Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ResourceSchemaGenerator.java
Go to the documentation of this file.
1 
2 package vmi1;
3 
4 import java.io.InputStream;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collection;
8 import java.util.Set;
9 import java.util.Map;
10 import java.util.HashMap;
11 import java.util.LinkedHashMap;
12 import java.util.Iterator;
13 
14 import java.lang.reflect.*;
15 import java.lang.annotation.Annotation;
16 
17 import java.net.URL;
18 
19 /* Failed wsdl4j attempt; cannot access the DOM to read XmlSchemas from WSDL */
20 /*
21 import javax.wsdl.factory.WSDLFactory;
22 import javax.wsdl.xml.WSDLReader;
23 import javax.wsdl.Definition;
24 import javax.wsdl.extensions.ExtensibilityElement;
25 */
26 
27 /* Failed woden attempt; woden does not support wsdl 1.x */
28 /*
29 import org.apache.woden.*;
30 import org.apache.woden.schema.*;
31 */
32 
33 /* Success: read from the document directly; WSDLs are simple! */
34 import org.w3c.dom.Document;
35 import org.w3c.dom.Node;
36 import org.w3c.dom.NodeList;
37 import org.w3c.dom.Element;
38 import javax.xml.parsers.DocumentBuilder;
39 import javax.xml.parsers.DocumentBuilderFactory;
40 import javax.xml.namespace.QName;
41 
42 import org.apache.axis2.jaxrs.JAXRSUtils;
43 import org.apache.axis2.jaxrs.JAXRSModel;
44 
45 import org.apache.axis2.wsdl.WSDLConstants;
46 
47 import org.apache.axis2.description.java2wsdl.SchemaGenerator;
48 import org.apache.axis2.description.java2wsdl.DefaultSchemaGenerator;
49 import org.apache.axis2.description.java2wsdl.DocLitBareSchemaGenerator;
50 import org.apache.axis2.description.AxisOperation;
51 import org.apache.axis2.description.AxisService;
52 import org.apache.axis2.description.AxisMessage;
53 
54 import org.apache.axis2.deployment.util.Utils;
55 
56 import org.apache.ws.commons.schema.*;
57 
58 import org.apache.axis2.jsr181.JSR181Helper;
59 import org.apache.axis2.jsr181.WebMethodAnnotation;
60 import org.apache.axis2.jsr181.WebParamAnnotation;
61 import org.apache.axis2.jsr181.WebResultAnnotation;
62 import org.apache.axis2.jsr181.WebServiceAnnotation;
63 
64 public class ResourceSchemaGenerator extends DefaultSchemaGenerator {
65  protected URL schemaURL = null;
66  protected Map<String,QName> typeMapping =
67  new HashMap<String,QName>();
68  protected Map<String,String> methodClassNameMapping =
69  new HashMap<String,String>();
70  protected Map<String,QName> dynamicTypeMapping =
71  new HashMap<String,QName>();
72 
73  protected JAXRSModel myClassModel;
74 
75  public ResourceSchemaGenerator(ClassLoader loader,String className,
76  URL schemaURL,
77  String schemaTargetNamespace,
78  String schemaTargetNamespacePrefix,
79  Map<String,String> methodClassNameMapping,
80  Map<String,QName> dynamicTypeMapping,
81  Map<String,QName> typeMapping,
82  AxisService service)
83  throws Exception {
84 
85  super(loader,className,schemaTargetNamespace,schemaTargetNamespacePrefix,
86  service);
87 
88  this.schemaURL = schemaURL;
89  this.typeMapping = typeMapping;
90  this.methodClassNameMapping = methodClassNameMapping;
91  this.dynamicTypeMapping = dynamicTypeMapping;
92  this.service = service;
93  }
94 
95  public Collection<XmlSchema> generateSchema() throws Exception {
96  WebServiceAnnotation wsa =
97  JSR181Helper.INSTANCE.getWebServiceAnnotation(serviceClass);
98  if (wsa != null) {
99  String tns = wsa.getTargetNamespace();
100  if (tns != null && !"".equals(tns)) {
101  targetNamespace = tns;
102  if (this.schemaTargetNameSpace == null)
103  this.schemaTargetNameSpace = tns;
104  }
105  if (service != null
106  && (service.getName() == null || service.getName().equals("")))
107  service.setName(Utils.getAnnotatedServiceName(serviceClass,wsa));
108  }
109 
110  if (schemaURL == null)
111  return super.generateSchema();
112 
113  try {
114  InputStream ris = schemaURL.openStream();
115 
116  /*
117  * Linkage with wsdl4j that amounts to nothing because
118  * wsdl4j gives no access to the DOM underneath.
119  */
120  /*
121  URLWSDLLocator wl = new URLWSDLLocator(rurl);
122  WSDLFactory wf = WSDLFactory.newInstance();
123  WSDLReader wr = wf.newWSDLReader();
124  Definition wd = wr.readWSDL(wl);
125  //Document doc = wd.getTypes().
126  Iterator<ExtensibilityElement> eei = (Iterator<ExtensibilityElement>)wd.getTypes().getExtensibilityElements().iterator();
127  while (eei.hasNext()) {
128  ExtensibilityElement ee = eei.next();
129  System.err.println("DEBUG: wsdl type qname = " + ee);
130  if (eei instanceof javax.wsdl.extensions.schema.Schema)
131  System.err.println("DEBUG: wsdl ee document = " + ((javax.wsdl.extensions.schema.Schema)ee).getElement());
132  }
133  */
134 
135  /* So instead, to get to the schema types stuff we need, we
136  * manually read WSDLs and look for element trees like
137  * <definitions><types><schema>
138  * or
139  * <description><types><schema>
140  *
141  * Once we have the Element for <schema>, we use axis's
142  * tools to grab the XmlSchema from it -- then we're money.
143  *
144  * Right now, we don't support multiple <types> or <schema>
145  * elements.
146  */
147 
148  /*
149  * Right now, we have to use a custom resolver because a
150  * null baseUri is passed to it for some reason -- perhaps
151  * because of the soap schema being imported rather than
152  * included -- and there is no schemaLocation in our schema
153  * for the import. Anyway, this causes an NPE, so do this
154  * for now.
155  */
156  CustomURIResolver dr = new CustomURIResolver(schemaURL);
157  xmlSchemaCollection.setSchemaResolver(dr);
158 
159  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
160  dbf.setNamespaceAware(true);
161  DocumentBuilder db = dbf.newDocumentBuilder();
162  Document doc = db.parse(ris);
163 
164  /*
165  * This will hopefully find all <schema> elements inlined in
166  * any WSDL document, 1.x or 2.0.
167  */
168  String toplevel[] = new String[] { "definitions","description" };
169  for (int i = 0; i < toplevel.length; ++i) {
170  NodeList nl = doc.getElementsByTagName(toplevel[i]);
171  for (int j = 0; j < nl.getLength(); ++j) {
172  Element defE = (Element)nl.item(j);
173 
174  NodeList defL = doc.getElementsByTagName("types");
175  for (int k = 0; k < defL.getLength(); ++k) {
176  Element typesE = (Element)defL.item(k);
177 
178  NodeList schemaL = doc.getElementsByTagName("schema");
179  for (int l = 0; l < schemaL.getLength(); ++l) {
180  Element schemaE = (Element)schemaL.item(k);
181 
182  /*
183  * Finally, read a schema!
184  */
185  XmlSchema schema = xmlSchemaCollection.read(schemaE);
186  schemaMap.put(schema.getTargetNamespace(),schema);
187 
188  /*
189  XmlSchemaType tt = schema.getTypeByName(new QName(schema.getTargetNamespace(),"TargetSpecT"));
190  System.err.println("TargetSpecT = " + tt);
191 
192  Iterator<?> iterator = schema.getItems().getIterator();
193  while (iterator.hasNext()) {
194  XmlSchemaObject obj = (XmlSchemaObject) iterator.next();
195  if (obj instanceof XmlSchemaElement) {
196  System.err.println("Element " + ((XmlSchemaElement)obj).getQName());
197  }
198  //else if (
199  else
200  System.err.println("Object " + obj);
201  }
202  */
203  }
204  }
205  }
206  }
207 
208  if (typeMapping != null) {
209  Set<Map.Entry<String,QName>> tms = typeMapping.entrySet();
210  Iterator<Map.Entry<String,QName>> tmi = tms.iterator();
211  while (tmi.hasNext()) {
212  Map.Entry<String,QName> me = tmi.next();
213  System.err.println("DEBUG: adding static mapping to"
214  + " typeTable: "
215  + me.getKey() + " -> " + me.getValue());
216  typeTable.addComplexSchema(me.getKey(),me.getValue());
217  }
218  }
219  } catch (Exception e) {
220  e.printStackTrace();
221  }
222 
223  //System.err.println("sC = " + serviceClass + "; s = " + service);
224 
225  myClassModel = JAXRSUtils.getClassModel(serviceClass);
226  methods = processMethods(serviceClass.getDeclaredMethods());
227 
228  for (String extraClassName : getExtraClasses()) {
229  Class<?> extraClass = Class.forName(extraClassName, true, classLoader);
230  if (typeTable.getSimpleSchemaTypeName(extraClassName) == null) {
231  generateSchema(extraClass);
232  }
233  }
234 
235  return schemaMap.values();
236  }
237 
238  /*
239  * We try to use pre-existing axis-generated classes based off the
240  * schema we've imported. If nothing exists, fallback to the
241  * DefaultSchemaGenerator way by calling super.processMethods()
242  * method by method.
243  */
244  protected Method[] processMethods(Method[] declaredMethods) throws Exception {
245  XmlSchema xmlSchema = getXmlSchema(schemaTargetNameSpace);
246 
247  ArrayList<Method> list = new ArrayList<Method>();
248 
249  Arrays.sort(declaredMethods,new MathodComparator());
250 
251  // since we do not support overload
252  HashMap<String,Method> uniqueMethods = new LinkedHashMap<String,Method>();
253 
254  for (Method jMethod : declaredMethods) {
255  if (jMethod.isBridge())
256  continue;
257 
258  WebMethodAnnotation methodAnnon =
259  JSR181Helper.INSTANCE.getWebMethodAnnotation(jMethod);
260  if (methodAnnon != null && methodAnnon.isExclude())
261  continue;
262 
263  String methodName = jMethod.getName();
264 
265  if (excludeMethods.contains(methodName))
266  continue;
267  if (uniqueMethods.get(methodName) != null)
268  continue;
269  if (!Modifier.isPublic(jMethod.getModifiers()))
270  continue;
271  if (nonRpcMethods.contains(methodName)) {
272  System.err.println("DEBUG: " + methodName + " is a nonRpcMethod;"
273  + " letting DefaultSchemaGenerator handle!");
274  Method tmplist[] = new Method[] { jMethod };
275  Method retval[] = super.processMethods(tmplist);
276  if (retval != null && retval.length == 1) {
277  list.add(jMethod);
278  uniqueMethods.put(methodName,jMethod);
279  }
280  continue;
281  }
282 
283  /*
284  * Need to get a classname for the method (i.e., its wsdl
285  * message), and get a qname for that class!
286  */
287  String methodClassName = methodName;
288  if (methodClassNameMapping.get(methodName) != null)
289  System.err.println("DEBUG: mapping method " + methodName
290  + " to class " + methodClassName);
291  QName methodQName =
292  new QName(xmlSchema.getTargetNamespace(),methodName);
293  if (dynamicTypeMapping.get(methodName) != null) {
294  methodQName = dynamicTypeMapping.get(methodName);
295  System.err.println("DEBUG: mapping method " + methodName
296  + " type to " + methodQName);
297  }
298  XmlSchemaComplexType methodSchemaType =
299  getComplexTypeForElement(xmlSchema,methodQName);
300  if (methodSchemaType == null) {
301  System.err.println("DEBUG: could not find schema type for"
302  + " method " + methodName + "; letting"
303  + "DefaultSchemaGenerator handle!");
304  Method tmplist[] = new Method[] { jMethod };
305  Method retval[] = super.processMethods(tmplist);
306  if (retval != null && retval.length == 1) {
307  list.add(jMethod);
308  uniqueMethods.put(methodName,jMethod);
309  }
310  continue;
311  }
312  boolean addToService = false;
313  AxisOperation axisOperation = service.getOperation(methodQName);
314  if (axisOperation == null) {
315  axisOperation = Utils.getAxisOperationForJmethod(jMethod);
316  addToService = true;
317  }
318  if (axisOperation != null) {
319  Object model =
320  JAXRSUtils.getMethodModel(this.myClassModel,jMethod);
321  axisOperation.addParameter("JAXRSAnnotaion",model);
322  }
323 
324  Class<?>[] parameters = jMethod.getParameterTypes();
325  String parameterNames[] = null;
326  if (parameters.length > 0)
327  parameterNames = methodTable.getParameterNames(methodName);
328  Annotation[][] parameterAnnotation = jMethod.getParameterAnnotations();
329  java.lang.reflect.Type[] genericParameterTypes = jMethod.getGenericParameterTypes();
330  for (int j = 0; j < parameters.length; j++) {
331  Class<?> methodParameter = parameters[j];
332  String parameterName =
333  getParameterName(parameterAnnotation,j,parameterNames);
334  java.lang.reflect.Type genericParameterType = genericParameterTypes[j];
335 
336  /* XXX: does the element for the param, and its type, exist? */
337  }
338 
339  Class<?> returnType = jMethod.getReturnType();
340  String returnClassName = returnType.getName();
341  QName returnQName = null;
342  if ((returnQName = dynamicTypeMapping.get(returnClassName)) != null) {
343  System.err.println("DEBUG: mapping return type " + returnClassName
344  + " to " + returnQName);
345  }
346  else {
347  int idx = returnClassName.lastIndexOf('.');
348  if (idx > -1)
349  returnQName = new QName(xmlSchema.getTargetNamespace(),
350  returnClassName.substring(idx + 1));
351  else
352  returnQName = new QName(xmlSchema.getTargetNamespace(),
353  returnClassName);
354  }
355  XmlSchemaType returnSchemaType = null;
356  if (!"void".equals(jMethod.getReturnType().getName())) {
357  returnSchemaType =
358  getComplexTypeForElement(xmlSchema,returnQName);
359 
360  if (returnSchemaType == null) {
361  System.err.println("DEBUG: could not find schema type for"
362  + "return type " + returnType
363  + " of method " + methodName + ";"
364  + " letting DefaultSchemaGenerator handle!");
365  Method tmplist[] = new Method[] { jMethod };
366  Method retval[] = super.processMethods(tmplist);
367  if (retval != null && retval.length == 1) {
368  list.add(jMethod);
369  uniqueMethods.put(methodName,jMethod);
370  }
371  continue;
372  }
373  }
374 
375  /*
376  * We're committed to handling this one now, rather than
377  * punting it to axis!
378  */
379  list.add(jMethod);
380  uniqueMethods.put(methodName, jMethod);
381 
382  /* TypeTable inserts for method (i.e., in message). */
383  typeTable.addComplexSchema(methodClassName,methodQName);
384  typeTable.addClassNameForQName(methodQName,methodClassName);
385  // hedge our bets with the "original" unqualified method name.
386  //typeTable.addComplexSchema(methodName,methodQName);
387  //typeTable.addClassNameForQName(methodQName,methodName);
388 
389  if (parameters.length > 0) {
390  parameterNames = methodTable.getParameterNames(methodName);
391  // put the parameter names to use it for parsing
392  service.addParameter(methodName,parameterNames);
393  }
394 
395  AxisMessage inMessage =
396  axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
397  inMessage.setElementQName(methodQName);
398  inMessage.setName(methodQName.getLocalPart());
399  service.addMessageElementQNameToOperationMapping(methodSchemaType.getQName(),
400  axisOperation);
401 
402  typeTable.addComplexSchema(returnClassName,returnQName);
403  typeTable.addClassNameForQName(returnQName,returnClassName);
404 
405  if (returnSchemaType != null) {
406  AxisMessage outMessage =
407  axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
408  outMessage.setElementQName(returnQName);
409  outMessage.setName(returnQName.getLocalPart());
410  service.addMessageElementQNameToOperationMapping(returnSchemaType.getQName(),
411  axisOperation);
412  }
413 
414  processException(jMethod,axisOperation);
415 
416  if (addToService)
417  service.addOperation(axisOperation);
418  }
419 
420  return list.toArray(new Method[list.size()]);
421  }
422 
423  protected XmlSchemaComplexType getComplexTypeForElement(XmlSchema xmlSchema,
424  QName name) {
425  System.err.println("DEBUG: getComplexTypeForElement(" + name + ")");
426  XmlSchemaComplexType retval =
427  super.getComplexTypeForElement(xmlSchema,name);
428  System.err.println("DEBUG: getComplexTypeForElement(" + name + ") = " + retval);
429  if (retval == null) {
430  String newLocalPart = name.getLocalPart();
431  char localPartChars[] = newLocalPart.toCharArray();
432  if (localPartChars != null && localPartChars.length > 0
433  && Character.isLowerCase(localPartChars[0])) {
434  localPartChars[0] = Character.toUpperCase(localPartChars[0]);
435  newLocalPart = new String(localPartChars);
436  name = new QName(name.getNamespaceURI(),newLocalPart,name.getPrefix());
437  System.err.println("DEBUG: (uppercase) getComplexTypeForElement(" + name + ")");
438  retval =
439  super.getComplexTypeForElement(xmlSchema,name);
440  System.err.println("DEBUG: (uppercase) getComplexTypeForElement(" + name + ") = " + retval);
441  }
442  }
443  return retval;
444  }
445 
446  protected XmlSchema getXmlSchema(String targetNamespace) {
447  System.err.println("DEBUG: getXmlSchema(" + targetNamespace + ")");
448  XmlSchema xmlSchema = super.getXmlSchema(targetNamespace);
449  System.err.println("DEBUG: getXmlSchema(" + targetNamespace + ") = " + xmlSchema);
450  return xmlSchema;
451  }
452 }
Method[] processMethods(Method[] declaredMethods)
static uint64_t unsigned int i
Collection< XmlSchema > generateSchema()
XmlSchemaComplexType getComplexTypeForElement(XmlSchema xmlSchema, QName name)
Map< String, String > methodClassNameMapping
XmlSchema getXmlSchema(String targetNamespace)
ResourceSchemaGenerator(ClassLoader loader, String className, URL schemaURL, String schemaTargetNamespace, String schemaTargetNamespacePrefix, Map< String, String > methodClassNameMapping, Map< String, QName > dynamicTypeMapping, Map< String, QName > typeMapping, AxisService service)