/** * Transfer given facet if it is one of length, maxLength or minLength. * * @param facet The facet to transfer. */ protected final void setLengthFacet(final Facet facet) { String name = facet.getName(); if (Facet.LENGTH.equals(name)) { setLength(facet.toInt()); } else if (Facet.MAX_LENGTH.equals(name)) { setMaxLength(facet.toInt()); } else if (Facet.MIN_LENGTH.equals(name)) { setMinLength(facet.toInt()); } }
/** * Attempts to translate a simpleType enumeration value into a legal java identifier. Translation * is through a couple of simple rules: * * <ul> * <li>if the value parses as a non-negative int, the string 'VALUE_' is prepended to it * <li>if the value parses as a negative int, the string 'VALUE_NEG_' is prepended to it * <li>the value is uppercased * <li>the characters <code>[](){}<>'`"</code> are removed * <li>the characters <code>|\/?~!@#$%^&*-+=:;.,</code> and any whitespace are replaced with * <code>_</code> * </ul> * * @param enumBinding if not null, a possible custom binding for this enum * @param facet the facet whose enum value is being translated. * @return the identifier for the enum value * @author [email protected] */ private String translateEnumValueToIdentifier( final EnumBindingType enumBinding, final Facet facet) { String enumValue = facet.getValue(); try { String enumerationValue = null; int intVal = Integer.parseInt(facet.getValue()); String customMemberName = null; if (enumBinding != null) { customMemberName = getCustomMemberName(enumBinding, String.valueOf(intVal)); } if (customMemberName != null) { enumerationValue = customMemberName; } else { if (intVal >= 0) { enumerationValue = "VALUE_" + intVal; } else { enumerationValue = "VALUE_NEG_" + Math.abs(intVal); } } return enumerationValue; } catch (NumberFormatException e) { // just keep going } StringBuilder sb = new StringBuilder(32); String customMemberName = null; if (enumBinding != null) { customMemberName = getCustomMemberName(enumBinding, enumValue); } if (customMemberName != null) { sb.append(customMemberName); } else { sb.append(enumValue.toUpperCase()); int i = 0; while (i < sb.length()) { char c = sb.charAt(i); if ("[](){}<>'`\"".indexOf(c) >= 0) { sb.deleteCharAt(i); i--; } else if (Character.isWhitespace(c) || "\\/?~!@#$%^&*-+=:;.,".indexOf(c) >= 0) { sb.setCharAt(i, '_'); } i++; } } return sb.toString(); }
/** * Reads and sets the facets for XSShort * @param simpletype the Simpletype containing the facets **/ public void setFacets(SimpleType simpleType) { //-- copy valid facets Enumeration enum = getFacets(simpleType); while (enum.hasMoreElements()) { Facet facet = (Facet)enum.nextElement(); String name = facet.getName(); //-- maxExclusive if (Facet.MAX_EXCLUSIVE.equals(name)) setMaxExclusive(facet.toShort()); //-- maxInclusive else if (Facet.MAX_INCLUSIVE.equals(name)) setMaxInclusive(facet.toShort()); //-- minExclusive else if (Facet.MIN_EXCLUSIVE.equals(name)) setMinExclusive(facet.toShort()); //-- minInclusive else if (Facet.MIN_INCLUSIVE.equals(name)) setMinInclusive(facet.toShort()); //-- pattern else if (Facet.PATTERN.equals(name)) setPattern(facet.getValue()); } } //-- toXSShort
/** * Reads and sets the facets for XSXSGDay override the readFacet method of XSType * * @param simpleType the Simpletype containing the facets * @see org.exolab.castor.builder.types.XSType#getFacets */ public void setFacets(SimpleType simpleType) { // -- copy valid facets Enumeration enumeration = getFacets(simpleType); while (enumeration.hasMoreElements()) { Facet facet = (Facet) enumeration.nextElement(); String name = facet.getName(); try { // -- maxExclusive if (Facet.MAX_EXCLUSIVE.equals(name)) this.setMaxExclusive(GDay.parseGDay(facet.getValue())); // -- maxInclusive else if (Facet.MAX_INCLUSIVE.equals(name)) this.setMaxInclusive(GDay.parseGDay(facet.getValue())); // -- minExclusive else if (Facet.MIN_EXCLUSIVE.equals(name)) this.setMinExclusive(GDay.parseGDay(facet.getValue())); // -- minInclusive else if (Facet.MIN_INCLUSIVE.equals(name)) this.setMinInclusive(GDay.parseGDay(facet.getValue())); // -- pattern else if (Facet.PATTERN.equals(name)) { LOG.warn("Warning: The facet 'pattern' is not currently supported for XSGDay."); } } catch (ParseException e) { // not possible to set the facet properly // This can't happen since a ParseException would have been set // during the unmarshalling of the facets e.printStackTrace(); return; } } // while } // setFacets
/** * 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
/** * 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
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); } }