jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r157342 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype: ChildItemDef.java NodeTypeDefStore.java xml/ xml/AdditionalNamespaceResolver.java xml/CommonFormat.java xml/ItemDefFormat.java xml/NodeDefFormat.java xml/NodeTypeFormat.java xml/PropDefFormat.java
Date Sun, 13 Mar 2005 16:35:40 GMT
Author: jukka
Date: Sun Mar 13 08:35:37 2005
New Revision: 157342

URL: http://svn.apache.org/viewcvs?view=rev&rev=157342
Log:
Refactored nodetype XML handling (preparing for JCR-54)

The load and store methods in NodeTypeDefStore are now implemented
using separate formatter classes in the new o.a.j.core.nodetype.xml
package. The changes are highly localized, pass all unit tests, and
have little externally visible effects.

The externally visible changes are:

   * Much more strict XML validation (missing or mistyped attributes
     now cause exceptions instead of backing up to default values)
   * Exception messages and root causes may be different
   * The ChildItemDef class is public

The changes have been approved by Stefan.

In addition to cleaning and documenting existing functionality, this
change also prepares for the work of removing the JDOM dependency as
discussed in JCR-54.

Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java
Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ChildItemDef.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ChildItemDef.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ChildItemDef.java?view=diff&r1=157341&r2=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ChildItemDef.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/ChildItemDef.java Sun Mar 13 08:35:37 2005
@@ -25,7 +25,7 @@
 /**
  * An <code>ItemDef</code> ...
  */
-abstract class ChildItemDef implements Cloneable {
+public abstract class ChildItemDef implements Cloneable {
 
     // '*' denoting residual child item definition
     protected static final QName ANY_NAME =

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java?view=diff&r1=157341&r2=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java Sun Mar 13 08:35:37 2005
@@ -16,38 +16,30 @@
  */
 package org.apache.jackrabbit.core.nodetype;
 
-import org.apache.jackrabbit.core.BaseException;
-import org.apache.jackrabbit.core.Constants;
-import org.apache.jackrabbit.core.InternalValue;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.jcr.RepositoryException;
+
 import org.apache.jackrabbit.core.NamespaceRegistryImpl;
 import org.apache.jackrabbit.core.NamespaceResolver;
-import org.apache.jackrabbit.core.NoPrefixDeclaredException;
 import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeFormat;
+import org.apache.jackrabbit.core.nodetype.xml.AdditionalNamespaceResolver;
 import org.apache.log4j.Logger;
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.JDOMException;
 import org.jdom.Namespace;
-import org.jdom.filter.ContentFilter;
-import org.jdom.filter.Filter;
 import org.jdom.input.SAXBuilder;
 import org.jdom.output.Format;
 import org.jdom.output.XMLOutputter;
 
-import javax.jcr.NamespaceException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.OnParentVersionAction;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
 /**
  * <code>NodeTypeDefStore</code> ...
  */
@@ -55,31 +47,6 @@
     private static Logger log = Logger.getLogger(NodeTypeDefStore.class);
 
     private static final String ROOT_ELEMENT = "nodeTypes";
-    private static final String NODETYPE_ELEMENT = "nodeType";
-    private static final String NAME_ATTRIBUTE = "name";
-    private static final String ISMIXIN_ATTRIBUTE = "isMixin";
-    private static final String HASORDERABLECHILDNODES_ATTRIBUTE = "hasOrderableChildNodes";
-    private static final String PRIMARYITEMNAME_ATTRIBUTE = "primaryItemName";
-    private static final String SUPERTYPES_ELEMENT = "supertypes";
-    private static final String SUPERTYPE_ELEMENT = "supertype";
-    private static final String PROPERTYDEF_ELEMENT = "propertyDef";
-    private static final String REQUIREDTYPE_ATTRIBUTE = "requiredType";
-    private static final String VALUECONSTRAINTS_ELEMENT = "valueConstraints";
-    private static final String VALUECONSTRAINT_ELEMENT = "valueConstraint";
-    private static final String DEFAULTVALUES_ELEMENT = "defaultValues";
-    private static final String DEFAULTVALUE_ELEMENT = "defaultValue";
-    private static final String AUTOCREATE_ATTRIBUTE = "autoCreate";
-    private static final String MANDATORY_ATTRIBUTE = "mandatory";
-    private static final String PROTECTED_ATTRIBUTE = "protected";
-    private static final String MULTIPLE_ATTRIBUTE = "multiple";
-    private static final String SAMENAMESIBS_ATTRIBUTE = "sameNameSibs";
-    private static final String ONPARENTVERSION_ATTRIBUTE = "onParentVersion";
-    private static final String CHILDNODEDEF_ELEMENT = "childNodeDef";
-    private static final String REQUIREDPRIMARYTYPES_ELEMENT = "requiredPrimaryTypes";
-    private static final String REQUIREDPRIMARYTYPE_ELEMENT = "requiredPrimaryType";
-    private static final String DEFAULTPRIMARYTYPE_ATTRIBUTE = "defaultPrimaryType";
-
-    private static final String WILDCARD = "*";
 
     // map of node type names and node type definitions
     private HashMap ntDefs;
@@ -109,40 +76,16 @@
             log.debug(msg);
             throw new RepositoryException(msg, jde);
         }
-        // read namespace declarations of root element
-        Iterator nsIter = root.getAdditionalNamespaces().iterator();
-        final HashMap prefixToURI = new HashMap();
-        final HashMap uriToPrefix = new HashMap();
-        while (nsIter.hasNext()) {
-            Namespace ns = (Namespace) nsIter.next();
-            prefixToURI.put(ns.getPrefix(), ns.getURI());
-            uriToPrefix.put(ns.getURI(), ns.getPrefix());
-        }
-        // add default namespace (empty uri)
-        prefixToURI.put(Constants.NS_EMPTY_PREFIX, Constants.NS_DEFAULT_URI);
-        uriToPrefix.put(Constants.NS_DEFAULT_URI, Constants.NS_EMPTY_PREFIX);
-
-        NamespaceResolver nsResolver = new NamespaceResolver() {
-            public String getURI(String prefix) throws NamespaceException {
-                if (!prefixToURI.containsKey(prefix)) {
-                    throw new NamespaceException(prefix + ": unknown prefix");
-                }
-                return (String) prefixToURI.get(prefix);
-            }
-
-            public String getPrefix(String uri) throws NamespaceException {
-                if (!uriToPrefix.containsKey(uri)) {
-                    throw new NamespaceException(uri + ": unknown URI");
-                }
-                return (String) uriToPrefix.get(uri);
-            }
-        };
 
         // read definitions
-        Iterator iter = root.getChildren(NODETYPE_ELEMENT).iterator();
+        NamespaceResolver resolver = new AdditionalNamespaceResolver(root);
+        Iterator iter =
+            root.getChildren(NodeTypeFormat.NODETYPE_ELEMENT).iterator();
         while (iter.hasNext()) {
-            NodeTypeDef ntDef = readDef((Element) iter.next(), nsResolver);
-            add(ntDef);
+            NodeTypeFormat format =
+                new NodeTypeFormat(resolver, (Element) iter.next());
+            format.read();
+            add(format.getNodeType());
         }
     }
 
@@ -170,10 +113,10 @@
         // node type definitions
         Iterator iter = all().iterator();
         while (iter.hasNext()) {
-            NodeTypeDef ntd = (NodeTypeDef) iter.next();
-            Element ntElem = new Element(NODETYPE_ELEMENT);
-            writeDef(ntd, ntElem, nsReg);
-            root.addContent(ntElem);
+            NodeTypeFormat format =
+                new NodeTypeFormat(nsReg, (NodeTypeDef) iter.next());
+            format.write();
+            root.addContent(format.getElement());
         }
 
         XMLOutputter serializer = new XMLOutputter(Format.getPrettyFormat());
@@ -225,404 +168,4 @@
         return Collections.unmodifiableCollection(ntDefs.values());
     }
 
-    //------------------------------------------------------< private methods >
-    private NodeTypeDef readDef(Element ntElem, NamespaceResolver nsResolver)
-            throws InvalidNodeTypeDefException {
-        String sntName = ntElem.getAttributeValue(NAME_ATTRIBUTE);
-        NodeTypeDef ntDef = new NodeTypeDef();
-
-        // name
-        QName qntName;
-        try {
-            qntName = QName.fromJCRName(sntName, nsResolver);
-        } catch (BaseException e) {
-            String msg = "invalid serialized node type definition [" + sntName + "]: invalid node type name: " + sntName;
-            log.debug(msg);
-            throw new InvalidNodeTypeDefException(msg, e);
-        }
-        ntDef.setName(qntName);
-
-        // supertypes
-        ArrayList list = new ArrayList();
-        Element typesElem = ntElem.getChild(SUPERTYPES_ELEMENT);
-        if (typesElem != null) {
-            Iterator iter = typesElem.getChildren(SUPERTYPE_ELEMENT).iterator();
-            while (iter.hasNext()) {
-                Element typeElem = (Element) iter.next();
-                Filter filter = new ContentFilter(ContentFilter.TEXT | ContentFilter.CDATA);
-                List content = typeElem.getContent(filter);
-                if (!content.isEmpty()) {
-                    String name = typeElem.getTextTrim();
-                    try {
-                        list.add(QName.fromJCRName(name, nsResolver));
-                    } catch (BaseException e) {
-                        String msg = "invalid serialized node type definition [" + sntName + "]: invalid supertype: " + name;
-                        log.debug(msg);
-                        throw new InvalidNodeTypeDefException(msg, e);
-                    }
-                }
-            }
-            if (!list.isEmpty()) {
-                ntDef.setSupertypes((QName[]) list.toArray(new QName[list.size()]));
-            }
-        }
-
-        // isMixin
-        String mixin = ntElem.getAttributeValue(ISMIXIN_ATTRIBUTE);
-        if (mixin != null && mixin.length() > 0) {
-            ntDef.setMixin(Boolean.valueOf(mixin).booleanValue());
-        }
-
-        // orderableChildNodes
-        String orderableChildNodes = ntElem.getAttributeValue(HASORDERABLECHILDNODES_ATTRIBUTE);
-        if (orderableChildNodes != null && orderableChildNodes.length() > 0) {
-            ntDef.setOrderableChildNodes(Boolean.valueOf(orderableChildNodes).booleanValue());
-        }
-
-        // primaryItemName
-        String primaryItemName = ntElem.getAttributeValue(PRIMARYITEMNAME_ATTRIBUTE);
-        if (primaryItemName != null && primaryItemName.length() > 0) {
-            try {
-                ntDef.setPrimaryItemName(QName.fromJCRName(primaryItemName, nsResolver));
-            } catch (BaseException e) {
-                String msg = "invalid serialized node type definition [" + sntName + "]: invalid primaryItemName: " + primaryItemName;
-                log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg, e);
-            }
-        }
-
-        // property definitions
-        list.clear();
-        Iterator iter = ntElem.getChildren(PROPERTYDEF_ELEMENT).iterator();
-        while (iter.hasNext()) {
-            Element elem = (Element) iter.next();
-            PropDef pd = new PropDef();
-            // declaring node type
-            pd.setDeclaringNodeType(qntName);
-            // name
-            String propName = elem.getAttributeValue(NAME_ATTRIBUTE);
-            if (propName != null && !propName.equals(WILDCARD)) {
-                try {
-                    pd.setName(QName.fromJCRName(propName, nsResolver));
-                } catch (BaseException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid property name: " + propName;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            } else {
-                pd.setName(ChildItemDef.ANY_NAME);
-            }
-            // requiredType
-            String typeName = elem.getAttributeValue(REQUIREDTYPE_ATTRIBUTE);
-            int type = PropertyType.UNDEFINED;
-            if (typeName != null && typeName.length() > 0) {
-                try {
-                    type = PropertyType.valueFromName(typeName);
-                    pd.setRequiredType(type);
-                } catch (IllegalArgumentException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid type: " + typeName;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            }
-            // valueConstraints
-            Element constraintsElem = elem.getChild(VALUECONSTRAINTS_ELEMENT);
-            if (constraintsElem != null) {
-                ArrayList list1 = new ArrayList();
-                Iterator iter1 = constraintsElem.getChildren(VALUECONSTRAINT_ELEMENT).iterator();
-                while (iter1.hasNext()) {
-                    Element constraintElem = (Element) iter1.next();
-                    Filter filter = new ContentFilter(ContentFilter.TEXT | ContentFilter.CDATA);
-                    List content = constraintElem.getContent(filter);
-                    if (!content.isEmpty()) {
-                        String constraint = constraintElem.getTextTrim();
-                        try {
-                            list1.add(ValueConstraint.create(type, constraint, nsResolver));
-                        } catch (InvalidConstraintException e) {
-                            String msg = "invalid serialized node type definition [" + sntName + "]: invalid constraint: " + constraint;
-                            log.debug(msg);
-                            throw new InvalidNodeTypeDefException(msg, e);
-                        }
-                    }
-                }
-                if (!list1.isEmpty()) {
-                    pd.setValueConstraints((ValueConstraint[]) list1.toArray(new ValueConstraint[list1.size()]));
-                }
-            }
-            // defaultValues
-            Element defValuesElem = elem.getChild(DEFAULTVALUES_ELEMENT);
-            if (defValuesElem != null) {
-                int defValType = (type == PropertyType.UNDEFINED) ? PropertyType.STRING : type;
-                ArrayList list1 = new ArrayList();
-                Iterator iter1 = defValuesElem.getChildren(DEFAULTVALUE_ELEMENT).iterator();
-                while (iter1.hasNext()) {
-                    Element valueElem = (Element) iter1.next();
-                    Filter filter = new ContentFilter(ContentFilter.TEXT | ContentFilter.CDATA);
-                    List content = valueElem.getContent(filter);
-                    if (!content.isEmpty()) {
-                        String defValue = valueElem.getTextTrim();
-                        try {
-                            list1.add(InternalValue.valueOf(defValue, defValType));
-                        } catch (IllegalArgumentException e) {
-                            String msg = "invalid serialized node type definition [" + sntName + "]: invalid defaultValue: " + defValue;
-                            log.debug(msg);
-                            throw new InvalidNodeTypeDefException(msg, e);
-                        }
-                    }
-                }
-                if (!list1.isEmpty()) {
-                    pd.setDefaultValues((InternalValue[]) list1.toArray(new InternalValue[list1.size()]));
-                }
-            }
-            // autoCreate
-            String autoCreate = elem.getAttributeValue(AUTOCREATE_ATTRIBUTE);
-            if (autoCreate != null && autoCreate.length() > 0) {
-                pd.setAutoCreate(Boolean.valueOf(autoCreate).booleanValue());
-            }
-            // mandatory
-            String mandatory = elem.getAttributeValue(MANDATORY_ATTRIBUTE);
-            if (mandatory != null && mandatory.length() > 0) {
-                pd.setMandatory(Boolean.valueOf(mandatory).booleanValue());
-            }
-            // onParentVersion
-            String onVersion = elem.getAttributeValue(ONPARENTVERSION_ATTRIBUTE);
-            if (onVersion != null && onVersion.length() > 0) {
-                try {
-                    pd.setOnParentVersion(OnParentVersionAction.valueFromName(onVersion));
-                } catch (IllegalArgumentException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid onVersion: " + onVersion;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            }
-            // protected
-            String writeProtected = elem.getAttributeValue(PROTECTED_ATTRIBUTE);
-            if (writeProtected != null && writeProtected.length() > 0) {
-                pd.setProtected(Boolean.valueOf(writeProtected).booleanValue());
-            }
-            // multiple
-            String multiple = elem.getAttributeValue(MULTIPLE_ATTRIBUTE);
-            if (multiple != null && multiple.length() > 0) {
-                pd.setMultiple(Boolean.valueOf(multiple).booleanValue());
-            }
-
-            list.add(pd);
-        }
-        if (!list.isEmpty()) {
-            ntDef.setPropertyDefs((PropDef[]) list.toArray(new PropDef[list.size()]));
-        }
-
-        // child-node definitions
-        list.clear();
-        iter = ntElem.getChildren(CHILDNODEDEF_ELEMENT).iterator();
-        while (iter.hasNext()) {
-            Element elem = (Element) iter.next();
-            ChildNodeDef cnd = new ChildNodeDef();
-            // declaring node type
-            cnd.setDeclaringNodeType(qntName);
-            // name
-            String nodeName = elem.getAttributeValue(NAME_ATTRIBUTE);
-            if (nodeName != null && !nodeName.equals(WILDCARD)) {
-                try {
-                    cnd.setName(QName.fromJCRName(nodeName, nsResolver));
-                } catch (BaseException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid child node name: " + nodeName;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            } else {
-                cnd.setName(ChildItemDef.ANY_NAME);
-            }
-            // requiredPrimaryTypes
-            Element reqTtypesElem = elem.getChild(REQUIREDPRIMARYTYPES_ELEMENT);
-            if (reqTtypesElem != null) {
-                ArrayList list1 = new ArrayList();
-                Iterator iter1 = reqTtypesElem.getChildren(REQUIREDPRIMARYTYPE_ELEMENT).iterator();
-                while (iter1.hasNext()) {
-                    Element typeElem = (Element) iter1.next();
-                    Filter filter = new ContentFilter(ContentFilter.TEXT | ContentFilter.CDATA);
-                    List content = typeElem.getContent(filter);
-                    if (!content.isEmpty()) {
-                        String name = typeElem.getTextTrim();
-                        try {
-                            list1.add(QName.fromJCRName(name, nsResolver));
-                        } catch (BaseException e) {
-                            String msg = "invalid serialized node type definition [" + sntName + "]: invalid requiredPrimaryType: " + name;
-                            log.debug(msg);
-                            throw new InvalidNodeTypeDefException(msg, e);
-                        }
-                    }
-                }
-                if (!list1.isEmpty()) {
-                    cnd.setRequiredPrimaryTypes((QName[]) list1.toArray(new QName[list1.size()]));
-                }
-            }
-            // defaultPrimaryType
-            String defaultPrimaryType = elem.getAttributeValue(DEFAULTPRIMARYTYPE_ATTRIBUTE);
-            if (defaultPrimaryType != null && defaultPrimaryType.length() > 0) {
-                try {
-                    cnd.setDefaultPrimaryType(QName.fromJCRName(defaultPrimaryType, nsResolver));
-                } catch (BaseException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid defaultPrimaryType: " + defaultPrimaryType;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            }
-            // autoCreate
-            String autoCreate = elem.getAttributeValue(AUTOCREATE_ATTRIBUTE);
-            if (autoCreate != null && autoCreate.length() > 0) {
-                cnd.setAutoCreate(Boolean.valueOf(autoCreate).booleanValue());
-            }
-            // mandatory
-            String mandatory = elem.getAttributeValue(MANDATORY_ATTRIBUTE);
-            if (mandatory != null && mandatory.length() > 0) {
-                cnd.setMandatory(Boolean.valueOf(mandatory).booleanValue());
-            }
-            // onParentVersion
-            String onVersion = elem.getAttributeValue(ONPARENTVERSION_ATTRIBUTE);
-            if (onVersion != null && onVersion.length() > 0) {
-                try {
-                    cnd.setOnParentVersion(OnParentVersionAction.valueFromName(onVersion));
-                } catch (IllegalArgumentException e) {
-                    String msg = "invalid serialized node type definition [" + sntName + "]: invalid onVersion: " + onVersion;
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg, e);
-                }
-            }
-            // protected
-            String writeProtected = elem.getAttributeValue(PROTECTED_ATTRIBUTE);
-            if (writeProtected != null && writeProtected.length() > 0) {
-                cnd.setProtected(Boolean.valueOf(writeProtected).booleanValue());
-            }
-            // sameNameSibs
-            String sameNameSibs = elem.getAttributeValue(SAMENAMESIBS_ATTRIBUTE);
-            if (sameNameSibs != null && sameNameSibs.length() > 0) {
-                cnd.setAllowSameNameSibs(Boolean.valueOf(sameNameSibs).booleanValue());
-            }
-
-            list.add(cnd);
-        }
-        if (!list.isEmpty()) {
-            ntDef.setChildNodeDefs((ChildNodeDef[]) list.toArray(new ChildNodeDef[list.size()]));
-        }
-
-        return ntDef;
-    }
-
-    private void writeDef(NodeTypeDef ntd, Element ntElem, NamespaceResolver nsResolver)
-            throws RepositoryException {
-        try {
-            // name
-            ntElem.setAttribute(NAME_ATTRIBUTE, ntd.getName().toJCRName(nsResolver));
-
-            // supertypes
-            QName[] qNames = ntd.getSupertypes();
-            if (qNames.length != 0) {
-                Element typesElem = new Element(SUPERTYPES_ELEMENT);
-                ntElem.addContent(typesElem);
-                for (int i = 0; i < qNames.length; i++) {
-                    Element typeElem = new Element(SUPERTYPE_ELEMENT);
-                    typesElem.addContent(typeElem);
-                    typeElem.setText(qNames[i].toJCRName(nsResolver));
-                }
-            }
-
-            // isMixin
-            ntElem.setAttribute(ISMIXIN_ATTRIBUTE, Boolean.toString(ntd.isMixin()));
-
-            // orderableChildNodes
-            ntElem.setAttribute(HASORDERABLECHILDNODES_ATTRIBUTE, Boolean.toString(ntd.hasOrderableChildNodes()));
-
-            // primaryItemName
-            String primaryItemName = ntd.getPrimaryItemName() == null ? "" : ntd.getPrimaryItemName().toJCRName(nsResolver);
-            ntElem.setAttribute(PRIMARYITEMNAME_ATTRIBUTE, primaryItemName);
-
-            // property definitions
-            PropDef[] pda = ntd.getPropertyDefs();
-            for (int i = 0; i < pda.length; i++) {
-                PropDef pd = pda[i];
-                Element elem = new Element(PROPERTYDEF_ELEMENT);
-                ntElem.addContent(elem);
-
-                // name
-                String name = pd.definesResidual() ? WILDCARD : pd.getName().toJCRName(nsResolver);
-                elem.setAttribute(NAME_ATTRIBUTE, name);
-                // requiredType
-                elem.setAttribute(REQUIREDTYPE_ATTRIBUTE, PropertyType.nameFromValue(pd.getRequiredType()));
-                // valueConstraints
-                ValueConstraint[] vca = pd.getValueConstraints();
-                if (vca != null && vca.length != 0) {
-                    Element constraintsElem = new Element(VALUECONSTRAINTS_ELEMENT);
-                    elem.addContent(constraintsElem);
-                    for (int j = 0; j < vca.length; j++) {
-                        Element constraintElem = new Element(VALUECONSTRAINT_ELEMENT);
-                        constraintsElem.addContent(constraintElem);
-                        constraintElem.setText(vca[j].getDefinition());
-                    }
-                }
-                // defaultValues
-                InternalValue[] defVals = pd.getDefaultValues();
-                if (defVals != null && defVals.length != 0) {
-                    Element valuesElem = new Element(DEFAULTVALUES_ELEMENT);
-                    elem.addContent(valuesElem);
-                    for (int j = 0; j < defVals.length; j++) {
-                        Element valueElem = new Element(DEFAULTVALUE_ELEMENT);
-                        valuesElem.addContent(valueElem);
-                        valueElem.setText(defVals[j].toString());
-                    }
-                }
-                // autoCreate
-                elem.setAttribute(AUTOCREATE_ATTRIBUTE, Boolean.toString(pd.isAutoCreate()));
-                // mandatory
-                elem.setAttribute(MANDATORY_ATTRIBUTE, Boolean.toString(pd.isMandatory()));
-                // onParentVersion
-                elem.setAttribute(ONPARENTVERSION_ATTRIBUTE, OnParentVersionAction.nameFromValue(pd.getOnParentVersion()));
-                // protected
-                elem.setAttribute(PROTECTED_ATTRIBUTE, Boolean.toString(pd.isProtected()));
-                // multiple
-                elem.setAttribute(MULTIPLE_ATTRIBUTE, Boolean.toString(pd.isMultiple()));
-            }
-
-            // child-node definitions
-            ChildNodeDef[] nda = ntd.getChildNodeDefs();
-            for (int i = 0; i < nda.length; i++) {
-                ChildNodeDef nd = nda[i];
-                Element elem = new Element(CHILDNODEDEF_ELEMENT);
-                ntElem.addContent(elem);
-
-                // name
-                String name = nd.definesResidual() ? WILDCARD : nd.getName().toJCRName(nsResolver);
-                elem.setAttribute(NAME_ATTRIBUTE, name);
-                // requiredPrimaryTypes
-                qNames = nd.getRequiredPrimaryTypes();
-                if (qNames.length != 0) {
-                    Element typesElem = new Element(REQUIREDPRIMARYTYPES_ELEMENT);
-                    elem.addContent(typesElem);
-                    for (int j = 0; j < qNames.length; j++) {
-                        Element typeElem = new Element(REQUIREDPRIMARYTYPE_ELEMENT);
-                        typesElem.addContent(typeElem);
-                        typeElem.setText(qNames[j].toJCRName(nsResolver));
-                    }
-                }
-                // defaultPrimaryType
-                String defaultPrimaryType = nd.getDefaultPrimaryType() == null ? "" : nd.getDefaultPrimaryType().toJCRName(nsResolver);
-                elem.setAttribute(DEFAULTPRIMARYTYPE_ATTRIBUTE, defaultPrimaryType);
-                // autoCreate
-                elem.setAttribute(AUTOCREATE_ATTRIBUTE, Boolean.toString(nd.isAutoCreate()));
-                // mandatory
-                elem.setAttribute(MANDATORY_ATTRIBUTE, Boolean.toString(nd.isMandatory()));
-                // onParentVersion
-                elem.setAttribute(ONPARENTVERSION_ATTRIBUTE, OnParentVersionAction.nameFromValue(nd.getOnParentVersion()));
-                // protected
-                elem.setAttribute(PROTECTED_ATTRIBUTE, Boolean.toString(nd.isProtected()));
-                // sameNameSibs
-                elem.setAttribute(SAMENAMESIBS_ATTRIBUTE, Boolean.toString(nd.allowSameNameSibs()));
-            }
-        } catch (NoPrefixDeclaredException npde) {
-            // should never get here...
-            String msg = "internal error: encountered unregistered namespace";
-            log.debug(msg);
-            throw new RepositoryException(msg, npde);
-        }
-    }
 }

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.jcr.NamespaceException;
+
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * A simple namespace resolver implementation, that uses the additional
+ * namespaces declared in an XML element.
+ */
+public class AdditionalNamespaceResolver implements NamespaceResolver {
+
+    /** Map from namespace prefixes to namespace URIs. */
+    private final Properties prefixToURI = new Properties();
+
+    /** Map from namespace URIs to namespace prefixes. */
+    private final Properties uriToPrefix = new Properties();
+
+    /**
+     * Creates a namespace resolver using the additional namespaces declared
+     * in the given XML element.
+     *
+     * @param element XML element
+     */
+    public AdditionalNamespaceResolver(Element element) {
+        Iterator namespaces = element.getAdditionalNamespaces().iterator();
+        while (namespaces.hasNext()) {
+            Namespace namespace = (Namespace) namespaces.next();
+            addNamespace(namespace.getPrefix(), namespace.getURI());
+        }
+
+        addNamespace(Constants.NS_EMPTY_PREFIX, Constants.NS_DEFAULT_URI);
+    }
+
+    /**
+     * Adds the given namespace declaration to this resolver.
+     *
+     * @param prefix namespace prefix
+     * @param uri namespace URI
+     */
+    private void addNamespace(String prefix, String uri) {
+        prefixToURI.put(prefix, uri);
+        uriToPrefix.put(uri, prefix);
+    }
+
+    /** {@inheritDoc} */
+    public String getURI(String prefix) throws NamespaceException {
+        String uri = prefixToURI.getProperty(prefix);
+        if (uri != null) {
+            return uri;
+        } else {
+            throw new NamespaceException(
+                    "Unknown namespace prefix " + prefix + ".");
+        }
+    }
+
+    /** {@inheritDoc} */
+    public String getPrefix(String uri) throws NamespaceException {
+        String prefix = uriToPrefix.getProperty(uri);
+        if (prefix != null) {
+            return prefix;
+        } else {
+            throw new NamespaceException(
+                    "Unknown namespace URI " + uri + ".");
+        }
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/CommonFormat.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import java.util.Iterator;
+
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.IllegalNameException;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.NoPrefixDeclaredException;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.UnknownPrefixException;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.jdom.Element;
+
+/**
+ * Common functionality shared by the format classes.
+ */
+class CommonFormat {
+
+    /** Name of the <code>name</code> attribute. */
+    private static final String NAME_ATTRIBUTE = "name";
+
+    /** The wildcard name */
+    private static final String WILDCARD = "*";
+
+    /** The namespace resolver. */
+    private final NamespaceResolver resolver;
+
+    /** The formatted XML element. */
+    private final Element element;
+
+    /**
+     * Creates a common format object.
+     *
+     * @param resolver namespace resolver
+     * @param element XML element
+     */
+    protected CommonFormat(NamespaceResolver resolver, Element element) {
+        this.resolver = resolver;
+        this.element = element;
+    }
+
+    /**
+     * Returns the namespace resolver associated with this format instance.
+     *
+     * @return namespace resolver
+     */
+    protected NamespaceResolver getNamespaceResolver() {
+        return resolver;
+    }
+
+    /**
+     * Returns the formatted XML element.
+     *
+     * @return XML element
+     */
+    public Element getElement() {
+        return element;
+    }
+
+    /**
+     * Converts the given JCR name to a qualified name using the associated
+     * namespace resolver.
+     *
+     * @param name JCR name
+     * @return qualified name
+     * @throws InvalidNodeTypeDefException if the name is invalid
+     */
+    protected QName fromJCRName(String name)
+            throws InvalidNodeTypeDefException {
+        try {
+            if (WILDCARD.equals(name)) {
+                return new QName(Constants.NS_DEFAULT_URI, WILDCARD);
+            } else {
+                return QName.fromJCRName(name, resolver);
+            }
+        } catch (IllegalNameException e) {
+            throw new InvalidNodeTypeDefException(
+                    "Illegal JCR name " + name, e);
+        } catch (UnknownPrefixException e) {
+            throw new InvalidNodeTypeDefException(
+                    "Unknown prefix in JCR name " + name, e);
+        }
+    }
+
+    /**
+     * Converts the given qualified name to a JCR name using the associated
+     * namespace resolver.
+     * <p>
+     * This method throws an IllegalArgumentException if the given qualified
+     * name cannot be represented as a JCR name. This problem should never
+     * happen in normal circumstances, and callers may safely ignore the
+     * exception.
+     *
+     * @param name qualified name
+     * @return JCR name
+     * @throws IllegalArgumentException if the name is invalid
+     */
+    protected String toJCRName(QName name) throws IllegalArgumentException {
+        try {
+            return name.toJCRName(resolver);
+        } catch (NoPrefixDeclaredException e) {
+            throw new IllegalArgumentException(
+                    "No prefix declared for namespace "
+                    + name.getNamespaceURI());
+        }
+    }
+
+    /**
+     * Returns the value of the named attribute of the XML element.
+     *
+     * @param name attribute name
+     * @return attribute value
+     * @throws InvalidNodeTypeDefException if the attribute does not exist
+     */
+    protected String getAttribute(String name) throws InvalidNodeTypeDefException {
+        String value = element.getAttributeValue(name);
+        if (value != null) {
+            return value;
+        } else {
+            throw new InvalidNodeTypeDefException(
+                    "Missing attribute " + name
+                    + " in element " + element.getName());
+        }
+    }
+
+    /**
+     * Sets the named attribute of the XML element.
+     *
+     * @param name attribute name
+     * @param value attribute value
+     */
+    protected void setAttribute(String name, String value) {
+        element.setAttribute(name, value);
+    }
+
+    /**
+     * Returns the named child element of the XML element.
+     *
+     * @param name child element name
+     * @return child element
+     */
+    protected Element getChild(String name) {
+        return element.getChild(name);
+    }
+
+    /**
+     * Returns an iterator of all the named child elements of the XML element.
+     *
+     * @param name child element name
+     * @return child element iterator
+     */
+    protected Iterator getChildIterator(String name) {
+        return element.getChildren(name).iterator();
+    }
+
+    /**
+     * Adds the given child element to the XML element.
+     *
+     * @param child child element
+     */
+    protected void addChild(Element child) {
+        element.addContent(child);
+    }
+
+    /**
+     * Returns the qualified name stored as the <code>name</code> attribute.
+     *
+     * @return qualified name
+     * @throws InvalidNodeTypeDefException if the format of the XML
+     *                                    element is invalid
+     */
+    protected QName getName() throws InvalidNodeTypeDefException {
+        return fromJCRName(getAttribute(NAME_ATTRIBUTE));
+    }
+
+    /**
+     * Sets the given name as the <code>name</code> attribute.
+     *
+     * @param name qualified name
+     */
+    protected void setName(QName name) {
+        setAttribute(NAME_ATTRIBUTE, toJCRName(name));
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/ItemDefFormat.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import javax.jcr.version.OnParentVersionAction;
+
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.nodetype.ChildItemDef;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.jdom.Element;
+
+/**
+ * Common functionality shared by the property and node definition format
+ * classes.
+ */
+class ItemDefFormat extends CommonFormat {
+
+    /** Name of the <code>autoCreate</code> attribute. */
+    private static final String AUTOCREATE_ATTRIBUTE = "autoCreate";
+
+    /** Name of the <code>mandatory</code> attribute. */
+    private static final String MANDATORY_ATTRIBUTE = "mandatory";
+
+    /** Name of the <code>onParentVersion</code> attribute. */
+    private static final String ONPARENTVERSION_ATTRIBUTE = "onParentVersion";
+
+    /** Name of the <code>protected</code> attribute. */
+    private static final String PROTECTED_ATTRIBUTE = "protected";
+
+    /** The child item definition. */
+    private final ChildItemDef def;
+
+    /**
+     * Creates a child item definition format object.
+     *
+     * @param resolver namespace resolver
+     * @param element child item definition element
+     * @param def child item definition
+     */
+    protected ItemDefFormat(
+            NamespaceResolver resolver, Element element, ChildItemDef def) {
+        super(resolver, element);
+        this.def = def;
+    }
+
+    /**
+     * Reads the item definition from the XML element.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    protected void read() throws InvalidNodeTypeDefException {
+        readName();
+        readAutoCreate();
+        readMandatory();
+        readOnParentVersion();
+        readProtected();
+    }
+
+    /**
+     * Writes the item definition to the XML element.
+     */
+    protected void write() {
+        writeName();
+        writeAutoCreate();
+        writeMandatory();
+        writeOnParentVersion();
+        writeProtected();
+    }
+
+    /**
+     * Reads and sets the name of the item definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    private void readName() throws InvalidNodeTypeDefException {
+        def.setName(getName());
+    }
+
+    /**
+     * Writes the name of the item definition.
+     */
+    private void writeName() {
+        setName(def.getName());
+    }
+
+    /**
+     * Reads and sets the <code>autoCreate</code> attribute of the
+     * item definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    private void readAutoCreate() throws InvalidNodeTypeDefException {
+        String value = getAttribute(AUTOCREATE_ATTRIBUTE);
+        def.setAutoCreate(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>autoCreate</code> attribute of the item
+     * definition.
+     */
+    private void writeAutoCreate() {
+        String value = Boolean.toString(def.isAutoCreate());
+        setAttribute(AUTOCREATE_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the <code>mandatory</code> attribute of the
+     * item definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    private void readMandatory() throws InvalidNodeTypeDefException {
+        String value = getAttribute(MANDATORY_ATTRIBUTE);
+        def.setMandatory(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>mandatory</code> attribute of the item definition.
+     */
+    private void writeMandatory() {
+        String value = Boolean.toString(def.isMandatory());
+        setAttribute(MANDATORY_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the <code>onParentVersion</code> attribute of the
+     * item definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    private void readOnParentVersion() throws InvalidNodeTypeDefException {
+        String value = getAttribute(ONPARENTVERSION_ATTRIBUTE);
+        def.setOnParentVersion(OnParentVersionAction.valueFromName(value));
+    }
+
+    /**
+     * Writes the <code>onParentVersion</code> attribute of the item
+     * definition.
+     */
+    private void writeOnParentVersion() {
+        String value =
+            OnParentVersionAction.nameFromValue(def.getOnParentVersion());
+        setAttribute(ONPARENTVERSION_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the <code>protected</code> attribute of the
+     * item definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the item
+     *                                    definition element is invalid
+     */
+    private void readProtected() throws InvalidNodeTypeDefException {
+        String value = getAttribute(PROTECTED_ATTRIBUTE);
+        def.setProtected(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>protected</code> attribute of the item definition.
+     */
+    private void writeProtected() {
+        String value = Boolean.toString(def.isProtected());
+        setAttribute(PROTECTED_ATTRIBUTE, value);
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeDefFormat.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.jdom.Element;
+
+/**
+ * Utility class for reading and writing node definition XML elements.
+ */
+class NodeDefFormat extends ItemDefFormat {
+
+    /** Name of the child node definition element. */
+    public static final String CHILDNODEDEF_ELEMENT = "childNodeDef";
+
+    /** Name of the required primary types element. */
+    private static final String REQUIREDPRIMARYTYPES_ELEMENT =
+        "requiredPrimaryTypes";
+
+    /** Name of the required primary type element. */
+    private static final String REQUIREDPRIMARYTYPE_ELEMENT =
+        "requiredPrimaryType";
+
+    /** Name of the default primary type attribute. */
+    private static final String DEFAULTPRIMARYTYPE_ATTRIBUTE =
+        "defaultPrimaryType";
+
+    /** Name of the <code>sameNameSibs</code> attribute. */
+    private static final String SAMENAMESIBS_ATTRIBUTE = "sameNameSibs";
+
+    /** The node definition. */
+    private final ChildNodeDef def;
+
+    /**
+     * Creates a node definition format object. This constructor
+     * is used internally by the public reader and writer constructors.
+     *
+     * @param resolver namespace resolver
+     * @param element node definition element
+     * @param def node definition
+     */
+    private NodeDefFormat(
+            NamespaceResolver resolver, Element element, ChildNodeDef def) {
+        super(resolver, element, def);
+        this.def = def;
+    }
+
+    /**
+     * Creates a node definition reader. An empty node definition instance
+     * is created. The instance properties are filled in by the
+     * {@link #read(QName) read} method.
+     *
+     * @param resolver namespace resolver
+     * @param element node definition element
+     */
+    public NodeDefFormat(NamespaceResolver resolver, Element element) {
+        this(resolver, element, new ChildNodeDef());
+    }
+
+    /**
+     * Creates a node definition writer. The node definition element is
+     * instantiated as an empty <code>childNodeDef</code> element.
+     * The element is filled in by the {@link #write() write} method.
+     *
+     * @param resolver namespace resolver
+     * @param def node definition
+     */
+    public NodeDefFormat(NamespaceResolver resolver, ChildNodeDef def) {
+        this(resolver, new Element(CHILDNODEDEF_ELEMENT), def);
+    }
+
+    /**
+     * Returns the node definition object.
+     *
+     * @return node definition
+     */
+    public ChildNodeDef getNodeDef() {
+        return def;
+    }
+
+    /**
+     * Reads the node definition from the XML element.
+     *
+     * @param type name of the declaring node type
+     * @throws InvalidNodeTypeDefException if the format of the node
+     *                                    definition element is invalid
+     */
+    public void read(QName type) throws InvalidNodeTypeDefException {
+        def.setDeclaringNodeType(type);
+        super.read();
+        readRequiredPrimaryTypes();
+        readDefaultPrimaryType();
+        readSameNameSibs();
+    }
+
+    /**
+     * Writes the node definition to the XML element.
+     */
+    public void write() {
+        super.write();
+        writeRequiredPrimaryTypes();
+        writeDefaultPrimaryType();
+        writeSameNameSibs();
+    }
+
+    /**
+     * Reads and sets the required primary types of the node definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node
+     *                                    definition element is invalid
+     */
+    private void readRequiredPrimaryTypes() throws InvalidNodeTypeDefException {
+        Vector vector = new Vector();
+
+        Element types = getChild(REQUIREDPRIMARYTYPES_ELEMENT);
+        if (types != null) {
+            Iterator iterator =
+                types.getChildren(REQUIREDPRIMARYTYPE_ELEMENT).iterator();
+            while (iterator.hasNext()) {
+                Element type = (Element) iterator.next();
+                vector.add(fromJCRName(type.getTextTrim()));
+            }
+        }
+
+        def.setRequiredPrimaryTypes((QName[]) vector.toArray(new QName[0]));
+    }
+
+    /**
+     * Writes the required primary types of the node definition.
+     */
+    private void writeRequiredPrimaryTypes() {
+        Element types = new Element(REQUIREDPRIMARYTYPES_ELEMENT);
+
+        QName[] values = def.getRequiredPrimaryTypes();
+        for (int i = 0; i < values.length; i++) {
+            Element type = new Element(REQUIREDPRIMARYTYPE_ELEMENT);
+            type.setText(toJCRName(values[i]));
+            types.addContent(type);
+        }
+
+        addChild(types);
+    }
+
+    /**
+     * Reads and sets the default primary type of the node definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node
+     *                                    definition element is invalid
+     */
+    private void readDefaultPrimaryType() throws InvalidNodeTypeDefException {
+        String value = getAttribute(DEFAULTPRIMARYTYPE_ATTRIBUTE);
+        if (value.length() > 0) {
+            def.setDefaultPrimaryType(fromJCRName(value));
+        }
+    }
+
+    /**
+     * Writes the default primary type of the node definition.
+     */
+    private void writeDefaultPrimaryType() {
+        QName type = def.getDefaultPrimaryType();
+        if (type != null) {
+            setAttribute(DEFAULTPRIMARYTYPE_ATTRIBUTE, toJCRName(type));
+        } else {
+            setAttribute(DEFAULTPRIMARYTYPE_ATTRIBUTE, ""); // Is this legal?
+        }
+    }
+
+    /**
+     * Reads and sets the <code>sameNameSibs</code> attribute of the
+     * node definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node
+     *                                    definition element is invalid
+     */
+    private void readSameNameSibs() throws InvalidNodeTypeDefException {
+        String value = getAttribute(SAMENAMESIBS_ATTRIBUTE);
+        def.setAllowSameNameSibs(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>sameNameSibs</code> attribute of the node definition.
+     */
+    private void writeSameNameSibs() {
+        String value = Boolean.toString(def.allowSameNameSibs());
+        setAttribute(SAMENAMESIBS_ATTRIBUTE, value);
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/NodeTypeFormat.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.jdom.Element;
+
+/**
+ * Utility class for reading and writing node type definition XML elements.
+ */
+public class NodeTypeFormat extends CommonFormat {
+
+    /** Name of the node type definition element. */
+    public static final String NODETYPE_ELEMENT = "nodeType";
+
+    /** Name of the <code>isMixin</code> attribute. */
+    private static final String ISMIXIN_ATTRIBUTE = "isMixin";
+
+    /** Name of the <code>hasOrderableChildNodes</code> attribute. */
+    private static final String HASORDERABLECHILDNODES_ATTRIBUTE =
+        "hasOrderableChildNodes";
+
+    /** Name of the primary item name attribute. */
+    private static final String PRIMARYITEMNAME_ATTRIBUTE = "primaryItemName";
+
+    /** Name of the supertypes element. */
+    private static final String SUPERTYPES_ELEMENT = "supertypes";
+
+    /** Name of the supertype element. */
+    private static final String SUPERTYPE_ELEMENT = "supertype";
+
+
+    /** The node type definition. */
+    private final NodeTypeDef def;
+
+    /**
+     * Creates a node type definition format object. This constructor
+     * is used internally by the public reader and writer constructors.
+     *
+     * @param resolver namespace resolver
+     * @param element node type definition element
+     * @param def node type definition
+     */
+    private NodeTypeFormat(
+            NamespaceResolver resolver, Element element, NodeTypeDef def) {
+        super(resolver, element);
+        this.def = def;
+    }
+
+    /**
+     * Creates a node type definition reader. An empty node type definition
+     * instance is created. The instance properties are filled in by the
+     * {@link #read() read} method.
+     *
+     * @param resolver namespace resolver
+     * @param element node type definition element
+     */
+    public NodeTypeFormat(NamespaceResolver resolver, Element element) {
+        this(resolver, element, new NodeTypeDef());
+    }
+
+    /**
+     * Creates a node type definition writer. The node type definition
+     * element is instantiated as an empty <code>nodeType</code> element.
+     * The element is filled in by the {@link #write() write} method.
+     *
+     * @param resolver namespace resolver
+     * @param def node type definition
+     */
+    public NodeTypeFormat(NamespaceResolver resolver, NodeTypeDef def) {
+        this(resolver, new Element(NODETYPE_ELEMENT), def);
+    }
+
+    /**
+     * Returns the node type definition object.
+     *
+     * @return node type definition
+     */
+    public NodeTypeDef getNodeType() {
+        return def;
+    }
+
+    /**
+     * Reads the node type definition from the XML element.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    public void read() throws InvalidNodeTypeDefException {
+        readName();
+        readSupertypes();
+        readIsMixin();
+        readOrderableChildNodes();
+        readPrimaryItemName();
+        readPropertyDefinitions();
+        readChildNodeDefinitions();
+    }
+
+    /**
+     * Writes the node type definition to the XML element.
+     */
+    public void write() {
+        writeName();
+        writeSupertypes();
+        writeIsMixin();
+        writeOrderableChildNodes();
+        writePrimaryItemName();
+        writePropertyDefinitions();
+        writeChildNodeDefinitions();
+    }
+
+    /**
+     * Reads and sets the name of the node type definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readName() throws InvalidNodeTypeDefException {
+        def.setName(getName());
+    }
+
+    /**
+     * Writes the name of the node type definition.
+     */
+    private void writeName() {
+        setName(def.getName());
+    }
+
+    /**
+     * Reads and sets the supertypes of the node type definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readSupertypes() throws InvalidNodeTypeDefException {
+        Vector vector = new Vector();
+
+        Element types = getChild(SUPERTYPES_ELEMENT);
+        if (types != null) {
+            Iterator iterator = types.getChildren(SUPERTYPE_ELEMENT).iterator();
+            while (iterator.hasNext()) {
+                Element type = (Element) iterator.next();
+                vector.add(fromJCRName(type.getTextTrim()));
+            }
+        }
+
+        def.setSupertypes((QName[]) vector.toArray(new QName[0]));
+    }
+
+    /**
+     * Writes the supertypes of the node type definition.
+     */
+    private void writeSupertypes() {
+        QName[] values = def.getSupertypes();
+        if (values.length > 0) {
+            Element types = new Element(SUPERTYPES_ELEMENT);
+            for (int i = 0; i < values.length; i++) {
+                Element type = new Element(SUPERTYPE_ELEMENT);
+                type.setText(toJCRName(values[i]));
+                types.addContent(type);
+            }
+            addChild(types);
+        }
+    }
+
+    /**
+     * Reads and sets the <code>isMixin</code> attribute of the
+     * node type definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readIsMixin() throws InvalidNodeTypeDefException {
+        String value = getAttribute(ISMIXIN_ATTRIBUTE);
+        def.setMixin(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>isMixin</code> attribute of the node type definition.
+     */
+    private void writeIsMixin() {
+        String value = Boolean.toString(def.isMixin());
+        setAttribute(ISMIXIN_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the <code>hasOrderableChildNodes</code> attribute
+     * of the node type definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readOrderableChildNodes() throws InvalidNodeTypeDefException {
+        String value = getAttribute(HASORDERABLECHILDNODES_ATTRIBUTE);
+        def.setOrderableChildNodes(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>hasOrderableChildNodes</code> attribute of
+     * the node type definition.
+     */
+    private void writeOrderableChildNodes() {
+        String value = Boolean.toString(def.hasOrderableChildNodes());
+        setAttribute(HASORDERABLECHILDNODES_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the primary item name of the node type definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readPrimaryItemName() throws InvalidNodeTypeDefException {
+        String value = getAttribute(PRIMARYITEMNAME_ATTRIBUTE);
+        if (value.length() > 0) {
+            def.setPrimaryItemName(fromJCRName(value));
+        }
+    }
+
+    /**
+     * Writes the primary item name of the node type definition.
+     */
+    private void writePrimaryItemName() {
+        String value = toJCRName(def.getPrimaryItemName());
+        setAttribute(PRIMARYITEMNAME_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the property definitions of the node type definition.
+     * <p>
+     * Note that the {@link #readName() readName} method must have been
+     * called before this method.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readPropertyDefinitions() throws InvalidNodeTypeDefException {
+        Vector vector = new Vector();
+
+        Iterator iterator = getChildIterator(PropDefFormat.PROPERTYDEF_ELEMENT);
+        while (iterator.hasNext()) {
+            PropDefFormat format = new PropDefFormat(
+                    getNamespaceResolver(), (Element) iterator.next());
+            format.read(def.getName());
+            vector.add(format.getPropDef());
+        }
+
+        def.setPropertyDefs((PropDef[]) vector.toArray(new PropDef[0]));
+    }
+
+    /**
+     * Writes the property definitions of the node type definition.
+     */
+    private void writePropertyDefinitions() {
+        PropDef[] defs = def.getPropertyDefs();
+        for (int i = 0; i < defs.length; i++) {
+            PropDefFormat format =
+                new PropDefFormat(getNamespaceResolver(), defs[i]);
+            format.write();
+            addChild(format.getElement());
+        }
+    }
+
+    /**
+     * Reads and sets the child node definitions of the node type definition.
+     * <p>
+     * Note that the {@link #readName() readName} method must have been
+     * called before this method.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the node type
+     *                                    definition element is invalid
+     */
+    private void readChildNodeDefinitions() throws InvalidNodeTypeDefException {
+        Vector vector = new Vector();
+
+        Iterator iterator =
+            getChildIterator(NodeDefFormat.CHILDNODEDEF_ELEMENT);
+        while (iterator.hasNext()) {
+            NodeDefFormat format = new NodeDefFormat(
+                    getNamespaceResolver(), (Element) iterator.next());
+            format.read(def.getName());
+            vector.add(format.getNodeDef());
+        }
+
+        def.setChildNodeDefs(
+                (ChildNodeDef[]) vector.toArray(new ChildNodeDef[0]));
+    }
+
+    /**
+     * Writes the child node definitions of the node type definition.
+     */
+    private void writeChildNodeDefinitions() {
+        ChildNodeDef[] defs = def.getChildNodeDefs();
+        for (int i = 0; i < defs.length; i++) {
+            NodeDefFormat format =
+                new NodeDefFormat(getNamespaceResolver(), defs[i]);
+            format.write();
+            addChild(format.getElement());
+        }
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java?view=auto&rev=157342
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/PropDefFormat.java Sun Mar 13 08:35:37 2005
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * 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 org.apache.jackrabbit.core.nodetype.xml;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.core.InternalValue;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.InvalidConstraintException;
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.nodetype.ValueConstraint;
+import org.jdom.Element;
+
+/**
+ * Utility class for reading and writing property definition XML elements.
+ */
+class PropDefFormat extends ItemDefFormat {
+
+    /** Name of the property definition element. */
+    public static final String PROPERTYDEF_ELEMENT = "propertyDef";
+
+    /** Name of the required type attribute. */
+    private static final String REQUIREDTYPE_ATTRIBUTE = "requiredType";
+
+    /** Name of the value constraints element. */
+    private static final String VALUECONSTRAINTS_ELEMENT = "valueConstraints";
+
+    /** Name of the value constraint element. */
+    private static final String VALUECONSTRAINT_ELEMENT = "valueConstraint";
+
+    /** Name of the default values element. */
+    private static final String DEFAULTVALUES_ELEMENT = "defaultValues";
+
+    /** Name of the default value element. */
+    private static final String DEFAULTVALUE_ELEMENT = "defaultValue";
+
+    /** Name of the <code>multiple</code> attribute. */
+    private static final String MULTIPLE_ATTRIBUTE = "multiple";
+
+    /** The property definition. */
+    private final PropDef def;
+
+    /**
+     * Creates a property definition format object. This constructor
+     * is used internally by the public reader and writer constructors.
+     *
+     * @param resolver namespace resolver
+     * @param element property definition element
+     * @param def property definition
+     */
+    private PropDefFormat(
+            NamespaceResolver resolver, Element element, PropDef def) {
+        super(resolver, element, def);
+        this.def = def;
+    }
+
+    /**
+     * Creates a property definition reader. The internal property
+     * definition instance is created using the given node type name
+     * as the name of the declaring node type.
+     *
+     * @param resolver namespace resolver
+     * @param element property definition element
+     */
+    public PropDefFormat(NamespaceResolver resolver, Element element) {
+        this(resolver, element, new PropDef());
+    }
+
+    /**
+     * Creates a property definition writer. The internal property
+     * definition element is instantiated as an empty <code>propertyDef</code>
+     * element.
+     *
+     * @param resolver namespace resolver
+     * @param def property definition
+     */
+    public PropDefFormat(NamespaceResolver resolver, PropDef def) {
+        this(resolver, new Element(PROPERTYDEF_ELEMENT), def);
+    }
+
+    /**
+     * Returns the property definition instance.
+     *
+     * @return property definition
+     */
+    public PropDef getPropDef() {
+        return def;
+    }
+
+    /**
+     * Reads the property definition from the XML element.
+     *
+     * @param type name of the declaring node type
+     * @throws InvalidNodeTypeDefException if the format of the property
+     *                                    definition element is invalid
+     */
+    public void read(QName type) throws InvalidNodeTypeDefException {
+        def.setDeclaringNodeType(type);
+        super.read();
+        readRequiredType();
+        readValueConstraints();
+        readDefaultValues();
+        readMultiple();
+    }
+
+    /**
+     * Writes the property definition to the XML element.
+     */
+    public void write() {
+        super.write();
+        writeRequiredType();
+        writeValueConstraints();
+        writeDefaultValues();
+        writeMultiple();
+    }
+
+    /**
+     * Reads and sets the required type of the property definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the property
+     *                                    definition element is invalid
+     */
+    private void readRequiredType() throws InvalidNodeTypeDefException {
+        String value = getAttribute(REQUIREDTYPE_ATTRIBUTE);
+        def.setRequiredType(PropertyType.valueFromName(value));
+    }
+
+    /**
+     * Writes the required type of the property definition.
+     */
+    private void writeRequiredType() {
+        String value = PropertyType.nameFromValue(def.getRequiredType());
+        setAttribute(REQUIREDTYPE_ATTRIBUTE, value);
+    }
+
+    /**
+     * Reads and sets the value constraints of the property definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the property
+     *                                    definition element is invalid
+     */
+    private void readValueConstraints() throws InvalidNodeTypeDefException {
+        Vector vector = new Vector();
+
+        Element constraints = getChild(VALUECONSTRAINTS_ELEMENT);
+        if (constraints != null) {
+            int type = def.getRequiredType();
+
+            Iterator iterator =
+                constraints.getChildren(VALUECONSTRAINT_ELEMENT).iterator();
+            while (iterator.hasNext()) {
+                Element constraint = (Element) iterator.next();
+                String value = constraint.getTextTrim();
+                try {
+                    vector.add(ValueConstraint.create(
+                            type, value, getNamespaceResolver()));
+                } catch (InvalidConstraintException e) {
+                    throw new InvalidNodeTypeDefException(
+                            "Invalid property value constraint " + value, e);
+                }
+            }
+        }
+
+        def.setValueConstraints(
+                (ValueConstraint[]) vector.toArray(new ValueConstraint[0]));
+    }
+
+    /**
+     * Writes the value constraints of the property definition.
+     */
+    private void writeValueConstraints() {
+        Element values = new Element(VALUECONSTRAINTS_ELEMENT);
+
+        ValueConstraint[] constraints = def.getValueConstraints();
+        for (int i = 0; i < constraints.length; i++) {
+            Element value = new Element(VALUECONSTRAINT_ELEMENT);
+            value.setText(constraints[i].getDefinition());
+            values.addContent(value);
+        }
+
+        addChild(values);
+    }
+
+    /**
+     * Reads and sets the default values of the property definition.
+     */
+    private void readDefaultValues() {
+        Vector vector = new Vector();
+
+        Element values = getChild(DEFAULTVALUES_ELEMENT);
+        if (values != null) {
+            int type = def.getRequiredType();
+            if (type == PropertyType.UNDEFINED) {
+                type = PropertyType.STRING;
+            }
+
+            Iterator iterator =
+                values.getChildren(DEFAULTVALUE_ELEMENT).iterator();
+            while (iterator.hasNext()) {
+                Element value = (Element) iterator.next();
+                vector.add(InternalValue.valueOf(value.getTextTrim(), type));
+            }
+        }
+
+        def.setDefaultValues(
+                (InternalValue[]) vector.toArray(new InternalValue[0]));
+    }
+
+    /**
+     * Writes the default values of the property definition.
+     */
+    private void writeDefaultValues() {
+        Element values = new Element(DEFAULTVALUES_ELEMENT);
+
+        InternalValue[] defaults = def.getDefaultValues();
+        for (int i = 0; i < defaults.length; i++) {
+            Element value = new Element(DEFAULTVALUE_ELEMENT);
+            value.setText(defaults[i].toString());
+            values.addContent(value);
+        }
+
+        addChild(values);
+    }
+
+    /**
+     * Reads and sets the <code>multiple</code> attribute of the
+     * property definition.
+     *
+     * @throws InvalidNodeTypeDefException if the format of the property
+     *                                    definition element is invalid
+     */
+    private void readMultiple() throws InvalidNodeTypeDefException {
+        String value = getAttribute(MULTIPLE_ATTRIBUTE);
+        def.setMultiple(Boolean.valueOf(value).booleanValue());
+    }
+
+    /**
+     * Writes the <code>multiple</code> attribute of the property definition.
+     */
+    private void writeMultiple() {
+        String value = Boolean.toString(def.isMultiple());
+        setAttribute(MULTIPLE_ATTRIBUTE, value);
+    }
+
+}



Mime
View raw message