[jbosstools-commits] JBoss Tools SVN: r39677 - in trunk/modeshape: plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd and 9 other directories.

jbosstools-commits at lists.jboss.org jbosstools-commits at lists.jboss.org
Tue Mar 20 16:14:15 EDT 2012


Author: elvisisking
Date: 2012-03-20 16:14:13 -0400 (Tue, 20 Mar 2012)
New Revision: 39677

Added:
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiConstants.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/ChildNodeDialog.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/
   trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/DelegateAction.java
Removed:
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/delete-16x.gif
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/edit-16x.png
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/new-16x.gif
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/UiConstants.java
Modified:
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiUtils.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndEditor.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndFormsEditorPage.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndMessages.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/NamespaceMappingDialog.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/QualifiedNameDialog.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/cndMessages.properties
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/Utils.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinition.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndValidator.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/AttributeState.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/DefaultType.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributes.java
   trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/META-INF/MANIFEST.MF
   trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinitionTest.java
   trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndValidatorTest.java
   trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/Constants.java
   trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributesTest.java
Log:
JBIDE-10702 Editor for JCR Compact Node Definition (CND) files. Mostly work associated with a dialog used to edit child node definitions.

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/Utils.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/Utils.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/Utils.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -1,5 +1,6 @@
 package org.jboss.tools.modeshape.jcr;
 
+import java.util.Arrays;
 import java.util.Collection;
 
 import org.eclipse.osgi.util.NLS;
@@ -102,6 +103,28 @@
     }
 
     /**
+     * @param thisArray the array being compared to the second array (can be <code>null</code>)
+     * @param thatArray the array being compared to the first array (can be <code>null</code>)
+     * @return <code>true</code> if both arrays are <code>null</code>, both are empty, or both contain the same items
+     */
+    public static boolean equivalent( final Object[] thisArray,
+                                      final Object[] thatArray ) {
+        if (isEmpty(thisArray)) {
+            return isEmpty(thatArray);
+        }
+
+        if (isEmpty(thatArray)) {
+            return false;
+        }
+
+        if (thisArray.length != thatArray.length) {
+            return false;
+        }
+
+        return Arrays.asList(thisArray).containsAll(Arrays.asList(thatArray));
+    }
+
+    /**
      * @param thisString the string being compared with the second string (can be <code>null</code> or empty)
      * @param thatString the string being compared with the first string (can be <code>null</code> or empty)
      * @return <code>true</code> if both are <code>null</code> or empty, or they are equal

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinition.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinition.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinition.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -9,6 +9,7 @@
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.jcr.nodetype.NodeDefinitionTemplate;
@@ -35,6 +36,23 @@
     public static final String NOTATION_PREFIX = "+"; //$NON-NLS-1$
 
     /**
+     * @param childNodeToCopy the child node definition being copied (cannot be <code>null</code>)
+     * @return the copy (never <code>null</code>)
+     */
+    public static ChildNodeDefinition copy( ChildNodeDefinition childNodeToCopy ) {
+        ChildNodeDefinition copy = new ChildNodeDefinition();
+        copy.setAutoCreated(childNodeToCopy.isAutoCreated());
+        copy.setMandatory(childNodeToCopy.isMandatory());
+        copy.setProtected(childNodeToCopy.isProtected());
+        copy.setOnParentVersion(childNodeToCopy.getOnParentVersion());
+        copy.setSameNameSiblings(childNodeToCopy.allowsSameNameSiblings());
+        copy.setName(childNodeToCopy.getName());
+        copy.setDefaultPrimaryTypeName(childNodeToCopy.getDefaultPrimaryTypeName());
+        copy.setRequiredPrimaryTypeNames(childNodeToCopy.getRequiredPrimaryTypeNames());
+        return copy;
+    }
+
+    /**
      * The node attributes (never <code>null</code>).
      */
     private final NodeAttributes attributes;
@@ -204,6 +222,38 @@
     }
 
     /**
+     * {@inheritDoc}
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals( Object obj ) {
+        if (this == obj) {
+            return true;
+        }
+
+        if ((obj == null) || !getClass().equals(obj.getClass())) {
+            return false;
+        }
+
+        ChildNodeDefinition that = (ChildNodeDefinition)obj;
+
+        if (!this.attributes.equals(that.attributes)) {
+            return false;
+        }
+
+        if (!Utils.equals(getName(), that.getName())) {
+            return false;
+        }
+
+        if (!Utils.equals(getDefaultPrimaryTypeName(), that.getDefaultPrimaryTypeName())) {
+            return false;
+        }
+
+        return Utils.equivalent(this.getRequiredPrimaryTypeNames(), that.getRequiredPrimaryTypeNames());
+    }
+
+    /**
      * @param notationType the notation type being requested (cannot be <code>null</code>)
      * @return the CND notation (never <code>null</code>)
      */
@@ -246,7 +296,7 @@
      */
     @Override
     public String getDefaultPrimaryTypeName() {
-        final String primaryType = this.defaultType.getDefaultType();
+        final String primaryType = this.defaultType.getDefaultTypeName();
 
         // per API should return null if empty
         if (Utils.isEmpty(primaryType)) {
@@ -318,6 +368,20 @@
     }
 
     /**
+     * @return the qualified name (never <code>null</code>)
+     */
+    public QualifiedName getQualifiedName() {
+        return this.name;
+    }
+
+    /**
+     * @return the list of required types (never <code>null</code> but can be empty)
+     */
+    public List<QualifiedName> getRequiredTypes() {
+        return this.requiredTypes.getSupportedItems();
+    }
+
+    /**
      * @param notationType the notation type being requested (cannot be <code>null</code>)
      * @return the CND notation (never <code>null</code>)
      */
@@ -380,6 +444,16 @@
     /**
      * {@inheritDoc}
      * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return Utils.hashCode(this.attributes, this.name, this.defaultType, this.requiredTypes);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
      * @see javax.jcr.nodetype.ItemDefinition#isAutoCreated()
      */
     @Override
@@ -486,7 +560,7 @@
      */
     @Override
     public void setDefaultPrimaryTypeName( final String newTypeName ) {
-        final String oldValue = this.defaultType.getDefaultType();
+        final String oldValue = this.defaultType.getDefaultTypeName();
 
         if (this.defaultType.setDefaultType(newTypeName)) {
             notifyChangeListeners(PropertyName.DEFAULT_TYPE, oldValue, newTypeName);

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndValidator.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndValidator.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/CndValidator.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -107,7 +107,7 @@
      * @param value the value being checked (can be <code>null</code> or empty)
      * @param propertyType the property type of the property definition the value is for (cannot be <code>null</code>)
      * @param propertyName the name to use to identify the property definition (cannot be <code>null</code> empty)
-     * @param status the status to add the new status to (never <code>null</code>)
+     * @param status the status to add the new status to (cannot be <code>null</code>)
      */
     public static void isValid( final String value,
                                 final PropertyType propertyType,
@@ -145,56 +145,15 @@
             childNodeName = Messages.missingName;
         }
 
-        { // name
-          // ERROR - Empty or invalid child node definition name
-            validateLocalName(childNodeDefinition.getName(), Messages.childDefinitionName, status);
-        }
+        // name
+        validateName(childNodeDefinition, status);
 
-        { // required types
-            final String[] requiredTypeNames = childNodeDefinition.getRequiredPrimaryTypeNames();
+        // required types
+        validateRequiredTypes(childNodeDefinition, status);
 
-            if (Utils.isEmpty(requiredTypeNames)) {
-                if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.REQUIRED_TYPES) == Value.IS) {
-                    status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.emptyRequiredTypes, childNodeName)));
-                }
-            } else {
-                final Collection<String> names = new ArrayList<String>(requiredTypeNames.length);
+        // default type
+        validateDefaultType(childNodeDefinition, status);
 
-                for (final String requiredTypeName : requiredTypeNames) {
-                    // ERROR - Invalid required type name
-                    validateLocalName(requiredTypeName, Messages.requiredTypeName, status);
-
-                    if (!Utils.isEmpty(requiredTypeName)) {
-                        // ERROR - Duplicate required type name
-                        if (names.contains(requiredTypeName)) {
-                            status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.duplicateRequiredType, childNodeName,
-                                                                                    requiredTypeName)));
-                        } else {
-                            names.add(requiredTypeName);
-                        }
-                    }
-                }
-
-                // ERROR - Cannot have explicit required types when required types is marked as a variant
-                if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.REQUIRED_TYPES) != Value.IS) {
-                    status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.requiredTypesExistButMarkedAsVariant,
-                                                                            childNodeName)));
-                }
-            }
-        }
-
-        { // default type
-            final String defaultType = childNodeDefinition.getDefaultPrimaryTypeName();
-
-            if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.DEFAULT_TYPE) == Value.IS) {
-                // ERROR - Invalid default type name
-                validateLocalName(defaultType, Messages.defaultTypeName, status);
-            } else if (!Utils.isEmpty(defaultType)) {
-                // ERROR - Cannot have explicit default type when default type is marked as a variant
-                status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.defaultTypeExistsButMarkedAsVariant, childNodeName)));
-            }
-        }
-
         return status;
     }
 
@@ -330,6 +289,62 @@
     }
 
     /**
+     * @param childNodeDefinition the child node definition whose name is being validated (cannot be <code>null</code>)
+     * @param status the status to add the new status to (cannot be <code>null</code>)
+     */
+    public static void validateName( final ChildNodeDefinition childNodeDefinition,
+                                     final MultiValidationStatus status ) {
+        // ERROR - Empty or invalid child node definition name
+        validateQualifiedName(childNodeDefinition.getQualifiedName(), Messages.childDefinitionName, status);
+    }
+
+    /**
+     * @param childNodeDefinition the child node definition whose name is being validated (cannot be <code>null</code>)
+     * @return the status (never <code>null</code>)
+     */
+    public static MultiValidationStatus validateName( final ChildNodeDefinition childNodeDefinition ) {
+        final MultiValidationStatus status = new MultiValidationStatus();
+        validateName(childNodeDefinition, status);
+        return status;
+    }
+
+    /**
+     * @param childNodeDefinition the child node definition whose default type is being validated (cannot be <code>null</code>)
+     * @return the status (never <code>null</code>)
+     */
+    public static MultiValidationStatus validateDefaultType( final ChildNodeDefinition childNodeDefinition ) {
+        final MultiValidationStatus status = new MultiValidationStatus();
+        validateDefaultType(childNodeDefinition, status);
+        return status;
+    }
+
+    /**
+     * @param childNodeDefinition the child node definition whose default type is being validated (cannot be <code>null</code>)
+     * @param status the status to add the new status to (cannot be <code>null</code>)
+     */
+    public static void validateDefaultType( final ChildNodeDefinition childNodeDefinition,
+                                            final MultiValidationStatus status ) {
+        Utils.verifyIsNotNull(childNodeDefinition, "childNodeDefinition"); //$NON-NLS-1$
+        Utils.verifyIsNotNull(status, "status"); //$NON-NLS-1$
+
+        final String defaultType = childNodeDefinition.getDefaultPrimaryTypeName();
+
+        if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.DEFAULT_TYPE) == Value.IS) {
+            // ERROR - Invalid default type name
+            validateQualifiedName(childNodeDefinition.getDefaultType().getDefaultType(), Messages.defaultTypeName, status);
+        } else if (!Utils.isEmpty(defaultType)) {
+            String childNodeName = childNodeDefinition.getName();
+
+            if (Utils.isEmpty(childNodeName)) {
+                childNodeName = Messages.missingName;
+            }
+
+            // ERROR - Cannot have explicit default type when default type is marked as a variant
+            status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.defaultTypeExistsButMarkedAsVariant, childNodeName)));
+        }
+    }
+
+    /**
      * @param localName the local name being validated (cannot be <code>null</code>)
      * @param propertyName the name to use in the validation message (cannot be <code>null</code>)
      * @return the status (never <code>null</code>)
@@ -400,7 +415,7 @@
         validateLocalName(namespaceMapping.getPrefix(), Messages.namespacePrefix, status);
 
         // ERROR - Empty or invalid URI
-        ValidationStatus uriStatus = validateUri(namespaceMapping.getUri(), Messages.namespaceUri);
+        final ValidationStatus uriStatus = validateUri(namespaceMapping.getUri(), Messages.namespaceUri);
 
         if (!uriStatus.isOk()) {
             status.add(uriStatus);
@@ -1069,6 +1084,60 @@
     }
 
     /**
+     * @param childNodeDefinition the child node definition whose required types are being validated (cannot be <code>null</code>)
+     * @return the status (never <code>null</code>)
+     */
+    public static MultiValidationStatus validateRequiredTypes( final ChildNodeDefinition childNodeDefinition ) {
+        final MultiValidationStatus status = new MultiValidationStatus();
+        validateRequiredTypes(childNodeDefinition, status);
+        return status;
+    }
+
+    /**
+     * @param childNodeDefinition the child node definition whose required types are being validated (cannot be <code>null</code>)
+     * @param status the status to add the new status to (cannot be <code>null</code>)
+     */
+    public static void validateRequiredTypes( final ChildNodeDefinition childNodeDefinition,
+                                              final MultiValidationStatus status ) {
+        Utils.verifyIsNotNull(childNodeDefinition, "childNodeDefinition"); //$NON-NLS-1$
+        Utils.verifyIsNotNull(status, "status"); //$NON-NLS-1$
+
+        final String[] requiredTypeNames = childNodeDefinition.getRequiredPrimaryTypeNames();
+        String childNodeName = childNodeDefinition.getName();
+
+        if (Utils.isEmpty(childNodeName)) {
+            childNodeName = Messages.missingName;
+        }
+
+        if (Utils.isEmpty(requiredTypeNames)) {
+            if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.REQUIRED_TYPES) == Value.IS) {
+                status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.emptyRequiredTypes, childNodeName)));
+            }
+        } else {
+            final Collection<QualifiedName> requiredTypes = new ArrayList<QualifiedName>(requiredTypeNames.length);
+
+            for (final QualifiedName requiredType : childNodeDefinition.getRequiredTypes()) {
+                // ERROR - Invalid required type name
+                validateQualifiedName(requiredType, Messages.requiredTypeName, status);
+
+                // ERROR - Duplicate required type name
+                if (requiredTypes.contains(requiredType)) {
+                    status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.duplicateRequiredType, childNodeName,
+                                                                            requiredType)));
+                } else {
+                    requiredTypes.add(requiredType);
+                }
+            }
+
+            // ERROR - Cannot have explicit required types when required types is marked as a variant
+            if (childNodeDefinition.getState(ChildNodeDefinition.PropertyName.REQUIRED_TYPES) != Value.IS) {
+                status.add(ValidationStatus.createErrorMessage(NLS.bind(Messages.requiredTypesExistButMarkedAsVariant,
+                                                                        childNodeName)));
+            }
+        }
+    }
+
+    /**
      * @param nodeTypeDefinitionName the node type name whose supertypes are being checked (cannot be <code>null</code> or empty)
      * @param superTypesState the supertypes property state (cannot be <code>null</code>)
      * @param superTypeNames the collection of a node type definition's supertypes to validate (can be <code>null</code> or empty)

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/AttributeState.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/AttributeState.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/AttributeState.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -89,7 +89,7 @@
      */
     @Override
     public int hashCode() {
-        return super.hashCode();
+        return this.state.hashCode();
     }
 
     /**

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/DefaultType.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/DefaultType.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/DefaultType.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -10,10 +10,10 @@
 import org.jboss.tools.modeshape.jcr.Utils;
 import org.jboss.tools.modeshape.jcr.cnd.CndNotationPreferences;
 import org.jboss.tools.modeshape.jcr.cnd.CndNotationPreferences.Preference;
-import org.jboss.tools.modeshape.jcr.cnd.LocalName;
+import org.jboss.tools.modeshape.jcr.cnd.QualifiedName;
 
 /**
- * The child node definitions default type property.
+ * The child node definition's default type property.
  */
 public class DefaultType extends AttributeState {
 
@@ -22,7 +22,7 @@
      */
     public static final String NOTATION = "="; //$NON-NLS-1$
 
-    private final LocalName defaultType = new LocalName();
+    private final QualifiedName defaultType = new QualifiedName();
 
     /**
      * {@inheritDoc}
@@ -65,13 +65,27 @@
     }
 
     /**
-     * @return the default type (can be <code>null</code> or empty)
+     * @return the default type's qualified name (never <code>null</code>)
      */
-    public String getDefaultType() {
-        return this.defaultType.get();
+    public QualifiedName getDefaultType() {
+        return this.defaultType;
     }
 
     /**
+     * @return the default type name (can be <code>null</code> or empty)
+     */
+    public String getDefaultTypeName() {
+        String defaultTypeName = this.defaultType.get();
+
+        // per API return null if it doesn't exist
+        if (Utils.isEmpty(defaultTypeName)) {
+            return null;
+        }
+
+        return defaultTypeName;
+    }
+
+    /**
      * {@inheritDoc}
      * 
      * @see org.jboss.tools.modeshape.jcr.cnd.attributes.AttributeState#getLongCndNotation()
@@ -82,7 +96,7 @@
             return getPrefix();
         }
 
-        String defaultType = getDefaultType();
+        String defaultType = getDefaultTypeName();
 
         if (Utils.isEmpty(defaultType)) {
             return Utils.EMPTY_STRING;

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributes.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributes.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributes.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -18,6 +18,20 @@
  */
 public class NodeAttributes implements CndElement {
 
+    /**
+     * @param attributesToCopy the attributes being copied (cannot be <code>null</code>)
+     * @return the copy (never <code>null</code>)
+     */
+    public static NodeAttributes copy( NodeAttributes attributesToCopy ) {
+        NodeAttributes copy = new NodeAttributes();
+        copy.autocreated.set(attributesToCopy.getAutocreated().get());
+        copy.mandatory.set(attributesToCopy.getMandatory().get());
+        copy.notDeletable.set(attributesToCopy.getProtected().get());
+        copy.opv = attributesToCopy.getOnParentVersion();
+        copy.sns.set(attributesToCopy.getSameNameSiblings().get());
+        return copy;
+    }
+
     private final Autocreated autocreated;
 
     private final Mandatory mandatory;

Deleted: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/delete-16x.gif
===================================================================
(Binary files differ)

Deleted: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/edit-16x.png
===================================================================
(Binary files differ)

Deleted: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/icons/new-16x.gif
===================================================================
(Binary files differ)

Copied: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiConstants.java (from rev 39542, trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/UiConstants.java)
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiConstants.java	                        (rev 0)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiConstants.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
+ *
+ * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
+ */
+package org.jboss.tools.modeshape.jcr.ui;
+
+
+/**
+ * Constants used within the <code>org.jboss.tools.modeshape.jcr.ui</code> plug-in.
+ */
+public interface JcrUiConstants {
+
+    /**
+     * The plug-in bundle's symbolic name.
+     */
+    String PLUGIN_ID = JcrUiConstants.class.getPackage().getName();
+
+    /**
+     * The identifiers for the CND editor-related parts.
+     */
+    interface EditorIds {
+
+        /**
+         * The extension ID for the CND editor part.
+         */
+        String CND_EDITOR = PLUGIN_ID + ".cndEditor"; //$NON-NLS-1$
+
+        /**
+         * The ID of the CND editor's forms editor page.
+         */
+        String CND_FORMS_PAGE = CND_EDITOR + ".formsPage"; //$NON-NLS-1$
+
+        /**
+         * The ID of the CND editor's text editor page.
+         */
+        String CND_SOURCE_PAGE = CND_EDITOR + ".sourcePage"; //$NON-NLS-1$
+    }
+
+    /**
+     * The image paths.
+     */
+    interface Images {
+
+        /**
+         * The relative path from the plugin folder to the icons folder.
+         */
+        String ICONS_FOLDER = "icons/"; //$NON-NLS-1$
+
+        /**
+         * The relative path from the plugin folder to the icon used for the CND editor.
+         */
+        String CND_EDITOR = ICONS_FOLDER + "cnd-editor-16x.png"; //$NON-NLS-1$
+    }
+}


Property changes on: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiConstants.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiUtils.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiUtils.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/JcrUiUtils.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -7,15 +7,48 @@
  */
 package org.jboss.tools.modeshape.jcr.ui;
 
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
 import org.jboss.tools.modeshape.jcr.ValidationStatus;
 import org.jboss.tools.modeshape.ui.forms.ErrorMessage;
 
 /**
- * 
+ * Commonly used utility methods for the JCR UI project.
  */
 public class JcrUiUtils {
 
     /**
+     * @return the CND editor icon (never <code>null</code>)
+     */
+    public static Image getCndEditorImage() {
+        return Activator.getSharedInstance().getImage(JcrUiConstants.Images.CND_EDITOR);
+    }
+
+    /**
+     * @return the generic delete toolbar/menu icon (never <code>null</code>)
+     */
+    public static ImageDescriptor getDeleteImageDescriptor() {
+        return org.jboss.tools.modeshape.ui.Activator.getSharedInstance()
+                                                     .getImageDescriptor(org.jboss.tools.modeshape.ui.UiConstants.Images.DELETE_16X);
+    }
+
+    /**
+     * @return the generic edit toolbar/menu icon (never <code>null</code>)
+     */
+    public static ImageDescriptor getEditImageDescriptor() {
+        return org.jboss.tools.modeshape.ui.Activator.getSharedInstance()
+                                                     .getImageDescriptor(org.jboss.tools.modeshape.ui.UiConstants.Images.EDIT_16X);
+    }
+
+    /**
+     * @return the generic new toolbar/menu icon (never <code>null</code>)
+     */
+    public static ImageDescriptor getNewImageDescriptor() {
+        return org.jboss.tools.modeshape.ui.Activator.getSharedInstance()
+                                                     .getImageDescriptor(org.jboss.tools.modeshape.ui.UiConstants.Images.NEW_16X);
+    }
+
+    /**
      * @param status the status being used to set the message (cannot be <code>null</code>)
      * @param message the message being set (cannot be <code>null</code>)
      */

Deleted: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/UiConstants.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/UiConstants.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/UiConstants.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -1,56 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- *
- * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
- *
- * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
- */
-package org.jboss.tools.modeshape.jcr.ui;
-
-/**
- * Constants used within the <code>org.jboss.tools.modeshape.jcr.ui</code> plug-in.
- */
-public interface UiConstants {
-
-    /**
-     * The plug-in bundle's symbolic name.
-     */
-    String PLUGIN_ID = UiConstants.class.getPackage().getName();
-
-    /**
-     * The identifiers for the CND editor-related parts.
-     */
-    interface EditorIds {
-
-        /**
-         * The extension ID for the CND editor part.
-         */
-        String CND_EDITOR = PLUGIN_ID + ".cndEditor"; //$NON-NLS-1$
-
-        /**
-         * The ID of the CND editor's forms editor page.
-         */
-        String CND_FORMS_PAGE = CND_EDITOR + ".formsPage"; //$NON-NLS-1$
-
-        /**
-         * The ID of the CND editor's text editor page.
-         */
-        String CND_SOURCE_PAGE = CND_EDITOR + ".sourcePage"; //$NON-NLS-1$
-    }
-
-    /**
-     * The image paths.
-     */
-    interface Images {
-
-        /**
-         * The relative path from the plugin folder to the icons folder.
-         */
-        String ICONS_FOLDER = "icons/"; //$NON-NLS-1$
-
-        /**
-         * The relative path from the plugin folder to the icon used for the CND editor.
-         */
-        String CND_EDITOR = ICONS_FOLDER + "cnd-editor-16x.png"; //$NON-NLS-1$
-    }
-}

Added: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/ChildNodeDialog.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/ChildNodeDialog.java	                        (rev 0)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/ChildNodeDialog.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -0,0 +1,811 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
+ *
+ * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
+ */
+package org.jboss.tools.modeshape.jcr.ui.cnd;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.ui.forms.FormDialog;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.jboss.tools.modeshape.jcr.Messages;
+import org.jboss.tools.modeshape.jcr.Utils;
+import org.jboss.tools.modeshape.jcr.ValidationStatus;
+import org.jboss.tools.modeshape.jcr.cnd.ChildNodeDefinition;
+import org.jboss.tools.modeshape.jcr.cnd.ChildNodeDefinition.PropertyName;
+import org.jboss.tools.modeshape.jcr.cnd.CndValidator;
+import org.jboss.tools.modeshape.jcr.cnd.QualifiedName;
+import org.jboss.tools.modeshape.jcr.cnd.attributes.OnParentVersion;
+import org.jboss.tools.modeshape.jcr.ui.Activator;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiConstants;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiUtils;
+import org.jboss.tools.modeshape.ui.UiMessages;
+import org.jboss.tools.modeshape.ui.actions.DelegateAction;
+import org.jboss.tools.modeshape.ui.forms.ErrorMessage;
+import org.jboss.tools.modeshape.ui.forms.FormUtils;
+import org.jboss.tools.modeshape.ui.forms.FormUtils.Styles;
+import org.jboss.tools.modeshape.ui.forms.MessageFormDialog;
+
+/**
+ * 
+ */
+class ChildNodeDialog extends FormDialog {
+
+    private IAction addRequiredType;
+    private Button btnOk;
+    private ChildNodeDefinition childNodeBeingEdited;
+    private final ErrorMessage defaultTypeError;
+    private IAction deleteRequiredType;
+    private IAction editRequiredType;
+
+    /**
+     * The existing child node definition names contained in the CND (never <code>null</code> but can be empty).
+     */
+    private Collection<QualifiedName> existingChildNodeNames;
+
+    /**
+     * The existing namespace prefixes contained in the CND (never <code>null</code> but can be empty).
+     */
+    private Collection<String> existingNamespacePrefixes;
+
+    private final ErrorMessage nameError;
+
+    private ChildNodeDefinition originalChildNode;
+    private final ErrorMessage requiredTypesError;
+
+    private TableViewer requiredTypesViewer;
+
+    private ScrolledForm scrolledForm;
+
+    /**
+     * Used to create a new child node definition.
+     * 
+     * @param parentShell the parent shell (can be <code>null</code>)
+     * @param existingChildNodeNames the existing child node names (can be <code>null</code> or empty)
+     * @param existingNamespacePrefixes the existing CND namespace prefixes (can be <code>null</code> or empty)
+     */
+    public ChildNodeDialog( final Shell parentShell,
+                            final Collection<QualifiedName> existingChildNodeNames,
+                            final Collection<String> existingNamespacePrefixes ) {
+        super(parentShell);
+        this.existingChildNodeNames = ((existingChildNodeNames == null) ? Collections.<QualifiedName> emptyList()
+                                                                       : new ArrayList<QualifiedName>(existingChildNodeNames));
+        this.existingNamespacePrefixes = ((existingNamespacePrefixes == null) ? Collections.<String> emptyList()
+                                                                             : new ArrayList<String>(existingNamespacePrefixes));
+        this.nameError = new ErrorMessage();
+        this.defaultTypeError = new ErrorMessage();
+        this.requiredTypesError = new ErrorMessage();
+        this.childNodeBeingEdited = new ChildNodeDefinition();
+    }
+
+    /**
+     * @return the child node definition represented by the dialog UI controls (never <code>null</code>)
+     */
+    public ChildNodeDefinition getChildNodeDefinition() {
+        return this.childNodeBeingEdited;
+    }
+
+    /**
+     * Used to create a new child node definition.
+     * 
+     * @param parentShell the parent shell (can be <code>null</code>)
+     * @param existingChildNodeNames the existing child node names (can be <code>null</code> or empty)
+     * @param childNodeBeingEdited the child node definition being edited (cannot be <code>null</code>)
+     * @param existingNamespacePrefixes the existing CND namespace prefixes (can be <code>null</code> or empty)
+     */
+    public ChildNodeDialog( final Shell parentShell,
+                            final Collection<QualifiedName> existingChildNodeNames,
+                            final Collection<String> existingNamespacePrefixes,
+                            final ChildNodeDefinition childNodeBeingEdited ) {
+        this(parentShell, existingChildNodeNames, existingNamespacePrefixes);
+
+        Utils.verifyIsNotNull(childNodeBeingEdited, "childNodeBeingEdited"); //$NON-NLS-1$
+        this.originalChildNode = childNodeBeingEdited;
+
+        // create copy of child node being edited
+        this.childNodeBeingEdited = ChildNodeDefinition.copy(this.originalChildNode);
+
+        // remove name from existing names so that validation won't show it as a duplicate
+        if (!Utils.isEmpty(this.childNodeBeingEdited.getName())) {
+            this.existingChildNodeNames.remove(this.childNodeBeingEdited.getName());
+        }
+    }
+
+    ChildNodeDefinition accessModel() {
+        return this.childNodeBeingEdited;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+     */
+    @Override
+    protected void configureShell( final Shell newShell ) {
+        super.configureShell(newShell);
+        newShell.setText(CndMessages.childNodeDialogTitle);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean)
+     */
+    @Override
+    protected Button createButton( final Composite parent,
+                                   final int id,
+                                   final String label,
+                                   final boolean defaultButton ) {
+        final Button btn = super.createButton(parent, id, label, defaultButton);
+
+        if (id == IDialogConstants.OK_ID) {
+            // disable OK button initially
+            this.btnOk = btn;
+            btn.setEnabled(false);
+        }
+
+        return btn;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.ui.forms.FormDialog#createFormContent(org.eclipse.ui.forms.IManagedForm)
+     */
+    @Override
+    protected void createFormContent( final IManagedForm managedForm ) {
+        this.scrolledForm = managedForm.getForm();
+        this.scrolledForm.setText(isEditMode() ? CndMessages.childNodeDialogEditTitle : CndMessages.childNodeDialogCreateTitle);
+        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(JcrUiConstants.Images.CND_EDITOR));
+        this.scrolledForm.setMessage(CndMessages.childNodeDialogMsg, IMessageProvider.NONE);
+
+        final FormToolkit toolkit = managedForm.getToolkit();
+        toolkit.decorateFormHeading(this.scrolledForm.getForm());
+
+        final Composite body = this.scrolledForm.getBody();
+        body.setLayout(new GridLayout(2, false));
+
+        { // left-side (name, default type, attributes)
+            final Composite leftContainer = toolkit.createComposite(body);
+            leftContainer.setLayout(new GridLayout(2, false));
+            leftContainer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+            toolkit.paintBordersFor(leftContainer);
+
+            { // name
+                toolkit.createLabel(leftContainer, CndMessages.nameLabel);
+                final Text txtName = toolkit.createText(leftContainer, Utils.EMPTY_STRING, Styles.TEXT_STYLE);
+                txtName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+                txtName.setToolTipText(CndMessages.childNodeNameToolTip);
+
+                if (isEditMode()) {
+                    String currentValue = this.childNodeBeingEdited.getName();
+
+                    if (currentValue == null) {
+                        currentValue = Utils.EMPTY_STRING;
+                    }
+
+                    txtName.setText(currentValue);
+                }
+
+                txtName.addModifyListener(new ModifyListener() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+                     */
+                    @Override
+                    public void modifyText( final ModifyEvent e ) {
+                        handleNameChanged(((Text)e.widget).getText());
+                    }
+                });
+
+                this.nameError.setControl(txtName);
+            }
+
+            { // default type
+                toolkit.createLabel(leftContainer, CndMessages.childNodeDefaultTypeLabel);
+                final Text txtDefaultType = toolkit.createText(leftContainer, Utils.EMPTY_STRING, Styles.TEXT_STYLE);
+                txtDefaultType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+                txtDefaultType.setToolTipText(CndMessages.childNodeDefaultTypeToolTip);
+
+                if (isEditMode()) {
+                    String currentValue = this.childNodeBeingEdited.getDefaultPrimaryTypeName();
+
+                    if (currentValue == null) {
+                        currentValue = Utils.EMPTY_STRING;
+                    }
+
+                    txtDefaultType.setText(currentValue);
+                }
+
+                txtDefaultType.addModifyListener(new ModifyListener() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+                     */
+                    @Override
+                    public void modifyText( final ModifyEvent e ) {
+                        handleDefaultTypeChanged(((Text)e.widget).getText());
+                    }
+                });
+
+                this.defaultTypeError.setControl(txtDefaultType);
+            }
+
+            { // attributes
+                final Group attributesContainer = new Group(leftContainer, SWT.SHADOW_NONE);
+                attributesContainer.setText(CndMessages.attributesHeaderText);
+                attributesContainer.setLayout(new GridLayout(2, true));
+                GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
+                gd.horizontalSpan = 2;
+                attributesContainer.setLayoutData(gd);
+                toolkit.adapt(attributesContainer);
+                toolkit.paintBordersFor(attributesContainer);
+
+                final Button btnAutocreated = toolkit.createButton(attributesContainer, CndMessages.autocreatedAttribute, SWT.CHECK);
+                btnAutocreated.setBackground(attributesContainer.getBackground());
+
+                if (isEditMode() && this.childNodeBeingEdited.isAutoCreated()) {
+                    btnAutocreated.setSelection(true);
+                }
+
+                btnAutocreated.addSelectionListener(new SelectionAdapter() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                     */
+                    @Override
+                    public void widgetSelected( final SelectionEvent e ) {
+                        handleAutocreatedChanged(((Button)e.widget).getSelection());
+                    }
+                });
+                btnAutocreated.setToolTipText(CndMessages.autocreatedAttributeToolTip);
+
+                final Button btnMandatory = toolkit.createButton(attributesContainer, CndMessages.mandatoryAttribute, SWT.CHECK);
+                btnMandatory.setBackground(attributesContainer.getBackground());
+
+                if (isEditMode() && this.childNodeBeingEdited.isMandatory()) {
+                    btnMandatory.setSelection(true);
+                }
+
+                btnMandatory.addSelectionListener(new SelectionAdapter() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                     */
+                    @Override
+                    public void widgetSelected( final SelectionEvent e ) {
+                        handleMandatoryChanged(((Button)e.widget).getSelection());
+                    }
+                });
+                btnMandatory.setToolTipText(CndMessages.mandatoryAttributeToolTip);
+
+                final Button btnProtected = toolkit.createButton(attributesContainer, CndMessages.protectedAttribute, SWT.CHECK);
+                btnProtected.setBackground(attributesContainer.getBackground());
+
+                if (isEditMode() && this.childNodeBeingEdited.isProtected()) {
+                    btnProtected.setSelection(true);
+                }
+
+                btnProtected.addSelectionListener(new SelectionAdapter() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                     */
+                    @Override
+                    public void widgetSelected( final SelectionEvent e ) {
+                        handleProtectedChanged(((Button)e.widget).getSelection());
+                    }
+                });
+                btnProtected.setToolTipText(CndMessages.protectedAttributeToolTip);
+
+                final Button btnSameNamedSiblings = toolkit.createButton(attributesContainer,
+                                                                         CndMessages.sameNamedSiblingsAttribute, SWT.CHECK);
+                btnSameNamedSiblings.setBackground(attributesContainer.getBackground());
+
+                if (isEditMode() && this.childNodeBeingEdited.allowsSameNameSiblings()) {
+                    btnSameNamedSiblings.setSelection(true);
+                }
+
+                btnSameNamedSiblings.addSelectionListener(new SelectionAdapter() {
+
+                    /**
+                     * {@inheritDoc}
+                     * 
+                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                     */
+                    @Override
+                    public void widgetSelected( final SelectionEvent e ) {
+                        handleSameNamedSiblingsChanged(((Button)e.widget).getSelection());
+                    }
+                });
+                btnSameNamedSiblings.setToolTipText(CndMessages.sameNamedSiblingsAttributeToolTip);
+
+                
+                { // opv
+                    final Composite opvContainer = toolkit.createComposite(attributesContainer);
+                    opvContainer.setLayout(new GridLayout(2, false));
+                    GridData gdOpv = new GridData(SWT.FILL, SWT.CENTER, true, false);
+                    gdOpv.horizontalSpan = 2;
+                    opvContainer.setLayoutData(gdOpv);
+                    toolkit.paintBordersFor(opvContainer);
+
+                    final Label lblOpv = toolkit.createLabel(opvContainer, CndMessages.onParentVersionLabel, SWT.NONE);
+                    lblOpv.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+
+                    final CCombo cbxOpvs = new CCombo(opvContainer, Styles.COMBO_STYLE);
+                    toolkit.adapt(cbxOpvs, true, false);
+                    cbxOpvs.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+                    cbxOpvs.setToolTipText(CndMessages.onParentVersionToolTip);
+
+                    // populate opv values
+                    for (final OnParentVersion opv : OnParentVersion.values()) {
+                        if (opv != OnParentVersion.VARIANT) {
+                            cbxOpvs.add(opv.toString());
+                        }
+                    }
+
+                    // select the current qualifier
+                    if (isEditMode()) {
+                        final String currentOpv = OnParentVersion.findUsingJcrValue(this.childNodeBeingEdited.getOnParentVersion())
+                                                                 .toString();
+                        final int index = cbxOpvs.indexOf(currentOpv);
+
+                        if (index != -1) {
+                            cbxOpvs.select(index);
+                        }
+                    }
+
+                    cbxOpvs.addSelectionListener(new SelectionAdapter() {
+
+                        /**
+                         * {@inheritDoc}
+                         * 
+                         * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                         */
+                        @Override
+                        public void widgetSelected( final SelectionEvent e ) {
+                            final String newOpv = ((CCombo)e.widget).getText();
+                            handleOnParentVersionChanged(newOpv);
+                        }
+                    });
+                }
+            }
+        }
+
+        { // right-side (required types)
+            final Composite rightContainer = toolkit.createComposite(body);
+            rightContainer.setLayout(new GridLayout(2, false));
+            rightContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+            toolkit.paintBordersFor(rightContainer);
+
+            final Label label = toolkit.createLabel(rightContainer, CndMessages.requiredTypesLabel);
+            label.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, false, false));
+            ((GridData)label.getLayoutData()).horizontalSpan = 2;
+
+            final Table table = FormUtils.createTable(toolkit, rightContainer);
+            table.setHeaderVisible(false);
+            table.setLinesVisible(false);
+            ((GridData)table.getLayoutData()).heightHint = table.getItemHeight() * 2;
+            this.requiredTypesError.setControl(table);
+
+            createRequiredTypesActions();
+
+            // table context menu
+            final MenuManager menuManager = new MenuManager();
+            menuManager.add(new DelegateAction(CndMessages.addRequiredTypeMenuText, this.addRequiredType));
+            menuManager.add(new DelegateAction(CndMessages.editRequiredTypeMenuText, this.editRequiredType));
+            menuManager.add(new DelegateAction(CndMessages.deleteRequiredTypeMenuText, this.deleteRequiredType));
+            table.setMenu(menuManager.createContextMenu(table));
+
+            createRequiredTypesViewer(table);
+
+            // add toolbar buttons (add, edit, delete)
+            final ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT | SWT.VERTICAL);
+            final ToolBar toolBar = toolBarManager.createControl(rightContainer);
+
+            toolkit.adapt(toolBar);
+            final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
+            toolBar.setCursor(handCursor);
+            toolBarManager.add(this.addRequiredType);
+            toolBarManager.add(this.editRequiredType);
+            toolBarManager.add(this.deleteRequiredType);
+            toolBarManager.update(true);
+
+            // fill with data
+            this.requiredTypesViewer.setInput(this);
+        }
+
+        // must be done after constructor
+        this.childNodeBeingEdited.addListener(new PropertyChangeListener() {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+             */
+            @Override
+            public void propertyChange( final PropertyChangeEvent e ) {
+                handlePropertyChanged(e);
+            }
+        });
+
+        // set messages
+        validateAttributes();
+        validateDefaultType();
+        validateName();
+        validateRequiredTypes();
+    }
+
+    void createRequiredTypesActions() {
+        this.addRequiredType = new Action(Utils.EMPTY_STRING) {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.action.Action#run()
+             */
+            @Override
+            public void run() {
+                handleAddRequiredType();
+            }
+        };
+        this.addRequiredType.setToolTipText(CndMessages.addRequiredTypeToolTip);
+        this.addRequiredType.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
+
+        this.deleteRequiredType = new Action(Utils.EMPTY_STRING) {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.action.Action#run()
+             */
+            @Override
+            public void run() {
+                handleDeleteRequiredType();
+            }
+        };
+        this.deleteRequiredType.setEnabled(false);
+        this.deleteRequiredType.setToolTipText(CndMessages.deleteRequiredTypeToolTip);
+        this.deleteRequiredType.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
+
+        this.editRequiredType = new Action(Utils.EMPTY_STRING) {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.action.Action#run()
+             */
+            @Override
+            public void run() {
+                handleEditRequiredType();
+            }
+        };
+        this.editRequiredType.setEnabled(false);
+        this.editRequiredType.setToolTipText(CndMessages.editRequiredTypeToolTip);
+        this.editRequiredType.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
+    }
+
+    private void createRequiredTypesViewer( final Table requiredTypesTable ) {
+        this.requiredTypesViewer = new TableViewer(requiredTypesTable);
+        this.requiredTypesViewer.setLabelProvider(new LabelProvider());
+        this.requiredTypesViewer.setContentProvider(new IStructuredContentProvider() {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+             */
+            @Override
+            public void dispose() {
+                // nothing to do
+            }
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+             */
+            @Override
+            public Object[] getElements( final Object inputElement ) {
+                final ChildNodeDefinition childNode = accessModel();
+                final String[] requiredTypes = childNode.getRequiredPrimaryTypeNames();
+
+                if (requiredTypes == null) {
+                    return Utils.EMPTY_OBJECT_ARRAY;
+                }
+
+                return requiredTypes;
+            }
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
+             *      java.lang.Object)
+             */
+            @Override
+            public void inputChanged( final Viewer viewer,
+                                      final Object oldInput,
+                                      final Object newInput ) {
+                // nothing to do
+            }
+        });
+
+        this.requiredTypesViewer.addDoubleClickListener(new IDoubleClickListener() {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+             */
+            @Override
+            public void doubleClick( final DoubleClickEvent event ) {
+                handleEditRequiredType();
+            }
+        });
+
+        this.requiredTypesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+             */
+            @Override
+            public void selectionChanged( final SelectionChangedEvent event ) {
+                handleRequiredTypeSelected();
+            }
+        });
+    }
+
+    /**
+     * @return the selected required type or <code>null</code> if the viewer has an empty selection
+     */
+    private String getSelectedRequiredType() {
+        final IStructuredSelection selection = (IStructuredSelection)this.requiredTypesViewer.getSelection();
+
+        if (selection.isEmpty()) {
+            return null;
+        }
+
+        assert (selection.size() == 1) : "required types viewer should not allow multiple selections"; //$NON-NLS-1$
+        assert (selection.getFirstElement() instanceof String) : "selection was not a string"; //$NON-NLS-1$
+        return (String)selection.getFirstElement();
+    }
+
+    void handleAddRequiredType() {
+        final QualifiedNameDialog dialog = new QualifiedNameDialog(getShell(),
+                                                                   CndMessages.newRequiredTypeDialogTitle,
+                                                                   Messages.requiredTypeName,
+                                                                   this.existingNamespacePrefixes);
+        dialog.setExistingQNames(this.childNodeBeingEdited.getRequiredTypes());
+        dialog.create();
+        dialog.getShell().pack();
+
+        if (dialog.open() == Window.OK) {
+            final QualifiedName newQName = dialog.getQualifiedName();
+
+            if (this.childNodeBeingEdited.addRequiredType(newQName.get())) {
+                this.requiredTypesViewer.refresh();
+            } else {
+                MessageFormDialog.openError(getShell(), UiMessages.errorDialogTitle, JcrUiUtils.getCndEditorImage(),
+                                            NLS.bind(CndMessages.errorAddingRequiredType, newQName));
+            }
+        }
+    }
+
+    void handleAutocreatedChanged( final boolean newAutocreated ) {
+        this.childNodeBeingEdited.setAutoCreated(newAutocreated);
+    }
+
+    void handleDefaultTypeChanged( final String newDefaultType ) {
+        this.childNodeBeingEdited.setDefaultPrimaryTypeName(newDefaultType);
+    }
+
+    void handleDeleteRequiredType() {
+        assert (getSelectedRequiredType() != null) : "Delete required type handler called and there is no required type selected"; //$NON-NLS-1$
+
+        String requiredTypeName = getSelectedRequiredType();
+
+        // should always have a name but just in case
+        if (Utils.isEmpty(requiredTypeName)) {
+            requiredTypeName = Messages.missingName;
+        }
+
+        // show confirmation dialog
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteRequiredTypeDialogTitle, JcrUiUtils.getCndEditorImage(),
+                                           NLS.bind(CndMessages.deleteRequiredTypeDialogMessage, requiredTypeName))) {
+            this.childNodeBeingEdited.removeRequiredType(requiredTypeName);
+        }
+    }
+
+    void handleEditRequiredType() {
+        assert (getSelectedRequiredType() != null) : "Edit required type handler has been called when there is no required type selected"; //$NON-NLS-1$
+        final String selectedRequiredType = getSelectedRequiredType();
+
+        final QualifiedNameDialog dialog = new QualifiedNameDialog(getShell(),
+                                                                   CndMessages.editRequiredTypeDialogTitle,
+                                                                   Messages.requiredTypeName,
+                                                                   this.existingNamespacePrefixes,
+                                                                   QualifiedName.parse(selectedRequiredType));
+        dialog.setExistingQNames(this.childNodeBeingEdited.getRequiredTypes());
+        dialog.create();
+        dialog.getShell().pack();
+
+        if (dialog.open() == Window.OK) {
+            final QualifiedName modifiedRequiredType = dialog.getQualifiedName();
+            boolean removed = false;
+            boolean added = false;
+
+            // remove existing and add in new
+            if (this.childNodeBeingEdited.removeRequiredType(selectedRequiredType)) {
+                removed = true;
+
+                if (this.childNodeBeingEdited.addRequiredType(modifiedRequiredType.get())) {
+                    added = true;
+                }
+            }
+
+            if (!removed || !added) {
+                MessageFormDialog.openError(getShell(),
+                                            UiMessages.errorDialogTitle,
+                                            JcrUiUtils.getCndEditorImage(),
+                                            NLS.bind(CndMessages.errorEditingRequiredType, new Object[] { modifiedRequiredType,
+                                                    removed, added }));
+            }
+        }
+    }
+
+    void handleMandatoryChanged( final boolean newMandatory ) {
+        this.childNodeBeingEdited.setMandatory(newMandatory);
+    }
+
+    void handleNameChanged( final String newName ) {
+        this.childNodeBeingEdited.setName(newName);
+    }
+
+    void handleOnParentVersionChanged( final String newOpv ) {
+        this.childNodeBeingEdited.setOnParentVersion(newOpv);
+    }
+
+    void handlePropertyChanged( final PropertyChangeEvent e ) {
+        final String propName = e.getPropertyName();
+
+        if (PropertyName.AUTOCREATED.toString().equals(propName) || PropertyName.MANDATORY.toString().equals(propName)
+                || PropertyName.PROTECTED.toString().equals(propName)
+                || PropertyName.SAME_NAME_SIBLINGS.toString().equals(propName)
+                || PropertyName.ON_PARENT_VERSION.toString().equals(propName)) {
+            validateAttributes();
+        } else if (PropertyName.DEFAULT_TYPE.toString().equals(propName)) {
+            validateDefaultType();
+        } else if (PropertyName.NAME.toString().equals(propName)) {
+            validateName();
+        } else if (PropertyName.REQUIRED_TYPES.toString().equals(propName)) {
+            validateRequiredTypes();
+            this.requiredTypesViewer.refresh();
+        }
+
+        updateState();
+    }
+
+    void handleProtectedChanged( final boolean newProtected ) {
+        this.childNodeBeingEdited.setProtected(newProtected);
+    }
+
+    void handleRequiredTypeSelected() {
+        // update button enablements
+        final boolean enable = (getSelectedRequiredType() != null);
+
+        if (this.editRequiredType.isEnabled() != enable) {
+            this.editRequiredType.setEnabled(enable);
+        }
+
+        if (this.deleteRequiredType.isEnabled() != enable) {
+            this.deleteRequiredType.setEnabled(enable);
+        }
+    }
+
+    void handleSameNamedSiblingsChanged( final boolean newSns ) {
+        this.childNodeBeingEdited.setSameNameSiblings(newSns);
+    }
+
+    private boolean isEditMode() {
+        return (this.childNodeBeingEdited != null);
+    }
+
+    private void validateAttributes() {
+        // no validation required
+    }
+
+    private void validateDefaultType() {
+        updateMessage(CndValidator.validateDefaultType(this.childNodeBeingEdited), this.defaultTypeError);
+    }
+
+    private void validateName() {
+        updateMessage(CndValidator.validateName(this.childNodeBeingEdited), this.nameError);
+    }
+
+    private void validateRequiredTypes() {
+        updateMessage(CndValidator.validateRequiredTypes(this.childNodeBeingEdited), this.requiredTypesError);
+    }
+
+    private void updateMessage( final ValidationStatus status, 
+                                final ErrorMessage errorMsg ) {
+        JcrUiUtils.setMessage(status, errorMsg);
+
+        if (errorMsg.isOk()) {
+            this.scrolledForm.getMessageManager().removeMessage(errorMsg.getKey(), errorMsg.getControl());
+        } else {
+            this.scrolledForm.getMessageManager().addMessage(errorMsg.getKey(), errorMsg.getMessage(), null,
+                                                             errorMsg.getMessageType(), errorMsg.getControl());
+        }
+    }
+
+    private void updateState() {
+        int messageType = this.scrolledForm.getMessageType();
+        boolean enable = (messageType != IMessageProvider.ERROR);
+
+        if (enable && isEditMode() && this.originalChildNode.equals(this.childNodeBeingEdited)) {
+            enable = false;
+        }
+
+        // set enabled state of OK button
+        if (this.btnOk.getEnabled() != enable) {
+            this.btnOk.setEnabled(enable);
+        }
+    }
+}


Property changes on: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/ChildNodeDialog.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndEditor.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndEditor.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndEditor.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -48,8 +48,8 @@
 import org.jboss.tools.modeshape.jcr.cnd.CndImporter;
 import org.jboss.tools.modeshape.jcr.cnd.CompactNodeTypeDefinition;
 import org.jboss.tools.modeshape.jcr.ui.Activator;
-import org.jboss.tools.modeshape.jcr.ui.UiConstants;
-import org.jboss.tools.modeshape.jcr.ui.UiConstants.Images;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiConstants;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiConstants.Images;
 import org.jboss.tools.modeshape.ui.UiMessages;
 import org.jboss.tools.modeshape.ui.forms.MessageFormDialog;
 
@@ -204,7 +204,7 @@
     @Override
     protected void createHeaderContents( final IManagedForm headerForm ) {
         this.scrolledForm = headerForm.getForm();
-        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(UiConstants.Images.CND_EDITOR));
+        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(JcrUiConstants.Images.CND_EDITOR));
         this.scrolledForm.setText(CndMessages.cndEditorTitle);
 
         final Form form = this.scrolledForm.getForm();
@@ -270,7 +270,7 @@
         // IStatus status = null;
         //
         // if (!(e instanceof CoreException)) {
-        // status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, e.getLocalizedMessage());
+        // status = new Status(IStatus.ERROR, JcrUiConstants.PLUGIN_ID, e.getLocalizedMessage());
         // } else {
         // status = ((CoreException)e).getStatus();
         // }
@@ -367,7 +367,7 @@
             IStatus status = null;
 
             if (!(e instanceof CoreException)) {
-                status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, e.getLocalizedMessage());
+                status = new Status(IStatus.ERROR, JcrUiConstants.PLUGIN_ID, e.getLocalizedMessage());
             } else {
                 status = ((CoreException)e).getStatus();
             }

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndFormsEditorPage.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndFormsEditorPage.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndFormsEditorPage.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -7,11 +7,13 @@
  */
 package org.jboss.tools.modeshape.jcr.ui.cnd;
 
-import static org.jboss.tools.modeshape.jcr.ui.UiConstants.EditorIds.CND_FORMS_PAGE;
+import static org.jboss.tools.modeshape.jcr.ui.JcrUiConstants.EditorIds.CND_FORMS_PAGE;
 
 import java.beans.PropertyChangeEvent;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.jface.action.Action;
@@ -27,6 +29,7 @@
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.jface.viewers.Viewer;
@@ -42,7 +45,6 @@
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -71,10 +73,9 @@
 import org.jboss.tools.modeshape.jcr.cnd.PropertyDefinition;
 import org.jboss.tools.modeshape.jcr.cnd.QualifiedName;
 import org.jboss.tools.modeshape.jcr.ui.JcrUiUtils;
-import org.jboss.tools.modeshape.ui.Activator;
-import org.jboss.tools.modeshape.ui.UiConstants;
 import org.jboss.tools.modeshape.ui.UiMessages;
 import org.jboss.tools.modeshape.ui.UiUtils;
+import org.jboss.tools.modeshape.ui.actions.DelegateAction;
 import org.jboss.tools.modeshape.ui.forms.ErrorMessage;
 import org.jboss.tools.modeshape.ui.forms.FormUtils;
 import org.jboss.tools.modeshape.ui.forms.FormUtils.Styles;
@@ -172,9 +173,8 @@
             }
         };
         this.addChildNode.setEnabled(false);
-        this.addChildNode.setText(CndMessages.addChildNodeMenuText);
         this.addChildNode.setToolTipText(CndMessages.addChildNodeToolTip);
-        this.addChildNode.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.NEW_16X));
+        this.addChildNode.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
 
         this.deleteChildNode = new Action(Utils.EMPTY_STRING) {
 
@@ -189,9 +189,8 @@
             }
         };
         this.deleteChildNode.setEnabled(false);
-        this.deleteChildNode.setText(CndMessages.deleteChildNodeMenuText);
         this.deleteChildNode.setToolTipText(CndMessages.deleteChildNodeToolTip);
-        this.deleteChildNode.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.DELETE_16X));
+        this.deleteChildNode.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
 
         this.editChildNode = new Action(Utils.EMPTY_STRING) {
 
@@ -206,9 +205,8 @@
             }
         };
         this.editChildNode.setEnabled(false);
-        this.editChildNode.setText(CndMessages.editChildNodeMenuText);
         this.editChildNode.setToolTipText(CndMessages.editChildNodeToolTip);
-        this.editChildNode.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.EDIT_16X));
+        this.editChildNode.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
     }
 
     private void createChildNodeSection( final IManagedForm managedForm,
@@ -238,9 +236,9 @@
 
         // table context menu
         MenuManager menuManager = new MenuManager();
-        menuManager.add(this.addChildNode);
-        menuManager.add(this.editChildNode);
-        menuManager.add(this.deleteChildNode);
+        menuManager.add(new DelegateAction(CndMessages.addChildNodeMenuText, this.addChildNode));
+        menuManager.add(new DelegateAction(CndMessages.editChildNodeMenuText, this.editChildNode));
+        menuManager.add(new DelegateAction(CndMessages.deleteChildNodeMenuText, this.deleteChildNode));
         table.setMenu(menuManager.createContextMenu(table));
 
         createChildNodeViewer(table);
@@ -560,9 +558,9 @@
 
             // table context menu
             MenuManager menuManager = new MenuManager();
-            menuManager.add(this.addSuperType);
-            menuManager.add(this.editSuperType);
-            menuManager.add(this.deleteSuperType);
+            menuManager.add(new DelegateAction(CndMessages.addSuperTypeMenuText, this.addSuperType));
+            menuManager.add(new DelegateAction(CndMessages.editSuperTypeMenuText, this.editSuperType));
+            menuManager.add(new DelegateAction(CndMessages.deleteSuperTypeMenuText, this.deleteSuperType));
             table.setMenu(menuManager.createContextMenu(table));
 
             createSuperTypesViewer(table);
@@ -597,9 +595,8 @@
                 handleAddNamespace();
             }
         };
-        this.addNamespace.setText(CndMessages.addNamespaceMenuText);
         this.addNamespace.setToolTipText(CndMessages.addNamespaceToolTip);
-        this.addNamespace.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.NEW_16X));
+        this.addNamespace.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
 
         this.deleteNamespace = new Action(Utils.EMPTY_STRING) {
 
@@ -614,9 +611,8 @@
             }
         };
         this.deleteNamespace.setEnabled(false);
-        this.deleteNamespace.setText(CndMessages.deleteNamespaceMenuText);
         this.deleteNamespace.setToolTipText(CndMessages.deleteNamespaceToolTip);
-        this.deleteNamespace.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.DELETE_16X));
+        this.deleteNamespace.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
 
         this.editNamespace = new Action(Utils.EMPTY_STRING) {
 
@@ -631,9 +627,8 @@
             }
         };
         this.editNamespace.setEnabled(false);
-        this.editNamespace.setText(CndMessages.editNamespaceMenuText);
         this.editNamespace.setToolTipText(CndMessages.editNamespaceToolTip);
-        this.editNamespace.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.EDIT_16X));
+        this.editNamespace.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
     }
 
     private void createNamespaceSection( final IManagedForm managedForm,
@@ -664,9 +659,9 @@
 
         // table context menu
         MenuManager menuManager = new MenuManager();
-        menuManager.add(this.addNamespace);
-        menuManager.add(this.editNamespace);
-        menuManager.add(this.deleteNamespace);
+        menuManager.add(new DelegateAction(CndMessages.addNamespaceMenuText, this.addNamespace));
+        menuManager.add(new DelegateAction(CndMessages.editNamespaceMenuText, this.editNamespace));
+        menuManager.add(new DelegateAction(CndMessages.deleteNamespaceMenuText, this.deleteNamespace));
         table.setMenu(menuManager.createContextMenu(table));
 
         createNamespaceViewer(table);
@@ -806,9 +801,8 @@
                 handleAddNodeType();
             }
         };
-        this.addNodeType.setText(CndMessages.addNodeTypeMenuText);
         this.addNodeType.setToolTipText(CndMessages.addNodeTypeToolTip);
-        this.addNodeType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.NEW_16X));
+        this.addNodeType.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
 
         this.deleteNodeType = new Action(Utils.EMPTY_STRING) {
 
@@ -823,9 +817,8 @@
             }
         };
         this.deleteNodeType.setEnabled(false);
-        this.deleteNodeType.setText(CndMessages.deleteNodeTypeMenuText);
         this.deleteNodeType.setToolTipText(CndMessages.deleteNodeTypeToolTip);
-        this.deleteNodeType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.DELETE_16X));
+        this.deleteNodeType.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
 
         this.editNodeType = new Action(Utils.EMPTY_STRING) {
 
@@ -840,9 +833,8 @@
             }
         };
         this.editNodeType.setEnabled(false);
-        this.editNodeType.setText(CndMessages.editNodeTypeMenuText);
         this.editNodeType.setToolTipText(CndMessages.editNodeTypeToolTip);
-        this.editNodeType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.EDIT_16X));
+        this.editNodeType.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
     }
 
     @SuppressWarnings("unused")
@@ -905,9 +897,9 @@
 
             // table context menu
             MenuManager menuManager = new MenuManager();
-            menuManager.add(this.addNodeType);
-            menuManager.add(this.editNodeType);
-            menuManager.add(this.deleteNodeType);
+            menuManager.add(new DelegateAction(CndMessages.addNodeTypeMenuText, this.addNodeType));
+            menuManager.add(new DelegateAction(CndMessages.editNodeTypeMenuText, this.editNodeType));
+            menuManager.add(new DelegateAction(CndMessages.deleteNodeTypeMenuText, this.deleteNodeType));
             table.setMenu(menuManager.createContextMenu(table));
 
             createNodeTypeViewer(table);
@@ -1085,9 +1077,8 @@
             }
         };
         this.addProperty.setEnabled(false);
-        this.addProperty.setText(CndMessages.addPropertyMenuText);
         this.addProperty.setToolTipText(CndMessages.addPropertyToolTip);
-        this.addProperty.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.NEW_16X));
+        this.addProperty.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
 
         this.deleteProperty = new Action(Utils.EMPTY_STRING) {
 
@@ -1102,9 +1093,8 @@
             }
         };
         this.deleteProperty.setEnabled(false);
-        this.deleteProperty.setText(CndMessages.deletePropertyMenuText);
         this.deleteProperty.setToolTipText(CndMessages.deletePropertyToolTip);
-        this.deleteProperty.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.DELETE_16X));
+        this.deleteProperty.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
 
         this.editProperty = new Action(Utils.EMPTY_STRING) {
 
@@ -1119,9 +1109,8 @@
             }
         };
         this.editProperty.setEnabled(false);
-        this.editProperty.setText(CndMessages.editPropertyMenuText);
         this.editProperty.setToolTipText(CndMessages.editPropertyToolTip);
-        this.editProperty.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.EDIT_16X));
+        this.editProperty.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
     }
 
     private void createPropertySection( final IManagedForm managedForm,
@@ -1152,9 +1141,9 @@
 
         // table context menu
         MenuManager menuManager = new MenuManager();
-        menuManager.add(this.addProperty);
-        menuManager.add(this.editProperty);
-        menuManager.add(this.deleteProperty);
+        menuManager.add(new DelegateAction(CndMessages.addPropertyMenuText, this.addProperty));
+        menuManager.add(new DelegateAction(CndMessages.editPropertyMenuText, this.editProperty));
+        menuManager.add(new DelegateAction(CndMessages.deletePropertyMenuText, this.deleteProperty));
         table.setMenu(menuManager.createContextMenu(table));
 
         createPropertyViewer(table);
@@ -1335,9 +1324,8 @@
             }
         };
         this.addSuperType.setEnabled(false);
-        this.addSuperType.setText(CndMessages.addSuperTypeMenuText);
         this.addSuperType.setToolTipText(CndMessages.addSuperTypeToolTip);
-        this.addSuperType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.NEW_16X));
+        this.addSuperType.setImageDescriptor(JcrUiUtils.getNewImageDescriptor());
 
         this.deleteSuperType = new Action(Utils.EMPTY_STRING) {
 
@@ -1352,9 +1340,8 @@
             }
         };
         this.deleteSuperType.setEnabled(false);
-        this.deleteSuperType.setText(CndMessages.deleteSuperTypeMenuText);
         this.deleteSuperType.setToolTipText(CndMessages.deleteSuperTypeToolTip);
-        this.deleteSuperType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.DELETE_16X));
+        this.deleteSuperType.setImageDescriptor(JcrUiUtils.getDeleteImageDescriptor());
 
         this.editSuperType = new Action(Utils.EMPTY_STRING) {
 
@@ -1369,9 +1356,8 @@
             }
         };
         this.editSuperType.setEnabled(false);
-        this.editSuperType.setText(CndMessages.editSuperTypeMenuText);
         this.editSuperType.setToolTipText(CndMessages.editSuperTypeToolTip);
-        this.editSuperType.setImageDescriptor(Activator.getSharedInstance().getImageDescriptor(UiConstants.Images.EDIT_16X));
+        this.editSuperType.setImageDescriptor(JcrUiUtils.getEditImageDescriptor());
     }
 
     private void createSuperTypesViewer( final Table superTypesTable ) {
@@ -1446,11 +1432,6 @@
         });
     }
 
-    private Image getCndEditorImage() {
-        return org.jboss.tools.modeshape.jcr.ui.Activator.getSharedInstance()
-                                                         .getImage(org.jboss.tools.modeshape.jcr.ui.UiConstants.Images.CND_EDITOR);
-    }
-
     private List<String> getNamespacePrefixes() {
         final List<NamespaceMapping> namespaces = getCnd().getNamespaceMappings();
 
@@ -1553,9 +1534,40 @@
         getSelectedNodeType().setAbstract(newValue);
     }
 
+    Collection<QualifiedName> getChildNodeNames() {
+        assert (getSelectedNodeType() != null) : "Add child node handler called but no selected node type"; //$NON-NLS-1$
+        Collection<ChildNodeDefinition> childNodes = getSelectedNodeType().getChildNodeDefinitions();
+
+        if (childNodes.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Collection<QualifiedName> childNodeNames = new ArrayList<QualifiedName>(childNodes.size());
+
+        for (ChildNodeDefinition childNode : childNodes) {
+            if (!Utils.isEmpty(childNode.getName())) {
+                childNodeNames.add(childNode.getQualifiedName());
+            }
+        }
+
+        return childNodeNames;
+    }
+
     void handleAddChildNode() {
-        // TODO handleAddChildNode
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        assert (getSelectedNodeType() != null) : "add child node handler called but there is no selected node type"; //$NON-NLS-1$
+
+        ChildNodeDialog dialog = new ChildNodeDialog(getShell(), getChildNodeNames(), getNamespacePrefixes());
+        dialog.create();
+        dialog.getShell().pack();
+
+        if (dialog.open() == Window.OK) {
+            ChildNodeDefinition newChildNodeDefinition = dialog.getChildNodeDefinition();
+
+            // select new child node definition
+            if (getSelectedNodeType().addChildNodeDefinition(newChildNodeDefinition)) {
+                this.childNodeViewer.setSelection(new StructuredSelection(newChildNodeDefinition));
+            }
+        }
     }
 
     void handleAddNamespace() {
@@ -1569,7 +1581,7 @@
             if (getCnd().addNamespaceMapping(namespaceMapping)) {
                 this.namespaceViewer.refresh();
             } else {
-                MessageFormDialog.openError(getShell(), UiMessages.errorDialogTitle, getCndEditorImage(),
+                MessageFormDialog.openError(getShell(), UiMessages.errorDialogTitle, JcrUiUtils.getCndEditorImage(),
                                             NLS.bind(CndMessages.errorAddingNamespaceMapping, namespaceMapping));
             }
         }
@@ -1577,12 +1589,12 @@
 
     void handleAddNodeType() {
         // TODO handleAddNodeType
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented"); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     void handleAddProperty() {
         // TODO handleAddProperty
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented"); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     void handleAddSuperType() {
@@ -1603,7 +1615,7 @@
             if (nodeTypeDefinition.addSuperType(newQName.get())) {
                 this.superTypesViewer.refresh();
             } else {
-                MessageFormDialog.openError(getShell(), UiMessages.errorDialogTitle, getCndEditorImage(),
+                MessageFormDialog.openError(getShell(), UiMessages.errorDialogTitle, JcrUiUtils.getCndEditorImage(),
                                             NLS.bind(CndMessages.errorAddingSupertype, newQName));
             }
         }
@@ -1657,7 +1669,7 @@
         }
 
         // show confirmation dialog
-        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteChildNodeDialogTitle, getCndEditorImage(),
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteChildNodeDialogTitle, JcrUiUtils.getCndEditorImage(),
                                            NLS.bind(CndMessages.deleteChildNodeDialogMessage, name))) {
             getSelectedNodeType().removeChildNodeDefinition(childNodeDefinition);
         }
@@ -1674,7 +1686,7 @@
         }
 
         // show confirmation dialog
-        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteNamespaceDialogTitle, getCndEditorImage(),
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteNamespaceDialogTitle, JcrUiUtils.getCndEditorImage(),
                                            NLS.bind(CndMessages.deleteNamespaceDialogMessage, prefix))) {
             getCnd().removeNamespaceMapping(namespaceMapping);
         }
@@ -1691,7 +1703,7 @@
         }
 
         // show confirmation dialog
-        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteNodeTypeDialogTitle, getCndEditorImage(),
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteNodeTypeDialogTitle, JcrUiUtils.getCndEditorImage(),
                                            NLS.bind(CndMessages.deleteNodeTypeDialogMessage, name))) {
             getCnd().removeNodeTypeDefinition(nodeTypeDefinition);
         }
@@ -1709,7 +1721,7 @@
         }
 
         // show confirmation dialog
-        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deletePropertyDialogTitle, getCndEditorImage(),
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deletePropertyDialogTitle, JcrUiUtils.getCndEditorImage(),
                                            NLS.bind(CndMessages.deletePropertyDialogMessage, name))) {
             getSelectedNodeType().removePropertyDefinition(propertyDefinition);
         }
@@ -1721,21 +1733,33 @@
 
         String superTypeName = getSelectedSuperType();
 
+        // should always have a name but just in case
         if (Utils.isEmpty(superTypeName)) {
             superTypeName = Messages.missingName;
         }
 
         // show confirmation dialog
-        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteSuperTypeDialogTitle, getCndEditorImage(),
+        if (MessageFormDialog.openQuestion(getShell(), CndMessages.deleteSuperTypeDialogTitle, JcrUiUtils.getCndEditorImage(),
                                            NLS.bind(CndMessages.deleteSuperTypeDialogMessage, superTypeName))) {
             getSelectedNodeType().removeSuperType(superTypeName);
         }
     }
 
     void handleEditChildNode() {
-        assert (getSelectedChildNode() != null) : "Edit child node handler has been called when there is no child node selected"; //$NON-NLS-1$
-        // TODO handleEditChildNode
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        assert (getSelectedNodeType() != null) : "edit child node handler called but there is no selected node type"; //$NON-NLS-1$
+        assert (getSelectedChildNode() != null) : "edit child node handler has been called when there is no child node selected"; //$NON-NLS-1$
+
+        ChildNodeDefinition childNodeBeingEdited = getSelectedChildNode();
+        ChildNodeDialog dialog = new ChildNodeDialog(getShell(), getChildNodeNames(), getNamespacePrefixes(), childNodeBeingEdited);
+        dialog.create();
+        dialog.getShell().pack();
+
+        if (dialog.open() == Window.OK) {
+            NodeTypeDefinition nodeTypeDefinition = getSelectedNodeType();
+            ChildNodeDefinition newChildNodeDefinition = dialog.getChildNodeDefinition();
+            nodeTypeDefinition.removeChildNodeDefinition(childNodeBeingEdited);
+            nodeTypeDefinition.addChildNodeDefinition(newChildNodeDefinition);
+        }
     }
 
     void handleEditNamespace() {
@@ -1760,14 +1784,13 @@
 
                 if (getCnd().addNamespaceMapping(modifiedNamespaceMapping)) {
                     added = true;
-                    this.namespaceViewer.refresh();
                 }
             }
 
             if (!removed || !added) {
                 MessageFormDialog.openError(getShell(),
                                             UiMessages.errorDialogTitle,
-                                            getCndEditorImage(),
+                                            JcrUiUtils.getCndEditorImage(),
                                             NLS.bind(CndMessages.errorEditingNamespaceMapping, new Object[] {
                                                     modifiedNamespaceMapping, removed, added }));
             }
@@ -1777,13 +1800,13 @@
     void handleEditNodeType() {
         assert (getSelectedNodeType() != null) : "Edit node type handler has been called when there is no node type selected"; //$NON-NLS-1$
         // TODO handleEditNodeType
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented"); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     void handleEditProperty() {
         assert (getSelectedProperty() != null) : "Edit property handler has been called when there is no property selected"; //$NON-NLS-1$
         // TODO handleEditProperty
-        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented");
+        MessageFormDialog.openInfo(getShell(), "Not Implemented Yet", null, "method has not be implemented"); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     void handleEditSuperType() {
@@ -1811,14 +1834,13 @@
 
                 if (nodeTypeDefinition.addSuperType(modifiedSuperType.get())) {
                     added = true;
-                    this.superTypesViewer.refresh();
                 }
             }
 
             if (!removed || !added) {
                 MessageFormDialog.openError(getShell(),
                                             UiMessages.errorDialogTitle,
-                                            getCndEditorImage(),
+                                            JcrUiUtils.getCndEditorImage(),
                                             NLS.bind(CndMessages.errorEditingSupertype, new Object[] { modifiedSuperType, removed,
                                                     added }));
             }

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndMessages.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndMessages.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/CndMessages.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -16,12 +16,12 @@
 class CndMessages extends NLS {
 
     /**
-     * The abstract attribute name suitable for a radio or check button.
+     * A name for the abstract attribute name for a radio or check button.
      */
     public static String abstractAttribute;
 
     /**
-     * The tool tip message of the node type definition's abstract attribute.
+     * A tool tip message of the node type definition's abstract attribute.
      */
     public static String abstractAttributeToolTip;
 
@@ -77,12 +77,22 @@
     public static String addPropertyToolTip;
 
     /**
+     * The context menu item text for the add required type action.
+     */
+    public static String addRequiredTypeMenuText;
+
+    /**
+     * The tool tip message of the add required type action.
+     */
+    public static String addRequiredTypeToolTip;
+
+    /**
      * The context menu item text for the add supertype action.
      */
     public static String addSuperTypeMenuText;
 
     /**
-     * The tool tip message of the add property definition action.
+     * The tool tip message of the add supertype action.
      */
     public static String addSuperTypeToolTip;
 
@@ -92,16 +102,51 @@
     public static String attributesHeaderText;
 
     /**
+     * A name for the autocreated attribute suitable for a radio or check button.
+     */
+    public static String autocreatedAttribute;
+
+    /**
+     * A tool tip message of a child node definition's and property definition's autocreated attribute.
+     */
+    public static String autocreatedAttributeToolTip;
+
+    /**
      * The tool tip for the attributes of a child node definition.
      */
     public static String childNodeAttributesToolTip;
 
     /**
+     * A label for the default type of a child node definition.
+     */
+    public static String childNodeDefaultTypeLabel;
+
+    /**
      * The tool tip text for the default type of a child node definition.
      */
     public static String childNodeDefaultTypeToolTip;
 
     /**
+     * The message area title of the child node definition dialog when creating a new child node.
+     */
+    public static String childNodeDialogCreateTitle;
+
+    /**
+     * The message area title of the child node definition dialog when an existing child node is being edited.
+     */
+    public static String childNodeDialogEditTitle;
+
+    /**
+     * The message displayed in the child node dialog when first displayed.
+     */
+    public static String childNodeDialogMsg;
+
+    /**
+     * The title of the child node definition dialog.
+     */
+    public static String childNodeDialogTitle;
+
+    /**
      * The tool tip for a child node definition name.
      */
     public static String childNodeNameToolTip;
@@ -112,18 +157,18 @@
     public static String childNodeRequiredTypesToolTip;
 
     /**
+     * The message of the dialog shown within the CND editor when the editor notices that the CND file has been changed outside the
+     * editor. One parameter, the file name, is expected.
+     */
+    public static String cndChangedOnFileSystemDialogMsg;
+
+    /**
      * The title of the dialog shown within the CND editor when the editor notices that the CND file has been changed outside the
      * editor.
      */
     public static String cndChangedOnFileSystemDialogTitle;
 
     /**
-     * The message of the dialog shown within the CND editor when the editor notices that the CND file has been changed outside the
-     * editor. One parameter, the file name, is expected.
-     */
-    public static String cndChangedOnFileSystemDialogMsg;
-
-    /**
      * The description of the child node definition section in the CND editor's form page.
      */
     public static String cndEditorChildNodeSectionDescription;
@@ -202,14 +247,14 @@
     public static String cndEditorPropertySectionTitle;
 
     /**
-     * The title of the dialog shown when refreshing the CND editor with the CND file from the file system fails.
+     * The message of the dialog shown when refreshing the CND editor with the CND file from the file system fails.
      */
-    public static String cndEditorRefreshErrorTitle;
+    public static String cndEditorRefreshErrorMsg;
 
     /**
-     * The message of the dialog shown when refreshing the CND editor with the CND file from the file system fails.
+     * The title of the dialog shown when refreshing the CND editor with the CND file from the file system fails.
      */
-    public static String cndEditorRefreshErrorMsg;
+    public static String cndEditorRefreshErrorTitle;
 
     /**
      * The message of an error dialog shown when saving the CND editor fails.
@@ -320,12 +365,32 @@
     public static String deletePropertyToolTip;
 
     /**
-     * The question message of the dialog for deleting a super type. One parameter, the super type name, is required.
+     * The question message of the dialog for deleting a required type. One parameter, the required type name, is required.
      */
+    public static String deleteRequiredTypeDialogMessage;
+
+    /**
+     * The title of the dialog for deleting a required type.
+     */
+    public static String deleteRequiredTypeDialogTitle;
+
+    /**
+     * The context menu item text for the delete required type action.
+     */
+    public static String deleteRequiredTypeMenuText;
+
+    /**
+     * The tool tip message of the delete required type action.
+     */
+    public static String deleteRequiredTypeToolTip;
+
+    /**
+     * The question message of the dialog for deleting a supertype. One parameter, the super type name, is required.
+     */
     public static String deleteSuperTypeDialogMessage;
 
     /**
-     * The title of the dialog for deleting a super type.
+     * The title of the dialog for deleting a supertype.
      */
     public static String deleteSuperTypeDialogTitle;
 
@@ -335,7 +400,7 @@
     public static String deleteSuperTypeMenuText;
 
     /**
-     * The tool tip message of the delete super type action.
+     * The tool tip message of the delete supertype action.
      */
     public static String deleteSuperTypeToolTip;
 
@@ -385,6 +450,21 @@
     public static String editPropertyToolTip;
 
     /**
+     * The qualified name editor dialog message area title when editing an existing required type.
+     */
+    public static String editRequiredTypeDialogTitle;
+
+    /**
+     * The context menu item text for the edit required type action.
+     */
+    public static String editRequiredTypeMenuText;
+
+    /**
+     * The tool tip message of the edit required type action.
+     */
+    public static String editRequiredTypeToolTip;
+
+    /**
      * The qualified name editor dialog message area title when editing an existing supertype.
      */
     public static String editSuperTypeDialogTitle;
@@ -395,38 +475,60 @@
     public static String editSuperTypeMenuText;
 
     /**
-     * The tool tip message of the edit super type action.
+     * The tool tip message of the edit supertype action.
      */
     public static String editSuperTypeToolTip;
 
     /**
+     * An error message indicating the new namespace mapping was not added to the CND. One parameter, the namespace mapping, is
+     * required.
+     */
+    public static String errorAddingNamespaceMapping;
+
+    /**
+     * An error message indicating the new required type was not added to the child node definition. One parameter, the required
+     * type, is required.
+     */
+    public static String errorAddingRequiredType;
+
+    /**
+     * An error message indicating the new supertype was not added to the node type definition. One parameter, the supertype, is
+     * required.
+     */
+    public static String errorAddingSupertype;
+
+    /**
      * An error message indicating the updated namespace mapping did not get saved to the CND. Three parameters, the namespace
      * mapping, a flag indicating if the remove succeeded, and a flag indicating if the add succeeded, are required.
      */
     public static String errorEditingNamespaceMapping;
 
     /**
+     * An error message indicating the updated required type did not get saved to the CND. Three parameters, the required type, a
+     * flag indicating if the remove succeeded, and a flag indicating if the add succeeded, are required.
+     */
+    public static String errorEditingRequiredType;
+
+    /**
      * An error message indicating the updated supertype did not get saved to the CND. Three parameters, the supertype, a flag
      * indicating if the remove succeeded, and a flag indicating if the add succeeded, are required.
      */
     public static String errorEditingSupertype;
 
     /**
-     * An error message indicating the new supertype was not added to the node type definition. One parameter, the supertype, is
-     * required.
+     * The error message when the CND editor could not be opened.
      */
-    public static String errorAddingSupertype;
+    public static String errorOpeningCndEditor;
 
     /**
-     * An error message indicating the new namespace mapping was not added to the CND. One parameter, the namespace mapping, is
-     * required.
+     * A name for the mandatory attribute suitable for a radio or check button.
      */
-    public static String errorAddingNamespaceMapping;
+    public static String mandatoryAttribute;
 
     /**
-     * The error message when the CND editor could not be opened.
+     * A tool tip message of the child node definition's and property definition's mandatory attribute.
      */
-    public static String errorOpeningCndEditor;
+    public static String mandatoryAttributeToolTip;
 
     /**
      * A message indicating there is no value.
@@ -434,12 +536,12 @@
     public static String missingValue;
 
     /**
-     * The mixin attribute name suitable for a radio or check button.
+     * A name for the mixin attribute suitable for a radio or check button.
      */
     public static String mixinAttribute;
 
     /**
-     * The tool tip message of the node type definition's mixin attribute.
+     * A tool tip message of the node type definition's mixin attribute.
      */
     public static String mixinAttributeToolTip;
 
@@ -449,6 +551,11 @@
     public static String nameHeaderText;
 
     /**
+     * A label for a generic name control.
+     */
+    public static String nameLabel;
+
+    /**
      * The message displayed in the namespace mapping dialog when first displayed.
      */
     public static String namespaceDialogMsg;
@@ -459,11 +566,6 @@
     public static String namespaceDialogTitle;
 
     /**
-     * A label for a generic name control.
-     */
-    public static String nameLabel;
-
-    /**
      * A label for a namespace mapping control.
      */
     public static String namespaceLabel;
@@ -494,14 +596,14 @@
     public static String namespaceUriToolTip;
 
     /**
-     * The message displayed in the node type name pattern filter when the pattern is empty.
+     * The namespace editor dialog message area title when creating a new namespace mapping.
      */
-    public static String nodeTypeNamePatternMessage;
+    public static String newNamespaceDialogTitle;
 
     /**
-     * The namespace editor dialog message area title when creating a new namespace mapping.
+     * The qualified name editor dialog message area title when creating a new required type.
      */
-    public static String newNamespaceDialogTitle;
+    public static String newRequiredTypeDialogTitle;
 
     /**
      * The qualified name editor dialog message area title when creating a new supertype.
@@ -514,6 +616,11 @@
     public static String nodeTypeNameHeaderText;
 
     /**
+     * The message displayed in the node type name pattern filter when the pattern is empty.
+     */
+    public static String nodeTypeNamePatternMessage;
+
+    /**
      * The tool tip for a node type definition name.
      */
     public static String nodeTypeNameToolTip;
@@ -524,12 +631,22 @@
     public static String noNameQualifierChoice;
 
     /**
-     * The orderable attribute name suitable for a radio or check button.
+     * A label for an on parent version attribute control.
      */
+    public static String onParentVersionLabel;
+
+    /**
+     * A tool tip message of a child node definition's and property definition's on parent version attribute.
+     */
+    public static String onParentVersionToolTip;
+
+    /**
+     * A name for the orderable attribute suitable for a radio or check button.
+     */
     public static String orderableAttribute;
 
     /**
-     * The tool tip message of the node type definition's orderable attribute.
+     * A tool tip message of the node type definition's orderable attribute.
      */
     public static String orderableAttributeToolTip;
 
@@ -559,6 +676,16 @@
     public static String propertyValueConstraintsToolTip;
 
     /**
+     * A name for the protected attribute suitable for a radio or check button.
+     */
+    public static String protectedAttribute;
+
+    /**
+     * A tool tip message of the child node definition's and property definition's protected attribute.
+     */
+    public static String protectedAttributeToolTip;
+
+    /**
      * The message displayed in the qualified name dialog when first displayed. One parameter, the type of qualified name, is
      * required.
      */
@@ -575,12 +702,12 @@
     public static String qualifierLabel;
 
     /**
-     * The queryable attribute name suitable for a radio or check button.
+     * A name for the queryable attribute suitable for a radio or check button.
      */
     public static String queryableAttribute;
 
     /**
-     * The tool tip message of the node type definition's queryable attribute.
+     * A tool tip message of the node type definition's queryable attribute.
      */
     public static String queryableAttributeToolTip;
 
@@ -590,6 +717,21 @@
     public static String requiredTypesHeaderText;
 
     /**
+     * A label for a required types control.
+     */
+    public static String requiredTypesLabel;
+
+    /**
+     * A name for the same named siblings attribute suitable for a radio or check button.
+     */
+    public static String sameNamedSiblingsAttribute;
+
+    /**
+     * A tool tip message of a child node definition's same named siblings attribute.
+     */
+    public static String sameNamedSiblingsAttributeToolTip;
+
+    /**
      * A label for a supertypes control.
      */
     public static String supertypesLabel;

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/NamespaceMappingDialog.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/NamespaceMappingDialog.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/NamespaceMappingDialog.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -32,7 +32,7 @@
 import org.jboss.tools.modeshape.jcr.cnd.CndValidator;
 import org.jboss.tools.modeshape.jcr.cnd.NamespaceMapping;
 import org.jboss.tools.modeshape.jcr.ui.Activator;
-import org.jboss.tools.modeshape.jcr.ui.UiConstants;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiConstants;
 import org.jboss.tools.modeshape.ui.forms.FormUtils.Styles;
 
 /**
@@ -135,7 +135,7 @@
     protected void createFormContent( final IManagedForm managedForm ) {
         this.scrolledForm = managedForm.getForm();
         this.scrolledForm.setText(isEditMode() ? CndMessages.editNamespaceDialogTitle : CndMessages.newNamespaceDialogTitle);
-        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(UiConstants.Images.CND_EDITOR));
+        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(JcrUiConstants.Images.CND_EDITOR));
         this.scrolledForm.setMessage(CndMessages.namespaceDialogMsg, IMessageProvider.NONE);
 
         final FormToolkit toolkit = managedForm.getToolkit();

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/QualifiedNameDialog.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/QualifiedNameDialog.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/QualifiedNameDialog.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -36,7 +36,7 @@
 import org.jboss.tools.modeshape.jcr.cnd.CndValidator;
 import org.jboss.tools.modeshape.jcr.cnd.QualifiedName;
 import org.jboss.tools.modeshape.jcr.ui.Activator;
-import org.jboss.tools.modeshape.jcr.ui.UiConstants;
+import org.jboss.tools.modeshape.jcr.ui.JcrUiConstants;
 import org.jboss.tools.modeshape.ui.forms.FormUtils.Styles;
 
 /**
@@ -47,10 +47,10 @@
     private Button btnOk;
 
     /**
-     * An optional list of existing qualified names. When this is non-empty, it is checked to make sure the qualified name being
-     * edited is not a duplicate.
+     * An optional collection of existing qualified names. When this is non-empty, it is checked to make sure the qualified name
+     * being edited is not a duplicate.
      */
-    private List<QualifiedName> existingQNames;
+    private Collection<QualifiedName> existingQNames;
 
     /**
      * The qualified name being edited or <code>null</code> when creating a qualified name.
@@ -121,7 +121,7 @@
      * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
      */
     @Override
-    protected void configureShell( Shell newShell ) {
+    protected void configureShell( final Shell newShell ) {
         super.configureShell(newShell);
         newShell.setText(CndMessages.qualifiedNameDialogTitle);
     }
@@ -156,7 +156,7 @@
     protected void createFormContent( final IManagedForm managedForm ) {
         this.scrolledForm = managedForm.getForm();
         this.scrolledForm.setText(this.title);
-        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(UiConstants.Images.CND_EDITOR));
+        this.scrolledForm.setImage(Activator.getSharedInstance().getImage(JcrUiConstants.Images.CND_EDITOR));
         this.scrolledForm.setMessage(NLS.bind(CndMessages.qualifiedNameDialogMsg, this.qualifiedNameType), IMessageProvider.NONE);
 
         final FormToolkit toolkit = managedForm.getToolkit();
@@ -273,10 +273,16 @@
     /**
      * @param existingQNames used to check against for duplicate qualified names (can be <code>null</code> or empty)
      */
-    void setExistingQNames( final List<QualifiedName> existingQNames ) {
-        if (!Utils.isEmpty(this.existingQNames) && isEditMode()) {
+    void setExistingQNames( final Collection<QualifiedName> existingQNames ) {
+        if (Utils.isEmpty(existingQNames)) {
+            this.existingQNames = null;
+        } else {
             this.existingQNames = new ArrayList<QualifiedName>(existingQNames);
-            this.existingQNames.remove(this.qnameBeingEdited); // so that validating won't show it as a duplicate
+
+            // so that validating won't show it as a duplicate
+            if (isEditMode()) {
+                this.existingQNames.remove(this.qnameBeingEdited);
+            }
         }
     }
 

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/cndMessages.properties
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/cndMessages.properties	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.jcr.ui/src/org/jboss/tools/modeshape/jcr/ui/cnd/cndMessages.properties	2012-03-20 20:14:13 UTC (rev 39677)
@@ -9,18 +9,27 @@
 acceptNamespaceDialogMsg = Select OK to accept the changes to the namespace mapping.
 acceptQualifiedNameDialogMsg = Select OK to accept the changes to the "{0}" qualified name.
 addChildNodeMenuText = Add Child Node
-addChildNodeToolTip = Add a child node definition
+addChildNodeToolTip = Add a child node definition to the node type definition
 addNamespaceMenuText = Add Namespace
-addNamespaceToolTip = Add a namespace mapping
+addNamespaceToolTip = Add a namespace mapping to the CND
 addNodeTypeMenuText = Add Node Type
-addNodeTypeToolTip = Add a node type definition
+addNodeTypeToolTip = Add a node type definition to the CND
 addPropertyMenuText = Add Property
-addPropertyToolTip = Add a property definition
+addPropertyToolTip = Add a property definition to the node type definition
+addRequiredTypeMenuText = Add Required Type
+addRequiredTypeToolTip = Add a required type to the child node definition
 addSuperTypeMenuText = Add Supertype
-addSuperTypeToolTip = Add a supertype
+addSuperTypeToolTip = Add a supertype to the node type definition
 attributesHeaderText = Attributes
+autocreatedAttribute = Autocreated
+autocreatedAttributeToolTip = Indicates if the child node definition is autocreated when it's node type definition is created
 childNodeAttributesToolTip = The attributes of a child node definition (autocreated, mandatory, abstract, opv, sns)
+childNodeDefaultTypeLabel = Default Type:
 childNodeDefaultTypeToolTip = The default type of a child node definition
+childNodeDialogCreateTitle = Create Child Node
+childNodeDialogEditTitle = Edit Child Node
+childNodeDialogMsg = Specify child node properties then select OK when finished.
+childNodeDialogTitle = Child Node Definition Editor
 childNodeNameToolTip = The name of a child node definition
 childNodeRequiredTypesToolTip = The required types of a child node definition
 cndChangedOnFileSystemDialogTitle = CND File Changed
@@ -55,12 +64,12 @@
 deleteChildNodeDialogMessage = Are you sure you want to delete the "{0}" child node definition?
 deleteChildNodeDialogTitle = Delete Child Node
 deleteChildNodeMenuText = Delete Child Node
-deleteChildNodeToolTip = Delete the selected child node definition
+deleteChildNodeToolTip = Delete the selected child node definition from the node type definition
 # 0 = namespace mapping prefix
 deleteNamespaceDialogMessage = Are you sure you want to delete the namespace mapping with prefix "{0}"?
 deleteNamespaceDialogTitle = Delete Namespace
 deleteNamespaceMenuText = Delete Namespace
-deleteNamespaceToolTip = Delete the selected namespace mapping
+deleteNamespaceToolTip = Delete the selected namespace mapping from the CND
 # 0 = node type definition name
 deleteNodeTypeDialogMessage = Are you sure you want to delete the "{0}" node type definition?
 deleteNodeTypeDialogTitle = Delete Node Type
@@ -70,35 +79,47 @@
 deletePropertyDialogMessage = Are you sure you want to delete the "{0}" property definition?
 deletePropertyDialogTitle = Delete Property
 deletePropertyMenuText = Delete Property
-deletePropertyToolTip = Delete the selected property definition
+deletePropertyToolTip = Delete the selected property definition from the node type definition
+# 0 = required type name
+deleteRequiredTypeDialogMessage = Are you sure you want to delete the "{0}" required type?
+deleteRequiredTypeDialogTitle = Delete Required Type
+deleteRequiredTypeMenuText = Delete Required Type
+deleteRequiredTypeToolTip = Delete the selected required type from the child node definition
 # 0 = supertype name
 deleteSuperTypeDialogMessage = Are you sure you want to delete the "{0}" supertype?
 deleteSuperTypeDialogTitle = Delete Supertype
 deleteSuperTypeMenuText = Delete Supertype
-deleteSuperTypeToolTip = Delete the selected supertype
+deleteSuperTypeToolTip = Delete the selected supertype from the node type definition
 editChildNodeMenuText = Edit Child Node
-editChildNodeToolTip = Edit the selected child node definition
+editChildNodeToolTip = Edit the selected child node definition of the selected node type definition
 editNamespaceDialogTitle = Edit Namespace
 editNamespaceMenuText = Edit Namespace
-editNamespaceToolTip = Edit the selected namespace mapping
+editNamespaceToolTip = Edit the selected namespace mapping of the CND
 editNodeTypeMenuText = Edit Node Type
-editNodeTypeToolTip = Edit the selected node type definition
+editNodeTypeToolTip = Edit the selected node type definition of the CND
 editPropertyMenuText = Edit Property
-editPropertyToolTip = Edit the selected property definition
+editPropertyToolTip = Edit the selected property definition of the selected node type definition
+editRequiredTypeDialogTitle = Edit Required Type
+editRequiredTypeMenuText = Edit Required Type
+editRequiredTypeToolTip = Edit the selected required type of the selected child node definition
 editSuperTypeDialogTitle = Edit Supertype
 editSuperTypeMenuText = Edit Supertype
-editSuperTypeToolTip = Edit the selected supertype
+editSuperTypeToolTip = Edit the selected supertype of the selected node type definition
 errorAddingNamespaceMapping = There was an unexpected error adding namespace mapping "{0}" to the CND.
+errorAddingRequiredType = There was an unexpected error adding required type "{0}" to the child node definition.
 errorAddingSupertype = There was an unexpected error adding supertype "{0}" to the CND.
 errorEditingNamespaceMapping = There was an unexpected error updating namespace mapping "{0}" to the CND.\nThe remove command result: {1}. The add command result: {2}.
+errorEditingRequiredType = There was an unexpected error updating required type "{0}" to the CND.\nThe remove command result: {1}. The add command result: {2}.
 errorEditingSupertype = There was an unexpected error updating supertype "{0}" to the CND.\nThe remove command result: {1}. The add command result: {2}.
 errorOpeningCndEditor = There was a problem creating the CND editor.
+mandatoryAttribute = Mandatory
+mandatoryAttributeToolTip = Indicates if the child node must exist
 missingValue = <missing>
 mixinAttribute = Mixin
 mixinAttributeToolTip = Indicates if the node type definition is a mixin and not a primary node type
 nameLabel = Name:
 nameHeaderText = Name
-namespaceDialogMsg = Enter a unique prefix and a unique URI.\nSelect OK when finished editing.
+namespaceDialogMsg = Enter a unique prefix and a unique URI.
 namespaceDialogTitle = Namespace Editor
 namespaceLabel = Namespace:
 namespacePrefixHeaderText = Prefix
@@ -106,12 +127,15 @@
 namespacePrefixToolTip = The prefix of the namespace mapping. Must be unique within a CND.
 namespaceUriHeaderText = URI
 namespaceUriToolTip = The URI of the namespace mapping. Must be unique with a CND.
-newNamespaceDialogTitle = Create Namespace
-newSuperTypeDialogTitle = Create Supertype
+newNamespaceDialogTitle = New Namespace
+newRequiredTypeDialogTitle = New Required Type
+newSuperTypeDialogTitle = New Supertype
 nodeTypeNamePatternMessage = enter name pattern
 nodeTypeNameHeaderText = Node Type Name
 nodeTypeNameToolTip = The name of the node type definition
 noNameQualifierChoice = <no qualifier>
+onParentVersionLabel = On Parent Version:
+onParentVersionToolTip = Indicates what happens to the child node when the parent is created
 orderableAttribute = Orderable
 orderableAttributeToolTip = Indicates if the node type definition's are ordered
 propertyAttributesToolTip = The attributes of a property definition (autocreated, mandatory, multiple, nofulltext, noqueryorder, abstract, opv, queryops)
@@ -119,13 +143,18 @@
 propertyNameToolTip = The name or identifier of the property definition
 propertyTypeToolTip = The data type of the property definition
 propertyValueConstraintsToolTip = The value constraints of a property definition
-qualifiedNameDialogMsg = Select a qualifier and edit the name value of the {0}.\nSelect OK when finished editing.
+protectedAttribute = Protected
+protectedAttributeToolTip = Indicates if child nodes of this type are protected from being deleted.
+qualifiedNameDialogMsg = Select a qualifier and edit the name value of the {0}.
 qualifiedNameDialogTitle = Qualified Name Editor
 qualifierLabel = Qualifier:
 queryableAttribute = Queryable
-queryableAttributeToolTip = Indicates if the node type can be queried
+queryableAttributeToolTip = Indicates if the child node definition supports siblings of the same name
+requiredTypesHeaderText = Required Types
+requiredTypesLabel = Required Types:
+sameNamedSiblingsAttribute = Same Named Siblings
+sameNamedSiblingsAttributeToolTip = Indicates if the node type can be queried
 supertypesLabel = Supertypes:
-requiredTypesHeaderText = Required Types
 typeHeaderText = Type
 unqualifiedNameToolTip = The name part of the qualified name (cannot be empty)
 validQualifiersToolTip = The qualifiers known to this CND

Modified: trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/META-INF/MANIFEST.MF
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/META-INF/MANIFEST.MF	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/META-INF/MANIFEST.MF	2012-03-20 20:14:13 UTC (rev 39677)
@@ -12,6 +12,7 @@
  org.eclipse.ui,
  org.eclipse.core.runtime
 Export-Package: org.jboss.tools.modeshape.ui,
+ org.jboss.tools.modeshape.ui.actions,
  org.jboss.tools.modeshape.ui.forms,
  org.jboss.tools.modeshape.ui.graphics
 Bundle-Activator: org.jboss.tools.modeshape.ui.Activator

Added: trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/DelegateAction.java
===================================================================
--- trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/DelegateAction.java	                        (rev 0)
+++ trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/DelegateAction.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
+ *
+ * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
+ */
+package org.jboss.tools.modeshape.ui.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.swt.events.HelpListener;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * The <code>DelegateAction</code> class is an action that requires a delegate action. It can be used to override behavior of the
+ * delegate. One use would be to have the delegate not to provide any text itself. The delegate action could be used for a toolbar
+ * action which does not need text. At the same time, the delegate action could be used in this class. This class could provide text
+ * so that the same action could be used as a menu item.
+ */
+public class DelegateAction extends Action {
+
+    /**
+     * The delegate action (never <code>null</code>).
+     */
+    private final IAction delegate;
+
+    /**
+     * @param delegate the delegate action (cannot be <code>null</code>)
+     */
+    public DelegateAction( final IAction delegate ) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * @param text
+     * @param delegate
+     */
+    public DelegateAction( final String text,
+                           final IAction delegate ) {
+        super(text);
+        this.delegate = delegate;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+     */
+    @Override
+    public void addPropertyChangeListener( final IPropertyChangeListener listener ) {
+        this.delegate.addPropertyChangeListener(listener);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getAccelerator()
+     */
+    @Override
+    public int getAccelerator() {
+        if (super.getAccelerator() == -1) {
+            return this.delegate.getAccelerator();
+        }
+
+        return super.getAccelerator();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getActionDefinitionId()
+     */
+    @Override
+    public String getActionDefinitionId() {
+        if (super.getActionDefinitionId() == null) {
+            return this.delegate.getActionDefinitionId();
+        }
+
+        return super.getActionDefinitionId();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getDescription()
+     */
+    @Override
+    public String getDescription() {
+        if (super.getDescription() == null) {
+            return this.delegate.getDescription();
+        }
+
+        return super.getDescription();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getDisabledImageDescriptor()
+     */
+    @Override
+    public ImageDescriptor getDisabledImageDescriptor() {
+        if (super.getDisabledImageDescriptor() == null) {
+            return this.delegate.getDisabledImageDescriptor();
+        }
+
+        return super.getDisabledImageDescriptor();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getHelpListener()
+     */
+    @Override
+    public HelpListener getHelpListener() {
+        if (super.getHelpListener() == null) {
+            return this.delegate.getHelpListener();
+        }
+
+        return super.getHelpListener();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getHoverImageDescriptor()
+     */
+    @Override
+    public ImageDescriptor getHoverImageDescriptor() {
+        if (super.getHoverImageDescriptor() == null) {
+            return this.delegate.getHoverImageDescriptor();
+        }
+
+        return super.getHoverImageDescriptor();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getId()
+     */
+    @Override
+    public String getId() {
+        if (super.getId() == null) {
+            return this.delegate.getId();
+        }
+
+        return super.getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getImageDescriptor()
+     */
+    @Override
+    public ImageDescriptor getImageDescriptor() {
+        if (super.getImageDescriptor() == null) {
+            return this.delegate.getImageDescriptor();
+        }
+
+        return super.getImageDescriptor();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getMenuCreator()
+     */
+    @Override
+    public IMenuCreator getMenuCreator() {
+        if (super.getMenuCreator() == null) {
+            return this.delegate.getMenuCreator();
+        }
+
+        return super.getMenuCreator();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getStyle()
+     */
+    @Override
+    public int getStyle() {
+        if (super.getStyle() == IAction.AS_PUSH_BUTTON) {
+            return this.delegate.getStyle();
+        }
+
+        return super.getStyle();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#getToolTipText()
+     */
+    @Override
+    public String getToolTipText() {
+        if (super.getToolTipText() == null) {
+            return this.delegate.getToolTipText();
+        }
+
+        return super.getToolTipText();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
+     */
+    @Override
+    public void removePropertyChangeListener( final IPropertyChangeListener listener ) {
+        this.delegate.removePropertyChangeListener(listener);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#run()
+     */
+    @Override
+    public void run() {
+        this.delegate.run();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#runWithEvent(org.eclipse.swt.widgets.Event)
+     */
+    @Override
+    public void runWithEvent( final Event event ) {
+        this.delegate.runWithEvent(event);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.eclipse.jface.action.IAction#setEnabled(boolean)
+     */
+    @Override
+    public void setEnabled( final boolean enabled ) {
+        this.delegate.setEnabled(enabled);
+    }
+}


Property changes on: trunk/modeshape/plugins/org.jboss.tools.modeshape.ui/src/org/jboss/tools/modeshape/ui/actions/DelegateAction.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinitionTest.java
===================================================================
--- trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinitionTest.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/ChildNodeDefinitionTest.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -184,7 +184,7 @@
     public void shouldReceiveEventAfterClearingSuperTypes() {
         final String REQUIRED_TYPE = "requiredType"; //$NON-NLS-1$
         assertTrue(this.childNodeDefinition.addRequiredType(REQUIRED_TYPE));
-        String[] oldValue = new String[] {REQUIRED_TYPE};
+        String[] oldValue = new String[] { REQUIRED_TYPE };
 
         Listener l = new Listener();
         assertTrue(this.childNodeDefinition.addListener(l));
@@ -406,4 +406,84 @@
         assertTrue(this.childNodeDefinition.getState(PropertyName.SAME_NAME_SIBLINGS) == Value.IS_NOT);
     }
 
+    @Test
+    public void differentInstancesWithSameValuesShouldBeEqual() {
+        ChildNodeDefinition that = new ChildNodeDefinition();
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setName(Constants.QUALIFIED_NAME1.get());
+        that.setName(this.childNodeDefinition.getName());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setDefaultPrimaryTypeName(Constants.DEFAULT_TYPE);
+        that.setDefaultPrimaryTypeName(this.childNodeDefinition.getDefaultPrimaryTypeName());
+        assertEquals(this.childNodeDefinition, that);
+        
+        this.childNodeDefinition.setAutoCreated(!this.childNodeDefinition.isAutoCreated());
+        that.setAutoCreated(this.childNodeDefinition.isAutoCreated());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setMandatory(!this.childNodeDefinition.isMandatory());
+        that.setMandatory(this.childNodeDefinition.isMandatory());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setProtected(!this.childNodeDefinition.isProtected());
+        that.setProtected(this.childNodeDefinition.isProtected());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setSameNameSiblings(!this.childNodeDefinition.allowsSameNameSiblings());
+        that.setSameNameSiblings(this.childNodeDefinition.allowsSameNameSiblings());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setOnParentVersion(OnParentVersion.ABORT.asJcrValue());
+        that.setOnParentVersion(this.childNodeDefinition.getOnParentVersion());
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setRequiredPrimaryTypeNames(Constants.Helper.getDefaultQualifiedNamesAsArray());
+        that.setRequiredPrimaryTypeNames(this.childNodeDefinition.getRequiredPrimaryTypeNames());
+        assertEquals(this.childNodeDefinition, that);
+    }
+
+    @Test
+    public void differentInstancesWithSameValuesShouldHaveSameHashCode() {
+        assertEquals(this.childNodeDefinition.hashCode(), new ChildNodeDefinition().hashCode());
+    }
+
+    @Test
+    public void copiesShouldBeEqual() {
+        ChildNodeDefinition that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setName(Constants.QUALIFIED_NAME1.get());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setDefaultPrimaryTypeName(Constants.DEFAULT_TYPE);
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+        
+        this.childNodeDefinition.setAutoCreated(!this.childNodeDefinition.isAutoCreated());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setMandatory(!this.childNodeDefinition.isMandatory());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setProtected(!this.childNodeDefinition.isProtected());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setSameNameSiblings(!this.childNodeDefinition.allowsSameNameSiblings());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setOnParentVersion(OnParentVersion.ABORT.asJcrValue());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+
+        this.childNodeDefinition.setRequiredPrimaryTypeNames(Constants.Helper.getDefaultQualifiedNamesAsArray());
+        that = ChildNodeDefinition.copy(this.childNodeDefinition);
+        assertEquals(this.childNodeDefinition, that);
+    }
 }

Modified: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndValidatorTest.java
===================================================================
--- trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndValidatorTest.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/CndValidatorTest.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -47,7 +47,7 @@
     @Test
     public void childNodeDefinitionWithInvalidDefaultTypeNameShouldBeAnError() {
         this.childNodeDefinition.setName("name"); //$NON-NLS-1$
-        this.childNodeDefinition.setDefaultPrimaryTypeName("invalid:name"); //$NON-NLS-1$
+        this.childNodeDefinition.setDefaultPrimaryTypeName("missingName:"); //$NON-NLS-1$
         assertTrue(CndValidator.validateChildNodeDefinition(this.childNodeDefinition).isError());
     }
 
@@ -60,7 +60,7 @@
     @Test
     public void childNodeDefinitionWithInvalidRequiredTypeNameShouldBeAnError() {
         this.childNodeDefinition.setName("name"); //$NON-NLS-1$
-        this.childNodeDefinition.addRequiredType("invalid:name"); //$NON-NLS-1$
+        this.childNodeDefinition.addRequiredType("missingName:"); //$NON-NLS-1$
         assertTrue(CndValidator.validateChildNodeDefinition(this.childNodeDefinition).isError());
     }
 

Modified: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/Constants.java
===================================================================
--- trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/Constants.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/Constants.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -14,6 +14,7 @@
 import org.jboss.tools.modeshape.jcr.cnd.CndNotationPreferences.Preference;
 import org.jboss.tools.modeshape.jcr.cnd.attributes.Abstract;
 import org.jboss.tools.modeshape.jcr.cnd.attributes.AttributeState;
+import org.jboss.tools.modeshape.jcr.cnd.attributes.AttributeState.Value;
 import org.jboss.tools.modeshape.jcr.cnd.attributes.Autocreated;
 import org.jboss.tools.modeshape.jcr.cnd.attributes.DefaultType;
 import org.jboss.tools.modeshape.jcr.cnd.attributes.DefaultValues;
@@ -48,7 +49,7 @@
     NamespaceMapping NAMESPACE1 = new NamespaceMapping(NAMESPACE_PREFIX1, NAMESPACE_URI1);
     NamespaceMapping NAMESPACE2 = new NamespaceMapping(NAMESPACE_PREFIX2, NAMESPACE_URI2);
     NamespaceMapping NAMESPACE3 = new NamespaceMapping(NAMESPACE_PREFIX3, NAMESPACE_URI3);
-    
+
     String QUALIFIER1 = "QUALIFIER1"; //$NON-NLS-1$
     String QUALIFIER2 = "QUALIFIER2"; //$NON-NLS-1$
     String QUALIFIER3 = "QUALIFIER3"; //$NON-NLS-1$
@@ -208,11 +209,9 @@
     String SUPER_TYPES_VARIANT = SuperTypes.NOTATION_PREFIX
             + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_PREFIX_END_DELIMITER) + VARIANT;
     String SUPER_TYPES_ONE_ITEM_FORM = SuperTypes.NOTATION_PREFIX
-            + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_PREFIX_END_DELIMITER)
-            + QUALIFIED_NAME1;
+            + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_PREFIX_END_DELIMITER) + QUALIFIED_NAME1;
     String SUPER_TYPES_THREE_ITEM_FORM = SuperTypes.NOTATION_PREFIX
-            + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_PREFIX_END_DELIMITER)
-            + QUALIFIED_NAME1
+            + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_PREFIX_END_DELIMITER) + QUALIFIED_NAME1
             + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_ELEMENT_DELIMITER) + QUALIFIED_NAME2
             + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_ELEMENT_DELIMITER) + QUALIFIED_NAME3;
 
@@ -238,6 +237,16 @@
             + CndNotationPreferences.DEFAULT_PREFERENCES.get(Preference.ATTRIBUTE_LIST_QUOTE_CHAR);
 
     class Helper {
+        public static void changeValue( AttributeState attribute ) {
+            if (attribute.is()) {
+                attribute.set(Value.IS_NOT);
+            } else if (attribute.isNot()) {
+                attribute.set(Value.IS);
+            } else {
+                attribute.set(Value.IS);
+            }
+        }
+
         public static Collection<NamespaceMapping> getDefaultNamespaces() {
             Collection<NamespaceMapping> namespaces = new ArrayList<NamespaceMapping>();
             namespaces.add(NAMESPACE1);
@@ -254,6 +263,10 @@
             return qualifiedNames;
         }
 
+        public static String[] getDefaultQualifiedNamesAsArray() {
+            return new String[] { QUALIFIED_NAME1.get(), QUALIFIED_NAME2.get(), QUALIFIED_NAME3.get() };
+        }
+
         public static Collection<String> getDefaultQualifiers() {
             Collection<String> qualifiers = new ArrayList<String>();
             qualifiers.add(QUALIFIER1);

Modified: trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributesTest.java
===================================================================
--- trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributesTest.java	2012-03-20 20:02:53 UTC (rev 39676)
+++ trunk/modeshape/tests/org.jboss.tools.modeshape.jcr.test/src/org/jboss/tools/modeshape/jcr/cnd/attributes/NodeAttributesTest.java	2012-03-20 20:14:13 UTC (rev 39677)
@@ -13,6 +13,7 @@
 
 import org.jboss.tools.modeshape.jcr.Utils;
 import org.jboss.tools.modeshape.jcr.cnd.CndElement.NotationType;
+import org.jboss.tools.modeshape.jcr.cnd.Constants;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -70,4 +71,36 @@
         assertTrue(Utils.isEmpty(this.attributes.toCndNotation(NotationType.COMPRESSED)));
         assertTrue(Utils.isEmpty(this.attributes.toCndNotation(NotationType.COMPACT)));
     }
+
+    @Test
+    public void copiesShouldBeEqual() {
+        NodeAttributes copy = NodeAttributes.copy(this.attributes);
+        assertEquals(this.attributes, copy);
+
+        Constants.Helper.changeValue(this.attributes.getAutocreated());
+        copy.setAutocreated(this.attributes.getAutocreated().get());
+        assertEquals(this.attributes, copy);
+
+        Constants.Helper.changeValue(this.attributes.getMandatory());
+        copy.setMandatory(this.attributes.getMandatory().get());
+        assertEquals(this.attributes, copy);
+
+        Constants.Helper.changeValue(this.attributes.getProtected());
+        copy.setProtected(this.attributes.getProtected().get());
+        assertEquals(this.attributes, copy);
+
+        Constants.Helper.changeValue(this.attributes.getSameNameSiblings());
+        copy.setSameNameSibling(this.attributes.getSameNameSiblings().get());
+        assertEquals(this.attributes, copy);
+
+        this.attributes.setOnParentVersion(OnParentVersion.ABORT);
+        copy.setOnParentVersion(this.attributes.getOnParentVersion());
+        assertEquals(this.attributes, copy);
+    }
+
+    @Test
+    public void equalInstancesShouldHaveSameHashCode() {
+        NodeAttributes second = new NodeAttributes();
+        assertEquals(this.attributes.hashCode(), second.hashCode());
+    }
 }



More information about the jbosstools-commits mailing list