bug 366235: establish test environment for DefaultObjectNameTranslatorTest
diff --git a/org.eclipse.gemini.mgmt.target/gemini-management.target b/org.eclipse.gemini.mgmt.target/gemini-management.target
index 1c8380e..023326f 100755
--- a/org.eclipse.gemini.mgmt.target/gemini-management.target
+++ b/org.eclipse.gemini.mgmt.target/gemini-management.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde version="3.6"?>
 
-<target includeMode="feature" name="gemini-management" sequenceNumber="36">
+<target name="gemini-management" sequenceNumber="60">
 <locations>
 <location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.eclipse.osgi" version="3.7.1.R37x_v20110808-1106"/>
@@ -10,15 +10,9 @@
 <repository location="http://download.eclipse.org/eclipse/updates/3.7/"/>
 </location>
 <location includeAllPlatforms="false" includeMode="planner" includeSource="false" type="InstallableUnit">
-<unit id="osgi.enterprise" version="0.0.0"/>
+<unit id="osgi.enterprise" version="4.2.0.v201108120515"/>
+<unit id="org.easymock" version="2.4.0.v20090202-0900"/>
 <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20111018035124/repository/"/>
 </location>
 </locations>
-<includeBundles>
-<plugin id="org.junit"/>
-<plugin id="org.junit4"/>
-<plugin id="org.eclipse.osgi"/>
-<plugin id="osgi.enterprise"/>
-<plugin id="org.eclipse.osgi.services"/>
-</includeBundles>
 </target>
diff --git a/org.eclipse.gemini.mgmt.tests/META-INF/MANIFEST.MF b/org.eclipse.gemini.mgmt.tests/META-INF/MANIFEST.MF
index 83e14cf..fe06625 100644
--- a/org.eclipse.gemini.mgmt.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.gemini.mgmt.tests/META-INF/MANIFEST.MF
@@ -6,6 +6,7 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: javax.management,
  javax.management.remote,
+ org.easymock,
  org.osgi.framework;version="1.3.0"
 Fragment-Host: org.eclipse.gemini.mgmt
 Require-Bundle: org.junit4
diff --git a/org.eclipse.gemini.mgmt.tests/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslatorTest.java b/org.eclipse.gemini.mgmt.tests/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslatorTest.java
new file mode 100755
index 0000000..2f8855d
--- /dev/null
+++ b/org.eclipse.gemini.mgmt.tests/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslatorTest.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 VMware Inc.
+ * 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:
+ *   VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.gemini.mgmt;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.junit.Test;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.easymock.EasyMock;
+
+public class DefaultObjectNameTranslatorTest {
+    
+    @Test
+    public void testDefaultObjectNameTranslator() throws Exception {
+        BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+        Bundle bundle = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(bundleContext.getBundle()).andReturn(bundle);
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        EasyMock.expect(bundle.getHeaders()).andReturn(headers);
+        EasyMock.replay(bundleContext, bundle);
+        ObjectNameTranslator defaultObjectNameTranslator = DefaultObjectNameTranslator.initialiseObjectNameTranslator(bundleContext);
+        Assert.assertTrue("Default ObjectNameTranslator has the wrong type", defaultObjectNameTranslator instanceof DefaultObjectNameTranslator);
+        EasyMock.verify(bundleContext, bundle);
+    }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
index d3ddf5d..226d4bf 100644
--- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
@@ -25,6 +25,7 @@
 import javax.management.InstanceNotFoundException;

 import javax.management.MBeanRegistrationException;

 import javax.management.MBeanServer;

+import javax.management.MalformedObjectNameException;

 import javax.management.NotCompliantMBeanException;

 import javax.management.ObjectName;

 import javax.management.StandardMBean;

@@ -58,9 +59,8 @@
 import org.osgi.util.tracker.ServiceTrackerCustomizer;

 

 /**

- * The bundle activator which starts and stops the system, as well as providing

- * the service tracker which listens for the MBeanServer. When the MBeanServer

- * is found, the MBeans representing the OSGi services will be installed.

+ * The bundle activator which starts and stops the system, as well as providing the service tracker which listens for

+ * the MBeanServer. When the MBeanServer is found, the MBeans representing the OSGi services will be installed.

  * 

  */

 public class Activator implements BundleActivator {

@@ -71,23 +71,25 @@
 	

 	private final AtomicBoolean servicesRegistered = new AtomicBoolean(false);

 	

-	private final ObjectName frameworkName;

+    private ObjectNameTranslator objectNameTranslator;

 	

-	private final ObjectName bundleStateName;

+	private ObjectName frameworkName;

 	

-	private final ObjectName bundleWiringStateName;

+	private ObjectName bundleStateName;

 	

-	private final ObjectName packageStateName;

+	private ObjectName bundleWiringStateName;

 	

-	private final ObjectName serviceStateName;

+	private ObjectName packageStateName;

 	

-	private final ObjectName configAdminName;

+	private ObjectName serviceStateName;

 	

-	private final ObjectName permissionAdminName;

+	private ObjectName configAdminName;

 	

-	private final ObjectName provisioningServiceName;

+	private ObjectName permissionAdminName;

 	

-	private final ObjectName userAdminName;

+	private ObjectName provisioningServiceName;

+	

+	private ObjectName userAdminName;

 	

 	private ServiceTracker<MBeanServer, ?> mbeanServiceTracker;

 	

@@ -111,17 +113,17 @@
 	

 	private ServiceTracker<UserAdmin, ?> userAdminTracker;

 

-	public Activator() {

+	private void createObjectNames() {

 		try {

-			frameworkName = new ObjectName(FrameworkMBean.OBJECTNAME);

-			bundleStateName = new ObjectName(CustomBundleStateMBean.OBJECTNAME);

-			bundleWiringStateName = new ObjectName(CustomBundleWiringStateMBean.OBJECTNAME);

-			serviceStateName = new ObjectName(CustomServiceStateMBean.OBJECTNAME);

-			packageStateName = new ObjectName(PackageStateMBean.OBJECTNAME);

-			configAdminName = new ObjectName(ConfigurationAdminMBean.OBJECTNAME);

-			permissionAdminName = new ObjectName(PermissionAdminMBean.OBJECTNAME);

-			provisioningServiceName = new ObjectName(ProvisioningServiceMBean.OBJECTNAME);

-			userAdminName = new ObjectName(UserAdminMBean.OBJECTNAME);		

+			frameworkName = translateObjectName(FrameworkMBean.OBJECTNAME);

+			bundleStateName = translateObjectName(CustomBundleStateMBean.OBJECTNAME);

+			bundleWiringStateName = translateObjectName(CustomBundleWiringStateMBean.OBJECTNAME);

+			serviceStateName = translateObjectName(CustomServiceStateMBean.OBJECTNAME);

+			packageStateName = translateObjectName(PackageStateMBean.OBJECTNAME);

+			configAdminName = translateObjectName(ConfigurationAdminMBean.OBJECTNAME);

+			permissionAdminName = translateObjectName(PermissionAdminMBean.OBJECTNAME);

+			provisioningServiceName = translateObjectName(ProvisioningServiceMBean.OBJECTNAME);

+			userAdminName = translateObjectName(UserAdminMBean.OBJECTNAME);		

 		} catch (Exception e) {

 			throw new IllegalStateException("Unable to start Gemini Management, Object name creation failed.", e);

 		}

@@ -131,11 +133,18 @@
 	 * {@inheritDoc}

 	 */

 	public void start(BundleContext bundleContext) throws Exception {

+        objectNameTranslator = DefaultObjectNameTranslator.initialiseObjectNameTranslator(bundleContext);

+        createObjectNames();

 		this.bundleContext = bundleContext;	

 		this.mbeanServiceTracker = new ServiceTracker<MBeanServer, Object>(this.bundleContext, MBeanServer.class, new MBeanServiceTracker());

 		LOGGER.fine("Awaiting initial MBeanServer service registration");

 		this.mbeanServiceTracker.open();

 	}

+	

+    private ObjectName translateObjectName(String objectName) throws MalformedObjectNameException {

+        return this.objectNameTranslator.translate(new ObjectName(objectName));

+    }

+

 

 	/**

 	 * {@inheritDoc}

@@ -345,16 +354,19 @@
 			LOGGER.log(Level.SEVERE, "Cannot register OSGi PackageStateMBean", e);

 		}

 

-		configAdminTracker = new ServiceTracker<ConfigurationAdmin, Object>(bundleContext, "org.osgi.service.cm.ConfigurationAdmin", new ConfigAdminTracker());

-		permissionAdminTracker = new ServiceTracker<PermissionAdmin, Object>(bundleContext, "org.osgi.service.permissionadmin.PermissionAdmin", new PermissionAdminTracker());

-		provisioningServiceTracker = new ServiceTracker<ProvisioningService, Object>(bundleContext, "org.osgi.service.provisioning.ProvisioningService", new ProvisioningServiceTracker());

-		userAdminTracker = new ServiceTracker<UserAdmin, Object>(bundleContext, "org.osgi.service.useradmin.UserAdmin", new UserAdminTracker());

-		configAdminTracker.open();

-		permissionAdminTracker.open();

-		provisioningServiceTracker.open();

-		userAdminTracker.open();

-		servicesRegistered.set(true);

-	}

+        configAdminTracker = new ServiceTracker<ConfigurationAdmin, Object>(bundleContext, "org.osgi.service.cm.ConfigurationAdmin",

+            new ConfigAdminTracker());

+        permissionAdminTracker = new ServiceTracker<PermissionAdmin, Object>(bundleContext, "org.osgi.service.permissionadmin.PermissionAdmin",

+            new PermissionAdminTracker());

+        provisioningServiceTracker = new ServiceTracker<ProvisioningService, Object>(bundleContext,

+            "org.osgi.service.provisioning.ProvisioningService", new ProvisioningServiceTracker());

+        userAdminTracker = new ServiceTracker<UserAdmin, Object>(bundleContext, "org.osgi.service.useradmin.UserAdmin", new UserAdminTracker());

+        configAdminTracker.open();

+        permissionAdminTracker.open();

+        provisioningServiceTracker.open();

+        userAdminTracker.open();

+        servicesRegistered.set(true);

+    }

 

 	private class MBeanServiceTracker implements ServiceTrackerCustomizer<MBeanServer, Object> {

 

diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslator.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslator.java
new file mode 100755
index 0000000..f5aed70
--- /dev/null
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/DefaultObjectNameTranslator.java
@@ -0,0 +1,61 @@
+/*******************************************************************************

+ * Copyright (c) 2011 VMware Inc.

+ * 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:

+ *   VMware Inc. - initial contribution

+ *******************************************************************************/

+

+package org.eclipse.gemini.mgmt;

+

+import javax.management.ObjectName;

+

+import org.osgi.framework.BundleContext;

+

+/**

+ * {@link DefaultObjectNameTranslator} is a default implementation of {@link ObjectNameTranslator} which maps each

+ * {@link ObjectName} to itself.

+ * <p />

+ * 

+ * <strong>Concurrent Semantics</strong><br />

+ * Thread safe.

+ */

+final class DefaultObjectNameTranslator implements ObjectNameTranslator {

+

+    /**

+     * {@inheritDoc}

+     */

+    @Override

+    public ObjectName translate(ObjectName objectName) {

+        return objectName;

+    }

+

+    /**

+     * Creates an {@link ObjectNameTranslator} instance based on the headers of the given bundle. This is either one

+     * configured by an attached fragment or, by default, an instance of this class.

+     * 

+     * @param bundleContext the bundle which may contain a header to define an {@link ObjectNameTranslator}

+     * @return an {@link ObjectNameTranslator}

+     * @throws ClassNotFoundException if the configured class cannot be loaded

+     * @throws InstantiationException if the configured class cannot be instantiated

+     * @throws IllegalAccessException if the configured class or its default constructor is not accessible

+     */

+    static ObjectNameTranslator initialiseObjectNameTranslator(BundleContext bundleContext) throws ClassNotFoundException, InstantiationException,

+        IllegalAccessException {

+        String ontClassName = bundleContext.getBundle().getHeaders().get(ObjectNameTranslator.HEADER_NAME);

+        if (ontClassName == null) {

+            return new DefaultObjectNameTranslator();

+        }

+        /*

+         * Attempt to load and instantiate the specified class, allowing exceptions to percolate and fail the bundle

+         * start.

+         */

+        @SuppressWarnings("unchecked")

+        Class<ObjectNameTranslator> ontClass = (Class<ObjectNameTranslator>) bundleContext.getBundle().loadClass(ontClassName);

+        return ontClass.newInstance();

+    }

+

+}
\ No newline at end of file
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/ObjectNameTranslator.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/ObjectNameTranslator.java
index b030d02..3603c0c 100644
--- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/ObjectNameTranslator.java
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/ObjectNameTranslator.java
@@ -33,6 +33,8 @@
  */
 public interface ObjectNameTranslator {
 
+    public static final String HEADER_NAME = "GeminiManagement-ObjectNameTranslator";
+    
     /**
      * Translates the given {@link ObjectName}. The translation must be injective, which means that translations of
      * distinct object names must be distinct.