/** * Get more info at : www.jrebirth.org . * Copyright JRebirth.org © 2011-2013 * Contact : sebastien.bordes@jrebirth.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jrebirth.af.core.facade; import org.jrebirth.af.api.application.JRebirthApplication; import org.jrebirth.af.api.component.factory.ComponentFactory; import org.jrebirth.af.api.concurrent.IJRebirthThreadPoolExecutor; import org.jrebirth.af.api.exception.CoreException; import org.jrebirth.af.api.facade.GlobalFacade; import org.jrebirth.af.api.facade.JRebirthEvent; import org.jrebirth.af.api.facade.JRebirthEventType; import org.jrebirth.af.api.link.Notifier; import org.jrebirth.af.api.log.JRLogger; import org.jrebirth.af.core.application.AbstractApplication; import org.jrebirth.af.core.component.factory.DefaultComponentFactory; import org.jrebirth.af.core.concurrent.JRebirthThreadPoolExecutor; import org.jrebirth.af.core.link.NotifierBase; import org.jrebirth.af.core.log.JRLoggerFactory; import org.jrebirth.af.core.resource.provided.JRebirthParameters; import org.jrebirth.af.core.util.ParameterUtility; /** * * The class <strong>GlobalFacadeBase</strong>. * * This class is a facade that helps to retrieve any JRebirth RIA pattern component of the application. * * It uses 3 facades that store services, commands and models of the application. It allows to dispatch waves to all required components. * * * @author Sébastien Bordes */ public class GlobalFacadeBase implements GlobalFacade, FacadeMessages { /** The JRebirth Thread Pool base name [JTP]. */ public static final String JTP_BASE_NAME = "JTP Slot "; /** The High Priority Thread Pool base name [HPTP]. */ public static final String HPTP_BASE_NAME = "HPTP Slot "; /** The class logger. */ private static final JRLogger LOGGER = JRLoggerFactory.getLogger(GlobalFacadeBase.class); /** The factory used to build all component. */ private final ComponentFactory componentFactory; /** The application. */ private final transient JRebirthApplication<?> application; /** The notifier that dispatch waves. */ private final transient Notifier notifier; /** The facade for UI components. */ private final transient UiFacade uiFacade; /** The facade for Services components. */ private final transient ServiceFacade serviceFacade; /** The facade for Commands components. */ private final transient CommandFacade commandFacade; /** The facade for Behaviors components. */ private final transient BehaviorFacade behaviorFacade; /** The default executor. */ private final IJRebirthThreadPoolExecutor executorService; /** The high priority executor used only for most important runnable. */ private final IJRebirthThreadPoolExecutor highPriorityExecutorService; /** The index of JRebirth events. */ private int eventSequence; /** * Default Constructor. Initialize all facades. * * @param application the current application launched */ public GlobalFacadeBase(final JRebirthApplication<?> application) { super(); // Attach the right EnhancedComponent Factory this.componentFactory = (ComponentFactory) ParameterUtility.buildCustomizableClass(JRebirthParameters.COMPONENT_FACTORY, DefaultComponentFactory.class, "ComponentFactory"); // Link the application this.application = application; trackEvent(JRebirthEventType.CREATE_APPLICATION, null, getApplication().getClass()); LOGGER.trace(JTP_CREATION); final int poolSize = Math.max(1, Math.round(JRebirthParameters.THREAD_POOL_SIZE_RATIO.get() * Runtime.getRuntime().availableProcessors())); // Launch the default executor this.executorService = new JRebirthThreadPoolExecutor(poolSize, new NamedThreadBuilder(((AbstractApplication<?>) application).getPoolUncaughtExceptionHandler(), JTP_BASE_NAME)); // Launch the High Priority executor this.highPriorityExecutorService = new JRebirthThreadPoolExecutor(poolSize, new NamedThreadBuilder(((AbstractApplication<?>) application).getPoolUncaughtExceptionHandler(), HPTP_BASE_NAME)); trackEvent(JRebirthEventType.CREATE_GLOBAL_FACADE, getApplication().getClass(), this.getClass()); // Build the notifier manager this.notifier = buildNotifier(); trackEvent(JRebirthEventType.CREATE_NOTIFIER, getClass(), this.notifier.getClass()); // Build the Command Facade this.commandFacade = buildCommandFacade(); trackEvent(JRebirthEventType.CREATE_COMMAND_FACADE, getClass(), this.commandFacade.getClass()); // Build the Service Facade this.serviceFacade = buildServiceFacade(); trackEvent(JRebirthEventType.CREATE_SERVICE_FACADE, getClass(), this.serviceFacade.getClass()); // Build the Ui Facade this.uiFacade = buildUiFacade(); trackEvent(JRebirthEventType.CREATE_UI_FACADE, getClass(), this.uiFacade.getClass()); // Build the Behavior Facade this.behaviorFacade = buildBehaviorFacade(); trackEvent(JRebirthEventType.CREATE_BEHAVIOR_FACADE, getClass(), this.behaviorFacade.getClass()); } /** * {@inheritDoc} */ @Override public final void trackEvent(final JRebirthEventType eventType, final Class<?> source, final Class<?> target, final String... eventData) { if (LOGGER.isInfoEnabled()) { final JRebirthEvent event = new JRebirthEventBase(this.eventSequence++, eventType, source == null ? null : source.getCanonicalName(), target == null ? null : target.getCanonicalName() , eventData); LOGGER.info(JREBIRTH_EVENT, event); } } /** * @return Returns the componentFactory. */ @Override public ComponentFactory getComponentFactory() { return this.componentFactory; } /** * {@inheritDoc} */ @Override public final JRebirthApplication<?> getApplication() { return this.application; } /** * {@inheritDoc} */ @Override public final Notifier getNotifier() { return this.notifier; } /** * {@inheritDoc} */ @Override public final UiFacade getUiFacade() { return this.uiFacade; } /** * {@inheritDoc} */ @Override public final ServiceFacade getServiceFacade() { return this.serviceFacade; } /** * {@inheritDoc} */ @Override public final CommandFacade getCommandFacade() { return this.commandFacade; } /** * {@inheritDoc} */ @Override public final BehaviorFacade getBehaviorFacade() { return this.behaviorFacade; } /** * {@inheritDoc} */ @Override public IJRebirthThreadPoolExecutor getExecutorService() { return this.executorService; } /** * {@inheritDoc} */ @Override public IJRebirthThreadPoolExecutor getHighPriorityExecutorService() { return this.highPriorityExecutorService; } /** * {@inheritDoc} */ @Override public final void stop() throws CoreException { // Manage design for extension customStop(); // Stop the thread pool if (getExecutorService() != null) { getExecutorService().shutdown(); } // Stop the high priority thread pool if (getHighPriorityExecutorService() != null) { getHighPriorityExecutorService().shutdown(); } } /** * Method to override to do some stuff when application stops. */ protected void customStop() { // Must be overridden } /** * Build the CommandFacade singleton to use. * * Can be overridden by sub class to customize its behaviors. * * @return the command facade */ protected CommandFacade buildCommandFacade() { return new CommandFacade(this); } /** * Build the ServiceFacade singleton to use. * * Can be overridden by sub class to customize its behaviors. * * @return the service facade */ protected ServiceFacade buildServiceFacade() { return new ServiceFacade(this); } /** * Build the UiFacade singleton to use. * * Can be overridden by sub class to customize its behaviors. * * @return the ui facade */ protected UiFacade buildUiFacade() { return new UiFacade(this); } /** * Build the BehaviorFacade singleton to use. * * Can be overridden by sub class to customize its facade behaviors. * * @return the behaviors facade */ protected BehaviorFacade buildBehaviorFacade() { return new BehaviorFacade(this); } /** * Build the notifier singleton to use. * * Can be overridden by sub class to customize its behaviors. * * @return the notifier */ protected NotifierBase buildNotifier() { return new NotifierBase(this); } }