/* * 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: * "Stephane Lacoin at Nuxeo (aka matic)" */ package org.eclipse.ecr.runtime.api; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.ecr.runtime.transaction.Transacted; import org.eclipse.ecr.runtime.transaction.TransactedServiceProvider; /** * @author "Stephane Lacoin at Nuxeo (aka matic)" * */ public abstract class AnnotatedServiceProvider implements ServiceProvider { protected static final Log log = LogFactory.getLog(TransactedServiceProvider.class); protected ServiceProvider nextProvider; boolean installed = false; protected final Map<Class<?>, Entry<?>> registry = new HashMap<Class<?>, Entry<?>>(); protected abstract Class<? extends Annotation> annotationClass(); protected abstract <T> T newProxy(T object, Class<T> clazz); public void installSelf() { // next provider can be null, we need a flag if (installed) { return; } installed = true; nextProvider = DefaultServiceProvider.getProvider(); DefaultServiceProvider.setProvider(this); } protected class Entry<T> { final Class<T> srvClass; final boolean isAnnotated; protected Entry(Class<T> srvClass) { this.srvClass = srvClass; this.isAnnotated = srvClass.isInterface() && hasAnnotations(srvClass); if (isAnnotated) { log.info("handling " + srvClass.getSimpleName() + " for " + annotationClass().getSimpleName()); } } protected boolean hasAnnotations(Class<?> srvClass) { Class<? extends Annotation> annotationClass = annotationClass(); if (srvClass.isAnnotationPresent(annotationClass)) { return true; } for (Method m : srvClass.getMethods()) { if (m.getAnnotation(Transacted.class) != null) { return true; } } return false; } public T getService() { // do not cache srv objects because we don't know if service is // adapted or not (CoreSession for instance) T srvObject = nextProvider != null ? nextProvider.getService(srvClass) : Framework.getRuntime().getService(srvClass); if (!isAnnotated) { return srvObject; } return newProxy(srvObject, srvClass); } } @Override public <T> T getService(Class<T> srvClass) { if (!registry.containsKey(srvClass)) { registry.put(srvClass, new Entry<T>(srvClass)); } return srvClass.cast(registry.get(srvClass).getService()); } }