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

org.fax4j.spi.FaxClientSpiFactory Maven / Gradle / Ivy

package org.fax4j.spi;

import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.fax4j.FaxException;
import org.fax4j.ProductInfo;
import org.fax4j.Provider;
import org.fax4j.common.Logger;
import org.fax4j.common.LoggerManager;
import org.fax4j.util.LibraryConfigurationLoader;
import org.fax4j.util.ReflectionHelper;
import org.fax4j.util.SpiUtil;

/**
 * This is the fax client SPI factory which is used to create
 * new instances of the fax client SPI.
*
* The configuration of the fax4j framework is made up of 3 layers.
* The configuration is based on simple properties.
* Each layer overrides the lower layers by adding/changing the property values.
* The first layer is the internal fax4j.properties file located in the fax4j jar.
* This layer contains the preconfigured values for the fax4j framework and can be changed * by updating these properties in the higher layers.
* The second layer is the external fax4j.properties file that is located on the classpath.
* This file is optional and provides the ability to override the internal configuration for the * entire fax4j framework.
* The top most layer is the optional java.util.Properties object provided by the external classes * when creating a new fax client.
* These properties enable to override the configuration of the lower 2 layers.
*
* Below table describes the configuration values relevant for this class, * for SPI specific configuration, see the relevant SPI class javadoc.
* Configuration: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDescriptionPreconfigured ValueDefault ValueMandatory
org.fax4j.spi.type.map.xxxFor each SPI type, there is a property that (with prefix: org.fax4j.spi.type.map. * and type name for example: org.fax4j.spi.type.map.adapter) which defines the SPI class name * for the given SPI type.
* For example:
* org.fax4j.spi.type.map.adapter=org.fax4j.spi.adapter.AdapterFaxClientSpi
* Means that for SPI type adapter, the SPI class to be used is org.fax4j.spi.adapter.AdapterFaxClientSpi
* org.fax4j.spi.type.map.adapter=org.fax4j.spi.adapter.AdapterFaxClientSpi
* org.fax4j.spi.type.map.windows=org.fax4j.spi.windows.WindowsFaxClientSpi
* org.fax4j.spi.type.map.vbs=org.fax4j.spi.vbs.VBSFaxClientSpi
* org.fax4j.spi.type.map.mail=org.fax4j.spi.email.MailFaxClientSpi
* org.fax4j.spi.type.map.http=org.fax4j.spi.http.HTTPTemplateFaxClientSpi
* org.fax4j.spi.type.map.process=org.fax4j.spi.process.ProcessFaxClientSpi
* org.fax4j.spi.type.map.linux=org.fax4j.spi.linux.LinuxFaxClientSpi
* org.fax4j.spi.type.map.mac=org.fax4j.spi.mac.MacFaxClientSpi
* org.fax4j.spi.type.map.hylafax=org.fax4j.spi.hylafax.HylaFaxClientSpi
* org.fax4j.spi.type.map.comm=org.fax4j.spi.comm.CommFaxClientSpi
* org.fax4j.spi.type.map.interfax=org.fax4j.spi.interfax.InterfaxMailFaxClientSpi
* org.fax4j.spi.type.map.send2fax=org.fax4j.spi.send2fax.Send2FaxMailFaxClientSpi
* org.fax4j.spi.type.map.metrofax=org.fax4j.spi.metrofax.MetroFaxMailFaxClientSpi
* org.fax4j.spi.type.map.faxage=org.fax4j.spi.faxage.FaxAgeMailFaxClientSpi
* org.fax4j.spi.type.map.extremefax=org.fax4j.spi.extremefax.ExtremeFaxMailFaxClientSpi
* org.fax4j.spi.type.map.efax=org.fax4j.spi.efax.EFaxMailFaxClientSpi
* org.fax4j.spi.type.map.rfax=org.fax4j.spi.java4less.RFaxFaxClientSpi *
NANA
org.fax4j.spi.default.typeIn case the SPI type was not provided in the createFaxClientSpi method, the type will be taken from * this property value.adapternonefalse
org.fax4j.logger.class.nameDefines the internal fax4j logger class name.
* The logger must implement the org.fax4j.common.Logger interface and have an empty constructor.
* This property can only be set in the internal fax4j.properties and the fax4j.properties on the classpath, * providing these values as part of the java.util.Properties input of the createFaxClientSpi will have no affect. *
org.fax4j.common.SimpleLoggerorg.fax4j.common.SimpleLoggerfalse
org.fax4j.logger.log.levelDefines the internal fax4j logger log level.
* The possible values are: DEBUG, INFO and ERROR.
* This property can only be set in the internal fax4j.properties and the fax4j.properties on the classpath, * providing these values as part of the java.util.Properties input of the createFaxClientSpi will have no affect. *
ERRORERRORfalse
org.fax4j.monitor.class.nameDefines the internal fax job monitor class name.
* This property can only be set in the internal fax4j.properties and the fax4j.properties on the classpath, * providing these values as part of the java.util.Properties input of the createFaxClientSpi will have no affect. *
org.fax4j.spi.FaxJobMonitorImplorg.fax4j.spi.FaxJobMonitorImplfalse
org.fax4j.proxy.enabledTrue to enable the fax client SPI proxy.truetruefalse
org.fax4j.proxy.class.nameDefines the fax client SPI proxy class name.org.fax4j.spi.FaxClientSpiProxyImplorg.fax4j.spi.FaxClientSpiProxyImplfalse
org.fax4j.proxy.interceptor.listA list of interceptor types, separated by a ';' character.
* Each type must have a matching org.fax4j.proxy.interceptor.type.xxx property. *
lognonefalse
org.fax4j.proxy.interceptor.type.xxxThe interceptor type to class name mapping.org.fax4j.proxy.interceptor.type.log=org.fax4j.spi.LogFaxClientSpiInterceptornonefalse
*
* * @author Sagie Gur-Ari * @version 1.14 * @since 0.1 */ public final class FaxClientSpiFactory { /**The system configuration*/ private static Map systemConfiguration; /**The logger*/ private static Logger logger; /**The fax job monitor*/ private static FaxJobMonitor faxJobMonitor; /**The fax job monitor class name property key*/ public static final String FAX_JOB_MONITOR_CLASS_NAME_PROPERTY_KEY="org.fax4j.monitor.class.name"; /**The default SPI type property key*/ public static final String DEFAULT_SPI_TYPE_PROPERTY_KEY="org.fax4j.spi.default.type"; /**The SPI class name to type mapping property key prefix*/ public static final String SPI_CLASS_NAME_TYPE_MAP_PROPERTY_KEY_PREFIX="org.fax4j.spi.type.map."; /**The SPI proxy enabled property key*/ public static final String SPI_PROXY_ENABLED_PROPERTY_KEY="org.fax4j.proxy.enabled"; /**The SPI proxy class name property key*/ public static final String SPI_PROXY_CLASS_NAME_PROPERTY_KEY="org.fax4j.proxy.class.name"; /**The SPI interceptor list property key*/ public static final String SPI_INTERCEPTOR_LIST_PROPERTY_KEY="org.fax4j.proxy.interceptor.list"; /**The SPI interceptor type property key prefix*/ public static final String SPI_INTERCEPTOR_TYPE_PROPERTY_KEY_PREFIX="org.fax4j.proxy.interceptor.type."; /**The SPI interceptor list separator ';'*/ public static final String SPI_INTERCEPTOR_LIST_SEPARATOR=";"; /** * This is the default constructor. */ private FaxClientSpiFactory() { super(); } /** * This function creates a new fax client SPI based on the provided configuration.
* This is an internal framework method and should not be invoked by classes outside the * fax4j framework. * * @param type * The fax client type (may be null for default type) * @param configuration * The fax client configuration (may be null) * @return The fax client SPI instance */ public static FaxClientSpi createFaxClientSpi(String type,Properties configuration) { //get layered configuration Map layeredConfiguration=FaxClientSpiFactory.getConfiguration(configuration); String updatedType=type; if((updatedType==null)||(updatedType.length()==0)) { //get default type updatedType=layeredConfiguration.get(FaxClientSpiFactory.DEFAULT_SPI_TYPE_PROPERTY_KEY); if((updatedType==null)||(updatedType.length()==0)) { throw new FaxException("Type value not provided and not configured in fax4j.properties"); } } //get SPI class name String key=FaxClientSpiFactory.SPI_CLASS_NAME_TYPE_MAP_PROPERTY_KEY_PREFIX+updatedType; String className=layeredConfiguration.get(key); if((className==null)||(className.length()==0)) { throw new FaxException("Class name for type: "+updatedType+" not configured in fax4j.properties"); } //get logger Logger spiLogger=FaxClientSpiFactory.getLogger(); //get fax job monitor FaxJobMonitor spiFaxJobMonitor=FaxClientSpiFactory.getFaxJobMonitor(); FaxClientSpi faxClientSpi=null; try { //create new instance Class classDefinition=Class.forName(className); faxClientSpi=(FaxClientSpi)classDefinition.newInstance(); } catch(Exception exception) { throw new FaxException("Unable to create a new fax client SPI instance for class name: "+className,exception); } //initialize SPI faxClientSpi.initialize(layeredConfiguration,spiLogger,spiFaxJobMonitor); //check if proxy is enabled String valueStr=faxClientSpi.getConfigurationValue(FaxClientSpiFactory.SPI_PROXY_ENABLED_PROPERTY_KEY); if(valueStr==null) { valueStr=Boolean.toString(true); } boolean enableProxy=Boolean.parseBoolean(valueStr); FaxClientSpi faxClientSpiWrapper=faxClientSpi; if(enableProxy) { //create fax client SPI proxy FaxClientSpiProxy faxClientSpiProxy=FaxClientSpiFactory.createFaxClientSpiProxy(faxClientSpi); //create proxy ClassLoader classLoader=ReflectionHelper.getThreadContextClassLoader(); faxClientSpiWrapper=(FaxClientSpi)Proxy.newProxyInstance(classLoader,new Class[]{FaxClientSpi.class},faxClientSpiProxy); } //validate provider Provider provider=faxClientSpiWrapper.getProvider(); if(provider==null) { throw new FaxException("Provider information not available in SPI."); } String name=provider.getName(); if(name==null) { throw new FaxException("Provider name not available in SPI."); } return faxClientSpiWrapper; } /** * This function returns the system configuration (internal and external * fax4j.properties files). * * @return The system configuration */ protected static Map getSystemConfiguration() { if(FaxClientSpiFactory.systemConfiguration==null) { synchronized(FaxClientSpiFactory.class) { if(FaxClientSpiFactory.systemConfiguration==null) { //read properties Properties properties=LibraryConfigurationLoader.readInternalAndExternalConfiguration(); //convert to map Map map=new HashMap(properties.size()*3/4); SpiUtil.copyPropertiesToMap(properties,map); //normalize map map=new HashMap(map); //set instance FaxClientSpiFactory.systemConfiguration=Collections.unmodifiableMap(map); } } } return FaxClientSpiFactory.systemConfiguration; } /** * Returns the configuration to be used by the new SPI instance.
* The configuration of the fax client SPI is made up of 3 layers. * The lowest layer is the internal fax4j.properties file located in the fax4j jar. * This configuration file contains the initial default configuration. * The next layer is the external fax4j.properties file that is located on the classpath. * This file is optional and provides the ability to override the internal configuration. * The top most layer is the optional properties object provided by the external classes. * These properties enable to override the configuration of the lower 2 layers. * * @param configuration * The fax client configuration (may be null) * @return The fax client layered configuration */ protected static Map getConfiguration(Properties configuration) { //get system configuration Map systemConfig=FaxClientSpiFactory.getSystemConfiguration(); //create new map Map layeredConfiguration=new HashMap(systemConfig); if(configuration!=null) { //convert to map SpiUtil.copyPropertiesToMap(configuration,layeredConfiguration); } return layeredConfiguration; } /** * This function returns the internal logger for the fax4j framework. * * @return The logger */ private static Logger getLogger() { //get system configuration Map systemConfig=FaxClientSpiFactory.getSystemConfiguration(); if(FaxClientSpiFactory.logger==null) { synchronized(FaxClientSpiFactory.class) { if(FaxClientSpiFactory.logger==null) { //get logger manager LoggerManager loggerManager=LoggerManager.getInstance(); //initialize logger loggerManager.initializeLogger(systemConfig); //get logger Logger localLogger=loggerManager.getLogger(); //print product info localLogger.logDebug(new Object[]{ProductInfo.getProductInfoPrintout()},null); //keep reference FaxClientSpiFactory.logger=localLogger; } } } return FaxClientSpiFactory.logger; } /** * This function returns the fax job monitor. * * @return The fax job monitor */ private static FaxJobMonitor getFaxJobMonitor() { //get system configuration Map systemConfig=FaxClientSpiFactory.getSystemConfiguration(); if(FaxClientSpiFactory.faxJobMonitor==null) { synchronized(FaxClientSpiFactory.class) { if(FaxClientSpiFactory.faxJobMonitor==null) { //create fax job monitor FaxJobMonitor localFaxJobMonitor=FaxClientSpiFactory.createFaxJobMonitor(systemConfig); //get logger Logger localLogger=FaxClientSpiFactory.getLogger(); //initialize localFaxJobMonitor.initialize(systemConfig,localLogger); //keep reference FaxClientSpiFactory.faxJobMonitor=localFaxJobMonitor; } } } return FaxClientSpiFactory.faxJobMonitor; } /** * This function creates the fax job monitor used by the fax4j framework. * * @param systemConfig * The system configuration * @return The logger */ private static FaxJobMonitor createFaxJobMonitor(Map systemConfig) { //get class name String className=systemConfig.get(FaxClientSpiFactory.FAX_JOB_MONITOR_CLASS_NAME_PROPERTY_KEY); if((className==null)||(className.length()==0)) { className=FaxJobMonitorImpl.class.getName(); } FaxJobMonitor faxJobMonitorInstance=null; try { //create new instance Class classDefinition=Class.forName(className); faxJobMonitorInstance=(FaxJobMonitor)classDefinition.newInstance(); } catch(Exception exception) { throw new FaxException("Unable to create a new fax job monitor instance for class name: "+className,exception); } return faxJobMonitorInstance; } /** * This function creates the fax client SPI proxy. * * @param faxClientSpi * The fax client SPI * @return The fax client SPI proxy */ private static FaxClientSpiProxy createFaxClientSpiProxy(FaxClientSpi faxClientSpi) { //create fax client SPI interceptors FaxClientSpiInterceptor[] interceptors=FaxClientSpiFactory.createFaxClientSpiInterceptors(faxClientSpi); //get class name String className=faxClientSpi.getConfigurationValue(FaxClientSpiFactory.SPI_PROXY_CLASS_NAME_PROPERTY_KEY); if(className==null) { className=FaxClientSpiProxyImpl.class.getName(); } FaxClientSpiProxy faxClientSpiProxy=null; try { //create new instance Class classDefinition=Class.forName(className); faxClientSpiProxy=(FaxClientSpiProxy)classDefinition.newInstance(); } catch(Exception exception) { throw new FaxException("Unable to create a new fax client SPI proxy instance for class name: "+className,exception); } //initialize faxClientSpiProxy.initialize(faxClientSpi,interceptors); return faxClientSpiProxy; } /** * This function creates the fax client SPI interceptors. * * @param faxClientSpi * The fax client SPI * @return The interceptors */ private static FaxClientSpiInterceptor[] createFaxClientSpiInterceptors(FaxClientSpi faxClientSpi) { //get type list String typeListStr=faxClientSpi.getConfigurationValue(FaxClientSpiFactory.SPI_INTERCEPTOR_LIST_PROPERTY_KEY); FaxClientSpiInterceptor[] interceptors=null; if(typeListStr!=null) { //split list String[] types=typeListStr.split(FaxClientSpiFactory.SPI_INTERCEPTOR_LIST_SEPARATOR); //get amount int amount=types.length; String type=null; String propertyKey=null; String className=null; FaxClientSpiInterceptor interceptor=null; List interceptorList=new LinkedList(); for(int index=0;index0)) { //get property key propertyKey=FaxClientSpiFactory.SPI_INTERCEPTOR_TYPE_PROPERTY_KEY_PREFIX+type; //get class name className=faxClientSpi.getConfigurationValue(propertyKey); if(className==null) { throw new FaxException("Class name not defined by property: "+propertyKey+" for SPI interceptor."); } try { //create new instance Class classDefinition=Class.forName(className); interceptor=(FaxClientSpiInterceptor)classDefinition.newInstance(); } catch(Exception exception) { throw new FaxException("Unable to create a new fax client SPI interceptor instance for class name: "+className,exception); } //initialize interceptor.initialize(faxClientSpi); //add to list interceptorList.add(interceptor); } //convert to array interceptors=interceptorList.toArray(new FaxClientSpiInterceptor[interceptorList.size()]); } } return interceptors; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy