# HG changeset patch
# User Wesley Leggette <wlegge...@cleversafe.com>
# Date 1237102589 18000
# Branch clean
# Node ID 1a589b49b118349cf54ebeee8f036ac32bfbe9dc
# Parent  5471ba2f2541e6cc0dc7808f0f1f86f35297ebdd
Custom user type support.
* * *
Finished user type support for multiple values, applied changes recommended in 
code review.
* * *
removed isUserType() as it is not needed.
* * *
Fixed changes after code review.

diff -r 5471ba2f2541 -r 1a589b49b118 src/configschema/schema/xmlconfig.xsd
--- a/src/configschema/schema/xmlconfig.xsd     Sun Mar 22 15:07:07 2009 -0500
+++ b/src/configschema/schema/xmlconfig.xsd     Sun Mar 15 02:36:29 2009 -0500
@@ -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" >
diff -r 5471ba2f2541 -r 1a589b49b118 
src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
--- a/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java   
Sun Mar 22 15:07:07 2009 -0500
+++ b/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java   
Sun Mar 15 02:36:29 2009 -0500
@@ -17,6 +17,7 @@
 
 import java.io.Writer;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
@@ -29,12 +30,15 @@
 
 import javax.xml.namespace.QName;
 import org.apache.xmlbeans.impl.common.NameUtil;
+import org.apache.xmlbeans.impl.xb.xsdschema.impl.SimpleTypeImpl;
 import org.apache.xmlbeans.PrePostExtension;
 import org.apache.xmlbeans.InterfaceExtension;
+import org.apache.xmlbeans.QNameSet;
 import org.apache.xmlbeans.SchemaType;
 import org.apache.xmlbeans.SchemaTypeSystem;
 import org.apache.xmlbeans.SchemaProperty;
 import org.apache.xmlbeans.SchemaStringEnumEntry;
+import org.apache.xmlbeans.SimpleValue;
 import org.apache.xmlbeans.SystemProperties;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
@@ -323,6 +327,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 +1035,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 +1469,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 +1591,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 +1665,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 +2052,9 @@
             makeMissingValue(javaType);
             endBlock();
 
-
-            printJGetValue(javaType, type);
+            
+            printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType());    
+            
 
             emitImplementationPostamble();
 
@@ -2023,6 +2067,7 @@
                 emit("public " + xtype + " xget" + propertyName + "()");
                 startBlock();
                 emitImplementationPreamble();
+                // TODO: This is where we could choose to emit a get handler 
target instead
                 emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, 
xtype);
 
                 if (isAttr && (prop.hasDefault() == 
SchemaProperty.CONSISTENTLY ||
@@ -2046,6 +2091,7 @@
                 emit("public boolean isNil" + propertyName + "()");
                 startBlock();
                 emitImplementationPreamble();
+                // TODO: This is where we could choose to emit a get handler 
target instead
                 emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, 
xtype);
 
                 emit("if (target == null) return false;");
@@ -2109,7 +2155,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 +2167,7 @@
             emitImplementationPreamble();
 
             emitGetTarget(setIdentifier, identifier, isAttr, "i", 
THROW_EXCEPTION, jtargetType);
-            printJGetValue(javaType, type);
+            printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType());
 
             emitImplementationPostamble();
             endBlock();
@@ -2194,7 +2240,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 +2255,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 +2277,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 +2394,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)
@@ -2372,12 +2436,21 @@
                         
"org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_ARRAYITEM);");
                 emitPost(sType, PrePostExtension.OPERATION_SET, identifier, 
isAttr, "i");
             }
+            else if (prop.getJavaTypeCode() == SchemaProperty.JAVA_USER)
+            {
+                emitImplementationPreamble();
+                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, 
isAttr, "i");
+                emitGetTarget(setIdentifier, identifier, isAttr, "i", 
THROW_EXCEPTION, jtargetType);
+                printJSetValue(javaType, safeVarName, 
(SchemaTypeImpl)prop.getType());
+                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, 
isAttr, "i");
+                emitImplementationPostamble();
+            }
             else
             {
                 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 +2509,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 +2521,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 +2675,7 @@
                 {
                     printSetterImpls(
                         name,
+                        prop,
                         prop.isAttribute(),
                         prop.getJavaPropertyName(),
                         prop.getJavaTypeCode(),
diff -r 5471ba2f2541 -r 1a589b49b118 
src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
--- a/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java  Sun Mar 
22 15:07:07 2009 -0500
+++ b/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java  Sun Mar 
15 02:36:29 2009 -0500
@@ -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,7 +583,29 @@
     public String getFullJavaImplName() { return _fullJavaImplName;}
     public String getShortJavaImplName() { return _shortJavaImplName;}
 
-    public void setInterfaceExtensions(InterfaceExtension[] interfaces)
+    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();
         _interfaces = interfaces;
@@ -1717,6 +1745,46 @@
 
         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()
     {
diff -r 5471ba2f2541 -r 1a589b49b118 
src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java
--- a/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java    Sun Mar 
22 15:07:07 2009 -0500
+++ b/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java    Sun Mar 
15 02:36:29 2009 -0500
@@ -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,14 @@
             {
                 sImpl.setFullJavaName(pickFullJavaClassName(usedNames, 
findTopName(sImpl), pickedName, sImpl.isDocumentType(), 
sImpl.isAttributeType()));
                 sImpl.setFullJavaImplName(pickFullJavaImplName(usedNames, 
sImpl.getFullJavaName()));
+
+                UserType utype = 
StscState.get().getBindingConfig().lookupUserTypeForQName(sImpl.getName());
+                if (utype != null)
+                {
+                    sImpl.setUserTypeName(utype.getJavaName());
+                    sImpl.setUserTypeHandlerName(utype.getStaticHandler());
+                }
+
                 setExtensions(sImpl, state);
             }
         }
@@ -531,6 +540,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
diff -r 5471ba2f2541 -r 1a589b49b118 
src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java
--- a/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java   
Sun Mar 22 15:07:07 2009 -0500
+++ b/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java   
Sun Mar 15 02:36:29 2009 -0500
@@ -160,7 +160,59 @@
             ((XmlObjectBase) user).objectSet( sources[ i ] );
         }
     }
+    
+    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;
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
--- a/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java     Sun Mar 
22 15:07:07 2009 -0500
+++ b/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java     Sun Mar 
15 02:36:29 2009 -0500
@@ -1259,7 +1259,7 @@
     }
 
     private static final String CONFIG_URI = 
"http://xml.apache.org/xmlbeans/2004/02/xbean/config";;
-    private static final String COMPATIBILITY_CONFIG_URI = 
"http://www.bea.com/2002/09/xbean/config";;
+    private static final String COMPATIBILITY_CONFIG_URI = 
"http://xml.apache.org/xmlbeans/2004/02/xbean/config";;
     private static final Map MAP_COMPATIBILITY_CONFIG_URIS;
     static
     {
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java
--- a/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java      
Sun Mar 22 15:07:07 2009 -0500
+++ b/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java      
Sun Mar 15 02:36:29 2009 -0500
@@ -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();
@@ -273,6 +284,14 @@
             addPrePostExtension(PrePostExtensionImpl.newInstance(jamLoader, 
xbeanSet, ppXO));
         }
     }
+    
+    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)
@@ -354,6 +373,7 @@
 
     public String lookupJavanameForQName(QName qname, int kind)
     {
+       // TODO: Want to return user type java name if applicable
         switch (kind)
         {
         case QNAME_TYPE:
@@ -367,6 +387,15 @@
         }
         return null;
     }
+    
+
+    public UserType lookupUserTypeForQName(QName qname)
+    {
+        if (qname == null)
+            return null;
+
+        return (UserType) _userTypes.get(qname);
+    }
 
     public InterfaceExtension[] getInterfaceExtensions()
     {
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java   Sun Mar 
15 02:36:29 2009 -0500
@@ -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;
+       }
+
+
+}
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlpublic/org/apache/xmlbeans/BindingConfig.java
--- a/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java      Sun Mar 22 
15:07:07 2009 -0500
+++ b/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java      Sun Mar 15 
02:36:29 2009 -0500
@@ -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;
@@ -84,5 +85,16 @@
      * type generated from schema compilation or null.
      */
     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; }
+    
 
 }
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java
--- a/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java     Sun Mar 22 
15:07:07 2009 -0500
+++ b/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java     Sun Mar 15 
02:36:29 2009 -0500
@@ -210,6 +210,9 @@
     static final int JAVA_ENUM = 18;
     /** 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,
diff -r 5471ba2f2541 -r 1a589b49b118 
src/xmlpublic/org/apache/xmlbeans/UserType.java
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xmlpublic/org/apache/xmlbeans/UserType.java   Sun Mar 15 02:36:29 
2009 -0500
@@ -0,0 +1,28 @@
+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();
+       
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@xmlbeans.apache.org
For additional commands, e-mail: dev-h...@xmlbeans.apache.org

Reply via email to