You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlbeans.apache.org by ra...@apache.org on 2009/04/27 21:31:14 UTC

svn commit: r769119 - in /xmlbeans/trunk: ./ src/configschema/schema/ src/typeimpl/org/apache/xmlbeans/impl/schema/ src/typeimpl/org/apache/xmlbeans/impl/values/ src/xmlconfig/org/apache/xmlbeans/impl/config/ src/xmlpublic/org/apache/xmlbeans/ test/cas...

Author: radup
Date: Mon Apr 27 19:31:13 2009
New Revision: 769119

URL: http://svn.apache.org/viewvc?rev=769119&view=rev
Log:
Added "User Types" feature - allows mapping of Schema simple types to custom user Java classes (http://wiki.apache.org/xmlbeans/UserTypes).
Contributed by Wesley Leggette.

Added:
    xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java
    xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/UserType.java
    xmlbeans/trunk/test/cases/xbean/usertype/
    xmlbeans/trunk/test/cases/xbean/usertype/averageCase/
    xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsd
    xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsdconfig
    xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/
    xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsd
    xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsdconfig
    xmlbeans/trunk/test/src/xmlobject/usertype/
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKU.java
    xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/Room.java
    xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java
Modified:
    xmlbeans/trunk/src/configschema/schema/xmlconfig.xsd
    xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
    xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
    xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java
    xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java
    xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java
    xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java
    xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java
    xmlbeans/trunk/testbuild.xml

Modified: xmlbeans/trunk/src/configschema/schema/xmlconfig.xsd
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/configschema/schema/xmlconfig.xsd?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/configschema/schema/xmlconfig.xsd (original)
+++ xmlbeans/trunk/src/configschema/schema/xmlconfig.xsd Mon Apr 27 19:31:13 2009
@@ -58,6 +58,15 @@
           </xs:annotation>
         </xs:element>
 
+        <xs:element name="usertype" type="xb:usertypeconfig">
+          <xs:annotation>
+              <xs:documentation>
+                  Specifies a custom java type mapping for a derived simple type.
+                  A static handler must be specified that converts between the
+                  custom java type and the built-in simple type it derives from.
+              </xs:documentation>
+          </xs:annotation>
+        </xs:element>
       </xs:choice>
     </xs:complexType>
   </xs:element>
@@ -172,6 +181,30 @@
     </xs:union>
    </xs:simpleType>
 
+    <xs:complexType name="usertypeconfig">
+       <xs:sequence>
+           <xs:choice>
+               <xs:element name="staticHandler" type="xs:string">
+                   <xs:annotation>
+                       <xs:documentation>
+                           The name of the handler class for this user type.
+                           The handler must contain public static methods for
+                           translating the user type to and from the derived simple type.
+                           Example:
+                           - qname example:uuid restricts xs:string
+                           - javaname is java.util.UUID
+                           - handler interface must have signatures:
+                                public void encodeUuid(UUID obj, SimpleValue target)
+                                public UUID decodeUuid(SimpleValue obj)
+                       </xs:documentation>
+                   </xs:annotation>
+               </xs:element>
+           </xs:choice>
+       </xs:sequence>
+       <xs:attribute name="name" type="xs:QName"/>
+       <xs:attribute name="javaname" type="xs:string"/>
+    </xs:complexType>
+
     <xs:complexType name="extensionconfig">
        <xs:sequence>
           <xs:element name="interface" minOccurs="0" maxOccurs="unbounded" >

Modified: xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java (original)
+++ xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java Mon Apr 27 19:31:13 2009
@@ -323,6 +323,20 @@
         }
         return ret;
     }
+    
+    private String getUserTypeStaticHandlerMethod(boolean encode, SchemaTypeImpl stype)
+    {
+        String unqualifiedName = stype.getName().getLocalPart();
+        if (unqualifiedName.length() < 2)
+            unqualifiedName = unqualifiedName.toUpperCase();
+        else
+            unqualifiedName = unqualifiedName.substring(0, 1).toUpperCase() + unqualifiedName.substring(1);
+        
+        if (encode)
+            return stype.getUserTypeHandlerName() + ".encode" + unqualifiedName;
+        else
+            return stype.getUserTypeHandlerName() + ".decode" + unqualifiedName;
+    }
 
 
     public static String indexClassForSystem(SchemaTypeSystem system)
@@ -1017,6 +1031,11 @@
             SchemaType sType = sProp.javaBasedOnType();
             return findJavaType(sType).replace('$', '.');
         }
+        
+        if (sProp.getJavaTypeCode() == SchemaProperty.JAVA_USER)
+        {
+               return ((SchemaTypeImpl)sProp.getType()).getUserTypeName();
+        }
 
         switch (sProp.getJavaTypeCode())
         {
@@ -1446,7 +1465,7 @@
         }
     }
 
-    void printJGetArrayValue(int javaType, String type) throws IOException {
+    void printJGetArrayValue(int javaType, String type, SchemaTypeImpl stype) throws IOException {
         switch (javaType)
         {
             case SchemaProperty.XML_OBJECT:
@@ -1568,10 +1587,19 @@
                 emit("    result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getObjectValue();");
                 break;
 
+            case SchemaProperty.JAVA_USER:
+                emit(stype.getUserTypeName() + "[] result = new " + stype.getUserTypeName() + "[targetList.size()];");
+                emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
+                emit("    result[i] = " + getUserTypeStaticHandlerMethod(false, stype)
+                        + "((org.apache.xmlbeans.SimpleValue)targetList.get(i));");
+                break;
+                
+            default:
+                throw new IllegalStateException();
         }
         emit("return result;");
     }
-    void printJGetValue(int javaType, String type) throws IOException {
+    void printJGetValue(int javaType, String type, SchemaTypeImpl stype) throws IOException {
         switch (javaType)
         {
         case SchemaProperty.XML_OBJECT:
@@ -1633,72 +1661,83 @@
 
         case SchemaProperty.JAVA_OBJECT:
             emit("return target.getObjectValue();"); break;
+            
+        case SchemaProperty.JAVA_USER:
+            emit("return " + getUserTypeStaticHandlerMethod(false, stype)
+                    + "(target);");
+            break;
+            
+        default:
+            throw new IllegalStateException();
         }
     }
-
-    String jsetMethod(int javaType) throws IOException
-    {
+    void printJSetValue(int javaType, String safeVarName, SchemaTypeImpl stype) throws IOException {
         switch (javaType)
         {
             case SchemaProperty.XML_OBJECT:
-                return "target.set";
+                emit("target.set(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_BOOLEAN:
-                return "target.setBooleanValue";
+                emit("target.setBooleanValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_FLOAT:
-                return "target.setFloatValue";
+                emit("target.setFloatValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_DOUBLE:
-                return "target.setDoubleValue";
+                emit("target.setDoubleValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_BYTE:
-                return "target.setByteValue";
+                emit("target.setByteValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_SHORT:
-                return "target.setShortValue";
+                emit("target.setShortValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_INT:
-                return "target.setIntValue";
+                emit("target.setIntValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_LONG:
-                return "target.setLongValue";
+                emit("target.setLongValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_BIG_DECIMAL:
-                return "target.setBigDecimalValue";
+                emit("target.setBigDecimalValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_BIG_INTEGER:
-                return "target.setBigIntegerValue";
+                emit("target.setBigIntegerValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_STRING:
-                return "target.setStringValue";
+                emit("target.setStringValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_BYTE_ARRAY:
-                return "target.setByteArrayValue";
+                emit("target.setByteArrayValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_GDATE:
-                return "target.setGDateValue";
+                emit("target.setGDateValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_GDURATION:
-                return "target.setGDurationValue";
+                emit("target.setGDurationValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_CALENDAR:
-                return "target.setCalendarValue";
+                emit("target.setCalendarValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_DATE:
-                return "target.setDateValue";
+                emit("target.setDateValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_QNAME:
-                return "target.setQNameValue";
+                emit("target.setQNameValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_LIST:
-                return "target.setListValue";
+                emit("target.setListValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_ENUM:
-                return "target.setEnumValue";
+                emit("target.setEnumValue(" + safeVarName + ");"); break;
 
             case SchemaProperty.JAVA_OBJECT:
-                return "target.setObjectValue";
+                emit("target.setObjectValue(" + safeVarName + ");"); break;
+                
+            case SchemaProperty.JAVA_USER:
+                emit(getUserTypeStaticHandlerMethod(true, stype)
+                        + "(" + safeVarName + ", target);");
+                break;
 
             default:
                 throw new IllegalStateException();
@@ -2009,8 +2048,9 @@
             makeMissingValue(javaType);
             endBlock();
 
-
-            printJGetValue(javaType, type);
+            
+            printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType());    
+            
 
             emitImplementationPostamble();
 
@@ -2109,7 +2149,7 @@
                 emit("java.util.List targetList = new java.util.ArrayList();");
             emit("get_store().find_all_element_users(" + setIdentifier + ", targetList);");
 
-            printJGetArrayValue(javaType, type);
+            printJGetArrayValue(javaType, type, (SchemaTypeImpl)prop.getType());
 
             emitImplementationPostamble();
             endBlock();
@@ -2121,7 +2161,7 @@
             emitImplementationPreamble();
 
             emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
-            printJGetValue(javaType, type);
+            printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType());
 
             emitImplementationPostamble();
             endBlock();
@@ -2194,7 +2234,7 @@
         }
     }
 
-    void printSetterImpls(QName qName, boolean isAttr,
+       void printSetterImpls(QName qName, SchemaProperty prop, boolean isAttr,
                        String propertyName, int javaType, String type, String xtype,
                        boolean nillable, boolean optional, boolean several, boolean singleton,
                        boolean isunion, String identifier, String setIdentifier, SchemaType sType)
@@ -2209,7 +2249,6 @@
         boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
         boolean isobj = (javaType == SchemaProperty.JAVA_OBJECT);
         boolean isSubstGroup = identifier != setIdentifier;
-        String jSet = jsetMethod(javaType);
         String jtargetType = (isunion || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype;
 
         String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
@@ -2232,7 +2271,7 @@
                 emitImplementationPreamble();
                 emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                 emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType);
-                emit(jSet + "(" + safeVarName + ");");
+                printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType());
                 emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                 emitImplementationPostamble();
             }
@@ -2349,6 +2388,25 @@
                     else
                         emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" );
                 }
+                else if (prop.getJavaTypeCode() == SchemaProperty.JAVA_USER)
+                {
+                    if (!isSubstGroup)
+                    {
+                        emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ");" );
+                        emit("for ( int i = 0 ; i < dests.length ; i++ ) {");
+                        emit("    " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl)prop.getType())
+                                + "(" + safeVarName + "Array[i], dests[i]);");
+                        emit("}");
+                    }
+                    else
+                    {
+                        emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ", " + setIdentifier + ");" );
+                        emit("for ( int i = 0 ; i < dests.length ; i++ ) {");
+                        emit("    " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl)prop.getType())
+                                + "(" + safeVarName + "Array[i], dests[i]);");
+                        emit("}");
+                    }
+                }
                 else
                 {
                     if (!isSubstGroup)
@@ -2377,7 +2435,7 @@
                 emitImplementationPreamble();
                 emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                 emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
-                emit(jSet + "(" + safeVarName + ");");
+                printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType());
                 emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                 emitImplementationPostamble();
             }
@@ -2436,7 +2494,7 @@
                     emit ("(" + jtargetType +")get_store().insert_element_user(" + setIdentifier + ", " +
                             identifier + ", i);");
                 outdent();
-                emit(jSet + "(" + safeVarName + ");");
+                printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType());
                 emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                 emitImplementationPostamble();
                 endBlock();
@@ -2448,7 +2506,7 @@
                 emitDeclareTarget(true, jtargetType);
   	            emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                 emitAddTarget(identifier, isAttr, true, jtargetType);
-                emit(jSet + "(" + safeVarName + ");");
+                printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType());
                 emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                 emitImplementationPostamble();
                 endBlock();
@@ -2602,6 +2660,7 @@
                 {
                     printSetterImpls(
                         name,
+                        prop,
                         prop.isAttribute(),
                         prop.getJavaPropertyName(),
                         prop.getJavaTypeCode(),

Modified: xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java (original)
+++ xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java Mon Apr 27 19:31:13 2009
@@ -100,6 +100,8 @@
     private volatile Constructor _javaImplConstructor;
     private volatile Constructor _javaImplConstructor2;
     private volatile boolean _implNotAvailable;
+    private volatile Class _userTypeClass;
+    private volatile Class _userTypeHandlerClass;
 
     // user data objects not persisted
     private volatile Object _userData;
@@ -140,6 +142,10 @@
     private int _baseDepth; // how many inheritance steps to AnyType
     private int _derivationType;
 
+    // user type support
+    private String _userTypeName;
+    private String _userTypeHandler;
+    
     // for complex types with simple content
     private SchemaType.Ref _contentBasedOnTyperef;
 
@@ -577,6 +583,26 @@
     public String getFullJavaImplName() { return _fullJavaImplName;}
     public String getShortJavaImplName() { return _shortJavaImplName;}
 
+    public String getUserTypeName() 
+    {
+        return _userTypeName;
+    }
+    
+    public void setUserTypeName(String userTypeName)
+    {
+        _userTypeName = userTypeName;
+    }
+
+    public String getUserTypeHandlerName() 
+    {
+        return _userTypeHandler;
+    }
+
+    public void setUserTypeHandlerName(String typeHandler) 
+    {
+        _userTypeHandler = typeHandler;
+    }
+
     public void setInterfaceExtensions(InterfaceExtension[] interfaces)
     {
         assertResolved();
@@ -1718,6 +1744,44 @@
         return _javaImplClass;
     }
 
+    public Class getUserTypeClass() 
+    {
+        // This field is declared volatile and Class is immutable so this is allowed.
+        if (_userTypeClass == null && getUserTypeName() != null) 
+        {
+            try 
+            {
+                _userTypeClass = Class.forName(_userTypeName, false,
+                    getTypeSystem().getClassLoader());
+            } 
+            catch (ClassNotFoundException e) 
+            {
+                _userTypeClass = null;
+            }
+        }
+
+        return _userTypeClass;
+    }
+
+    public Class getUserTypeHandlerClass() 
+    {
+        // This field is declared volatile and Class is immutable so this is allowed.
+        if (_userTypeHandlerClass == null && getUserTypeHandlerName() != null) 
+        {
+            try 
+            {
+                _userTypeHandlerClass = Class.forName(_userTypeHandler, false,
+                    getTypeSystem().getClassLoader());
+            } 
+            catch (ClassNotFoundException e) 
+            {
+                _userTypeHandlerClass = null;
+            }
+        }
+
+        return _userTypeHandlerClass;
+    }
+
     public Constructor getJavaImplConstructor()
     {
         if (_javaImplConstructor == null && !_implNotAvailable)

Modified: xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java (original)
+++ xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java Mon Apr 27 19:31:13 2009
@@ -22,6 +22,7 @@
 import org.apache.xmlbeans.SchemaParticle;
 import org.apache.xmlbeans.SchemaProperty;
 import org.apache.xmlbeans.QNameSet;
+import org.apache.xmlbeans.UserType;
 import org.apache.xmlbeans.XmlAnySimpleType;
 import org.apache.xmlbeans.SchemaStringEnumEntry;
 import org.apache.xmlbeans.XmlByte;
@@ -98,6 +99,9 @@
             {
                 sImpl.setFullJavaName(pickFullJavaClassName(usedNames, findTopName(sImpl), pickedName, sImpl.isDocumentType(), sImpl.isAttributeType()));
                 sImpl.setFullJavaImplName(pickFullJavaImplName(usedNames, sImpl.getFullJavaName()));
+
+                setUserTypes(sImpl, state);
+
                 setExtensions(sImpl, state);
             }
         }
@@ -131,6 +135,21 @@
         }
     }
 
+    private static void setUserTypes(SchemaTypeImpl sImpl, StscState state)
+    {
+        BindingConfig config = state.getBindingConfig();
+
+        if (config != null)
+        {
+            UserType utype = config.lookupUserTypeForQName(sImpl.getName());
+            if (utype != null)
+            {
+                sImpl.setUserTypeName(utype.getJavaName());
+                sImpl.setUserTypeHandlerName(utype.getStaticHandler());
+            }
+        }
+    }
+
     private static void setExtensions(SchemaTypeImpl sImpl, StscState state)
     {
         String javaName = sImpl.getFullJavaName();
@@ -531,6 +550,9 @@
         if (!sType.isSimpleType())
             return SchemaProperty.XML_OBJECT;
 
+        if (((SchemaTypeImpl)sType).getUserTypeHandlerName() != null)
+            return SchemaProperty.JAVA_USER;
+
         if (sType.getSimpleVariety() == SchemaType.UNION)
         {
             // see if we can find an interesting common base type, e.g., for string enums

Modified: xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java (original)
+++ xmlbeans/trunk/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java Mon Apr 27 19:31:13 2009
@@ -161,6 +161,58 @@
         }
     }
 
+    protected SimpleValue[] arraySetterHelper ( int sourcesLength, QName elemName )
+    {
+        SimpleValue[] dests = new SimpleValue[sourcesLength];
+
+        TypeStore store = get_store();
+
+        int m = store.count_elements( elemName );
+
+        for ( ; m > sourcesLength ; m-- )
+            store.remove_element( elemName, m - 1 );
+
+        for ( int i = 0 ; i < sourcesLength ; i++ )
+        {
+            TypeStoreUser user;
+
+            if (i >= m)
+                user = store.add_element_user( elemName );
+            else
+                user = store.find_element_user( elemName, i );
+
+            dests[i] = (SimpleValue) user;
+        }
+
+        return dests;
+    }
+
+    protected SimpleValue[] arraySetterHelper ( int sourcesLength, QName elemName, QNameSet set )
+    {
+        SimpleValue[] dests = new SimpleValue[sourcesLength];
+
+        TypeStore store = get_store();
+
+        int m = store.count_elements( set );
+
+        for ( ; m > sourcesLength ; m-- )
+            store.remove_element( set, m - 1 );
+
+        for ( int i = 0 ; i < sourcesLength ; i++ )
+        {
+            TypeStoreUser user;
+
+            if (i >= m)
+                user = store.add_element_user( elemName );
+            else
+                user = store.find_element_user( set, i );
+
+            dests[i] = (SimpleValue) user;
+        }
+
+        return dests;
+    }
+
     protected void arraySetterHelper ( boolean[] sources, QName elemName )
     {
         int n = sources == null ? 0 : sources.length;

Modified: xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java (original)
+++ xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java Mon Apr 27 19:31:13 2009
@@ -20,7 +20,9 @@
 import org.apache.xmlbeans.impl.xb.xmlconfig.Nsconfig;
 import org.apache.xmlbeans.impl.xb.xmlconfig.Qnameconfig;
 import org.apache.xmlbeans.impl.xb.xmlconfig.Qnametargetenum;
+import org.apache.xmlbeans.impl.xb.xmlconfig.Usertypeconfig;
 import org.apache.xmlbeans.BindingConfig;
+import org.apache.xmlbeans.UserType;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlError;
 import org.apache.xmlbeans.InterfaceExtension;
@@ -54,6 +56,7 @@
 
     private List _interfaceExtensions;
     private List _prePostExtensions;
+    private Map _userTypes;
 
     private BindingConfigImpl()
     {
@@ -69,6 +72,7 @@
         _qnameAttMap = Collections.EMPTY_MAP;
         _interfaceExtensions = new ArrayList();
         _prePostExtensions = new ArrayList();
+        _userTypes = Collections.EMPTY_MAP;
     }
 
     public static BindingConfig forConfigDocuments(Config[] configs, File[] javaFiles, File[] classpath)
@@ -90,6 +94,7 @@
         _qnameAttMap = new LinkedHashMap();
         _interfaceExtensions = new ArrayList();
         _prePostExtensions = new ArrayList();
+        _userTypes = new LinkedHashMap();
 
         for (int i = 0; i < configs.length; i++)
         {
@@ -137,6 +142,12 @@
             {
                 recordExtensionSetting(javaFiles, classpath, ext[j]);
             }
+            
+            Usertypeconfig[] utypes = config.getUsertypeArray();
+            for (int j = 0; j < utypes.length; j++)
+            {
+                recordUserTypeSetting(javaFiles, classpath, utypes[j]);
+            }
         }
 
         secondPhaseValidation();
@@ -274,6 +285,14 @@
         }
     }
 
+    private void recordUserTypeSetting(File[] javaFiles, File[] classpath,
+            Usertypeconfig usertypeconfig)
+    {
+        JamClassLoader jamLoader = getJamLoader(javaFiles, classpath);
+        UserTypeImpl userType = UserTypeImpl.newInstance(jamLoader, usertypeconfig);
+        _userTypes.put(userType.getName(), userType);
+    }
+
 
     private String lookup(Map map, Map mapByUriPrefix, String uri)
     {
@@ -368,6 +387,14 @@
         return null;
     }
 
+    public UserType lookupUserTypeForQName(QName qname)
+    {
+        if (qname == null)
+            return null;
+
+        return (UserType) _userTypes.get(qname);
+    }
+
     public InterfaceExtension[] getInterfaceExtensions()
     {
         return (InterfaceExtension[])_interfaceExtensions.toArray(new InterfaceExtension[_interfaceExtensions.size()]);

Added: xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java (added)
+++ xmlbeans/trunk/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,46 @@
+package org.apache.xmlbeans.impl.config;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xmlbeans.UserType;
+import org.apache.xmlbeans.impl.jam.JamClassLoader;
+import org.apache.xmlbeans.impl.xb.xmlconfig.Usertypeconfig;
+
+public class UserTypeImpl implements UserType
+{
+    private QName _name;
+    private String _javaName;
+    private String _staticHandler;
+
+
+    static UserTypeImpl newInstance(JamClassLoader loader, Usertypeconfig cfgXO)
+    {
+        UserTypeImpl result = new UserTypeImpl();
+
+        result._name = cfgXO.getName();
+        result._javaName = cfgXO.getJavaname();
+        result._staticHandler = cfgXO.getStaticHandler();
+
+        // We don't validate here because we're just using reflection in
+        // the implementation. However, in the future we might want to add
+        // the option of directly using the static handler in generated code
+
+        return result;
+    }
+
+
+    public String getJavaName() 
+    {
+        return _javaName;
+    }
+
+    public QName getName()
+    {
+        return _name;
+    }
+
+    public String getStaticHandler()
+    {
+        return _staticHandler;
+    }
+}

Modified: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java (original)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java Mon Apr 27 19:31:13 2009
@@ -27,6 +27,7 @@
 {
     private static final InterfaceExtension[] EMPTY_INTERFACE_EXT_ARRAY = new InterfaceExtension[0];
     private static final PrePostExtension[] EMPTY_PREPOST_EXT_ARRAY = new PrePostExtension[0];
+    private static final UserType[] EMPTY_USER_TYPE_ARRY = new UserType[0];
 
     public static final int QNAME_TYPE = 1;
     public static final int QNAME_DOCUMENT_TYPE = 2;
@@ -85,4 +86,14 @@
      */
     public PrePostExtension getPrePostExtension(String fullJavaName) { return null; }
 
+    /**
+     * Returns all defined user types.
+     */
+    public UserType[] getUserTypes() { return EMPTY_USER_TYPE_ARRY; }
+
+    /**
+     * Returns a user defined Java type for a given QName.
+     */
+    public UserType lookupUserTypeForQName(QName qname) { return null; }
+
 }

Modified: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java (original)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java Mon Apr 27 19:31:13 2009
@@ -211,6 +211,9 @@
     /** A {@link java.lang.Object}, used for some simple type unions. See {@link #getJavaTypeCode}. */
     static final int JAVA_OBJECT = 19; // for some unions
 
+    /** A user specified type. */
+    static final int JAVA_USER = 20;
+
     /**
      * Returns the default or fixed value,
      * if it is consistent. If it is not consistent,

Added: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/UserType.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/UserType.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/UserType.java (added)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/UserType.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,27 @@
+package org.apache.xmlbeans;
+
+import javax.xml.namespace.QName;
+
+/**
+ * The UserType class represents a mapping between an XML Schema QName and
+ * a custom Java class type. It is used during code generation to determine
+ * how to convert user-defined simple types to user defined Java classes.
+ */
+public interface UserType
+{
+    /**
+     * The QName of the simple value that will be converted to a Java class.
+     */
+    QName getName();
+
+    /**
+     * The class name the simple value will be converted to.
+     */
+    String getJavaName();
+
+    /**
+     * A class which provides public static methods to convert {@link SimpleValue}
+     * objects to and from the Java type specified by {@link #getJavaName()}.
+     */
+    String getStaticHandler();
+}

Added: xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsd
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsd?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsd (added)
+++ xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsd Mon Apr 27 19:31:13 2009
@@ -0,0 +1,62 @@
+<!-- edited with XMLSPY v5 rel. 2 U (http://www.xmlspy.com) by Michael Kintzer (BEA Systems) -->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+xmlns:po="http://xbean.usertype/averageCase/PurchaseOrder"
+targetNamespace="http://xbean.usertype/averageCase/PurchaseOrder"
+elementFormDefault="qualified"
+>
+       <xsd:annotation>
+               <xsd:documentation xml:lang="en">
+   Purchase order schema for Example.com.
+   Copyright 2000 Example.com. All rights reserved.
+  </xsd:documentation>
+       </xsd:annotation>
+       <xsd:element name="purchaseOrder" type="po:PurchaseOrderType"/>
+       <xsd:element name="comment" type="xsd:string"/>
+       <xsd:complexType name="PurchaseOrderType">
+               <xsd:sequence>
+                       <xsd:element name="shipTo" type="po:USAddress"/>
+                       <xsd:element name="billTo" type="po:USAddress"/>
+                       <xsd:element ref="po:comment" minOccurs="0"/>
+                       <xsd:element name="items" type="po:Items"/>
+               </xsd:sequence>
+               <xsd:attribute name="orderDate" type="xsd:date"/>
+       </xsd:complexType>
+       <xsd:complexType name="USAddress">
+               <xsd:sequence>
+                       <xsd:element name="name" type="xsd:string" nillable="true"/>
+                       <xsd:element name="street" type="xsd:string"/>
+                       <xsd:element name="city" type="xsd:string"/>
+                       <xsd:element name="state" type="xsd:string"/>
+                       <xsd:element name="zip" type="xsd:decimal"/>
+               </xsd:sequence>
+               <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
+       </xsd:complexType>
+       <xsd:complexType name="Items">
+               <xsd:sequence>
+                       <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
+                               <xsd:complexType>
+                                       <xsd:sequence>
+                                               <xsd:element name="productName" type="xsd:string"/>
+                                               <xsd:element name="quantity">
+                                                       <xsd:simpleType>
+                                                               <xsd:restriction base="xsd:positiveInteger">
+                                                                       <xsd:maxExclusive value="100"/>
+                                                               </xsd:restriction>
+                                                       </xsd:simpleType>
+                                               </xsd:element>
+                                               <xsd:element name="USPrice" type="xsd:decimal"/>
+                                               <xsd:element ref="po:comment" minOccurs="0"/>
+                                               <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
+                                       </xsd:sequence>
+                                       <xsd:attribute name="partNum" type="po:SKU" use="required"/>
+                               </xsd:complexType>
+                       </xsd:element>
+               </xsd:sequence>
+       </xsd:complexType>
+       <!-- Stock Keeping Unit, a code for identifying products -->
+       <xsd:simpleType name="SKU">
+               <xsd:restriction base="xsd:string">
+                       <xsd:pattern value="\d{3}-[A-Z]{2}"/>
+               </xsd:restriction>
+       </xsd:simpleType>
+</xsd:schema>

Added: xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsdconfig
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsdconfig?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsdconfig (added)
+++ xmlbeans/trunk/test/cases/xbean/usertype/averageCase/po.xsdconfig Mon Apr 27 19:31:13 2009
@@ -0,0 +1,21 @@
+<!-- Copyright 2004 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. -->
+<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config"
+xmlns:po="http://xbean.usertype/averageCase/PurchaseOrder">
+
+    <xb:usertype name="po:SKU" javaname="xmlobject.usertype.averageCase.existing.SKU">
+        <xb:staticHandler>xmlobject.usertype.averageCase.existing.SKUHandler</xb:staticHandler>
+    </xb:usertype>
+
+</xb:config>

Added: xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsd
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsd?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsd (added)
+++ xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsd Mon Apr 27 19:31:13 2009
@@ -0,0 +1,40 @@
+<xsd:schema targetNamespace="http://xbean.usertype/multipleItems/company"
+       xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:company="http://xbean.usertype/multipleItems/company">
+       <xsd:element name="company" type="company:CompanyType" />
+       <xsd:complexType name="CompanyType">
+               <xsd:sequence>
+                       <xsd:element name="departments" type="company:DepartmentType"
+                               maxOccurs="unbounded" />
+               </xsd:sequence>
+
+               <xsd:anyAttribute namespace="http://www.omg.org/XMI"
+                       processContents="lax" />
+       </xsd:complexType>
+       <xsd:element name="department" type="company:DepartmentType" />
+       <xsd:complexType name="DepartmentType">
+               <xsd:sequence>
+                       <xsd:element name="consultant" type="company:ConsultantType"
+                               maxOccurs="unbounded" />
+               </xsd:sequence>
+               <xsd:anyAttribute namespace="http://www.omg.org/XMI"
+                       processContents="lax" />
+       </xsd:complexType>
+       <xsd:complexType name="ConsultantType">
+               <xsd:sequence>
+                       <xsd:element name="room" type="company:Room" maxOccurs="unbounded" />
+               </xsd:sequence>
+               <xsd:attribute name="name" type="xsd:string" />
+               <xsd:attribute name="age" type="xsd:integer" />
+               <xsd:anyAttribute namespace="http://www.omg.org/XMI"
+                       processContents="lax" />
+
+
+       </xsd:complexType>
+
+
+       <xsd:simpleType name="Room">
+               <xsd:restriction base="xsd:string">
+                       <xsd:pattern value="\d{3}-[A-Z]{2}" />
+               </xsd:restriction>
+       </xsd:simpleType>
+</xsd:schema>

Added: xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsdconfig
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsdconfig?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsdconfig (added)
+++ xmlbeans/trunk/test/cases/xbean/usertype/multipleItems/company.xsdconfig Mon Apr 27 19:31:13 2009
@@ -0,0 +1,21 @@
+<!-- Copyright 2004 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. -->
+<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config"
+xmlns:company="http://xbean.usertype/multipleItems/company">
+
+    <xb:usertype name="company:Room" javaname="xmlobject.usertype.multipleItems.existing.Room">
+        <xb:staticHandler>xmlobject.usertype.multipleItems.existing.RoomHandler</xb:staticHandler>
+    </xb:usertype>
+
+</xb:config>

Added: xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,100 @@
+/*   Copyright 2004 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 xmlobject.usertype.averageCase.checkin;
+
+import java.math.BigDecimal;
+
+import javax.xml.stream.XMLOutputFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+
+import usertype.xbean.averageCase.purchaseOrder.Items;
+import usertype.xbean.averageCase.purchaseOrder.PurchaseOrderDocument;
+import usertype.xbean.averageCase.purchaseOrder.PurchaseOrderType;
+import xmlobject.usertype.averageCase.existing.SKU;
+
+
+public class AverageTest extends TestCase
+{
+
+    public  AverageTest(String s){
+        super(s);
+    }
+
+    public void test(){
+
+        PurchaseOrderDocument poDoc ;
+
+        poDoc= PurchaseOrderDocument.Factory.newInstance();
+        PurchaseOrderType po=poDoc.addNewPurchaseOrder();
+        int LEN=20;
+
+        Items.Item[] it= new Items.Item[LEN];
+        for (int i=0; i< LEN; i++){
+            it[i]=Items.Item.Factory.newInstance();
+            it[i].setUSPrice(new BigDecimal(""+ 2 ));
+            it[i].setPartNum(new SKU(i, "AB"));
+        }
+        Items items= Items.Factory.newInstance();
+        items.setItemArray(it);
+        po.setItems(items);
+        //  System.out.println("poDoc: " + poDoc);
+
+        for (int i=0; i< LEN; i++){
+            assertEquals(i, it[i].getPartNum().getDigits());
+            assertEquals("AB", it[i].getPartNum().getLetters());
+        }
+
+
+    }
+
+    public void testBadInput() throws XmlException{
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("<purchaseOrder xmlns=\"http://xbean.usertype/averageCase/PurchaseOrder\">");
+        sb.append("<items><item partNum=\"000-AB\"><USPrice>2</USPrice></item>");
+        sb.append("<item partNum=\"0013-AB\"><USPrice>2</USPrice></item>");
+        sb.append("</items></purchaseOrder>");
+
+        PurchaseOrderDocument poDocument = PurchaseOrderDocument.Factory.parse(sb.toString());
+
+        PurchaseOrderType po = poDocument.getPurchaseOrder();
+
+        Items.Item[] it = po.getItems().getItemArray();
+        assertEquals(2, it.length);
+
+
+        SKU sku = it[0].getPartNum();
+
+        assertEquals(0, sku.getDigits());
+        assertEquals("AB", sku.getLetters());
+
+        try {
+
+            sku = it[1].getPartNum();
+            fail("Invalid SKU format should have failed");
+
+        } catch (XmlValueOutOfRangeException e) {
+
+            // test passed
+        }
+
+
+    }
+}

Added: xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKU.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKU.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKU.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKU.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,42 @@
+package xmlobject.usertype.averageCase.existing;
+
+public class SKU
+{
+    private int digits;
+    private String letters;
+
+    
+    public SKU()
+    {
+    }
+
+    public SKU(int digits, String letters)
+    {
+        setDigits(digits);
+        setLetters(letters);
+    }
+
+    public int getDigits()
+    {
+        return digits;
+    }
+
+    public void setDigits(int digits)
+    {
+        if (digits > 999 || digits < 0)
+            throw new IllegalArgumentException("bad digits");
+        this.digits = digits;
+    }
+
+    public String getLetters()
+    {
+        return letters;
+    }
+
+    public void setLetters(String letters)
+    {
+        if (letters == null || letters.length() != 2)
+            throw new IllegalArgumentException("bad letters");
+        this.letters = letters;
+    }
+}

Added: xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,40 @@
+package xmlobject.usertype.averageCase.existing;
+
+import org.apache.xmlbeans.SimpleValue;
+import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+
+public class SKUHandler
+{
+
+    public static void encodeSKU(SKU obj, SimpleValue target)
+    {
+        String digits;
+        if (obj.getDigits() < 10)
+            digits = "00" + Integer.toString(obj.getDigits());
+        else if (obj.getDigits() < 100)
+            digits = "0" + Integer.toString(obj.getDigits());
+        else
+            digits = Integer.toString(obj.getDigits());
+        target.setStringValue(digits + "-" + obj.getLetters());
+    }
+
+    public static SKU decodeSKU(SimpleValue obj) throws XmlValueOutOfRangeException
+    {
+        String encoded = obj.getStringValue();
+        if (encoded.length() != 6)
+            throw new XmlValueOutOfRangeException("Invalid SKU format: " + encoded);
+
+        SKU sku = new SKU();
+        try
+        {
+            sku.setDigits(Integer.parseInt(encoded.substring(0,3)));
+        } catch (NumberFormatException e) {
+            throw new XmlValueOutOfRangeException("Invalid SKU format: " + encoded);
+        } catch (IllegalArgumentException e) {
+            throw new XmlValueOutOfRangeException("Invalid SKU format: " + encoded);
+        }
+
+        sku.setLetters(encoded.substring(4,6));
+        return sku;
+    }
+}

Added: xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,222 @@
+/*   Copyright 2004 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 xmlobject.usertype.multipleItems.checkin;
+
+
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+
+import usertype.xbean.multipleItems.company.CompanyDocument;
+import usertype.xbean.multipleItems.company.CompanyType;
+import usertype.xbean.multipleItems.company.ConsultantType;
+import usertype.xbean.multipleItems.company.DepartmentType;
+import xmlobject.usertype.multipleItems.existing.Room;
+
+
+public class AverageTest extends TestCase{
+
+    public  AverageTest(String s){
+        super(s);
+    }
+
+    public void test() {
+
+        CompanyDocument doc;
+
+        doc = CompanyDocument.Factory.newInstance();
+
+        CompanyType company = doc.addNewCompany();
+
+        DepartmentType dept = company.addNewDepartments();
+
+
+        ConsultantType cons = dept.addNewConsultant();
+
+        cons.setName("Joe Smith");
+        cons.setAge(BigInteger.valueOf(100));
+
+        int LEN=20;
+
+        for (int i=0; i < LEN; i++) {
+            cons.addRoom(new Room(i, "AB"));
+        }
+
+        System.out.println(doc.xmlText());
+
+        Room[] rooms = cons.getRoomArray();
+
+        for (int i=0; i < LEN; i++) {
+            assertEquals(i, rooms[i].getDigits());
+            assertEquals("AB", rooms[i].getLetters());
+        }
+    }
+
+
+    public void testArrayGetSet() {
+
+        CompanyDocument doc;
+
+        doc = CompanyDocument.Factory.newInstance();
+
+        CompanyType company = doc.addNewCompany();
+
+        DepartmentType dept = company.addNewDepartments();
+
+
+        ConsultantType cons = dept.addNewConsultant();
+
+        cons.setName("Joe Smith");
+        cons.setAge(BigInteger.valueOf(100));
+
+        int LEN=20;
+
+        Room[] rooms = new Room[LEN];
+
+        for (int i=0; i < LEN; i++) {
+            rooms[i] = new Room(i, "AB");
+        }
+
+        cons.setRoomArray(rooms);
+
+        rooms = cons.getRoomArray();
+        for (int i=0; i < LEN; i++) {
+            assertEquals(i, rooms[i].getDigits());
+            assertEquals("AB", rooms[i].getLetters());
+        }
+
+
+    }
+
+    public void testIthGetSet() {
+
+        CompanyDocument doc;
+
+        doc = CompanyDocument.Factory.newInstance();
+
+        CompanyType company = doc.addNewCompany();
+
+        DepartmentType dept = company.addNewDepartments();
+
+
+        ConsultantType cons = dept.addNewConsultant();
+
+        cons.setName("Joe Smith");
+        cons.setAge(BigInteger.valueOf(100));
+
+
+        int LEN=20;
+
+        for (int i=0; i < LEN; i++) {
+            cons.addNewRoom();
+        }
+
+
+        for (int i=0; i < LEN; i++) {
+            cons.setRoomArray(i, new Room(i, "AB"));
+        }
+
+        for (int i=0; i < LEN; i++) {
+            assertEquals(i, cons.getRoomArray(i).getDigits());
+            assertEquals("AB", cons.getRoomArray(i).getLetters());
+        }
+
+
+    }
+
+
+    public void testBadInput() throws XmlException{
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("<com:company xmlns:com=\"http://xbean.usertype/multipleItems/company\">");
+        sb.append("<departments><consultant name=\"Joe Smith\" age=\"100\">");
+        sb.append("<room>000-AB</room><room>0001-AB</room><room>002-AB</room>");
+        sb.append("</consultant></departments></com:company>");
+
+        CompanyDocument doc = CompanyDocument.Factory.parse(sb.toString());
+
+        CompanyType company = doc.getCompany();
+
+        ConsultantType cons = company.getDepartmentsArray(0).getConsultantArray(0);
+        assertEquals(3, cons.xgetRoomArray().length);
+
+        try
+        {
+            cons.getRoomArray();
+            fail("Invalid Room format should have failed");
+
+        } catch (XmlValueOutOfRangeException e) {
+
+            // test passed
+        }
+
+    }
+
+
+
+    public void testBadInputGetIthBad() throws XmlException{
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("<com:company xmlns:com=\"http://xbean.usertype/multipleItems/company\">");
+        sb.append("<departments><consultant name=\"Joe Smith\" age=\"100\">");
+        sb.append("<room>000-AB</room><room>0001-AB</room><room>002-AB</room>");
+        sb.append("</consultant></departments></com:company>");
+
+        CompanyDocument doc = CompanyDocument.Factory.parse(sb.toString());
+
+        CompanyType company = doc.getCompany();
+
+        ConsultantType cons = company.getDepartmentsArray(0).getConsultantArray(0);
+        assertEquals(3, cons.xgetRoomArray().length);
+
+        try
+        {
+            cons.getRoomArray(1);
+            fail("Invalid Room format should have failed");
+        } catch (XmlValueOutOfRangeException e) {
+
+            // test passed
+        }
+
+    }
+
+
+    public void testBadInputGetIthGood() throws XmlException{
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("<com:company xmlns:com=\"http://xbean.usertype/multipleItems/company\">");
+        sb.append("<departments><consultant name=\"Joe Smith\" age=\"100\">");
+        sb.append("<room>000-AB</room><room>0001-AB</room><room>002-AB</room>");
+        sb.append("</consultant></departments></com:company>");
+
+        CompanyDocument doc = CompanyDocument.Factory.parse(sb.toString());
+
+        CompanyType company = doc.getCompany();
+
+        ConsultantType cons = company.getDepartmentsArray(0).getConsultantArray(0);
+        assertEquals(3, cons.xgetRoomArray().length);
+
+        assertEquals(0, cons.getRoomArray(0).getDigits());
+        assertEquals("AB", cons.getRoomArray(0).getLetters());
+        assertEquals(2, cons.getRoomArray(2).getDigits());
+        assertEquals("AB", cons.getRoomArray(2).getLetters());
+
+    }
+
+}

Added: xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/Room.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/Room.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/Room.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/Room.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,42 @@
+package xmlobject.usertype.multipleItems.existing;
+
+public class Room
+{
+    private int digits;
+    private String letters;
+
+
+    public Room()
+    {
+    }
+
+    public Room(int digits, String letters)
+    {
+        setDigits(digits);
+        setLetters(letters);
+    }
+
+    public int getDigits()
+    {
+        return digits;
+    }
+
+    public void setDigits(int digits)
+    {
+        if (digits > 999 || digits < 0)
+            throw new IllegalArgumentException("bad digits");
+        this.digits = digits;
+    }
+
+    public String getLetters()
+    {
+        return letters;
+    }
+
+    public void setLetters(String letters)
+    {
+        if (letters == null || letters.length() != 2)
+            throw new IllegalArgumentException("bad letters");
+        this.letters = letters;
+    }
+}

Added: xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java?rev=769119&view=auto
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java (added)
+++ xmlbeans/trunk/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java Mon Apr 27 19:31:13 2009
@@ -0,0 +1,41 @@
+package xmlobject.usertype.multipleItems.existing;
+
+import org.apache.xmlbeans.SimpleValue;
+import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+
+public class RoomHandler
+{
+
+    public static void encodeRoom(Room obj, SimpleValue target)
+    {
+        String digits;
+        if (obj.getDigits() < 10)
+            digits = "00" + Integer.toString(obj.getDigits());
+        else if (obj.getDigits() < 100)
+            digits = "0" + Integer.toString(obj.getDigits());
+        else
+            digits = Integer.toString(obj.getDigits());
+        target.setStringValue(digits + "-" + obj.getLetters());
+    }
+
+
+    public static Room decodeRoom(SimpleValue obj) throws XmlValueOutOfRangeException
+    {
+        String encoded = obj.getStringValue();
+        if (encoded.length() != 6)
+            throw new XmlValueOutOfRangeException("Invalid Room format: " + encoded);
+
+        Room sku = new Room();
+        try
+        {
+            sku.setDigits(Integer.parseInt(encoded.substring(0,3)));
+        } catch (NumberFormatException e) {
+            throw new XmlValueOutOfRangeException("Invalid Room format: " + encoded);
+        } catch (IllegalArgumentException e) {
+            throw new XmlValueOutOfRangeException("Invalid Room format: " + encoded);
+        }
+
+        sku.setLetters(encoded.substring(4,6));
+        return sku;
+    }
+}

Modified: xmlbeans/trunk/testbuild.xml
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/testbuild.xml?rev=769119&r1=769118&r2=769119&view=diff
==============================================================================
--- xmlbeans/trunk/testbuild.xml (original)
+++ xmlbeans/trunk/testbuild.xml Mon Apr 27 19:31:13 2009
@@ -256,7 +256,8 @@
         ${build.dir.test.schemas}/xbean/xmlobject/store,
         ${build.dir.test.schemas}/xbean/xmltokensource,
         ${build.dir.test.schemas}/xbean/ValidatingStream,
-        ${build.dir.test.schemas}/xbean/scomp"/>
+        ${build.dir.test.schemas}/xbean/scomp,
+        ${build.dir.test.schemas}/xbean/usertype"/>
     <!-- comma separated list of directories containing schemas that *must* be separately
          compiled -->
     <property name="schema.standalone"
@@ -571,7 +572,7 @@
     <!-- NOTE: This target depends on build.schemas, but we do not
                explicitly put it on the depends list. -->
 
-    <target name="build.tests" depends="init, build.test.tools, build.xpath,extensions.build"
+    <target name="build.tests" depends="init, build.test.tools, build.xpath,extensions.build,usertype.build"
         description="Build the tests">
 
         <javac srcdir="${xbeans.test.src}"
@@ -646,6 +647,12 @@
                 <antcall target="extensions.build"/>
             </then>
         </if>
+        <if>
+            <isset property="compile.usertype"/>
+            <then>
+                <antcall target="usertype.build"/>
+            </then>
+        </if>
         <antcall target="build.xmlcases"/>
         <antcall target="build.xsdcases"/>
 
@@ -708,6 +715,37 @@
 
         </foreachloop>
     </target>
+    <!--User type feature-->
+    <target name="usertype.build" depends="init">
+        <echo message="Building user types"/>
+        <foreachloop
+            param="case" trim="true">
+            <path>
+                <dirset dir="${xbeans.test.src}/xmlobject/usertype/">
+                    <include name="*"/>
+                </dirset>
+            </path>
+            <loop>
+                <basename property="testcase" path="${case}"/>
+                
+                <available file="${build.dir.test.schemas.lib}/usertype_${testcase}.jar" property="usertypejar.exists"/>
+                <echo message="JAR ${build.dir.test.schemas.lib}/usertype_${testcase}.jar, Exists: ${usertypejar.exists}"/>
+                <if>
+                    <isfalse value="${usertypejar.exists}"/>
+                    <then>
+                        <java classname="${schema.compiler}"
+                            classpathref="build.classpath"
+                            fork="true">
+                            <arg line="-out ${build.dir.test.schemas.lib}/usertype_${testcase}.jar
+                            ${case}/existing
+                            ${xbeans.test.cases}/xbean/usertype/${testcase}"
+                                />
+                        </java>
+                    </then>
+                </if>
+            </loop>
+        </foreachloop>
+    </target>
 
     <!--test xmlbeans task-->
     <target name="xmlbean-test" depends="init">
@@ -733,6 +771,7 @@
             ${schema.standalone}/SimpleRailCarrierWaybillInterchange_V40_LX.xsd,
             ${schema.standalone}/TerminalOperationsAndIntermodalRampActivity_V40_LX.xsd,"/>
         <property name="compile.extensions" value="true"/>
+        <property name="compile.usertype" value="true"/>
 
         <property name="includes.for.compile"
             value="**/xmlobject/**/*.java"/>
@@ -830,7 +869,7 @@
     </target>
 
     <!-- FREQ Target -->
-    <target name="build.area.checkin" depends="clean.tests,extensions.build">
+    <target name="build.area.checkin" depends="clean.tests,extensions.build,usertype.build">
         <property name="includes.for.compile"
             value="**/checkin/**/*.java,
                    **/common/**/*.java"/>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: commits-help@xmlbeans.apache.org