/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * 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: * bstefanescu * * $Id$ */ package org.eclipse.ecr.runtime.service; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> * */ public class AdapterManager { private static final AdapterManager instance = new AdapterManager(); protected final Map<Class<?>, AdaptableDescriptor> adapters; public static AdapterManager getInstance() { return instance; } public AdapterManager() { adapters = new ConcurrentHashMap<Class<?>, AdaptableDescriptor>(); } @SuppressWarnings("unchecked") public <T> T getAdapter(Object instance, Class<T> adapter) { AdapterFactory af = getAdapterFactory(instance, adapter); if (af != null) { return adapter.cast(af.getAdapter(instance, adapter)); } if (adapter.isInstance(instance)) { return (T)instance; } return null; } public AdapterFactory<?> getAdapterFactory(Object instance, Class<?> adapter) { return getAdapterFactory(instance.getClass(), adapter); } protected AdapterFactory<?> getAdapterFactory(Class<?> klass, Class<?> adapter) { AdaptableDescriptor descriptor = adapters.get(klass); if (descriptor != null) { AdapterFactory<?> factory = descriptor.getAdapterFactory(adapter); if (factory != null) { return factory; } } return findAdapterFactory(klass, adapter); } protected synchronized AdapterFactory<?> findAdapterFactory(Class<?> klass, Class<?> adapter) { // try again the lookup (we are synchronized now) AdaptableDescriptor descriptor = adapters.get(klass); if (descriptor != null) { AdapterFactory<?> factory = descriptor.getAdapterFactory(adapter); if (factory != null) { return factory; } } else { descriptor = new AdaptableDescriptor(klass); adapters.put(klass, descriptor); } // ask super types Class<?>[] superTypes = descriptor.getSuperTypes(); for (Class<?> superType : superTypes) { AdapterFactory<?> factory = findAdapterFactory(superType, adapter); if (factory != null) { descriptor.addAdapterFactory(adapter, factory); return factory; } } return null; } public synchronized void registerAdapter(AdapterFactory<?> factory) { Class<?> adaptable = factory.getAdaptableType(); AdaptableDescriptor descriptor = adapters.get(adaptable); if (descriptor == null) { descriptor = new AdaptableDescriptor(adaptable); adapters.put(adaptable, descriptor); } for (Class<?> klass : factory.getAdapterTypes()) { descriptor.addAdapterFactory(klass, factory); } } public void unregisterAdapter(Class<?> adapter) { //TODO } }