/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package fi.vtt.simantics.procore.internal; import gnu.trove.map.hash.THashMap; import java.util.Iterator; import java.util.Map; import org.simantics.db.Disposable; import org.simantics.db.ServiceLocator; import org.simantics.db.exception.ServiceNotFoundException; /** * @author Tuukka Lehtonen */ public class ServiceLocatorImpl implements ServiceLocator { /** * The parent for this service locator. If a service can't be found in this * locator, then the parent is asked. This value may be null * if there is no parent. */ private final ServiceLocator parent; /** * The map of services maintained by the workbench window. These services * are initialized during workbench window during the * {@link #configureShell(Shell)}. This value is null until * a service is registered. */ private Map, Object> services = null; /** * Constructs a service locator with no parent. */ public ServiceLocatorImpl() { this(null); } /** * Constructs a service locator with the given parent. * * @param parent * The parent for this service locator; this value may be * null. */ public ServiceLocatorImpl(final ServiceLocator parent) { this.parent = parent; } // public final void activate() { // if (services != null) { // final Iterator serviceItr = services.values().iterator(); // while (serviceItr.hasNext()) { // final Object service = serviceItr.next(); // if (service instanceof INestable) { // final INestable nestableService = (INestable) service; // nestableService.activate(); // } // } // } // } // // public final void deactivate() { // if (services != null) { // final Iterator serviceItr = services.values().iterator(); // while (serviceItr.hasNext()) { // final Object service = serviceItr.next(); // if (service instanceof INestable) { // final INestable nestableService = (INestable) service; // nestableService.deactivate(); // } // } // } // } public final void dispose() { Map, Object> s = null; synchronized (this) { s = services; services = null; } if (s != null) { final Iterator serviceItr = s.values().iterator(); while (serviceItr.hasNext()) { final Object object = serviceItr.next(); if (object instanceof Disposable) { final Disposable service = (Disposable) object; service.dispose(); } } s.clear(); } } @Override public final T getService(final Class key) { T t = peekService(key); if (t == null) throw new ServiceNotFoundException(this, key); return t; } @SuppressWarnings("unchecked") @Override public final T peekService(final Class key) { final Object service; synchronized (this) { if (services != null) { service = services.get(key); } else { service = null; } } if (service == null) if (parent != null) return parent.getService(key); else return null; T t = null; try { t = (T)service; } catch (ClassCastException e) { } return t; } @Override public final boolean hasService(final Class key) { if (services != null) { if (services.containsKey(key)) { return true; } } return false; } /** * Registers a service with this locator. If there is an existing service * matching the same api and it implements * {@link Disposable}, it will be disposed. * * @param api * This is the interface that the service implements. Must not be * null. * @param service * The service to register. This must be some implementation of * api. This value must not be null. */ public final void registerService(final Class api, final T service) { if (api == null) { throw new NullPointerException("The service key cannot be null"); //$NON-NLS-1$ } // if (!api.isInstance(service)) { // throw new IllegalArgumentException( // "The service does not implement the given interface"); //$NON-NLS-1$ // } synchronized (this) { if (services == null) { services = new THashMap, Object>(); } final Object currentService = services.remove(api); if (currentService instanceof Disposable) { final Disposable disposable = (Disposable) currentService; disposable.dispose(); } if (service == null) { if (services.isEmpty()) { services = null; } } else { // System.out.println("register " + api.toString()); services.put(api, service); } } } }