Пример #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