Ejemplo n.º 1
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
Ejemplo n.º 2
0
  private void createJava5Enum(
      final SimpleType simpleType,
      final FactoryState state,
      final XMLBindingComponent component,
      final boolean useValuesAsName,
      final Enumeration enumeration) {

    AnnotationBuilder[] annotationBuilders =
        state.getSGStateInfo().getSourceGenerator().getAnnotationBuilders();

    JEnum jEnum = (JEnum) state.getJClass();

    // add value field
    JField jField = new JField(new JClass("java.lang.String"), "value");
    JModifiers modifiers = new JModifiers();
    modifiers.setFinal(true);
    modifiers.makePrivate();
    jField.setModifiers(modifiers);
    jEnum.addField(jField);

    JMethod valueMethod =
        new JMethod("value", new JClass("java.lang.String"), "the value of this constant");
    valueMethod.setSourceCode("return this.value;");
    jEnum.addMethod(valueMethod, false);

    JMethod fromValueMethod = new JMethod("fromValue", jEnum, "the constant for this value");
    fromValueMethod.addParameter(new JParameter(new JClass("java.lang.String"), "value"));
    JSourceCode sourceCode = new JSourceCode();
    sourceCode.add("for (" + jEnum.getLocalName() + " c: " + jEnum.getLocalName() + ".values()) {");
    sourceCode.indent();
    sourceCode.add("if (c.value.equals(value)) {");
    sourceCode.indent();
    sourceCode.add("return c;");
    sourceCode.unindent();
    sourceCode.add("}");
    sourceCode.unindent();
    sourceCode.add("}");
    sourceCode.add("throw new IllegalArgumentException(value);");
    fromValueMethod.setSourceCode(sourceCode);
    modifiers = new JModifiers();
    modifiers.setStatic(true);
    fromValueMethod.setModifiers(modifiers);
    jEnum.addMethod(fromValueMethod, false);

    JMethod setValueMethod = new JMethod("setValue");
    setValueMethod.addParameter(new JParameter(new JClass("java.lang.String"), "value"));
    jEnum.addMethod(setValueMethod, false);

    JMethod toStringMethod =
        new JMethod("toString", new JClass("java.lang.String"), "the value of this constant");
    toStringMethod.setSourceCode("return this.value;");
    jEnum.addMethod(toStringMethod, false);

    JConstructor constructor = jEnum.createConstructor();
    constructor.addParameter(new JParameter(new JClass("java.lang.String"), "value"));
    constructor.setSourceCode("this.value = value;");
    modifiers = new JModifiers();
    modifiers.makePrivate();
    constructor.setModifiers(modifiers);
    jEnum.addConstructor(constructor);

    int enumCount = 0;
    while (enumeration.hasMoreElements()) {
      Facet facet = (Facet) enumeration.nextElement();
      JEnumConstant enumConstant;
      if (useValuesAsName) {
        enumConstant =
            new JEnumConstant(
                translateEnumValueToIdentifier(component.getEnumBinding(), facet),
                new String[] {"\"" + facet.getValue() + "\""});
      } else {
        enumConstant =
            new JEnumConstant("VALUE_" + enumCount, new String[] {"\"" + facet.getValue() + "\""});
      }

      // custom annotations
      for (int i = 0; i < annotationBuilders.length; i++) {
        AnnotationBuilder annotationBuilder = annotationBuilders[i];
        annotationBuilder.addEnumConstantAnnotations(facet, enumConstant);
      }

      jEnum.addConstant(enumConstant);
      enumCount++;
    }

    // custom annotations
    for (int i = 0; i < annotationBuilders.length; i++) {
      AnnotationBuilder annotationBuilder = annotationBuilders[i];
      annotationBuilder.addEnumAnnotations(simpleType, jEnum);
    }
  }