]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ServiceLocatorImpl.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / ServiceLocatorImpl.java
diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ServiceLocatorImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ServiceLocatorImpl.java
new file mode 100644 (file)
index 0000000..bf4d0f6
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.vtt.simantics.procore.internal;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+\r
+import org.simantics.db.Disposable;\r
+import org.simantics.db.ServiceLocator;\r
+import org.simantics.db.exception.ServiceNotFoundException;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ServiceLocatorImpl implements ServiceLocator {\r
+\r
+    /**\r
+     * The parent for this service locator. If a service can't be found in this\r
+     * locator, then the parent is asked. This value may be <code>null</code>\r
+     * if there is no parent.\r
+     */\r
+    private final ServiceLocator parent;\r
+\r
+    /**\r
+     * The map of services maintained by the workbench window. These services\r
+     * are initialized during workbench window during the\r
+     * {@link #configureShell(Shell)}. This value is <code>null</code> until\r
+     * a service is registered.\r
+     */\r
+    private Map<Class<?>, Object> services = null;\r
+\r
+    /**\r
+     * Constructs a service locator with no parent.\r
+     */\r
+    public ServiceLocatorImpl() {\r
+        this(null);\r
+    }\r
+\r
+    /**\r
+     * Constructs a service locator with the given parent.\r
+     * \r
+     * @param parent\r
+     *            The parent for this service locator; this value may be\r
+     *            <code>null</code>.\r
+     */\r
+    public ServiceLocatorImpl(final ServiceLocator parent) {\r
+        this.parent = parent;\r
+    }\r
+\r
+//    public final void activate() {\r
+//        if (services != null) {\r
+//            final Iterator serviceItr = services.values().iterator();\r
+//            while (serviceItr.hasNext()) {\r
+//                final Object service = serviceItr.next();\r
+//                if (service instanceof INestable) {\r
+//                    final INestable nestableService = (INestable) service;\r
+//                    nestableService.activate();\r
+//                }\r
+//            }\r
+//        }\r
+//    }\r
+//\r
+//    public final void deactivate() {\r
+//        if (services != null) {\r
+//            final Iterator serviceItr = services.values().iterator();\r
+//            while (serviceItr.hasNext()) {\r
+//                final Object service = serviceItr.next();\r
+//                if (service instanceof INestable) {\r
+//                    final INestable nestableService = (INestable) service;\r
+//                    nestableService.deactivate();\r
+//                }\r
+//            }\r
+//        }\r
+//    }\r
+\r
+    public final void dispose() {\r
+        Map<Class<?>, Object> s = null;\r
+        synchronized (this) {\r
+            s = services;\r
+            services = null;\r
+        }\r
+        if (s != null) {\r
+            final Iterator<Object> serviceItr = s.values().iterator();\r
+            while (serviceItr.hasNext()) {\r
+                final Object object = serviceItr.next();\r
+                if (object instanceof Disposable) {\r
+                    final Disposable service = (Disposable) object;\r
+                    service.dispose();\r
+                }\r
+            }\r
+            s.clear();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public final <T> T getService(final Class<T> key) {\r
+        T t = peekService(key);\r
+        if (t == null)\r
+            throw new ServiceNotFoundException(this, key);\r
+        return t;\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Override\r
+    public final <T> T peekService(final Class<T> key) {\r
+        final Object service;\r
+        synchronized (this) {\r
+            if (services != null) {\r
+                service = services.get(key);\r
+            } else {\r
+                service = null;\r
+            }\r
+        }\r
+        if (service == null)\r
+            if (parent != null)\r
+                return parent.getService(key);\r
+            else\r
+                return null;\r
+        T t = null;\r
+        try {\r
+            t = (T)service;\r
+        } catch (ClassCastException e) {\r
+        }\r
+        return t;\r
+    }\r
+\r
+    @Override\r
+    public final boolean hasService(final Class<?> key) {\r
+        if (services != null) {\r
+            if (services.containsKey(key)) {\r
+                return true;\r
+            }\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Registers a service with this locator. If there is an existing service\r
+     * matching the same <code>api</code> and it implements\r
+     * {@link Disposable}, it will be disposed.\r
+     * \r
+     * @param api\r
+     *            This is the interface that the service implements. Must not be\r
+     *            <code>null</code>.\r
+     * @param service\r
+     *            The service to register. This must be some implementation of\r
+     *            <code>api</code>. This value must not be <code>null</code>.\r
+     */\r
+    public final <T> void registerService(final Class<T> api, final T service) {\r
+        if (api == null) {\r
+            throw new NullPointerException("The service key cannot be null"); //$NON-NLS-1$\r
+        }\r
+\r
+//        if (!api.isInstance(service)) {\r
+//            throw new IllegalArgumentException(\r
+//                    "The service does not implement the given interface"); //$NON-NLS-1$\r
+//        }\r
+\r
+        synchronized (this) {\r
+            if (services == null) {\r
+                services = new THashMap<Class<?>, Object>();\r
+            }\r
+\r
+            final Object currentService = services.remove(api);\r
+            if (currentService instanceof Disposable) {\r
+                final Disposable disposable = (Disposable) currentService;\r
+                disposable.dispose();\r
+            }\r
+\r
+            if (service == null) {\r
+                if (services.isEmpty()) {\r
+                    services = null;\r
+                }\r
+            } else {\r
+//             System.out.println("register " + api.toString());\r
+                services.put(api, service);\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+}\r