예제 #1
0
  /** Adds the methods we override from. {@link org.exolab.castor.xml.XMLClassDescriptor} */
  private void addXMLClassDescriptorOverrides() {
    JMethod method;
    JSourceCode jsc;
    // -- create getNameSpacePrefix method
    method =
        new JMethod(
            "getNameSpacePrefix",
            SGTypes.String,
            "the namespace prefix to use when marshaling as XML.");

    if (_config.useJava50()) {
      method.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = method.getSourceCode();
    jsc.add("return nsPrefix;");
    addMethod(method);

    // -- create getNameSpaceURI method
    method =
        new JMethod(
            "getNameSpaceURI",
            SGTypes.String,
            "the namespace URI used when marshaling and unmarshaling as XML.");

    if (_config.useJava50()) {
      method.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = method.getSourceCode();
    jsc.add("return nsURI;");
    addMethod(method);

    // -- create getValidator method
    method =
        new JMethod(
            "getValidator",
            TYPE_VALIDATOR_CLASS,
            "a specific validator for the class described" + " by this ClassDescriptor.");

    if (_config.useJava50()) {
      method.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = method.getSourceCode();
    jsc.add("return this;");
    addMethod(method);

    // -- create getXMLName method
    method =
        new JMethod("getXMLName", SGTypes.String, "the XML Name for the Class being described.");

    if (_config.useJava50()) {
      method.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = method.getSourceCode();
    jsc.add("return xmlName;");
    addMethod(method);
  }
예제 #2
0
  /**
   * Adds the methods we override from. {@link org.exolab.castor.mapping.ClassDescriptor}
   *
   * @param extended true if we extend another class and thus need to call super()
   */
  private void addClassDescriptorOverrides(final boolean extended) {
    JSourceCode jsc;

    // -- create getAccessMode method
    JClass amClass = new JClass(MAPPING_ACCESS_MODE);
    JMethod getAccessMode =
        new JMethod("getAccessMode", amClass, "the access mode specified for this class.");

    if (_config.useJava50()) {
      getAccessMode.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = getAccessMode.getSourceCode();
    jsc.add("return null;");
    addMethod(getAccessMode);

    // -- create getIdentity method
    JMethod getIdentity =
        new JMethod(
            "getIdentity",
            FIELD_DESCRIPTOR_CLASS,
            "the identity field, null if this class has no identity.");

    if (_config.useJava50()) {
      getIdentity.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = getIdentity.getSourceCode();
    if (extended) {
      jsc.add("if (identity == null) {");
      jsc.indent();
      jsc.add("return super.getIdentity();");
      jsc.unindent();
      jsc.add("}");
    }
    jsc.add("return identity;");

    // --don't add the type to the import list
    addMethod(getIdentity, false);

    // -- create getJavaClass method
    JMethod getJavaClass =
        new JMethod(
            "getJavaClass", SGTypes.Class, "the Java class represented by this descriptor.");

    if (_config.useJava50()) {
      getJavaClass.addAnnotation(new JAnnotation(new JAnnotationType("Override")));
    }

    jsc = getJavaClass.getSourceCode();
    jsc.add("return ");
    jsc.append(classType(_type));
    jsc.append(";");

    // --don't add the type to the import list
    addMethod(getJavaClass, false);
  }
예제 #3
0
  /**
   * Returns the JSourceCode instance for the current init() method, dealing with static initializer
   * limits of the JVM by creating new init() methods as needed.
   *
   * @param jClass The JClass instance for which an init method needs to be added
   * @return the JSourceCode instance for the current init() method
   */
  private JSourceCode getSourceCodeForInitMethod(final JClass jClass) {
    final JMethod currentInitMethod = jClass.getMethod(getInitMethodName(_maxSuffix), 0);
    if (currentInitMethod.getSourceCode().size() > _maxEnumerationsPerClass) {
      ++_maxSuffix;
      JMethod mInit = createInitMethod(jClass);
      currentInitMethod.getSourceCode().add("members.putAll(" + mInit.getName() + "());");
      currentInitMethod.getSourceCode().add("return members;");

      return mInit.getSourceCode();
    }
    return currentInitMethod.getSourceCode();
  }
예제 #4
0
 /**
  * Creates 'getType()' method for this enumeration class.
  *
  * @param jClass The enumeration class to create this method for.
  * @param className The name of the class.
  */
 private void createGetTypeMethod(final JClass jClass, final String className) {
   JMethod mGetType = new JMethod("getType", JType.INT, "the type of this " + className);
   mGetType.getSourceCode().add("return this.type;");
   JDocComment jdc = mGetType.getJDocComment();
   jdc.appendComment("Returns the type of this " + className);
   jClass.addMethod(mGetType);
 }
예제 #5
0
 /**
  * Creates 'toString()' method for this enumeration class.
  *
  * @param jClass The enumeration class to create this method for.
  * @param className The name of the class.
  */
 private void createToStringMethod(final JClass jClass, final String className) {
   JMethod mToString =
       new JMethod("toString", SGTypes.STRING, "the String representation of this " + className);
   jClass.addMethod(mToString);
   JDocComment jdc = mToString.getJDocComment();
   jdc.appendComment("Returns the String representation of this ");
   jdc.appendComment(className);
   mToString.getSourceCode().add("return this.stringValue;");
 }
예제 #6
0
 /**
  * Adds the methods we override from. {@link org.exolab.castor.xml.util.XMLClassDescriptorImpl}
  */
 private void addXMLClassDescriptorImplOverrides() {
   // -- create isElementDefinition method
   JMethod getElementDefinition =
       new JMethod(
           "isElementDefinition",
           JType.BOOLEAN,
           "true if XML schema definition of this Class is that of a global\n"
               + "element or element with anonymous type definition.");
   JSourceCode jsc = getElementDefinition.getSourceCode();
   jsc.add("return elementDefinition;");
   addMethod(getElementDefinition);
 }
예제 #7
0
 /**
  * Creates 'init()' method for this enumeration class.
  *
  * @param jClass The enumeration class to create this method for.
  * @return an 'init()' method for this enumeration class.
  */
 private JMethod createInitMethod(final JClass jClass) {
   final String initMethodName = getInitMethodName(_maxSuffix);
   JMethod mInit =
       new JMethod(
           initMethodName,
           SGTypes.createHashtable(getConfig().useJava50()),
           "the initialized Hashtable for the member table");
   jClass.addMethod(mInit);
   mInit.getModifiers().makePrivate();
   mInit.getModifiers().setStatic(true);
   if (getConfig().useJava50()) {
     mInit
         .getSourceCode()
         .add(
             "java.util.Hashtable<Object, Object> members"
                 + " = new java.util.Hashtable<Object, Object>();");
   } else {
     mInit.getSourceCode().add("java.util.Hashtable members = new java.util.Hashtable();");
   }
   return mInit;
 }
예제 #8
0
 /**
  * Creates 'readResolve(Object)' method for this enumeration class.
  *
  * @param jClass The enumeration class to create this method for.
  */
 private void createReadResolveMethod(final JClass jClass) {
   JDocComment jdc;
   JSourceCode jsc;
   JMethod mReadResolve = new JMethod("readResolve", SGTypes.OBJECT, "this deserialized object");
   mReadResolve.getModifiers().makePrivate();
   jClass.addMethod(mReadResolve);
   jdc = mReadResolve.getJDocComment();
   jdc.appendComment(" will be called during deserialization to replace ");
   jdc.appendComment("the deserialized object with the correct constant ");
   jdc.appendComment("instance.");
   jsc = mReadResolve.getSourceCode();
   jsc.add("return valueOf(this.stringValue);");
 }
예제 #9
0
 /**
  * Creates 'enumerate()' method for this enumeration class.
  *
  * @param jClass The enumeration class to create this method for.
  * @param className The name of the class.
  */
 private void createEnumerateMethod(final JClass jClass, final String className) {
   // TODO for the time being return Enumeration<Object> for Java 5.0; change
   JMethod mEnumerate =
       new JMethod(
           "enumerate",
           SGTypes.createEnumeration(SGTypes.OBJECT, getConfig().useJava50(), true),
           "an Enumeration over all possible instances of " + className);
   mEnumerate.getModifiers().setStatic(true);
   jClass.addMethod(mEnumerate);
   JDocComment jdc = mEnumerate.getJDocComment();
   jdc.appendComment("Returns an enumeration of all possible instances of ");
   jdc.appendComment(className);
   mEnumerate.getSourceCode().add("return _memberTable.elements();");
 }
예제 #10
0
  /**
   * Creates 'valueOf(String)' method for this enumeration class.
   *
   * @param jClass The enumeration class to create this method for.
   * @param className The name of the class.
   */
  private void createValueOfMethod(final JClass jClass, final String className) {
    JMethod mValueOf =
        new JMethod("valueOf", jClass, "the " + className + " value of parameter 'string'");
    mValueOf.addParameter(new JParameter(SGTypes.STRING, "string"));
    mValueOf.getModifiers().setStatic(true);
    jClass.addMethod(mValueOf);

    JDocComment jdc = mValueOf.getJDocComment();
    jdc.appendComment("Returns a new " + className);
    jdc.appendComment(" based on the given String value.");

    JSourceCode jsc = mValueOf.getSourceCode();
    jsc.add(
        "java.lang.Object obj = null;\n"
            + "if (string != null) {\n"
            + " obj = _memberTable.get(string{1});\n"
            + "}\n"
            + "if (obj == null) {\n"
            + " String err = \"'\" + string + \"' is not a valid {0}\";\n"
            + " throw new IllegalArgumentException(err);\n"
            + "}\n"
            + "return ({0}) obj;",
        className, (_caseInsensitive ? ".toLowerCase()" : ""));
  }
예제 #11
0
  /**
   * Creates all the necessary enumeration code for a given SimpleType.
   *
   * @param binding Extended binding instance
   * @param simpleType the SimpleType we are processing an enumeration for
   * @param state our current state
   * @see #processEnumerationAsBaseType
   */
  void processEnumerationAsNewObject(
      final ExtendedBinding binding, final SimpleType simpleType, final FactoryState state) {
    // reset _maxSuffix value to 0
    _maxSuffix = 0;
    boolean generateConstantDefinitions = true;
    int numberOfEnumerationFacets = simpleType.getNumberOfFacets(Facet.ENUMERATION);
    if (numberOfEnumerationFacets > _maxEnumerationsPerClass) {
      generateConstantDefinitions = false;
    }

    Enumeration enumeration = simpleType.getFacets(Facet.ENUMERATION);

    XMLBindingComponent component = new XMLBindingComponent(getConfig(), getGroupNaming());
    if (binding != null) {
      component.setBinding(binding);
      component.setView(simpleType);
    }

    // -- select naming for types and instances
    boolean useValuesAsName = true;
    useValuesAsName = selectNamingScheme(component, enumeration, useValuesAsName);

    enumeration = simpleType.getFacets(Facet.ENUMERATION);

    JClass jClass = state.getJClass();
    String className = jClass.getLocalName();

    if (component.getJavaClassName() != null) {
      className = component.getJavaClassName();
    }

    // the java 5 way -> create an enum
    if (state.getJClass() instanceof JEnum) {
      createJava5Enum(simpleType, state, component, useValuesAsName, enumeration);
      return;
    }

    JField field = null;
    JField fHash = new JField(SGTypes.createHashtable(getConfig().useJava50()), "_memberTable");
    fHash.setInitString("init()");
    fHash.getModifiers().setStatic(true);

    JSourceCode jsc = null;

    // -- modify constructor
    JConstructor constructor = jClass.getConstructor(0);
    constructor.getModifiers().makePrivate();
    constructor.addParameter(new JParameter(JType.INT, "type"));
    constructor.addParameter(new JParameter(SGTypes.STRING, "value"));
    jsc = constructor.getSourceCode();
    jsc.add("this.type = type;");
    jsc.add("this.stringValue = value;");

    createValueOfMethod(jClass, className);
    createEnumerateMethod(jClass, className);
    createToStringMethod(jClass, className);
    createInitMethod(jClass);
    createReadResolveMethod(jClass);

    // -- Loop through "enumeration" facets
    int count = 0;

    while (enumeration.hasMoreElements()) {
      Facet facet = (Facet) enumeration.nextElement();

      String value = facet.getValue();

      String typeName = null;
      String objName = null;

      if (useValuesAsName) {
        objName = translateEnumValueToIdentifier(component.getEnumBinding(), facet);
      } else {
        objName = "VALUE_" + count;
      }

      // -- create typeName
      // -- Note: this could cause name conflicts
      typeName = objName + "_TYPE";

      // -- Inheritence/Duplicate name cleanup
      boolean addInitializerCode = true;
      if (jClass.getField(objName) != null) {
        // -- either inheritence, duplicate name, or error.
        // -- if inheritence or duplicate name, always take
        // -- the later definition. Do same if error, for now.
        jClass.removeField(objName);
        jClass.removeField(typeName);
        addInitializerCode = false;
      }

      if (generateConstantDefinitions) {
        // -- handle int type
        field = new JField(JType.INT, typeName);
        field.setComment("The " + value + " type");
        JModifiers modifiers = field.getModifiers();
        modifiers.setFinal(true);
        modifiers.setStatic(true);
        modifiers.makePublic();
        field.setInitString(Integer.toString(count));
        jClass.addField(field);

        // -- handle Class type
        field = new JField(jClass, objName);
        field.setComment("The instance of the " + value + " type");

        modifiers = field.getModifiers();
        modifiers.setFinal(true);
        modifiers.setStatic(true);
        modifiers.makePublic();

        StringBuilder init = new StringBuilder(32);
        init.append("new ");
        init.append(className);
        init.append("(");
        init.append(typeName);
        init.append(", \"");
        init.append(escapeValue(value));
        init.append("\")");

        field.setInitString(init.toString());
        jClass.addField(field);
      }
      // -- initializer method

      if (addInitializerCode) {
        jsc = getSourceCodeForInitMethod(jClass);
        jsc.add("members.put(\"");
        jsc.append(escapeValue(value));
        if (_caseInsensitive) {
          jsc.append("\".toLowerCase(), ");
        } else {
          jsc.append("\", ");
        }
        if (generateConstantDefinitions) {
          jsc.append(objName);
        } else {
          StringBuilder init = new StringBuilder(32);
          init.append("new ");
          init.append(className);
          init.append("(");
          init.append(Integer.toString(count));
          init.append(", \"");
          init.append(escapeValue(value));
          init.append("\")");
          jsc.append(init.toString());
        }
        jsc.append(");");
      }

      ++count;
    }

    // -- finish init method
    final JMethod method = jClass.getMethod(this.getInitMethodName(_maxSuffix), 0);
    method.getSourceCode().add("return members;");

    // -- add memberTable to the class, we can only add this after all the types,
    // -- or we'll create source code that will generate null pointer exceptions,
    // -- because calling init() will try to add null values to the hashtable.
    jClass.addField(fHash);

    // -- add internal type
    field = new JField(JType.INT, "type");
    field.getModifiers().setFinal(true);
    jClass.addField(field);

    // -- add internal stringValue
    field = new JField(SGTypes.STRING, "stringValue");
    field.setInitString("null");
    jClass.addField(field);

    createGetTypeMethod(jClass, className);
  } // -- processEnumerationAsNewObject
예제 #12
0
  /**
   * Creates all the necessary enumeration code from the given SimpleType. Enumerations are handled
   * by creating an Object like the following:
   *
   * <pre>
   *     public class {name} {
   *         // list of values
   *         {type}[] values = {
   *             ...
   *         };
   *
   *         // Returns true if the given value is part
   *         // of this enumeration
   *         public boolean contains({type} value);
   *
   *         // Returns the {type} value whose String value
   *         // is equal to the given String
   *         public {type} valueOf(String strValue);
   *     }
   * </pre>
   *
   * @param binding Extended binding instance
   * @param simpleType the SimpleType we are processing an enumeration for
   * @param state our current state
   */
  void processEnumerationAsBaseType(
      final ExtendedBinding binding, final SimpleType simpleType, final FactoryState state) {
    SimpleType base = (SimpleType) simpleType.getBaseType();
    XSType baseType = null;

    if (base == null) {
      baseType = new XSString();
    } else {
      baseType = _typeConversion.convertType(base, getConfig().useJava50());
    }

    Enumeration enumeration = simpleType.getFacets(Facet.ENUMERATION);

    JClass jClass = state.getJClass();
    String className = jClass.getLocalName();

    JField fValues = null;
    JDocComment jdc = null;
    JSourceCode jsc = null;

    // -- modify constructor
    JConstructor constructor = jClass.getConstructor(0);
    constructor.getModifiers().makePrivate();

    fValues = new JField(new JArrayType(baseType.getJType(), getConfig().useJava50()), "values");

    // -- Loop through "enumeration" facets
    // -- and create the default values for the type.
    int count = 0;

    StringBuilder values = new StringBuilder("{\n");

    while (enumeration.hasMoreElements()) {
      Facet facet = (Facet) enumeration.nextElement();
      String value = facet.getValue();

      // -- Should we make sure the value is valid before proceeding??

      // -- we need to move this code to XSType so that we don't have to do
      // -- special code here for each type

      if (count > 0) {
        values.append(",\n");
      }

      // -- indent for fun
      values.append("    ");

      if (baseType.getType() == XSType.STRING_TYPE) {
        values.append('\"');
        // -- escape value
        values.append(escapeValue(value));
        values.append('\"');
      } else {
        values.append(value);
      }

      ++count;
    }

    values.append("\n}");

    fValues.setInitString(values.toString());
    jClass.addField(fValues);

    // -- #valueOf method
    JMethod method =
        new JMethod("valueOf", jClass, "the String value of the provided " + baseType.getJType());
    method.addParameter(new JParameter(SGTypes.STRING, "string"));
    method.getModifiers().setStatic(true);
    jClass.addMethod(method);
    jdc = method.getJDocComment();
    jdc.appendComment("Returns the " + baseType.getJType());
    jdc.appendComment(" based on the given String value.");
    jsc = method.getSourceCode();

    jsc.add("for (int i = 0; i < values.length; i++) {");
    jsc.add("}");
    jsc.add("throw new IllegalArgumentException(\"");
    jsc.append("Invalid value for ");
    jsc.append(className);
    jsc.append(": \" + string + \".\");");
  } // -- processEnumerationAsBaseType