001: /*******************************************************************************
002: * Copyright (c) 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: ******************************************************************************/package org.eclipse.ui.internal.services;
011:
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: import org.eclipse.swt.widgets.Shell;
017: import org.eclipse.ui.services.IDisposable;
018: import org.eclipse.ui.services.IServiceLocator;
019:
020: /**
021: * @since 3.2
022: *
023: */
024: public final class ServiceLocator implements IDisposable, INestable,
025: IServiceLocator {
026:
027: /**
028: * The parent for this service locator. If a service can't be found in this
029: * locator, then the parent is asked. This value may be <code>null</code>
030: * if there is no parent.
031: */
032: private final IServiceLocator parent;
033:
034: /**
035: * The map of services maintained by the workbench window. These services
036: * are initialized during workbench window during the
037: * {@link #configureShell(Shell)}. This value is <code>null</code> until
038: * a service is registered.
039: */
040: private Map services = null;
041:
042: /**
043: * Constructs a service locator with no parent.
044: */
045: public ServiceLocator() {
046: this (null);
047: }
048:
049: /**
050: * Constructs a service locator with the given parent.
051: *
052: * @param parent
053: * The parent for this service locator; this value may be
054: * <code>null</code>.
055: */
056: public ServiceLocator(final IServiceLocator parent) {
057: this .parent = parent;
058: }
059:
060: public final void activate() {
061: if (services != null) {
062: final Iterator serviceItr = services.values().iterator();
063: while (serviceItr.hasNext()) {
064: final Object service = serviceItr.next();
065: if (service instanceof INestable) {
066: final INestable nestableService = (INestable) service;
067: nestableService.activate();
068: }
069: }
070: }
071: }
072:
073: public final void deactivate() {
074: if (services != null) {
075: final Iterator serviceItr = services.values().iterator();
076: while (serviceItr.hasNext()) {
077: final Object service = serviceItr.next();
078: if (service instanceof INestable) {
079: final INestable nestableService = (INestable) service;
080: nestableService.deactivate();
081: }
082: }
083: }
084: }
085:
086: public final void dispose() {
087: if (services != null) {
088: final Iterator serviceItr = services.values().iterator();
089: while (serviceItr.hasNext()) {
090: final Object object = serviceItr.next();
091: if (object instanceof IDisposable) {
092: final IDisposable service = (IDisposable) object;
093: service.dispose();
094: }
095: }
096: services = null;
097: }
098: }
099:
100: public final Object getService(final Class key) {
101: final Object service;
102: if (services != null) {
103: service = services.get(key);
104: } else {
105: service = null;
106: }
107: if ((service == null) && (parent != null)) {
108: return parent.getService(key);
109: }
110:
111: return service;
112: }
113:
114: public final boolean hasService(final Class key) {
115: if (services != null) {
116: if (services.containsKey(key)) {
117: return true;
118: }
119: }
120:
121: return false;
122: }
123:
124: /**
125: * Registers a service with this locator. If there is an existing service
126: * matching the same <code>api</code> and it implements
127: * {@link IDisposable}, it will be disposed.
128: *
129: * @param api
130: * This is the interface that the service implements. Must not be
131: * <code>null</code>.
132: * @param service
133: * The service to register. This must be some implementation of
134: * <code>api</code>. This value must not be <code>null</code>.
135: */
136: public final void registerService(final Class api,
137: final Object service) {
138: if (api == null) {
139: throw new NullPointerException(
140: "The service key cannot be null"); //$NON-NLS-1$
141: }
142:
143: if (!api.isInstance(service)) {
144: throw new IllegalArgumentException(
145: "The service does not implement the given interface"); //$NON-NLS-1$
146: }
147:
148: if (services == null) {
149: services = new HashMap();
150: }
151:
152: if (services.containsKey(api)) {
153: final Object currentService = services.remove(api);
154: if (currentService instanceof IDisposable) {
155: final IDisposable disposable = (IDisposable) currentService;
156: disposable.dispose();
157: }
158: }
159:
160: if (service == null) {
161: if (services.isEmpty()) {
162: services = null;
163: }
164: } else {
165: services.put(api, service);
166: }
167: }
168:
169: }
|