Save This Page
Home » axis2-1.5-src » org.apache » axis2 » jaxbri » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.axis2.jaxbri;
   21   
   22   import com.sun.codemodel.JCodeModel;
   23   import com.sun.codemodel.writer.FileCodeWriter;
   24   import com.sun.tools.xjc.api.ErrorListener;
   25   import com.sun.tools.xjc.api.Mapping;
   26   import com.sun.tools.xjc.api.Property;
   27   import com.sun.tools.xjc.api.S2JJAXBModel;
   28   import com.sun.tools.xjc.api.SchemaCompiler;
   29   import com.sun.tools.xjc.api.XJC;
   30   import com.sun.tools.xjc.BadCommandLineException;
   31   import org.apache.axis2.description.AxisMessage;
   32   import org.apache.axis2.description.AxisOperation;
   33   import org.apache.axis2.description.AxisService;
   34   import org.apache.axis2.util.SchemaUtil;
   35   import org.apache.axis2.util.URLProcessor;
   36   import org.apache.axis2.util.XMLUtils;
   37   import org.apache.axis2.wsdl.WSDLConstants;
   38   import org.apache.axis2.wsdl.WSDLUtil;
   39   import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
   40   import org.apache.axis2.wsdl.databinding.DefaultTypeMapper;
   41   import org.apache.axis2.wsdl.databinding.JavaTypeMapper;
   42   import org.apache.axis2.wsdl.databinding.TypeMapper;
   43   import org.apache.axis2.wsdl.util.Constants;
   44   import org.apache.commons.logging.Log;
   45   import org.apache.commons.logging.LogFactory;
   46   import org.apache.ws.commons.schema.XmlSchema;
   47   import org.w3c.dom.Document;
   48   import org.w3c.dom.Element;
   49   import org.xml.sax.EntityResolver;
   50   import org.xml.sax.InputSource;
   51   import org.xml.sax.SAXException;
   52   import org.xml.sax.SAXParseException;
   53   
   54   import javax.xml.namespace.QName;
   55   import javax.xml.transform.Result;
   56   import javax.xml.transform.Transformer;
   57   import javax.xml.transform.TransformerFactory;
   58   import javax.xml.transform.dom.DOMSource;
   59   import javax.xml.transform.stream.StreamResult;
   60   import java.io;
   61   import java.util;
   62   import java.net.URLClassLoader;
   63   import java.net.URL;
   64   
   65   public class CodeGenerationUtility {
   66       private static final Log log = LogFactory.getLog(CodeGenerationUtility.class);
   67   
   68       public static final String BINDING_FILE_NAME = "bindingFileName";
   69   
   70       /**
   71        * @param additionalSchemas
   72        * @throws RuntimeException
   73        */
   74       public static TypeMapper processSchemas(final List schemas,
   75                                               Element[] additionalSchemas,
   76                                               CodeGenConfiguration cgconfig)
   77               throws RuntimeException {
   78           try {
   79   
   80               //check for the imported types. Any imported types are supposed to be here also
   81               if (schemas == null || schemas.isEmpty()) {
   82                   //there are no types to be code generated
   83                   //However if the type mapper is left empty it will be a problem for the other
   84                   //processes. Hence the default type mapper is set to the configuration
   85                   return new DefaultTypeMapper();
   86               }
   87   
   88               final Map schemaToInputSourceMap = new HashMap();
   89   
   90               //create the type mapper
   91               JavaTypeMapper mapper = new JavaTypeMapper();
   92   
   93               String baseURI = cgconfig.getBaseURI();
   94               if (!baseURI.endsWith("/")){
   95                  baseURI = baseURI + "/";
   96               }
   97   
   98   
   99               for (int i = 0; i < schemas.size(); i++) {
  100                   XmlSchema schema = (XmlSchema)schemas.get(i);
  101                   InputSource inputSource =
  102                           new InputSource(new StringReader(getSchemaAsString(schema)));
  103                   //here we have to set a proper system ID. otherwise when processing the
  104                   // included schaemas for this schema we have a problem
  105                   // it creates the system ID using this target namespace value
  106   
  107                   inputSource.setSystemId(baseURI + "xsd" + i + ".xsd");
  108                   inputSource.setPublicId(schema.getTargetNamespace());
  109                   schemaToInputSourceMap.put(schema,inputSource);
  110               }
  111   
  112               File outputDir = new File(cgconfig.getOutputLocation(), "src");
  113               outputDir.mkdir();
  114   
  115               Map nsMap = cgconfig.getUri2PackageNameMap();
  116               EntityResolver resolver = new EntityResolver() {
  117                   public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
  118                       InputSource returnInputSource = null;
  119                       XmlSchema key = null;
  120                       for (Iterator iter = schemaToInputSourceMap.keySet().iterator();iter.hasNext();) {
  121                           key = (XmlSchema) iter.next();
  122                           String nsp = key.getTargetNamespace();
  123                           if (nsp != null && nsp.equals(publicId)) {
  124   
  125                               // when returning the input stream we have to always return a new
  126                               // input stream.
  127                               // sinc jaxbri internally consumes the input stream it gives an
  128                               // exception.
  129                               returnInputSource = new InputSource(new StringReader(getSchemaAsString(key)));
  130                               InputSource existingInputSource = (InputSource) schemaToInputSourceMap.get(key);
  131                               returnInputSource.setSystemId(existingInputSource.getSystemId());
  132                               returnInputSource.setPublicId(existingInputSource.getPublicId());
  133                               break;
  134                           }
  135                       }
  136                       if (returnInputSource == null){
  137                           // then we have to find this using the file system
  138                           if (systemId != null){
  139                               returnInputSource = new InputSource(systemId);
  140                               returnInputSource.setSystemId(systemId);
  141                           }
  142                       }
  143                       return returnInputSource;
  144                   }
  145               };
  146   
  147   
  148               Map properties = cgconfig.getProperties();
  149               String bindingFileName = (String) properties.get(BINDING_FILE_NAME);
  150   
  151               XmlSchema key = null;
  152               for (Iterator schemaIter = schemaToInputSourceMap.keySet().iterator();
  153                    schemaIter.hasNext();) {
  154   
  155                   SchemaCompiler sc = XJC.createSchemaCompiler();
  156                   if (bindingFileName != null){
  157                       if (bindingFileName.endsWith(".jar")) {
  158                           scanEpisodeFile(new File(bindingFileName), sc);
  159                       } else {
  160                           InputSource inputSoruce = new InputSource(new FileInputStream(bindingFileName));
  161                           inputSoruce.setSystemId(new File(bindingFileName).toURI().toString());
  162                           sc.getOptions().addBindFile(inputSoruce);
  163                       }
  164   
  165                   }
  166   
  167                   key = (XmlSchema) schemaIter.next();
  168   
  169                   if (nsMap != null) {
  170                       Iterator iterator = nsMap.entrySet().iterator();
  171                       while(iterator.hasNext()){
  172                           Map.Entry entry = (Map.Entry) iterator.next();
  173                           String namespace = (String) entry.getKey();
  174                           String pkg = (String)nsMap.get(namespace);
  175                           registerNamespace(sc, namespace, pkg);
  176                       }
  177                   }
  178   
  179                   sc.setEntityResolver(resolver);
  180   
  181                   sc.setErrorListener(new ErrorListener(){
  182                       public void error(SAXParseException saxParseException) {
  183                           log.error(saxParseException.getMessage());
  184                           log.debug(saxParseException.getMessage(), saxParseException);
  185                       }
  186   
  187                       public void fatalError(SAXParseException saxParseException) {
  188                           log.error(saxParseException.getMessage());
  189                           log.debug(saxParseException.getMessage(), saxParseException);
  190                       }
  191   
  192                       public void warning(SAXParseException saxParseException) {
  193                           log.warn(saxParseException.getMessage());
  194                           log.debug(saxParseException.getMessage(), saxParseException);
  195                       }
  196   
  197                       public void info(SAXParseException saxParseException) {
  198                           log.info(saxParseException.getMessage());
  199                           log.debug(saxParseException.getMessage(), saxParseException);
  200                       }
  201                   });
  202   
  203                   sc.parseSchema((InputSource) schemaToInputSourceMap.get(key));
  204   
  205                   // Bind the XML
  206                   S2JJAXBModel jaxbModel = sc.bind();
  207   
  208                   if(jaxbModel == null){
  209                       throw new RuntimeException("Unable to generate code using jaxbri");
  210                   }
  211   
  212                   // Emit the code artifacts
  213                   JCodeModel codeModel = jaxbModel.generateCode(null, null);
  214                   FileCodeWriter writer = new FileCodeWriter(outputDir);
  215                   codeModel.build(writer);
  216   
  217                   Collection mappings = jaxbModel.getMappings();
  218   
  219                   Iterator iter = mappings.iterator();
  220   
  221                   while (iter.hasNext()) {
  222                       Mapping mapping = (Mapping)iter.next();
  223                       QName qn = mapping.getElement();
  224                       String typeName = mapping.getType().getTypeClass().fullName();
  225   
  226                       mapper.addTypeMappingName(qn, typeName);
  227                   }
  228   
  229                   //process the unwrapped parameters
  230                   if (!cgconfig.isParametersWrapped()) {
  231                       //figure out the unwrapped operations
  232                       List axisServices = cgconfig.getAxisServices();
  233                       for (Iterator servicesIter = axisServices.iterator(); servicesIter.hasNext();) {
  234                           AxisService axisService = (AxisService)servicesIter.next();
  235                           for (Iterator operations = axisService.getOperations();
  236                                operations.hasNext();) {
  237                               AxisOperation op = (AxisOperation)operations.next();
  238   
  239                               if (WSDLUtil.isInputPresentForMEP(op.getMessageExchangePattern())) {
  240                                   AxisMessage message = op.getMessage(
  241                                           WSDLConstants.MESSAGE_LABEL_IN_VALUE);
  242                                   if (message != null &&
  243                                           message.getParameter(Constants.UNWRAPPED_KEY) != null) {
  244   
  245                                       Mapping mapping = jaxbModel.get(message.getElementQName());
  246                                       List elementProperties = mapping.getWrapperStyleDrilldown();
  247                                       for(int j = 0; j < elementProperties.size(); j++){
  248                                           Property elementProperty = (Property) elementProperties.get(j);
  249   
  250                                           QName partQName =
  251                                                       WSDLUtil.getPartQName(op.getName().getLocalPart(),
  252                                                                             WSDLConstants.INPUT_PART_QNAME_SUFFIX,
  253                                                                             elementProperty.elementName().getLocalPart());
  254                                           //this type is based on a primitive type- use the
  255                                           //primitive type name in this case
  256                                           String fullJaveName =
  257                                                   elementProperty.type().fullName();
  258                                           if (elementProperty.type().isArray()) {
  259                                               fullJaveName = fullJaveName.concat("[]");
  260                                           }
  261                                           mapper.addTypeMappingName(partQName, fullJaveName);
  262   
  263                                           if (elementProperty.type().isPrimitive()) {
  264                                               mapper.addTypeMappingStatus(partQName, Boolean.TRUE);
  265                                           }
  266                                           if (elementProperty.type().isArray()) {
  267                                               mapper.addTypeMappingStatus(partQName,
  268                                                                           Constants.ARRAY_TYPE);
  269                                           }
  270                                       }
  271                                   }
  272                               }
  273   
  274                               if (WSDLUtil.isOutputPresentForMEP(op.getMessageExchangePattern())) {
  275                                   AxisMessage message = op.getMessage(
  276                                           WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
  277                                   if (message != null &&
  278                                           message.getParameter(Constants.UNWRAPPED_KEY) != null) {
  279   
  280                                       Mapping mapping = jaxbModel.get(message.getElementQName());
  281                                       List elementProperties = mapping.getWrapperStyleDrilldown();
  282                                       for(int j = 0; j < elementProperties.size(); j++){
  283                                           Property elementProperty = (Property) elementProperties.get(j);
  284   
  285                                           QName partQName =
  286                                                       WSDLUtil.getPartQName(op.getName().getLocalPart(),
  287                                                                             WSDLConstants.OUTPUT_PART_QNAME_SUFFIX,
  288                                                                             elementProperty.elementName().getLocalPart());
  289                                           //this type is based on a primitive type- use the
  290                                           //primitive type name in this case
  291                                           String fullJaveName =
  292                                                   elementProperty.type().fullName();
  293                                           if (elementProperty.type().isArray()) {
  294                                               fullJaveName = fullJaveName.concat("[]");
  295                                           }
  296                                           mapper.addTypeMappingName(partQName, fullJaveName);
  297   
  298                                           if (elementProperty.type().isPrimitive()) {
  299                                               mapper.addTypeMappingStatus(partQName, Boolean.TRUE);
  300                                           }
  301                                           if (elementProperty.type().isArray()) {
  302                                               mapper.addTypeMappingStatus(partQName,
  303                                                                           Constants.ARRAY_TYPE);
  304                                           }
  305                                       }
  306                                   }
  307                               }
  308                           }
  309                       }
  310                   }
  311               }
  312   
  313               // Return the type mapper
  314               return mapper;
  315   
  316           } catch (Exception e) {
  317               throw new RuntimeException(e);
  318           }
  319       }
  320   
  321       private static void scanEpisodeFile(File jar, SchemaCompiler sc)
  322               throws BadCommandLineException, IOException {
  323   
  324           URLClassLoader ucl = new URLClassLoader(new URL[]{jar.toURL()});
  325           Enumeration<URL> resources = ucl.findResources("META-INF/sun-jaxb.episode");
  326           while (resources.hasMoreElements()) {
  327               URL url = resources.nextElement();
  328               sc.getOptions().addBindFile(new InputSource(url.toExternalForm()));
  329           }
  330   
  331       }
  332   
  333   
  334       private static void registerNamespace(SchemaCompiler sc, String namespace, String pkgName) throws Exception {
  335           Document doc = XMLUtils.newDocument();
  336           Element rootElement = doc.createElement("schema");
  337           rootElement.setAttribute("xmlns", "http://www.w3.org/2001/XMLSchema");
  338           rootElement.setAttribute("xmlns:jaxb", "http://java.sun.com/xml/ns/jaxb");
  339           rootElement.setAttribute("jaxb:version", "2.0");
  340           rootElement.setAttribute("targetNamespace", namespace);
  341           Element annoElement = doc.createElement("annotation");
  342           Element appInfo = doc.createElement("appinfo");
  343           Element schemaBindings = doc.createElement("jaxb:schemaBindings");
  344           Element pkgElement = doc.createElement("jaxb:package");
  345           pkgElement.setAttribute("name", pkgName);
  346           annoElement.appendChild(appInfo);
  347           appInfo.appendChild(schemaBindings);
  348           schemaBindings.appendChild(pkgElement);
  349           rootElement.appendChild(annoElement);
  350           File file = File.createTempFile("customized",".xsd");
  351           FileOutputStream stream = new FileOutputStream(file);
  352           try {
  353               Result result = new StreamResult(stream);
  354               Transformer xformer = TransformerFactory.newInstance().newTransformer();
  355               xformer.transform(new DOMSource(rootElement), result);
  356               stream.flush();
  357               stream.close();
  358           } catch (Exception e) {
  359               e.printStackTrace();
  360           }
  361           InputSource ins = new InputSource(file.toURI().toString());
  362           sc.parseSchema(ins);
  363           file.delete();
  364       }
  365   
  366       private static String extractNamespace(XmlSchema schema) {
  367           String pkg;
  368           pkg = schema.getTargetNamespace();
  369           if (pkg == null) {
  370               XmlSchema[] schemas2 = SchemaUtil.getAllSchemas(schema);
  371               for (int j = 0; schemas2 != null && j < schemas2.length; j++) {
  372                   pkg = schemas2[j].getTargetNamespace();
  373                   if (pkg != null)
  374                       break;
  375               }
  376           }
  377           if (pkg == null) {
  378               pkg = URLProcessor.DEFAULT_PACKAGE;
  379           }
  380           pkg = URLProcessor.makePackageName(pkg);
  381           return pkg;
  382       }
  383   
  384       private static String getSchemaAsString(XmlSchema schema) {
  385           ByteArrayOutputStream baos = new ByteArrayOutputStream();
  386           schema.write(baos);
  387           return baos.toString();
  388       }
  389   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » jaxbri » [javadoc | source]