/*
|
Transit - Remote procedure calls made simple
|
Copyright (c) 2012 Ulrich Hilger
|
|
This program is free software: you can redistribute it and/or modify
|
it under the terms of the GNU Affero General Public License as published by
|
the Free Software Foundation, either version 3 of the License, or
|
(at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU Affero General Public License for more details.
|
|
You should have received a copy of the GNU Affero General Public License
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
*/
|
|
package de.uhilger.transit;
|
|
import java.lang.reflect.Method;
|
import java.util.HashMap;
|
import java.util.Set;
|
import java.util.Iterator;
|
|
/**
|
* Methoden beliebiger Java-Klassen zur Ausfuehrung bringen und
|
* dabei Methodenaufrufe, Parameter und Rueckgabewerte als
|
* Zeichenketten (Strings) verarbeiten.
|
*
|
* @author Copyright (c) Ulrich Hilger, http://uhilger.de
|
* @author Published under the terms and conditions of
|
* the <a href="http://www.gnu.org/licenses/agpl-3.0" target="_blank">GNU Affero General Public License</a>
|
*
|
* @version 1, September 16, 2012
|
*/
|
public class JavaServer implements JavaDienst {
|
|
/**
|
* Die Sammlung von Wandlern, die dieser Server
|
* verwenden soll um Objekte in Java und zuruck
|
* zu verwandeln
|
*/
|
private HashMap<String, Wandler> wandler;
|
|
/**
|
* Ein Objekt der Klasse <code>JavaServer</code> erzeugen
|
*/
|
public JavaServer() {
|
super();
|
wandler = new HashMap<String, Wandler>();
|
}
|
|
/**
|
* Eine Klasse heraussuchen
|
*
|
* @param klassenName voller Name der gesuchten Klasse, z.B. java.lang.String
|
* @return die Klasse oder null, wenn keine Klasse mit diesem Namen gefunden wurde
|
*/
|
@SuppressWarnings("rawtypes")
|
public Class klasseFinden(String klassenName) throws Exception {
|
Class c = null;
|
c = Class.forName(klassenName);
|
return c;
|
}
|
|
/**
|
* Eine Methode ausfuehren
|
*
|
* Diese Methode sieht vor, dass ein Methodenname nur einmal in einer
|
* Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den
|
* selben Namen haben, wird die erste Methode dieses Namens verwendet.
|
*
|
* @param klassenName Name der Klasse
|
* @param methodenName Name der Methode
|
* @param format das Format, das Parameter und Rueckgabewert haben
|
* @param parameter die Parameter der Methode
|
* @return der Rueckgabewert der Methode nach der Ausfuehrung
|
*/
|
@SuppressWarnings("rawtypes")
|
public Object methodeAusfuehren(String klassenName, String methodenName, String format, Object... parameter) throws Exception {
|
Object resultat = null;
|
Class c = klasseFinden(klassenName);
|
if(c != null) {
|
resultat = methodeAusfuehren(c.newInstance(), methodenName, format, parameter);
|
}
|
return resultat;
|
}
|
|
/**
|
* Eine Methode ausfuehren
|
*
|
* Diese Methode sieht vor, dass ein Methodenname nur einmal in einer
|
* Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den
|
* selben Namen haben, wird die erste Methode dieses Namens verwendet.
|
*
|
* @param o ein Objekt der Klasse, die die auszufuehrende Methode enthaelt
|
* @param methodenName Name der Methode
|
* @param format das Format, das Parameter und Rueckgabewert haben
|
* @param parameter die Parameter der Methode
|
* @return der Rueckgabewert der Methode nach der Ausfuehrung
|
*/
|
@SuppressWarnings("rawtypes")
|
public Object methodeAusfuehren(Object o, String methodenName, String format, Object... parameter) throws Exception {
|
Object resultat = null;
|
if(o != null) {
|
Class c = o.getClass();
|
Method m = findeMethode(c.getDeclaredMethods(), methodenName);
|
resultat = methodeAusfuehren(o, m, format, parameter);
|
}
|
return resultat;
|
}
|
|
/**
|
* Eine Methode ausfuehren
|
*
|
* @param o ein Objekt der Klasse, die die auszufuehrende Methode enthaelt
|
* @param methode das Methodenobjekt, das ausgefuehrt werden soll
|
* @param format das Format, das Parameter und Rueckgabewert haben
|
* @param parameter die Parameter der Methode
|
* @return der Rueckgabewert der Methode nach der Ausfuehrung
|
*/
|
@SuppressWarnings("rawtypes")
|
public Object methodeAusfuehren(Object o, Method methode, String format, Object... parameter) throws Exception {
|
Object resultat = null;
|
if(methode != null) {
|
Access access = methode.getAnnotation(Access.class);
|
if(access != null && access.type().equals(Access.Type.ALLOW)) {
|
resultat = methode.invoke(o, parameterKonvertieren(methode, parameter, format));
|
Class returnType = methode.getReturnType();
|
/*
|
* Wenn der Rueckgabewert der Methode nicht vom Typ String ist,
|
* wird das Objekt in das Format verwandelt, das der Standardwandler
|
* liefert, z.B. JSON
|
*/
|
if(!returnType.getName().equals("java.lang.String")) {
|
//resultat = new JsonWandler().vonJava(resultat, returnType);
|
Wandler w = wandler.get(format);
|
if(w != null) {
|
resultat = w.vonJava(resultat, returnType);
|
}
|
/*if(format == Wandler.JSON) {
|
resultat = new JsonWandler().vonJava(resultat, returnType);
|
}*/
|
}
|
} else {
|
// nicht zum Zugriff vorgesehen
|
}
|
}
|
return resultat;
|
}
|
|
/**
|
* Zur Vereinfachung wird hier angenommen, dass es nur Eingangsparamter vom Typ String gibt
|
*
|
* @param m
|
* @param parameter
|
* @return
|
*/
|
@SuppressWarnings("rawtypes")
|
protected Object[] parameterKonvertieren(Method m, Object[] parameter, String format) throws Exception {
|
Object[] resultat = null;
|
if(parameter != null && parameter.length > 0) {
|
resultat = new Object[parameter.length];
|
Class[] types = m.getParameterTypes();
|
for(int i = 0; i < types.length; i++) {
|
resultat[i] = toType(types[i], parameter[i].toString(), format);
|
}
|
}
|
return resultat;
|
}
|
|
/**
|
* Umwandlung von String zu einem anderen Typ
|
*
|
* @param c die Klasse, in deren Typ umgewandelt werden soll
|
* @param parameter der Wert, der umgewandelt werden soll
|
* @return der Parameter umgewandelt in den gewuenschten Typ oder null, falls
|
* die Umwandlung nicht gelang
|
*/
|
@SuppressWarnings("rawtypes")
|
protected Object toType(Class c, String parameter, String format) throws Exception {
|
Object o = null;
|
String className = c.getName();
|
if(className.equals("java.lang.Integer") || className.equals("int")) {
|
o = Integer.parseInt(parameter);
|
} else if(className.equals("java.lang.Short") || className.equals("short")) {
|
o = Short.parseShort(parameter);
|
} else if(className.equals("java.lang.Boolean") || className.equals("boolean")) {
|
o = Boolean.parseBoolean(parameter);
|
} else if(className.equals("java.lang.Character") || className.equals("char")) {
|
o = Character.valueOf(parameter.charAt(0));
|
} else if(className.equals("java.lang.Byte") || className.equals("byte")) {
|
o = Byte.parseByte(parameter);
|
} else if(className.equals("java.lang.Long") || className.equals("long")) {
|
o = Long.parseLong(parameter);
|
} else if(className.equals("java.lang.Double") || className.equals("double")) {
|
o = Double.parseDouble(parameter);
|
} else if(className.equals("java.lang.String")) {
|
o = parameter;
|
} else {
|
/*
|
* wenn die Ziel-Klasse keine der vorigen Klasse ist wird angenommen, dass
|
* der Standardwandler das Format erzeugen kann, z.B. aus einem JSON-String
|
*/
|
//o = wandler.get(format).zuJava(parameter, c);
|
//o = new JsonWandler().zuJava(parameter, c);
|
Wandler w = wandler.get(format);
|
if(w != null) {
|
o = w.zuJava(parameter, c);
|
}
|
/*if(format == Wandler.JSON) {
|
o = new JsonWandler().zuJava(parameter, c);
|
}*/
|
}
|
return o;
|
}
|
|
/**
|
* Eine Methode aus einer Liste von Methoden heraussuchen
|
* @param methoden die Liste der Methoden
|
* @param methodenName der Name der gesuchten Methode
|
* @return die Methode oder null, wenn die gesuchte Methode nicht gefunden wurde
|
*/
|
protected Method findeMethode(Method[] methoden, String methodenName) {
|
Method methode = null;
|
for(int i = 0; methode == null && i < methoden.length; i++) {
|
Method m = methoden[i];
|
if(m.getName().equals(methodenName)) {
|
methode = m;
|
}
|
}
|
return methode;
|
}
|
|
/**
|
* Eine Methode heraussuchen
|
*
|
* Diese Methode sieht vor, dass ein Methodenname nur einmal in einer
|
* Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den
|
* selben Namen haben, wird die erste Methode dieses Namens geliefert.
|
*
|
* @param klassenName Name der Klasse
|
* @param methodenName Name der gesuchten Mthode
|
* @return die Methode oder null, wenn keine Methode mit diesem Namen
|
* in der angegebenen Klasse gefunden wurde
|
*/
|
@SuppressWarnings("rawtypes")
|
public Method methodeFinden(String klassenName, String methodenName) throws Exception {
|
Method m = null;
|
Class klasse = Class.forName(klassenName);
|
if(klasse != null) {
|
m = findeMethode(klasse.getDeclaredMethods(), methodenName);
|
}
|
return m;
|
}
|
|
/**
|
* Einen Wandler entfernen
|
*
|
* @param wandler der Wandler, der entfernt werden soll
|
*/
|
public void wandlerEntfernen(Wandler wandler) {
|
this.wandler.remove(wandler.getFormat());
|
}
|
|
/**
|
* Einen Wandler hinzufuegen
|
*
|
* @param wandler der Wandler, der hinzugefuegt werden soll
|
*/
|
public void wandlerHinzufuegen(Wandler wandler) {
|
this.wandler.put(wandler.getFormat(), wandler);
|
}
|
|
/**
|
* Diese Instanz aufloesen, also alle Ressourcen frei geben
|
*/
|
public void aufloesen() {
|
Set keySet = wandler.keySet();
|
Iterator i = keySet.iterator();
|
while(i.hasNext()) {
|
String key = i.next().toString();
|
Wandler w = wandler.get(key);
|
w.aufloesen();
|
w = null;
|
}
|
wandler.clear();
|
wandler = null;
|
}
|
|
}
|