Java Web Services via REST bereitstellen
ulrich@undisclosed
2020-05-02 1177762340ebc0e7bee444ae2d7c119f697cbdbb
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);
669527 109       resultat = methodeAusfuehren(o, m, format, parameter);
ca8e1e 110         }
U 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) {
669527 127       Access access = methode.getAnnotation(Access.class);
adfe21 128       if(access == null || access.type().equals(Access.Type.ALLOW)) {
669527 129         resultat = methode.invoke(o, parameterKonvertieren(methode, parameter, format));
U 130         Class returnType = methode.getReturnType();
131         /*
132          * Wenn der Rueckgabewert der Methode nicht vom Typ String ist, 
133          * wird das Objekt in das Format verwandelt, das der Standardwandler 
134          * liefert, z.B. JSON
135          */
136         if(!returnType.getName().equals("java.lang.String")) {
137           //resultat = new JsonWandler().vonJava(resultat, returnType);
138           Wandler w = wandler.get(format);
139           if(w != null) {
140             resultat = w.vonJava(resultat, returnType);
141           }
142           /*if(format == Wandler.JSON) {
143             resultat = new JsonWandler().vonJava(resultat, returnType);
144           }*/
ca8e1e 145         }
669527 146       } else {
U 147         // nicht zum Zugriff vorgesehen
148       }
ca8e1e 149         }
U 150         return resultat;
151     }
152
153     /**
154      * Zur Vereinfachung wird hier angenommen, dass es nur Eingangsparamter vom Typ String gibt
155      * 
156      * @param m
157      * @param parameter
158      * @return
159      */
160     @SuppressWarnings("rawtypes")
161     protected Object[] parameterKonvertieren(Method m, Object[] parameter, String format) throws Exception {
162         Object[] resultat = null;
163         if(parameter != null && parameter.length > 0) {
164             resultat = new Object[parameter.length];
165             Class[] types = m.getParameterTypes();
166             for(int i = 0; i < types.length; i++) {
167                 resultat[i] = toType(types[i], parameter[i].toString(), format);
168             }
169         }
170         return resultat;
171     }
172     
173     /**
174      * Umwandlung von String zu einem anderen Typ
175      * 
176      * @param c  die Klasse, in deren Typ umgewandelt werden soll
177      * @param parameter  der Wert, der umgewandelt werden soll
178      * @return der Parameter umgewandelt in den gewuenschten Typ oder null, falls 
179      * die Umwandlung nicht gelang
180      */
181     @SuppressWarnings("rawtypes")
182     protected Object toType(Class c, String parameter, String format) throws Exception {
183         Object o = null;
184         String className = c.getName();
185         if(className.equals("java.lang.Integer") || className.equals("int")) {
186             o = Integer.parseInt(parameter);
187         } else if(className.equals("java.lang.Short") || className.equals("short")) {
188             o = Short.parseShort(parameter);
189         } else if(className.equals("java.lang.Boolean") || className.equals("boolean")) {
190             o = Boolean.parseBoolean(parameter);
191         } else if(className.equals("java.lang.Character") || className.equals("char")) {
192             o = Character.valueOf(parameter.charAt(0));
193         } else if(className.equals("java.lang.Byte") || className.equals("byte")) {
194             o = Byte.parseByte(parameter);
195         } else if(className.equals("java.lang.Long") || className.equals("long")) {
196             o = Long.parseLong(parameter);
197         } else if(className.equals("java.lang.Double") || className.equals("double")) {
198             o = Double.parseDouble(parameter);
199         } else if(className.equals("java.lang.String")) {
200             o = parameter;
201         } else {
202             /*
203              * wenn die Ziel-Klasse keine der vorigen Klasse ist wird angenommen, dass 
204              * der Standardwandler das Format erzeugen kann, z.B. aus einem JSON-String 
205              */
206             //o = wandler.get(format).zuJava(parameter, c);
207       //o = new JsonWandler().zuJava(parameter, c);
208       Wandler w = wandler.get(format);
209       if(w != null) {
210         o = w.zuJava(parameter, c);
211       }
212       /*if(format == Wandler.JSON) {
213         o = new JsonWandler().zuJava(parameter, c);
214       }*/
215         }
216         return o;
217     }
218     
219     /**
220      * Eine Methode aus einer Liste von Methoden heraussuchen
221      * @param methoden  die Liste der Methoden
222      * @param methodenName  der Name der gesuchten Methode
223      * @return  die Methode oder null, wenn die gesuchte Methode nicht gefunden wurde
224      */
225     protected Method findeMethode(Method[] methoden, String methodenName) {
226         Method methode = null;
227         for(int i = 0; methode == null && i < methoden.length; i++) {
228             Method m = methoden[i];
229             if(m.getName().equals(methodenName)) {
230                 methode = m;
231             }
232         }
233         return methode;
234     }
235     
236     /**
237      * Eine Methode heraussuchen
238      * 
239      * Diese Methode sieht vor, dass ein Methodenname nur einmal in einer 
240      * Klasse vorkommt. In Faellen, wo mehrere Methoden einer Klasse den 
241      * selben Namen haben, wird die erste Methode dieses Namens geliefert. 
242      * 
243      * @param klassenName  Name der Klasse
244      * @param methodenName Name der gesuchten Mthode
245      * @return  die Methode oder null, wenn keine Methode mit diesem Namen
246      * in der angegebenen Klasse gefunden wurde
247      */
248     @SuppressWarnings("rawtypes")
249     public Method methodeFinden(String klassenName, String methodenName) throws Exception {
250         Method m = null;
251         Class klasse = Class.forName(klassenName);
252         if(klasse != null) {
253             m = findeMethode(klasse.getDeclaredMethods(), methodenName);
254         }
255         return m;
256     }
257
258   /**
259    * Einen Wandler entfernen
260    * 
261    * @param wandler  der Wandler, der entfernt werden soll
262    */
263     public void wandlerEntfernen(Wandler wandler) {
264         this.wandler.remove(wandler.getFormat());
265     }
266
267   /**
268    * Einen Wandler hinzufuegen
269    * 
270    * @param wandler  der Wandler, der hinzugefuegt werden soll
271    */
272     public void wandlerHinzufuegen(Wandler wandler) {
273         this.wandler.put(wandler.getFormat(), wandler);
274     }
275   
276   /**
277    * Diese Instanz aufloesen, also alle Ressourcen frei geben 
278    */
279   public void aufloesen() {
280     Set keySet = wandler.keySet();
281     Iterator i = keySet.iterator();
282     while(i.hasNext()) {
283       String key = i.next().toString();
284       Wandler w = wandler.get(key);
285       w.aufloesen();
286       w = null;
287     }
288     wandler.clear();
289     wandler = null;
290   }
291   
292 }