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

Source Code of org.apache.ws.jaxme.generator.sg.impl.ccsg.GroupHandlerSG

/*
* Copyright 2005  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.ccsg;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.ws.jaxme.JMManager;
import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
import org.apache.ws.jaxme.generator.sg.Context;
import org.apache.ws.jaxme.generator.sg.GroupSG;
import org.apache.ws.jaxme.generator.sg.ObjectSG;
import org.apache.ws.jaxme.generator.sg.ParticleSG;
import org.apache.ws.jaxme.generator.sg.PropertySG;
import org.apache.ws.jaxme.generator.sg.PropertySGChain;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.generator.sg.impl.PropertySGChainImpl;
import org.apache.ws.jaxme.generator.sg.impl.PropertySGImpl;
import org.apache.ws.jaxme.impl.JMSAXElementParser;
import org.apache.ws.jaxme.impl.JMSAXGroupParser;
import org.apache.ws.jaxme.impl.JMUnmarshallerHandlerImpl;
import org.apache.ws.jaxme.js.DirectAccessible;
import org.apache.ws.jaxme.js.JavaField;
import org.apache.ws.jaxme.js.JavaInnerClass;
import org.apache.ws.jaxme.js.JavaMethod;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.LocalJavaField;
import org.apache.ws.jaxme.js.Parameter;
import org.apache.ws.jaxme.js.TypedValue;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.xml.sax.SAXException;


/** An instance of <code>GroupHandlerSG</code> is
* responsible for creating an instance of
* {@link org.apache.ws.jaxme.impl.JMSAXGroupParser},
* or {@link org.apache.ws.jaxme.impl.JMSAXElementParser}.<br>
* The {@link org.apache.ws.jaxme.generator.sg.ComplexContentSG}
* creates a <code>GroupHandlerSG</code> for any group,
* contained in the element.
*/
public abstract class GroupHandlerSG extends HandlerSGImpl {
  protected final ComplexContentSG ccSG;
  protected final GroupSG group;
  protected final ParticleSG[] particles;
  private final Map groups = new HashMap();
  private JavaField stateField;
  private final boolean isMixed;
  protected final GroupHandlerSG outerHandler;

  /** Creates a new instance, which generates a handler for
   * the complex type <code>pTypeSG</code> by adding methods
   * and fields to the Java class <code>pJs</code>.
   */
  protected GroupHandlerSG(ComplexTypeSG pType, JavaSource pJs) throws SAXException {
    super(pType, pJs);
    outerHandler = this;
    ccSG = pType.getComplexContentSG();
    group = ccSG.getRootParticle().getGroupSG();
    particles = group.getParticles();
    isMixed = ccSG.isMixed();
    findGroups(particles);
  }

  /** Creates a new instance, which generates a handler for
   * the group <code>pGroupSG</code> by adding methods and
   * fields to the Java class <code>pJs</code>.
   */
  protected GroupHandlerSG(GroupHandlerSG pOuterHandler, ComplexTypeSG pType,
               GroupSG pGroup, JavaSource pJs) throws SAXException {
    super(pType, pJs);
    outerHandler = pOuterHandler;
    if (!pJs.isInnerClass()) {
      throw new IllegalStateException("Expected inner class");
    }
    ccSG = null;
    group = pGroup;
    particles = pGroup.getParticles();
    isMixed = pType.getComplexContentSG().isMixed();
    findGroups(particles);
  }

  protected abstract JavaField newStateField() throws SAXException;

  protected JavaField getStateField() throws SAXException {
    if (stateField == null) {
      stateField = newStateField();
    }
    return stateField;
  }

  protected GroupHandlerSG getGroupHandlerSG(GroupSG pGroup) {
    return (GroupHandlerSG) groups.get(pGroup);
  }

  private GroupHandlerSG newGroupHandlerSG(GroupSG pGroup, String pName) throws SAXException {
    JavaSource js = getJavaSource();
    JavaInnerClass jic = js.newJavaInnerClass(pName, JavaSource.PUBLIC);
    jic.addExtends(JMSAXGroupParser.class);
    if (pGroup.isSequence()) {
      return new SequenceHandlerSG(outerHandler, ctSG, pGroup, jic);
    } else if (pGroup.isChoice()) {
      return new ChoiceHandlerSG(outerHandler, ctSG, pGroup, jic);
    } else if (pGroup.isAll()) {
      return new AllHandlerSG(outerHandler, ctSG, pGroup, jic);
    } else {
      throw new IllegalStateException("Invalid group type");
    }
  }

  private GroupHandlerSG newGroupHandlerSG(GroupSG pGroup) throws SAXException {
    JavaSource js = getJavaSource();
    String name = GroupUtil.getGroupName(pGroup);
    for (int i = 0;  ;  i++) {
      String n = name;
      if (i > 0) {
        name += i;
      }
      n += "Handler";
      if (js.getInnerClass(n) == null) {
        GroupHandlerSG result = newGroupHandlerSG(pGroup, n);
        result.newGetHandlerMethod(js);
        return result;
      }
    }
  }

  public JavaMethod newAddAttributeMethod() throws SAXException {
    if (ccSG == null) {
      return null;
    } else {
      return super.newAddAttributeMethod();
    }
  }

  private void findGroups(ParticleSG[] pParticles) throws SAXException {
    for (int i = 0;  i < pParticles.length;  i++) {
      ParticleSG particle = pParticles[i];
      if (particle.isGroup()) {
        GroupSG group = particle.getGroupSG();
        if (!groups.containsKey(group)) {
          GroupHandlerSG handler = newGroupHandlerSG(group);
          groups.put(group, handler);
        }
      } else if (particle.isElement()) {
        TypeSG tSG = particle.getObjectSG().getTypeSG();
        if (tSG.isComplex()  &&  !tSG.isGlobalClass()) {
          tSG.getComplexTypeSG().getXMLHandler(outerHandler.getJavaSource());
        }
      }
    }
  }

  protected boolean isRequiredParticle(ParticleSG particleSG) throws SAXException {
    if (particleSG.getMinOccurs() == 0) {
      return false;
    } else {
      if (particleSG.isGroup()) {
        GroupSG group = particleSG.getGroupSG();
        ParticleSG[] particles = group.getParticles();
        if (group.isChoice()) {
          for (int i = 0;  i < particles.length;  i++) {
            if (!isRequiredParticle(particles[i])) {
              return false;
            }
          }
          return true;
        } else {
          for (int i = 0;  i < particles.length;  i++) {
            if (isRequiredParticle(particles[i])) {
              return true;
            }
          }
          return false;
        }
      } else {
        return true;
      }
    }
  }

  protected void handleStartOfChildElement(Object pUnmarshallerHandler,
                       JavaMethod pJm, ParticleSG pParticle) {
    ObjectSG oSG = pParticle.getObjectSG();
    TypeSG tSG = oSG.getTypeSG();
    if (tSG.isComplex()) {
      JavaQName elementInterfaceClass = pParticle.getObjectSG().getClassContext().getXMLInterfaceName();
      Object[] o, h;
      if (oSG.getClassContext().isGlobal()) {
        LocalJavaField manager = pJm.newJavaField(JMManager.class);
        manager.addLine("getHandler().getJMUnmarshaller().getJAXBContextImpl().getManagerS(",
            elementInterfaceClass, ".class)");
        o = new Object[]{manager, ".getElementS();"};
        h = new Object[]{manager, ".getHandler();"};
      } else {
        Context context = oSG.getClassContext();
        o = new Object[]{" new ", context.getXMLImplementationName(), "()"};
        h = new Object[]{" new ", context.getXMLHandlerName(), "()"};
      }
      LocalJavaField oField = pJm.newJavaField(Object.class);
      oField.addLine(o);
      LocalJavaField hField = pJm.newJavaField(JMSAXElementParser.class);
      hField.addLine(h);
      XsQName name = oSG.getName();
      pJm.addLine(hField, ".init(", pUnmarshallerHandler, ", ", oField, ", ",
          JavaSource.getQuoted(name.getNamespaceURI()), ", ",
          JavaSource.getQuoted(name.getLocalName()),
      ", ", pUnmarshallerHandler, ".getLevel());");
      pJm.addLine(hField, ".setAttributes(", getParamAttrs(), ");");
      pJm.addLine(pUnmarshallerHandler, ".addElementParser(", hField, ");");
    } else {
      pJm.addLine(pUnmarshallerHandler, ".addSimpleAtomicState();");
    }
  }

  protected abstract void acceptParticle(JavaMethod pJm, int pNum) throws SAXException;

  protected void handleStartElementStates(Object pUnmarshallerHandler,
                      JavaMethod pJm, int pFrom,
                      int pTo) throws SAXException {
    if (pFrom < ||  pFrom >= particles.length  ||
        pTo < ||  pTo >= particles.length  ||  pTo < pFrom) {
      return;
    }
    for (int i = pFrom;  i <= pTo;  i++) {
      ParticleSG particle = particles[i];
      if (particle.isElement()) {
        ObjectSG oSG = particle.getObjectSG();
        XsQName name = oSG.getName();
        Object uriCondition;
        if ("".equals(name.getNamespaceURI())) {
          uriCondition = new Object[]{"(", getParamNamespaceURI(),
              " == null  ||  ",
              getParamNamespaceURI(),
          ".length() == 0)"};
        } else {
          uriCondition = new Object[]{JavaSource.getQuoted(name.getNamespaceURI()),
              ".equals(", getParamNamespaceURI(), ")"};
        }
        pJm.addIf(i == pFrom, uriCondition, "  &&  ",
              JavaSource.getQuoted(name.getLocalName()),
              ".equals(", getParamLocalName(), ")");
        acceptParticle(pJm, i);
        handleStartOfChildElement(pUnmarshallerHandler, pJm, particle);
        pJm.addLine("return true;");
      } else if (particle.isGroup()) {
        GroupSG gSG = particle.getGroupSG();
        GroupHandlerSG handlerSG = getGroupHandlerSG(gSG);
        pJm.addIf(i == pFrom,
              pUnmarshallerHandler, ".testGroupParser(new ",
              handlerSG.getJavaSource().getQName(), "(), ",
              getParamNamespaceURI(), ", ", getParamLocalName(),
              ", ", getParamQName(), ", ", getParamAttrs(), ")");
        acceptParticle(pJm, i);
        pJm.addLine("return true;");
      } else if (particle.isWildcard()) {
        throw new IllegalStateException("TODO: Add support for wildcards");
      } else {
        throw new IllegalStateException("Invalid particle type");
      }
    }
    pJm.addEndIf();
  }

  protected abstract int getState(int pParticleNum);
  protected abstract DirectAccessible getEndElementState() throws SAXException;

  public JavaMethod newEndElementMethod() throws SAXException {
    JavaMethod result = super.newEndElementMethod();
    JavaQName elementInterface = ctSG.getClassContext().getXMLInterfaceName();
    LocalJavaField element = result.newJavaField(elementInterface);
    element.addLine("(", elementInterface, ") result");
    result.addSwitch(getEndElementState());
    for (int i = 0;  i < particles.length;  i++) {
      result.addCase(new Integer(getState(i)));
      ParticleSG particle = particles[i];
      handleEndElementState(result, element, particle);
    }
    result.addDefault();
    result.addThrowNew(IllegalStateException.class,
               JavaSource.getQuoted("Illegal state: "), " + ",
               getEndElementState());
    result.addEndSwitch();
    return result;
  }

  private void handleEndElementState(JavaMethod pJm, LocalJavaField pElement,
                     ParticleSG pParticle) throws SAXException {
    if (pParticle.isElement()) {
      ObjectSG oSG = pParticle.getObjectSG();
      TypeSG childType = oSG.getTypeSG();
      XsQName name = oSG.getName();
      Object[] uriCondition;
      if ("".equals(name.getNamespaceURI())) {
        uriCondition = new Object[]{
          getParamNamespaceURI(), " == null  ||  ",
          getParamNamespaceURI(), ".length() == 0"
        };
      } else {
        uriCondition = new Object[]{
          JavaSource.getQuoted(name.getNamespaceURI()), ".equals(",
          getParamNamespaceURI(), ")"
        };
      }
      pJm.addIf(uriCondition, "  &&  ", JavaSource.getQuoted(name.getLocalName()),
          ".equals(", getParamLocalName(), ")");
      JavaQName type;
      TypedValue v = getParamResult();
      if (childType.isComplex()) {
        type = childType.getComplexTypeSG().getClassContext().getXMLInterfaceName();
        if (isMixed) {
          pJm.addLine(pElement, ".getContent().add(", v, ");");
        } else {
          pParticle.getPropertySG().addValue(pJm, pElement, v, type);
        }
      } else {
        PropertySG pSG;
        DirectAccessible element;
        if (isMixed) {
          LocalJavaField f = pJm.newJavaField(GroupUtil.getContentClass(group, pParticle, ctSG.getClassContext().getXMLInterfaceName()));
          f.addLine("new ", GroupUtil.getContentClass(group, pParticle, ctSG.getClassContext().getXMLImplementationName()), "()");
          PropertySGChain chain = ((PropertySGImpl) pParticle.getPropertySG()).getHeadOfChain();
          PropertySGChain head = new PropertySGChainImpl(chain){
            public String getXMLFieldName(PropertySG pController) throws SAXException {
              return "_value";
            }
            public String getPropertyName(PropertySG pController) throws SAXException {
              return "value";
            }
          };
          pSG = new PropertySGImpl(head);
          element = f;
        } else {
          pSG = pParticle.getPropertySG();
          element = pElement;
        }
        createSimpleTypeConversion(pJm, childType, v,
                       oSG.getName().toString(),
                       pSG, element);
        if (isMixed) {
          pJm.addLine(pElement, ".getContent().add(", element, ");");
        }
      }
      pJm.addLine("return;");
      pJm.addEndIf();
      pJm.addBreak();
    } else if (pParticle.isGroup()) {
      pJm.addThrowNew(IllegalStateException.class,
              JavaSource.getQuoted("This case should be handled by a nested group parser."));
    } else if (pParticle.isWildcard()) {
      throw new IllegalStateException("TODO: Add support for wildcards.");
    } else {
      throw new IllegalStateException("Invalid particle type");
    }
  }

  public JavaMethod newIsAtomicMethod() throws SAXException {
    return null;
  }

  public JavaMethod newIsEmptyMethod() throws SAXException {
    return null;
  }

  protected JavaMethod newIsMixedMethod() throws SAXException {
    if (!isMixed) {
      return null;
    }
    JavaMethod jm = getJavaSource().newJavaMethod("isMixed", boolean.class, JavaSource.PUBLIC);
    jm.addLine("return true;");
    return jm;
  }

  protected JavaMethod newAddTextMethod() throws SAXException {
    if (!isMixed) {
      return null;
    }
    JavaMethod jm = getJavaSource().newJavaMethod("addText", void.class, JavaSource.PUBLIC);
    Parameter buffer = jm.addParam(char[].class, "pBuffer");
    Parameter offset = jm.addParam(int.class, "pOffset");
    Parameter length = jm.addParam(int.class, "pLength");
    if (ccSG == null) {
      jm.addLine(outerHandler.getJavaSource().getQName(), ".this.addText(",
             buffer, ", ", offset, ", ", length, ");");
    } else {
      JavaQName elementInterface = ctSG.getClassContext().getXMLInterfaceName();
      LocalJavaField element = jm.newJavaField(elementInterface);
      element.addLine("(", elementInterface, ") result");
      Object s = new Object[]{"new ", String.class, "(", buffer, ", ",
                  offset, ", ", length, ")"};
      LocalJavaField list = jm.newJavaField(List.class);
      list.addLine(element, ".getContent()");
      jm.addIf(list, ".size() > 0");
      LocalJavaField o = jm.newJavaField(Object.class);
      o.addLine(list, ".get(", list, ".size()-1)");
      jm.addIf(o, " instanceof ", String.class);
      jm.addLine(list, ".set(", list, ".size()-1, ",
             "((", String.class, ") ", o, ") + ", s, ");");
      jm.addLine("return;");
      jm.addEndIf();
      jm.addEndIf();
      jm.addLine(list, ".add(", s, ");");
    }
    return jm;
  }

  private JavaMethod newGetHandlerMethod(JavaSource pOuter) throws SAXException {
    JavaMethod result = getJavaSource().newJavaMethod("getHandler", JMUnmarshallerHandlerImpl.class, JavaSource.PUBLIC);
    result.addLine("return ", pOuter.getQName(), ".this.getHandler();");
    return result;
  }

  public void generate() throws SAXException {
    super.generate();
    newAddTextMethod();
    newIsMixedMethod();
    for (Iterator iter = groups.values().iterator();  iter.hasNext()) {
      HandlerSG handler = (HandlerSG) iter.next();
      handler.generate();
    }
  }
}
TOP

Related Classes of org.apache.ws.jaxme.generator.sg.impl.ccsg.GroupHandlerSG

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.