Schlankes Backend ohne JSF-Code
This commit is contained in:
parent
19ea388bf1
commit
4dd9894b86
357
hsarback/src/de/hsadmin/cliClientConnector/ArgumentParser.java
Normal file
357
hsarback/src/de/hsadmin/cliClientConnector/ArgumentParser.java
Normal file
@ -0,0 +1,357 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.hsadmin.cliClientConnector.CLIClientConnectorServlet.FunctionNotKnownException;
|
||||
import de.hsadmin.cliClientConnector.CLIClientConnectorServlet.UnknownModuleException;
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.ModuleInterface;
|
||||
|
||||
/**
|
||||
* Parses Arguments for the CLI Client Connector Servlet
|
||||
*
|
||||
* @author Christof Donat
|
||||
*
|
||||
*/
|
||||
public class ArgumentParser {
|
||||
/// I am working for this Servlet instance
|
||||
private CLIClientConnectorServlet master;
|
||||
private DateFormat df = new SimpleDateFormat( "yyyy-MM-dd");
|
||||
|
||||
public ArgumentParser(CLIClientConnectorServlet master) {
|
||||
this.master = master;
|
||||
}
|
||||
|
||||
private String getUsageString() {
|
||||
return " [ (-W name=value|--globalWhere:name=value) ...]\n"+
|
||||
" [ (-S name=value|--globalSet:name=value) ...]\n"+
|
||||
" [ (-D displayspec|--globalDisplay=displayspec) ...]\n"+
|
||||
" [ (-c module.function|--call=module.function)\n" +
|
||||
" [ (-w name=value|--where:name=value) ...]\n"+
|
||||
" [ (-s name=value|--set:name=value) ...]\n"+
|
||||
" [ (-d displayspec|--display:displayspec) ...]\n"+
|
||||
" [ oids ...] ] ]\n"+
|
||||
"\n"+
|
||||
"(" + CLIClientConnectorServlet.version + ")\n";
|
||||
}
|
||||
|
||||
private ArrayList<Method> getMethodList(Object o) {
|
||||
Method[] meths = o.getClass().getMethods();
|
||||
ArrayList<Method> methodlist = new ArrayList<Method>();
|
||||
|
||||
for( int i = 0; i < meths.length; i++ ) {
|
||||
Method m = meths[i];
|
||||
String n = m.getName();
|
||||
if( n.startsWith("get") && !n.equals("getNew") ) {
|
||||
String fn = m.getName().substring(3).toLowerCase();
|
||||
if( fn.equals("class") ) continue;
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
methodlist.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return methodlist;
|
||||
}
|
||||
|
||||
private Hashtable<String,String> getValues(Object o, ArrayList<Method> methodlist, ArrayList<String>fieldNames, boolean deep, ArrayList<Object> foundObjects) {
|
||||
Hashtable<String,String> row = new Hashtable<String,String>();
|
||||
int i, j;
|
||||
|
||||
if( foundObjects == null ) foundObjects = new ArrayList<Object>();
|
||||
|
||||
for( i = 0; i < methodlist.size(); i++ ) {
|
||||
Method m = methodlist.get(i);
|
||||
try {
|
||||
String name = fieldNames.get(i);
|
||||
String type = m.getReturnType().getCanonicalName();
|
||||
String val = "";
|
||||
|
||||
Object value = null;
|
||||
try {
|
||||
value = m.invoke(o);
|
||||
} catch( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if( value == null )
|
||||
val = "";
|
||||
else if( type.equals("java.lang.String") )
|
||||
val = (String)value;
|
||||
else if( type.equals("java.lang.Integer") )
|
||||
val = String.valueOf((Integer)value);
|
||||
else if( type.equals("java.lang.Long") )
|
||||
val = String.valueOf((Long)value);
|
||||
else if( type.equals("java.lang.Boolean") )
|
||||
val = String.valueOf((Boolean)value);
|
||||
else if( type.equals("java.util.Date") ) {
|
||||
val = df.format((Date)value);
|
||||
} else if( type.equals("java.util.Set") ) {
|
||||
val = "<Set>";
|
||||
} else try {
|
||||
Entity v = (Entity)value;
|
||||
val = v.createStringKey();
|
||||
if( deep && !foundObjects.contains(v) ) {
|
||||
foundObjects.add(v);
|
||||
ArrayList<String> fieldNamesDeep = new ArrayList<String>();
|
||||
ArrayList<Method> methodlistDeep = getMethodList(v);
|
||||
for( j = 0; j < methodlistDeep.size(); j++ ) {
|
||||
fieldNamesDeep.add(methodlistDeep.get(j).getName().substring(3).toLowerCase());
|
||||
}
|
||||
Hashtable<String,String> tmp = getValues(v,methodlistDeep,fieldNamesDeep,deep,foundObjects);
|
||||
Enumeration<String> keys = tmp.keys();
|
||||
while(keys.hasMoreElements()) {
|
||||
try {
|
||||
String k = (String)keys.nextElement();
|
||||
row.put(name+"."+k, tmp.get(k));
|
||||
} catch( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(ClassCastException e) {
|
||||
val = value.toString();
|
||||
}
|
||||
if (val != null) row.put(name, val);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
private String formatObjectsWithoutDisplay(int j, ArrayList<String> fieldNames, ArrayList<Integer>columnWidths, ArrayList<Hashtable<String,String> > rows) {
|
||||
int i;
|
||||
StringBuffer rval = new StringBuffer();
|
||||
|
||||
for( i = 0; i < fieldNames.size(); i++ ) {
|
||||
StringBuffer name = new StringBuffer(fieldNames.get(i));
|
||||
int fieldwidth = columnWidths.get(i);
|
||||
while( name.length() < fieldwidth )
|
||||
name.append(" ");
|
||||
rval.append(name.toString()+((i < fieldNames.size()-1)?" | ":""));
|
||||
}
|
||||
rval.append("\n");
|
||||
for( i = 0; i < j; i++ )
|
||||
rval.append("-");
|
||||
rval.append("\n");
|
||||
|
||||
for( j = 0; j < rows.size(); j++ ) {
|
||||
for( i = 0; i < fieldNames.size(); i++ ) {
|
||||
StringBuffer value = new StringBuffer(rows.get(j).get(fieldNames.get(i)));
|
||||
int fieldwidth = columnWidths.get(i);
|
||||
while( value.length() < fieldwidth )
|
||||
value.append(" ");
|
||||
rval.append(value.toString()+((i < fieldNames.size()-1)?" | ":""));
|
||||
}
|
||||
rval.append("\n");
|
||||
}
|
||||
return rval.toString();
|
||||
}
|
||||
|
||||
private String formatObjectsWithDisplay(ArrayList<Hashtable<String,String> > rows, String displayDef) {
|
||||
StringBuffer rval = new StringBuffer();
|
||||
for( int j = 0; j < rows.size(); j++) {
|
||||
String rv = displayDef;
|
||||
Enumeration<String> fNames = rows.get(j).keys();
|
||||
while( fNames.hasMoreElements() ) {
|
||||
String f = (String)fNames.nextElement();
|
||||
rv = rv.replaceAll("\\$\\{"+f+"\\}", rows.get(j).get(f));
|
||||
}
|
||||
rv = rv.replaceAll("\\\\n", "\n");
|
||||
rv = rv.replaceAll("\\\\t", "\t");
|
||||
rv = rv.replaceAll("\\\\(.)?", "$1");
|
||||
rval.append(rv);
|
||||
}
|
||||
return rval.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* format Objects for the output as a Human readable table
|
||||
*
|
||||
* @param objects
|
||||
* format these objects
|
||||
*
|
||||
* @return humanReadableString
|
||||
* a string with the human readable representation of the objects
|
||||
*/
|
||||
public String formatObjects(List<?> objects, String displayDef) {
|
||||
if( objects.size() == 0 ) return "";
|
||||
if( objects.get(0) == null ) return "";
|
||||
ArrayList<Method> methodlist = getMethodList(objects.get(0));
|
||||
ArrayList<Integer>columnWidths = new ArrayList<Integer>();
|
||||
ArrayList<String>fieldNames = new ArrayList<String>();
|
||||
ArrayList<Hashtable<String,String> > rows =
|
||||
new ArrayList<Hashtable<String,String> >();
|
||||
int i, j;
|
||||
|
||||
for( i = 0; i < methodlist.size(); i++ ) {
|
||||
Method m = methodlist.get(i);
|
||||
String n = m.getName();
|
||||
String fn = n.substring(3).toLowerCase();
|
||||
fieldNames.add(fn);
|
||||
columnWidths.add(n.length()+3);
|
||||
}
|
||||
|
||||
for( j = 0; j < objects.size(); j++ ) {
|
||||
Object o = objects.get(j);
|
||||
Hashtable<String,String> row = getValues(o,methodlist,fieldNames,(displayDef != null), null);
|
||||
for( i = 0; i < fieldNames.size(); i++ ) {
|
||||
String val = row.get(fieldNames.get(i));
|
||||
if( val != null && i < columnWidths.size() && val.length()+3 > columnWidths.get(i) )
|
||||
columnWidths.set(i, val.length()+3);
|
||||
}
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
if( displayDef == null ) {
|
||||
j = 0;
|
||||
for( i = 0; i < columnWidths.size(); i++ ) {
|
||||
j += columnWidths.get(i)+2;
|
||||
}
|
||||
j -= 2;
|
||||
|
||||
return formatObjectsWithoutDisplay(j, fieldNames, columnWidths, rows);
|
||||
} else
|
||||
return formatObjectsWithDisplay(rows, displayDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main parser function. Parses the Parameters, uses the master to call
|
||||
* the functions and returns a formatet output.
|
||||
*
|
||||
* @param arguments
|
||||
* @return humanReadableObjectsString
|
||||
*/
|
||||
public String parse(List<String> arguments, ModuleInterface module) {
|
||||
String rval = "";
|
||||
|
||||
String currentModule = null;
|
||||
String currentFunction = null;
|
||||
Map<String,String> currentWhere = new Hashtable<String,String>();
|
||||
Map<String,String> currentSet = new Hashtable<String,String>();
|
||||
ArrayList<String> currentOIDs = new ArrayList<String>();
|
||||
|
||||
Map<String,String> globalWhere = new Hashtable<String,String>();
|
||||
Map<String,String> globalSet = new Hashtable<String,String>();
|
||||
String display = null;
|
||||
String globalDisplay = null;
|
||||
|
||||
for( int i = 0; i < arguments.size(); i++ ) {
|
||||
String arg = arguments.get(i);
|
||||
|
||||
if( arg.equals("-c") || arg.startsWith("--call:") ) {
|
||||
// call
|
||||
if( currentModule != null ) {
|
||||
try {
|
||||
// execute the last call now
|
||||
rval += formatObjects(master.callModule(
|
||||
currentModule,
|
||||
currentFunction,
|
||||
currentWhere,
|
||||
currentSet,
|
||||
currentOIDs,
|
||||
module),(display==null)?globalDisplay:display);
|
||||
} catch (FunctionNotKnownException e) {
|
||||
rval += "Function unknown: "+currentModule+'.'+currentFunction+"\n";
|
||||
} catch (UnknownModuleException e) {
|
||||
rval += "Module unknown: "+currentModule+"\n";
|
||||
}
|
||||
}
|
||||
// reset parameters for next call
|
||||
currentWhere = new HashMap<String, String>();
|
||||
currentWhere.putAll(globalWhere);
|
||||
currentSet = new HashMap<String, String>();
|
||||
currentSet.putAll(globalSet);
|
||||
currentOIDs = new ArrayList<String>();
|
||||
display = null;
|
||||
|
||||
// set the new call
|
||||
boolean isShortParam = arg.equals("-c");
|
||||
String calldef = isShortParam?arguments.get(i+1):arg.substring(7);
|
||||
|
||||
if( calldef != null ) {
|
||||
String[] split = calldef.split("[.]", 2);
|
||||
currentModule = split[0];
|
||||
currentFunction = split[1];
|
||||
}
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-w") || arg.startsWith("--where:") ) {
|
||||
// where
|
||||
boolean isShortParam = arg.equals("-w");
|
||||
String wheredef = isShortParam?arguments.get(i+1):arg.substring(8);
|
||||
if( wheredef != null ) {
|
||||
String[] split = wheredef.split("[=]", 2);
|
||||
currentWhere.put(split[0],split[1]);
|
||||
}
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-W") || arg.startsWith("--globalWhere:") ) {
|
||||
// global where
|
||||
boolean isShortParam = arg.equals("-W");
|
||||
String gwheredef = isShortParam?arguments.get(i+1):arg.substring(14);
|
||||
if( gwheredef != null ) {
|
||||
String[] split = gwheredef.split("[=]", 2);
|
||||
globalWhere.put(split[0],split[1]);
|
||||
}
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-s") || arg.startsWith("--set:") ) {
|
||||
// set
|
||||
boolean isShortParam = arg.equals("-s");
|
||||
String setdef = isShortParam?arguments.get(i+1):arg.substring(6);
|
||||
if( setdef != null ) {
|
||||
String[] split = setdef.split("[=]", 2);
|
||||
currentSet.put(split[0],split[1]);
|
||||
}
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-S") || arg.startsWith("--globalSet:") ) {
|
||||
// global set
|
||||
boolean isShortParam = arg.equals("-S");
|
||||
String gsetdef = isShortParam?arguments.get(i+1):arg.substring(12);
|
||||
if( gsetdef != null ) {
|
||||
String[] split = gsetdef.split("[=]", 2);
|
||||
globalSet.put(split[0],split[1]);
|
||||
}
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-d") || arg.startsWith("--display:") ) {
|
||||
// display
|
||||
boolean isShortParam = arg.equals("-d");
|
||||
display = isShortParam?arguments.get(i+1):arg.substring(10);
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-D") || arg.startsWith("--globalDisplay:") ) {
|
||||
// global display
|
||||
boolean isShortParam = arg.equals("-D");
|
||||
globalDisplay = isShortParam?arguments.get(i+1):arg.substring(16);
|
||||
if( isShortParam ) i++;
|
||||
} else if( arg.equals("-h") || arg.equals("--help") ) {
|
||||
return getUsageString();
|
||||
} else if( arg.startsWith("-") ) {
|
||||
return "unknown option '"+arg+"'\n"+getUsageString();
|
||||
} else currentOIDs.add(arg);
|
||||
}
|
||||
if( currentModule != null ) {
|
||||
try {
|
||||
rval += formatObjects(master.callModule(
|
||||
currentModule,
|
||||
currentFunction,
|
||||
currentWhere,
|
||||
currentSet,
|
||||
currentOIDs,
|
||||
module),(display==null)?globalDisplay:display);
|
||||
} catch (FunctionNotKnownException e) {
|
||||
rval += "Function unknown: "+currentModule+'.'+currentFunction+"\n";
|
||||
} catch (UnknownModuleException e) {
|
||||
rval += "Module unknown: "+currentModule+"\n";
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
}
|
244
hsarback/src/de/hsadmin/cliClientConnector/Base64.java
Normal file
244
hsarback/src/de/hsadmin/cliClientConnector/Base64.java
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* @(#)Base64.java 1.5 03/12/19
|
||||
*
|
||||
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
||||
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
/**
|
||||
* Static methods for translating Base64 encoded strings to byte arrays
|
||||
* and vice-versa.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @version 1.5, 12/19/03
|
||||
* @see Preferences
|
||||
* @since 1.4
|
||||
*/
|
||||
class Base64 {
|
||||
/**
|
||||
* Translates the specified byte array into a Base64 string as per
|
||||
* Preferences.put(byte[]).
|
||||
*/
|
||||
static String byteArrayToBase64(byte[] a) {
|
||||
return byteArrayToBase64(a, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the specified byte array into an "aternate representation"
|
||||
* Base64 string. This non-standard variant uses an alphabet that does
|
||||
* not contain the uppercase alphabetic characters, which makes it
|
||||
* suitable for use in situations where case-folding occurs.
|
||||
*/
|
||||
static String byteArrayToAltBase64(byte[] a) {
|
||||
return byteArrayToBase64(a, true);
|
||||
}
|
||||
|
||||
private static String byteArrayToBase64(byte[] a, boolean alternate) {
|
||||
int aLen = a.length;
|
||||
int numFullGroups = aLen/3;
|
||||
int numBytesInPartialGroup = aLen - 3*numFullGroups;
|
||||
int resultLen = 4*((aLen + 2)/3);
|
||||
StringBuffer result = new StringBuffer(resultLen);
|
||||
char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64);
|
||||
|
||||
// Translate all full groups from byte array elements to Base64
|
||||
int inCursor = 0;
|
||||
for (int i=0; i<numFullGroups; i++) {
|
||||
int byte0 = a[inCursor++] & 0xff;
|
||||
int byte1 = a[inCursor++] & 0xff;
|
||||
int byte2 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[byte0 >> 2]);
|
||||
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
|
||||
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
|
||||
result.append(intToAlpha[byte2 & 0x3f]);
|
||||
}
|
||||
|
||||
// Translate partial group if present
|
||||
if (numBytesInPartialGroup != 0) {
|
||||
int byte0 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[byte0 >> 2]);
|
||||
if (numBytesInPartialGroup == 1) {
|
||||
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
|
||||
result.append("==");
|
||||
} else {
|
||||
// assert numBytesInPartialGroup == 2;
|
||||
int byte1 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
|
||||
result.append(intToAlpha[(byte1 << 2)&0x3f]);
|
||||
result.append('=');
|
||||
}
|
||||
}
|
||||
// assert inCursor == a.length;
|
||||
// assert result.length() == resultLen;
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates 6-bit positive integer
|
||||
* index values into their "Base64 Alphabet" equivalents as specified
|
||||
* in Table 1 of RFC 2045.
|
||||
*/
|
||||
private static final char intToBase64[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates 6-bit positive integer
|
||||
* index values into their "Alternate Base64 Alphabet" equivalents.
|
||||
* This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
|
||||
* This alternate alphabet does not use the capital letters. It is
|
||||
* designed for use in environments where "case folding" occurs.
|
||||
*/
|
||||
private static final char intToAltBase64[] = {
|
||||
'!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
|
||||
';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
|
||||
};
|
||||
|
||||
/**
|
||||
* Translates the specified Base64 string (as per Preferences.get(byte[]))
|
||||
* into a byte array.
|
||||
*
|
||||
* @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64
|
||||
* string.
|
||||
*/
|
||||
static byte[] base64ToByteArray(String s) {
|
||||
return base64ToByteArray(s, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the specified "aternate representation" Base64 string
|
||||
* into a byte array.
|
||||
*
|
||||
* @throw IllegalArgumentException or ArrayOutOfBoundsException
|
||||
* if <tt>s</tt> is not a valid alternate representation
|
||||
* Base64 string.
|
||||
*/
|
||||
static byte[] altBase64ToByteArray(String s) {
|
||||
return base64ToByteArray(s, true);
|
||||
}
|
||||
|
||||
private static byte[] base64ToByteArray(String s, boolean alternate) {
|
||||
byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
|
||||
int sLen = s.length();
|
||||
int numGroups = sLen/4;
|
||||
if (4*numGroups != sLen)
|
||||
throw new IllegalArgumentException(
|
||||
"String length must be a multiple of four.");
|
||||
int missingBytesInLastGroup = 0;
|
||||
int numFullGroups = numGroups;
|
||||
if (sLen != 0) {
|
||||
if (s.charAt(sLen-1) == '=') {
|
||||
missingBytesInLastGroup++;
|
||||
numFullGroups--;
|
||||
}
|
||||
if (s.charAt(sLen-2) == '=')
|
||||
missingBytesInLastGroup++;
|
||||
}
|
||||
byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
|
||||
|
||||
// Translate all full groups from base64 to byte array elements
|
||||
int inCursor = 0, outCursor = 0;
|
||||
for (int i=0; i<numFullGroups; i++) {
|
||||
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
|
||||
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
|
||||
result[outCursor++] = (byte) ((ch2 << 6) | ch3);
|
||||
}
|
||||
|
||||
// Translate partial group, if present
|
||||
if (missingBytesInLastGroup != 0) {
|
||||
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
|
||||
|
||||
if (missingBytesInLastGroup == 1) {
|
||||
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
|
||||
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
|
||||
}
|
||||
}
|
||||
// assert inCursor == s.length()-missingBytesInLastGroup;
|
||||
// assert outCursor == result.length;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the specified character, which is assumed to be in the
|
||||
* "Base 64 Alphabet" into its equivalent 6-bit positive integer.
|
||||
*
|
||||
* @throw IllegalArgumentException or ArrayOutOfBoundsException if
|
||||
* c is not in the Base64 Alphabet.
|
||||
*/
|
||||
private static int base64toInt(char c, byte[] alphaToInt) {
|
||||
int result = alphaToInt[c];
|
||||
if (result < 0)
|
||||
throw new IllegalArgumentException("Illegal character " + c);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates unicode characters
|
||||
* drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
|
||||
* into their 6-bit positive integer equivalents. Characters that
|
||||
* are not in the Base64 alphabet but fall within the bounds of the
|
||||
* array are translated to -1.
|
||||
*/
|
||||
private static final byte base64ToInt[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
|
||||
/**
|
||||
* This array is the analogue of base64ToInt, but for the nonstandard
|
||||
* variant that avoids the use of uppercase alphabetic characters.
|
||||
*/
|
||||
private static final byte altBase64ToInt[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
|
||||
2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
||||
51, 22, 23, 24, 25
|
||||
};
|
||||
|
||||
public static void main(String args[]) {
|
||||
int numRuns = Integer.parseInt(args[0]);
|
||||
int numBytes = Integer.parseInt(args[1]);
|
||||
java.util.Random rnd = new java.util.Random();
|
||||
for (int i=0; i<numRuns; i++) {
|
||||
for (int j=0; j<numBytes; j++) {
|
||||
byte[] arr = new byte[j];
|
||||
for (int k=0; k<j; k++)
|
||||
arr[k] = (byte)rnd.nextInt();
|
||||
|
||||
String s = byteArrayToBase64(arr);
|
||||
byte [] b = base64ToByteArray(s);
|
||||
if (!java.util.Arrays.equals(arr, b))
|
||||
System.out.println("Dismal failure!");
|
||||
|
||||
s = byteArrayToAltBase64(arr);
|
||||
b = altBase64ToByteArray(s);
|
||||
if (!java.util.Arrays.equals(arr, b))
|
||||
System.out.println("Alternate dismal failure!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BusinessException
|
||||
extends RuntimeException
|
||||
{
|
||||
|
||||
public BusinessException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public BusinessException(Exception exc)
|
||||
{
|
||||
super(exc.getMessage());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,490 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.GenericModuleImpl;
|
||||
import de.hsadmin.core.model.ModuleInterface;
|
||||
import de.hsadmin.core.model.TicketAuthentication;
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
import de.hsadmin.core.model.onetier.TicketValidator;
|
||||
|
||||
/**
|
||||
* actually this is the core of the CLI-Client. The other CLI-Client is just a
|
||||
* rather simple HTTP Client that calls this Servlet.
|
||||
*
|
||||
* @author Christof Donat
|
||||
*
|
||||
*/
|
||||
public class CLIClientConnectorServlet extends HttpServlet {
|
||||
private static final long serialVersionUID = 7150004719303750077L;
|
||||
public static final String version = "1.0.8 (2009/May/27 18:22)";
|
||||
private Map<String, Class<?>> componentmap;
|
||||
private Map<String, String> componentDescriptions;
|
||||
private ArgumentParser parser;
|
||||
|
||||
/**
|
||||
* Servlet initialization
|
||||
*/
|
||||
public void init(ServletConfig cfg) {
|
||||
// init ticket validator
|
||||
String validateURL = cfg.getInitParameter("proxyValidateUrl");
|
||||
String serviceURL = cfg.getInitParameter("proxyServiceUrl");
|
||||
TicketValidator.getInstance().initialize(validateURL, serviceURL);
|
||||
// find components
|
||||
String cstring = cfg.getInitParameter("Components");
|
||||
String[] components = cstring.split(",");
|
||||
|
||||
componentmap = new HashMap<String, Class<?>>();
|
||||
componentDescriptions = new HashMap<String, String>();
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
// get everything for this component and create an entry.
|
||||
try {
|
||||
// component class
|
||||
String classname = cfg.getInitParameter("ComponentClass_"
|
||||
+ components[i]);
|
||||
if (classname == null)
|
||||
throw new NullPointerException(
|
||||
"no class name found for Component "
|
||||
+ components[i]);
|
||||
Class<?> cls = Class.forName(classname);
|
||||
componentmap.put(components[i], cls);
|
||||
// description
|
||||
String descr = cfg.getInitParameter("ComponentDescription_"
|
||||
+ components[i]);
|
||||
if (descr != null)
|
||||
componentDescriptions.put(components[i], descr);
|
||||
else
|
||||
componentDescriptions.put(components[i], "");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// TODO: get username, password from http session
|
||||
parser = new ArgumentParser(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* set values to a given entity Object
|
||||
*
|
||||
* @param o
|
||||
* the entity Object
|
||||
* @param set
|
||||
* Hashtable with names and values that sould be changed in o
|
||||
*/
|
||||
private void setValues(Object o, Map<String, String> set, ModuleInterface module) {
|
||||
Iterator<String> keys = set.keySet().iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
String[] ns = key.split("[.]", 2);
|
||||
Object realO = o;
|
||||
for (int i = 0; i < ns.length - 1; i++) {
|
||||
Method[] m = realO.getClass().getMethods();
|
||||
boolean oFound = false;
|
||||
for (int j = 0; j < m.length; j++) {
|
||||
if (m[j].getName().toLowerCase().equals(
|
||||
"get" + ns[i].toLowerCase())) {
|
||||
try {
|
||||
realO = m[j].invoke(realO, (Object[]) null);
|
||||
oFound = (realO != null);
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
new TechnicalException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!oFound)
|
||||
break;
|
||||
}
|
||||
Method[] m = realO.getClass().getMethods();
|
||||
String value = set.get(key);
|
||||
for (int j = 0; j < m.length; j++) {
|
||||
if (!m[j].getName().toLowerCase().equals(
|
||||
"set" + ns[ns.length - 1].toLowerCase()))
|
||||
continue;
|
||||
String type = m[j].getParameterTypes()[0].getCanonicalName();
|
||||
try {
|
||||
if (type.equals("java.lang.String"))
|
||||
m[j].invoke(o, value);
|
||||
else if (type.equals("java.lang.Integer"))
|
||||
m[j].invoke(o, Integer.parseInt(value));
|
||||
else if (type.equals("java.lang.Long"))
|
||||
m[j].invoke(o, Long.parseLong(value));
|
||||
else if (type.equals("java.lang.Boolean"))
|
||||
m[j].invoke(o, Boolean.valueOf(value));
|
||||
else if (type.equals("java.util.Date")) {
|
||||
DateFormat df = DateFormat.getInstance();
|
||||
m[j].invoke(o, df.parse(value));
|
||||
} else {
|
||||
Method m2 = module.getClass().getMethod(
|
||||
"findByString", Class.class, String.class);
|
||||
Object entity =
|
||||
m2.invoke(module, m[j].getParameterTypes()[0], value);
|
||||
if (entity != null)
|
||||
m[j].invoke(o, entity);
|
||||
else
|
||||
throw new BusinessException(
|
||||
"not object found for '" + value + "'");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new TechnicalException(e); // TODO: this needs to be
|
||||
// more specific for
|
||||
// some cases
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String hasGetter(Class<?> eType, String name) {
|
||||
String rval = null;
|
||||
String[] ns = name.split("[.]", 2);
|
||||
String n1 = ns[0];
|
||||
Method meth = null;
|
||||
|
||||
for (Method m : eType.getMethods()) {
|
||||
String n = m.getName();
|
||||
if (n.startsWith("get")) {
|
||||
String fn = m.getName().substring(3).toLowerCase();
|
||||
if (fn != "class" && fn.equals(n1)) {
|
||||
meth = m;
|
||||
rval = fn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (meth != null) {
|
||||
Class<?> returnType = meth.getReturnType();
|
||||
if (rval != null && ns.length > 1 && meth != null)
|
||||
return hasGetter(returnType, ns[1]);
|
||||
if (returnType.getCanonicalName().startsWith("de.hsadmin.mods")) {
|
||||
try {
|
||||
if (returnType.getMethod("getName") != null) {
|
||||
return rval + ".name";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no method found
|
||||
}
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a query from a where clause and some objectIDs.
|
||||
*
|
||||
* @param eType
|
||||
* The class of the Entity Object for which the string should be
|
||||
* built. We need this to call the static method
|
||||
* "createQueryFromStringKey"
|
||||
* @param where
|
||||
* Hashtable with where parameters. Only objects which match all
|
||||
* where parameters are found
|
||||
* @param oids
|
||||
* Only objects with one of these object IDs are found
|
||||
*
|
||||
* @return queryString a query string that can be used to select the
|
||||
* required Objects
|
||||
*/
|
||||
private String buildQuery(Class<?> eType, Map<String, String> where,
|
||||
ArrayList<String> oids) {
|
||||
String rval = "";
|
||||
|
||||
boolean first = true;
|
||||
Iterator<String> wkeys = where.keySet().iterator();
|
||||
while (wkeys.hasNext()) {
|
||||
String k = (String) wkeys.next();
|
||||
String kname = hasGetter(eType, k);
|
||||
if (kname != null) {
|
||||
rval += (first ? "" : " and ")
|
||||
+ "(obj." + Entity.escapeString(kname) + " = '" + Entity.escapeString(where.get(k)) + "')";
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
String rv = "";
|
||||
if (oids != null)
|
||||
try {
|
||||
Method m;
|
||||
m = eType.getMethod("createQueryFromStringKey", String.class);
|
||||
|
||||
first = true;
|
||||
for (String s : oids) {
|
||||
rv += (first ? "" : " or ") + "("
|
||||
+ (String) m.invoke(eType, s) + ")";
|
||||
first = false;
|
||||
}
|
||||
if (rv != "" && rval != "")
|
||||
rval = rval + " and (" + rv + ")";
|
||||
else if (rv != "")
|
||||
rval = rv;
|
||||
} catch (Exception e) {
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
|
||||
return (rval == "") ? null : rval;
|
||||
}
|
||||
|
||||
public class FunctionNotKnownException extends Exception {
|
||||
private static final long serialVersionUID = -6330015688609717838L;
|
||||
}
|
||||
|
||||
public class UnknownModuleException extends Exception {
|
||||
private static final long serialVersionUID = 696641072107896601L;
|
||||
}
|
||||
|
||||
private Object callAdd(Class<?> cls, Map<String, String> set, ModuleInterface module) {
|
||||
Transaction transaction = module.getTransaction();
|
||||
transaction.beginTransaction();
|
||||
try {
|
||||
Method m = module.getClass().getMethod("add", Entity.class);
|
||||
Object o = cls.newInstance();
|
||||
setValues(o, set, module);
|
||||
m.invoke(module, o);
|
||||
transaction.commitTransaction();
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
transaction.rollbackTransaction();
|
||||
// TODO: this needs to be more specific, but how?
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> callSearch(Class<?> cls, Map<String, String> where,
|
||||
ArrayList<String> oids, ModuleInterface module) {
|
||||
try {
|
||||
Method m = module.getClass().getMethod("search", Class.class,
|
||||
String.class, String.class);
|
||||
return (List<Object>) m.invoke(module, cls,
|
||||
buildQuery(cls, where, oids), null);
|
||||
} catch (Exception e) {
|
||||
throw new TechnicalException(e); // TODO: this needs to be more
|
||||
// specific, but how?
|
||||
}
|
||||
}
|
||||
|
||||
// / checks wheather all 'oids' are in 'list'
|
||||
private void checkOids(List<Entity> list, List<String> oids) {
|
||||
List<String> oidsNotFound = new ArrayList<String>();
|
||||
for (String id : oids) {
|
||||
boolean found = false;
|
||||
for (Entity e : list) {
|
||||
String foundKey = e.createStringKey();
|
||||
if (foundKey.equals(id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
oidsNotFound.add(id);
|
||||
}
|
||||
if (oidsNotFound.size() > 0) {
|
||||
throw new OidsNotFoundException(oids);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> callUpdate(Class<?> cls, Map<String, String> where,
|
||||
ArrayList<String> oids, Map<String, String> set,
|
||||
ModuleInterface module) {
|
||||
// better safe than sorry - alsd hso same behavior as UNIX rm
|
||||
if (where.size() == 0 && oids.size() == 0)
|
||||
throw new BusinessException(
|
||||
"better safe than sorry - 'update' needs a -w/--where-query or object id");
|
||||
Transaction tx = module.getTransaction();
|
||||
tx.beginTransaction();
|
||||
try {
|
||||
Method m = module.getClass().getMethod("search", Class.class,
|
||||
String.class, String.class);
|
||||
List<Entity> list = (List<Entity>) m.invoke(module, cls,
|
||||
buildQuery(cls, where, oids), null);
|
||||
checkOids(list, oids);
|
||||
Method m2 = module.getClass().getMethod("update", Entity.class);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Entity entity = list.get(i);
|
||||
tx.detach(entity);
|
||||
setValues(entity, set, module);
|
||||
m2.invoke(module, entity);
|
||||
}
|
||||
tx.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
tx.rollbackTransaction();
|
||||
// TODO: this needs to be more specific, but how?
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void callDelete(Class<?> cls, Map<String, String> where,
|
||||
ArrayList<String> oids, ModuleInterface module) {
|
||||
// better safe than sorry - also same behavior as UNIX rm
|
||||
if (where.size() == 0 && oids.size() == 0)
|
||||
throw new BusinessException(
|
||||
"better safe than sorry - 'update' needs a -w/--where-query or object id");
|
||||
Transaction tx = module.getTransaction();
|
||||
tx.beginTransaction();
|
||||
try {
|
||||
Method m =
|
||||
module.getClass().getMethod("search", Class.class, String.class, String.class);
|
||||
List<Entity> list =
|
||||
(List<Entity>) m.invoke(module, cls, buildQuery(cls, where, oids), null);
|
||||
checkOids(list, oids);
|
||||
Method m2 = module.getClass().getMethod("delete", Entity.class);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
m2.invoke(module, o);
|
||||
}
|
||||
tx.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
tx.rollbackTransaction();
|
||||
// TODO: this needs to be more specific, but how?
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call one of the EntitySessions methods
|
||||
*
|
||||
* @param moduleName
|
||||
* Defines the Entity class that will be given to the
|
||||
* EntitySession
|
||||
* @param function
|
||||
* Defines the method that will be called. The function can be
|
||||
* "add", "search", "update" and "delete".
|
||||
* @param where
|
||||
* Reduces the set of Entity objects which the function operates
|
||||
* on to those matched by the where parameters. Only for
|
||||
* "search", "update" and "delete". Will be ignored otherwise.
|
||||
* @param set
|
||||
* Set these values on all Objects - only for "add" and "update".
|
||||
* Will be ignored otherwise.
|
||||
* @param oids
|
||||
* Works on Objects with these IDs. Only for "search", "update"
|
||||
* and "delete". Will be ignored for "add".
|
||||
* @return foundObjects
|
||||
* @throws FunctionNotKnownException
|
||||
*/
|
||||
public List<Object> callModule(String moduleName, String function,
|
||||
Map<String, String> where, Map<String, String> set,
|
||||
ArrayList<String> oids, ModuleInterface module)
|
||||
throws FunctionNotKnownException, UnknownModuleException {
|
||||
List<Object> rval = new ArrayList<Object>();
|
||||
|
||||
// handle calls to the virtual module "modules"
|
||||
if (moduleName.equals("modules")) {
|
||||
// only search, no manipulation is possible
|
||||
if (function.equals("search")) {
|
||||
Iterator<?> m = componentDescriptions.keySet().iterator();
|
||||
while (m.hasNext()) {
|
||||
String mn = (String) m.next();
|
||||
rval.add(new ModuleModel(mn, componentDescriptions.get(mn)));
|
||||
}
|
||||
} else if (function.equals("version")) {
|
||||
rval.add(new VersionModel(version));
|
||||
} else {
|
||||
throw new FunctionNotKnownException();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
// find the component for the named module
|
||||
Class<?> cls = componentmap.get(moduleName);
|
||||
if (cls == null)
|
||||
throw (new UnknownModuleException());
|
||||
|
||||
// call the appropriate methods
|
||||
if (function.equals("add"))
|
||||
rval.add(callAdd(cls, set, module));
|
||||
else if (function.equals("search")) {
|
||||
List<Object> r = callSearch(cls, where, oids, module);
|
||||
if (r != null)
|
||||
return r;
|
||||
} else if (function.equals("update")) {
|
||||
List<Object> r = callUpdate(cls, where, oids, set, module);
|
||||
if (r != null)
|
||||
return callUpdate(cls, where, oids, set, module);
|
||||
} else if (function.equals("delete")) {
|
||||
callDelete(cls, where, oids, module);
|
||||
} else
|
||||
throw (new FunctionNotKnownException());
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle put method
|
||||
*/
|
||||
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
|
||||
try {
|
||||
ModuleInterface module;
|
||||
|
||||
// check login
|
||||
String auth = req.getHeader("authorization");
|
||||
if (auth == null) {
|
||||
// no login information at all - get it
|
||||
resp.setHeader("WWW-Authenticate",
|
||||
"Basic realm=\"CLIClientConnector\"");
|
||||
resp.getOutputStream().println("login Failed.");
|
||||
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return;
|
||||
} else {
|
||||
// parse login information
|
||||
String[] a = auth.split(" ", 2);
|
||||
String ticket = a[1];
|
||||
byte[] decoded = Base64.base64ToByteArray(ticket.trim());
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i = 0; i < decoded.length; i++)
|
||||
s.append((char) decoded[i]);
|
||||
a = s.toString().split(":", 2);
|
||||
// try to log in
|
||||
String login = a[0];
|
||||
ticket = a[1];
|
||||
module = null;
|
||||
try {
|
||||
if (TicketAuthentication.getInstance().login(login, ticket)) {
|
||||
|
||||
// login successful
|
||||
module = new GenericModuleImpl(new Transaction(login));
|
||||
|
||||
// read arguments
|
||||
BufferedReader read = req.getReader();
|
||||
|
||||
String tmpbuf;
|
||||
ArrayList<String> arguments = new ArrayList<String>();
|
||||
while ((tmpbuf = read.readLine()) != null) {
|
||||
arguments.add(tmpbuf);
|
||||
}
|
||||
|
||||
// actually handle the request and write result to output
|
||||
String output = parser.parse(arguments, module);
|
||||
resp.getWriter().write(output);
|
||||
} else {
|
||||
resp.addHeader("X-hsadmin-error", "authentication failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resp.addHeader("X-hsadmin-error", "exception: " + e.getMessage());
|
||||
} finally {
|
||||
if (module != null && module.getTransaction() != null) {
|
||||
module.getTransaction().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
19
hsarback/src/de/hsadmin/cliClientConnector/ModuleModel.java
Normal file
19
hsarback/src/de/hsadmin/cliClientConnector/ModuleModel.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
public class ModuleModel {
|
||||
private String name;
|
||||
private String description;
|
||||
|
||||
public ModuleModel(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class OidsNotFoundException
|
||||
extends RuntimeException
|
||||
{
|
||||
static private String oidsAsString(List<String> oids)
|
||||
{
|
||||
StringBuilder oidsBuilder = new StringBuilder();
|
||||
for ( String id: oids )
|
||||
oidsBuilder.append(", " + id);
|
||||
if ( oidsBuilder.length() > 0 )
|
||||
return oidsBuilder.substring(2);
|
||||
throw new RuntimeException( "an empty list of missing OIDS does not make sense" );
|
||||
}
|
||||
|
||||
public OidsNotFoundException(List<String> oids)
|
||||
{
|
||||
super("OIDS not found: " + oidsAsString(oids));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.RollbackException;
|
||||
|
||||
public class TechnicalException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TechnicalException(Throwable e) {
|
||||
super(extractCauseMessage(e));
|
||||
}
|
||||
|
||||
private static String extractCauseMessage(Throwable e) {
|
||||
if (e.getMessage() != null && !(e instanceof RollbackException)) {
|
||||
return e.getMessage();
|
||||
}
|
||||
else if (e instanceof InvocationTargetException || e instanceof RollbackException) {
|
||||
String sqlState = null;
|
||||
Throwable cause = e.getCause();
|
||||
Throwable prev = null;
|
||||
while (cause != null && cause != prev) {
|
||||
prev = cause;
|
||||
cause = prev.getCause();
|
||||
if ((cause == null || cause == prev)
|
||||
&& prev instanceof SQLException) {
|
||||
SQLException sqlExc = (SQLException) prev;
|
||||
sqlState = sqlExc.getSQLState();
|
||||
cause = sqlExc.getNextException();
|
||||
}
|
||||
}
|
||||
if (cause == null)
|
||||
cause = prev;
|
||||
if (cause != null)
|
||||
return composeMessage(sqlState, cause.getMessage());
|
||||
if (e instanceof InvocationTargetException) {
|
||||
return composeMessage(sqlState, ((InvocationTargetException) e).getTargetException().getMessage());
|
||||
}
|
||||
}
|
||||
return e.getClass() + " without detail message";
|
||||
}
|
||||
|
||||
private static String composeMessage(String sqlState, String message) {
|
||||
if (sqlState != null) return "SQLSTATE[" + sqlState + "] " + message;
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
14
hsarback/src/de/hsadmin/cliClientConnector/VersionModel.java
Normal file
14
hsarback/src/de/hsadmin/cliClientConnector/VersionModel.java
Normal file
@ -0,0 +1,14 @@
|
||||
package de.hsadmin.cliClientConnector;
|
||||
|
||||
public class VersionModel
|
||||
{
|
||||
private String version;
|
||||
|
||||
public VersionModel( String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
361
hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java
Normal file
361
hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java
Normal file
@ -0,0 +1,361 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import de.hsadmin.core.qserv.EntityProcessorFactory;
|
||||
import de.hsadmin.core.qserv.Processor;
|
||||
import de.hsadmin.core.qserv.QueueTask;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
/**
|
||||
* Generic implementation of EntitySession interface.
|
||||
*
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class AbstractModuleImpl implements ModuleInterface {
|
||||
|
||||
private static final long serialVersionUID = 2693948730004920437L;
|
||||
private static Log log = LogFactory.getLog(AbstractModuleImpl.class);
|
||||
|
||||
private UnixUser loginUser;
|
||||
private Transaction transaction;
|
||||
|
||||
public void construct(Transaction tx) {
|
||||
transaction = tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply access restriction to JPA-QL condition.
|
||||
* @param entityClass
|
||||
* @param loginUser
|
||||
* @param condition
|
||||
* @return
|
||||
*/
|
||||
private String restrict(Class<?> entityClass, UnixUser loginUser, String condition) {
|
||||
String restriction = Entity.restriction(entityClass, loginUser);
|
||||
if (restriction == null)
|
||||
return condition;
|
||||
if (condition != null && condition.length() > 0)
|
||||
condition = "(" + condition + ") AND (" + restriction + ")";
|
||||
else
|
||||
condition = restriction;
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Transaction getTransaction() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public Entity initialize(Entity newEntity)
|
||||
throws AuthorisationException {
|
||||
newEntity.initialize(transaction.getEntityManager(), getLoginUser());
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
public Entity add(Entity newEntity) throws HSAdminException {
|
||||
// get the user who is logged in
|
||||
UnixUser loginUser = getLoginUser();
|
||||
|
||||
// create record in database
|
||||
log.debug("merging?");
|
||||
newEntity.complete(transaction.getEntityManager(), loginUser);
|
||||
try {
|
||||
transaction.getEntityManager().persist(newEntity);
|
||||
} catch (Throwable exc) {
|
||||
log.error("exception: " + exc);
|
||||
} finally {
|
||||
log.debug("finally");
|
||||
}
|
||||
log.debug("merged");
|
||||
|
||||
// check rights
|
||||
if (!newEntity.isWriteAllowedFor(loginUser))
|
||||
throw new AuthorisationException(loginUser, "add", newEntity);
|
||||
|
||||
// generically create the processor
|
||||
EntityProcessorFactory procFact = createProcessorFactory(newEntity.getClass());
|
||||
if (procFact == null) {
|
||||
log.debug("no procFact found :-(");
|
||||
return newEntity;
|
||||
}
|
||||
log.debug("procFact found :-)");
|
||||
Processor proc = procFact.createCreateProcessor(transaction.getEntityManager(), newEntity);
|
||||
|
||||
// queue the processor
|
||||
queueProcessor(proc, loginUser, newEntity, "hinzugefuegt");
|
||||
|
||||
// return the added entity
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
public Entity find(Class<? extends Entity> entityClass, Object key) throws HSAdminException {
|
||||
Entity entity = transaction.getEntityManager().find(entityClass, key);
|
||||
|
||||
// check rights
|
||||
UnixUser loginUser = getLoginUser();
|
||||
if (!entity.isReadAllowedFor(loginUser))
|
||||
throw new AuthorisationException(loginUser, "add", entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Entity findByString(Class<? extends Entity> entityClass, String key) throws HSAdminException {
|
||||
// find a static method which creates the query
|
||||
java.lang.reflect.Method method = null;
|
||||
try {
|
||||
method = entityClass.getDeclaredMethod("createQueryFromStringKey", String.class);
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
method = null;
|
||||
}
|
||||
|
||||
Entity entity;
|
||||
if (method == null)
|
||||
entity = transaction.getEntityManager().find(entityClass, key);
|
||||
else {
|
||||
// get the query expression from the static method (query part after
|
||||
// WHERE)
|
||||
String query;
|
||||
try {
|
||||
query = (String) method.invoke(null, key);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// perform the query
|
||||
List<Entity> result = search(entityClass, query, null);
|
||||
if (result.size() > 1)
|
||||
throw new javax.persistence.NonUniqueResultException();
|
||||
if (result.size() == 0)
|
||||
return null;
|
||||
entity = result.get(0);
|
||||
|
||||
// this was maybe thought as a fallback
|
||||
// but is wrong when the above result is empty due to accessibility
|
||||
// entity = em.find(entityClass, key);
|
||||
}
|
||||
|
||||
// return (checking rights already done in search)
|
||||
return entity;
|
||||
}
|
||||
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String condition, String orderBy) throws HSAdminException {
|
||||
// restrict query
|
||||
UnixUser loginUser = getLoginUser();
|
||||
condition = restrict(entityClass, loginUser, condition);
|
||||
|
||||
// get the entities name (query part from FROM to WHERE)
|
||||
// TODO: beware SQL injections!!!
|
||||
javax.persistence.Entity entityAnnot = entityClass.getAnnotation(javax.persistence.Entity.class);
|
||||
String queryString = "SELECT obj FROM " + entityAnnot.name() + " obj";
|
||||
if (condition != null && condition.length() > 0)
|
||||
queryString += " WHERE " + condition;
|
||||
|
||||
// Fix problem with queries WHERE .. AND (FALSE) -- pe
|
||||
if (condition != null && condition.contains("AND (FALSE)")) {
|
||||
return new LinkedList<Entity>();
|
||||
}
|
||||
|
||||
if (orderBy != null) {
|
||||
queryString += " ";
|
||||
queryString += orderBy;
|
||||
}
|
||||
|
||||
// set parameters
|
||||
EntityManager entityManager = transaction.getEntityManager();
|
||||
entityManager.clear();
|
||||
|
||||
Query query = entityManager.createQuery(queryString);
|
||||
setQueryParameter(query, queryString, "loginUser", loginUser);
|
||||
setQueryParameter(query, queryString, "loginUserName", loginUser.getName());
|
||||
setQueryParameter(query, queryString, "loginUserPac", loginUser.getPac());
|
||||
|
||||
// do query
|
||||
try {
|
||||
List<?> res = query.getResultList();
|
||||
List<Entity> ret = new LinkedList<Entity>();
|
||||
|
||||
// remove entities where login user has no access rights
|
||||
for (Object entity : res) {
|
||||
if (entity instanceof Entity) {
|
||||
Entity returnedEntity = (Entity) entity;
|
||||
if (returnedEntity.isReadAllowedFor(getLoginUser())) {
|
||||
ret.add(returnedEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return clean result
|
||||
return ret;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Entity update(Entity existingEntity) throws HSAdminException {
|
||||
// get the user who is logged in
|
||||
UnixUser loginUser = getLoginUser();
|
||||
|
||||
// update record in database
|
||||
log.debug("merging:");
|
||||
try {
|
||||
existingEntity = existingEntity.merge(transaction.getEntityManager(), loginUser);
|
||||
} catch (Throwable exc) {
|
||||
log.error("exception: " + exc);
|
||||
throw new RuntimeException(exc);
|
||||
} finally {
|
||||
log.debug("finally");
|
||||
}
|
||||
log.debug("merged!");
|
||||
|
||||
// check rights
|
||||
if (!existingEntity.isWriteAllowedFor(loginUser))
|
||||
throw new AuthorisationException(loginUser, "update",
|
||||
existingEntity);
|
||||
|
||||
// generically create the processor
|
||||
EntityProcessorFactory procFact =
|
||||
createProcessorFactory(existingEntity.getClass());
|
||||
if (procFact != null) {
|
||||
log.debug("creating processor");
|
||||
Processor proc = procFact.createUpdateProcessor(transaction.getEntityManager(), existingEntity);
|
||||
|
||||
// queue the processor
|
||||
queueProcessor(proc, loginUser, existingEntity, "aktualisiert");
|
||||
}
|
||||
|
||||
// return the merged entity
|
||||
return existingEntity;
|
||||
}
|
||||
|
||||
public void delete(Entity existingEntity) throws HSAdminException {
|
||||
// get the user who is logged in
|
||||
UnixUser user = getLoginUser();
|
||||
|
||||
// re-attach the entity
|
||||
log.debug("merging:");
|
||||
try {
|
||||
existingEntity = transaction.getEntityManager().find(existingEntity.getClass(), existingEntity.id());
|
||||
} catch (Throwable exc) {
|
||||
log.error("exception: " + exc);
|
||||
throw new RuntimeException(exc);
|
||||
} finally {
|
||||
log.debug("finally");
|
||||
}
|
||||
log.debug("merged!");
|
||||
|
||||
// check rights
|
||||
if (!existingEntity.isWriteAllowedFor(loginUser))
|
||||
throw new AuthorisationException(loginUser, "add", existingEntity);
|
||||
|
||||
// delete record in database
|
||||
log.debug("deleting:");
|
||||
try {
|
||||
transaction.getEntityManager().remove(existingEntity);
|
||||
} catch (Throwable exc) {
|
||||
log.error("exception: " + exc);
|
||||
} finally {
|
||||
log.debug("finally");
|
||||
}
|
||||
log.debug("deleted!");
|
||||
|
||||
// generically create the processor
|
||||
EntityProcessorFactory procFact = createProcessorFactory(existingEntity.getClass());
|
||||
if (procFact == null) {
|
||||
log.debug("no procFact found :-(");
|
||||
return;
|
||||
}
|
||||
log.debug("procFact found :-)");
|
||||
Processor proc = procFact.createDeleteProcessor(transaction.getEntityManager(), existingEntity);
|
||||
|
||||
// queue the processor
|
||||
queueProcessor(proc, user, existingEntity, "geloescht");
|
||||
}
|
||||
|
||||
public EntityProcessorFactory createProcessorFactory(Class<? extends Entity> entityClass) {
|
||||
try {
|
||||
String procFactName = entityClass.getCanonicalName()
|
||||
+ "ProcessorFactory";
|
||||
Class<?> procFactClass = Class.forName(procFactName);
|
||||
if (procFactClass == null)
|
||||
return null;
|
||||
Object procFact = procFactClass.newInstance();
|
||||
return (EntityProcessorFactory) procFact;
|
||||
} catch (Exception exc) {
|
||||
log.error("exception creating instance: " + exc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get current login user from session context.
|
||||
* @return
|
||||
*/
|
||||
public UnixUser getLoginUser() {
|
||||
if (loginUser == null) {
|
||||
log.debug("getting login user");
|
||||
Query userQuery = transaction.getEntityManager().createQuery("SELECT u FROM UnixUsers u WHERE u.name=:name");
|
||||
userQuery.setParameter("name", transaction.getLoginName());
|
||||
loginUser = (UnixUser) userQuery.getSingleResult();
|
||||
log.debug("found login user: " + loginUser.getName());
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
public void queueProcessor(Processor proc, UnixUser user, Entity entity, String action) {
|
||||
log.debug("queueing processor for user " + user.getId() + "/"
|
||||
+ user.getUserId() + "/" + user.getName());
|
||||
EntityInfo entityInfo =
|
||||
entity.getClass().getAnnotation(EntityInfo.class);
|
||||
String entityTypeName =
|
||||
entityInfo != null ? entityInfo.name() : entity.getClass().getSimpleName();
|
||||
StringBuilder details = new StringBuilder();
|
||||
|
||||
// TODO: add properties of entity to details
|
||||
|
||||
String title =
|
||||
entityTypeName + " (" + entity.createStringKey() + ") " + action;
|
||||
QueueTask task = new QueueTask(user, title, details.toString(), proc);
|
||||
transaction.getEntityManager().persist(task);
|
||||
transaction.enqueue(entity.getHiveName(), task);
|
||||
log.debug("processor queued");
|
||||
}
|
||||
|
||||
public String toString(StackTraceElement[] stackTrace) {
|
||||
StringBuilder stack = new StringBuilder();
|
||||
for (StackTraceElement e : stackTrace)
|
||||
stack.append(e.getFileName() + ":" + e.getLineNumber() + "\n");
|
||||
return stack.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* determines if the login user is a hostmaster.
|
||||
* @return
|
||||
*/
|
||||
public boolean isHostmaster() {
|
||||
// TODO: dummy
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setQueryParameter(Query query, String queryString,
|
||||
String argName, Object argValue) {
|
||||
int argLen = argName.length();
|
||||
int iMax = queryString.length();
|
||||
int i = 0;
|
||||
while ((i = queryString.indexOf(argName, i)) >= 0) {
|
||||
if ((i + argLen) >= iMax || queryString.charAt(i + argLen) < 'A') {
|
||||
query.setParameter(argName, argValue);
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
public class AuthenticationException extends HSAdminException {
|
||||
|
||||
private static final long serialVersionUID = 6242824365822822456L;
|
||||
|
||||
public AuthenticationException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public AuthenticationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
public class AuthorisationException extends HSAdminException {
|
||||
|
||||
private static final long serialVersionUID = -8125905071037488732L;
|
||||
|
||||
private UnixUser user;
|
||||
private String method;
|
||||
private Entity entity;
|
||||
private String field;
|
||||
|
||||
public UnixUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public AuthorisationException(UnixUser user, String method) {
|
||||
super("nicht authorisiert fuer " + method + "()");
|
||||
|
||||
this.user = user;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public AuthorisationException(UnixUser user, String method, Entity entity) {
|
||||
super("nicht authorisiert fuer " + method + "("
|
||||
+ entity.createStringKey() + ")");
|
||||
|
||||
this.user = user;
|
||||
this.method = method;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public AuthorisationException(UnixUser user, String method, Entity entity,
|
||||
String field) {
|
||||
super("nicht authorisiert fuer " + method + "("
|
||||
+ entity.createStringKey() + "." + field + ")");
|
||||
|
||||
this.user = user;
|
||||
this.method = method;
|
||||
this.entity = entity;
|
||||
this.field = field;
|
||||
}
|
||||
}
|
249
hsarback/src/de/hsadmin/core/model/Entity.java
Normal file
249
hsarback/src/de/hsadmin/core/model/Entity.java
Normal file
@ -0,0 +1,249 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
public abstract class Entity {
|
||||
|
||||
/**
|
||||
* trims whitespace from both ends, but a null remains null.
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static String trim(String field) {
|
||||
if (field == null)
|
||||
return field;
|
||||
return field.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* trims whitespace from both ends, returns null for a resulting empty
|
||||
* string or null.
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static String trimToNull(String field) {
|
||||
if (field == null)
|
||||
return field;
|
||||
field = field.trim();
|
||||
if (field.length() == 0)
|
||||
return null;
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* trims whitespace from both ends, returns an empty string for null
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static String trimToEmpty(String field) {
|
||||
if (field == null)
|
||||
return "";
|
||||
field = field.trim();
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JPA-QL query string from a human readable string representing a
|
||||
* key.
|
||||
*
|
||||
* Such a static method is to be implemented by every entity class which has
|
||||
* a human readable key different from "id".
|
||||
*
|
||||
* @param humanKey
|
||||
* A human readable key representing the entity. E.g.
|
||||
* "info@example.com" for an E-Mail-Address.
|
||||
*
|
||||
* @return jpaQLQuery the matching JPA-QL query
|
||||
*/
|
||||
public static String createQueryFromStringKey(String humanKey) throws HSAdminException {
|
||||
return "id=" + humanKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* escapes a String so that it can be used for SQL statements
|
||||
* @param str a sting that should be usable as a String in an SQLStatement
|
||||
* @return the escapedString
|
||||
*/
|
||||
public static String escapeString(String str) {
|
||||
str = str.replaceAll("\"", "\\\"");
|
||||
str = str.replaceAll("\'", "\\'");
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the static method of the Entity subclass to get a query
|
||||
* restriction.
|
||||
*
|
||||
* @return a restricting JPA-QL expression to limit access to entities
|
||||
*/
|
||||
public static String restriction(Class<?> entityClass, UnixUser loginUser) {
|
||||
// hostmasters don't get any restriction
|
||||
if (loginUser.hasHostmasterRole())
|
||||
return null;
|
||||
|
||||
// find a static method which creates the query
|
||||
java.lang.reflect.Method method = null;
|
||||
try {
|
||||
method = entityClass.getDeclaredMethod("restriction");
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException(
|
||||
"unexpected SecurityException in restriction()");
|
||||
} catch (NoSuchMethodException e) {
|
||||
// don't grant any access
|
||||
return "FALSE";
|
||||
}
|
||||
|
||||
// get the restriction from a static method of the Entity class
|
||||
String restriction = "FALSE";
|
||||
try {
|
||||
restriction = (String) method.invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"unexpected Exception in Entity-restriction() implementation");
|
||||
}
|
||||
return restriction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable string representing a key to this entity.
|
||||
*
|
||||
* @return humanReadableString A human readable string which can be used as
|
||||
* a key to this entity. This string can also be used with the
|
||||
* static method createQueryFromStringKey which has to be supported
|
||||
* by all entity
|
||||
*/
|
||||
public abstract String createStringKey();
|
||||
|
||||
/**
|
||||
* returns true if entity is not yet stored to the database, false otherwise.
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean isNew();
|
||||
|
||||
/**
|
||||
* returns the unique database if
|
||||
*/
|
||||
public abstract long id();
|
||||
|
||||
/**
|
||||
* returns true if the argument entity has the same database id
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public boolean sameIdAs(Entity entity) {
|
||||
if (entity == null)
|
||||
return false;
|
||||
if (getClass() != entity.getClass())
|
||||
return false;
|
||||
return id() == entity.id();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if entity is not yet stored to the database, false otherwise.
|
||||
* @return
|
||||
*/
|
||||
@javax.persistence.Transient
|
||||
public boolean getNew() {
|
||||
return isNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a newly created entity.
|
||||
*
|
||||
* This method makes it possible to initialize fields of entities using the
|
||||
* login user and database access.
|
||||
* @param em
|
||||
* @param loginUser
|
||||
*/
|
||||
public void initialize(EntityManager em, UnixUser loginUser) {
|
||||
}
|
||||
|
||||
/**
|
||||
* completes the (new) entity before it gets stored to the database
|
||||
* @param em
|
||||
* @param loginUser
|
||||
*/
|
||||
public void complete(EntityManager em, UnixUser loginUser) {
|
||||
}
|
||||
|
||||
/**
|
||||
* merges this entity with the database, keeping transient members which are
|
||||
* otherwise nulled.
|
||||
*
|
||||
* Usually subclasses load the attached entity with same id and update all
|
||||
* fields to which the login user has access, but no other fields. Then the
|
||||
* attached entity is returned instead of this entity.
|
||||
* @param em
|
||||
* @param loginUser
|
||||
*/
|
||||
public Entity merge(EntityManager em, UnixUser loginUser) {
|
||||
return em.merge(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether the given user has full read access on all merged
|
||||
* fields of this entity
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
public boolean isReadAllowedFor(UnixUser loginUser) {
|
||||
return loginUser.hasHostmasterRole();
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether the given user has full write access on all merged
|
||||
* fields of this entity
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
public boolean isWriteAllowedFor(UnixUser loginUser) {
|
||||
return loginUser.hasHostmasterRole();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the hive name in which this entity resists or null if entity
|
||||
* is new or does not need a hive.
|
||||
* @return
|
||||
*/
|
||||
public String getHiveName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the UnixUser who owns this entity (and thus has broad access to it
|
||||
* @param em
|
||||
* @return
|
||||
*/
|
||||
public abstract UnixUser owningUser(EntityManager em);
|
||||
|
||||
/**
|
||||
* Clonable::clone did result in javasisst errors (duplicate method) since
|
||||
* JBoss 5.1.
|
||||
* This is just for testing, it does not use the proper class loader!
|
||||
*/
|
||||
public <T extends Entity> T replicate() {
|
||||
try {
|
||||
ByteArrayOutputStream baOut = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oOut = new ObjectOutputStream(baOut);
|
||||
oOut.writeObject(this);
|
||||
byte[] buffer = baOut.toByteArray();
|
||||
|
||||
ByteArrayInputStream baIn = new ByteArrayInputStream(buffer);
|
||||
ObjectInputStream oIn = new ObjectInputStream(baIn);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T clone = (T) oIn.readObject();
|
||||
return clone;
|
||||
} catch (Exception exc) {
|
||||
throw new RuntimeException(exc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
12
hsarback/src/de/hsadmin/core/model/EntityInfo.java
Normal file
12
hsarback/src/de/hsadmin/core/model/EntityInfo.java
Normal file
@ -0,0 +1,12 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(value=RetentionPolicy.RUNTIME)
|
||||
public @interface EntityInfo
|
||||
{
|
||||
/// human readable identifier of the entity
|
||||
String name();
|
||||
|
||||
}
|
41
hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java
Normal file
41
hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java
Normal file
@ -0,0 +1,41 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class EntitySessionHelper {
|
||||
|
||||
private static Log log = LogFactory.getLog(EntitySessionHelper.class);
|
||||
|
||||
/**
|
||||
* helper method to create a wrapper for checking the rights according to
|
||||
* the entity class.
|
||||
* @param entityClass
|
||||
* @return
|
||||
*/
|
||||
public static AbstractModuleImpl createEntitySessionWrapper(Class<? extends Entity> entityClass) {
|
||||
// get in instance
|
||||
AbstractModuleImpl impl = null;
|
||||
try {
|
||||
// determine wrapper class
|
||||
ModuleImpl wrapperAnnot = entityClass.getAnnotation(ModuleImpl.class);
|
||||
Class<?> wrapperClass = null;
|
||||
if (wrapperAnnot != null) {
|
||||
wrapperClass = wrapperAnnot.value();
|
||||
} else {
|
||||
wrapperClass = Class.forName(entityClass.getCanonicalName() + "ModuleImpl");
|
||||
}
|
||||
// instantiate wrapper
|
||||
impl = (AbstractModuleImpl) wrapperClass.newInstance();
|
||||
} catch (ClassNotFoundException exc) {
|
||||
log.info("entity class '"
|
||||
+ entityClass.getCanonicalName()
|
||||
+ "' has no session wrapper => using restrictive default access rights");
|
||||
impl = new SecureDefaultModuleImpl();
|
||||
} catch (Exception exc) {
|
||||
throw new RuntimeException(exc);
|
||||
}
|
||||
return impl;
|
||||
}
|
||||
|
||||
}
|
99
hsarback/src/de/hsadmin/core/model/GenericModuleImpl.java
Normal file
99
hsarback/src/de/hsadmin/core/model/GenericModuleImpl.java
Normal file
@ -0,0 +1,99 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class GenericModuleImpl implements ModuleInterface {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GenericModuleImpl.class);
|
||||
|
||||
private Transaction tx;
|
||||
|
||||
public GenericModuleImpl(Transaction transaction) {
|
||||
tx = transaction;
|
||||
}
|
||||
|
||||
public Transaction getTransaction() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity initialize(Entity newEntity) throws HSAdminException {
|
||||
log.trace("initialize(" + newEntity + ")");
|
||||
AbstractModuleImpl wrapper =
|
||||
EntitySessionHelper.createEntitySessionWrapper(newEntity.getClass());
|
||||
wrapper.construct(tx);
|
||||
return wrapper.initialize(newEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity add(Entity newEntity) throws HSAdminException {
|
||||
if (!newEntity.isNew())
|
||||
throw new HSAdminException("cannot add an already persistent entity");
|
||||
log.trace("add(" + newEntity + ")");
|
||||
AbstractModuleImpl wrapper =
|
||||
EntitySessionHelper.createEntitySessionWrapper(newEntity.getClass());
|
||||
wrapper.construct(tx);
|
||||
Entity result = null;
|
||||
try {
|
||||
result = wrapper.add(newEntity);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new HSAdminException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity find(Class<? extends Entity> entityClass, Object key) throws HSAdminException {
|
||||
log.trace("find(" + entityClass + ", " + key + ")");
|
||||
AbstractModuleImpl wrapper = EntitySessionHelper.createEntitySessionWrapper(entityClass);
|
||||
wrapper.construct(tx);
|
||||
return wrapper.find(entityClass, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity findByString(Class<? extends Entity> entityClass, String key) throws HSAdminException {
|
||||
log.trace("find(" + entityClass + ", " + key + ")");
|
||||
AbstractModuleImpl wrapper = EntitySessionHelper.createEntitySessionWrapper(entityClass);
|
||||
wrapper.construct(tx);
|
||||
return wrapper.findByString(entityClass, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String condition, String orderBy) throws HSAdminException {
|
||||
log.trace("search(" + entityClass + ", " + condition + ")");
|
||||
AbstractModuleImpl wrapper = EntitySessionHelper.createEntitySessionWrapper(entityClass);
|
||||
wrapper.construct(tx);
|
||||
return wrapper.search(entityClass, condition, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity update(Entity existingEntity) throws HSAdminException {
|
||||
if (existingEntity.isNew())
|
||||
return add(existingEntity);
|
||||
log.debug("update(" + existingEntity + ")");
|
||||
AbstractModuleImpl wrapper = EntitySessionHelper.createEntitySessionWrapper(existingEntity.getClass());
|
||||
wrapper.construct(tx);
|
||||
try {
|
||||
return wrapper.update(existingEntity);
|
||||
} catch (Exception e) {
|
||||
throw new HSAdminException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Entity existingEntity) throws HSAdminException {
|
||||
log.trace("delete(" + existingEntity + ")");
|
||||
AbstractModuleImpl wrapper =
|
||||
EntitySessionHelper.createEntitySessionWrapper(existingEntity.getClass());
|
||||
wrapper.construct(tx);
|
||||
try {
|
||||
wrapper.delete(existingEntity);
|
||||
} catch (Exception e) {
|
||||
throw new HSAdminException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
hsarback/src/de/hsadmin/core/model/HSAdminException.java
Normal file
19
hsarback/src/de/hsadmin/core/model/HSAdminException.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
public class HSAdminException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -5082179267383474532L;
|
||||
|
||||
public HSAdminException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HSAdminException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public HSAdminException(String message, Exception aExc) {
|
||||
super(message, aExc);
|
||||
}
|
||||
|
||||
}
|
10
hsarback/src/de/hsadmin/core/model/ModuleImpl.java
Normal file
10
hsarback/src/de/hsadmin/core/model/ModuleImpl.java
Normal file
@ -0,0 +1,10 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ModuleImpl
|
||||
{
|
||||
Class<?> value();
|
||||
}
|
50
hsarback/src/de/hsadmin/core/model/ModuleInterface.java
Normal file
50
hsarback/src/de/hsadmin/core/model/ModuleInterface.java
Normal file
@ -0,0 +1,50 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a CRUD (Create, Retrieve, Update, Delete) interface for generic
|
||||
* entity instances.
|
||||
* @author peter
|
||||
*/
|
||||
public interface ModuleInterface {
|
||||
|
||||
public Transaction getTransaction();
|
||||
|
||||
/**
|
||||
* initializes a newly created entity.
|
||||
*/
|
||||
public Entity initialize(Entity newEntity) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Adds a new entity instance to the model.
|
||||
*/
|
||||
public Entity add(Entity newEntity) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Finds an entity instance in the model, using its primary key.
|
||||
*/
|
||||
public Entity find(Class<? extends Entity> entityClass, Object key) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Finds an entity instance in the model, using its primary key in a String
|
||||
* representation.
|
||||
*/
|
||||
public Entity findByString(Class<? extends Entity> entityClass, String key) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Searches entity instances in the model, using a simplified JPA-QL query.
|
||||
*/
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String query, String orderBy) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Updates an existing entity in the model.
|
||||
*/
|
||||
public Entity update(Entity existingEntity) throws HSAdminException;
|
||||
|
||||
/**
|
||||
* Deletes an existing entity from the model.
|
||||
*/
|
||||
public void delete(Entity existingEntity) throws HSAdminException;
|
||||
|
||||
}
|
12
hsarback/src/de/hsadmin/core/model/SearchFilter.java
Normal file
12
hsarback/src/de/hsadmin/core/model/SearchFilter.java
Normal file
@ -0,0 +1,12 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/// specifies pre-filters (JPAQL) for several roles
|
||||
@Retention(value=RetentionPolicy.RUNTIME)
|
||||
public @interface SearchFilter
|
||||
{
|
||||
/// an additional JPA condition to add to the WHERE clause
|
||||
String value();
|
||||
}
|
105
hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java
Normal file
105
hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java
Normal file
@ -0,0 +1,105 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* allows access only for hostmasters, used as fallback wrapper.
|
||||
*/
|
||||
public class SecureDefaultModuleImpl extends AbstractModuleImpl {
|
||||
|
||||
private static final long serialVersionUID = 4567381515459292565L;
|
||||
|
||||
@Override
|
||||
public Entity initialize(Entity newEntity) throws AuthorisationException {
|
||||
return super.initialize(newEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity find(Class<? extends Entity> entityClass, Object key) throws HSAdminException {
|
||||
Entity entity = super.find(entityClass, key);
|
||||
if (entity != null && !entity.isReadAllowedFor(getLoginUser()))
|
||||
throw new AuthorisationException(getLoginUser(), "find");
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity findByString(Class<? extends Entity> entityClass, String key) throws HSAdminException {
|
||||
Entity entity = super.findByString(entityClass, key);
|
||||
if (entity != null && !entity.isReadAllowedFor(getLoginUser()))
|
||||
throw new AuthorisationException(getLoginUser(), "findByString");
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String condition, String orderBy)
|
||||
throws HSAdminException {
|
||||
// restrict query to entities where the loginUser could have rights on
|
||||
SearchFilter filterAnnot;
|
||||
if (!getLoginUser().hasHostmasterRole()
|
||||
&& (filterAnnot = getSecurityFilterAnnotation(entityClass)) != null) {
|
||||
String securityCondition = filterAnnot.value();
|
||||
if (condition != null && condition.length() > 0)
|
||||
condition = "(" + condition + ")" + " AND ( "
|
||||
+ securityCondition + ")";
|
||||
else
|
||||
condition = securityCondition;
|
||||
}
|
||||
|
||||
// do query
|
||||
List<Entity> res = super.search(entityClass, condition, orderBy);
|
||||
List<Entity> ret = new LinkedList<Entity>();
|
||||
|
||||
// remove entities where login user has no access rights
|
||||
if (res != null) {
|
||||
for (Entity entity : res) {
|
||||
Entity returnedEntity = entity;
|
||||
if (returnedEntity.isReadAllowedFor(getLoginUser()))
|
||||
ret.add(returnedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// return clean result
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
// helper method to get annotation from class or superclass
|
||||
private SearchFilter getSecurityFilterAnnotation(Class<?> entityClass) {
|
||||
SearchFilter ret;
|
||||
while (entityClass != null) {
|
||||
ret = (SearchFilter) entityClass.getAnnotation(SearchFilter.class);
|
||||
if (ret != null)
|
||||
return ret;
|
||||
entityClass = entityClass.getSuperclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity add(Entity newEntity) throws HSAdminException {
|
||||
// access rights checking is done by base class
|
||||
return super.add(newEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity update(Entity existingEntity) throws HSAdminException {
|
||||
// access rights checking is done by base class
|
||||
return super.update(existingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Entity detachedEntity) throws HSAdminException {
|
||||
// get the entity from the database
|
||||
Entity attachedEntity = getTransaction().getEntityManager().find(detachedEntity.getClass(),
|
||||
detachedEntity.id());
|
||||
|
||||
// does the login user have the right to delete?
|
||||
if (!attachedEntity.isWriteAllowedFor(getLoginUser()))
|
||||
throw new AuthorisationException(getLoginUser(), "delete",
|
||||
detachedEntity);
|
||||
|
||||
super.delete(attachedEntity);
|
||||
}
|
||||
|
||||
}
|
17
hsarback/src/de/hsadmin/core/model/TicketAuthentication.java
Normal file
17
hsarback/src/de/hsadmin/core/model/TicketAuthentication.java
Normal file
@ -0,0 +1,17 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import de.hsadmin.core.model.onetier.TicketValidator;
|
||||
|
||||
public class TicketAuthentication {
|
||||
|
||||
private static TicketAuthentication auth = new TicketAuthentication();
|
||||
|
||||
public static TicketAuthentication getInstance() {
|
||||
return auth;
|
||||
}
|
||||
|
||||
public boolean login(String login, String ticket) throws AuthenticationException {
|
||||
return TicketValidator.getInstance().validateTicket(login, ticket);
|
||||
}
|
||||
|
||||
}
|
179
hsarback/src/de/hsadmin/core/model/Transaction.java
Normal file
179
hsarback/src/de/hsadmin/core/model/Transaction.java
Normal file
@ -0,0 +1,179 @@
|
||||
package de.hsadmin.core.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.QueueConnectionFactory;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
//import org.hibernate.Session;
|
||||
|
||||
import de.hsadmin.cliClientConnector.TechnicalException;
|
||||
import de.hsadmin.core.model.onetier.PersistenceManager;
|
||||
import de.hsadmin.core.qserv.QueueClient;
|
||||
import de.hsadmin.core.qserv.QueueTask;
|
||||
|
||||
public class Transaction {
|
||||
|
||||
private static final Log log = LogFactory.getLog(Transaction.class);
|
||||
|
||||
private EntityManager entityManager;
|
||||
private QueueConnectionFactory queueConnectionFactory;
|
||||
private String loginName;
|
||||
private Map<String, QueueTaskStore> taskStores;
|
||||
private boolean transactionActive;
|
||||
private InitialContext ctx;
|
||||
|
||||
public Transaction(String loginName) {
|
||||
transactionActive = false;
|
||||
this.entityManager = PersistenceManager.getEntityManager("hsadmin");
|
||||
this.loginName = loginName;
|
||||
taskStores = new HashMap<String, QueueTaskStore>();
|
||||
try {
|
||||
ctx = new InitialContext();
|
||||
Context env = (Context) ctx.lookup("java:comp/env");
|
||||
queueConnectionFactory = (QueueConnectionFactory) env.lookup("jms/QueueCF");
|
||||
} catch (NamingException e) {
|
||||
log.fatal(e);
|
||||
e.printStackTrace();
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
return entityManager;
|
||||
}
|
||||
|
||||
public QueueConnectionFactory getQueueConnectionFactory() {
|
||||
return queueConnectionFactory;
|
||||
}
|
||||
|
||||
public Queue lookupJMSQueue(String queueName) {
|
||||
if (ctx != null) {
|
||||
try {
|
||||
Context env = (Context) ctx.lookup("java:comp/env");
|
||||
return (Queue) env.lookup("jms/" + queueName);
|
||||
} catch (NamingException e) {
|
||||
log.fatal(e);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLoginName() {
|
||||
if (loginName != null) return loginName;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void enqueue(String hiveName, QueueTask task) {
|
||||
QueueTaskStore taskStore = taskStores.get(hiveName);
|
||||
if (taskStore == null) {
|
||||
taskStore = new QueueTaskStore();
|
||||
taskStores.put(hiveName, taskStore);
|
||||
}
|
||||
taskStore.add(task);
|
||||
}
|
||||
|
||||
private void sendAll(EntityTransaction transaction) {
|
||||
boolean firstHive = true;
|
||||
for (String hive : taskStores.keySet()) {
|
||||
QueueTaskStore store = taskStores.get(hive);
|
||||
String queueName = "hsadminSystem-" + hive;
|
||||
Queue jmsSystemQueue = lookupJMSQueue(queueName);
|
||||
QueueClient qClient = null;
|
||||
try {
|
||||
qClient = new QueueClient(queueConnectionFactory, jmsSystemQueue);
|
||||
if (firstHive) {
|
||||
firstHive = false;
|
||||
transaction.commit();
|
||||
}
|
||||
for (QueueTask task : store.getTasks()) {
|
||||
qClient.send(task);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new TechnicalException(e);
|
||||
} finally {
|
||||
store.clear();
|
||||
if (qClient != null) qClient.close();
|
||||
}
|
||||
}
|
||||
if (firstHive) {
|
||||
try {
|
||||
transaction.commit();
|
||||
} catch (Exception e) {
|
||||
throw new TechnicalException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beginTransaction() {
|
||||
transactionActive = true;
|
||||
entityManager.getTransaction().begin();
|
||||
}
|
||||
|
||||
public void commitTransaction() {
|
||||
sendAll(entityManager.getTransaction());
|
||||
transactionActive = false;
|
||||
}
|
||||
|
||||
public void rollbackTransaction() {
|
||||
taskStores.clear();
|
||||
transactionActive = false;
|
||||
try {
|
||||
entityManager.getTransaction().rollback();
|
||||
} catch (IllegalStateException e) {
|
||||
log.info(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (transactionActive) {
|
||||
rollbackTransaction();
|
||||
}
|
||||
entityManager.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach entities from hibernate session.
|
||||
* Used to detach entities before update. Makes it possible to compare
|
||||
* old and new attribute values.
|
||||
*/
|
||||
public void detach(Entity entity) {
|
||||
// TODO: replace hibernate specific implmentation
|
||||
// org.hibernate.Session hSession = (Session) entityManager.getDelegate();
|
||||
// hSession.evict(entity);
|
||||
if (entityManager instanceof OpenJPAEntityManager) {
|
||||
OpenJPAEntityManager openjpaEM = (OpenJPAEntityManager) entityManager;
|
||||
openjpaEM.detach(entity);
|
||||
}
|
||||
}
|
||||
|
||||
class QueueTaskStore {
|
||||
private List<QueueTask> taskList;
|
||||
QueueTaskStore() {
|
||||
taskList = new ArrayList<QueueTask>();
|
||||
}
|
||||
public void clear() {
|
||||
taskList = new ArrayList<QueueTask>();
|
||||
}
|
||||
void add(QueueTask t) {
|
||||
taskList.add(t);
|
||||
}
|
||||
Iterable<QueueTask> getTasks() {
|
||||
return taskList;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package de.hsadmin.core.model.onetier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
public class PersistenceManager {
|
||||
|
||||
private static PersistenceManager instance;
|
||||
|
||||
private Map<String, EntityManagerFactory> persistenceUnits;
|
||||
|
||||
private PersistenceManager() {
|
||||
persistenceUnits = new HashMap<String, EntityManagerFactory>();
|
||||
}
|
||||
|
||||
private EntityManagerFactory getEMF(String persistUnitName) {
|
||||
EntityManagerFactory emf = persistenceUnits.get(persistUnitName);
|
||||
if (emf == null) {
|
||||
emf = Persistence.createEntityManagerFactory(persistUnitName);
|
||||
persistenceUnits.put(persistUnitName, emf);
|
||||
}
|
||||
return emf;
|
||||
}
|
||||
|
||||
public static EntityManager getEntityManager(String persistUnitName) {
|
||||
PersistenceManager pm = PersistenceManager.getInstance();
|
||||
EntityManagerFactory emf = pm.getEMF(persistUnitName);
|
||||
return emf.createEntityManager();
|
||||
}
|
||||
|
||||
private static PersistenceManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new PersistenceManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package de.hsadmin.core.model.onetier;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import de.hsadmin.core.model.AuthenticationException;
|
||||
|
||||
public class TicketValidator {
|
||||
|
||||
private static final Log log = LogFactory.getLog(TicketValidator.class);
|
||||
|
||||
private static TicketValidator instance;
|
||||
|
||||
private String proxyValidateURL;
|
||||
private String proxyServiceURL;
|
||||
|
||||
private TicketValidator() {
|
||||
proxyServiceURL = null;
|
||||
proxyValidateURL = null;
|
||||
}
|
||||
|
||||
public static TicketValidator getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new TicketValidator();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void initialize(String validateURL, String serviceURL) {
|
||||
proxyServiceURL = serviceURL;
|
||||
proxyValidateURL = validateURL;
|
||||
}
|
||||
|
||||
public boolean validateTicket(String runAsUser, String ticket) throws AuthenticationException {
|
||||
String ticketUser = validateTicket(ticket);
|
||||
if (runAsUser != null &&
|
||||
(runAsUser.equals(ticketUser) // user himself
|
||||
|| (ticketUser.length() == 5 && runAsUser.startsWith(ticketUser))
|
||||
// pac-admin
|
||||
|| ticketUser.length() == 2) // hostmaster
|
||||
// TODO: add test for member-account
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
throw new AuthenticationException("User " + ticketUser + " is not allowed to run as " + runAsUser);
|
||||
}
|
||||
}
|
||||
|
||||
public String validateTicket(String ticket) throws AuthenticationException {
|
||||
if (proxyServiceURL == null || proxyServiceURL == null) {
|
||||
log.fatal("TicketValidator is not initialized.");
|
||||
throw new RuntimeException("TicketValidator is not initialized.");
|
||||
}
|
||||
try {
|
||||
URL url = new URL(proxyValidateURL + "?service=" + proxyServiceURL + "&ticket=" + ticket);
|
||||
URLConnection httpConnection = url.openConnection();
|
||||
httpConnection.connect();
|
||||
InputStream inputStream = httpConnection.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String nextLine = reader.readLine();
|
||||
while (nextLine != null) {
|
||||
if (nextLine.contains("<cas:user>")) {
|
||||
String user = extractUser(nextLine);
|
||||
inputStream.close();
|
||||
return user;
|
||||
}
|
||||
nextLine = reader.readLine();
|
||||
}
|
||||
inputStream.close();
|
||||
log.debug("Ticket validation failed: " + ticket);
|
||||
throw new AuthenticationException("Invalid Ticket: " + ticket);
|
||||
} catch (MalformedURLException e) {
|
||||
log.fatal(e);
|
||||
throw new AuthenticationException(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.fatal(e);
|
||||
throw new AuthenticationException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String extractUser(String nextLine) {
|
||||
int start = nextLine.indexOf("<cas:user>");
|
||||
int end = nextLine.indexOf("</cas:user>");
|
||||
String user = nextLine.substring(start + 10, end);
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
17
hsarback/src/de/hsadmin/core/qserv/AbstractProcessor.java
Normal file
17
hsarback/src/de/hsadmin/core/qserv/AbstractProcessor.java
Normal file
@ -0,0 +1,17 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
|
||||
abstract public class AbstractProcessor implements Processor {
|
||||
|
||||
private static final long serialVersionUID = -2401718681212973276L;
|
||||
|
||||
@Override
|
||||
abstract public Object process() throws ProcessorException;
|
||||
|
||||
@Override
|
||||
public void finalize(Transaction transaction, QueueTask task) throws ProcessorException {
|
||||
task.done();
|
||||
}
|
||||
|
||||
}
|
162
hsarback/src/de/hsadmin/core/qserv/CommandShell.java
Normal file
162
hsarback/src/de/hsadmin/core/qserv/CommandShell.java
Normal file
@ -0,0 +1,162 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class CommandShell
|
||||
{
|
||||
private static boolean bExecute = true; // really execute or just store command and stdin?
|
||||
private static String executedCommands; // stored command and stdin
|
||||
private static String[] aEnvironment; // stored environment
|
||||
|
||||
/** Set mode of real execution or just storing the command and stdin.
|
||||
*
|
||||
* @param bExec
|
||||
* specifies whether shell commands should really be executed (true) or not (false)
|
||||
*/
|
||||
public static void setExecute( boolean bExec )
|
||||
{
|
||||
bExecute = bExec;
|
||||
}
|
||||
|
||||
/** Returns and clears the last command which should have been executed.
|
||||
*
|
||||
* @return
|
||||
* Last command, plus "<<EOF\n" + stdin + "EOF" if stdin was given.
|
||||
*/
|
||||
public static String popLastCommand()
|
||||
{
|
||||
String aLastCommand = executedCommands;
|
||||
executedCommands = null;
|
||||
return aLastCommand != null ? aLastCommand.trim() : null;
|
||||
}
|
||||
|
||||
/** Returns and clears the environment which ist currently used for commands.
|
||||
*
|
||||
* @return
|
||||
* Most recent command environment.
|
||||
*/
|
||||
public static String[] popEnvironment()
|
||||
{
|
||||
String[] aLastEnvironment = aEnvironment;
|
||||
aEnvironment = null;
|
||||
return aLastEnvironment;
|
||||
}
|
||||
|
||||
public static void setEnvironment( String[] env )
|
||||
{
|
||||
aEnvironment = env;
|
||||
}
|
||||
|
||||
/** Execute the given command by a shell.
|
||||
*
|
||||
* @throws ShellException
|
||||
* if an execution error has occured.
|
||||
*/
|
||||
public static String execute( String command )
|
||||
throws ShellException
|
||||
{
|
||||
return execute( command, null );
|
||||
}
|
||||
|
||||
/** Execute the given command by a shell including stdin.
|
||||
*
|
||||
* @throws ShellException
|
||||
* if an execution error has occured.
|
||||
*/
|
||||
public static String execute( String command, String stdInput )
|
||||
throws ShellException
|
||||
{
|
||||
Process backend = null;
|
||||
String callOutput = null;
|
||||
int exitCode = 0;
|
||||
try
|
||||
{
|
||||
String logCommand = command;
|
||||
if ( stdInput != null ) //&& stdInput.length() > 0 )
|
||||
logCommand += "<<EOF\n" + stdInput + "EOF";
|
||||
logCommand += "\n";
|
||||
|
||||
// add to command buffer (used in tests)
|
||||
if ( executedCommands == null )
|
||||
executedCommands = logCommand;
|
||||
else
|
||||
executedCommands += logCommand;
|
||||
|
||||
if ( bExecute )
|
||||
{
|
||||
// TODO logging
|
||||
System.out.println("--- shell command: ---" );
|
||||
System.out.println( logCommand );
|
||||
|
||||
|
||||
String[] cmdArray = { "/bin/bash", "-c", command };
|
||||
backend = Runtime.getRuntime().exec(cmdArray, aEnvironment);
|
||||
if ( stdInput != null )
|
||||
{
|
||||
OutputStream stdInputStream = backend.getOutputStream();
|
||||
PrintWriter stdInputWriter = new PrintWriter(stdInputStream);
|
||||
stdInputWriter.print(stdInput);
|
||||
stdInputWriter.close();
|
||||
stdInputStream.close();
|
||||
}
|
||||
callOutput = readProcessStream(backend.getInputStream());
|
||||
exitCode = backend.waitFor();
|
||||
|
||||
// TODO logging
|
||||
System.out.println( "RET: " + exitCode );
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
String aErr = readProcessStream(backend.getErrorStream());
|
||||
|
||||
// TODO logging
|
||||
System.out.println( "ERR: " + aErr );
|
||||
System.out.println("--- done. ---" );
|
||||
|
||||
throw new ShellException( exitCode, aErr );
|
||||
}
|
||||
|
||||
// TODO logging
|
||||
System.out.println("--- done. ---" );
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ShellException();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new ShellException();
|
||||
}
|
||||
|
||||
if ( callOutput != null )
|
||||
{
|
||||
// int nLen = callOutput.length();
|
||||
// if ( nLen > 0 && callOutput.charAt(nLen-1) == '\n' )
|
||||
// callOutput = callOutput.substring(0, nLen-1);
|
||||
return callOutput.trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String readProcessStream(InputStream stream) throws IOException
|
||||
{
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(stream));
|
||||
StringBuffer textBuff = new StringBuffer();
|
||||
String textLine = reader.readLine();
|
||||
while (textLine != null)
|
||||
{
|
||||
textBuff.append(textLine);
|
||||
textBuff.append('\n');
|
||||
textLine = reader.readLine();
|
||||
}
|
||||
reader.close();
|
||||
return textBuff.toString();
|
||||
}
|
||||
}
|
30
hsarback/src/de/hsadmin/core/qserv/CompoundProcessor.java
Normal file
30
hsarback/src/de/hsadmin/core/qserv/CompoundProcessor.java
Normal file
@ -0,0 +1,30 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CompoundProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = 5718623579674305929L;
|
||||
|
||||
private List<Processor> aProcessors;
|
||||
|
||||
public CompoundProcessor(Processor... aProcessor) {
|
||||
aProcessors = new ArrayList<Processor>();
|
||||
for (Processor aP : aProcessor) {
|
||||
aProcessors.add(aP);
|
||||
}
|
||||
}
|
||||
|
||||
public Object process() throws ProcessorException {
|
||||
for (Processor aProcessor : aProcessors) {
|
||||
aProcessor.process();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void appendProcessor(Processor aProcessor) {
|
||||
aProcessors.add(aProcessor);
|
||||
}
|
||||
|
||||
}
|
22
hsarback/src/de/hsadmin/core/qserv/CopyFileProcessor.java
Normal file
22
hsarback/src/de/hsadmin/core/qserv/CopyFileProcessor.java
Normal file
@ -0,0 +1,22 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
public class CopyFileProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = 1741419610410712714L;
|
||||
|
||||
private Processor internal;
|
||||
|
||||
public CopyFileProcessor(String source, String target, String owner, String group, String modeMask) {
|
||||
internal = new ShellProcessor(
|
||||
"cp " + source + " " + target + " && " +
|
||||
"chown " + owner + ":" + group + " " + target + " && " +
|
||||
"chmod " + modeMask + " " + target
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process() throws ProcessorException {
|
||||
return internal.process();
|
||||
}
|
||||
|
||||
}
|
25
hsarback/src/de/hsadmin/core/qserv/CreateFileProcessor.java
Normal file
25
hsarback/src/de/hsadmin/core/qserv/CreateFileProcessor.java
Normal file
@ -0,0 +1,25 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateFileProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = -2947609532975712444L;
|
||||
|
||||
private CompoundProcessor compoundProcessor;
|
||||
|
||||
public CreateFileProcessor(String templateName, Map<String, String> templateValues, String targetPath, String owner, String group, String modeMask) throws ProcessorException {
|
||||
TemplateProcessor templateProcessor = new TemplateProcessor(templateName, templateValues, targetPath, false);
|
||||
ShellProcessor shellProcessor =
|
||||
new ShellProcessor(
|
||||
"chown " + owner + ":" + group + " " + targetPath + " && " +
|
||||
"chmod " + modeMask + " " + targetPath);
|
||||
compoundProcessor = new CompoundProcessor(templateProcessor, shellProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process() throws ProcessorException {
|
||||
return compoundProcessor.process();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
|
||||
/**
|
||||
* Most processor factories need only these methods.
|
||||
*
|
||||
* @author peter
|
||||
*/
|
||||
public interface EntityProcessorFactory {
|
||||
public <T extends Entity> Processor createCreateProcessor(EntityManager em,
|
||||
T entity) throws ProcessorException;
|
||||
|
||||
public <T extends Entity> Processor createUpdateProcessor(EntityManager em,
|
||||
T newEntity) throws ProcessorException;
|
||||
|
||||
public <T extends Entity> Processor createDeleteProcessor(EntityManager em,
|
||||
T entity) throws ProcessorException;
|
||||
|
||||
}
|
89
hsarback/src/de/hsadmin/core/qserv/JDBCProcessor.java
Normal file
89
hsarback/src/de/hsadmin/core/qserv/JDBCProcessor.java
Normal file
@ -0,0 +1,89 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.hsadmin.core.qserv.AbstractProcessor;
|
||||
import de.hsadmin.core.qserv.ProcessorException;
|
||||
import de.hsadmin.core.util.Config;
|
||||
|
||||
public class JDBCProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = 7702753017749022325L;
|
||||
|
||||
private String driver;
|
||||
private String url;
|
||||
private String user;
|
||||
private String password;
|
||||
private List<String> sql;
|
||||
|
||||
public JDBCProcessor(String driver, String url, String user, String password) {
|
||||
this.driver = driver;
|
||||
this.url = url;
|
||||
this.user = user;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public JDBCProcessor(String driver, String url) {
|
||||
this.driver = driver;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void addSQL(String sqlStatement) {
|
||||
if (sql == null)
|
||||
sql = new ArrayList<String>();
|
||||
sql.add(sqlStatement);
|
||||
}
|
||||
|
||||
public Object process() throws ProcessorException {
|
||||
Connection c = null;
|
||||
Config config = Config.getInstance();
|
||||
if ("com.mysql.jdbc.Driver".equals(driver)) {
|
||||
if (user == null)
|
||||
user = config.getProperty("mysqladmin.user", "root");
|
||||
if (password == null)
|
||||
password = config.getProperty("mysqladmin.password");
|
||||
}
|
||||
if ("org.postgresql.Driver".equals(driver)) {
|
||||
if (user == null)
|
||||
user = config.getProperty("pgsqladmin.user", "postgres");
|
||||
if (password == null)
|
||||
password = config.getProperty("pgsqladmin.password");
|
||||
}
|
||||
if (user == null || password == null) {
|
||||
throw new ProcessorException("database admin-user configuration failed");
|
||||
}
|
||||
try {
|
||||
Class.forName(driver);
|
||||
c = DriverManager.getConnection(url, user, password);
|
||||
if (c == null)
|
||||
throw new ProcessorException("cannot connect to '" + url + "'");
|
||||
Statement s = c.createStatement();
|
||||
for (String sqlStatement : sql) {
|
||||
s.addBatch(sqlStatement);
|
||||
System.out.println("SQL: " + sqlStatement);
|
||||
}
|
||||
return s.executeBatch();
|
||||
} catch (SQLException aSqlExc) {
|
||||
Exception exc = aSqlExc.getNextException();
|
||||
if (exc == null)
|
||||
exc = aSqlExc;
|
||||
System.out.println("ERR: " + exc.getMessage());
|
||||
throw new ProcessorException(aSqlExc.getMessage() + ", reason: "
|
||||
+ exc.getMessage());
|
||||
} catch (Exception aExc) {
|
||||
throw new ProcessorException(aExc.getMessage());
|
||||
} finally {
|
||||
if (c != null) {
|
||||
try {
|
||||
c.close();
|
||||
} catch (Exception exc) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
hsarback/src/de/hsadmin/core/qserv/MailerProcessor.java
Normal file
41
hsarback/src/de/hsadmin/core/qserv/MailerProcessor.java
Normal file
@ -0,0 +1,41 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class MailerProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = -8900943664576420041L;
|
||||
|
||||
private String aTo;
|
||||
private String aSubject;
|
||||
private String aBody;
|
||||
|
||||
public MailerProcessor(String aTo, String aSubject, String aBody) {
|
||||
this.aTo = aTo;
|
||||
this.aSubject = aSubject;
|
||||
this.aBody = aBody;
|
||||
}
|
||||
|
||||
public Object process() throws ProcessorException {
|
||||
Properties aProps = new Properties();
|
||||
aProps.setProperty("mail.smtp.host", "localhost");
|
||||
|
||||
Session aSess = Session.getInstance(aProps);
|
||||
MimeMessage aMsg = new MimeMessage(aSess);
|
||||
try {
|
||||
aMsg.setFrom(new InternetAddress("robot@hostsharing.net"));
|
||||
aMsg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(aTo));
|
||||
aMsg.setSubject(aSubject);
|
||||
aMsg.setText(aBody);
|
||||
MailerShell.send(aMsg);
|
||||
return null;
|
||||
} catch (MessagingException aExc) {
|
||||
throw new ProcessorException(aExc);
|
||||
}
|
||||
}
|
||||
}
|
41
hsarback/src/de/hsadmin/core/qserv/MailerShell.java
Normal file
41
hsarback/src/de/hsadmin/core/qserv/MailerShell.java
Normal file
@ -0,0 +1,41 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class MailerShell {
|
||||
|
||||
private static boolean bExecute = true; // really execute or just store
|
||||
// command and stdin?
|
||||
private static MimeMessage aMessage; // stored message
|
||||
|
||||
/**
|
||||
* Set mode of real mailer or just storing the messages for testing
|
||||
* purposes.
|
||||
*
|
||||
* @param bExec
|
||||
* specifies whether messages are really send (true) or just
|
||||
* stored (false)
|
||||
*/
|
||||
public static void setExecute(boolean bExec) {
|
||||
bExecute = bExec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns and clears the last command which should have been executed.
|
||||
*
|
||||
* @return Last command, plus "<<EOF\n" + stdin + "EOF" if stdin was given.
|
||||
*/
|
||||
public static MimeMessage popLastMessage() {
|
||||
MimeMessage aLastMessage = aMessage;
|
||||
aMessage = null;
|
||||
return aLastMessage;
|
||||
}
|
||||
|
||||
public static void send(MimeMessage aMsg) throws MessagingException {
|
||||
if (bExecute)
|
||||
javax.mail.Transport.send(aMsg);
|
||||
aMessage = aMsg;
|
||||
}
|
||||
|
||||
}
|
22
hsarback/src/de/hsadmin/core/qserv/Processor.java
Normal file
22
hsarback/src/de/hsadmin/core/qserv/Processor.java
Normal file
@ -0,0 +1,22 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
|
||||
/**
|
||||
* A Processor encapsulates some code to be prepared by a client and to be
|
||||
* executed on a server.
|
||||
*/
|
||||
public interface Processor extends Serializable {
|
||||
|
||||
/**
|
||||
* Executes the encapsulated code, optionally returning a result.
|
||||
* @return
|
||||
* @throws ProcessorException
|
||||
*/
|
||||
public abstract Object process() throws ProcessorException;
|
||||
|
||||
public abstract void finalize(Transaction transaction, QueueTask task) throws ProcessorException;
|
||||
|
||||
}
|
21
hsarback/src/de/hsadmin/core/qserv/ProcessorException.java
Normal file
21
hsarback/src/de/hsadmin/core/qserv/ProcessorException.java
Normal file
@ -0,0 +1,21 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import de.hsadmin.core.model.HSAdminException;
|
||||
|
||||
public class ProcessorException extends HSAdminException {
|
||||
|
||||
private static final long serialVersionUID = -1893688504714037106L;
|
||||
|
||||
public ProcessorException(String message, Exception aExc) {
|
||||
super(message, aExc);
|
||||
}
|
||||
|
||||
public ProcessorException(Exception aExc) {
|
||||
super(aExc);
|
||||
}
|
||||
|
||||
public ProcessorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
80
hsarback/src/de/hsadmin/core/qserv/QueueClient.java
Normal file
80
hsarback/src/de/hsadmin/core/qserv/QueueClient.java
Normal file
@ -0,0 +1,80 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.JMSSecurityException;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.QueueConnection;
|
||||
import javax.jms.QueueConnectionFactory;
|
||||
import javax.jms.QueueSender;
|
||||
import javax.jms.QueueSession;
|
||||
import javax.jms.Session;
|
||||
|
||||
import de.hsadmin.core.util.Config;
|
||||
|
||||
/**
|
||||
* An instance of this class is used to send Processor instances to the
|
||||
* QueueServer.
|
||||
*
|
||||
* @author mi
|
||||
*/
|
||||
public class QueueClient extends QueueCommons {
|
||||
|
||||
private QueueConnectionFactory jmsConnectionFactory;
|
||||
private Queue jmsSystemQueue;
|
||||
|
||||
private QueueConnection jmsConnection;
|
||||
private QueueSession jmsSession;
|
||||
private QueueSender jmsSender;
|
||||
|
||||
public QueueClient(QueueConnectionFactory jmsConFact, Queue jmsSysQueue)
|
||||
throws JMSException {
|
||||
this.jmsConnectionFactory = jmsConFact;
|
||||
this.jmsSystemQueue = jmsSysQueue;
|
||||
|
||||
Config config = Config.getInstance();
|
||||
String jmsUser = config.getProperty("hsadmin.jms.username", "hsadmin");
|
||||
String jmsPass = config.getProperty("hsadmin.jms.password", "hsadmin-pw");
|
||||
jmsConnection = jmsConnectionFactory.createQueueConnection(jmsUser, jmsPass);
|
||||
jmsSession = jmsConnection.createQueueSession(DEFAULT, Session.AUTO_ACKNOWLEDGE);
|
||||
jmsSender = jmsSession.createSender(jmsSystemQueue);
|
||||
}
|
||||
|
||||
// Query a single value from the QueueServer which will process it as
|
||||
// root.
|
||||
public void send(QueueTask task) throws ProcessorException {
|
||||
try {
|
||||
ObjectMessage jmsMessage = jmsSession.createObjectMessage(task);
|
||||
jmsSender.send(jmsMessage);
|
||||
} catch (JMSSecurityException secExc) {
|
||||
secExc.printStackTrace();
|
||||
throw new ProcessorException("Not allowed to send to queue "
|
||||
+ queueName(jmsSystemQueue) + " failed", secExc);
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
throw new ProcessorException("Error while sending to queue "
|
||||
+ queueName(jmsSystemQueue) + " failed", exc);
|
||||
}
|
||||
}
|
||||
|
||||
private String queueName(Queue jmsSystemQueue2) {
|
||||
try {
|
||||
return jmsSystemQueue.getQueueName();
|
||||
} catch (Exception exc) {
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
// frees all ressources
|
||||
public void close() {
|
||||
try {
|
||||
if (jmsSender != null) jmsSender.close();
|
||||
} catch (Exception exc) { }
|
||||
try {
|
||||
if (jmsSession != null) jmsSession.close();
|
||||
} catch (Exception exc) { }
|
||||
try {
|
||||
if (jmsConnection != null) jmsConnection.close();
|
||||
} catch (Exception exc) { }
|
||||
}
|
||||
}
|
14
hsarback/src/de/hsadmin/core/qserv/QueueCommons.java
Normal file
14
hsarback/src/de/hsadmin/core/qserv/QueueCommons.java
Normal file
@ -0,0 +1,14 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
public class QueueCommons
|
||||
{
|
||||
protected static final boolean TRANSACTED = true;
|
||||
protected static final boolean IMMEDIATE = false;
|
||||
protected static final boolean DEFAULT = IMMEDIATE;
|
||||
|
||||
public QueueCommons()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
}
|
254
hsarback/src/de/hsadmin/core/qserv/QueueServer.java
Normal file
254
hsarback/src/de/hsadmin/core/qserv/QueueServer.java
Normal file
@ -0,0 +1,254 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.ExceptionListener;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.QueueConnection;
|
||||
import javax.jms.QueueConnectionFactory;
|
||||
import javax.jms.QueueReceiver;
|
||||
import javax.jms.QueueSession;
|
||||
import javax.jms.Session;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
public class QueueServer extends QueueCommons implements
|
||||
MessageListener, ExceptionListener {
|
||||
|
||||
private static final String VERSION_NO = "1.0";
|
||||
|
||||
private int nMessagesProcessed = 0;
|
||||
private QueueConnection conn;
|
||||
private QueueSession queueSession;
|
||||
private String jmsStatusQueue;
|
||||
private String jmsPassWord;
|
||||
private String jmsUserName;
|
||||
private String jmsSystemQueue;
|
||||
private String jmsFactory;
|
||||
|
||||
/** Runs the QueueServer, using the arguments as ConnectionFactory
|
||||
* and Topic names.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
File propFile = new File(System.getProperty("user.dir"),
|
||||
"conf/qserv.properties");
|
||||
if (args.length == 1)
|
||||
propFile = new File(args[0]);
|
||||
else if (args.length != 0) {
|
||||
throw new Exception(
|
||||
"Wrong number of arguments.\n"
|
||||
+ "With no arguments '"
|
||||
+ propFile
|
||||
+ "' will be used as config file.\n"
|
||||
+ "Or give a properties file as single argument.\n\n"
|
||||
+ "Example config file:\n\n"
|
||||
+ "hsadmin.jms.factory=QueueCF\n"
|
||||
+ "hsadmin.jms.system-queue=hive-h01\n"
|
||||
+ "hsadmin.jms.status-queue=queue/hsadminStatus\n"
|
||||
+ "hsadmin.jms.username=hive-h01\n"
|
||||
+ "hsadmin.jms.password=geheimeskennwort\n");
|
||||
}
|
||||
|
||||
FileInputStream propStream = new FileInputStream(propFile);
|
||||
Properties props = new Properties(System.getProperties());
|
||||
props.load(propStream);
|
||||
propStream.close();
|
||||
String stdout = System.getProperty("hsadmin.stdout");
|
||||
if (stdout != null && stdout.length() > 0)
|
||||
System.setOut(new PrintStream(new FileOutputStream(stdout)));
|
||||
String stderr = System.getProperty("hsadmin.stderr");
|
||||
if (stderr != null && stderr.length() > 0)
|
||||
System.setErr(new PrintStream(new FileOutputStream(stderr)));
|
||||
|
||||
final QueueServer qServ = new QueueServer();
|
||||
qServ.setJmsFactory(props.getProperty("hsadmin.jms.factory"));
|
||||
qServ.setJmsSystemQueue(props.getProperty("hsadmin.jms.system-queue"));
|
||||
qServ.setJmsStatusQueue(props.getProperty("hsadmin.jms.status-queue"));
|
||||
qServ.setJmsUserName(props.getProperty("hsadmin.jms.username"));
|
||||
qServ.setJmsPassWord(props.getProperty("hsadmin.jms.password"));
|
||||
System.out.println("==================================================");
|
||||
System.out.println("hsadmin-qserv " + VERSION_NO +
|
||||
" started using:");
|
||||
System.out.println("queue server: "
|
||||
+ props.getProperty("hsadmin.jms.factory"));
|
||||
System.out.println("system queue: "
|
||||
+ props.getProperty("hsadmin.jms.system-queue"));
|
||||
System.out.println("status queue: "
|
||||
+ props.getProperty("hsadmin.jms.status-queue"));
|
||||
System.out.println("queue user: "
|
||||
+ props.getProperty("hsadmin.jms.username"));
|
||||
System.out.println("==================================================");
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
qServ.close();
|
||||
}
|
||||
});
|
||||
while (!qServ.connect()) {
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
while (true) {
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean connect() {
|
||||
// create JMS connection and session
|
||||
try {
|
||||
Context ctx = new InitialContext();
|
||||
QueueConnectionFactory connectionFactory =
|
||||
(QueueConnectionFactory) ctx.lookup(jmsFactory);
|
||||
conn = connectionFactory.createQueueConnection(jmsUserName, jmsPassWord);
|
||||
conn.setExceptionListener(this);
|
||||
queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = (Queue) ctx.lookup(jmsSystemQueue);
|
||||
conn.start();
|
||||
QueueReceiver receiver = queueSession.createReceiver(queue);
|
||||
receiver.setMessageListener(this);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// / Is called when a message arrives; processes Processor within message.
|
||||
public synchronized void onMessage(Message jmsMessage) {
|
||||
// TODO logging
|
||||
System.out.println("\nonMessage(" + jmsMessage);
|
||||
QueueTask task = null;
|
||||
try {
|
||||
// expect ObjectMessage
|
||||
ObjectMessage jmsObjectMessage = (ObjectMessage) jmsMessage;
|
||||
|
||||
// get QueueTask
|
||||
task = (QueueTask) jmsObjectMessage.getObject();
|
||||
|
||||
// TODO: logging
|
||||
System.out.println("processing (" + task.getTitle() + " | started("
|
||||
+ task.getStarted() + ") |" + task.getDetails() + "|"
|
||||
+ task.getProcessor() + ")");
|
||||
System.out.println("with " + task.getProcessor());
|
||||
// execute processor within the message
|
||||
task.getProcessor().process();
|
||||
System.out.println("done");
|
||||
|
||||
// mark done
|
||||
sendStatus(task);
|
||||
} catch (Exception receiveException) {
|
||||
System.err.println("exception " + receiveException); // TODO:
|
||||
// logging
|
||||
receiveException.printStackTrace(System.err);
|
||||
if (receiveException.getCause() != null) {
|
||||
System.err.println("caused by exception "
|
||||
+ receiveException.getCause()); // TODO: logging
|
||||
receiveException.getCause().printStackTrace(System.err);
|
||||
} else
|
||||
System.err.println("no further cause available");
|
||||
task.setException(receiveException);
|
||||
sendStatus(task);
|
||||
} catch (Throwable t) {
|
||||
System.err.println("severe exception " + t); // TODO: logging
|
||||
} finally {
|
||||
setNMessagesProcessed(getNMessagesProcessed() + 1);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException e) {
|
||||
System.out.println("Exception: " + e.getMessage());
|
||||
close();
|
||||
while (!connect()) {
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e1) { }
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (queueSession != null) {
|
||||
try {
|
||||
queueSession.close();
|
||||
} catch (JMSException e1) { }
|
||||
}
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (JMSException e1) { }
|
||||
}
|
||||
}
|
||||
|
||||
// / send the status information back to the hsadmin server
|
||||
protected void sendStatus(QueueTask queueMessage) {
|
||||
MessageProducer producer = null;
|
||||
Session statusSession = null;
|
||||
Connection statusConnection = null;
|
||||
try {
|
||||
System.out.println("sendStatus( " + queueMessage + ")");
|
||||
Context ctx = new InitialContext();
|
||||
System.out.println("Created InitialContext");
|
||||
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup(jmsFactory);
|
||||
System.out.println("connectionFactory= "
|
||||
+ connectionFactory.toString());
|
||||
Destination queue = (Destination) ctx.lookup(jmsStatusQueue);
|
||||
statusConnection = connectionFactory.createConnection(jmsUserName, jmsPassWord);
|
||||
statusSession = statusConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
producer = statusSession.createProducer(queue);
|
||||
ObjectMessage statusMessage = statusSession.createObjectMessage(queueMessage);
|
||||
System.out.println("send( " + statusMessage + ")");
|
||||
producer.send(statusMessage);
|
||||
} catch (Exception statusException) {
|
||||
// TODO: log exception
|
||||
System.out.println("failed");
|
||||
statusException.printStackTrace(System.err);
|
||||
} finally {
|
||||
// close JMS
|
||||
try { producer.close(); } catch (Exception exc) { }
|
||||
try { statusSession.close(); } catch (Exception exc) { }
|
||||
try { statusConnection.close(); } catch (Exception exc) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setNMessagesProcessed(int nMessagesProcessed) {
|
||||
this.nMessagesProcessed = nMessagesProcessed;
|
||||
}
|
||||
|
||||
public int getNMessagesProcessed() {
|
||||
return nMessagesProcessed;
|
||||
}
|
||||
|
||||
public void setJmsStatusQueue(String property) {
|
||||
jmsStatusQueue = property;
|
||||
}
|
||||
|
||||
public void setJmsPassWord(String property) {
|
||||
jmsPassWord = property;
|
||||
}
|
||||
|
||||
public void setJmsUserName(String property) {
|
||||
jmsUserName = property;
|
||||
}
|
||||
|
||||
public void setJmsSystemQueue(String property) {
|
||||
jmsSystemQueue = property;
|
||||
}
|
||||
|
||||
public void setJmsFactory(String property) {
|
||||
jmsFactory = property;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.jms.ExceptionListener;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.Queue;
|
||||
import javax.jms.QueueConnection;
|
||||
import javax.jms.QueueConnectionFactory;
|
||||
import javax.jms.QueueReceiver;
|
||||
import javax.jms.QueueSession;
|
||||
import javax.jms.Session;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import de.hsadmin.cliClientConnector.TechnicalException;
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
import de.hsadmin.core.util.Config;
|
||||
|
||||
public class QueueStatusReceiverServlet extends HttpServlet
|
||||
implements MessageListener, ExceptionListener {
|
||||
|
||||
private static final long serialVersionUID = -5701350884034782083L;
|
||||
|
||||
private String jmsUser;
|
||||
private String jmsPass;
|
||||
private QueueConnectionFactory queueConnectionFactory;
|
||||
private QueueConnection queueConnection;
|
||||
private QueueSession queueSession;
|
||||
private boolean isConnected;
|
||||
private int messageCount;
|
||||
private int errorCount;
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException {
|
||||
isConnected = false;
|
||||
messageCount = 0;
|
||||
errorCount = 0;
|
||||
try {
|
||||
connect();
|
||||
} catch (NamingException e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void connect() throws NamingException {
|
||||
Config config = Config.getInstance();
|
||||
jmsUser = config.getProperty("hsadmin.jms.username", "hsadmin");
|
||||
jmsPass = config.getProperty("hsadmin.jms.password", "hsadmin-pw");
|
||||
InitialContext ctx = new InitialContext();
|
||||
Context env = (Context) ctx.lookup("java:comp/env");
|
||||
queueConnectionFactory = (QueueConnectionFactory) env.lookup("jms/QueueCF");
|
||||
while (!isConnected) {
|
||||
try {
|
||||
queueConnection = queueConnectionFactory.createQueueConnection(jmsUser, jmsPass);
|
||||
queueConnection.setExceptionListener(this);
|
||||
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = (Queue) env.lookup("jms/hsadminStatus");
|
||||
queueConnection.start();
|
||||
QueueReceiver receiver = queueSession.createReceiver(queue);
|
||||
receiver.setMessageListener(this);
|
||||
isConnected = true;
|
||||
} catch (JMSException e) {
|
||||
close();
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e1) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.setContentType("text/plain");
|
||||
PrintWriter writer = resp.getWriter();
|
||||
writer.println("Verbindungsstatus: " + (isConnected ? "OK" : "ERROR"));
|
||||
writer.println("Verarbeitete Nachrichten: " + messageCount);
|
||||
writer.println("Verarbeitungsfehler: " + errorCount);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
close();
|
||||
}
|
||||
|
||||
private void close() {
|
||||
try { if (queueSession != null) queueSession.close(); } catch (JMSException e) { }
|
||||
try { if (queueConnection != null) queueConnection.close(); } catch (JMSException e) { }
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(Message jmsMessage) {
|
||||
Transaction transaction = null;
|
||||
messageCount++;
|
||||
try {
|
||||
ObjectMessage objMessage = (ObjectMessage) jmsMessage;
|
||||
QueueTask detachedQT = (QueueTask) objMessage.getObject();
|
||||
transaction = new Transaction("statusreceiver");
|
||||
transaction.beginTransaction();
|
||||
EntityManager em = transaction.getEntityManager();
|
||||
// merging detachedQT directly makes Hibernate run into an endless recursion (stack overflow)
|
||||
em.clear();
|
||||
QueueTask persistentQT = em.find(QueueTask.class, detachedQT.getId());
|
||||
persistentQT.assign(detachedQT);
|
||||
Processor processor = persistentQT.getProcessor();
|
||||
if (processor != null) {
|
||||
processor.finalize(transaction, persistentQT);
|
||||
}
|
||||
em.persist(persistentQT);
|
||||
em.flush();
|
||||
transaction.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
errorCount++;
|
||||
if (transaction != null) transaction.rollbackTransaction();
|
||||
throw new TechnicalException(e);
|
||||
} finally {
|
||||
if (transaction != null) transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException exception) {
|
||||
close();
|
||||
try { Thread.sleep(10000); } catch (InterruptedException e) { }
|
||||
try { connect(); } catch (NamingException e) { }
|
||||
}
|
||||
|
||||
}
|
232
hsarback/src/de/hsadmin/core/qserv/QueueTask.java
Normal file
232
hsarback/src/de/hsadmin/core/qserv/QueueTask.java
Normal file
@ -0,0 +1,232 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GenerationType;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.EntityInfo;
|
||||
import de.hsadmin.core.model.ModuleImpl;
|
||||
import de.hsadmin.mods.qstat.QTaskModuleImpl;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "QueueTasks")
|
||||
@javax.persistence.Table(name = "queue_task")
|
||||
@javax.persistence.SequenceGenerator(name = "QueueTaskSeqGen", sequenceName = "queue_task_id_seq")
|
||||
@EntityInfo(name = "Systemauftrag")
|
||||
@ModuleImpl(QTaskModuleImpl.class)
|
||||
public class QueueTask extends Entity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2171870783383767875L;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "QueueTaskSeqGen")
|
||||
@javax.persistence.Column(name = "task_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
@javax.persistence.JoinColumn(name="user_id", columnDefinition="integer", nullable=true)
|
||||
@javax.persistence.ManyToOne(fetch=FetchType.EAGER)
|
||||
private UnixUser user;
|
||||
|
||||
@javax.persistence.Column(name = "started", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
private Date started;
|
||||
|
||||
@javax.persistence.Column(name = "finished", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
private Date finished;
|
||||
|
||||
@javax.persistence.Column(name = "title", columnDefinition = "character varying(192)")
|
||||
private String title;
|
||||
|
||||
@javax.persistence.Column(name = "details", columnDefinition = "text", nullable = true)
|
||||
private String details;
|
||||
|
||||
private Processor proc;
|
||||
|
||||
@javax.persistence.Column(name = "exception", columnDefinition = "text", nullable = true)
|
||||
private String exception;
|
||||
|
||||
public QueueTask() {
|
||||
}
|
||||
|
||||
public QueueTask(UnixUser user, String title, String details, Processor proc) {
|
||||
this.user = user;
|
||||
this.title = title;
|
||||
this.details = details;
|
||||
this.started = new Date();
|
||||
this.finished = null;
|
||||
this.proc = proc;
|
||||
this.exception = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether the given user has full read access
|
||||
* on all merged fields of this entity
|
||||
*/
|
||||
@Override
|
||||
public boolean isReadAllowedFor(UnixUser loginUser) {
|
||||
return loginUser.hasPacAdminRoleFor(getUser().getPac())
|
||||
|| loginUser.id() == getUser().id();
|
||||
}
|
||||
|
||||
/**
|
||||
* JPA-Query restriction for these entities
|
||||
* @return
|
||||
*/
|
||||
public static String restriction() {
|
||||
return
|
||||
// customers can see all entries of all users of their pacs
|
||||
"obj.user.pac.customer.name=:loginUserName OR " +
|
||||
// packet admins can access all entries of their users
|
||||
// TODO: Hostsharing convention
|
||||
"obj.user.pac.name=:loginUserName OR " +
|
||||
// otherwise only their own tasks
|
||||
"obj.user=:loginUser";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return Long.toString(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UnixUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UnixUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Date getStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public void setStarted(Date started) {
|
||||
this.finished = started;
|
||||
}
|
||||
|
||||
public Date getFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual attribute done
|
||||
* @return
|
||||
*/
|
||||
@javax.persistence.Transient
|
||||
public boolean isDone() {
|
||||
return finished != null;
|
||||
}
|
||||
|
||||
public void done() {
|
||||
finished = new java.util.Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual attribute status
|
||||
* @return
|
||||
*/
|
||||
@javax.persistence.Transient
|
||||
public QueueTaskStatus getStatus() {
|
||||
return isDone() ? (exception == null ? QueueTaskStatus.DONE
|
||||
: QueueTaskStatus.ERROR) : QueueTaskStatus.PENDING;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(String details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public Processor getProcessor() {
|
||||
return proc;
|
||||
}
|
||||
|
||||
public void setProcessor(Processor proc) {
|
||||
this.proc = proc;
|
||||
}
|
||||
|
||||
public String getException() {
|
||||
return exception;
|
||||
};
|
||||
|
||||
public void setException(String exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public void setException(Exception exception) {
|
||||
this.exception = exception.toString();
|
||||
// TODO: stack+cause
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* assigns all data field of qt to this instance, with
|
||||
* the exception of the id
|
||||
*/
|
||||
public void assign(QueueTask qt) {
|
||||
this.user = qt.user;
|
||||
this.title = qt.title;
|
||||
this.details = qt.details;
|
||||
this.started = qt.started;
|
||||
this.finished = qt.finished;
|
||||
this.proc = qt.proc;
|
||||
this.exception = qt.exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHiveName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum QueueTaskStatus {
|
||||
|
||||
PENDING("pending"), ERROR("error"), DONE("done");
|
||||
|
||||
private final String color;
|
||||
|
||||
QueueTaskStatus(final String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
19
hsarback/src/de/hsadmin/core/qserv/ShellException.java
Normal file
19
hsarback/src/de/hsadmin/core/qserv/ShellException.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
public class ShellException
|
||||
extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 8335020360721047849L;
|
||||
|
||||
int nExitCode;
|
||||
|
||||
public ShellException()
|
||||
{
|
||||
}
|
||||
|
||||
public ShellException( int exitCode, String message )
|
||||
{
|
||||
super( message );
|
||||
nExitCode = exitCode;
|
||||
}
|
||||
}
|
76
hsarback/src/de/hsadmin/core/qserv/ShellProcessor.java
Normal file
76
hsarback/src/de/hsadmin/core/qserv/ShellProcessor.java
Normal file
@ -0,0 +1,76 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
|
||||
/**
|
||||
* A ShellProcessor encapsulates a shell command as a Processor.
|
||||
*
|
||||
* As such, a client can prepare shell commands to be processed on a server.
|
||||
*
|
||||
* @author mi
|
||||
*/
|
||||
public class ShellProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = -649045174380048818L;
|
||||
|
||||
private String aSystemCall;
|
||||
private String[] aEnv;
|
||||
private String aInput;
|
||||
private String aOutput;
|
||||
private String aErrors;
|
||||
|
||||
/**
|
||||
* Constructor for a queue entry which executes a system call.
|
||||
*
|
||||
* @param aSystemCall
|
||||
* the system call to be executed
|
||||
*/
|
||||
public ShellProcessor(String aSystemCall) {
|
||||
this(aSystemCall, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a queue entry which executes a system call with stdin
|
||||
* data.
|
||||
*
|
||||
* @param aSystemCall
|
||||
* the system call to be executed
|
||||
* @param aInput
|
||||
* data for stdin of the system call
|
||||
*/
|
||||
public ShellProcessor(String aSystemCall, String aInput) {
|
||||
this.aSystemCall = aSystemCall;
|
||||
this.aInput = aInput;
|
||||
}
|
||||
|
||||
public ShellProcessor(String aSystemCall, String[] aEnv, String aInput) {
|
||||
this.aSystemCall = aSystemCall;
|
||||
this.aEnv = aEnv;
|
||||
this.aInput = aInput;
|
||||
}
|
||||
|
||||
public Object process() throws ProcessorException {
|
||||
try {
|
||||
CommandShell.setEnvironment(aEnv);
|
||||
aOutput = CommandShell.execute(aSystemCall, aInput);
|
||||
return aOutput;
|
||||
} catch (ShellException aExc) {
|
||||
aExc.printStackTrace(System.err); // Logging
|
||||
throw new ProcessorException(aExc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns stderr as a String.
|
||||
*/
|
||||
public String getErrors() {
|
||||
return aErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns stdout as a String.
|
||||
*/
|
||||
public String getOutput() {
|
||||
return aOutput;
|
||||
}
|
||||
|
||||
}
|
57
hsarback/src/de/hsadmin/core/qserv/TemplateProcessor.java
Normal file
57
hsarback/src/de/hsadmin/core/qserv/TemplateProcessor.java
Normal file
@ -0,0 +1,57 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.jtpl.Template;
|
||||
|
||||
public class TemplateProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = 4520635523274792876L;
|
||||
|
||||
private String content = null;
|
||||
private String targetPath = null;
|
||||
private boolean overwriteTarget = false;
|
||||
|
||||
public TemplateProcessor(String templateName, Map<String, String> templateValues, String targetPath, boolean overwriteTarget) throws ProcessorException {
|
||||
this.targetPath = targetPath;
|
||||
this.overwriteTarget = overwriteTarget;
|
||||
try {
|
||||
InputStream stream = TemplateProcessor.class.getClassLoader().getResourceAsStream(templateName);
|
||||
Template template = new Template(new InputStreamReader(stream));
|
||||
for (String key : templateValues.keySet()) {
|
||||
template.assign(key, templateValues.get(key));
|
||||
}
|
||||
template.parse("main");
|
||||
content = template.out();
|
||||
} catch (IOException e) {
|
||||
throw new ProcessorException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process() throws ProcessorException {
|
||||
try {
|
||||
File file = new File(targetPath);
|
||||
if (file.exists() && !overwriteTarget) {
|
||||
return null;
|
||||
}
|
||||
if (!file.exists() || file.canWrite()) {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
writer.append(content);
|
||||
writer.close();
|
||||
} else {
|
||||
throw new ProcessorException("could not write file " + targetPath);
|
||||
}
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
throw new ProcessorException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package de.hsadmin.core.qserv;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
|
||||
public class WaitingTasksProcessor extends AbstractProcessor {
|
||||
|
||||
private static final long serialVersionUID = 1198528557513957546L;
|
||||
|
||||
private Processor main;
|
||||
private List<WaitingProcessor> waitingTasks;
|
||||
|
||||
public WaitingTasksProcessor(Processor mainProcessor) {
|
||||
this.main = mainProcessor;
|
||||
this.waitingTasks = new ArrayList<WaitingProcessor>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object process() throws ProcessorException {
|
||||
return main.process();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize(Transaction transaction, QueueTask task)
|
||||
throws ProcessorException {
|
||||
if (task.getException() == null) {
|
||||
for (WaitingProcessor p : waitingTasks) {
|
||||
QueueTask wTask =
|
||||
new QueueTask(task.getUser(), task.getTitle() + " / " + p.getTitle(), task.getTitle() + " / " + p.getTitle(), p.getProc());
|
||||
transaction.getEntityManager().persist(wTask);
|
||||
transaction.enqueue(p.getHost(), wTask);
|
||||
}
|
||||
}
|
||||
super.finalize(transaction, task);
|
||||
}
|
||||
|
||||
public void appendProcessor(String hostName, Processor waitingTask, String title) {
|
||||
waitingTasks.add(new WaitingProcessor(hostName, waitingTask, title));
|
||||
}
|
||||
|
||||
class WaitingProcessor implements Serializable {
|
||||
private static final long serialVersionUID = -5205925170344385765L;
|
||||
private String host;
|
||||
private Processor proc;
|
||||
private String title;
|
||||
public WaitingProcessor(String hostName, Processor processor, String procTitle) {
|
||||
host = hostName;
|
||||
proc = processor;
|
||||
title = procTitle;
|
||||
}
|
||||
public Processor getProc() {
|
||||
return proc;
|
||||
}
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
}
|
53
hsarback/src/de/hsadmin/core/util/Config.java
Normal file
53
hsarback/src/de/hsadmin/core/util/Config.java
Normal file
@ -0,0 +1,53 @@
|
||||
package de.hsadmin.core.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.Properties;
|
||||
|
||||
public class Config {
|
||||
|
||||
private static Config instance;
|
||||
|
||||
private Properties props;
|
||||
|
||||
private Config() {
|
||||
props = new Properties();
|
||||
File file = new File(System.getProperty("user.dir") + "/hsadmin.properties");
|
||||
if (!file.canRead()) {
|
||||
file = new File(System.getProperty("user.dir") + "/conf/hsadmin.properties");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
file = new File(System.getProperty("user.home") + "/.hsadmin.properties");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
file = new File("/etc/hsadmin.properties");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
file = new File("/etc/hsadmin/hsadmin.properties");
|
||||
}
|
||||
if (file.canRead()) {
|
||||
try {
|
||||
props.load(new FileReader(file));
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Config getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new Config();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public String getProperty(String propertyName) {
|
||||
return props.getProperty(propertyName).trim();
|
||||
}
|
||||
|
||||
public String getProperty(String propertyName, String defaultValue) {
|
||||
return props.getProperty(propertyName, defaultValue).trim();
|
||||
}
|
||||
|
||||
}
|
164
hsarback/src/de/hsadmin/mods/cust/BankAccount.java
Normal file
164
hsarback/src/de/hsadmin/mods/cust/BankAccount.java
Normal file
@ -0,0 +1,164 @@
|
||||
package de.hsadmin.mods.cust;
|
||||
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "BankAccounts")
|
||||
@javax.persistence.Table(name = "bank_account")
|
||||
public class BankAccount extends de.hsadmin.core.model.Entity implements
|
||||
java.io.Serializable {
|
||||
private static final long serialVersionUID = 2965368183976686458L;
|
||||
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "customer.name = " + humanKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getCustomer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
// attribute id
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.SEQUENCE)
|
||||
@javax.persistence.SequenceGenerator(name = "bank_account_id_seq_gen", sequenceName = "bank_account_bank_account_i_seq", allocationSize = 20)
|
||||
@javax.persistence.Column(name = "bank_account_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// attribute customer
|
||||
@javax.persistence.JoinColumn(name = "bp_id", columnDefinition = "integer")
|
||||
@javax.persistence.OneToOne(fetch = EAGER)
|
||||
private Customer customer;
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
// attribute autoDebitGA
|
||||
@javax.persistence.Column(name = "autodebit_ga", columnDefinition = "boolean", nullable = true)
|
||||
private Boolean autoDebitGA;
|
||||
|
||||
public Boolean isAutoDebitGA() {
|
||||
return autoDebitGA;
|
||||
}
|
||||
|
||||
public Boolean getAutoDebitGA() {
|
||||
return autoDebitGA;
|
||||
}
|
||||
|
||||
public void setAutoDebitGA(Boolean autoDebitGA) {
|
||||
this.autoDebitGA = autoDebitGA;
|
||||
}
|
||||
|
||||
// attribute autoDebitAR
|
||||
@javax.persistence.Column(name = "autodebit_ar", columnDefinition = "boolean", nullable = true)
|
||||
private Boolean autoDebitAR;
|
||||
|
||||
public Boolean isAutoDebitAR() {
|
||||
return autoDebitAR;
|
||||
}
|
||||
|
||||
public Boolean getAutoDebitAR() {
|
||||
return autoDebitAR;
|
||||
}
|
||||
|
||||
public void setAutoDebitAR(Boolean autoDebitAR) {
|
||||
this.autoDebitAR = autoDebitAR;
|
||||
}
|
||||
|
||||
// attribute autoDebitOP
|
||||
@javax.persistence.Column(name = "autodebit_op", columnDefinition = "boolean", nullable = true)
|
||||
private Boolean autoDebitOP;
|
||||
|
||||
public Boolean isAutoDebitOP() {
|
||||
return autoDebitOP;
|
||||
}
|
||||
|
||||
public Boolean getAutoDebitOP() {
|
||||
return autoDebitOP;
|
||||
}
|
||||
|
||||
public void setAutoDebitOP(Boolean autoDebitOP) {
|
||||
this.autoDebitOP = autoDebitOP;
|
||||
}
|
||||
|
||||
// attribute bankCustomer
|
||||
@javax.persistence.Column(name = "bank_customer", columnDefinition = "character varying(50)", nullable = true)
|
||||
private String bankCustomer;
|
||||
|
||||
public String getBankCustomer() {
|
||||
return bankCustomer;
|
||||
}
|
||||
|
||||
public void setBankCustomer(String bankCustomer) {
|
||||
this.bankCustomer = bankCustomer;
|
||||
}
|
||||
|
||||
// attribute bankAccount
|
||||
@javax.persistence.Column(name = "bank_account", columnDefinition = "character varying(10)", nullable = true)
|
||||
private String bankAccount;
|
||||
|
||||
public String getBankAccount() {
|
||||
return bankAccount;
|
||||
}
|
||||
|
||||
public void setBankAccount(String bankAccount) {
|
||||
this.bankAccount = bankAccount;
|
||||
}
|
||||
|
||||
// attribute bankCode
|
||||
@javax.persistence.Column(name = "bank_code", columnDefinition = "character varying(8)", nullable = true)
|
||||
private String bankCode;
|
||||
|
||||
public String getBankCode() {
|
||||
return bankCode;
|
||||
}
|
||||
|
||||
public void setBankCode(String bankCode) {
|
||||
this.bankCode = bankCode;
|
||||
}
|
||||
|
||||
// attribute bankName
|
||||
@javax.persistence.Column(name = "bank_name", columnDefinition = "character varying(50)", nullable = true)
|
||||
private String bankName;
|
||||
|
||||
public String getBankName() {
|
||||
return bankName;
|
||||
}
|
||||
|
||||
public void setBankName(String bankName) {
|
||||
this.bankName = bankName;
|
||||
}
|
||||
|
||||
// / {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return customer.owningUser(em);
|
||||
}
|
||||
}
|
282
hsarback/src/de/hsadmin/mods/cust/Contact.java
Normal file
282
hsarback/src/de/hsadmin/mods/cust/Contact.java
Normal file
@ -0,0 +1,282 @@
|
||||
package de.hsadmin.mods.cust;
|
||||
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "Contacts")
|
||||
@javax.persistence.Table(name = "contact")
|
||||
@javax.persistence.SequenceGenerator(name = "ContactsSeqGen", sequenceName = "contact_contact_id_seq")
|
||||
public class Contact extends de.hsadmin.core.model.Entity implements
|
||||
java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 9119607911598098558L;
|
||||
|
||||
// attribute id
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "ContactsSeqGen")
|
||||
@javax.persistence.Column(name = "contact_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
// attribute customer
|
||||
@javax.persistence.JoinColumn(name = "bp_id", columnDefinition = "integer")
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private Customer customer;
|
||||
|
||||
// attribute salut
|
||||
@javax.persistence.Column(name = "salut", columnDefinition = "character varying(30)")
|
||||
private String salut;
|
||||
|
||||
// attribute firstName
|
||||
@javax.persistence.Column(name = "first_name", columnDefinition = "character varying(40)")
|
||||
private String firstName;
|
||||
|
||||
// attribute lastName
|
||||
@javax.persistence.Column(name = "last_name", columnDefinition = "character varying(40)")
|
||||
private String lastName;
|
||||
|
||||
// attribute title
|
||||
@javax.persistence.Column(name = "title", columnDefinition = "character varying(20)")
|
||||
private String title;
|
||||
|
||||
// attribute firma
|
||||
@javax.persistence.Column(name = "firma", columnDefinition = "character varying(120)")
|
||||
private String firma;
|
||||
|
||||
// attribute co
|
||||
@javax.persistence.Column(name = "co", columnDefinition = "character varying(50)")
|
||||
private String co;
|
||||
|
||||
// attribute street
|
||||
@javax.persistence.Column(name = "street", columnDefinition = "character varying(50)")
|
||||
private String street;
|
||||
|
||||
// attribute zipCode
|
||||
@javax.persistence.Column(name = "zipcode", columnDefinition = "character varying(10)")
|
||||
private String zipCode;
|
||||
|
||||
// attribute city
|
||||
@javax.persistence.Column(name = "city", columnDefinition = "character varying(40)")
|
||||
private String city;
|
||||
|
||||
// attribute country
|
||||
@javax.persistence.Column(name = "country", columnDefinition = "character varying(30)")
|
||||
private String country;
|
||||
|
||||
// attribute phonePrivate
|
||||
@javax.persistence.Column(name = "phone_private", columnDefinition = "character varying(30)")
|
||||
private String phonePrivate;
|
||||
|
||||
// attribute phoneOffice
|
||||
@javax.persistence.Column(name = "phone_office", columnDefinition = "character varying(30)")
|
||||
private String phoneOffice;
|
||||
|
||||
// attribute phoneMobile
|
||||
@javax.persistence.Column(name = "phone_mobile", columnDefinition = "character varying(30)")
|
||||
private String phoneMobile;
|
||||
|
||||
// attribute fax
|
||||
@javax.persistence.Column(name = "fax", columnDefinition = "character varying(30)")
|
||||
private String fax;
|
||||
|
||||
// attribute email
|
||||
@javax.persistence.Column(name = "email", columnDefinition = "character varying(50)")
|
||||
private String email;
|
||||
|
||||
public Contact() {
|
||||
}
|
||||
|
||||
public Contact(Customer cust) {
|
||||
this.customer = cust;
|
||||
}
|
||||
|
||||
public Contact(Customer cust, String salut, String title, String firstName,
|
||||
String lastName, String firma, String co, String street,
|
||||
String zipCode, String city, String country, String phonePrivate,
|
||||
String phoneOffice, String phoneMobile, String fax, String email) {
|
||||
this.customer = cust;
|
||||
this.salut = salut;
|
||||
this.title = title;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.firma = firma;
|
||||
this.co = co;
|
||||
this.street = street;
|
||||
this.zipCode = zipCode;
|
||||
this.city = city;
|
||||
this.country = country;
|
||||
this.phonePrivate = phonePrivate;
|
||||
this.phoneOffice = phoneOffice;
|
||||
this.phoneMobile = phoneMobile;
|
||||
this.fax = fax;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "name='" + humanKey + "'";
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getCustomer().getName();
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public String getSalut() {
|
||||
return salut;
|
||||
}
|
||||
|
||||
public void setSalut(String salut) {
|
||||
this.salut = salut;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getFirma() {
|
||||
return firma;
|
||||
}
|
||||
|
||||
public void setFirma(String firma) {
|
||||
this.firma = firma;
|
||||
}
|
||||
|
||||
public String getCo() {
|
||||
return co;
|
||||
}
|
||||
|
||||
public void setCo(String co) {
|
||||
this.co = co;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getPhonePrivate() {
|
||||
return phonePrivate;
|
||||
}
|
||||
|
||||
public void setPhonePrivate(String phonePrivate) {
|
||||
this.phonePrivate = phonePrivate;
|
||||
}
|
||||
|
||||
public String getPhoneOffice() {
|
||||
return phoneOffice;
|
||||
}
|
||||
|
||||
public void setPhoneOffice(String phoneOffice) {
|
||||
this.phoneOffice = phoneOffice;
|
||||
}
|
||||
|
||||
public String getPhoneMobile() {
|
||||
return phoneMobile;
|
||||
}
|
||||
|
||||
public void setPhoneMobile(String phoneMobile) {
|
||||
this.phoneMobile = phoneMobile;
|
||||
}
|
||||
|
||||
public String getFax() {
|
||||
return fax;
|
||||
}
|
||||
|
||||
public void setFax(String fax) {
|
||||
this.fax = fax;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
// / {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return null; // TODO: no access yet
|
||||
}
|
||||
}
|
267
hsarback/src/de/hsadmin/mods/cust/Customer.java
Normal file
267
hsarback/src/de/hsadmin/mods/cust/Customer.java
Normal file
@ -0,0 +1,267 @@
|
||||
package de.hsadmin.mods.cust;
|
||||
|
||||
import static javax.persistence.CascadeType.ALL;
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.pac.Pac;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "Customers")
|
||||
@javax.persistence.Table(name = "business_partner")
|
||||
@javax.persistence.SequenceGenerator(name = "CustomersSeqGen", sequenceName = "business_partner_bp_id_seq")
|
||||
public class Customer extends de.hsadmin.core.model.Entity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7450594652238392616L;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "CustomersSeqGen")
|
||||
@javax.persistence.Column(name = "bp_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
@javax.persistence.Column(name = "member_id", columnDefinition = "integer")
|
||||
private int memberNo;
|
||||
|
||||
@javax.persistence.Column(name = "member_code", columnDefinition = "character varying(20)")
|
||||
private String name;
|
||||
|
||||
@javax.persistence.Column(name = "member_since", columnDefinition = "date", nullable = true)
|
||||
private Date memberSince;
|
||||
|
||||
@javax.persistence.Column(name = "member_until", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date memberUntil;
|
||||
|
||||
@javax.persistence.Column(name = "member_role", columnDefinition = "character varying(100)", nullable = true)
|
||||
private String memberRole;
|
||||
|
||||
@javax.persistence.Column(name = "author_contract", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date authorContract;
|
||||
|
||||
@javax.persistence.Column(name = "nondisc_contract", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date nonDiscContract;
|
||||
|
||||
@javax.persistence.Column(name = "shares_updated", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date sharesUpdated;
|
||||
|
||||
@javax.persistence.Column(name = "shares_signed", columnDefinition = "integer")
|
||||
private int sharesSigned;
|
||||
|
||||
@javax.persistence.Column(name = "uid_vat", columnDefinition = "character varying(20)", nullable = true)
|
||||
private String uidVAT;
|
||||
|
||||
@javax.persistence.OneToMany(fetch = EAGER, cascade = ALL, mappedBy = "customer")
|
||||
private Set<Contact> contacts;
|
||||
|
||||
// virtual attribute bankAccount
|
||||
@javax.persistence.OneToOne(fetch = EAGER, cascade = ALL, mappedBy = "customer")
|
||||
private BankAccount bankAccount;
|
||||
|
||||
// virtual attribute billData
|
||||
@javax.persistence.OneToOne(fetch = EAGER, cascade = ALL, mappedBy = "customer")
|
||||
private CustomersTariff billData;
|
||||
|
||||
// virtual attribute pacs
|
||||
@javax.persistence.OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "customer")
|
||||
@javax.persistence.OrderBy("name")
|
||||
private Set<Pac> pacs;
|
||||
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(int memberNo, String memberCode) {
|
||||
this.memberNo = memberNo;
|
||||
this.name = memberCode;
|
||||
}
|
||||
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "name='" + humanKey + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getMemberNo() {
|
||||
return memberNo;
|
||||
}
|
||||
|
||||
public void setMemberNo(int memberNo) {
|
||||
this.memberNo = memberNo;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String memberCode) {
|
||||
this.name = memberCode;
|
||||
}
|
||||
|
||||
public Date getMemberSince() {
|
||||
return memberSince;
|
||||
}
|
||||
|
||||
public void setMemberSince(Date memberSince) {
|
||||
this.memberSince = memberSince;
|
||||
}
|
||||
|
||||
public Date getMemberUntil() {
|
||||
return memberUntil;
|
||||
}
|
||||
|
||||
public void setMemberUntil(Date memberUntil) {
|
||||
this.memberUntil = memberUntil;
|
||||
}
|
||||
|
||||
public String getMemberRole() {
|
||||
return memberRole;
|
||||
}
|
||||
|
||||
public void setMemberRole(String memberRole) {
|
||||
this.memberRole = memberRole;
|
||||
}
|
||||
|
||||
public Date getAuthorContract() {
|
||||
return authorContract;
|
||||
}
|
||||
|
||||
public void setAuthorContract(Date authorContract) {
|
||||
this.authorContract = authorContract;
|
||||
}
|
||||
|
||||
public Date getNonDiscContract() {
|
||||
return nonDiscContract;
|
||||
}
|
||||
|
||||
public void setNonDiscContract(Date nonDiscContract) {
|
||||
this.nonDiscContract = nonDiscContract;
|
||||
}
|
||||
|
||||
public Date getSharesUpdated() {
|
||||
return sharesUpdated;
|
||||
}
|
||||
|
||||
public void setSharesUpdated(Date sharesUpdated) {
|
||||
this.sharesUpdated = sharesUpdated;
|
||||
}
|
||||
|
||||
public int getSharesSigned() {
|
||||
return sharesSigned;
|
||||
}
|
||||
|
||||
public void setSharesSigned(int sharesSigned) {
|
||||
this.sharesSigned = sharesSigned;
|
||||
}
|
||||
|
||||
public String getUidVAT() {
|
||||
return uidVAT;
|
||||
}
|
||||
|
||||
public void setUidVAT(String uidVAT) {
|
||||
this.uidVAT = uidVAT;
|
||||
}
|
||||
|
||||
public Set<Contact> getContacts() {
|
||||
if (contacts == null) {
|
||||
contacts = new HashSet<Contact>();
|
||||
contacts.add(new Contact(this));
|
||||
}
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void setContacts(Set<Contact> contacts) {
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
// virtual attribute contractualContact
|
||||
// TODO: currently only a single contact can be managed
|
||||
@javax.persistence.Transient
|
||||
public Contact getContractualContact() {
|
||||
return getContacts().iterator().next();
|
||||
}
|
||||
|
||||
public void setContractualContact(Contact contact) {
|
||||
contacts = new HashSet<Contact>();
|
||||
contacts.add(contact);
|
||||
}
|
||||
|
||||
public BankAccount getBankAccount() {
|
||||
return bankAccount;
|
||||
}
|
||||
|
||||
public void setBankAccount(BankAccount bankAccount) {
|
||||
this.bankAccount = bankAccount;
|
||||
}
|
||||
|
||||
public CustomersTariff getBillData() {
|
||||
return billData;
|
||||
}
|
||||
|
||||
public void setBillData(CustomersTariff tariff) {
|
||||
this.billData = tariff;
|
||||
}
|
||||
|
||||
public Set<Pac> getPacs() {
|
||||
return pacs;
|
||||
}
|
||||
|
||||
public void setPacs(Set<Pac> pacs) {
|
||||
this.pacs = pacs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return null; // TODO: no access yet
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether the given user has full read access on all merged fields of this entity
|
||||
*/
|
||||
@Override
|
||||
public boolean isReadAllowedFor(UnixUser loginUser) {
|
||||
return loginUser.hasCustomerRoleFor(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether the given user has full write access on all merged fields of this entity
|
||||
*/
|
||||
@Override
|
||||
public boolean isWriteAllowedFor(UnixUser loginUser) {
|
||||
return loginUser.hasCustomerRoleFor(this);
|
||||
}
|
||||
|
||||
public static String restriction() {
|
||||
return "name=:loginUserName";
|
||||
}
|
||||
}
|
188
hsarback/src/de/hsadmin/mods/cust/CustomersTariff.java
Normal file
188
hsarback/src/de/hsadmin/mods/cust/CustomersTariff.java
Normal file
@ -0,0 +1,188 @@
|
||||
package de.hsadmin.mods.cust;
|
||||
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "CustomersTariffs")
|
||||
@javax.persistence.Table(name = "billdata")
|
||||
@javax.persistence.SequenceGenerator(name = "CustomersTariffsSeqGen", sequenceName = "billdata_billdata_id_seq")
|
||||
public class CustomersTariff extends de.hsadmin.core.model.Entity implements
|
||||
java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3628577459027111705L;
|
||||
|
||||
// / bean ctor
|
||||
public CustomersTariff() {
|
||||
}
|
||||
|
||||
public CustomersTariff(Customer cust) {
|
||||
this.customer = cust;
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "customer.name = '" + humanKey + "'";
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getCustomer().getName();
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
// attribute id
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "CustomersTariffsSeqGen")
|
||||
@javax.persistence.Column(name = "billdata_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// attribute customer
|
||||
@javax.persistence.JoinColumn(name = "bp_id", columnDefinition = "integer")
|
||||
@javax.persistence.OneToOne(fetch = EAGER)
|
||||
// TODO: das will ich gar nicht, geht aber nicht ohne?!?
|
||||
private Customer customer;
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
// attribute domainDiscountSince
|
||||
@javax.persistence.Column(name = "tariff_domain_discount_since", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date domainDiscountSince;
|
||||
|
||||
public Date getDomainDiscountSince() {
|
||||
return domainDiscountSince;
|
||||
}
|
||||
|
||||
public void setDomainDiscountSince(Date domainDiscountSince) {
|
||||
this.domainDiscountSince = domainDiscountSince;
|
||||
}
|
||||
|
||||
// attribute domainDiscountUntil
|
||||
@javax.persistence.Column(name = "tariff_domain_discount_until", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date domainDiscountUntil;
|
||||
|
||||
public Date getDomainDiscountUntil() {
|
||||
return domainDiscountUntil;
|
||||
}
|
||||
|
||||
public void setDomainDiscountUntil(Date domainDiscountUntil) {
|
||||
this.domainDiscountUntil = domainDiscountUntil;
|
||||
}
|
||||
|
||||
// attribute trafficDiscountSince
|
||||
@javax.persistence.Column(name = "tariff_traffic_discount_since", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date trafficDiscountSince;
|
||||
|
||||
public Date getTrafficDiscountSince() {
|
||||
return trafficDiscountSince;
|
||||
}
|
||||
|
||||
public void setTrafficDiscountSince(Date trafficDiscountSince) {
|
||||
this.trafficDiscountSince = trafficDiscountSince;
|
||||
}
|
||||
|
||||
// attribute trafficDiscountUntil
|
||||
@javax.persistence.Column(name = "tariff_traffic_discount_until", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date trafficDiscountUntil;
|
||||
|
||||
public Date getTrafficDiscountUntil() {
|
||||
return trafficDiscountUntil;
|
||||
}
|
||||
|
||||
public void setTrafficDiscountUntil(Date trafficDiscountUntil) {
|
||||
this.trafficDiscountUntil = trafficDiscountUntil;
|
||||
}
|
||||
|
||||
// attribute quotaDiscountSince
|
||||
@javax.persistence.Column(name = "tariff_quota_discount_since", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date quotaDiscountSince;
|
||||
|
||||
public Date getQuotaDiscountSince() {
|
||||
return quotaDiscountSince;
|
||||
}
|
||||
|
||||
public void setQuotaDiscountSince(Date quotaDiscountSince) {
|
||||
this.quotaDiscountSince = quotaDiscountSince;
|
||||
}
|
||||
|
||||
// attribute quotaDiscountUntil
|
||||
@javax.persistence.Column(name = "tariff_quota_discount_until", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date quotaDiscountUntil;
|
||||
|
||||
public Date getQuotaDiscountUntil() {
|
||||
return quotaDiscountUntil;
|
||||
}
|
||||
|
||||
public void setQuotaDiscountUntil(Date quotaDiscountUntil) {
|
||||
this.quotaDiscountUntil = quotaDiscountUntil;
|
||||
}
|
||||
|
||||
// attribute discountSince
|
||||
@javax.persistence.Column(name = "tariff_discount_since", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date discountSince;
|
||||
|
||||
public Date getDiscountSince() {
|
||||
return discountSince;
|
||||
}
|
||||
|
||||
public void setDiscountSince(Date discountSince) {
|
||||
this.discountSince = discountSince;
|
||||
}
|
||||
|
||||
// attribute discountUntil
|
||||
@javax.persistence.Column(name = "tariff_discount_until", columnDefinition = "date")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date discountUntil;
|
||||
|
||||
public Date getDiscountUntil() {
|
||||
return discountUntil;
|
||||
}
|
||||
|
||||
public void setDiscountUntil(Date discountUntil) {
|
||||
this.discountUntil = discountUntil;
|
||||
}
|
||||
|
||||
// / {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return customer.owningUser(em);
|
||||
}
|
||||
}
|
108
hsarback/src/de/hsadmin/mods/pac/BaseComponent.java
Normal file
108
hsarback/src/de/hsadmin/mods/pac/BaseComponent.java
Normal file
@ -0,0 +1,108 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "BaseComponents")
|
||||
@javax.persistence.Table(name = " basecomponent")
|
||||
@javax.persistence.SequenceGenerator(name = "BaseComponentsSeqGen", sequenceName = "basecomponent_basecomponent_seq")
|
||||
public class BaseComponent extends de.hsadmin.core.model.Entity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8161827018235142603L;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "BaseComponentsSeqGen")
|
||||
@javax.persistence.Column(name = "basecomponent_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
@javax.persistence.Column(name = "basecomponent_code", columnDefinition = "character varying(10)")
|
||||
private String feature;
|
||||
|
||||
@javax.persistence.Column(name = "description", columnDefinition = "character varying(100)")
|
||||
private String description;
|
||||
|
||||
@javax.persistence.Column(name = "sorting", columnDefinition = "integer")
|
||||
private int sorting;
|
||||
|
||||
@javax.persistence.Column(name = "valid", columnDefinition = "boolean")
|
||||
private boolean valid;
|
||||
|
||||
public BaseComponent() {
|
||||
}
|
||||
|
||||
public BaseComponent(String feature, String desc, int sortPos, boolean valid) {
|
||||
this.feature = feature;
|
||||
this.description = desc;
|
||||
this.sorting = sortPos;
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "feature='" + humanKey + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getFeature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFeature() {
|
||||
return feature;
|
||||
}
|
||||
|
||||
public void setFeature(String code) {
|
||||
this.feature = code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getSorting() {
|
||||
return sorting;
|
||||
}
|
||||
|
||||
public void setSorting(int sorting) {
|
||||
this.sorting = sorting;
|
||||
}
|
||||
|
||||
public boolean getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return null; // TODO: kinda somebody like root needed
|
||||
}
|
||||
}
|
141
hsarback/src/de/hsadmin/mods/pac/BasePac.java
Normal file
141
hsarback/src/de/hsadmin/mods/pac/BasePac.java
Normal file
@ -0,0 +1,141 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.CascadeType.ALL;
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@javax.persistence.Entity(name = "BasePacs")
|
||||
@javax.persistence.Table(name = "basepacket")
|
||||
@javax.persistence.SequenceGenerator(name = "BasePacsSeqGen", sequenceName = "basepacket_basepacket_id_seq")
|
||||
public class BasePac implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1491121619195513435L;
|
||||
|
||||
public BasePac() {
|
||||
}
|
||||
|
||||
public BasePac(String name, String desc, int sortPos) {
|
||||
this.name = name;
|
||||
this.description = desc;
|
||||
this.sorting = sortPos;
|
||||
this.valid = true;
|
||||
}
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "BasePacsSeqGen")
|
||||
@javax.persistence.Column(name = "basepacket_id", columnDefinition = "integer")
|
||||
private long id;
|
||||
|
||||
@javax.persistence.Column(name = "basepacket_code", columnDefinition = "character varying(10)")
|
||||
private String name;
|
||||
|
||||
@javax.persistence.Column(name = "description", columnDefinition = "character varying(100)")
|
||||
private String description;
|
||||
|
||||
@javax.persistence.Column(name = "sorting", columnDefinition = "integer")
|
||||
private int sorting;
|
||||
|
||||
@javax.persistence.Column(name = "valid", columnDefinition = "boolean")
|
||||
private boolean valid;
|
||||
|
||||
@javax.persistence.OneToMany(fetch = LAZY, cascade = ALL)
|
||||
private Set<Component> components;
|
||||
|
||||
@javax.persistence.OneToMany(fetch = LAZY, cascade = ALL)
|
||||
@javax.persistence.JoinTable(name = "packet_component", joinColumns = @javax.persistence.JoinColumn(name = "packet_id"), inverseJoinColumns = @javax.persistence.JoinColumn(name = "basepacket_id"))
|
||||
private Set<Pac> pacs;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getSorting() {
|
||||
return sorting;
|
||||
}
|
||||
|
||||
public void setSorting(int sorting) {
|
||||
this.sorting = sorting;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public Set<Component> getComponents() {
|
||||
return components != null ? components
|
||||
: (components = new HashSet<Component>());
|
||||
}
|
||||
|
||||
public void setComponents(Set<Component> components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public Component getComponent(String feature) {
|
||||
for (Component comp : getComponents())
|
||||
if (feature.equals(comp.getBaseComponent().getFeature()))
|
||||
return comp;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addComponent(Component comp) {
|
||||
getComponents().add(comp);
|
||||
}
|
||||
|
||||
public void removeComponent(Component comp) {
|
||||
getComponents().remove(comp);
|
||||
}
|
||||
|
||||
public Set<Pac> getPacs() {
|
||||
return pacs;
|
||||
}
|
||||
|
||||
public void setPacs(Set<Pac> pacs) {
|
||||
this.pacs = pacs;
|
||||
}
|
||||
|
||||
// generic
|
||||
public boolean equals(Object aOther) {
|
||||
if (aOther == null || aOther.getClass() != getClass())
|
||||
return false;
|
||||
BasePac aOtherBP = (BasePac) aOther;
|
||||
if (id != aOtherBP.id)
|
||||
return false;
|
||||
if (name != null && !name.equals(aOtherBP.name))
|
||||
return false;
|
||||
if (description != null && description.equals(aOtherBP.description))
|
||||
return false;
|
||||
if (sorting != aOtherBP.sorting)
|
||||
return false;
|
||||
if (valid != aOtherBP.valid)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
117
hsarback/src/de/hsadmin/mods/pac/Component.java
Normal file
117
hsarback/src/de/hsadmin/mods/pac/Component.java
Normal file
@ -0,0 +1,117 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
@javax.persistence.Entity(name = "Components")
|
||||
@javax.persistence.Table(name = "component")
|
||||
@IdClass(ComponentId.class)
|
||||
public class Component implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 970709621200712794L;
|
||||
|
||||
@javax.persistence.Id
|
||||
private BasePac basePac;
|
||||
|
||||
@javax.persistence.Id
|
||||
private BaseComponent baseComponent;
|
||||
|
||||
@javax.persistence.Column(name = "min_quantity", columnDefinition = "integer")
|
||||
private int minimumQuantity;
|
||||
|
||||
@javax.persistence.Column(name = "max_quantity", columnDefinition = "integer")
|
||||
private int maximimumQuantity;
|
||||
|
||||
@javax.persistence.Column(name = "default_quantity", columnDefinition = "integer")
|
||||
private int defaultQuantity;
|
||||
|
||||
@javax.persistence.Column(name = "increment_quantity", columnDefinition = "integer")
|
||||
private int incrementQuantity;
|
||||
|
||||
@javax.persistence.Column(name = "include_quantity", columnDefinition = "integer")
|
||||
private int includedQuantity;
|
||||
|
||||
@javax.persistence.Column(name = "admin_only", columnDefinition = "boolean")
|
||||
private boolean adminOnly;
|
||||
|
||||
public Component() {
|
||||
}
|
||||
|
||||
public Component(BasePac basePac, BaseComponent baseComp, int min, int max,
|
||||
int def, int incr, int incl, boolean adminOnly) {
|
||||
this.basePac = basePac;
|
||||
this.baseComponent = baseComp;
|
||||
this.minimumQuantity = min;
|
||||
this.maximimumQuantity = max;
|
||||
this.defaultQuantity = def;
|
||||
this.incrementQuantity = incr;
|
||||
this.includedQuantity = incl;
|
||||
this.adminOnly = adminOnly;
|
||||
}
|
||||
|
||||
public BasePac getBasePac() {
|
||||
return basePac;
|
||||
}
|
||||
|
||||
public void setBasePac(BasePac basePac) {
|
||||
this.basePac = basePac;
|
||||
}
|
||||
|
||||
public BaseComponent getBaseComponent() {
|
||||
return baseComponent;
|
||||
}
|
||||
|
||||
public void setBaseComponent(BaseComponent baseComponent) {
|
||||
this.baseComponent = baseComponent;
|
||||
}
|
||||
|
||||
public int getMinimumQuantity() {
|
||||
return minimumQuantity;
|
||||
}
|
||||
|
||||
public void setMinimumQuantity(int minimumQuantity) {
|
||||
this.minimumQuantity = minimumQuantity;
|
||||
}
|
||||
|
||||
public int getMaximimumQuantity() {
|
||||
return maximimumQuantity;
|
||||
}
|
||||
|
||||
public void setMaximimumQuantity(int maximimumQuantity) {
|
||||
this.maximimumQuantity = maximimumQuantity;
|
||||
}
|
||||
|
||||
public int getDefaultQuantity() {
|
||||
return defaultQuantity;
|
||||
}
|
||||
|
||||
public void setDefaultQuantity(int defiautoQuantity) {
|
||||
this.defaultQuantity = defiautoQuantity;
|
||||
}
|
||||
|
||||
public int getIncrementQuantity() {
|
||||
return incrementQuantity;
|
||||
}
|
||||
|
||||
public void setIncrementQuantity(int incrementQuantity) {
|
||||
this.incrementQuantity = incrementQuantity;
|
||||
}
|
||||
|
||||
public int getIncludedQuantity() {
|
||||
return includedQuantity;
|
||||
}
|
||||
|
||||
public void setIncludedQuantity(int includedQuantity) {
|
||||
this.includedQuantity = includedQuantity;
|
||||
}
|
||||
|
||||
public boolean isAdminOnly() {
|
||||
return adminOnly;
|
||||
}
|
||||
|
||||
public void setAdminOnly(boolean adminOnly) {
|
||||
this.adminOnly = adminOnly;
|
||||
}
|
||||
|
||||
}
|
22
hsarback/src/de/hsadmin/mods/pac/ComponentId.java
Normal file
22
hsarback/src/de/hsadmin/mods/pac/ComponentId.java
Normal file
@ -0,0 +1,22 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
public class ComponentId {
|
||||
|
||||
public long basePac;
|
||||
public long baseComponent;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj instanceof ComponentId) {
|
||||
ComponentId other = (ComponentId) obj;
|
||||
return basePac == other.basePac && baseComponent == other.baseComponent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (new Long(basePac ^ baseComponent % Integer.MAX_VALUE)).intValue();
|
||||
}
|
||||
|
||||
}
|
109
hsarback/src/de/hsadmin/mods/pac/Hive.java
Normal file
109
hsarback/src/de/hsadmin/mods/pac/Hive.java
Normal file
@ -0,0 +1,109 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.CascadeType.ALL;
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name="Hives")
|
||||
@javax.persistence.Table(name="hive")
|
||||
@javax.persistence.SequenceGenerator(name="HivesSeqGen", sequenceName="hive_hive_id_seq")
|
||||
public class Hive
|
||||
extends de.hsadmin.core.model.Entity
|
||||
implements java.io.Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -2270234313165009590L;
|
||||
|
||||
/// bean ctor
|
||||
public Hive()
|
||||
{
|
||||
}
|
||||
|
||||
public Hive( String name, INetAddress inetAddr )
|
||||
{
|
||||
this.name = name;
|
||||
this.inetAddr = inetAddr;
|
||||
}
|
||||
|
||||
public Hive( String name, INetAddress inetAddr, String desc )
|
||||
{
|
||||
this(name, inetAddr);
|
||||
this.description = desc;
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
public static String createQueryFromStringKey(String humanKey)
|
||||
{
|
||||
return "hiveName='" + humanKey + "'";
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public String createStringKey()
|
||||
{
|
||||
return getHiveName();
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public long id()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
// attribute id
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy=SEQUENCE, generator="HivesSeqGen")
|
||||
@javax.persistence.Column(name="hive_id")
|
||||
private long id;
|
||||
public long getId() { return id; }
|
||||
public void setId( long id ) { this.id = id; }
|
||||
|
||||
// attribute hiveName
|
||||
@javax.persistence.Column(name="hive_name", columnDefinition="character varying(3)", unique=true)
|
||||
private String name;
|
||||
public String getName() { return name; }
|
||||
@Override
|
||||
public String getHiveName() { return name; }
|
||||
public void setName( String hiveName ) { this.name = hiveName; }
|
||||
|
||||
// attribute inetAddr
|
||||
@javax.persistence.JoinColumn(name="inet_addr_id")
|
||||
@javax.persistence.ManyToOne(fetch=EAGER)
|
||||
private INetAddress inetAddr;
|
||||
public INetAddress getInetAddr() { return inetAddr; }
|
||||
public void setInetAddr( INetAddress inetAddr ) { this.inetAddr = inetAddr; }
|
||||
|
||||
// attribute description
|
||||
@javax.persistence.Column(name="description", columnDefinition="character varying(100)")
|
||||
private String description;
|
||||
public String getDescription() { return description; }
|
||||
public void setDescription( String description ) { this.description = description; }
|
||||
|
||||
// virtual attribute pacs
|
||||
@javax.persistence.OneToMany(fetch=LAZY, cascade=ALL, mappedBy="hive")
|
||||
@javax.persistence.OrderBy("name")
|
||||
private Set<Pac> pacs;
|
||||
public Set<Pac> getPacs() { return pacs; }
|
||||
public void setPacs( Set<Pac> pacs) { this.pacs = pacs; }
|
||||
|
||||
/// {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew()
|
||||
{
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser( EntityManager em )
|
||||
{
|
||||
return null; // TODO: kinda somebody like root needed
|
||||
}
|
||||
}
|
87
hsarback/src/de/hsadmin/mods/pac/INetAddress.java
Normal file
87
hsarback/src/de/hsadmin/mods/pac/INetAddress.java
Normal file
@ -0,0 +1,87 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name="INetAddresses")
|
||||
@javax.persistence.Table(name="inet_addr")
|
||||
@javax.persistence.SequenceGenerator(name="INetAddressesSeqGen", sequenceName="inet_addr_inet_addr_id_seq")
|
||||
public class INetAddress
|
||||
extends de.hsadmin.core.model.Entity
|
||||
implements java.io.Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -5792279453911426607L;
|
||||
|
||||
/// bean ctor
|
||||
public INetAddress()
|
||||
{
|
||||
}
|
||||
|
||||
public INetAddress( String inetAddr )
|
||||
{
|
||||
this.inetAddr = inetAddr;
|
||||
}
|
||||
|
||||
public INetAddress( String inetAddr, String desc )
|
||||
{
|
||||
this(inetAddr);
|
||||
description = desc;
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
public static String createQueryFromStringKey(String humanKey)
|
||||
{
|
||||
return "inetAddr='" + humanKey + "'";
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public String createStringKey()
|
||||
{
|
||||
return getInetAddr();
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public long id()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
// attribute id
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy=SEQUENCE, generator="INetAddressesSeqGen")
|
||||
@javax.persistence.Column(name="inet_addr_id")
|
||||
private long id;
|
||||
public long getId() { return id; }
|
||||
public void setId( long id ) { this.id = id; }
|
||||
|
||||
// attribute inetAddr
|
||||
@javax.persistence.Column(name="inet_addr", columnDefinition="inet", unique=true)
|
||||
private String inetAddr;
|
||||
public String getInetAddr() { return inetAddr; }
|
||||
public void setInetAddr( String inetAddr ) { this.inetAddr = inetAddr; }
|
||||
|
||||
// attribute description
|
||||
@javax.persistence.Column(name="description", columnDefinition="character varying(100)")
|
||||
private String description;
|
||||
public String getDescription() { return description; }
|
||||
public void setDescription( String description ) { this.description = description; }
|
||||
|
||||
/// {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew()
|
||||
{
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
/// {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser( EntityManager em )
|
||||
{
|
||||
return null; // TODO: kinda somebody like root needed
|
||||
}
|
||||
}
|
280
hsarback/src/de/hsadmin/mods/pac/Pac.java
Normal file
280
hsarback/src/de/hsadmin/mods/pac/Pac.java
Normal file
@ -0,0 +1,280 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.CascadeType.ALL;
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.FetchType.LAZY;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.mods.cust.Customer;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
@javax.persistence.Entity(name = "Pacs")
|
||||
@javax.persistence.Table(name = "packet")
|
||||
@javax.persistence.SequenceGenerator(name = "PacsSeqGen", sequenceName = "packet_packet_id_seq")
|
||||
@de.hsadmin.core.model.EntityInfo(name = "Paket")
|
||||
public class Pac extends de.hsadmin.core.model.Entity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1201899873300190132L;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "PacsSeqGen")
|
||||
@javax.persistence.Column(name = "packet_id")
|
||||
private long id;
|
||||
|
||||
@javax.persistence.Column(name = "packet_name", unique = true)
|
||||
private String name;
|
||||
|
||||
@javax.persistence.JoinColumn(name = "bp_id")
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private Customer customer;
|
||||
|
||||
@javax.persistence.JoinColumn(name = "hive_id")
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private Hive hive;
|
||||
|
||||
@javax.persistence.Column(name = "created")
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date created;
|
||||
|
||||
@javax.persistence.Column(name = "cancelled", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date cancelled;
|
||||
|
||||
@javax.persistence.Column(name = "order_number", nullable = true)
|
||||
private String orderNo;
|
||||
|
||||
@javax.persistence.Column(name = "webserver_group", nullable = true)
|
||||
private String webserverGroup;
|
||||
|
||||
@javax.persistence.JoinColumn(name = "cur_inet_addr_id", nullable = true)
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private INetAddress curINetAddr;
|
||||
|
||||
@javax.persistence.JoinColumn(name = "old_inet_addr_id", nullable = true)
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private INetAddress oldINetAddr;
|
||||
|
||||
@javax.persistence.OneToMany(fetch = LAZY, cascade = ALL)
|
||||
private java.util.Set<PacComponent> pacComponents;
|
||||
|
||||
@javax.persistence.OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "pac")
|
||||
private java.util.Set<UnixUser> unixUser;
|
||||
|
||||
public Pac() {
|
||||
}
|
||||
|
||||
public Pac(String name, Customer cust, BasePac basePac, Hive hive) {
|
||||
this.name = name;
|
||||
this.customer = cust;
|
||||
this.hive = hive;
|
||||
|
||||
this.created = new java.util.Date();
|
||||
this.webserverGroup = "httpd";
|
||||
this.curINetAddr = hive.getInetAddr();
|
||||
|
||||
pacComponents = new java.util.HashSet<PacComponent>();
|
||||
java.util.Date today = new java.util.Date();
|
||||
for (Component comp : basePac.getComponents()) {
|
||||
PacComponent pacComp = new PacComponent(basePac,
|
||||
comp.getBaseComponent(), this, comp.getDefaultQuantity(),
|
||||
today, null);
|
||||
pacComponents.add(pacComp);
|
||||
System.err.println("TRACE [Pac]: added pacComp " + pacComp + " to "
|
||||
+ getName());
|
||||
}
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "obj.name='" + humanKey + "'";
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public Hive getHive() {
|
||||
return hive;
|
||||
}
|
||||
|
||||
public void setHive(Hive hive) {
|
||||
this.hive = hive;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(Date cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public String getOrderNo() {
|
||||
return orderNo;
|
||||
}
|
||||
|
||||
public void setOrderNo(String orderNo) {
|
||||
this.orderNo = orderNo;
|
||||
}
|
||||
|
||||
public String getwebserverGroup() {
|
||||
return webserverGroup;
|
||||
}
|
||||
|
||||
public void setwebserverGroup(String webserverGroup) {
|
||||
this.webserverGroup = webserverGroup;
|
||||
}
|
||||
|
||||
public INetAddress getCurINetAddr() {
|
||||
return curINetAddr;
|
||||
}
|
||||
|
||||
public void setCurINetAddr(INetAddress curINetAddr) {
|
||||
this.curINetAddr = curINetAddr;
|
||||
}
|
||||
|
||||
public INetAddress getOldINetAddr() {
|
||||
return oldINetAddr;
|
||||
}
|
||||
|
||||
public void setOldINetAddr(INetAddress oldINetAddr) {
|
||||
this.oldINetAddr = oldINetAddr;
|
||||
}
|
||||
|
||||
// virtual attribute basePac
|
||||
/*
|
||||
* This does not work, JPA/Hibernate always wants to create an invalid row
|
||||
* in packet_component
|
||||
*
|
||||
* @javax.persistence.ManyToOne(fetch=EAGER, optional=true) // optional
|
||||
* should be default anyway
|
||||
*
|
||||
* @javax.persistence.JoinTable( name="packet_component",
|
||||
* joinColumns=@javax.persistence.JoinColumn(name="packet_id"),
|
||||
* inverseJoinColumns=@javax.persistence.JoinColumn(name="basepacket_id") )
|
||||
*/
|
||||
@javax.persistence.Transient
|
||||
public BasePac getBasePac() {
|
||||
return getPacComponents().iterator().next().getBasePac();
|
||||
}
|
||||
|
||||
public void setBasePac(BasePac basePac) {
|
||||
// TODO: needs code to change basePac in all pacComponents
|
||||
}
|
||||
|
||||
public java.util.Set<PacComponent> getPacComponents() {
|
||||
return pacComponents;
|
||||
}
|
||||
|
||||
public void setPacComponents(java.util.Set<PacComponent> pacComponents) {
|
||||
this.pacComponents = pacComponents;
|
||||
}
|
||||
|
||||
public PacComponent getPacComponent(String feature) {
|
||||
for (PacComponent pc : getPacComponents())
|
||||
if (feature.equals(pc.getBaseComponent().getFeature()))
|
||||
return pc;
|
||||
return null;
|
||||
}
|
||||
|
||||
public java.util.Set<UnixUser> getUnixUser() {
|
||||
return unixUser;
|
||||
}
|
||||
|
||||
public void setUnixUser(java.util.Set<UnixUser> unixUser) {
|
||||
this.unixUser = unixUser;
|
||||
}
|
||||
|
||||
// generic
|
||||
public String toString() {
|
||||
return super.toString() + "{ name=" + name + " }";
|
||||
}
|
||||
|
||||
// / {$inheritDoc}
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
// / {$inheritDoc}
|
||||
@Override
|
||||
public String getHiveName() {
|
||||
if (isNew())
|
||||
return null;
|
||||
else
|
||||
return getHive().getHiveName();
|
||||
}
|
||||
|
||||
// / {@inheritDoc}
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return customer.owningUser(em);
|
||||
}
|
||||
|
||||
public UnixUser getAdminUser(EntityManager em) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
// / determines whether the given user has full read access on all merged
|
||||
// fields of this entity
|
||||
public boolean isReadAllowedFor(UnixUser loginUser) {
|
||||
return getName().equals(loginUser.getName())
|
||||
|| super.isReadAllowedFor(loginUser);
|
||||
}
|
||||
|
||||
// / query restriction for access control
|
||||
public static String restriction() {
|
||||
return
|
||||
// all pacs of customer
|
||||
"obj.customer.name=:loginUserName OR " +
|
||||
|
||||
// pac of packet admin
|
||||
"obj.name=:loginUserName";
|
||||
}
|
||||
}
|
99
hsarback/src/de/hsadmin/mods/pac/PacComponent.java
Normal file
99
hsarback/src/de/hsadmin/mods/pac/PacComponent.java
Normal file
@ -0,0 +1,99 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
@javax.persistence.Entity(name = "PacComponents")
|
||||
@javax.persistence.Table(name = "packet_component")
|
||||
@IdClass(PacComponentId.class)
|
||||
public class PacComponent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5359873462163274873L;
|
||||
|
||||
@javax.persistence.Id
|
||||
private Pac pac;
|
||||
|
||||
@javax.persistence.Id
|
||||
private BaseComponent baseComponent;
|
||||
|
||||
@javax.persistence.JoinColumn(name = "basepacket_id", columnDefinition = "integer", nullable = false)
|
||||
@javax.persistence.ManyToOne(fetch = EAGER)
|
||||
private BasePac basePac;
|
||||
|
||||
@javax.persistence.Column(name = "quantity", columnDefinition = "integer")
|
||||
private int quantity;
|
||||
|
||||
@javax.persistence.Column(name = "created", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date created;
|
||||
|
||||
@javax.persistence.Column(name = "cancelled", columnDefinition = "date", nullable = true)
|
||||
@javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
|
||||
private Date cancelled;
|
||||
|
||||
public PacComponent() {
|
||||
}
|
||||
|
||||
public PacComponent(BasePac basePac, BaseComponent baseComp, Pac pac,
|
||||
int quantity, Date created, Date cancelled) {
|
||||
this.basePac = basePac;
|
||||
this.pac = pac;
|
||||
this.baseComponent = baseComp;
|
||||
this.quantity = quantity;
|
||||
this.created = created;
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public BasePac getBasePac() {
|
||||
return basePac;
|
||||
}
|
||||
|
||||
public void setbasePac(BasePac basePac) {
|
||||
this.basePac = basePac;
|
||||
}
|
||||
|
||||
public BaseComponent getBaseComponent() {
|
||||
return baseComponent;
|
||||
}
|
||||
|
||||
public void setBaseComponent(BaseComponent baseComponent) {
|
||||
this.baseComponent = baseComponent;
|
||||
}
|
||||
|
||||
public Pac getPac() {
|
||||
return pac;
|
||||
}
|
||||
|
||||
public void setPac(Pac pac) {
|
||||
this.pac = pac;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(Date cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
}
|
23
hsarback/src/de/hsadmin/mods/pac/PacComponentId.java
Normal file
23
hsarback/src/de/hsadmin/mods/pac/PacComponentId.java
Normal file
@ -0,0 +1,23 @@
|
||||
package de.hsadmin.mods.pac;
|
||||
|
||||
|
||||
public class PacComponentId {
|
||||
|
||||
public long pac;
|
||||
public long baseComponent;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj instanceof PacComponentId) {
|
||||
PacComponentId other = (PacComponentId) obj;
|
||||
return pac == other.pac && baseComponent == other.baseComponent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (new Long(pac ^ baseComponent % Integer.MAX_VALUE)).intValue();
|
||||
}
|
||||
|
||||
}
|
38
hsarback/src/de/hsadmin/mods/qstat/QTaskModuleImpl.java
Normal file
38
hsarback/src/de/hsadmin/mods/qstat/QTaskModuleImpl.java
Normal file
@ -0,0 +1,38 @@
|
||||
package de.hsadmin.mods.qstat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.hsadmin.core.model.AbstractModuleImpl;
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.HSAdminException;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
public class QTaskModuleImpl extends AbstractModuleImpl {
|
||||
|
||||
private static final long serialVersionUID = 3942424688570077274L;
|
||||
|
||||
public QTaskModuleImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String condition, String orderBy) throws HSAdminException {
|
||||
// do query and return result
|
||||
if (orderBy == null || orderBy.length() == 0) {
|
||||
orderBy = "ORDER BY obj.started DESC";
|
||||
}
|
||||
return super.search(entityClass, condition, orderBy);
|
||||
}
|
||||
|
||||
// throws an AuthorisationException if the login user has no write acess
|
||||
// on the pac of the given UnixUser
|
||||
@SuppressWarnings("unused")
|
||||
private boolean hasAccessOnPacOf(UnixUser user) {
|
||||
// only pac admins (same name as pac) and the owner (customer) have
|
||||
// write access to the pac
|
||||
boolean isPacAdmin = getLoginUser().getName().equals(
|
||||
user.getPac().getName());
|
||||
boolean isCustomer = getLoginUser().getName().equals(
|
||||
user.getPac().getCustomer().getName());
|
||||
return isPacAdmin || isCustomer;
|
||||
}
|
||||
}
|
323
hsarback/src/de/hsadmin/mods/user/UnixUser.java
Normal file
323
hsarback/src/de/hsadmin/mods/user/UnixUser.java
Normal file
@ -0,0 +1,323 @@
|
||||
package de.hsadmin.mods.user;
|
||||
|
||||
import static javax.persistence.FetchType.EAGER;
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import de.hsadmin.core.model.EntityInfo;
|
||||
import de.hsadmin.mods.pac.Pac;
|
||||
|
||||
@Entity(name = "UnixUsers")
|
||||
@Table(name = "unixuser")
|
||||
@SequenceGenerator(name = "UnixUsersSeqGen", sequenceName = "unixuser_unixuser_id_seq")
|
||||
@EntityInfo(name = "UNIX-Zugang/Mailbox")
|
||||
public class UnixUser extends de.hsadmin.core.model.Entity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7823071611805642906L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = SEQUENCE, generator = "UnixUsersSeqGen")
|
||||
@Column(name = "unixuser_id", columnDefinition = "integer", updatable=false, insertable=false)
|
||||
private long id;
|
||||
|
||||
// attribute userid - really NOT unique!
|
||||
@Column(name = "userid", columnDefinition = "integer", nullable = false, updatable=false)
|
||||
private long userId;
|
||||
|
||||
@Column(name = "name", columnDefinition = "character varying(24)", unique = true, updatable=false)
|
||||
private String name;
|
||||
|
||||
@Transient
|
||||
private String password;
|
||||
|
||||
@JoinColumn(name = "packet_id", columnDefinition = "integer", updatable=false)
|
||||
@ManyToOne(fetch = EAGER)
|
||||
private Pac pac;
|
||||
|
||||
@Column(name = "comment", columnDefinition = "character varying(128)")
|
||||
private String comment;
|
||||
|
||||
@Column(name = "shell", columnDefinition = "character varying(32)")
|
||||
private String shell;
|
||||
|
||||
@Column(name = "homedir", columnDefinition = "character varying(48)", updatable=false)
|
||||
private String homedir;
|
||||
|
||||
@Column(name = "locked", columnDefinition = "boolean")
|
||||
private boolean locked;
|
||||
|
||||
@Column(name = "quota_softlimit", columnDefinition = "integer")
|
||||
private Integer quotaSoftlimit;
|
||||
|
||||
@Column(name = "quota_hardlimit", columnDefinition = "integer")
|
||||
private Integer quotaHardlimit;
|
||||
|
||||
public UnixUser() {
|
||||
}
|
||||
|
||||
public UnixUser(Pac pac, String name, int userId, String comment,
|
||||
String homeDir, String shell) {
|
||||
this.pac = pac;
|
||||
this.name = name;
|
||||
this.userId = userId;
|
||||
this.comment = comment;
|
||||
this.shell = shell;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* fixes some fields if null
|
||||
*/
|
||||
public void init() {
|
||||
if (comment == null) {
|
||||
comment = name;
|
||||
}
|
||||
if (homedir == null) {
|
||||
this.homedir = getDefaultHomedir();
|
||||
}
|
||||
if (shell == null) {
|
||||
shell = "/bin/false";
|
||||
}
|
||||
if (quotaSoftlimit == null) {
|
||||
quotaSoftlimit = new Integer(0);
|
||||
}
|
||||
if (quotaHardlimit == null) {
|
||||
quotaHardlimit = new Integer(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static String createQueryFromStringKey(String humanKey) {
|
||||
return "obj.name='" + humanKey + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createStringKey() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
// TODO: should NOT be an external property
|
||||
return password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Pac getPac() {
|
||||
return pac;
|
||||
}
|
||||
|
||||
public void setPac(Pac pac) {
|
||||
this.pac = pac;
|
||||
pac.getUnixUser().add(this);
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String getShell() {
|
||||
return shell;
|
||||
}
|
||||
|
||||
public void setShell(String shell) {
|
||||
this.shell = shell;
|
||||
}
|
||||
|
||||
public String getHomedir() {
|
||||
return homedir;
|
||||
}
|
||||
|
||||
public void setHomedir(String homedir) {
|
||||
this.homedir = homedir;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the user has the default homedir path
|
||||
*/
|
||||
public boolean isDefaultHomedir() {
|
||||
return getHomedir().equals(getDefaultHomedir());
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the default homedir path
|
||||
*/
|
||||
private String getDefaultHomedir() {
|
||||
String pacName = pac.getName();
|
||||
if (name.equals(pacName))
|
||||
return "/home/pacs/" + pacName;
|
||||
else
|
||||
return "/home/pacs/" + pacName + "/users/"
|
||||
+ name.substring(pacName.length() + 1);
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public Integer getQuotaSoftlimit() {
|
||||
return quotaSoftlimit;
|
||||
}
|
||||
|
||||
public void setQuotaSoftlimit(Integer quota) {
|
||||
this.quotaSoftlimit = quota;
|
||||
}
|
||||
|
||||
public void setQuotaHardlimit(Integer quotaLimit) {
|
||||
this.quotaHardlimit = quotaLimit;
|
||||
}
|
||||
|
||||
public Integer getQuotaHardlimit() {
|
||||
return quotaHardlimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return id == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(EntityManager em, UnixUser loginUser) {
|
||||
pac = loginUser.getPac(); // a default useful for the pac admin
|
||||
// TODO should not be hardcoded, but how?
|
||||
homedir = "/home/pacs/" + pac.getName() + "/users/...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnixUser merge(EntityManager em, UnixUser loginUser) {
|
||||
if (homedir == null)
|
||||
homedir = "/home/pacs/" + pac.getName() + "/users/"
|
||||
+ getName().substring(6); // TODO: Hack
|
||||
|
||||
UnixUser dbEntity = (UnixUser) super.merge(em, loginUser);
|
||||
dbEntity.setPassword(this.getPassword()); // because this is not in database
|
||||
return dbEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHiveName() {
|
||||
if (isNew())
|
||||
return null;
|
||||
else
|
||||
return getPac().getHiveName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnixUser owningUser(EntityManager em) {
|
||||
return getPac().getAdminUser(em);
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether this user account is a hostmaster account
|
||||
*/
|
||||
public boolean hasHostmasterRole() {
|
||||
// TODO: hardcoded Hostsharing conventions
|
||||
return getName().length() == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether this user account has rights on the given customer
|
||||
*/
|
||||
public boolean hasCustomerRoleFor(de.hsadmin.mods.cust.Customer cust) {
|
||||
// TODO: hardcoded Hostsharing conventions
|
||||
return getName().equals(cust.getName()) || hasHostmasterRole();
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether this user account has admin rights on the given pac
|
||||
*/
|
||||
public boolean hasPacAdminRoleFor(de.hsadmin.mods.pac.Pac pac) {
|
||||
// TODO: hardcoded Hostsharing conventions
|
||||
return pac.getName().equals(getName())
|
||||
|| hasCustomerRoleFor(pac.getCustomer());
|
||||
}
|
||||
|
||||
/**
|
||||
* determines whether this user account has admin rights on the given dom
|
||||
*/
|
||||
// public boolean hasDomAdminRoleFor(de.hsadmin.mods.dom.Domain dom) {
|
||||
// // TODO: hardcoded Hostsharing conventions
|
||||
// return this.getId() == dom.getUser().getId()
|
||||
// || hasPacAdminRoleFor(dom.getUser().getPac());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isWriteAllowedFor(UnixUser loginUser) {
|
||||
String pacName = pac.getName();
|
||||
if (!name.equals(pacName) && !name.startsWith(pacName + "-"))
|
||||
return false;
|
||||
|
||||
if (super.isWriteAllowedFor(loginUser))
|
||||
return true;
|
||||
return this == loginUser || loginUser.hasPacAdminRoleFor(getPac());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadAllowedFor(UnixUser loginUser) {
|
||||
if (super.isReadAllowedFor(loginUser))
|
||||
return true;
|
||||
return this.getId() == loginUser.getId() || loginUser.hasPacAdminRoleFor(getPac());
|
||||
}
|
||||
|
||||
/**
|
||||
* JPA-Query restriction for these entities
|
||||
*/
|
||||
public static String restriction() {
|
||||
return
|
||||
// customers can access all users in their pacs
|
||||
"obj.pac.customer.name = :loginUserName OR "
|
||||
// packet admins can access all users in their pacs
|
||||
+ "obj.pac.name = :loginUserName OR "
|
||||
// all users can access their own account
|
||||
+ "obj.name = :loginUserName";
|
||||
}
|
||||
}
|
279
hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java
Normal file
279
hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java
Normal file
@ -0,0 +1,279 @@
|
||||
package de.hsadmin.mods.user;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import de.hsadmin.core.model.AuthorisationException;
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.AbstractModuleImpl;
|
||||
import de.hsadmin.core.model.HSAdminException;
|
||||
import de.hsadmin.mods.pac.Pac;
|
||||
|
||||
public class UnixUserModuleImpl extends AbstractModuleImpl {
|
||||
|
||||
private static final long serialVersionUID = 7480353553685400790L;
|
||||
|
||||
public UnixUserModuleImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity initialize(Entity newEntity) throws AuthorisationException {
|
||||
UnixUser newUnixUser = (UnixUser) super.initialize(newEntity);
|
||||
newUnixUser.setName(getLoginUser().getPac().getName() + '-');
|
||||
return newUnixUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity find(Class<? extends Entity> entityClass, Object key) throws HSAdminException {
|
||||
// do query
|
||||
UnixUser res = (UnixUser) super.find(entityClass, key);
|
||||
|
||||
// check access rights
|
||||
needsPartialAccessOnPacOf(res, "find");
|
||||
|
||||
// return clean result
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity findByString(Class<? extends Entity> entityClass, String key) throws HSAdminException {
|
||||
// do query
|
||||
UnixUser res = (UnixUser) super.findByString(entityClass, key);
|
||||
|
||||
// return directly (checking rights already done in search within
|
||||
// findByString)
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> search(Class<? extends Entity> entityClass, String condition, String orderBy) throws HSAdminException {
|
||||
// do query
|
||||
if (orderBy == null || orderBy.length() == 0) {
|
||||
orderBy = "ORDER BY obj.name ASC";
|
||||
}
|
||||
List<Entity> res = super.search(entityClass, condition, orderBy);
|
||||
List<Entity> ret = new LinkedList<Entity>();
|
||||
|
||||
// remove entities where login user has no access rights
|
||||
if (res != null) {
|
||||
for (Entity entity : res) {
|
||||
try {
|
||||
UnixUser returnedUnixUser = (UnixUser) entity;
|
||||
needsPartialAccessOnPacOf(returnedUnixUser, "search");
|
||||
ret.add(returnedUnixUser);
|
||||
} catch (AuthorisationException exc) {
|
||||
} // ignore
|
||||
}
|
||||
}
|
||||
|
||||
// return clean result
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity add(Entity newEntity) throws HSAdminException {
|
||||
EntityManager em = getEntityManager();
|
||||
// only allow pac which matches the username (TODO: hard coded
|
||||
// Hostsharing convention)
|
||||
UnixUser newUnixUser = (UnixUser) newEntity;
|
||||
// validation of username and password
|
||||
String name = newUnixUser.getName();
|
||||
if (name == null) {
|
||||
throw new HSAdminException("username is required");
|
||||
}
|
||||
String userName = name.toLowerCase().trim();
|
||||
for (char c : userName.toCharArray()) {
|
||||
if (!(Character.isLetterOrDigit(c) || c == '.' || c == '-' || c == '_')) {
|
||||
throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
|
||||
}
|
||||
}
|
||||
if (userName.length() < 7 || userName.charAt(5) != '-' || userName.lastIndexOf('-') > 5) {
|
||||
throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
|
||||
}
|
||||
String passWord = newUnixUser.getPassword();
|
||||
if (passWord == null || passWord.length() == 0) {
|
||||
throw new HSAdminException("password is required");
|
||||
}
|
||||
if (passWord.indexOf(':') >= 0) {
|
||||
throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
|
||||
}
|
||||
Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
|
||||
qPac.setParameter("pacName", userName.substring(0, 5));
|
||||
Pac pac = (Pac) qPac.getSingleResult();
|
||||
newUnixUser.setName(userName);
|
||||
newUnixUser.setHomedir("/home/pacs/" + userName.substring(0, 5) + "/users/" + userName.substring(6));
|
||||
|
||||
// no appropriate uid?
|
||||
if (newUnixUser.getUserId() < 1000) {
|
||||
// determine next free uid
|
||||
long nUID = 20000;
|
||||
Query qUID = em.createQuery("SELECT MAX(u.userId) FROM UnixUsers u");
|
||||
Long maxUid = (Long) qUID.getSingleResult();
|
||||
if (maxUid >= nUID)
|
||||
nUID = maxUid + 1;
|
||||
newUnixUser.setUserId(nUID);
|
||||
} else {
|
||||
// given uid belongs to same pac?
|
||||
Query q = em.createQuery("SELECT u.userId FROM UnixUsers u WHERE u.userId = :userId AND u.pac = :pac");
|
||||
q.setParameter("userId", newUnixUser.getUserId());
|
||||
q.setParameter("pac", pac);
|
||||
List<?> idOfSamePac = q.getResultList();
|
||||
if (idOfSamePac.size() == 0) {
|
||||
throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
|
||||
}
|
||||
}
|
||||
|
||||
// don't move this up, it will update the new entity still with wrong
|
||||
// userid!
|
||||
newUnixUser.setPac(pac);
|
||||
newUnixUser.init();
|
||||
|
||||
// authorisation check
|
||||
needsFullAccessOnPacOf(newUnixUser, "add");
|
||||
|
||||
// add new entity
|
||||
return super.add(newEntity);
|
||||
}
|
||||
|
||||
private EntityManager getEntityManager() {
|
||||
return getTransaction().getEntityManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity update(Entity existingEntity) throws HSAdminException {
|
||||
// get the entity from the database
|
||||
UnixUser detachedUnixUser = (UnixUser) existingEntity;
|
||||
UnixUser attachedUnixUser = getEntityManager().find(detachedUnixUser.getClass(),
|
||||
detachedUnixUser.getId());
|
||||
|
||||
// authorisation check
|
||||
needsFullAccessOnUser(attachedUnixUser, "update");
|
||||
|
||||
// update fields where the login user has write access
|
||||
if (attachedUnixUser.getUserId() != detachedUnixUser.getUserId())
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "id");
|
||||
attachedUnixUser.setName(detachedUnixUser.getName());
|
||||
attachedUnixUser.setPassword(detachedUnixUser.getPassword());
|
||||
if (hasFullAccessOnPacOf(attachedUnixUser))
|
||||
attachedUnixUser.setComment(detachedUnixUser.getComment());
|
||||
else if (!attachedUnixUser.getComment().equals(
|
||||
detachedUnixUser.getComment()))
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "comment");
|
||||
if (hasFullAccessOnPacOf(attachedUnixUser))
|
||||
attachedUnixUser.setHomedir(detachedUnixUser.getHomedir());
|
||||
else if (!attachedUnixUser.getHomedir().equals(
|
||||
detachedUnixUser.getHomedir()))
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "homedir");
|
||||
if (!attachedUnixUser.getShell().equals(detachedUnixUser.getShell()))
|
||||
if (hasFullAccessOnPacOf(attachedUnixUser)
|
||||
|| isLoginShell(attachedUnixUser.getShell())
|
||||
|| !isLoginShell(detachedUnixUser.getShell()))
|
||||
attachedUnixUser.setShell(detachedUnixUser.getShell());
|
||||
else
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "shell");
|
||||
if (attachedUnixUser.isLocked() != detachedUnixUser.isLocked())
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "locked");
|
||||
if (detachedUnixUser.getQuotaSoftlimit() != null) {
|
||||
if (hasFullAccessOnPacOf(attachedUnixUser)) {
|
||||
attachedUnixUser.setQuotaSoftlimit(detachedUnixUser.getQuotaSoftlimit());
|
||||
if (detachedUnixUser.getQuotaHardlimit() != null) {
|
||||
attachedUnixUser.setQuotaHardlimit(detachedUnixUser.getQuotaHardlimit());
|
||||
}
|
||||
}
|
||||
else {
|
||||
Integer oldQuota = attachedUnixUser.getQuotaSoftlimit();
|
||||
Integer newQuota = detachedUnixUser.getQuotaSoftlimit();
|
||||
if (oldQuota != newQuota && !oldQuota.equals(newQuota))
|
||||
throw new AuthorisationException(getLoginUser(), "update",
|
||||
detachedUnixUser, "quota");
|
||||
}
|
||||
}
|
||||
|
||||
// update entity
|
||||
return super.update(attachedUnixUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Entity existingEntity) throws HSAdminException {
|
||||
// get the entity from the database
|
||||
UnixUser detachedUnixUser = (UnixUser) existingEntity;
|
||||
UnixUser attachedUnixUser = getEntityManager().find(detachedUnixUser.getClass(),
|
||||
detachedUnixUser.getId());
|
||||
|
||||
// authorisation check
|
||||
if (attachedUnixUser.getName().length() < 7) {
|
||||
throw new AuthorisationException(attachedUnixUser, "delete");
|
||||
}
|
||||
needsFullAccessOnPacOf(attachedUnixUser, "delete");
|
||||
|
||||
// delete entity
|
||||
super.delete(attachedUnixUser);
|
||||
}
|
||||
|
||||
// throws an AuthorisationException if the login user has no write acess
|
||||
// on the pac of the given UnixUser
|
||||
private boolean hasFullAccessOnPacOf(UnixUser user) {
|
||||
// only pac admins (same name as pac) and the owner (customer) have
|
||||
// write access to the pac
|
||||
boolean isPacAdmin = getLoginUser().getName().equals(
|
||||
user.getPac().getName());
|
||||
boolean isCustomer = getLoginUser().getName().equals(
|
||||
user.getPac().getCustomer().getName());
|
||||
boolean isHostmaster = getLoginUser().hasHostmasterRole();
|
||||
return isPacAdmin || isCustomer || isHostmaster;
|
||||
}
|
||||
|
||||
// throws an AuthorisationException if the login user has no write acess
|
||||
// on the pac of the given UnixUser
|
||||
private void needsFullAccessOnPacOf(UnixUser user, String method)
|
||||
throws AuthorisationException {
|
||||
if (!hasFullAccessOnPacOf(user))
|
||||
throw new AuthorisationException(getLoginUser(), method, user);
|
||||
}
|
||||
|
||||
// throws an AuthorisationException if the login user has no read acess on
|
||||
// the pac of the given UnixUser
|
||||
private void needsPartialAccessOnPacOf(UnixUser user, String method)
|
||||
throws AuthorisationException {
|
||||
if (!hasFullAccessOnPacOf(user)
|
||||
&& getLoginUser().getPac().id() != user.getPac().id())
|
||||
throw new AuthorisationException(getLoginUser(), method, user);
|
||||
}
|
||||
|
||||
// throws an AuthorisationException if the login user has not even partial
|
||||
// write access on the given UnixUser
|
||||
private void needsFullAccessOnUser(UnixUser user, String method)
|
||||
throws AuthorisationException {
|
||||
// neither pac admin (same name as pac), pac owner (customer) nor the
|
||||
// user itself?
|
||||
if (!hasFullAccessOnPacOf(user) && !getLoginUser().sameIdAs(user))
|
||||
throw new AuthorisationException(getLoginUser(), method, user);
|
||||
}
|
||||
|
||||
// returns true if the given shell is a login shell
|
||||
private static boolean isLoginShell(String shell) {
|
||||
// TODO: list of login shells should not be hardcoded
|
||||
if (shell.equals("/bin/sh"))
|
||||
return true;
|
||||
if (shell.equals("/bin/bash"))
|
||||
return true;
|
||||
if (shell.equals("/bin/csh"))
|
||||
return true;
|
||||
if (shell.equals("/bin/tcsh"))
|
||||
return true;
|
||||
if (shell.equals("/bin/zsh"))
|
||||
return true;
|
||||
if (shell.equals("/bin/ksh"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
105
hsarback/src/de/hsadmin/mods/user/UnixUserProcessorFactory.java
Normal file
105
hsarback/src/de/hsadmin/mods/user/UnixUserProcessorFactory.java
Normal file
@ -0,0 +1,105 @@
|
||||
package de.hsadmin.mods.user;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.qserv.CompoundProcessor;
|
||||
import de.hsadmin.core.qserv.EntityProcessorFactory;
|
||||
import de.hsadmin.core.qserv.Processor;
|
||||
import de.hsadmin.core.qserv.ShellProcessor;
|
||||
|
||||
/**
|
||||
* Factory class which creates Processor instances for dealing with UNIX user
|
||||
* accounts.
|
||||
*
|
||||
* @author mi
|
||||
*/
|
||||
public class UnixUserProcessorFactory implements EntityProcessorFactory {
|
||||
|
||||
/**
|
||||
* @return a Processor which creates a new UNIX user account
|
||||
*/
|
||||
public <T extends Entity> Processor createCreateProcessor(EntityManager em,
|
||||
T entity) {
|
||||
UnixUser user = (UnixUser) entity;
|
||||
CompoundProcessor aCP = new CompoundProcessor(new ShellProcessor(
|
||||
"newusers", user.getName() + ":" + user.getPassword() + ":"
|
||||
+ user.getUserId() + ":" + user.getPac().getName()
|
||||
+ ":" + user.getComment() + ":" + user.getHomedir()
|
||||
+ ":" + user.getShell() + "\n"));
|
||||
appendSetQuotaProcessor(aCP, user);
|
||||
appendMakeMaildirProcessor(aCP, user);
|
||||
return aCP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Processor which updates an existing UNIX user account
|
||||
*/
|
||||
public <T extends Entity> Processor createUpdateProcessor(EntityManager em,
|
||||
T entity) {
|
||||
UnixUser user = (UnixUser) entity;
|
||||
CompoundProcessor aCP = new CompoundProcessor(new ShellProcessor(
|
||||
"usermod -c '" + user.getComment() + "'" + " -d '"
|
||||
+ user.getHomedir() + "'" + " -s '" + user.getShell()
|
||||
+ "' " + user.getName()));
|
||||
if (user.getPassword() != null && user.getPassword().length() > 0)
|
||||
aCP.appendProcessor(new ShellProcessor("chpasswd ", user.getName()
|
||||
+ ":" + user.getPassword() + "\n"));
|
||||
appendSetQuotaProcessor(aCP, user);
|
||||
return aCP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Processor which deletes an existing UNIX user account
|
||||
*/
|
||||
public <T extends Entity> Processor createDeleteProcessor(EntityManager em,
|
||||
T entity) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyMMdd-HHmm-");
|
||||
String trashPrefix = "/home/trash/" + sdf.format(new Date());
|
||||
|
||||
UnixUser user = (UnixUser) entity;
|
||||
CompoundProcessor aCP = new CompoundProcessor();
|
||||
if (user.isDefaultHomedir())
|
||||
aCP.appendProcessor(new ShellProcessor("mv '" + user.getHomedir()
|
||||
+ "' '" + trashPrefix + user.getName() + "'"));
|
||||
aCP.appendProcessor(new ShellProcessor("userdel " + user.getName()));
|
||||
return aCP;
|
||||
}
|
||||
|
||||
private void appendSetQuotaProcessor(CompoundProcessor aCP, UnixUser user) {
|
||||
Integer quotaSoft = user.getQuotaSoftlimit();
|
||||
if (quotaSoft == null || quotaSoft.intValue() == 0) {
|
||||
aCP.appendProcessor(new ShellProcessor("setquota -u "
|
||||
+ user.getName() + " 0 0 0 0 "
|
||||
+ "`df /home/pacs/ | tail -n1 | cut -d' ' -f1`"));
|
||||
return;
|
||||
}
|
||||
Integer userSoftQuota = quotaSoft * 1024;
|
||||
Integer quotaHard = user.getQuotaHardlimit();
|
||||
if (quotaHard == null) {
|
||||
quotaHard = new Integer(0);
|
||||
}
|
||||
Integer userHardQuota = quotaHard * 1024;
|
||||
if (userHardQuota.intValue() < userSoftQuota.intValue()) {
|
||||
// set default value
|
||||
userHardQuota = ((Double) (userSoftQuota * 1.5 + 32)).intValue();
|
||||
}
|
||||
aCP.appendProcessor(new ShellProcessor("setquota -u "
|
||||
+ user.getName() + " " + userSoftQuota + " "
|
||||
+ userHardQuota + " 0 0 "
|
||||
+ "`df /home/pacs/ | tail -n1 | cut -d' ' -f1`"));
|
||||
}
|
||||
|
||||
private void appendMakeMaildirProcessor(CompoundProcessor aCP, UnixUser user) {
|
||||
aCP.appendProcessor(
|
||||
new ShellProcessor(
|
||||
"su -l " + user.getName() + " -s \"/bin/bash\" -c \"maildirmake " +
|
||||
user.getHomedir() + "/Maildir" +
|
||||
"\""
|
||||
));
|
||||
}
|
||||
|
||||
}
|
229
hsarback/src/de/hsadmin/remote/AbstractRemote.java
Normal file
229
hsarback/src/de/hsadmin/remote/AbstractRemote.java
Normal file
@ -0,0 +1,229 @@
|
||||
package de.hsadmin.remote;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.hsadmin.core.model.AuthenticationException;
|
||||
import de.hsadmin.core.model.AuthorisationException;
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.model.GenericModuleImpl;
|
||||
import de.hsadmin.core.model.HSAdminException;
|
||||
import de.hsadmin.core.model.ModuleInterface;
|
||||
import de.hsadmin.core.model.TicketAuthentication;
|
||||
import de.hsadmin.core.model.Transaction;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
public abstract class AbstractRemote implements IRemote {
|
||||
|
||||
private TicketAuthentication authentication;
|
||||
|
||||
public AbstractRemote() {
|
||||
authentication = new TicketAuthentication();
|
||||
}
|
||||
|
||||
protected abstract Class<? extends Entity> getEntityClass();
|
||||
|
||||
protected abstract void entity2map(Entity entity, Map<String, String> resultMap);
|
||||
|
||||
protected abstract void map2entity(Map<String, String> setParams, Entity entity);
|
||||
|
||||
protected abstract void regularizeKeys(Map<String, String> whereParams);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see de.hsadmin.remote.IRemote#search(java.lang.String, java.lang.String, java.util.Map)
|
||||
*/
|
||||
public List<Map<String, String>> search(String runAsUser, String ticket,
|
||||
Map<String, String> whereParams) throws HSAdminException {
|
||||
String user = runAsUser;
|
||||
Transaction transaction = new Transaction(user);
|
||||
try {
|
||||
if (authentication.login(user, ticket)) {
|
||||
ModuleInterface module = new GenericModuleImpl(transaction);
|
||||
UnixUser unixUser = null;
|
||||
unixUser = (UnixUser) module.findByString(UnixUser.class, user);
|
||||
List<Entity> list = module.search(getEntityClass(),
|
||||
buildQueryCondition(whereParams), null);
|
||||
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
|
||||
for (Entity e : list) {
|
||||
HashMap<String, String> entry = new HashMap<String, String>();
|
||||
entity2map(e, entry);
|
||||
if (e.isReadAllowedFor(unixUser)) {
|
||||
result.add(entry);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new AuthenticationException("authentication failed");
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
throw new HSAdminException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new HSAdminException(e);
|
||||
} finally {
|
||||
transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see de.hsadmin.remote.IRemote#add(java.lang.String, java.lang.String, java.util.Map)
|
||||
*/
|
||||
public Map<String, String> add(String runAsUser, String ticket,
|
||||
Map<String, String> setParams) throws HSAdminException {
|
||||
String user = runAsUser;
|
||||
Transaction transaction = new Transaction(user);
|
||||
try {
|
||||
if (authentication.login(user, ticket)) {
|
||||
ModuleInterface module = new GenericModuleImpl(transaction);
|
||||
Constructor<? extends Entity> constructor =
|
||||
getEntityClass().getConstructor();
|
||||
Entity entity = constructor.newInstance();
|
||||
map2entity(setParams, entity);
|
||||
transaction.beginTransaction();
|
||||
Entity insertedEntity = module.add(entity);
|
||||
transaction.commitTransaction();
|
||||
HashMap<String, String> entry = new HashMap<String, String>();
|
||||
entity2map(insertedEntity, entry);
|
||||
return entry;
|
||||
} else {
|
||||
throw new AuthenticationException("authentication failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new HSAdminException(e);
|
||||
} finally {
|
||||
transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see de.hsadmin.remote.IRemote#delete(java.lang.String, java.lang.String, java.util.Map)
|
||||
*/
|
||||
public void delete(String runAsUser, String ticket,
|
||||
Map<String, String> whereParams) throws HSAdminException {
|
||||
String user = runAsUser;
|
||||
Transaction transaction = new Transaction(user);
|
||||
try {
|
||||
if (authentication.login(user, ticket)) {
|
||||
ModuleInterface module = new GenericModuleImpl(transaction);
|
||||
UnixUser unixUser = null;
|
||||
unixUser = (UnixUser) module.findByString(UnixUser.class, user);
|
||||
String queryCondition = buildQueryCondition(whereParams);
|
||||
if (queryCondition == null || queryCondition.length() == 0) {
|
||||
throw new HSAdminException(
|
||||
"better safe than sorry: no where parameter found");
|
||||
}
|
||||
List<Entity> list = module.search(getEntityClass(),
|
||||
queryCondition, null);
|
||||
transaction.beginTransaction();
|
||||
for (Entity e : list) {
|
||||
if (e.isWriteAllowedFor(unixUser)) {
|
||||
module.delete(e);
|
||||
} else {
|
||||
throw new AuthorisationException(unixUser, "delete", e);
|
||||
}
|
||||
}
|
||||
transaction.commitTransaction();
|
||||
} else {
|
||||
throw new AuthenticationException("authentication failed");
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
throw new HSAdminException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new HSAdminException(e);
|
||||
} finally {
|
||||
transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see de.hsadmin.remote.IRemote#update(java.lang.String, java.lang.String, java.util.Map, java.util.Map)
|
||||
*/
|
||||
public List<Map<String, String>> update(String runAsUser, String ticket,
|
||||
Map<String, String> setParams, Map<String, String> whereParams)
|
||||
throws HSAdminException {
|
||||
String user = runAsUser;
|
||||
Transaction transaction = new Transaction(user);
|
||||
try {
|
||||
if (authentication.login(user, ticket)) {
|
||||
ModuleInterface module = new GenericModuleImpl(transaction);
|
||||
UnixUser unixUser = null;
|
||||
unixUser = (UnixUser) module.findByString(UnixUser.class, user);
|
||||
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
|
||||
String queryCondition = buildQueryCondition(whereParams);
|
||||
if (queryCondition == null || queryCondition.length() == 0) {
|
||||
throw new HSAdminException(
|
||||
"better safe than sorry: no where parameter found");
|
||||
}
|
||||
List<Entity> list = module.search(getEntityClass(),
|
||||
queryCondition, "ORDER BY name ASC");
|
||||
transaction.beginTransaction();
|
||||
for (Entity update : list) {
|
||||
if (update.isWriteAllowedFor(unixUser)) {
|
||||
transaction.detach(update);
|
||||
map2entity(setParams, update);
|
||||
update = module.update(update);
|
||||
HashMap<String, String> entry = new HashMap<String, String>();
|
||||
entity2map(update, entry);
|
||||
result.add(entry);
|
||||
} else {
|
||||
throw new AuthorisationException(unixUser, "update", update);
|
||||
}
|
||||
}
|
||||
transaction.commitTransaction();
|
||||
return result;
|
||||
} else {
|
||||
throw new AuthenticationException("authentication failed");
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
throw new HSAdminException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new HSAdminException(e);
|
||||
} finally {
|
||||
transaction.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean assertNotNull(String string) {
|
||||
return string != null && string.length() > 0;
|
||||
}
|
||||
|
||||
protected boolean assertNotNull(Integer integ) {
|
||||
return integ != null;
|
||||
}
|
||||
|
||||
private String buildQueryCondition(Map<String, String> whereParams) {
|
||||
regularizeKeys(whereParams);
|
||||
StringBuffer cond = new StringBuffer();
|
||||
Iterator<String> keyIterator = whereParams.keySet().iterator();
|
||||
while (keyIterator.hasNext()) {
|
||||
if (cond.length() > 0) {
|
||||
cond.append(" AND ");
|
||||
}
|
||||
String field = keyIterator.next();
|
||||
String value = whereParams.get(field).replaceAll("'", "\'");
|
||||
cond.append("obj.");
|
||||
cond.append(field);
|
||||
cond.append(" = '");
|
||||
cond.append(value);
|
||||
cond.append("'");
|
||||
}
|
||||
return cond.toString();
|
||||
}
|
||||
|
||||
protected void replaceKey(Map<String, String> whereParams, String shortKey, String regularKey) {
|
||||
if (whereParams.containsKey(shortKey)) {
|
||||
String value = whereParams.get(shortKey);
|
||||
whereParams.remove(shortKey);
|
||||
whereParams.put(regularKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean assertNotNull(Date aDate) {
|
||||
return aDate != null;
|
||||
}
|
||||
|
||||
}
|
35
hsarback/src/de/hsadmin/remote/IRemote.java
Normal file
35
hsarback/src/de/hsadmin/remote/IRemote.java
Normal file
@ -0,0 +1,35 @@
|
||||
package de.hsadmin.remote;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.hsadmin.core.model.HSAdminException;
|
||||
|
||||
public interface IRemote {
|
||||
|
||||
public abstract List<Map<String, String>> search(
|
||||
String runAsUser,
|
||||
String ticket,
|
||||
Map<String, String> whereParams
|
||||
) throws HSAdminException;
|
||||
|
||||
public abstract Map<String, String> add(
|
||||
String runAsUser,
|
||||
String ticket,
|
||||
Map<String, String> setParams
|
||||
) throws HSAdminException;
|
||||
|
||||
public abstract void delete(
|
||||
String runAsUser,
|
||||
String ticket,
|
||||
Map<String, String> whereParams
|
||||
) throws HSAdminException;
|
||||
|
||||
public abstract List<Map<String, String>> update(
|
||||
String runAsUser,
|
||||
String ticket,
|
||||
Map<String, String> setParams,
|
||||
Map<String, String> whereParams
|
||||
) throws HSAdminException;
|
||||
|
||||
}
|
49
hsarback/src/de/hsadmin/remote/QueueTaskRemote.java
Normal file
49
hsarback/src/de/hsadmin/remote/QueueTaskRemote.java
Normal file
@ -0,0 +1,49 @@
|
||||
package de.hsadmin.remote;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.core.qserv.QueueTask;
|
||||
|
||||
public class QueueTaskRemote extends AbstractRemote {
|
||||
|
||||
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
|
||||
|
||||
@Override
|
||||
protected Class<? extends Entity> getEntityClass() {
|
||||
return QueueTask.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entity2map(Entity entity, Map<String, String> resultMap) {
|
||||
QueueTask task = (QueueTask) entity;
|
||||
resultMap.put("id", Long.toString(task.getId()));
|
||||
resultMap.put("status", task.getStatus().toString());
|
||||
resultMap.put("title", task.getTitle());
|
||||
resultMap.put("details", task.getDetails());
|
||||
resultMap.put("exception", task.getException());
|
||||
resultMap.put("user", task.getUser().getName());
|
||||
Date started = task.getStarted();
|
||||
if (assertNotNull(started)) {
|
||||
resultMap.put("started", df.format(started));
|
||||
}
|
||||
Date finished = task.getFinished();
|
||||
if (assertNotNull(finished)) {
|
||||
resultMap.put("finished", df.format(finished));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void map2entity(Map<String, String> setParams, Entity entity) {
|
||||
// never used
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void regularizeKeys(Map<String, String> whereParams) {
|
||||
replaceKey(whereParams, "user", "user.name");
|
||||
}
|
||||
|
||||
}
|
81
hsarback/src/de/hsadmin/remote/UnixUserRemote.java
Normal file
81
hsarback/src/de/hsadmin/remote/UnixUserRemote.java
Normal file
@ -0,0 +1,81 @@
|
||||
package de.hsadmin.remote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import de.hsadmin.core.model.Entity;
|
||||
import de.hsadmin.mods.user.UnixUser;
|
||||
|
||||
public class UnixUserRemote extends AbstractRemote {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Entity> getEntityClass() {
|
||||
return UnixUser.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entity2map(Entity entity, Map<String, String> map) {
|
||||
UnixUser user = (UnixUser) entity;
|
||||
map.put("id", Long.toString(user.getId()));
|
||||
map.put("name", user.getName());
|
||||
map.put("comment", user.getComment());
|
||||
map.put("userid", Long.toString(user.getUserId()));
|
||||
map.put("pac", user.getPac().getName());
|
||||
map.put("shell", user.getShell());
|
||||
map.put("homedir", user.getHomedir());
|
||||
Integer quotaSoft = user.getQuotaSoftlimit();
|
||||
if (assertNotNull(quotaSoft)) {
|
||||
map.put("quota_softlimit", quotaSoft.toString());
|
||||
}
|
||||
Integer quotaHard = user.getQuotaHardlimit();
|
||||
if (assertNotNull(quotaHard)) {
|
||||
map.put("quota_hardlimit", quotaHard.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void map2entity(Map<String, String> map, Entity entity) {
|
||||
UnixUser user = (UnixUser) entity;
|
||||
String id = map.get("id");
|
||||
if (assertNotNull(id)) {
|
||||
user.setId(Long.parseLong(id));
|
||||
}
|
||||
String name = map.get("name");
|
||||
if (assertNotNull(name)) {
|
||||
user.setName(name);
|
||||
}
|
||||
String password = map.get("password");
|
||||
if (assertNotNull(password)) {
|
||||
user.setPassword(password);
|
||||
}
|
||||
String comment = map.get("comment");
|
||||
if (assertNotNull(comment)) {
|
||||
user.setComment(comment);
|
||||
}
|
||||
String userid = map.get("userid");
|
||||
if (assertNotNull(userid)) {
|
||||
user.setUserId(Long.parseLong(userid));
|
||||
}
|
||||
String shell = map.get("shell");
|
||||
if (assertNotNull(shell)) {
|
||||
user.setShell(shell);
|
||||
}
|
||||
String homedir = map.get("homedir");
|
||||
if (assertNotNull(homedir)) {
|
||||
user.setHomedir(homedir);
|
||||
}
|
||||
String quota = map.get("quota_softlimit");
|
||||
if (assertNotNull(quota)) {
|
||||
user.setQuotaSoftlimit(Integer.parseInt(quota));
|
||||
}
|
||||
String quotaLimit = map.get("quota_hardlimit");
|
||||
if (assertNotNull(quotaLimit)) {
|
||||
user.setQuotaHardlimit(Integer.parseInt(quotaLimit));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void regularizeKeys(Map<String, String> whereParams) {
|
||||
replaceKey(whereParams, "pac", "pac.name");
|
||||
}
|
||||
|
||||
}
|
307
hsarback/src/net/sf/jtpl/Jtpl.java
Normal file
307
hsarback/src/net/sf/jtpl/Jtpl.java
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
Copyright 2009 jtpl.sourceforge.net
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package net.sf.jtpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <b>Jtpl: a very simple template engine for Java</b><br>
|
||||
* Contact: <a href="mailto:emmanuel.alliel@gmail.com">emmanuel.alliel@gmail.com</a><br>
|
||||
* Web: <a href="http://jtpl.sourceforge.net">http://jtpl.sourceforge.net</a><br>
|
||||
*
|
||||
* @version $LastChangedRevision: 51 $
|
||||
* @author Emmanuel ALLIEL
|
||||
* @author Staffan Olsson
|
||||
*
|
||||
* <p>
|
||||
* Template syntax:<br>
|
||||
* Variables:<br>
|
||||
* <code>{VARIABLE_NAME}</code><br>
|
||||
* Blocks:<br>
|
||||
* <code><!-- BEGIN: BlockName --></code><br>
|
||||
* <code><!-- BEGIN: SubBlockName --></code><br>
|
||||
* <code><!-- END: SubBlockName --></code><br>
|
||||
* <code><!-- END: BlockName --></code><br>
|
||||
* <p>
|
||||
* License: Apache 2.0<br>
|
||||
*/
|
||||
|
||||
public class Jtpl implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -7175035307912229580L;
|
||||
|
||||
private HashMap<String, String> blocks = new HashMap<String, String>();
|
||||
private HashMap<String, String> parsedBlocks = new HashMap<String, String>();
|
||||
private HashMap<String, String> subBlocks = new HashMap<String, String>();
|
||||
private HashMap<String, String> vars = new HashMap<String, String>();
|
||||
// flag for backwards compatibility, will probably be reomved in future releases
|
||||
private boolean failSilently = false;
|
||||
private boolean implicitMain = false;
|
||||
|
||||
/**
|
||||
* Constructs a Jtpl object and reads the template from a file.
|
||||
* For backwards compatibility this constructor enables 'failSilently'.
|
||||
* @param fileName the <code>file name</code> of the template, exemple: "java/folder/index.tpl"
|
||||
* @throws IOException when an i/o error occurs while reading the template.
|
||||
*/
|
||||
public Jtpl(String fileName) throws IOException
|
||||
{
|
||||
this(new File(fileName));
|
||||
// this is the old constructor so it enables the old (pre-1.3) behavior on errors
|
||||
this.failSilently = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Jtpl object and reads the template from a file.
|
||||
* @param file readable file containing template source
|
||||
* @throws IOException when an i/o error occurs while reading the template.
|
||||
*/
|
||||
public Jtpl(File file) throws IOException
|
||||
{
|
||||
FileReader fr = new FileReader(file);
|
||||
String fileText = readFile(fr);
|
||||
makeTree(fileText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Jtpl object and reads the template from arbitrary input source.
|
||||
* @param template the template source
|
||||
* @throws IOException when an i/o error occurs while reading the template.
|
||||
*/
|
||||
public Jtpl(Reader template) throws IOException
|
||||
{
|
||||
String fileText = readFile(template);
|
||||
makeTree(fileText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a template variable.
|
||||
* For variables that are used in blocks, the variable value
|
||||
* must be set before <code>parse</code> is called.
|
||||
* @param varName the name of the variable to be set.
|
||||
* @param varData the new value of the variable.
|
||||
*/
|
||||
public void assign(String varName, String varData)
|
||||
{
|
||||
vars.put(varName, varData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the HTML page and return it into a String.
|
||||
*/
|
||||
public String out()
|
||||
{
|
||||
if (this.implicitMain) {
|
||||
this.parse("main");
|
||||
}
|
||||
Object main = parsedBlocks.get("main");
|
||||
if (main == null) {
|
||||
throw new IllegalStateException("'main' block not parsed");
|
||||
}
|
||||
return(main.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a template block.
|
||||
* If the block contains variables, these variables must be set
|
||||
* before the block is added.
|
||||
* If the block contains subblocks, the subblocks
|
||||
* must be parsed before this block.
|
||||
* @param blockName the name of the block to be parsed.
|
||||
* @throws IllegalArgumentException if the block name is not found (and failSiletly==false)
|
||||
*/
|
||||
public void parse(String blockName) throws IllegalArgumentException
|
||||
{
|
||||
String copy = "";
|
||||
if (implicitMain && !"main".equals(blockName) && !blockName.startsWith("main.")) {
|
||||
blockName = "main." + blockName;
|
||||
}
|
||||
try {
|
||||
copy = blocks.get(blockName).toString();
|
||||
} catch (NullPointerException e) {
|
||||
if (!this.failSilently) throw new IllegalArgumentException(
|
||||
"Block '" + blockName + "' not found." +
|
||||
" Matches " + locateBlock(blockName));
|
||||
}
|
||||
Pattern pattern = Pattern.compile("\\{([\\w\\.]+)\\}");
|
||||
Matcher matcher = pattern.matcher(copy);
|
||||
pattern = Pattern.compile("_BLOCK_\\.(.+)");
|
||||
for (Matcher matcher2; matcher.find();)
|
||||
{
|
||||
String match = matcher.group(1);
|
||||
matcher2 = pattern.matcher(match);
|
||||
if (matcher2.find())
|
||||
{
|
||||
if (parsedBlocks.containsKey(matcher2.group(1)))
|
||||
{
|
||||
copy = copy.replaceFirst("\\{"+match+"\\}", escape(
|
||||
parsedBlocks.get(matcher2.group(1)).toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = copy.replaceFirst("\\{"+match+"\\}", "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vars.containsKey(match))
|
||||
{
|
||||
copy = copy.replaceFirst("\\{"+match+"\\}", escape(
|
||||
vars.get(match).toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave unchanged because it might be wanted in output.
|
||||
// Can always be removed by assigning empty value.
|
||||
//copy = copy.replaceFirst("\\{"+match+"\\}", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parsedBlocks.containsKey(blockName))
|
||||
{
|
||||
parsedBlocks.put(blockName, parsedBlocks.get(blockName) + copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedBlocks.put(blockName, copy);
|
||||
}
|
||||
if (subBlocks.containsKey(blockName))
|
||||
{
|
||||
parsedBlocks.put(subBlocks.get(blockName), "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template parsing uses regex replace to insert result text,
|
||||
* which means that special characters in replacement string must be escaped.
|
||||
* @param replacement The text that should appear in output.
|
||||
* @return Text escaped so that it works as String.replaceFirst replacement.
|
||||
*/
|
||||
protected String escape(String replacement) {
|
||||
return replacement.replace("\\", "\\\\").replace("$", "\\$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the blocks that end with the given blockName.
|
||||
* @param blockName The name as used in parse
|
||||
* @return Blocks where blockName is the child
|
||||
* (the Set's toString lists the full names)
|
||||
*/
|
||||
protected Set<Object> locateBlock(final String blockName) {
|
||||
Set<Object> matches = new java.util.HashSet<Object>();
|
||||
for (Iterator<String> it = blocks.keySet().iterator(); it.hasNext(); ) {
|
||||
Object b = it.next();
|
||||
if (b.toString().endsWith('.' + blockName)) matches.add(b);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
private String readFile(Reader fr) throws IOException
|
||||
{
|
||||
StringBuffer content = new StringBuffer();
|
||||
for (int c; (c = fr.read()) != -1; content.append((char)c));
|
||||
fr.close();
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
private void makeTree(String fileText)
|
||||
{
|
||||
// BEGIN: implicit main
|
||||
if (!Pattern.compile(".*<!--\\s*BEGIN\\s*:\\s*main\\s*-->.*", Pattern.DOTALL)
|
||||
.matcher(fileText).matches()) {
|
||||
this.implicitMain = true; // affects parse(block) and out()
|
||||
fileText = "<!-- BEGIN: main -->" + fileText + "<!-- END: main -->";
|
||||
}
|
||||
// END: implicit main
|
||||
Pattern pattern = Pattern.compile("<!--\\s*(BEGIN|END)\\s*:\\s*(\\w+)\\s*-->(.*?)(?=(?:<!--\\s*(?:BEGIN|END)\\s*:\\s*\\w+\\s*-->)|(?:\\s*$))", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(fileText);
|
||||
ArrayList<String> blockNames = new ArrayList<String>();
|
||||
String parentName = "";
|
||||
int lastlength = 0; // used in newline trimming to see if one block immediately follows the previous
|
||||
while (matcher.find())
|
||||
{
|
||||
// BEGIN: newline trimming
|
||||
String after = matcher.group(3); // contents after tag
|
||||
if (lastlength == 0 || fileText.charAt(matcher.start() - 1) == '\n') {
|
||||
after = after.replaceFirst("^\\r?\\n", "");
|
||||
}
|
||||
lastlength = after.length();
|
||||
// END: newline trimming
|
||||
if (matcher.group(1).toUpperCase().equals("BEGIN"))
|
||||
{
|
||||
parentName = implode(blockNames);
|
||||
blockNames.add(matcher.group(2));
|
||||
String currentBlockName = implode(blockNames);
|
||||
if (blocks.containsKey(currentBlockName))
|
||||
{
|
||||
blocks.put(currentBlockName, blocks.get(currentBlockName) + after);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks.put(currentBlockName, after);
|
||||
}
|
||||
if (blocks.containsKey(parentName))
|
||||
{
|
||||
blocks.put(parentName, blocks.get(parentName) + "{_BLOCK_." + currentBlockName + "}");
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks.put(parentName, "{_BLOCK_." + currentBlockName + "}");
|
||||
}
|
||||
subBlocks.put(parentName, currentBlockName);
|
||||
subBlocks.put(currentBlockName, "");
|
||||
}
|
||||
else if (matcher.group(1).toUpperCase().equals("END"))
|
||||
{
|
||||
blockNames.remove(blockNames.size()-1);
|
||||
parentName = implode(blockNames);
|
||||
if (blocks.containsKey(parentName))
|
||||
{
|
||||
blocks.put(parentName, blocks.get(parentName) + after);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks.put(parentName, after);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String implode(ArrayList<String> al)
|
||||
{
|
||||
String ret = "";
|
||||
for (int i = 0; al.size() > i; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
ret += ".";
|
||||
}
|
||||
ret += al.get(i);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
}
|
136
hsarback/src/net/sf/jtpl/Template.java
Normal file
136
hsarback/src/net/sf/jtpl/Template.java
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright 2009 jtpl.sourceforge.net
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package net.sf.jtpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sf.jtpl.Jtpl;
|
||||
|
||||
/**
|
||||
* The forward compatible template engine interface,
|
||||
* replacing {@link Jtpl}.
|
||||
*/
|
||||
public class Template implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3916690583929137140L;
|
||||
|
||||
private Jtpl t;
|
||||
|
||||
public Template(Reader template) throws IOException {
|
||||
t = new Jtpl(template);
|
||||
}
|
||||
|
||||
public Template(String templateSource) {
|
||||
try {
|
||||
t = new Jtpl(new StringReader(templateSource));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); // should be impossible with StringReader
|
||||
}
|
||||
}
|
||||
|
||||
public Template(File templateFile) throws FileNotFoundException {
|
||||
FileReader r = new FileReader(templateFile);
|
||||
try {
|
||||
t = new Jtpl(templateFile);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
r.close();
|
||||
} catch (Exception nothingToDoAboutIt) {}
|
||||
}
|
||||
}
|
||||
|
||||
// proxying methods from Jtpl1
|
||||
|
||||
public Template assign(String varName, String varData) {
|
||||
t.assign(varName, varData);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Template parse(String blockName) throws IllegalArgumentException {
|
||||
t.parse(blockName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String out() {
|
||||
return t.out();
|
||||
}
|
||||
|
||||
// bean properties support
|
||||
|
||||
public Template parse(String blockName, Object bean) {
|
||||
assignAll(bean);
|
||||
return parse(blockName);
|
||||
}
|
||||
|
||||
public String out(Object bean) {
|
||||
assignAll(bean);
|
||||
return out();
|
||||
}
|
||||
|
||||
protected void assignAll(Object bean) {
|
||||
Map<String, Object> p = getBeanProperties(bean);
|
||||
Iterator<String> i = p.keySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
String key = (String) i.next();
|
||||
assign(key.toUpperCase(), "" + p.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bean The instance that has properties named according to JavaBean standard.
|
||||
* @return Map<String, Object> that should be considered immutable
|
||||
*/
|
||||
protected Map<String, Object> getBeanProperties(Object bean) {
|
||||
HashMap<String, Object> values = new HashMap<String, Object>();
|
||||
if (bean == null) return values;
|
||||
Method[] m = bean.getClass().getMethods();
|
||||
|
||||
Pattern p = Pattern.compile("get([A-Z]\\w+)");
|
||||
|
||||
for (int i = 0; i < m.length; i++) {
|
||||
if (m[i].getName().equals("getClass")) continue;
|
||||
if (m[i].getParameterTypes().length > 0) continue;
|
||||
Matcher r = p.matcher(m[i].getName());
|
||||
if (r.matches()) {
|
||||
try {
|
||||
values.put(r.group(1).toLowerCase(), m[i].invoke(bean, new Object[0]));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw e;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
user=de.hsadmin.remote.UnixUserRemote
|
||||
q=de.hsadmin.remote.QueueTaskRemote
|
Loading…
Reference in New Issue
Block a user