[153605] fix for extended translators mechanism
diff --git a/plugins/org.eclipse.wst.common.emf/plugin.xml b/plugins/org.eclipse.wst.common.emf/plugin.xml
index f74b398..dde6ad8 100644
--- a/plugins/org.eclipse.wst.common.emf/plugin.xml
+++ b/plugins/org.eclipse.wst.common.emf/plugin.xml
@@ -3,6 +3,7 @@
 <plugin>
 
      <extension-point id="packageURIMap" name="%PackageURIMap" schema="schema/packageURIMap.exsd"/>
+     <extension-point id="translatorExtension" name="translatorExtension" schema="schema/translatorExtension.exsd"/>
 
 <!-- Need to register the Ecore specific package mappings -->
    <extension
diff --git a/plugins/org.eclipse.wst.common.emf/schema/translatorExtension.exsd b/plugins/org.eclipse.wst.common.emf/schema/translatorExtension.exsd
new file mode 100644
index 0000000..5aa9669
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.emf/schema/translatorExtension.exsd
@@ -0,0 +1,103 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.common.emf">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.wst.common.emf" id="translatorExtension" name="translatorExtension"/>
+      </appInfo>
+      <documentation>
+         This is used to contribute child translators to the default translators in EMF2DOMAdapterImpl.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="translator"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="translator">
+      <complexType>
+         <attribute name="className" type="string" use="required">
+            <annotation>
+               <documentation>
+                  This is the fully qualified classname of the child translator.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         This extension point is part of an interim API that is still under development and expected to change significantly before reaching stability. It is being made available at this early stage to solicit feedback from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken (repeatedly) as the API evolves.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2005 IBM Corporation and others.
+All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.wst.common.emf/workbench/org/eclipse/wst/common/internal/emf/plugin/EcoreUtilitiesPlugin.java b/plugins/org.eclipse.wst.common.emf/workbench/org/eclipse/wst/common/internal/emf/plugin/EcoreUtilitiesPlugin.java
index 3b29f4a..d21bec3 100644
--- a/plugins/org.eclipse.wst.common.emf/workbench/org/eclipse/wst/common/internal/emf/plugin/EcoreUtilitiesPlugin.java
+++ b/plugins/org.eclipse.wst.common.emf/workbench/org/eclipse/wst/common/internal/emf/plugin/EcoreUtilitiesPlugin.java
@@ -30,6 +30,7 @@
  */
 public class EcoreUtilitiesPlugin extends Plugin {
 	public static final String ID = "org.eclipse.wst.common.emf"; //$NON-NLS-1$
+	public static final String TRANSLATOR_EXTENSTION_POINT = "translatorExtension"; //$NON-NLS-1$
 
 	/**
 	 * @param descriptor
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/EMF2DOMAdapterImpl.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/EMF2DOMAdapterImpl.java
index 12ba6c5..5107fe7 100644
--- a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/EMF2DOMAdapterImpl.java
+++ b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/EMF2DOMAdapterImpl.java
@@ -33,6 +33,7 @@
 import org.eclipse.wst.common.internal.emf.utilities.FeatureValueConversionException;
 import org.eclipse.wst.common.internal.emf.utilities.Revisit;
 import org.eclipse.wst.common.internal.emf.utilities.StringUtil;
+import org.eclipse.wst.common.internal.emf.utilities.TranslatorService;
 import org.eclipse.wst.common.internal.emf.utilities.WFTUtilsResourceHandler;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -123,8 +124,13 @@
 	}
 
 	protected void initChildTranslators() {
-
 		List children = new ArrayList();
+		// Get extended child translators
+		Translator[] extendedChildren = TranslatorService.getInstance().getTranslators();
+        for (int i = 0; i < extendedChildren.length; i++) {
+        	if (extendedChildren[i] != null)
+            	children.add(extendedChildren[i]);
+        }
 		children.addAll(Arrays.asList(fTranslator.getChildren(getTarget(), fRenderer.getVersionID())));
 
 		VariableTranslatorFactory factory = fTranslator.getVariableTranslatorFactory();
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorManager.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorManager.java
new file mode 100644
index 0000000..79ee8b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorManager.java
@@ -0,0 +1,168 @@
+/***************************************************************************************************
+ * Copyright (c) 2003, 2006 IBM Corporation and others. All rights reserved. This program and the
+ * accompanying materials are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ **************************************************************************************************/
+package org.eclipse.wst.common.internal.emf.utilities;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jem.util.RegistryReader;
+import org.eclipse.jem.util.logger.proxy.Logger;
+import org.eclipse.wst.common.internal.emf.plugin.EcoreUtilitiesPlugin;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+/**
+ * This is the TranslatorManager class used by the TranslatorService in order to discover
+ * and cache all of the extended Translators to be used by EMF2DOMAdapterImpl.
+ */
+public class TranslatorManager {
+	
+	/**
+	 * The singleton TranslatorManager instance
+	 */
+	private static final TranslatorManager INSTANCE = new TranslatorManager();
+	
+	/**
+	 * Cache of all the TranslatorDescriptors
+	 */
+	private final Set translators = new HashSet();
+	
+	/**
+	 * Default static empty array used when no descriptors found
+	 */
+	private static final TranslatorDescriptor[] NO_EXTENDED_TRANSLATORS = new TranslatorDescriptor[0];
+	
+	/**
+	 * Returns the singleton instance of the TranslatorManager
+	 * @return TranslatorManager INSTANCE
+	 */
+	public static TranslatorManager getInstance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Private constructor
+	 */
+	private TranslatorManager() {
+		new TranslatorRegistry().readRegistry();
+	}
+	
+	/**
+	 * Simple Registry Reader used by Translator Manager to recognize the Translator extensions
+	 */
+	private class TranslatorRegistry extends RegistryReader {
+		
+		/**
+		 * The Translator element of the extension point.
+		 */
+		public static final String TRANSLATOR = "translator"; //$NON-NLS-1$
+		
+		/**
+		 * Default constructor
+		 */
+		public TranslatorRegistry() {
+			super(EcoreUtilitiesPlugin.ID, EcoreUtilitiesPlugin.TRANSLATOR_EXTENSTION_POINT);
+		}
+
+		/**
+		 * Add the configuration element if it matchs the expected translator element name
+		 */
+		public boolean readElement(IConfigurationElement element) {
+			boolean result = false;
+			if (TRANSLATOR.equals(element.getName())) {
+				addTranslatorDescriptor(new TranslatorDescriptor(element));
+					result = true;
+			}
+			return result;
+		}
+	}
+
+	/**
+	 * Describes a Translator extension point element
+	 */
+	public class TranslatorDescriptor {
+	
+		/**
+		 * Qualified class name attribute
+		 */
+		public static final String CLASSNAME = "className"; //$NON-NLS-1$
+		
+		/**
+		 * The config element for this Descriptor
+		 */
+		private final IConfigurationElement configElement;
+		
+		/**
+		 * the cached qualified className value of this descriptor
+		 */
+		private String className;
+	
+		/**
+		 * Constructor
+		 * @param aConfigElement
+		 */
+		public TranslatorDescriptor(IConfigurationElement aConfigElement) {
+			super();
+			configElement = aConfigElement;
+			className = configElement.getAttribute(CLASSNAME);
+		}
+		
+		/**
+		 * Retrieve the cached value of the qualified class name of the extended Translator
+		 * @return String classname
+		 */
+		public String getClassName() {
+			return className;
+		}
+	
+		/**
+		 * Create the actual Translator instance from the configuration element.
+		 * @return Translator
+		 */
+		public Translator createTranslator() {
+			Translator instance = null;
+			try {
+				instance = (Translator) configElement.createExecutableExtension(CLASSNAME);
+			} catch (CoreException e) {
+				Logger.getLogger().logError(e);
+			}
+			return instance;
+		}
+	}
+	
+	/**
+	 * Add the TranslatorDescriptor to the cache of descriptor extensions.
+	 * @param descriptor
+	 */
+	private void addTranslatorDescriptor(TranslatorDescriptor descriptor) {
+		Assert.isNotNull(descriptor);
+		translators.add(descriptor);
+	}
+	
+	/**
+	 * Find all the associated TranslatorDescriptors for the Traslator extensions defined.
+	 * @return TranslatorDescriptor[]
+	 */
+	public TranslatorDescriptor[] findTranslators() {
+		List result = new ArrayList();
+		TranslatorDescriptor descriptor = null;
+		for (Iterator translatorsItr = translators.iterator(); translatorsItr.hasNext();) {
+			descriptor = (TranslatorDescriptor) translatorsItr.next();
+			result.add(descriptor);
+		}
+		if (result.size() == 0) {
+			return NO_EXTENDED_TRANSLATORS;
+		}
+		return (TranslatorDescriptor[]) result.toArray(new TranslatorDescriptor[result.size()]);
+	}
+}
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorService.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorService.java
new file mode 100644
index 0000000..6641b47
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/utilities/TranslatorService.java
@@ -0,0 +1,95 @@
+/***************************************************************************************************
+ * Copyright (c) 2003, 2006 IBM Corporation and others. All rights reserved. This program and the
+ * accompanying materials are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ **************************************************************************************************/
+package org.eclipse.wst.common.internal.emf.utilities;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+import org.eclipse.wst.common.internal.emf.utilities.TranslatorManager.TranslatorDescriptor;
+
+/**
+ * This is the service class to deliver API to use to retrieve Translator extensions from
+ * the TranslatorManager and its RegistryReader.
+ */
+public class TranslatorService {
+
+	/**
+	 * Static Key value pair of descriptors as keys and Translator instances as values
+	 */
+	private static final Map translators = new HashMap();
+	
+	/**
+	 * Static empty array used when no extensions found
+	 */
+	private static final Translator[] NO_TRANSLATORS = new Translator[0];
+	
+	/**
+	 * Singleton instance of the Translator service
+	 */
+	private static final TranslatorService INSTANCE = new TranslatorService();
+	
+	/**
+	 * Default constructor
+	 */
+	private TranslatorService() {
+		super();
+	}
+	
+	public static TranslatorService getInstance() {
+		return INSTANCE;
+	}
+	
+	/**
+	 * This will return the associated extension point TranslatorDescriptor objects from the manager
+	 * @return TranslatorDescriptor[]
+	 */
+	public TranslatorDescriptor[] getTranslatorDescriptors() {
+		return TranslatorManager.getInstance().findTranslators();
+	}
+	
+	/**
+     * This retrieves the extended Translators using the extension point manager and descriptors
+     * @return Translator[] (Note, the return value may contain null entries.)
+     */
+	public Translator[] getTranslators() {
+		TranslatorDescriptor[] descriptors = getTranslatorDescriptors();
+		Translator[] result = new Translator[descriptors.length];
+		//The result index could differ from the descriptors index.
+		int resultIndex = 0;
+		for (int i=0; i<descriptors.length; i++) {
+			Translator instance = getTranslator(descriptors[i]);
+			if (instance!=null) {
+				result[resultIndex] = instance;
+				resultIndex++;
+			}
+		}
+		return result;  
+    }
+	
+	/**
+	 * Retrieve the existing associated Translator instance for the descriptor, or create a new
+	 * one and cache on the Set.
+	 * 
+	 * @param translatorDescriptor
+	 * @return Translator associated with the descriptor
+	 */
+	public Translator getTranslator(TranslatorDescriptor translatorDescriptor) {
+		Translator translator = (Translator) translators.get(translatorDescriptor);
+		if (translator != null)
+			return translator;
+		
+		synchronized (translators) {
+			translator = translatorDescriptor.createTranslator();
+			if (translator != null)
+				translators.put(translatorDescriptor, translator);
+		}
+		return translator;
+	}
+}