[246624] resourceFactories extension override enhancement
diff --git a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
index fda1a5c..c6e1e45 100644
--- a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
+++ b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
@@ -26,6 +26,8 @@
 	String ATT_CONTENTTYPEID = "contentTypeId"; //$NON-NLS-1$ 
 	
 	String ATT_ISDEFAULT = "isDefault"; //$NON-NLS-1$ 
+	
+	String ATT_OVERRIDES_FACTORY ="overridesFactoryClass"; //$NON-NLS-1$ 
 		
 
 }
diff --git a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
index dca61f6..96f8777 100644
--- a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
+++ b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
@@ -11,6 +11,8 @@
 package org.eclipse.wst.common.componentcore.internal.impl;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.Set;
 
@@ -115,6 +117,11 @@
 		key.shortName = descriptor.getShortSegment();
 		key.type = descriptor.getContentType();
 		key.isDefault = descriptor.isDefault();
+		if(descriptor instanceof ConfigurationResourceFactoryDescriptor){
+			ConfigurationResourceFactoryDescriptor configurationDescriptor = (ConfigurationResourceFactoryDescriptor)descriptor;
+			key.factoryClassName = configurationDescriptor.getFactoryClassName();
+			key.overridesFactoryClassName = configurationDescriptor.getOverridesFactoryClassName();
+		}
 		return key;
 	}
 	
@@ -126,6 +133,8 @@
 		private String shortSegment;
 		private IContentType contentType;
 		private boolean isDefault = true;
+		private String factoryClassName = null;
+		private String overridesFactoryClassName = null;
 		private final IConfigurationElement element; 
 		
 		public ConfigurationResourceFactoryDescriptor(IConfigurationElement ext) throws CoreException {
@@ -134,6 +143,14 @@
 			init();
 		} 
 		
+		public String getOverridesFactoryClassName() {
+			return overridesFactoryClassName;
+		}
+
+		public String getFactoryClassName() {
+			return factoryClassName;
+		}
+
 		private void init() throws CoreException {
 			shortSegment = element.getAttribute(ATT_SHORT_SEGMENT);
 			
@@ -161,6 +178,9 @@
 			
 			if ("false".equals(element.getAttribute(ATT_ISDEFAULT)))
 				isDefault = false;
+				
+            factoryClassName = element.getAttribute(ATT_CLASS);
+			overridesFactoryClassName = element.getAttribute(ATT_OVERRIDES_FACTORY);				
 		} 
 
 		public boolean isEnabledFor(URI fileURI) {
@@ -258,6 +278,8 @@
 	}
 	private class WTPResourceFactoryRegistryKey { 
  		
+		public String overridesFactoryClassName;
+		public String factoryClassName;
 		public String shortName;
 		public IContentType type;
 		public boolean isDefault = true;
@@ -265,21 +287,82 @@
 			super();
 		}
 		
-		
+		/**
+		 * Sort in the following manner:
+		 * First, sort by shortName
+		 * If shortNames are equal, then sort by isDefault
+		 * If isDefault is also equal, then the one defining a factoryClassName wins
+		 * If both have factoryClassNames, then check to see if one overrides the other via overridesFactoryClassName
+		 * If neither override the other factory class, then sort by factoryClassname
+		 * @param other
+		 * @return
+		 */
+		public int compareTo(WTPResourceFactoryRegistryKey other){
+			if(this == other){
+				return 0;
+			}
+			int shortNameCompare = this.shortName.compareTo(other.shortName);
+			if(shortNameCompare != 0){
+				return shortNameCompare;
+			} else {
+				if(this.isDefault != other.isDefault){
+					if(this.isDefault){
+						return -1;
+					} else {
+						return 1;
+					}
+				} else {
+					if(this.factoryClassName == null && other.factoryClassName == null){
+						return 0;
+					} else if(other.factoryClassName == null){
+						return -1;
+					} else if (this.factoryClassName == null){
+						return 1;
+					} else if(other.factoryClassName.equals(this.overridesFactoryClassName)){
+						return -1;
+					} else if(this.factoryClassName.equals(other.overridesFactoryClassName)){
+						return 1;
+					} else {
+						return this.factoryClassName.compareTo(other.factoryClassName);
+					}	
+				}
+			}
+		}
 	}
 
 	protected void addDescriptor(ResourceFactoryDescriptor descriptor) {
 		getDescriptors().put(getKey(descriptor), descriptor);
 	}
+	
+	private WTPResourceFactoryRegistryKey []  sortedDescriptors = null;
+	
+	private WTPResourceFactoryRegistryKey []  getSortedDescriptorKeys() {
+		if(sortedDescriptors == null || sortedDescriptors.length != getDescriptors().size()){
+			Set keys = getDescriptors().keySet();
+			WTPResourceFactoryRegistryKey [] array = new WTPResourceFactoryRegistryKey [keys.size()];
+			int count = 0;
+			for (Iterator iterator = keys.iterator(); iterator.hasNext();count++) {
+				WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) iterator.next();
+				array[count] = key;
+			}
+			Arrays.sort(array, new Comparator<WTPResourceFactoryRegistryKey>() {
+				public int compare(WTPResourceFactoryRegistryKey key1,
+						WTPResourceFactoryRegistryKey key2) {
+					return key1.compareTo(key2);
+				}
+			});
+			sortedDescriptors = array;
+		}
+		return sortedDescriptors;
+	}
 
 	protected synchronized ResourceFactoryDescriptor getDescriptor(URI uri, IContentDescription description) {
-		Set keys = getDescriptors().keySet();
+		WTPResourceFactoryRegistryKey [] keys = getSortedDescriptorKeys();
 		ResourceFactoryDescriptor defaultDescriptor = null;
 		
 		// first check content type
 		if (description != null) {
-			for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
-				WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) iterator.next();
+			for (WTPResourceFactoryRegistryKey key : keys) {
 				ResourceFactoryDescriptor descriptor = (ResourceFactoryDescriptor) getDescriptors().get(key);
 				
 				if ((key.type != null) && (description.getContentType().equals(key.type))) {
@@ -291,8 +374,7 @@
 		}
 		
 		// then check short name, overriding default if necessary
-		for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
-			WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) iterator.next();
+		for (WTPResourceFactoryRegistryKey key : keys) {
 			ResourceFactoryDescriptor descriptor = (ResourceFactoryDescriptor) getDescriptors().get(key);
 						
 			if ((key.shortName != null) && (uri.lastSegment().equals(key.shortName))) {
diff --git a/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd b/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
index b8cd792..49f7a80 100644
--- a/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
+++ b/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
@@ -1,16 +1,21 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <!-- Schema file written by PDE -->
-<schema targetNamespace="org.eclipse.wst.common.modulecore">
+<schema targetNamespace="org.eclipse.wst.common.modulecore" xmlns="http://www.w3.org/2001/XMLSchema">
 <annotation>
-      <appInfo>
+      <appinfo>
          <meta.schema plugin="org.eclipse.wst.common.modulecore" id="resourceFactories" name="Resource Factory Association (Internal)"/>
-      </appInfo>
+      </appinfo>
       <documentation>
          An *internal* extension point that declares an association between a short-segment filename and a Resource.Factory.
       </documentation>
    </annotation>
 
    <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
       <complexType>
          <sequence>
             <element ref="resourceFactory"/>
@@ -34,9 +39,9 @@
                <documentation>
                   
                </documentation>
-               <appInfo>
+               <appinfo>
                   <meta.attribute translatable="true"/>
-               </appInfo>
+               </appinfo>
             </annotation>
          </attribute>
       </complexType>
@@ -57,9 +62,9 @@
                <documentation>
                   Declares an implementation of &lt;code&gt;org.eclipse.emf.ecore.resource.Resource.Factory&lt;/code&gt;.
                </documentation>
-               <appInfo>
+               <appinfo>
                   <meta.attribute kind="java" basedOn="org.eclipse.emf.ecore.resource.Resource.Factory"/>
-               </appInfo>
+               </appinfo>
             </annotation>
          </attribute>
          <attribute name="shortSegment" type="string">
@@ -76,14 +81,24 @@
                </documentation>
             </annotation>
          </attribute>
+         <attribute name="overridesFactoryClass" type="string">
+            <annotation>
+               <documentation>
+                  This optional attribute is to resolve conflicts between multiple defeault factories registered to the same content type and short segments.  The value should be the fully qualified class name of the factory being overridden.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.emf.ecore.resource.Resource.Factory:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
       </complexType>
    </element>
 
    <element name="contentTypeBinding">
       <annotation>
-         <appInfo>
+         <appinfo>
             <meta.element labelAttribute="contentTypeId"/>
-         </appInfo>
+         </appinfo>
          <documentation>
             Advertises that the containing editor understands the given content type and is suitable for editing files of that type.
          </documentation>
@@ -100,48 +115,40 @@
    </element>
 
    <annotation>
-      <appInfo>
+      <appinfo>
          <meta.section type="since"/>
-      </appInfo>
+      </appinfo>
       <documentation>
          [Enter the first release in which this extension point appears.]
       </documentation>
    </annotation>
 
    <annotation>
-      <appInfo>
+      <appinfo>
          <meta.section type="examples"/>
-      </appInfo>
+      </appinfo>
       <documentation>
          [Enter extension point usage example here.]
       </documentation>
    </annotation>
 
    <annotation>
-      <appInfo>
+      <appinfo>
          <meta.section type="apiInfo"/>
-      </appInfo>
+      </appinfo>
       <documentation>
          [Enter API information here.]
       </documentation>
    </annotation>
 
    <annotation>
-      <appInfo>
+      <appinfo>
          <meta.section type="implementation"/>
-      </appInfo>
+      </appinfo>
       <documentation>
          [Enter information about supplied implementation of this extension point.]
       </documentation>
    </annotation>
 
-   <annotation>
-      <appInfo>
-         <meta.section type="copyright"/>
-      </appInfo>
-      <documentation>
-         
-      </documentation>
-   </annotation>
 
 </schema>