All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.richfaces.application.ServiceTracker Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.richfaces.application;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.faces.FacesException;
import javax.faces.context.FacesContext;

/**
 * 

* Tracker class to provide access to various framework implementation services. Examples of such services are: * {@link org.richfaces.skin.SkinFactory}, TBD. *

* * *

* This class managess application-scoped service factories that are stored in the map with {@link Thread#currentThread()} * Context classloader as the key. Therefore, there is only one instance per JEE application in the current JVM. *

*

* actuall cal for the service instance delegated to the current factory *

* services tracking class diagramm * * *

* Note: in initial state this class is not synchronized and presumes that all modification operations are done in a * context of single-thread (in JSF initialization listener). *

* * @author Nick Belaevski * @since 4.0 */ public final class ServiceTracker { /** *

*

*/ private static final Map INSTANCES = new ConcurrentHashMap(); /** *

* This class supposed to use with static methods only and cannot be instantiated. *

*/ private ServiceTracker() { } /** *

* Get service instance for given type. This is a wrapper method for {@link #getService(FacesContext, Class)} that gets * faces context by {@link FacesContext#getCurrentInstance()} call, if needed. *

* * @param The service type, usually interface. * @param target Service type class. * @return service implementation instance. */ public static T getService(Class target) { return getServicesFactory().getInstance(target); } /** *

* Get service instance for given type. *

* * @param The service type, usually interface. * @param context current {@link FacesContext}. * @param target Service type class. * @return service instance. */ public static T getService(FacesContext context, Class target) { return getServicesFactory().getInstance(target); } private static ServicesFactory getServicesFactory() { if (!INSTANCES.containsKey(getCurrentLoader())) { throw new FacesException("Service Tracker has not been initialized"); } ServicesFactory service = INSTANCES.get(getCurrentLoader()); return service; } private static ClassLoader getCurrentLoader() { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (null == contextClassLoader) { contextClassLoader = ServiceTracker.class.getClassLoader(); } return contextClassLoader; } /** *

* Set service factory implementation for the current context. *

* * @param factory */ public static void setFactory(ServicesFactory factory) { INSTANCES.put(getCurrentLoader(), factory); } /** *

* Release factory service associated with current context. *

*/ public static void release() { ServicesFactory servicesFactory = INSTANCES.remove(getCurrentLoader()); servicesFactory.release(); } /** * Provides proxy which delegates to the given targetService interface once the method is invoked on the targetService. * * @param targetService the service to delegate operations to * @return proxy which delegates to the given targetService */ @SuppressWarnings("unchecked") public static T getProxy(final Class targetService) { return (T) Proxy.newProxyInstance(getCurrentLoader(), new Class[] { targetService }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { T service = ServiceTracker.getService(targetService); if (service == null) { throw new IllegalStateException("Failed to obtain service " + targetService.getSimpleName()); } return method.invoke(service, args); } }); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy