001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 *
012 * $Id$
013 */
014
015package org.nuxeo.runtime.api;
016
017import java.util.Hashtable;
018import java.util.Map;
019
020/**
021 * A service provider.
022 * <p>
023 * A service provider is used by the framework to be able to change the local services are found
024 * <p>
025 * For example, you may want to use a simple service provider for testing purpose to avoid loading the nuxeo runtime
026 * framework to register services.
027 *
028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
029 */
030public class DefaultServiceProvider implements ServiceProvider {
031
032    private static ServiceProvider provider;
033
034    public static void setProvider(ServiceProvider provider) {
035        DefaultServiceProvider.provider = provider;
036    }
037
038    public static ServiceProvider getProvider() {
039        return provider;
040    }
041
042    protected final Map<Class<?>, ServiceRef> registry = new Hashtable<Class<?>, ServiceRef>();
043
044    @Override
045    @SuppressWarnings("unchecked")
046    public <T> T getService(Class<T> serviceClass) {
047        ServiceRef ref = registry.get(serviceClass);
048        if (ref != null) {
049            return (T) ref.getService();
050        }
051        return null;
052    }
053
054    public <T> void registerService(Class<T> serviceClass, Class<?> implClass) {
055        registry.put(serviceClass, new ServiceRef(implClass));
056    }
057
058    public <T> void registerService(Class<T> serviceClass, Object impl) {
059        registry.put(serviceClass, new ServiceRef(impl));
060    }
061
062    public static class ServiceRef {
063        final Class<?> type;
064
065        Object service;
066
067        public ServiceRef(Object service) {
068            this.service = service;
069            type = service.getClass();
070        }
071
072        public ServiceRef(Class<?> type) {
073            service = null;
074            this.type = type;
075        }
076
077        public Class<?> getType() {
078            return type;
079        }
080
081        public Object getService() {
082            if (service == null) {
083                try {
084                    service = type.newInstance();
085                } catch (ReflectiveOperationException e) {
086                    throw new RuntimeException(e);
087                }
088            }
089            return service;
090        }
091    }
092
093}