Java Web Services via REST bereitstellen
ulrich
2014-11-20 4b8725bf2f6fbf3acd63c1f1a168ac32f129694a
commit | author | age
ca8e1e 1 /*
U 2     Transit - Remote procedure calls made simple
3     Copyright (c) 2012  Ulrich Hilger
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Affero General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Affero General Public License for more details.
14
15     You should have received a copy of the GNU Affero General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package de.uhilger.transit;
20
21 import java.lang.reflect.Method;
22 import java.util.HashMap;
23 import java.util.Set;
24 import java.util.Iterator;
25
26 /**
27  * Methoden beliebiger Java-Klassen zur Ausfuehrung bringen und 
28  * dabei Methodenaufrufe, Parameter und Rueckgabewerte als 
29  * Zeichenketten (Strings) verarbeiten.
30  * 
31  * @author Copyright (c) Ulrich Hilger, http://uhilger.de
32  * @author Published under the terms and conditions of
33  * the <a href="http://www.gnu.org/licenses/agpl-3.0" target="_blank">GNU Affero General Public License</a>
34  * 
35  * @version 1, September 16, 2012
36  */
37 public class JavaServer implements JavaDienst {
38           
39     /**
40      * Die Sammlung von Wandlern, die dieser Server 
41      * verwenden soll um Objekte in Java und zuruck 
42      * zu verwandeln
43      */
44     private HashMap<String, Wandler> wandler;
45     
46     /**
47      * Ein Objekt der Klasse <code>JavaServer</code> erzeugen
48      */
49     public JavaServer() {
50         super();
51         wandler = new HashMap<String, Wandler>();
52     }
53
54     /**
55      * Eine Klasse heraussuchen
56      * 
57      * @param klassenName  voller Name der gesuchten Klasse, z.B. java.lang.String
58      * @return  die Klasse oder null, wenn keine Klasse mit diesem Namen gefunden wurde
59      */
60     @SuppressWarnings("rawtypes")
61     public Class klasseFinden(String klassenName) throws Exception {
62         Class c = null;
63         c = Class.forName(klassenName);
64         return c;
65     }
66
67     /**
68      * Eine Methode ausfuehren
69      * 
70      * Diese Methode sieht vor, dass ein Methodenname nur einmal in einer 
71      * Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den 
72      * selben Namen haben, wird die erste Methode dieses Namens verwendet. 
73      * 
74      * @param klassenName  Name der Klasse
75      * @param methodenName  Name der Methode
76      * @param format  das Format, das Parameter und Rueckgabewert haben
77      * @param parameter  die Parameter der Methode
78      * @return  der Rueckgabewert der Methode nach der Ausfuehrung
79      */
80     @SuppressWarnings("rawtypes")
81     public Object methodeAusfuehren(String klassenName, String methodenName, String format, Object... parameter) throws Exception {
82         Object resultat = null;
83         Class c = klasseFinden(klassenName);
84         if(c != null) {
85             resultat = methodeAusfuehren(c.newInstance(), methodenName, format, parameter);
86         }
87         return resultat;
88     }
89
90     /**
91      * Eine Methode ausfuehren
92      * 
93      * Diese Methode sieht vor, dass ein Methodenname nur einmal in einer 
94      * Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den 
95      * selben Namen haben, wird die erste Methode dieses Namens verwendet. 
96      * 
97      * @param o  ein Objekt der Klasse, die die auszufuehrende Methode enthaelt
98      * @param methodenName  Name der Methode
99      * @param format  das Format, das Parameter und Rueckgabewert haben
100      * @param parameter  die Parameter der Methode
101      * @return  der Rueckgabewert der Methode nach der Ausfuehrung
102      */
103     @SuppressWarnings("rawtypes")
104     public Object methodeAusfuehren(Object o, String methodenName, String format, Object... parameter) throws Exception {
105         Object resultat = null;
106         if(o != null) {
107             Class c = o.getClass();
108             Method m = findeMethode(c.getDeclaredMethods(), methodenName);
109             resultat = methodeAusfuehren(o, m, format, parameter);
110         }
111         return resultat;
112     }
113
114     /**
115      * Eine Methode ausfuehren
116      * 
117      * @param o  ein Objekt der Klasse, die die auszufuehrende Methode enthaelt
118      * @param methode  das Methodenobjekt, das ausgefuehrt werden soll
119      * @param format  das Format, das Parameter und Rueckgabewert haben
120      * @param parameter  die Parameter der Methode
121      * @return  der Rueckgabewert der Methode nach der Ausfuehrung
122      */
123     @SuppressWarnings("rawtypes")
124     public Object methodeAusfuehren(Object o, Method methode, String format, Object... parameter) throws Exception {
125         Object resultat = null;
126         if(methode != null) {
127             resultat = methode.invoke(o, parameterKonvertieren(methode, parameter, format));
128             Class returnType = methode.getReturnType();
129             /*
130              * Wenn der Rueckgabewert der Methode nicht vom Typ String ist, 
131              * wird das Objekt in das Format verwandelt, das der Standardwandler 
132              * liefert, z.B. JSON
133              */
134             if(!returnType.getName().equals("java.lang.String")) {
135         //resultat = new JsonWandler().vonJava(resultat, returnType);
136         Wandler w = wandler.get(format);
137         if(w != null) {
138                 resultat = w.vonJava(resultat, returnType);
139         }
140         /*if(format == Wandler.JSON) {
141                 resultat = new JsonWandler().vonJava(resultat, returnType);
142         }*/
143             }
144         }
145         return resultat;
146     }
147
148     /**
149      * Zur Vereinfachung wird hier angenommen, dass es nur Eingangsparamter vom Typ String gibt
150      * 
151      * @param m
152      * @param parameter
153      * @return
154      */
155     @SuppressWarnings("rawtypes")
156     protected Object[] parameterKonvertieren(Method m, Object[] parameter, String format) throws Exception {
157         Object[] resultat = null;
158         if(parameter != null && parameter.length > 0) {
159             resultat = new Object[parameter.length];
160             Class[] types = m.getParameterTypes();
161             for(int i = 0; i < types.length; i++) {
162                 resultat[i] = toType(types[i], parameter[i].toString(), format);
163             }
164         }
165         return resultat;
166     }
167     
168     /**
169      * Umwandlung von String zu einem anderen Typ
170      * 
171      * @param c  die Klasse, in deren Typ umgewandelt werden soll
172      * @param parameter  der Wert, der umgewandelt werden soll
173      * @return der Parameter umgewandelt in den gewuenschten Typ oder null, falls 
174      * die Umwandlung nicht gelang
175      */
176     @SuppressWarnings("rawtypes")
177     protected Object toType(Class c, String parameter, String format) throws Exception {
178         Object o = null;
179         String className = c.getName();
180         if(className.equals("java.lang.Integer") || className.equals("int")) {
181             o = Integer.parseInt(parameter);
182         } else if(className.equals("java.lang.Short") || className.equals("short")) {
183             o = Short.parseShort(parameter);
184         } else if(className.equals("java.lang.Boolean") || className.equals("boolean")) {
185             o = Boolean.parseBoolean(parameter);
186         } else if(className.equals("java.lang.Character") || className.equals("char")) {
187             o = Character.valueOf(parameter.charAt(0));
188         } else if(className.equals("java.lang.Byte") || className.equals("byte")) {
189             o = Byte.parseByte(parameter);
190         } else if(className.equals("java.lang.Long") || className.equals("long")) {
191             o = Long.parseLong(parameter);
192         } else if(className.equals("java.lang.Double") || className.equals("double")) {
193             o = Double.parseDouble(parameter);
194         } else if(className.equals("java.lang.String")) {
195             o = parameter;
196         } else {
197             /*
198              * wenn die Ziel-Klasse keine der vorigen Klasse ist wird angenommen, dass 
199              * der Standardwandler das Format erzeugen kann, z.B. aus einem JSON-String 
200              */
201             //o = wandler.get(format).zuJava(parameter, c);
202       //o = new JsonWandler().zuJava(parameter, c);
203       Wandler w = wandler.get(format);
204       if(w != null) {
205         o = w.zuJava(parameter, c);
206       }
207       /*if(format == Wandler.JSON) {
208         o = new JsonWandler().zuJava(parameter, c);
209       }*/
210         }
211         return o;
212     }
213     
214     /**
215      * Eine Methode aus einer Liste von Methoden heraussuchen
216      * @param methoden  die Liste der Methoden
217      * @param methodenName  der Name der gesuchten Methode
218      * @return  die Methode oder null, wenn die gesuchte Methode nicht gefunden wurde
219      */
220     protected Method findeMethode(Method[] methoden, String methodenName) {
221         Method methode = null;
222         for(int i = 0; methode == null && i < methoden.length; i++) {
223             Method m = methoden[i];
224             if(m.getName().equals(methodenName)) {
225                 methode = m;
226             }
227         }
228         return methode;
229     }
230     
231     /**
232      * Eine Methode heraussuchen
233      * 
234      * Diese Methode sieht vor, dass ein Methodenname nur einmal in einer 
235      * Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den 
236      * selben Namen haben, wird die erste Methode dieses Namens geliefert. 
237      * 
238      * @param klassenName  Name der Klasse
239      * @param methodenName Name der gesuchten Mthode
240      * @return  die Methode oder null, wenn keine Methode mit diesem Namen
241      * in der angegebenen Klasse gefunden wurde
242      */
243     @SuppressWarnings("rawtypes")
244     public Method methodeFinden(String klassenName, String methodenName) throws Exception {
245         Method m = null;
246         Class klasse = Class.forName(klassenName);
247         if(klasse != null) {
248             m = findeMethode(klasse.getDeclaredMethods(), methodenName);
249         }
250         return m;
251     }
252
253   /**
254    * Einen Wandler entfernen
255    * 
256    * @param wandler  der Wandler, der entfernt werden soll
257    */
258     public void wandlerEntfernen(Wandler wandler) {
259         this.wandler.remove(wandler.getFormat());
260     }
261
262   /**
263    * Einen Wandler hinzufuegen
264    * 
265    * @param wandler  der Wandler, der hinzugefuegt werden soll
266    */
267     public void wandlerHinzufuegen(Wandler wandler) {
268         this.wandler.put(wandler.getFormat(), wandler);
269     }
270   
271   /**
272    * Diese Instanz aufloesen, also alle Ressourcen frei geben 
273    */
274   public void aufloesen() {
275     Set keySet = wandler.keySet();
276     Iterator i = keySet.iterator();
277     while(i.hasNext()) {
278       String key = i.next().toString();
279       Wandler w = wandler.get(key);
280       w.aufloesen();
281       w = null;
282     }
283     wandler.clear();
284     wandler = null;
285   }
286   
287 }