Package org.apache.ws.jaxme.generator.sg.impl

Source Code of org.apache.ws.jaxme.generator.sg.impl.JAXBComplexTypeSG

/*
* Copyright 2003,2004  The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.

*/
package org.apache.ws.jaxme.generator.sg.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBException;
import javax.xml.bind.ValidationEvent;
import javax.xml.namespace.QName;

import org.apache.ws.jaxme.JMXmlSerializer;
import org.apache.ws.jaxme.ValidationEvents;
import org.apache.ws.jaxme.WildcardAttribute;
import org.apache.ws.jaxme.generator.SchemaReader;
import org.apache.ws.jaxme.generator.sg.AttributeSG;
import org.apache.ws.jaxme.generator.sg.AttributeSGChain;
import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
import org.apache.ws.jaxme.generator.sg.ComplexContentSGChain;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSGChain;
import org.apache.ws.jaxme.generator.sg.Context;
import org.apache.ws.jaxme.generator.sg.GroupSG;
import org.apache.ws.jaxme.generator.sg.ParticleSG;
import org.apache.ws.jaxme.generator.sg.SGlet;
import org.apache.ws.jaxme.generator.sg.SimpleContentSG;
import org.apache.ws.jaxme.generator.sg.SimpleContentSGChain;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.impl.JMHandlerImpl;
import org.apache.ws.jaxme.impl.JMXmlSerializerImpl;
import org.apache.ws.jaxme.js.DirectAccessible;
import org.apache.ws.jaxme.js.JavaField;
import org.apache.ws.jaxme.js.JavaMethod;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaQNameImpl;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.JavaSourceFactory;
import org.apache.ws.jaxme.js.LocalJavaField;
import org.apache.ws.jaxme.js.Parameter;
import org.apache.ws.jaxme.js.PlaceHolder;
import org.apache.ws.jaxme.logging.Logger;
import org.apache.ws.jaxme.logging.LoggerAccess;
import org.apache.ws.jaxme.xs.XSAttributable;
import org.apache.ws.jaxme.xs.XSAttribute;
import org.apache.ws.jaxme.xs.XSComplexType;
import org.apache.ws.jaxme.xs.XSType;
import org.apache.ws.jaxme.xs.XSWildcard;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.AttributesImpl;

/**
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
* @author <a href="mailto:iasandcb@tmax.co.kr">Ias</a>
*/
public class JAXBComplexTypeSG implements ComplexTypeSGChain {
  private final static Logger log = LoggerAccess.getLogger(JAXBComplexTypeSG.class);
  private final TypeSG typeSG;
  private final XSType xsType;
  private final boolean hasSimpleContent;
  private final Context classContext;
  private SimpleContentSG simpleContentSG;
  private ComplexContentSG complexContentSG;
  private AttributeSG[] attributes;
 
  protected JAXBComplexTypeSG(TypeSG pTypeSG, XSType pType) throws SAXException {
    final String mName = "<init>(XSType)";
    log.finest(mName, "->", new Object[]{pTypeSG, pType});
    typeSG = pTypeSG;
    xsType = pType;
    XSComplexType complexType= pType.getComplexType();
    hasSimpleContent = complexType.hasSimpleContent();
    String suffix = pTypeSG.isGlobalType() ? null : "Type";
    classContext = new GlobalContext(pTypeSG.getName(), pType, null, suffix, pTypeSG.getSchema());
    log.finest(mName, "<-", classContext);
  }
 
  /** <p>Constructor for a local type, which is embedded into the enclosing
   * <code>pContext</code>.</p>
   */
  protected JAXBComplexTypeSG(TypeSG pTypeSG, XSType pType, Context pContext) throws SAXException {
    final String mName = "<init>(XSType)";
    log.finest(mName, "->", new Object[]{pTypeSG, pType, pContext});
    typeSG = pTypeSG;
    xsType = pType;
    XSComplexType complexType= pType.getComplexType();
    hasSimpleContent = complexType.hasSimpleContent();
    classContext = new LocalContext(pContext, pTypeSG.getName().getLocalName(), pType, null, "Type",
        pTypeSG.getSchema());
    log.finest(mName, "<-", classContext);
  }
 
  public Object newAttributeSG(ComplexTypeSG pController, XSAttribute pAttribute) throws SAXException {
    return new JAXBAttributeSG(typeSG.getSchema(), pAttribute, classContext);
  }

  public Object newAttributeSG(ComplexTypeSG pController, XSWildcard pWildcard) throws SAXException {
    return new JAXBAttributeSG(typeSG.getSchema(), pWildcard, classContext);
  }

  private AttributeSG[] initAttributes(ComplexTypeSG pController) throws SAXException {
    XSAttributable[] xsAttributes = xsType.getComplexType().getAttributes();
    List attributeList = new ArrayList();
    for (int i = 0;  i < xsAttributes.length;  i++) {
      AttributeSGChain attrChain;
      if (xsAttributes[i] instanceof XSAttribute) {
        XSAttribute attr = (XSAttribute) xsAttributes[i];
        attrChain = (AttributeSGChain) pController.newAttributeSG(attr);
      } else if (xsAttributes[i] instanceof XSWildcard) {
        boolean isSupportingExtensions = false;
        SchemaReader schemaReader = pController.getTypeSG().getFactory().getGenerator().getSchemaReader();
        if (schemaReader instanceof JAXBSchemaReader) {
          isSupportingExtensions = ((JAXBSchemaReader) schemaReader).isSupportingExtensions();
        }
        if (isSupportingExtensions) {
          XSWildcard wildcard = (XSWildcard) xsAttributes[i];
          attrChain = (AttributeSGChain) pController.newAttributeSG(wildcard);
        } else {
          throw new SAXParseException("Extensions must be enabled to support wildcard attributes (JAXB 1.0, App. E.2.1.1)",
              ((XSWildcard) xsAttributes[i]).getLocator());
        }
      } else {
        throw new IllegalStateException("Unknown attribute type: " + xsAttributes[i].getClass().getName());
      }
      AttributeSG attrSG = new AttributeSGImpl(attrChain);
      attrSG.init();
      attributeList.add(attrSG);
    }
    return (AttributeSG[]) attributeList.toArray(new AttributeSG[attributeList.size()]);
  }
 
  public void addAttributeSG(ComplexTypeSG pController, AttributeSG pAttribute) throws SAXException {
    AttributeSG[] result = new AttributeSG[attributes.length+1];
    System.arraycopy(attributes, 0, result, 0, attributes.length);
    result[attributes.length] = pAttribute;
    attributes = result;
    pAttribute.init();
  }
 
  public void init(ComplexTypeSG pController) throws SAXException {
    attributes = initAttributes(pController);
    if (pController.hasSimpleContent()) {
      SimpleContentSGChain chain = (SimpleContentSGChain) pController.newSimpleContentTypeSG();
      simpleContentSG = new SimpleContentSGImpl(chain);
      simpleContentSG.init();
    } else {
      ComplexContentSGChain chain = (ComplexContentSGChain) pController.newComplexContentTypeSG();
      complexContentSG = new ComplexContentSGImpl(chain);
      complexContentSG.init();
    }
  }
 
  public boolean hasSimpleContent(ComplexTypeSG pController) { return hasSimpleContent; }
  public TypeSG getTypeSG(ComplexTypeSG pController) { return typeSG; }
 
  public boolean hasAttributes(ComplexTypeSG pController) {
    return attributes.length != 0;
  }
 
  public AttributeSG[] getAttributes(ComplexTypeSG pController) {
    return attributes;
  }
 
  public Context getClassContext(ComplexTypeSG pController) { return classContext; }
  public Locator getLocator(ComplexTypeSG pController) { return xsType.getLocator(); }
 
 
  private void generateProperties(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    AttributeSG[] myAttributes = pController.getAttributes();
    for (int i = 0;  i < myAttributes.length;  i++) {
      myAttributes[i].getPropertySG().generate(pSource);
    }
   
    if (pController.hasSimpleContent()) {
      pController.getSimpleContentSG().getPropertySG().generate(pSource);
    } else {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs
        groupSG.generateProperties(pSource);
      }
    }   
  }
 
  public JavaSource getXMLInterface(ComplexTypeSG pController) throws SAXException {
    final String mName = "getXMLInterface";
    log.finest(mName, "->");
    JavaQName qName = pController.getClassContext().getXMLInterfaceName();
    JavaSourceFactory jsf = pController.getTypeSG().getSchema().getJavaSourceFactory();
    JavaSource js = jsf.newJavaSource(qName, JavaSource.PUBLIC);
    js.setType(JavaSource.INTERFACE);

    generateProperties(pController, js);
    if (!pController.hasSimpleContent()) {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs
        groupSG.generateXMLInterfaceSubclasses(js);
      }
    }
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public JavaSource getXMLInterface(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    final String mName = "getXMLInterface(JavaSource)";
    log.finest(mName, "->", pSource.getQName());
    JavaQName qName = pController.getClassContext().getXMLInterfaceName();
    JavaSource js = pSource.newJavaInnerClass(qName.getClassName(), JavaSource.PUBLIC);
    js.setType(JavaSource.INTERFACE);
   
    generateProperties(pController, js);
    if (!pController.hasSimpleContent()) {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs
        groupSG.generateXMLInterfaceSubclasses(js);
      }
    }
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public JavaSource getXMLImplementation(ComplexTypeSG pController) throws SAXException {
    final String mName = "getXMLImplementation(JavaQName)";
    log.finest(mName, "->", typeSG.getName());
    JavaSourceFactory jsf = pController.getTypeSG().getSchema().getJavaSourceFactory();
    JavaSource js = jsf.newJavaSource(pController.getClassContext().getXMLImplementationName(), JavaSource.PUBLIC);
    js.addImplements(pController.getClassContext().getXMLInterfaceName());
    SerializableSG.makeSerializable(pController.getTypeSG().getSchema(), js);

    generateProperties(pController, js);
    if (!pController.hasSimpleContent()) {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs
        groupSG.generateXMLImplementationSubclasses(js);
      }
    }
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public JavaSource getXMLImplementation(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    final String mName = "getXMLImplementation(JavaQName,JavaSource)";
    log.finest(mName, "->", pSource.getQName());
    JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLImplementationName().getInnerClassName(), JavaSource.PUBLIC);
    js.setStatic(true);
    js.addImplements(pController.getClassContext().getXMLInterfaceName());
    SerializableSG.makeSerializable(pController.getTypeSG().getSchema(), js);
   
    generateProperties(pController, js);
    if (!pController.hasSimpleContent()) {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs
        groupSG.generateXMLImplementationSubclasses(js);
      }
    }
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public JavaSource getXMLSerializer(ComplexTypeSG pController) throws SAXException {
    final String mName = "getXMLSerializer";
    log.finest(mName, "->", typeSG.getName());
    JavaQName xmlSerializerName = pController.getClassContext().getXMLSerializerName();
    JavaSourceFactory jsf = typeSG.getSchema().getJavaSourceFactory();
    JavaSource js = jsf.newJavaSource(xmlSerializerName, JavaSource.PUBLIC);
    js.addExtends(JMXmlSerializerImpl.class);
    pController.generateXMLSerializerMethods(js);
    return js;
  }
 
  public JavaSource getXMLSerializer(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    final String mName = "getXMLSerializer(JavaSource)";
    log.finest(mName, "->", pSource.getQName());
    JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLSerializerName().getInnerClassName(), JavaSource.PUBLIC);
    js.setStatic(true);
    js.addExtends(JMXmlSerializerImpl.class);
    pController.generateXMLSerializerMethods(js);
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public JavaSource getXMLHandler(ComplexTypeSG pController) throws SAXException {
    final String mName = "getXMLHandler";
    log.finest(mName, "->", typeSG.getName());
    JavaQName xmlSerializerName = pController.getClassContext().getXMLHandlerName();
    JavaSourceFactory jsf = typeSG.getSchema().getJavaSourceFactory();
    JavaSource js = jsf.newJavaSource(xmlSerializerName, JavaSource.PUBLIC);
    js.addExtends(JMHandlerImpl.class);
    pController.generateXMLHandlerMethods(js);
    return js;
  }
 
  public JavaSource getXMLHandler(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    final String mName = "getXMLHandler(JavaSource)";
    log.finest(mName, "->", pSource.getQName());
    JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLHandlerName().getInnerClassName(), JavaSource.PUBLIC);
    js.setStatic(true);
    js.addExtends(JMHandlerImpl.class);
    pController.generateXMLHandlerMethods(js);
    log.finest(mName, "<-", js.getQName());
    return js;
  }
 
  public SimpleContentSG getSimpleContentSG(ComplexTypeSG pController) {
    if (simpleContentSG == null) {
      throw new IllegalStateException("This complex type doesn't have simple content.");
    }
    return simpleContentSG;
  }
 
  public ComplexContentSG getComplexContentSG(ComplexTypeSG pController) {
    if (complexContentSG == null) {
      throw new IllegalStateException("This complex type doesn't have complex content.");
    }
    return complexContentSG;
  }
 
  public void generateXMLInterfaceMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    generateProperties(pController, pSource);
    if (pController.hasSimpleContent()) {
      pController.getSimpleContentSG().getPropertySG().generate(pSource);
    } else {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      groupSG.generateXMLInterfaceSubclasses(pSource);
    }
  }
 
  public void generateXMLImplementationMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    generateProperties(pController, pSource);
    if (pController.hasSimpleContent()) {
      pController.getSimpleContentSG().getPropertySG().generate(pSource);
    } else {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      groupSG.generateXMLImplementationSubclasses(pSource);
    }
  }

  private class XMLSerializerAttributeSGlet implements SGlet {
    private AttributeSG attribute;
    private final DirectAccessible attributeList;
    private final DirectAccessible data;
    public XMLSerializerAttributeSGlet(DirectAccessible pAttributeList, DirectAccessible pData) {
      attributeList = pAttributeList;
      data = pData;
    }
    public void setAttribute(AttributeSG pAttribute) {
      attribute = pAttribute;
    }
    public void generate(JavaMethod pMethod, Object pValue) throws SAXException {
      String uri = JavaSource.getQuoted(attribute.getName().getNamespaceURI());
      String localName = JavaSource.getQuoted(attribute.getName().getLocalName());
      pMethod.addLine(attributeList, ".addAttribute(", uri, ", ", localName,
              ", getAttributeQName(pData, ", uri, ", ", localName, "), \"CDATA\", ",
              attribute.getTypeSG().getSimpleTypeSG().getCastToString(pMethod, pValue, data), ");");
    }
  }
 
  private void generateXMLSerializersAttributes(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    final String mName = "generateXMLSerializersAttributes";
    log.finest(mName, "->", pSource.getQName());
    if (!pController.hasAttributes()) {
      log.finest(mName, "<-");
      return;
    }
   
    JavaMethod jm = pSource.newJavaMethod("getAttributes", AttributesImpl.class, "protected");
    DirectAccessible pData = jm.addParam(JavaQNameImpl.getInstance(JMXmlSerializer.Data.class), "pData");
    DirectAccessible pElement = jm.addParam(Object.class, "pElement");
    jm.addThrows(SAXException.class);
    LocalJavaField result = jm.newJavaField(AttributesImpl.class);
    result.addLine("super.getAttributes(", pData, ", ", pElement, ")");
    JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
    LocalJavaField element = jm.newJavaField(elementInterface);
    element.addLine("(", elementInterface, ") ", pElement);
   
    AttributeSG[] myAttributes = pController.getAttributes();
    XMLSerializerAttributeSGlet sgLet = new XMLSerializerAttributeSGlet(result, pData);
    for (int i = 0;  i < attributes.length;  i++) {
      AttributeSG attribute = myAttributes[i];
      if (attribute.isWildcard()) {
          LocalJavaField anyAttributes = jm.newJavaField(WildcardAttribute[].class);
          anyAttributes.addLine(element, ".", attribute.getPropertySG().getXMLGetMethodName() + "Array", "()");
          DirectAccessible index = jm.addForArray(anyAttributes);
          LocalJavaField wildcardAttribute = jm.newJavaField(WildcardAttribute.class);
          wildcardAttribute.addLine(anyAttributes, "[", index, "]");
        LocalJavaField qName = jm.newJavaField(QName.class);
        qName.addLine(wildcardAttribute, ".getName()");
        LocalJavaField uri = jm.newJavaField(String.class);
        uri.addLine(qName, ".getNamespaceURI()");
        LocalJavaField localPart = jm.newJavaField(String.class);
        localPart.addLine(qName, ".getLocalPart()");
        jm.addLine(result, ".addAttribute(", uri, ", ", localPart,
               ", getAttributeQName(pData, ", uri, ", ", localPart,
                           "), \"CDATA\", ", wildcardAttribute, ".getValue());");
        jm.addEndFor();
      } else {
        sgLet.setAttribute(attribute);
        attribute.forAllNonNullValues(jm, element, sgLet);
      }
    }
    jm.addLine("return ", result, ";");
  }
 
  private JavaMethod getXMLSerializersGetPreferredPrefixMethod(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    Map uris = new HashMap();
    List names = new ArrayList();
    names.add(pController.getTypeSG().getName());
    AttributeSG[] myAttributes = pController.getAttributes();
    for (int i = 0;  i < myAttributes.length;  i++) {
      XsQName qName = myAttributes[i].getName();
      if (qName != null) {
        names.add(qName);
      }
    }
    if (!pController.hasSimpleContent()) {
      ComplexContentSG myComplexContentSG = pController.getComplexContentSG();
      GroupSG groupSG = myComplexContentSG.getGroupSG();
      if (groupSG != null) { // Check required, in case the element doesn't have any childs.
        ParticleSG[] particles = groupSG.getParticles();
        for (int i = 0;  i < particles.length;  i++) {
          if (particles[i].isElement()) {
            names.add(particles[i].getObjectSG().getName());
          }
        }
      }
    }
    for (Iterator iter = names.iterator();  iter.hasNext()) {
      XsQName qName = (XsQName) iter.next();
      String prefix = qName.getPrefix();
      if (prefix != null) {
        String uri = qName.getNamespaceURI();
        if (uri == null) uri = "";
        if (!uris.containsKey(uri)) {
          uris.put(uri, prefix);
        }
      }
    }
   
    if (uris.isEmpty()) {
      return null;
    }
    JavaMethod jm = pSource.newJavaMethod("getPreferredPrefix", String.class, JavaSource.PUBLIC);
    DirectAccessible pURI = jm.addParam(String.class, "pURI");
    jm.addIf(pURI, " == null");
    jm.addLine(pURI, " = \"\";");
    jm.addEndIf();
    boolean first = true;
    for (Iterator iter = uris.entrySet().iterator();  iter.hasNext()) {
      Map.Entry entry = (Map.Entry) iter.next();
      String uri = (String) entry.getKey();
      String prefix = (String) entry.getValue();
      jm.addIf(first, pURI, ".equals(", JavaSource.getQuoted(uri), ")");
      jm.addLine("return ", JavaSource.getQuoted(prefix), ";");     
      first = false;
    }
    jm.addEndIf();
    jm.addLine("return super.getPreferredPrefix(", pURI, ");");
    return jm;
  }

  protected JavaMethod getXMLSerializersMarshalChildsMethod(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
      JavaMethod jm = pSource.newJavaMethod("marshalChilds", void.class, JavaSource.PUBLIC);
      jm.addThrows(SAXException.class);
      Parameter pData = jm.addParam(JMXmlSerializer.Data.class, "pData");
      Parameter pElement = jm.addParam(Object.class, "pElement");
      JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
      LocalJavaField element = jm.newJavaField(elementInterface);
      element.addLine("(", elementInterface, ") ", pElement);
      LocalJavaField chars = jm.newJavaField(String.class);
      SimpleContentSG simpleContent = pController.getSimpleContentSG();
      Object value = simpleContent.getPropertySG().getValue(element);
      chars.addLine(simpleContent.getContentTypeSG().getSimpleTypeSG().getCastToString(jm, value, pData));
        jm.addIf(chars, ".length() > 0");
      LocalJavaField charArray = jm.newJavaField(char[].class);
      charArray.addLine(chars, ".toCharArray()");
      jm.addLine(pData, ".getContentHandler().characters(", charArray, ", 0, ", charArray, ".length);");
        jm.addEndIf();
      return jm;
  }
 
  public void generateXMLSerializerMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    generateXMLSerializersAttributes(pController, pSource);
    getXMLSerializersGetPreferredPrefixMethod(pController, pSource);
    if (pController.hasSimpleContent()) {
        getXMLSerializersMarshalChildsMethod(pController, pSource);
    } else {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) {  // Check required, in case of empty content
        groupSG.generateXMLSerializersElements(pSource);
      }
    }
  }
 
  private JavaMethod getXMLHandlersStartDocumentMethod(ComplexTypeSG pController, JavaSource pSource,
                             DirectAccessible pLevelVar) {
    JavaMethod jm = pSource.newJavaMethod("startDocument", JavaQNameImpl.VOID, JavaSource.PUBLIC);
    jm.addThrows(SAXException.class);
    jm.addLine(pLevelVar, " = 0;");
    return jm;
  }

  private Set createSetOfExplicitURIs(AttributeSG[] pAttributes) {
    Set result = new HashSet();
    for (int i = 0;  i < pAttributes.length;  i++) {
      AttributeSG attr = pAttributes[i];
      if (attr.isWildcard()) {
        continue;
      }
      String uri = attr.getName().getNamespaceURI();
      if (uri == null) { uri = ""; }

      result.add(uri);
    }
    return result;
  }

  private JavaMethod getXMLHandlersAddAttributeMethod(ComplexTypeSG pController, JavaSource pSource)
      throws SAXException {
    AttributeSG[] myAttributes = pController.getAttributes();
    if (myAttributes.length == 0) {
      return null;
    }
   
    JavaMethod jm = pSource.newJavaMethod("addAttribute", JavaQNameImpl.VOID, JavaSource.PUBLIC);
    DirectAccessible pURI = jm.addParam(String.class, "pURI");
    DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
    DirectAccessible pValue = jm.addParam(String.class, "pValue");
    jm.addThrows(SAXException.class);
    jm.addIf(pURI, " == null");
    jm.addLine(pURI, " = \"\";");
    jm.addEndIf();
   
    JavaQName resultType = pController.getClassContext().getXMLInterfaceName();
    LocalJavaField result = jm.newJavaField(resultType);
    result.addLine("(", resultType, ") getResult()");

    Set uris = createSetOfExplicitURIs(myAttributes);
    boolean first = true;
    for (Iterator iter = uris.iterator();  iter.hasNext()) {
      String uri = (String) iter.next();
      jm.addIf(first, JavaSource.getQuoted(uri), ".equals(", pURI, ")");
      first = false;
        boolean firstInNamespace = true;
      for (int i = 0;  i < myAttributes.length;  i++) {
        AttributeSG attr = myAttributes[i];
        if (attr.isWildcard()) {
          continue;
        }
        String jUri = attr.getName().getNamespaceURI();
        if (jUri == null) { jUri = ""; }
        if (!uri.equals(jUri)) {
          continue;
        }
       
        jm.addIf(firstInNamespace, JavaSource.getQuoted(attr.getName().getLocalName()), ".equals(", pLocalName, ")");
        firstInNamespace = false;
        Object v = myAttributes[i].getTypeSG().getSimpleTypeSG().getCastFromString(jm, pValue, "getData()");
        attr.getPropertySG().setValue(jm, result, v, null);
        jm.addLine("return;");
      }
      if (!firstInNamespace) {
          jm.addEndIf();
      }
    }
    if (!first) {
      jm.addEndIf();
    }

    AttributeSG wildcard = null;
    for (int i = 0;  i < myAttributes.length;  i++) {
        if (myAttributes[i].isWildcard()) {
            wildcard = myAttributes[i];
            break;
        }
    }
    if (wildcard == null) {
        jm.addLine("super.addAttribute(", pURI, ", ", pLocalName, ", ", pValue, ");");
    } else {
        jm.addTry();
        jm.addLine(result, ".", wildcard.getPropertySG().getXMLSetMethodName(), "(new ",
                QName.class, "(", pURI, ", ", pLocalName, "), ", pValue, ");");
        jm.addCatch(IllegalArgumentException.class);
        jm.addLine("validationEvent(", ValidationEvent.class, ".ERROR, ",
                JavaSource.getQuoted("Invalid namespace for anyAttribute: '"),
                " + ", pURI, " + ", JavaSource.getQuoted("', attribute name is '"),
          " + ", pLocalName, " + ", JavaSource.getQuoted("'"),
          ", ", ValidationEvents.class, ".EVENT_UNKNOWN_ANY_ATTRIBUTE);");
        jm.addEndTry();
    }
    return jm;
  }
 
  protected JavaMethod getXMLHandlersNewResultMethod(ComplexTypeSG pController, JavaSource pSource) {
    JavaQName elementInterfaceClass = pController.getClassContext().getXMLInterfaceName();
    JavaMethod jm = pSource.newJavaMethod("newResult", elementInterfaceClass, JavaSource.PROTECTED);
    jm.addThrows(SAXException.class);
    if (pController.getClassContext().isGlobal()) {
      jm.addTry();
      jm.addLine("return (", elementInterfaceClass, ") getData().getFactory().getElement(",
          elementInterfaceClass, ".class);");
      DirectAccessible e = jm.addCatch(JAXBException.class);
      jm.addThrowNew(SAXException.class, e);
      jm.addEndTry();
    } else {
      JavaQName elementImplClass = pController.getClassContext().getXMLImplementationName();
      jm.addLine("return new ", elementImplClass, "();");
    }
    return jm;
  }

  public JavaMethod getXMLHandlersEndElementMethod(ComplexTypeSG pController, JavaSource pSource,
                           DirectAccessible pLevelVar)
      throws SAXException {
      if (!pController.hasSimpleContent()  &&  pController.getComplexContentSG().getGroupSG() != null) {
          return null// GroupSG creates method
      }
      JavaMethod jm = pSource.newJavaMethod("endElement", void.class, JavaSource.PUBLIC);
      DirectAccessible pNamespaceURI = jm.addParam(String.class, "pNamespaceURI");
      DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
      DirectAccessible pQName = jm.addParam(String.class, "pQName");
      jm.addThrows(SAXException.class);
      jm.addSwitch("--", pLevelVar);
      jm.addCase("0");
      if (pController.hasSimpleContent()) {
          JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
          LocalJavaField element = jm.newJavaField(elementInterface);
          element.addLine("(", elementInterface, ") getResult()");

          SimpleContentSG simpleContent = pController.getSimpleContentSG();
          Object value = simpleContent.getContentTypeSG().getSimpleTypeSG().getCastFromString(jm, "__content.toString()", "getData()");
          simpleContent.getPropertySG().setValue(jm, element, value, null);
      }
      jm.addBreak();
      if (pController.hasSimpleContent()) {
          jm.addDefault();
          jm.addLine("super.endElement(pNamespaceURI, pLocalName, pQName);");
          jm.addBreak();
      } else {
          PlaceHolder placeHolder = jm.newPlaceHolder("GroupSG", true);
          placeHolder.setProperty("pNamespaceURI", pNamespaceURI);
          placeHolder.setProperty("pLocalName", pLocalName);
          placeHolder.setProperty("pQName", pQName);
      }
      jm.addEndSwitch();
      return jm;
  }

  public JavaMethod getXMLHandlersStartElementMethod(ComplexTypeSG pController, JavaSource pSource,
                             DirectAccessible pLevelVar)
      throws SAXException {
    JavaMethod jm = pSource.newJavaMethod("startElement", void.class, JavaSource.PUBLIC);
    DirectAccessible pNamespaceURI = jm.addParam(String.class, "pNamespaceURI");
    DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
    DirectAccessible pQName = jm.addParam(String.class, "pQName");
    DirectAccessible pAttr = jm.addParam(Attributes.class, "pAttr");
    jm.addThrows(SAXException.class);

    jm.addSwitch(pLevelVar, "++");
    jm.addCase("0");
   
    jm.addLine("setResult(newResult());");
    jm.addIf(pAttr, " != null");
   
    String iVar = jm.getLocalVariableName();
    jm.addFor("int ", iVar, " = 0;  ", iVar, " < pAttr.getLength();  ", iVar, "++");
    AttributeSG[] myAttributes = pController.getAttributes();
    if (myAttributes.length == 0) {
      jm.addLine("super.addAttribute(", pAttr, ".getURI(", iVar, "), ", pAttr, ".getLocalName(", iVar,
          "), ", pAttr, ".getValue(", iVar, "));");
    } else {
      jm.addLine("addAttribute(", pAttr, ".getURI(", iVar, "), ", pAttr, ".getLocalName(", iVar,
          "), ", pAttr, ".getValue(", iVar, "));");     
    }
    jm.addEndFor();
    jm.addEndIf();
    if (pController.hasSimpleContent()) {
        JavaField jf = pSource.newJavaField("__content", StringBuffer.class, JavaSource.PRIVATE);
        jm.addLine(jf, " = new ", StringBuffer.class, "();");
    }
    jm.addBreak();
   
    if (pController.hasSimpleContent()) {
      jm.addDefault();
      jm.addLine("super.startElement(pNamespaceURI, pLocalName, pQName, pAttr);");
      jm.addBreak();
    } else {
      PlaceHolder placeHolder = jm.newPlaceHolder("GroupSG", true);
      placeHolder.setProperty("pNamespaceURI", pNamespaceURI);
      placeHolder.setProperty("pLocalName", pLocalName);
      placeHolder.setProperty("pQName", pQName);
      placeHolder.setProperty("pAttr", pAttr);
    }
    jm.addEndSwitch();
   
    return jm;
  }
 
  private JavaField getXMLHandlersLevelField(ComplexTypeSG pController, JavaSource pSource) {
    JavaField jf = pSource.newJavaField("__level", int.class, JavaSource.PRIVATE);
    jf.newComment().addLine("The current level of nested elements. 0, if outside the root element.");
    return jf;
  }

  protected JavaMethod getXMLHandlersCharactersMethod(ComplexTypeSG pController, JavaSource pSource,
                            JavaField pLevelVar) throws SAXException {
      if (!pController.hasSimpleContent()) {
          return null;
      }
      JavaMethod jm = pSource.newJavaMethod("characters", void.class, JavaSource.PUBLIC);
      Parameter buffer = jm.addParam(char[].class, "pChars");
      Parameter offset = jm.addParam(int.class, "pOffset");
      Parameter length = jm.addParam(int.class, "pLength");
      jm.addThrows(SAXException.class);
      jm.addIf(pLevelVar, " == 1");
      jm.addLine("__content.append(", buffer, ", ", offset, ", ", length, ");");
      jm.addEndIf();
      return jm;
  }

  public void generateXMLHandlerMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
    JavaField levelVar = getXMLHandlersLevelField(pController, pSource);
    getXMLHandlersStartDocumentMethod(pController, pSource, levelVar);
    getXMLHandlersAddAttributeMethod(pController, pSource);
    getXMLHandlersNewResultMethod(pController, pSource);
    getXMLHandlersStartElementMethod(pController, pSource, levelVar);
    getXMLHandlersEndElementMethod(pController, pSource, levelVar);
    getXMLHandlersCharactersMethod(pController, pSource, levelVar);
    if (!pController.hasSimpleContent()) {
      GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
      if (groupSG != null) {  // Check required, in case the element doesn't have any childs.
        groupSG.generateXMLHandlersElements(pSource, levelVar);
      }
    }
  }
 
  public Object newComplexContentTypeSG(ComplexTypeSG pController) throws SAXException {
    return new JAXBComplexContentTypeSG(pController, xsType);
  }
 
  public Object newSimpleContentTypeSG(ComplexTypeSG pController) throws SAXException {
    return new JAXBSimpleContentTypeSG(pController, xsType);
  }
}
TOP

Related Classes of org.apache.ws.jaxme.generator.sg.impl.JAXBComplexTypeSG

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.