1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package fi.vtt.simantics.procore.internal;
\r
14 import gnu.trove.map.hash.THashMap;
\r
16 import java.util.Iterator;
\r
17 import java.util.Map;
\r
19 import org.simantics.db.Disposable;
\r
20 import org.simantics.db.ServiceLocator;
\r
21 import org.simantics.db.exception.ServiceNotFoundException;
\r
24 * @author Tuukka Lehtonen
\r
26 public class ServiceLocatorImpl implements ServiceLocator {
\r
29 * The parent for this service locator. If a service can't be found in this
\r
30 * locator, then the parent is asked. This value may be <code>null</code>
\r
31 * if there is no parent.
\r
33 private final ServiceLocator parent;
\r
36 * The map of services maintained by the workbench window. These services
\r
37 * are initialized during workbench window during the
\r
38 * {@link #configureShell(Shell)}. This value is <code>null</code> until
\r
39 * a service is registered.
\r
41 private Map<Class<?>, Object> services = null;
\r
44 * Constructs a service locator with no parent.
\r
46 public ServiceLocatorImpl() {
\r
51 * Constructs a service locator with the given parent.
\r
54 * The parent for this service locator; this value may be
\r
55 * <code>null</code>.
\r
57 public ServiceLocatorImpl(final ServiceLocator parent) {
\r
58 this.parent = parent;
\r
61 // public final void activate() {
\r
62 // if (services != null) {
\r
63 // final Iterator serviceItr = services.values().iterator();
\r
64 // while (serviceItr.hasNext()) {
\r
65 // final Object service = serviceItr.next();
\r
66 // if (service instanceof INestable) {
\r
67 // final INestable nestableService = (INestable) service;
\r
68 // nestableService.activate();
\r
74 // public final void deactivate() {
\r
75 // if (services != null) {
\r
76 // final Iterator serviceItr = services.values().iterator();
\r
77 // while (serviceItr.hasNext()) {
\r
78 // final Object service = serviceItr.next();
\r
79 // if (service instanceof INestable) {
\r
80 // final INestable nestableService = (INestable) service;
\r
81 // nestableService.deactivate();
\r
87 public final void dispose() {
\r
88 Map<Class<?>, Object> s = null;
\r
89 synchronized (this) {
\r
94 final Iterator<Object> serviceItr = s.values().iterator();
\r
95 while (serviceItr.hasNext()) {
\r
96 final Object object = serviceItr.next();
\r
97 if (object instanceof Disposable) {
\r
98 final Disposable service = (Disposable) object;
\r
107 public final <T> T getService(final Class<T> key) {
\r
108 T t = peekService(key);
\r
110 throw new ServiceNotFoundException(this, key);
\r
114 @SuppressWarnings("unchecked")
\r
116 public final <T> T peekService(final Class<T> key) {
\r
117 final Object service;
\r
118 synchronized (this) {
\r
119 if (services != null) {
\r
120 service = services.get(key);
\r
125 if (service == null)
\r
126 if (parent != null)
\r
127 return parent.getService(key);
\r
133 } catch (ClassCastException e) {
\r
139 public final boolean hasService(final Class<?> key) {
\r
140 if (services != null) {
\r
141 if (services.containsKey(key)) {
\r
150 * Registers a service with this locator. If there is an existing service
\r
151 * matching the same <code>api</code> and it implements
\r
152 * {@link Disposable}, it will be disposed.
\r
155 * This is the interface that the service implements. Must not be
\r
156 * <code>null</code>.
\r
158 * The service to register. This must be some implementation of
\r
159 * <code>api</code>. This value must not be <code>null</code>.
\r
161 public final <T> void registerService(final Class<T> api, final T service) {
\r
163 throw new NullPointerException("The service key cannot be null"); //$NON-NLS-1$
\r
166 // if (!api.isInstance(service)) {
\r
167 // throw new IllegalArgumentException(
\r
168 // "The service does not implement the given interface"); //$NON-NLS-1$
\r
171 synchronized (this) {
\r
172 if (services == null) {
\r
173 services = new THashMap<Class<?>, Object>();
\r
176 final Object currentService = services.remove(api);
\r
177 if (currentService instanceof Disposable) {
\r
178 final Disposable disposable = (Disposable) currentService;
\r
179 disposable.dispose();
\r
182 if (service == null) {
\r
183 if (services.isEmpty()) {
\r
187 // System.out.println("register " + api.toString());
\r
188 services.put(api, service);
\r