diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java index 1a01e5feda..0545279038 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -45,9 +45,13 @@ import org.compiere.model.PaymentInterface; import org.compiere.model.PaymentProcessor; import org.compiere.model.StandardTaxProvider; import org.compiere.process.ProcessCall; +import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.PaymentExport; import org.compiere.util.ReplenishInterface; +import org.idempiere.distributed.ICacheService; +import org.idempiere.distributed.IClusterService; +import org.idempiere.distributed.IMessageService; import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO; import org.idempiere.fa.service.api.IDepreciationMethod; import org.idempiere.fa.service.api.IDepreciationMethodFactory; @@ -63,6 +67,8 @@ public class Core { private final static CLogger s_log = CLogger.getCLogger(Core.class); + private static final CCache> s_resourceFinderCache = new CCache<>(null, "IResourceFinder", 100, false); + /** * @return list of active resource finder */ @@ -70,16 +76,33 @@ public class Core { return new IResourceFinder() { public URL getResource(String name) { - List f = Service.locator().list(IResourceFinder.class).getServices(); - for (IResourceFinder finder : f) { - URL url = finder.getResource(name); - if (url!=null) - return url; + IServiceReferenceHolder cache = s_resourceFinderCache.get(name); + if (cache != null) { + IResourceFinder service = cache.getService(); + if (service != null) { + URL url = service.getResource(name); + if (url!=null) + return url; + } + s_resourceFinderCache.remove(name); + } + List> f = Service.locator().list(IResourceFinder.class).getServiceReferences(); + for (IServiceReferenceHolder finder : f) { + IResourceFinder service = finder.getService(); + if (service != null) { + URL url = service.getResource(name); + if (url!=null) { + s_resourceFinderCache.put(name, finder); + return url; + } + } } return null; } }; } + + private static final CCache>> s_columnCalloutFactoryCache = new CCache<>(null, "List", 100, false); /** * @@ -89,20 +112,56 @@ public class Core { */ public static List findCallout(String tableName, String columnName) { List list = new ArrayList(); - List factories = Service.locator().list(IColumnCalloutFactory.class).getServices(); + + String cacheKey = tableName + "." + columnName; + List> cache = s_columnCalloutFactoryCache.get(cacheKey); + if (cache != null) { + boolean staleReference = false; + for (IServiceReferenceHolder factory : cache) { + IColumnCalloutFactory service = factory.getService(); + if (service != null) { + IColumnCallout[] callouts = service.getColumnCallouts(tableName, columnName); + if (callouts != null && callouts.length > 0) { + for(IColumnCallout callout : callouts) { + list.add(callout); + } + } else { + staleReference = true; + break; + } + } else { + staleReference = true; + break; + } + } + if (!staleReference) + return list; + else + s_columnCalloutFactoryCache.remove(cacheKey); + } + + List> factories = Service.locator().list(IColumnCalloutFactory.class).getServiceReferences(); + List> found = new ArrayList<>(); if (factories != null) { - for(IColumnCalloutFactory factory : factories) { - IColumnCallout[] callouts = factory.getColumnCallouts(tableName, columnName); - if (callouts != null && callouts.length > 0) { - for(IColumnCallout callout : callouts) { - list.add(callout); + for(IServiceReferenceHolder factory : factories) { + IColumnCalloutFactory service = factory.getService(); + if (service != null) { + IColumnCallout[] callouts = service.getColumnCallouts(tableName, columnName); + if (callouts != null && callouts.length > 0) { + for(IColumnCallout callout : callouts) { + list.add(callout); + } + found.add(factory); } } } + s_columnCalloutFactoryCache.put(cacheKey, found); } return list; } + private static final CCache> s_calloutFactoryCache = new CCache<>(null, "ICalloutFactory", 100, false); + // IDEMPIERE-2732 /** * @@ -111,31 +170,65 @@ public class Core { * @return callout for className */ public static Callout getCallout(String className, String methodName) { - List factories = Service.locator().list(ICalloutFactory.class).getServices(); - if (factories != null) { - for(ICalloutFactory factory : factories) { - Callout callout = factory.getCallout(className, methodName); + String cacheKey = className + "::" + methodName; + IServiceReferenceHolder cache = s_calloutFactoryCache.get(cacheKey); + if (cache != null) { + ICalloutFactory service = cache.getService(); + if (service != null) { + Callout callout = service.getCallout(className, methodName); if (callout != null) { return callout; } } + s_calloutFactoryCache.remove(cacheKey); + } + List> factories = Service.locator().list(ICalloutFactory.class).getServiceReferences(); + if (factories != null) { + for(IServiceReferenceHolder factory : factories) { + ICalloutFactory service = factory.getService(); + if (service != null) { + Callout callout = service.getCallout(className, methodName); + if (callout != null) { + s_calloutFactoryCache.put(cacheKey, factory); + return callout; + } + } + } } return null; } + private static final CCache> s_processFactoryCache = new CCache<>(null, "IProcessFactory", 100, false); + /** * * @param processId Java class name or equinox extension id * @return ProcessCall instance or null if processId not found */ public static ProcessCall getProcess(String processId) { - List factories = getProcessFactories(); - if (factories != null && !factories.isEmpty()) { - for(IProcessFactory factory : factories) { - ProcessCall process = factory.newProcessInstance(processId); + IServiceReferenceHolder cache = s_processFactoryCache.get(processId); + if (cache != null) { + IProcessFactory service = cache.getService(); + if (service != null) { + ProcessCall process = service.newProcessInstance(processId); if (process != null) return process; } + s_processFactoryCache.remove(processId); + } + + List> factories = getProcessFactories(); + if (factories != null && !factories.isEmpty()) { + for(IServiceReferenceHolder factory : factories) { + IProcessFactory service = factory.getService(); + if (service != null) { + ProcessCall process = service.newProcessInstance(processId); + if (process != null) { + s_processFactoryCache.put(processId, factory); + return process; + } + } + } } return null; } @@ -144,18 +237,19 @@ public class Core { * This method load the process factories waiting until the DefaultProcessFactory on base is loaded (IDEMPIERE-3829) * @return List of factories implementing IProcessFactory */ - private static List getProcessFactories() { - List factories = null; + private static List> getProcessFactories() { + List> factories = null; int maxIterations = 5; int waitMillis = 1000; int iterations = 0; boolean foundDefault = false; while (true) { - factories = Service.locator().list(IProcessFactory.class).getServices(); + factories = Service.locator().list(IProcessFactory.class).getServiceReferences(); if (factories != null && !factories.isEmpty()) { - for(IProcessFactory factory : factories) { + for(IServiceReferenceHolder factory : factories) { // wait until DefaultProcessFactory is loaded - if (factory instanceof DefaultProcessFactory) { + IProcessFactory service = factory.getService(); + if (service instanceof DefaultProcessFactory) { foundDefault = true; break; } @@ -173,32 +267,64 @@ public class Core { return factories; } + private static final CCache> s_modelValidatorFactoryCache = new CCache<>(null, "IModelValidatorFactory", 100, false); + /** * * @param validatorId Java class name or equinox extension Id * @return ModelValidator instance of null if validatorId not found */ public static ModelValidator getModelValidator(String validatorId) { - List factoryList = Service.locator().list(IModelValidatorFactory.class).getServices(); - if (factoryList != null) { - for(IModelValidatorFactory factory : factoryList) { - ModelValidator validator = factory.newModelValidatorInstance(validatorId); + IServiceReferenceHolder cache = s_modelValidatorFactoryCache.get(validatorId); + if (cache != null) { + IModelValidatorFactory service = cache.getService(); + if (service != null) { + ModelValidator validator = service.newModelValidatorInstance(validatorId); if (validator != null) return validator; } + s_modelValidatorFactoryCache.remove(validatorId); + } + List> factoryList = Service.locator().list(IModelValidatorFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IModelValidatorFactory service = factory.getService(); + if (service != null) { + ModelValidator validator = service.newModelValidatorInstance(validatorId); + if (validator != null) { + s_modelValidatorFactoryCache.put(validatorId, factory); + return validator; + } + } + } } return null; } + private static IServiceReferenceHolder s_keystoreServiceReference = null; + /** * - * @return keystore + * @return {@link IKeyStore} */ public static IKeyStore getKeyStore(){ - return Service.locator().locate(IKeyStore.class).getService(); + IKeyStore keystoreService = null; + if (s_keystoreServiceReference != null) { + keystoreService = s_keystoreServiceReference.getService(); + if (keystoreService != null) + return keystoreService; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IKeyStore.class).getServiceReference(); + if (serviceReference != null) { + keystoreService = serviceReference.getService(); + s_keystoreServiceReference = serviceReference; + } + return keystoreService; } + private static final CCache> s_paymentProcessorFactoryCache = new CCache<>(null, "IPaymentProcessorFactory", 100, false); + /** * Get payment processor instance * @param mbap payment processor model @@ -216,14 +342,31 @@ public class Core { } // PaymentProcessor myProcessor = null; - - List factoryList = Service.locator().list(IPaymentProcessorFactory.class).getServices(); - if (factoryList != null) { - for(IPaymentProcessorFactory factory : factoryList) { - PaymentProcessor processor = factory.newPaymentProcessorInstance(className); - if (processor != null) { + IServiceReferenceHolder cache = s_paymentProcessorFactoryCache.get(className); + if (cache != null) { + IPaymentProcessorFactory service = cache.getService(); + if (service != null) { + PaymentProcessor processor = service.newPaymentProcessorInstance(className); + if (processor != null) myProcessor = processor; - break; + } + if (myProcessor == null) + s_paymentProcessorFactoryCache.remove(className); + } + + if (myProcessor == null) { + List> factoryList = Service.locator().list(IPaymentProcessorFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IPaymentProcessorFactory service = factory.getService(); + if (service != null) { + PaymentProcessor processor = service.newPaymentProcessorInstance(className); + if (processor != null) { + myProcessor = processor; + s_paymentProcessorFactoryCache.put(className, factory); + break; + } + } } } } @@ -239,6 +382,8 @@ public class Core { return myProcessor; } + private static final CCache> s_bankStatementLoaderFactoryCache = new CCache<>(null, "IBankStatementLoaderFactory", 100, false); + /** * get BankStatementLoader instance * @@ -252,15 +397,30 @@ public class Core { } BankStatementLoaderInterface myBankStatementLoader = null; - - List factoryList = - Service.locator().list(IBankStatementLoaderFactory.class).getServices(); - if (factoryList != null) { - for(IBankStatementLoaderFactory factory : factoryList) { - BankStatementLoaderInterface loader = factory.newBankStatementLoaderInstance(className); - if (loader != null) { + IServiceReferenceHolder cache = s_bankStatementLoaderFactoryCache.get(className); + if (cache != null) { + IBankStatementLoaderFactory service = cache.getService(); + if (service != null) { + BankStatementLoaderInterface loader = service.newBankStatementLoaderInstance(className); + if (loader != null) myBankStatementLoader = loader; - break; + } + if (myBankStatementLoader == null) + s_bankStatementLoaderFactoryCache.remove(className); + } + if (myBankStatementLoader == null) { + List> factoryList = Service.locator().list(IBankStatementLoaderFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IBankStatementLoaderFactory service = factory.getService(); + if (service != null) { + BankStatementLoaderInterface loader = service.newBankStatementLoaderInstance(className); + if (loader != null) { + myBankStatementLoader = loader; + s_bankStatementLoaderFactoryCache.put(className, factory); + break; + } + } } } } @@ -273,6 +433,8 @@ public class Core { return myBankStatementLoader; } + private static final CCache> s_bankStatementMatcherFactoryCache = new CCache<>(null, "IBankStatementMatcherFactory", 100, false); + /** * get BankStatementMatcher instance * @@ -286,15 +448,30 @@ public class Core { } BankStatementMatcherInterface myBankStatementMatcher = null; - - List factoryList = - Service.locator().list(IBankStatementMatcherFactory.class).getServices(); - if (factoryList != null) { - for(IBankStatementMatcherFactory factory : factoryList) { - BankStatementMatcherInterface matcher = factory.newBankStatementMatcherInstance(className); - if (matcher != null) { + IServiceReferenceHolder cache = s_bankStatementMatcherFactoryCache.get(className); + if (cache != null) { + IBankStatementMatcherFactory service = cache.getService(); + if (service != null) { + BankStatementMatcherInterface matcher = service.newBankStatementMatcherInstance(className); + if (matcher != null) myBankStatementMatcher = matcher; - break; + } + if (myBankStatementMatcher == null) + s_bankStatementMatcherFactoryCache.remove(className); + } + if (myBankStatementMatcher == null) { + List> factoryList = Service.locator().list(IBankStatementMatcherFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IBankStatementMatcherFactory service = factory.getService(); + if (service != null) { + BankStatementMatcherInterface matcher = service.newBankStatementMatcherInstance(className); + if (matcher != null) { + myBankStatementMatcher = matcher; + s_bankStatementMatcherFactoryCache.put(className, factory); + break; + } + } } } } @@ -307,6 +484,8 @@ public class Core { return myBankStatementMatcher; } + private static final CCache> s_shipmentProcessorFactoryCache = new CCache<>(null, "IShipmentProcessorFactory", 100, false); + /** * * @param sf @@ -322,20 +501,37 @@ public class Core { s_log.log(Level.SEVERE, "Shipment processor or class not defined for shipper " + sf); return null; } - - List factoryList = Service.locator().list(IShipmentProcessorFactory.class).getServices(); + + IServiceReferenceHolder cache = s_shipmentProcessorFactoryCache.get(className); + if (cache != null) { + IShipmentProcessorFactory service = cache.getService(); + if (service != null) { + IShipmentProcessor processor = service.newShipmentProcessorInstance(className); + if (processor != null) + return processor; + } + s_shipmentProcessorFactoryCache.remove(className); + } + List> factoryList = Service.locator().list(IShipmentProcessorFactory.class).getServiceReferences(); if (factoryList == null) return null; - for (IShipmentProcessorFactory factory : factoryList) + for (IServiceReferenceHolder factory : factoryList) { - IShipmentProcessor processor = factory.newShipmentProcessorInstance(className); - if (processor != null) - return processor; + IShipmentProcessorFactory service = factory.getService(); + if (service != null) { + IShipmentProcessor processor = service.newShipmentProcessorInstance(className); + if (processor != null) { + s_shipmentProcessorFactoryCache.put(className, factory); + return processor; + } + } } return null; } + private static final CCache> s_addressValidationFactoryCache = new CCache<>(null, "IAddressValidationFactory", 100, false); + /** * Get address validation instance * @param validation @@ -350,19 +546,36 @@ public class Core { return null; } - List factoryList = Service.locator().list(IAddressValidationFactory.class).getServices(); + IServiceReferenceHolder cache = s_addressValidationFactoryCache.get(className); + if (cache != null) { + IAddressValidationFactory service = cache.getService(); + if (service != null) { + IAddressValidation processor = service.newAddressValidationInstance(className); + if (processor != null) + return processor; + } + s_addressValidationFactoryCache.remove(className); + } + List> factoryList = Service.locator().list(IAddressValidationFactory.class).getServiceReferences(); if (factoryList == null) return null; - for (IAddressValidationFactory factory : factoryList) + for (IServiceReferenceHolder factory : factoryList) { - IAddressValidation processor = factory.newAddressValidationInstance(className); - if (processor != null) - return processor; + IAddressValidationFactory service = factory.getService(); + if (service != null) { + IAddressValidation processor = service.newAddressValidationInstance(className); + if (processor != null) { + s_addressValidationFactoryCache.put(className, factory); + return processor; + } + } } return null; } + private static final CCache> s_taxProviderFactoryCache = new CCache<>(null, "ITaxProviderFactory", 100, false); + /** * Get tax provider instance * @param provider @@ -388,43 +601,75 @@ public class Core { s_log.log(Level.SEVERE, "Tax provider class not defined: " + provider); return null; } - - List factoryList = Service.locator().list(ITaxProviderFactory.class).getServices(); + + IServiceReferenceHolder cache = s_taxProviderFactoryCache.get(className); + if (cache != null) { + ITaxProviderFactory service = cache.getService(); + if (service != null) { + calculator = service.newTaxProviderInstance(className); + if (calculator != null) + return calculator; + } + s_taxProviderFactoryCache.remove(className); + } + List> factoryList = Service.locator().list(ITaxProviderFactory.class).getServiceReferences(); if (factoryList == null) return null; - for (ITaxProviderFactory factory : factoryList) + for (IServiceReferenceHolder factory : factoryList) { - calculator = factory.newTaxProviderInstance(className); - if (calculator != null) - return calculator; + ITaxProviderFactory service = factory.getService(); + if (service != null) { + calculator = service.newTaxProviderInstance(className); + if (calculator != null) { + s_taxProviderFactoryCache.put(className, factory); + return calculator; + } + } } } return null; } + private static final CCache> s_replenishFactoryCache = new CCache<>(null, "IReplenishFactory", 100, false); + /** * get Custom Replenish instance * * @param className * @return instance of the ReplenishInterface or null */ - public static ReplenishInterface getReplenish(String className){ + public static ReplenishInterface getReplenish(String className) { if (className == null || className.length() == 0) { s_log.log(Level.SEVERE, "No ReplenishInterface class name"); return null; } ReplenishInterface myReplenishInstance = null; - - List factoryList = - Service.locator().list(IReplenishFactory.class).getServices(); - if (factoryList != null) { - for(IReplenishFactory factory : factoryList) { - ReplenishInterface loader = factory.newReplenishInstance(className); - if (loader != null) { + IServiceReferenceHolder cache = s_replenishFactoryCache.get(className); + if (cache != null) { + IReplenishFactory service = cache.getService(); + if (service != null) { + ReplenishInterface loader = service.newReplenishInstance(className); + if (loader != null) myReplenishInstance = loader; - break; + } + if (myReplenishInstance == null) + s_replenishFactoryCache.remove(className); + } + if (myReplenishInstance == null) { + List> factoryList = Service.locator().list(IReplenishFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IReplenishFactory service = factory.getService(); + if (service != null) { + ReplenishInterface loader = service.newReplenishInstance(className); + if (loader != null) { + myReplenishInstance = loader; + s_replenishFactoryCache.put(className, factory); + break; + } + } } } } @@ -437,7 +682,8 @@ public class Core { return myReplenishInstance; } - + private final static CCache> s_scriptEngineFactoryCache = new CCache<>(null, "ScriptEngineFactory", 100, false); + /** Get script engine * * @param engineName @@ -450,13 +696,23 @@ public class Core { if (engine != null) return engine; - List factoryList = - Service.locator().list(ScriptEngineFactory.class).getServices(); + IServiceReferenceHolder cache = s_scriptEngineFactoryCache.get(engineName); + if (cache != null) { + ScriptEngineFactory service = cache.getService(); + if (service != null) + return service.getScriptEngine(); + s_scriptEngineFactoryCache.remove(engineName); + } + List> factoryList = Service.locator().list(ScriptEngineFactory.class).getServiceReferences(); if (factoryList != null) { - for(ScriptEngineFactory factory : factoryList) { - for (String name : factory.getNames()) { - if (engineName.equals(name)) { - return factory.getScriptEngine(); + for(IServiceReferenceHolder factory : factoryList) { + ScriptEngineFactory service = factory.getService(); + if (service != null) { + for (String name : service.getNames()) { + if (engineName.equals(name)) { + s_scriptEngineFactoryCache.put(engineName, factory); + return service.getScriptEngine(); + } } } } @@ -465,6 +721,8 @@ public class Core { return null; } + private static final CCache> s_paymentExporterFactory = new CCache<>(null, "IPaymentExporterFactory", 100, false); + /** * get PaymentExporter instance * @@ -478,15 +736,30 @@ public class Core { } PaymentExport myPaymentExporter = null; - - List factoryList = - Service.locator().list(IPaymentExporterFactory.class).getServices(); - if (factoryList != null) { - for(IPaymentExporterFactory factory : factoryList) { - PaymentExport exporter = factory.newPaymentExporterInstance(className); - if (exporter != null) { + IServiceReferenceHolder cache = s_paymentExporterFactory.get(className); + if (cache != null) { + IPaymentExporterFactory service = cache.getService(); + if (service != null) { + PaymentExport exporter = service.newPaymentExporterInstance(className); + if (exporter != null) myPaymentExporter = exporter; - break; + } + if (myPaymentExporter == null) + s_paymentExporterFactory.remove(className); + } + if (myPaymentExporter == null) { + List> factoryList = Service.locator().list(IPaymentExporterFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IPaymentExporterFactory service = factory.getService(); + if (service != null) { + PaymentExport exporter = service.newPaymentExporterInstance(className); + if (exporter != null) { + myPaymentExporter = exporter; + s_paymentExporterFactory.put(className, factory); + break; + } + } } } } @@ -499,19 +772,30 @@ public class Core { return myPaymentExporter; } + private static IServiceReferenceHolder s_productPricingFactoryCache = null; + /** * get ProductPricing instance * * @return instance of the IProductPricing or null */ - public static IProductPricing getProductPricing() { - - List factoryList = - Service.locator().list(IProductPricingFactory.class).getServices(); - if (factoryList != null) { - for(IProductPricingFactory factory : factoryList) { - IProductPricing myProductPricing = factory.newProductPricingInstance(); + public static synchronized IProductPricing getProductPricing() { + if (s_productPricingFactoryCache != null) { + IProductPricingFactory service = s_productPricingFactoryCache.getService(); + if (service != null) { + IProductPricing myProductPricing = service.newProductPricingInstance(); + if (myProductPricing != null) + return myProductPricing; + } + s_productPricingFactoryCache = null; + } + IServiceReferenceHolder factoryReference = Service.locator().locate(IProductPricingFactory.class).getServiceReference(); + if (factoryReference != null) { + IProductPricingFactory service = factoryReference.getService(); + if (service != null) { + IProductPricing myProductPricing = service.newProductPricingInstance(); if (myProductPricing != null) { + s_productPricingFactoryCache = factoryReference; return myProductPricing; } } @@ -520,20 +804,35 @@ public class Core { return null; } + private final static CCache> s_depreciationMethodFactoryCache = new CCache<>(null, "IDepreciationMethodFactory", 100, false); + /** * lookup implement {@link IDepreciationMethod} * @param factoryLookupDTO - * @return + * @return {@link IDepreciationMethod} */ public static IDepreciationMethod getDepreciationMethod(DepreciationFactoryLookupDTO factoryLookupDTO) { - - List factoryList = - Service.locator().list(IDepreciationMethodFactory.class).getServices(); - if (factoryList != null) { - for(IDepreciationMethodFactory factory : factoryList) { - IDepreciationMethod depreciationMethod = factory.getDepreciationMethod(factoryLookupDTO); - if (depreciationMethod != null) { + String cacheKey = factoryLookupDTO.depreciationType; + IServiceReferenceHolder cache = s_depreciationMethodFactoryCache.get(cacheKey); + if (cache != null) { + IDepreciationMethodFactory service = cache.getService(); + if (service != null) { + IDepreciationMethod depreciationMethod = service.getDepreciationMethod(factoryLookupDTO); + if (depreciationMethod != null) return depreciationMethod; + } + s_depreciationMethodFactoryCache.remove(cacheKey); + } + List> factoryList = Service.locator().list(IDepreciationMethodFactory.class).getServiceReferences(); + if (factoryList != null) { + for(IServiceReferenceHolder factory : factoryList) { + IDepreciationMethodFactory service = factory.getService(); + if (service != null) { + IDepreciationMethod depreciationMethod = service.getDepreciationMethod(factoryLookupDTO); + if (depreciationMethod != null) { + s_depreciationMethodFactoryCache.put(cacheKey, factory); + return depreciationMethod; + } } } } @@ -541,4 +840,88 @@ public class Core { return null; } + private static IServiceReferenceHolder s_messageServiceReference = null; + + /** + * + * @return {@link IMessageService} + */ + public static synchronized IMessageService getMessageService() { + IMessageService messageService = null; + if (s_messageServiceReference != null) { + messageService = s_messageServiceReference.getService(); + if (messageService != null) + return messageService; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IMessageService.class).getServiceReference(); + if (serviceReference != null) { + messageService = serviceReference.getService(); + s_messageServiceReference = serviceReference; + } + return messageService; + } + + private static IServiceReferenceHolder s_clusterServiceReference = null; + + /** + * + * @return {@link IClusterService} + */ + public static synchronized IClusterService getClusterService() { + IClusterService clusterService = null; + if (s_clusterServiceReference != null) { + clusterService = s_clusterServiceReference.getService(); + if (clusterService != null) + return clusterService; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IClusterService.class).getServiceReference(); + if (serviceReference != null) { + clusterService = serviceReference.getService(); + s_clusterServiceReference = serviceReference; + } + return clusterService; + } + + private static IServiceReferenceHolder s_cacheServiceReference = null; + + /** + * + * @return {@link ICacheService} + */ + public static synchronized ICacheService getCacheService() { + ICacheService cacheService = null; + if (s_cacheServiceReference != null) { + cacheService = s_cacheServiceReference.getService(); + if (cacheService != null) + return cacheService; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(ICacheService.class).getServiceReference(); + if (serviceReference != null) { + cacheService = serviceReference.getService(); + s_cacheServiceReference = serviceReference; + } + return cacheService; + } + + private static IServiceReferenceHolder s_dictionaryServiceReference = null; + + /** + * + * @return {@link IDictionaryService} + */ + public static synchronized IDictionaryService getDictionaryService() { + IDictionaryService ids = null; + if (s_dictionaryServiceReference != null) { + ids = s_dictionaryServiceReference.getService(); + if (ids != null) + return ids; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IDictionaryService.class).getServiceReference(); + if (serviceReference != null) { + ids = serviceReference.getService(); + s_dictionaryServiceReference = serviceReference; + } + return ids; + } + } diff --git a/org.adempiere.base/src/org/adempiere/base/DefaultModelFactory.java b/org.adempiere.base/src/org/adempiere/base/DefaultModelFactory.java index 3e565a332f..1ef2ecc94b 100644 --- a/org.adempiere.base/src/org/adempiere/base/DefaultModelFactory.java +++ b/org.adempiere.base/src/org/adempiere/base/DefaultModelFactory.java @@ -37,7 +37,7 @@ import org.compiere.util.Util; */ public class DefaultModelFactory implements IModelFactory { - private static CCache> s_classCache = new CCache>(null, "PO_Class", 20, false); + private static CCache> s_classCache = new CCache>(null, "PO_Class", 100, 120, false, 2000); private final static CLogger s_log = CLogger.getCLogger(DefaultModelFactory.class); /** Packages for Model Classes */ diff --git a/org.adempiere.base/src/org/adempiere/base/IServiceHolder.java b/org.adempiere.base/src/org/adempiere/base/IServiceHolder.java index a8e07dc8fa..3790199215 100644 --- a/org.adempiere.base/src/org/adempiere/base/IServiceHolder.java +++ b/org.adempiere.base/src/org/adempiere/base/IServiceHolder.java @@ -22,9 +22,14 @@ package org.adempiere.base; public interface IServiceHolder { /** - * + * Get service with highest service.ranking value * @return service instance. null if not available or no matching service found */ public T getService(); + /** + * Get service reference for service with highest service.ranking value + * @return {@link IServiceReferenceHolder} + */ + public IServiceReferenceHolder getServiceReference(); } diff --git a/org.adempiere.base/src/org/adempiere/base/IServiceReferenceHolder.java b/org.adempiere.base/src/org/adempiere/base/IServiceReferenceHolder.java new file mode 100644 index 0000000000..46b8097a58 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/IServiceReferenceHolder.java @@ -0,0 +1,49 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.adempiere.base; + +import org.osgi.framework.ServiceReference; + +/** + * Dynamic service reference holder for a service object. + * For cache usage, you should cache this instead of service object + * @author hengsin + * + * @param + */ +public interface IServiceReferenceHolder { + + /** + * Get service object from cache service reference + * @return Service Object or null if the osgi service is no longer available + */ + public T getService(); + + /** + * Get the cache service reference + * @return ServiceReference + */ + public ServiceReference getServiceReference(); +} diff --git a/org.adempiere.base/src/org/adempiere/base/IServicesHolder.java b/org.adempiere.base/src/org/adempiere/base/IServicesHolder.java index e16b9ed23d..5f8bd566d5 100644 --- a/org.adempiere.base/src/org/adempiere/base/IServicesHolder.java +++ b/org.adempiere.base/src/org/adempiere/base/IServicesHolder.java @@ -24,9 +24,15 @@ import java.util.List; public interface IServicesHolder { /** - * + * Get list of service, sorted by service.ranking (from highest to lowest ranking) * @return list of service instance. null if not available or no matching service found */ public List getServices(); + /** + * Get list of service reference, sorted by service.ranking (from highest to lowest ranking). + * If you want to cache service, cache IServiceReferenceHolder instead of the actual service object + * @return list of {@link IServiceReferenceHolder} + */ + public List> getServiceReferences(); } diff --git a/org.adempiere.base/src/org/adempiere/base/LookupFactoryHelper.java b/org.adempiere.base/src/org/adempiere/base/LookupFactoryHelper.java new file mode 100644 index 0000000000..b82d5dfb5a --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/LookupFactoryHelper.java @@ -0,0 +1,129 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.adempiere.base; + +import java.util.ArrayList; +import java.util.List; + +import org.compiere.model.GridFieldVO; +import org.compiere.model.Lookup; +import org.compiere.util.CCache; +import org.osgi.framework.Constants; + +/** + * Static helper methods for working with {@link ILookupFactory} + * @author hengsin + * + */ +public final class LookupFactoryHelper { + + private LookupFactoryHelper() { + } + + private static final CCache> s_lookupFactoryCache = new CCache>( + null, "ILookupFactory", 10, false); + + /** + * Get lookup from osgi factory + * + * @param gridFieldVO + * @return {@link Lookup} + */ + public static Lookup getLookup(GridFieldVO gridFieldVO) { + List visitedIds = new ArrayList(); + if (!s_lookupFactoryCache.isEmpty()) { + Long[] keys = s_lookupFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_lookupFactoryCache.get(key); + if (serviceReference != null) { + ILookupFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + Lookup lookup = service.getLookup(gridFieldVO); + if (lookup != null) + return lookup; + } else { + s_lookupFactoryCache.remove(key); + } + } + } + } + List> serviceReferences = Service.locator().list(ILookupFactory.class) + .getServiceReferences(); + for (IServiceReferenceHolder serviceReference : serviceReferences) { + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + ILookupFactory service = serviceReference.getService(); + if (service != null) { + s_lookupFactoryCache.put(serviceId, serviceReference); + Lookup lookup = service.getLookup(gridFieldVO); + if (lookup != null) + return lookup; + } + } + return null; + } + + /** + * Check lookup from osgi factory + * + * @param gridFieldVO + * @return true if gridFieldVO is a lookup field + */ + public static boolean isLookup(GridFieldVO gridFieldVO) { + List visitedIds = new ArrayList(); + if (!s_lookupFactoryCache.isEmpty()) { + Long[] keys = s_lookupFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_lookupFactoryCache.get(key); + if (serviceReference != null) { + ILookupFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + if (service.isLookup(gridFieldVO)) + return true; + } else { + s_lookupFactoryCache.remove(key); + } + } + } + } + List> serviceReferences = Service.locator().list(ILookupFactory.class) + .getServiceReferences(); + for (IServiceReferenceHolder serviceReference : serviceReferences) { + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + ILookupFactory service = serviceReference.getService(); + if (service != null) { + s_lookupFactoryCache.put(serviceId, serviceReference); + if (service.isLookup(gridFieldVO)) + return true; + } + } + return false; + } +} diff --git a/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceHolder.java b/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceHolder.java index 96a29dd57b..00cd362263 100644 --- a/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceHolder.java +++ b/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceHolder.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import org.adempiere.base.IServiceHolder; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.IServicesHolder; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; @@ -54,10 +55,36 @@ public class DynamicServiceHolder implements IServiceHolder, IServicesHold if (objects != null && objects.length > 0) { references = Arrays.asList(objects); } - Collections.sort(references, Collections.reverseOrder()); + if (references.size() > 1) + Collections.sort(references, ServiceRankingComparator.INSTANCE); for(ServiceReference reference : references) { services.add(serviceTracker.getService(reference)); } return services; } + + + @Override + public IServiceReferenceHolder getServiceReference() { + ServiceReference v = serviceTracker.getServiceReference(); + if (v != null) + return new DynamicServiceReference(serviceTracker, v); + return null; + } + + @Override + public List> getServiceReferences() { + List> services = new ArrayList<>(); + ServiceReference[] objects = serviceTracker.getServiceReferences(); + List> references = new ArrayList>(); + if (objects != null && objects.length > 0) { + references = Arrays.asList(objects); + } + if (references.size() > 1) + Collections.sort(references, ServiceRankingComparator.INSTANCE); + for(ServiceReference reference : references) { + services.add(new DynamicServiceReference(serviceTracker, reference)); + } + return services; + } } diff --git a/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceReference.java b/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceReference.java new file mode 100644 index 0000000000..e73b58b5b2 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/ds/DynamicServiceReference.java @@ -0,0 +1,61 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.ds; + +import org.adempiere.base.IServiceReferenceHolder; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +/** + * IServiceReferenceHolder implementation using ServiceTracker + * @author hengsin + * + * @param + */ +public class DynamicServiceReference implements IServiceReferenceHolder { + + private ServiceTracker serviceTracker; + private ServiceReference serviceReference; + + /** + * + * @param tracker + * @param serviceReference + */ + public DynamicServiceReference(ServiceTracker tracker, ServiceReference serviceReference) { + this.serviceTracker = tracker; + this.serviceReference = serviceReference; + } + + @Override + public T getService() { + return serviceTracker.getService(serviceReference); + } + + @Override + public ServiceReference getServiceReference() { + return serviceReference; + } +} diff --git a/org.adempiere.base/src/org/adempiere/base/ds/ServiceRankingComparator.java b/org.adempiere.base/src/org/adempiere/base/ds/ServiceRankingComparator.java new file mode 100644 index 0000000000..64990d8db8 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/ds/ServiceRankingComparator.java @@ -0,0 +1,102 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.ds; + +import java.io.Serializable; +import java.util.Comparator; + +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; + +/** + * Service Reference Comparator. + * This comparator follows OSGi Ranking policy. + * @author hengsin + */ +public final class ServiceRankingComparator implements Comparator>, Serializable { + /** + * + */ + private static final long serialVersionUID = 3444598255961708618L; + + /** + * share service ranking comparator instance + */ + public static final ServiceRankingComparator INSTANCE = new ServiceRankingComparator(); + + private ServiceRankingComparator() {} + + /** + * Compares two service reference. + * @param serviceReference1 service reference 1 + * @param serviceReference2 service reference 2 + * @return -1 if service reference 1 service.ranking value + * is higher than service reference 2, 1 otherwise. + * (i.e for sorting in descending order of service.ranking value) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(ServiceReference serviceReference1, ServiceReference serviceReference2) { + if (serviceReference1.equals(serviceReference2)) { return 0; } + + if (serviceReference2 != null) { + Object serviceRankingP1 = serviceReference1.getProperty(Constants.SERVICE_RANKING); + Object serviceRankingP2 = serviceReference2.getProperty(Constants.SERVICE_RANKING); + + int serviceRanking1 = 0; + int serviceRanking2 = 0; + if (serviceRankingP1 instanceof Integer) { + serviceRanking1 = (Integer) serviceRankingP1; + } + if (serviceRankingP2 instanceof Integer) { + serviceRanking2 = (Integer) serviceRankingP2; + } + + if (serviceRanking1 == serviceRanking2) { + // Check service.id + Object serviceIdP1 = serviceReference1.getProperty(Constants.SERVICE_ID); + Object serviceIdP2 = serviceReference2.getProperty(Constants.SERVICE_ID); + + long serviceId1 = (Long) serviceIdP1; + long serviceId2 = (Long) serviceIdP2; + + if (serviceId1 == serviceId2) { + return 0; + } else if (serviceId1 > serviceId2) { + return -1; + } else { + return 1; + } + + } else if (serviceRanking1 > serviceRanking2) { + return -1; + } else { + return 1; + } + + } else { + return 0; + } + } +} \ No newline at end of file diff --git a/org.adempiere.base/src/org/adempiere/process/PrintShippingLabel.java b/org.adempiere.base/src/org/adempiere/process/PrintShippingLabel.java index 235aee43c4..f83ea32ad2 100644 --- a/org.adempiere.base/src/org/adempiere/process/PrintShippingLabel.java +++ b/org.adempiere.base/src/org/adempiere/process/PrintShippingLabel.java @@ -1,5 +1,6 @@ package org.adempiere.process; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.compiere.model.MAttachment; import org.compiere.model.MPackage; @@ -27,7 +28,7 @@ public class PrintShippingLabel extends SvrProcess if (labelId <= 0) return "Label format not defined."; - IPrintShippingLabel service = Service.locator().locate(IPrintShippingLabel.class).getService(); + IPrintShippingLabel service = getService(); if (service != null) { MShipperLabels label = new MShipperLabels(getCtx(), labelId, get_TrxName()); @@ -39,4 +40,24 @@ public class PrintShippingLabel extends SvrProcess else return "Not found in service/extension registry and classpath"; } + + private static IServiceReferenceHolder s_serviceReference = null; + + private synchronized static IPrintShippingLabel getService() { + if (s_serviceReference != null) { + IPrintShippingLabel service = s_serviceReference.getService(); + if (service != null) + return service; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IPrintShippingLabel.class).getServiceReference(); + if (serviceReference != null) { + IPrintShippingLabel service = serviceReference.getService(); + if (service != null) { + s_serviceReference = serviceReference; + return service; + } + } + return null; + + } } \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/acct/DocManager.java b/org.adempiere.base/src/org/compiere/acct/DocManager.java index 28b8c161cf..50fbcec79c 100644 --- a/org.adempiere.base/src/org/compiere/acct/DocManager.java +++ b/org.adempiere.base/src/org/compiere/acct/DocManager.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; import org.adempiere.base.IDocFactory; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.base.ServiceQuery; import org.adempiere.exceptions.AdempiereException; @@ -31,6 +32,7 @@ import org.adempiere.exceptions.DBException; import org.compiere.model.MAcctSchema; import org.compiere.model.MTable; import org.compiere.util.AdempiereUserError; +import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -108,6 +110,8 @@ public class DocManager { } } + private static final CCache> s_DocFactoryCache = new CCache<>(null, "IDocFactory", 100, false); + /** * Create Posting document * @param as accounting schema @@ -133,29 +137,57 @@ public class DocManager { return null; } - ServiceQuery query = new ServiceQuery(); - query.put("gaap", as.getGAAP()); - List factoryList = Service.locator().list(IDocFactory.class, query).getServices(); - if (factoryList != null) + String cacheKey = as.getC_AcctSchema_ID() + "|" + AD_Table_ID; + IServiceReferenceHolder cache = s_DocFactoryCache.get(cacheKey); + if (cache != null) { - for(IDocFactory factory : factoryList) + IDocFactory service = cache.getService(); + if (service != null) { - Doc doc = factory.getDocument(as, AD_Table_ID, Record_ID, trxName); + Doc doc = service.getDocument(as, AD_Table_ID, Record_ID, trxName); if (doc != null) return doc; } + s_DocFactoryCache.remove(cacheKey); + } + + ServiceQuery query = new ServiceQuery(); + query.put("gaap", as.getGAAP()); + List> factoryList = Service.locator().list(IDocFactory.class, query).getServiceReferences(); + if (factoryList != null) + { + for(IServiceReferenceHolder factory : factoryList) + { + IDocFactory service = factory.getService(); + if (service != null) + { + Doc doc = service.getDocument(as, AD_Table_ID, Record_ID, trxName); + if (doc != null) + { + s_DocFactoryCache.put(cacheKey, factory); + return doc; + } + } + } } query.clear(); query.put("gaap", "*"); - factoryList = Service.locator().list(IDocFactory.class, query).getServices(); + factoryList = Service.locator().list(IDocFactory.class, query).getServiceReferences(); if (factoryList != null) { - for(IDocFactory factory : factoryList) + for(IServiceReferenceHolder factory : factoryList) { - Doc doc = factory.getDocument(as, AD_Table_ID, Record_ID, trxName); - if (doc != null) - return doc; + IDocFactory service = factory.getService(); + if (service != null) + { + Doc doc = service.getDocument(as, AD_Table_ID, Record_ID, trxName); + if (doc != null) + { + s_DocFactoryCache.put(cacheKey, factory); + return doc; + } + } } } @@ -173,29 +205,57 @@ public class DocManager { */ public static Doc getDocument(MAcctSchema as, int AD_Table_ID, ResultSet rs, String trxName) { - ServiceQuery query = new ServiceQuery(); - query.put("gaap", as.getGAAP()); - List factoryList = Service.locator().list(IDocFactory.class,query).getServices(); - if (factoryList != null) + String cacheKey = as.getC_AcctSchema_ID() + "|" + AD_Table_ID; + IServiceReferenceHolder cache = s_DocFactoryCache.get(cacheKey); + if (cache != null) { - for(IDocFactory factory : factoryList) + IDocFactory service = cache.getService(); + if (service != null) { - Doc doc = factory.getDocument(as, AD_Table_ID, rs, trxName); + Doc doc = service.getDocument(as, AD_Table_ID, rs, trxName); if (doc != null) return doc; } + s_DocFactoryCache.remove(cacheKey); + } + + ServiceQuery query = new ServiceQuery(); + query.put("gaap", as.getGAAP()); + List> factoryList = Service.locator().list(IDocFactory.class,query).getServiceReferences(); + if (factoryList != null) + { + for(IServiceReferenceHolder factory : factoryList) + { + IDocFactory service = factory.getService(); + if (service != null) + { + Doc doc = service.getDocument(as, AD_Table_ID, rs, trxName); + if (doc != null) + { + s_DocFactoryCache.put(cacheKey, factory); + return doc; + } + } + } } query.clear(); query.put("gaap", "*"); - factoryList = Service.locator().list(IDocFactory.class,query).getServices(); + factoryList = Service.locator().list(IDocFactory.class,query).getServiceReferences(); if (factoryList != null) { - for(IDocFactory factory : factoryList) + for(IServiceReferenceHolder factory : factoryList) { - Doc doc = factory.getDocument(as, AD_Table_ID, rs, trxName); - if (doc != null) - return doc; + IDocFactory service = factory.getService(); + if (service != null) + { + Doc doc = service.getDocument(as, AD_Table_ID, rs, trxName); + if (doc != null) + { + s_DocFactoryCache.put(cacheKey, factory); + return doc; + } + } } } diff --git a/org.adempiere.base/src/org/compiere/db/Database.java b/org.adempiere.base/src/org/compiere/db/Database.java index aa909468fc..7195612445 100644 --- a/org.adempiere.base/src/org/compiere/db/Database.java +++ b/org.adempiere.base/src/org/compiere/db/Database.java @@ -19,8 +19,10 @@ package org.compiere.db; import java.util.ArrayList; import java.util.List; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.base.ServiceQuery; +import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.Util; @@ -51,15 +53,29 @@ public class Database /** Default Port */ public static final int DB_POSTGRESQL_DEFAULT_PORT = 5432; + private static final CCache> s_databaseReferenceCache = new CCache<>(null, "IDatabase", 2, false); + /** * Get Database by database Id. * @return database */ public static AdempiereDatabase getDatabase (String type) { + AdempiereDatabase db = null; + IServiceReferenceHolder cache = s_databaseReferenceCache.get(type); + if (cache != null) { + db = cache.getService(); + if (db != null) + return db; + s_databaseReferenceCache.remove(type); + } ServiceQuery query = new ServiceQuery(); query.put("id", type); - AdempiereDatabase db = Service.locator().locate(AdempiereDatabase.class, query).getService(); + IServiceReferenceHolder serviceReference = Service.locator().locate(AdempiereDatabase.class, query).getServiceReference(); + if (serviceReference != null) { + db = serviceReference.getService(); + s_databaseReferenceCache.put(type, serviceReference); + } return db; } diff --git a/org.adempiere.base/src/org/compiere/model/GridField.java b/org.adempiere.base/src/org/compiere/model/GridField.java index 938e6f26b0..0746b94a10 100644 --- a/org.adempiere.base/src/org/compiere/model/GridField.java +++ b/org.adempiere.base/src/org/compiere/model/GridField.java @@ -35,8 +35,7 @@ import java.util.Properties; import java.util.StringTokenizer; import java.util.logging.Level; -import org.adempiere.base.ILookupFactory; -import org.adempiere.base.Service; +import org.adempiere.base.LookupFactoryHelper; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.CLogMgt; import org.compiere.util.CLogger; @@ -195,15 +194,8 @@ public class GridField } // m_lookup private void loadLookupFromFactory() { - //http://jira.idempiere.com/browse/IDEMPIERE-694 - //see DefaultLookupFactory.java for the other default Lookups - List factoryList = Service.locator().list(ILookupFactory.class).getServices(); - for(ILookupFactory factory : factoryList) - { - m_lookup = factory.getLookup(m_vo); - if (m_lookup != null) - break; - } + //http://jira.idempiere.com/browse/IDEMPIERE-694 + m_lookup = LookupFactoryHelper.getLookup(m_vo); } /*** @@ -263,14 +255,8 @@ public class GridField // retValue = false; else { //http://jira.idempiere.com/browse/IDEMPIERE-694 - //see DefaultLookupFactory.java for the other default Lookups - List factoryList = Service.locator().list(ILookupFactory.class).getServices(); - for(ILookupFactory factory : factoryList) - { - retValue = factory.isLookup(m_vo); - if (retValue == true) - break; - } + if (LookupFactoryHelper.isLookup(m_vo)) + retValue = true; } return retValue; } // isLookup diff --git a/org.adempiere.base/src/org/compiere/model/GridWindowVO.java b/org.adempiere.base/src/org/compiere/model/GridWindowVO.java index feee29c3eb..473c7c0cee 100644 --- a/org.adempiere.base/src/org/compiere/model/GridWindowVO.java +++ b/org.adempiere.base/src/org/compiere/model/GridWindowVO.java @@ -41,6 +41,17 @@ public class GridWindowVO implements Serializable */ private static final long serialVersionUID = 6884332743173214735L; + /** + * Create Window Value Object + * @param WindowNo window no for ctx + * @param AD_Window_ID window id + * @return MWindowVO + */ + public static GridWindowVO create (int WindowNo, int AD_Window_ID) + { + return create(Env.getCtx(), WindowNo, AD_Window_ID); + } + /** * Create Window Value Object * @param ctx context diff --git a/org.adempiere.base/src/org/compiere/model/MPInstance.java b/org.adempiere.base/src/org/compiere/model/MPInstance.java index e923cab763..85c7bfb4a2 100644 --- a/org.adempiere.base/src/org/compiere/model/MPInstance.java +++ b/org.adempiere.base/src/org/compiere/model/MPInstance.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.Properties; import java.util.logging.Level; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.base.event.EventManager; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -402,7 +402,7 @@ public class MPInstance extends X_AD_PInstance } public static void publishChangedEvent(int AD_User_ID) { - IMessageService service = Service.locator().locate(IMessageService.class).getService(); + IMessageService service = Core.getMessageService(); if (service != null) { ITopic topic = service.getTopic(ON_RUNNING_JOB_CHANGED_TOPIC); topic.publish(AD_User_ID); diff --git a/org.adempiere.base/src/org/compiere/model/MRecentItem.java b/org.adempiere.base/src/org/compiere/model/MRecentItem.java index 821c831fed..b821915486 100644 --- a/org.adempiere.base/src/org/compiere/model/MRecentItem.java +++ b/org.adempiere.base/src/org/compiere/model/MRecentItem.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Properties; import java.util.logging.Level; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.base.event.EventManager; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.CLogger; @@ -244,7 +244,7 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport } public static void publishChangedEvent(int AD_User_ID) { - IMessageService service = Service.locator().locate(IMessageService.class).getService(); + IMessageService service = Core.getMessageService(); if (service != null) { ITopic topic = service.getTopic(ON_RECENT_ITEM_CHANGED_TOPIC); topic.publish(AD_User_ID); diff --git a/org.adempiere.base/src/org/compiere/model/MStorageProvider.java b/org.adempiere.base/src/org/compiere/model/MStorageProvider.java index af50b9b0f3..619ecd5350 100644 --- a/org.adempiere.base/src/org/compiere/model/MStorageProvider.java +++ b/org.adempiere.base/src/org/compiere/model/MStorageProvider.java @@ -19,9 +19,11 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.base.ServiceQuery; import org.adempiere.exceptions.AdempiereException; +import org.compiere.util.CCache; public class MStorageProvider extends X_AD_StorageProvider { /** @@ -37,42 +39,132 @@ public class MStorageProvider extends X_AD_StorageProvider { super(ctx, rs, trxName); } + /** + * + * @return {@link IAttachmentStore} + */ public IAttachmentStore getAttachmentStore() { ServiceQuery query=new ServiceQuery(); String method = this.getMethod(); if (method == null) method = "DB"; query.put("method", method); - IAttachmentStore store = Service.locator().locate(IAttachmentStore.class, query).getService(); + IAttachmentStore store = getAttachmentStoreService(query); if (store == null) { throw new AdempiereException("No attachment storage provider found"); } return store; } + + private static CCache> s_attachmentStoreReference = new CCache<>(null, "IAttachmentStore", 3, false); + /** + * + * @param query + * @return {@link IAttachmentStore} + */ + public static IAttachmentStore getAttachmentStoreService(ServiceQuery query) { + IAttachmentStore store = null; + IServiceReferenceHolder cache = s_attachmentStoreReference.get(query); + if (cache != null) { + store = cache.getService(); + if (store != null) + return store; + else + s_attachmentStoreReference.remove(query); + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IAttachmentStore.class, query).getServiceReference(); + if (serviceReference != null) { + store = serviceReference.getService(); + if (store != null) + s_attachmentStoreReference.put(query, serviceReference); + } + return store; + } + + /** + * + * @return {@link IArchiveStore} + */ public IArchiveStore getArchiveStore() { ServiceQuery query=new ServiceQuery(); String method = this.getMethod(); if (method == null) method = "DB"; query.put("method", method); - IArchiveStore store = Service.locator().locate(IArchiveStore.class, query).getService(); + IArchiveStore store = getArchiveStoreService(query); if (store == null) { throw new AdempiereException("No archive storage provider found"); } return store; } + + private static CCache> s_archiveStoreReference = new CCache<>(null, "IArchiveStore", 3, false); + + /** + * + * @param query + * @return {@link IArchiveStore} + */ + public static IArchiveStore getArchiveStoreService(ServiceQuery query) { + IArchiveStore store = null; + IServiceReferenceHolder cache = s_archiveStoreReference.get(query); + if (cache != null) { + store = cache.getService(); + if (store != null) + return store; + else + s_archiveStoreReference.remove(query); + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IArchiveStore.class, query).getServiceReference(); + if (serviceReference != null) { + store = serviceReference.getService(); + if (store != null) + s_archiveStoreReference.put(query, serviceReference); + } + return store; + } + + /** + * + * @return {@link IImageStore} + */ public IImageStore getImageStore() { ServiceQuery query=new ServiceQuery(); String method = this.getMethod(); if (method == null) method = "DB"; query.put("method", method); - IImageStore store = Service.locator().locate(IImageStore.class, query).getService(); + IImageStore store = getImageStoreService(query); if (store == null) { throw new AdempiereException("No image storage provider found"); } return store; } + + private static CCache> s_imageStoreReference = new CCache<>(null, "IImageStore", 3, false); + + /** + * + * @param query + * @return {@link IImageStore} + */ + public static IImageStore getImageStoreService(ServiceQuery query) { + IImageStore store = null; + IServiceReferenceHolder cache = s_imageStoreReference.get(query); + if (cache != null) { + store = cache.getService(); + if (store != null) + return store; + else + s_imageStoreReference.remove(query); + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IImageStore.class, query).getServiceReference(); + if (serviceReference != null) { + store = serviceReference.getService(); + s_imageStoreReference.put(query, serviceReference); + } + return store; + } } diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index 6601275799..be1d316aa1 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -31,10 +31,12 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.base.IModelFactory; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.model.GenericPO; import org.compiere.db.AdempiereDatabase; import org.compiere.db.Database; +import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -207,7 +209,7 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport /** Static Logger */ private static CLogger s_log = CLogger.getCLogger (MTable.class); - + private static final CCache> s_modelFactoryCache = new CCache<>(null, "IModelFactory", 100, 120, false, 2000); /** * Get Persistence Class for Table @@ -216,13 +218,32 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport */ public static Class getClass (String tableName) { - List factoryList = Service.locator().list(IModelFactory.class).getServices(); + IServiceReferenceHolder cache = s_modelFactoryCache.get(tableName); + if (cache != null) + { + IModelFactory service = cache.getService(); + if (service != null) + { + Class clazz = service.getClass(tableName); + if (clazz != null) + return clazz; + } + s_modelFactoryCache.remove(tableName); + } + + List> factoryList = Service.locator().list(IModelFactory.class).getServiceReferences(); if (factoryList == null) return null; - for(IModelFactory factory : factoryList) { - Class clazz = factory.getClass(tableName); - if (clazz != null) - return clazz; + for(IServiceReferenceHolder factory : factoryList) { + IModelFactory service = factory.getService(); + if (service != null) { + Class clazz = service.getClass(tableName); + if (clazz != null) + { + s_modelFactoryCache.put(tableName, factory); + return clazz; + } + } } return null; } // getClass @@ -481,18 +502,43 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport } PO po = null; - List factoryList = Service.locator().list(IModelFactory.class).getServices(); - if (factoryList != null) + IServiceReferenceHolder cache = s_modelFactoryCache.get(tableName); + if (cache != null) { - for(IModelFactory factory : factoryList) + IModelFactory service = cache.getService(); + if (service != null) { - po = factory.getPO(tableName, Record_ID, trxName); + po = service.getPO(tableName, Record_ID, trxName); if (po != null) { if (po.get_ID() != Record_ID && Record_ID > 0) po = null; else - break; + return po; + } + } + s_modelFactoryCache.remove(tableName); + } + + List> factoryList = Service.locator().list(IModelFactory.class).getServiceReferences(); + if (factoryList != null) + { + for(IServiceReferenceHolder factory : factoryList) + { + IModelFactory service = factory.getService(); + if (service != null) + { + po = service.getPO(tableName, Record_ID, trxName); + if (po != null) + { + if (po.get_ID() != Record_ID && Record_ID > 0) + po = null; + else + { + s_modelFactoryCache.put(tableName, factory); + break; + } + } } } } @@ -518,13 +564,32 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport String tableName = getTableName(); PO po = null; - List factoryList = Service.locator().list(IModelFactory.class).getServices(); + IServiceReferenceHolder cache = s_modelFactoryCache.get(tableName); + if (cache != null) + { + IModelFactory service = cache.getService(); + if (service != null) + { + po = service.getPO(tableName, rs, trxName); + if (po != null) + return po; + } + s_modelFactoryCache.remove(tableName); + } + List> factoryList = Service.locator().list(IModelFactory.class).getServiceReferences(); if (factoryList != null) { - for(IModelFactory factory : factoryList) { - po = factory.getPO(tableName, rs, trxName); - if (po != null) - break; + for(IServiceReferenceHolder factory : factoryList) { + IModelFactory service = factory.getService(); + if (service != null) + { + po = service.getPO(tableName, rs, trxName); + if (po != null) + { + s_modelFactoryCache.put(tableName, factory); + break; + } + } } } diff --git a/org.adempiere.base/src/org/compiere/util/CCache.java b/org.adempiere.base/src/org/compiere/util/CCache.java index bbfc2fe7d3..230b2912b7 100644 --- a/org.adempiere.base/src/org/compiere/util/CCache.java +++ b/org.adempiere.base/src/org/compiere/util/CCache.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.idempiere.distributed.ICacheService; /** @@ -112,7 +112,7 @@ public class CCache implements CacheInterface, Map, Serializable cache = CacheMgt.get().register(this, distributed); m_distributed = distributed; if (distributed) { - ICacheService provider = Service.locator().locate(ICacheService.class).getService(); + ICacheService provider = Core.getCacheService(); if (provider != null) { nullList = provider.getSet(name); } diff --git a/org.adempiere.base/src/org/compiere/util/CLogMgt.java b/org.adempiere.base/src/org/compiere/util/CLogMgt.java index b78f4a16a7..51eaff6100 100644 --- a/org.adempiere.base/src/org/compiere/util/CLogMgt.java +++ b/org.adempiere.base/src/org/compiere/util/CLogMgt.java @@ -35,7 +35,7 @@ import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.compiere.Adempiere; import org.compiere.db.AdempiereDatabase; import org.compiere.db.CConnection; @@ -561,7 +561,7 @@ public class CLogMgt // //cluster info if (Env.getAD_Client_ID(Env.getCtx()) == 0) { - IClusterService service = Service.locator().locate(IClusterService.class).getService(); + IClusterService service = Core.getClusterService(); if (service != null) { IClusterMember local = service.getLocalMember(); Collection members = service.getMembers(); diff --git a/org.adempiere.base/src/org/compiere/util/CacheInfo.java b/org.adempiere.base/src/org/compiere/util/CacheInfo.java index 4bbfde6a0c..5c2886c6f3 100644 --- a/org.adempiere.base/src/org/compiere/util/CacheInfo.java +++ b/org.adempiere.base/src/org/compiere/util/CacheInfo.java @@ -37,8 +37,7 @@ import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.adempiere.base.IServiceHolder; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.idempiere.distributed.IClusterMember; import org.idempiere.distributed.IClusterService; @@ -157,8 +156,7 @@ public class CacheInfo implements Serializable { * @return cache infos */ public static List getCacheInfos(boolean sortByName) { - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder != null ? holder.getService() : null; + IClusterService service = Core.getClusterService(); if (service != null && service.getMembers().size() > 1) { List instances = new ArrayList<>(); GetCacheInfoCallable callable = new GetCacheInfoCallable(); diff --git a/org.adempiere.base/src/org/compiere/util/CacheMgt.java b/org.adempiere.base/src/org/compiere/util/CacheMgt.java index 1c13de55c2..3edab8c529 100644 --- a/org.adempiere.base/src/org/compiere/util/CacheMgt.java +++ b/org.adempiere.base/src/org/compiere/util/CacheMgt.java @@ -26,8 +26,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.logging.Level; -import org.adempiere.base.IServiceHolder; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.idempiere.distributed.ICacheService; import org.idempiere.distributed.IClusterMember; import org.idempiere.distributed.IClusterService; @@ -107,10 +106,10 @@ public class CacheMgt Map map = null; if (distributed) { - ICacheService provider = Service.locator().locate(ICacheService.class).getService(); + ICacheService provider = Core.getCacheService(); if (provider != null) { - IClusterService clusterService = Service.locator().locate(IClusterService.class).getService(); + IClusterService clusterService = Core.getClusterService(); if (clusterService != null && !clusterService.isStandAlone()) map = provider.getMap(name); } @@ -162,8 +161,7 @@ public class CacheMgt * @return number of deleted cache entries */ private int clusterReset(String tableName, int recordId) { - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder.getService(); + IClusterService service = Core.getClusterService(); if (service != null) { ResetCacheCallable callable = new ResetCacheCallable(tableName, recordId); Map> futureMap = service.execute(callable, service.getMembers()); @@ -203,8 +201,7 @@ public class CacheMgt * @return number of deleted cache entries */ private void clusterNewRecord(String tableName, int recordId) { - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder.getService(); + IClusterService service = Core.getClusterService(); if (service != null) { CacheNewRecordCallable callable = new CacheNewRecordCallable(tableName, recordId); if (service.execute(callable, service.getMembers()) == null) { diff --git a/org.adempiere.base/src/org/compiere/util/DisplayType.java b/org.adempiere.base/src/org/compiere/util/DisplayType.java index 35973f0456..a4c07f1c3a 100644 --- a/org.adempiere.base/src/org/compiere/util/DisplayType.java +++ b/org.adempiere.base/src/org/compiere/util/DisplayType.java @@ -64,9 +64,11 @@ import java.text.SimpleDateFormat; import java.util.Currency; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.logging.Level; import org.adempiere.base.IDisplayTypeFactory; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.compiere.db.AdempiereDatabase; import org.compiere.db.Database; @@ -214,10 +216,18 @@ public final class DisplayType || displayType == Image || displayType == Chart) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isID(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isID(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isID(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; @@ -235,10 +245,18 @@ public final class DisplayType || displayType == Integer || displayType == Quantity) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isNumeric(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isNumeric(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isNumeric(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; @@ -260,13 +278,22 @@ public final class DisplayType || displayType == Quantity) return 4; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.getDefaultPrecision(displayType) != null) - return factory.getDefaultPrecision(displayType).intValue(); - + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + Integer v = service.getDefaultPrecision(displayType); + return v != null ? v.intValue() : 0; + } + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getDefaultPrecision(displayType) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + Integer v = found.get().getService().getDefaultPrecision(displayType); + return v != null ? v.intValue() : 0; } - return 0; } // getDefaultPrecision @@ -289,10 +316,18 @@ public final class DisplayType || displayType == ChosenMultipleSelectionSearch) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isText(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isText(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isText(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; } // isText @@ -308,10 +343,18 @@ public final class DisplayType if (displayType == Date || displayType == DateTime || displayType == Time) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isDate(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isDate(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isDate(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; @@ -332,10 +375,18 @@ public final class DisplayType || displayType == ChosenMultipleSelectionList) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isLookup(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isLookup(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isLookup(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; @@ -352,10 +403,18 @@ public final class DisplayType || displayType == TextLong) return true; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - if(factory.isLOB(displayType)) - return true; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) + return service.isLOB(displayType); + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().isLOB(displayType)) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return true; } return false; @@ -415,13 +474,22 @@ public final class DisplayType } else { - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - DecimalFormat osgiFormat = factory.getNumberFormat(displayType, myLanguage, pattern); - if(osgiFormat!=null){ - return osgiFormat; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + DecimalFormat f = service.getNumberFormat(displayType, language, pattern); + if (f != null) + return f; } } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getNumberFormat(displayType, language, pattern) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return found.get().getService().getNumberFormat(displayType, language, pattern); + } format.setMaximumIntegerDigits(MAX_DIGITS); format.setMaximumFractionDigits(MAX_FRACTION); @@ -530,11 +598,21 @@ public final class DisplayType } else { - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - SimpleDateFormat osgiFormat = factory.getDateFormat(displayType, myLanguage, pattern); - if(osgiFormat!=null) - return osgiFormat; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + SimpleDateFormat v = service.getDateFormat(displayType, language, pattern); + if (v != null) + return v; + } + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getDateFormat(displayType, language, pattern) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return found.get().getService().getDateFormat(displayType, language, pattern); } } @@ -593,11 +671,21 @@ public final class DisplayType return byte[].class; else { - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - Class osgiClass = factory.getClass(displayType, yesNoAsBoolean); - if(osgiClass!=null) - return osgiClass; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + Class v = service.getClass(displayType, yesNoAsBoolean); + if (v != null) + return v; + } + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getClass(displayType, yesNoAsBoolean) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return found.get().getService().getClass(displayType, yesNoAsBoolean); } } // @@ -672,11 +760,21 @@ public final class DisplayType return getDatabase().getCharacterDataType()+"(" + fieldLength + ")"; } - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - String osgiSQLDataType = factory.getSQLDataType(displayType, columnName, fieldLength); - if(osgiSQLDataType!=null) - return osgiSQLDataType; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + String v = service.getSQLDataType(displayType, columnName, fieldLength); + if (v != null) + return v; + } + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getSQLDataType(displayType, columnName, fieldLength) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return found.get().getService().getSQLDataType(displayType, columnName, fieldLength); } if (!DisplayType.isText(displayType)) @@ -764,11 +862,21 @@ public final class DisplayType if (displayType == Chart) return "Chart"; - List factoryList = Service.locator().list(IDisplayTypeFactory.class).getServices(); - for(IDisplayTypeFactory factory : factoryList){ - String osgiDescription = factory.getDescription(displayType); - if(osgiDescription!=null) - return osgiDescription; + IServiceReferenceHolder cache = s_displayTypeFactoryCache.get(displayType); + if (cache != null) { + IDisplayTypeFactory service = cache.getService(); + if (service != null) { + String v = service.getDescription(displayType); + if (v != null) + return v; + } + } + Optional> found = getDisplayTypeFactories().stream() + .filter(e -> e.getService() != null && e.getService().getDescription(displayType) != null) + .findFirst(); + if (found.isPresent()) { + s_displayTypeFactoryCache.put(displayType, found.get()); + return found.get().getService().getDescription(displayType); } // @@ -791,4 +899,9 @@ public final class DisplayType } // getCurrencyFormat + private final static CCache> s_displayTypeFactoryCache = new CCache<>(null, "IDisplayTypeFactory", 100, false); + + private static List> getDisplayTypeFactories() { + return Service.locator().list(IDisplayTypeFactory.class).getServiceReferences(); + } } // DisplayType diff --git a/org.adempiere.pipo/OSGI-INF/dictionaryservice.xml b/org.adempiere.pipo/OSGI-INF/dictionaryservice.xml index c6d3f25d68..919e0e91bb 100644 --- a/org.adempiere.pipo/OSGI-INF/dictionaryservice.xml +++ b/org.adempiere.pipo/OSGI-INF/dictionaryservice.xml @@ -1,5 +1,5 @@ - + diff --git a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AbstractActivator.java b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AbstractActivator.java index e13249a085..a23f5b336a 100644 --- a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AbstractActivator.java +++ b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AbstractActivator.java @@ -18,8 +18,8 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; +import org.adempiere.base.Core; import org.adempiere.base.IDictionaryService; -import org.adempiere.base.Service; import org.adempiere.util.IProcessUI; import org.compiere.model.MClient; import org.compiere.model.MSysConfig; @@ -93,9 +93,8 @@ public abstract class AbstractActivator implements BundleActivator, ServiceTrack boolean success = false; if (!installedPackage(version)) { - List list = Service.locator().list(IDictionaryService.class).getServices(); - if (list != null) { - IDictionaryService ids = list.get(0); + IDictionaryService ids = Core.getDictionaryService(); + if (ids != null) { ids.merge(null, zipfile); success = true; if (ids.getAD_Package_Imp_Proc() != null) { diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProvider.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProvider.java index b4cf8622f2..681992275c 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProvider.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProvider.java @@ -1,3 +1,30 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + * - carlos * + * - deepak * + * - thomas * + **********************************************************************/ package org.adempiere.report.jasper; import org.compiere.model.PrintInfo; @@ -5,11 +32,29 @@ import org.compiere.model.PrintInfo; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperPrint; +/** + * + * @author hengsin + * + */ public interface JRViewerProvider { + /** + * + * @param jasperPrint + * @param title + * @param printInfo + * @throws JRException + */ public void openViewer(JasperPrint jasperPrint, String title, PrintInfo printInfo) throws JRException; - default void openViewer(JasperPrint jasperPrint, String title) throws JRException { + /** + * + * @param jasperPrint + * @param title + * @throws JRException + */ + public default void openViewer(JasperPrint jasperPrint, String title) throws JRException { openViewer(jasperPrint, title, null); } diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java index 23e393e803..081c45b3c2 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java @@ -1,3 +1,28 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - carlos * + * - deepak * + **********************************************************************/ package org.adempiere.report.jasper; import java.util.List; @@ -7,11 +32,23 @@ import org.compiere.model.PrintInfo; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperPrint; +/** + * + * @author carlos + * + */ public interface JRViewerProviderList { + /** + * + * @param jasperPrintList + * @param title + * @param printInfo + * @throws JRException + */ public void openViewer(List jasperPrintList, String title, PrintInfo printInfo) throws JRException; - default void openViewer(List jasperPrintList, String title) throws JRException { + public default void openViewer(List jasperPrintList, String title) throws JRException { openViewer(jasperPrintList, title, null); } diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java index 0d7a7cd454..4c235c30f4 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java @@ -50,6 +50,7 @@ import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.JobName; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.DBException; @@ -755,7 +756,7 @@ public class ReportStarter implements ProcessCall, ClientProcess printInfo = new PrintInfo(pi); if (reportPathList.length == 1) { if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); - JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); + JRViewerProvider viewerLauncher = getViewerProvider(); if (!Util.isEmpty(processInfo.getReportType())) { jasperPrint.setProperty("IDEMPIERE_REPORT_TYPE", processInfo.getReportType()); } @@ -763,7 +764,7 @@ public class ReportStarter implements ProcessCall, ClientProcess } else { jasperPrintList.add(jasperPrint); if (idx+1 == reportPathList.length) { - JRViewerProviderList viewerLauncher = Service.locator().locate(JRViewerProviderList.class).getService(); + JRViewerProviderList viewerLauncher = getViewerProviderList(); if (viewerLauncher == null) { throw new AdempiereException("Can not find a viewer provider for multiple jaspers"); } @@ -886,7 +887,49 @@ public class ReportStarter implements ProcessCall, ClientProcess reportResult( AD_PInstance_ID, null, trxName); pi.setSummary(Msg.getMsg(Env.getCtx(), "Success"), false); return true; - } + } + + private static IServiceReferenceHolder s_viewerProviderListReference = null; + + /** + * + * @return {@link JRViewerProviderList} + */ + public static synchronized JRViewerProviderList getViewerProviderList() { + JRViewerProviderList viewerLauncher = null; + if (s_viewerProviderListReference != null) { + viewerLauncher = s_viewerProviderListReference.getService(); + if (viewerLauncher != null) + return viewerLauncher; + } + IServiceReferenceHolder viewerReference = Service.locator().locate(JRViewerProviderList.class).getServiceReference(); + if (viewerReference != null) { + viewerLauncher = viewerReference.getService(); + s_viewerProviderListReference = viewerReference; + } + return viewerLauncher; + } + + private static IServiceReferenceHolder s_viewerProviderReference = null; + + /** + * + * @return {@link JRViewerProvider} + */ + public static synchronized JRViewerProvider getViewerProvider() { + JRViewerProvider viewerLauncher = null; + if (s_viewerProviderReference != null) { + viewerLauncher = s_viewerProviderReference.getService(); + if (viewerLauncher != null) + return viewerLauncher; + } + IServiceReferenceHolder viewerReference = Service.locator().locate(JRViewerProvider.class).getServiceReference(); + if (viewerReference != null) { + viewerLauncher = viewerReference.getService(); + s_viewerProviderReference = viewerReference; + } + return viewerLauncher; + } private String makePrefix(String name) { StringBuilder prefix = new StringBuilder(); diff --git a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java index e0e15ae8fd..fad431ff5f 100644 --- a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java +++ b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java @@ -27,7 +27,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -import org.adempiere.base.IServiceHolder; +import org.adempiere.base.Core; import org.adempiere.base.Service; import org.adempiere.server.AdempiereServerActivator; import org.adempiere.server.IServerFactory; @@ -142,7 +142,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer map = getServerOwnerMap(); if (map != null) { - ICacheService cacheService = getCacheService(); + ICacheService cacheService = Core.getCacheService(); try { String reloadLockKey = "cluster.server.owner.map.reload"; if (cacheService.tryLock(map, reloadLockKey, 30, TimeUnit.SECONDS)) { @@ -200,7 +200,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer map = getServerOwnerMap(); if (map != null) { - ICacheService cacheService = getCacheService(); + ICacheService cacheService = Core.getCacheService(); try { if (cacheService.tryLock(map, server.getServerID(), 30, TimeUnit.SECONDS)) { try { @@ -257,7 +257,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer map = getServerOwnerMap(); if (map != null) { - ICacheService cacheService = getCacheService(); + ICacheService cacheService = Core.getCacheService(); try { if (cacheService.tryLock(map, server.getServerID(), 30, TimeUnit.SECONDS)) { try { @@ -853,14 +853,8 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer holder = Service.locator().locate(ICacheService.class); - ICacheService service = holder != null ? holder.getService() : null; - return service; - } - private Map getServerOwnerMap() { - ICacheService service = getCacheService(); + ICacheService service = Core.getCacheService(); if (service != null) { return service.getMap("cluster.server.owner.map"); } diff --git a/org.adempiere.server/src/main/server/org/idempiere/server/cluster/ClusterServerMgr.java b/org.adempiere.server/src/main/server/org/idempiere/server/cluster/ClusterServerMgr.java index 0ebd8a3418..9fcbf776c8 100644 --- a/org.adempiere.server/src/main/server/org/idempiere/server/cluster/ClusterServerMgr.java +++ b/org.adempiere.server/src/main/server/org/idempiere/server/cluster/ClusterServerMgr.java @@ -36,8 +36,7 @@ import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.adempiere.base.IServiceHolder; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.compiere.Adempiere; import org.compiere.model.MScheduler; import org.compiere.server.IServerManager; @@ -84,9 +83,7 @@ public class ClusterServerMgr implements IServerManager { * @return cluster service */ public static IClusterService getClusterService() { - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder != null ? holder.getService() : null; - return service; + return Core.getClusterService(); } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java index ecc5d0cf83..8b6512d282 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java @@ -20,13 +20,25 @@ *****************************************************************************/ package org.adempiere.webui; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.base.ServiceQuery; import org.adempiere.webui.apps.IProcessParameterListener; +import org.adempiere.webui.apps.graph.IChartRendererService; +import org.adempiere.webui.factory.IDashboardGadgetFactory; import org.adempiere.webui.factory.IFormFactory; import org.adempiere.webui.panel.ADForm; +import org.compiere.grid.ICreateFrom; +import org.compiere.grid.ICreateFromFactory; +import org.compiere.grid.IPaymentForm; +import org.compiere.grid.IPaymentFormFactory; +import org.compiere.model.GridTab; +import org.compiere.util.CCache; +import org.zkoss.zk.ui.Component; /** * @@ -36,23 +48,42 @@ import org.adempiere.webui.panel.ADForm; */ public class Extensions { + private final static CCache> s_formFactoryCache = new CCache<>(null, "IFormFactory", 100, false); + /** * * @param formId Java class name or equinox extension Id * @return IFormController instance or null if formId not found */ public static ADForm getForm(String formId) { - List factories = Service.locator().list(IFormFactory.class).getServices(); - if (factories != null) { - for(IFormFactory factory : factories) { - ADForm form = factory.newFormInstance(formId); + IServiceReferenceHolder cache = s_formFactoryCache.get(formId); + if (cache != null) { + IFormFactory service = cache.getService(); + if (service != null) { + ADForm form = service.newFormInstance(formId); if (form != null) return form; } + s_formFactoryCache.remove(formId); + } + List> factories = Service.locator().list(IFormFactory.class).getServiceReferences(); + if (factories != null) { + for(IServiceReferenceHolder factory : factories) { + IFormFactory service = factory.getService(); + if (service != null) { + ADForm form = service.newFormInstance(formId); + if (form != null) { + s_formFactoryCache.put(formId, factory); + return form; + } + } + } } return null; } + private final static CCache>> s_processParameterListenerCache = new CCache<>(null, "List", 100, false); + /** * * @param processClass @@ -60,10 +91,133 @@ public class Extensions { * @return list of parameter listener */ public static List getProcessParameterListeners(String processClass, String columnName) { + String cacheKey = processClass + "|" + columnName; + List> listeners = s_processParameterListenerCache.get(cacheKey); + if (listeners != null) + return listeners.stream().filter(e -> e.getService() != null).map(e -> e.getService()).collect(Collectors.toCollection(ArrayList::new)); + ServiceQuery query = new ServiceQuery(); query.put("ProcessClass", processClass); if (columnName != null) query.put("|(ColumnName", columnName+")(ColumnName="+columnName+",*)(ColumnName="+"*,"+columnName+",*)(ColumnName=*,"+columnName+")"); - return Service.locator().list(IProcessParameterListener.class, null, query).getServices(); + listeners = Service.locator().list(IProcessParameterListener.class, null, query).getServiceReferences(); + if (listeners == null) + listeners = new ArrayList<>(); + s_processParameterListenerCache.put(cacheKey, listeners); + return listeners.stream().filter(e -> e.getService() != null).map(e -> e.getService()).collect(Collectors.toCollection(ArrayList::new)); } + + private final static CCache> s_createFromFactoryCache = new CCache<>(null, "ICreateFromFactory", 100, false); + + /** + * + * @param mTab + * @return ICreateFrom instance + */ + public static ICreateFrom getCreateFrom(GridTab mTab) { + ICreateFrom createFrom = null; + String cacheKey = Integer.toString(mTab.getAD_Tab_ID()); + IServiceReferenceHolder cache = s_createFromFactoryCache.get(cacheKey); + if (cache != null) { + ICreateFromFactory service = cache.getService(); + if (service != null) { + createFrom = service.create(mTab); + if (createFrom != null) { + return createFrom; + } + } + s_createFromFactoryCache.remove(cacheKey); + } + + List> factories = Service.locator().list(ICreateFromFactory.class).getServiceReferences(); + for (IServiceReferenceHolder factory : factories) + { + ICreateFromFactory service = factory.getService(); + if (service != null) { + createFrom = service.create(mTab); + if (createFrom != null) { + s_createFromFactoryCache.put(cacheKey, factory); + return createFrom; + } + } + } + + return null; + } + + private static final CCache> s_paymentFormFactoryCache = new CCache<>(null, "IPaymentFormFactory", 100, false); + /** + * + * @param windowNo + * @param mTab + * @param paymentRule + * @return IPaymentForm instance + */ + public static IPaymentForm getPaymentForm(int windowNo, GridTab mTab, String paymentRule) { + String cacheKey = mTab.getAD_Tab_ID() + "|" + paymentRule; + IServiceReferenceHolder cache = s_paymentFormFactoryCache.get(cacheKey); + if (cache != null) { + IPaymentFormFactory service = cache.getService(); + if (service != null) { + IPaymentForm paymentForm = service.create(windowNo, mTab, paymentRule); + if (paymentForm != null) + return paymentForm; + } + s_paymentFormFactoryCache.remove(cacheKey); + } + IPaymentForm paymentForm = null; + List> factories = Service.locator().list(IPaymentFormFactory.class).getServiceReferences(); + for (IServiceReferenceHolder factory : factories) { + IPaymentFormFactory service = factory.getService(); + if (service != null) { + paymentForm = service.create(windowNo, mTab, paymentRule); + if (paymentForm != null) { + s_paymentFormFactoryCache.put(cacheKey, factory); + return paymentForm; + } + } + } + return null; + } + + private static final CCache> s_dashboardGadgetFactoryCache = new CCache<>(null, "IDashboardGadgetFactory", 100, false); + + /** + * + * @param url + * @param parent + * @return Gadget component + */ + public static final Component getDashboardGadget(String url, Component parent) { + IServiceReferenceHolder cache = s_dashboardGadgetFactoryCache.get(url); + if (cache != null) { + IDashboardGadgetFactory service = cache.getService(); + if (service != null) { + Component component = service.getGadget(url,parent); + if(component != null) + return component; + } + s_dashboardGadgetFactoryCache.remove(url); + } + + List> f = Service.locator().list(IDashboardGadgetFactory.class).getServiceReferences(); + for (IServiceReferenceHolder factory : f) { + IDashboardGadgetFactory service = factory.getService(); + if (service != null) { + Component component = service.getGadget(url,parent); + if(component != null) + return component; + } + } + + return null; + } + + /** + * + * @return list of {@link IChartRendererService} + */ + public static final List getChartRendererServices() { + return Service.locator().list(IChartRendererService.class).getServices(); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java index 1c8c95bdc8..7809b53c0e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/action/Actions.java @@ -37,7 +37,7 @@ public class Actions { synchronized (trackerCache) { action = trackerCache.get(actionId); } - if (action != null) + if (action != null && action.getService() != null) return action; action = Service.locator().locate(IAction.class, actionId, null); @@ -57,7 +57,7 @@ public class Actions { if (aImage != null) return aImage; - IServiceHolder action = Service.locator().locate(IAction.class, actionId, null); + IServiceHolder action = getAction(actionId); if (action.getService() != null) { String path = ACTION_IMAGES_PATH + actionId + "24.png"; InputStream inputStream = action.getService().getClass().getClassLoader().getResourceAsStream(path); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java index 5ebe52790d..106ef5e94d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/IProcessParameterListener.java @@ -16,7 +16,8 @@ package org.adempiere.webui.apps; import org.adempiere.webui.editor.WEditor; /** - * Listener interface for process parameter panel + * Listener interface for process parameter panel. + * Implementation must be thread safe * @author hengsin * */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromFactory.java index 6527b5b55c..4f3501ba9d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromFactory.java @@ -13,25 +13,24 @@ *****************************************************************************/ package org.adempiere.webui.apps.form; -import java.util.List; - -import org.adempiere.base.Service; +import org.adempiere.webui.Extensions; import org.compiere.grid.ICreateFrom; -import org.compiere.grid.ICreateFromFactory; import org.compiere.model.GridTab; +/** + * + * @author hengsin + * + */ public class WCreateFromFactory { + /** + * + * @param mTab + * @return ICreateFrom instance + */ public static ICreateFrom create (GridTab mTab) { - ICreateFrom createFrom = null; - List factories = Service.locator().list(ICreateFromFactory.class).getServices(); - for (ICreateFromFactory factory : factories) - { - createFrom = factory.create(mTab); - if (createFrom != null) - break; - } - return createFrom; + return Extensions.getCreateFrom(mTab); } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormFactory.java index 92403a68f7..f543f0ed44 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormFactory.java @@ -13,11 +13,8 @@ *****************************************************************************/ package org.adempiere.webui.apps.form; -import java.util.List; - -import org.adempiere.base.Service; +import org.adempiere.webui.Extensions; import org.compiere.grid.IPaymentForm; -import org.compiere.grid.IPaymentFormFactory; import org.compiere.model.GridTab; /** @@ -27,15 +24,15 @@ import org.compiere.model.GridTab; */ public class WPaymentFormFactory { + /** + * + * @param windowNo + * @param mTab + * @param paymentRule + * @return IPaymentForm instance + */ public static IPaymentForm create(int windowNo, GridTab mTab, String paymentRule) { - IPaymentForm paymentForm = null; - List factories = Service.locator().list(IPaymentFormFactory.class).getServices(); - for (IPaymentFormFactory factory : factories) { - paymentForm = factory.create(windowNo, mTab, paymentRule); - if (paymentForm != null) - break; - } - return paymentForm; + return Extensions.getPaymentForm(windowNo, mTab, paymentRule); } } \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java index 9e6bac9f78..3223cb4761 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java @@ -22,8 +22,8 @@ import java.util.Collections; import java.util.List; import org.adempiere.apps.graph.GraphColumn; -import org.adempiere.base.Service; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.graph.model.GoalModel; import org.adempiere.webui.editor.WTableDirEditor; @@ -277,7 +277,7 @@ public class WGraph extends Div implements IdSpace { goalModel.xAxisLabel = m_xAxisLabel; goalModel.yAxisLabel = m_yAxisLabel; goalModel.zoomFactor = zoomFactor; - List list = Service.locator().list(IChartRendererService.class).getServices(); + List list = Extensions.getChartRendererServices(); for (IChartRendererService renderer : list) { if (renderer.renderPerformanceGraph(panel.getPanelchildren(), width, height, goalModel)) break; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WPerformanceIndicator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WPerformanceIndicator.java index f7088ecd75..05357b97b5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WPerformanceIndicator.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WPerformanceIndicator.java @@ -18,7 +18,7 @@ import java.text.DecimalFormat; import java.util.List; import java.util.Map; -import org.adempiere.base.Service; +import org.adempiere.webui.Extensions; import org.adempiere.webui.apps.graph.model.IndicatorModel; import org.adempiere.webui.component.Panel; import org.adempiere.webui.theme.ThemeManager; @@ -199,7 +199,7 @@ public class WPerformanceIndicator extends Panel implements EventListener model.dialBackground = dialBackground; model.needleColor = needleColor; model.tickColor = tickColor; - List list = Service.locator().list(IChartRendererService.class).getServices(); + List list = Extensions.getChartRendererServices(); for (IChartRendererService renderer : list) { if (renderer.renderPerformanceIndicator(this, chartWidth, chartHeight, model)) break; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java index 7ddccf7ded..63d16f8ed3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Properties; import java.util.logging.Level; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.base.event.AbstractEventHandler; import org.adempiere.base.event.EventManager; import org.adempiere.base.event.IEventTopics; @@ -167,7 +167,7 @@ public class DPCalendar extends DashboardPanel implements EventListener, if (subscriber == null) { subscriber = new TopicSubscriber(); - IMessageService service = Service.locator().locate(IMessageService.class).getService(); + IMessageService service = Core.getMessageService(); if (service != null) { ITopic> topic = service.getTopic("onRequestChanged"); topic.subscribe(subscriber); @@ -562,7 +562,7 @@ public class DPCalendar extends DashboardPanel implements EventListener, @Override public void run() { - IMessageService service = Service.locator().locate(IMessageService.class).getService(); + IMessageService service = Core.getMessageService(); if (service != null) { ITopic> topic = service.getTopic(ON_REQUEST_CHANGED_TOPIC); topic.publish(message); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java index fda1721698..9c39f4604b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java @@ -16,7 +16,7 @@ package org.adempiere.webui.dashboard; import java.lang.ref.WeakReference; import java.util.List; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.base.event.EventManager; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.session.SessionManager; @@ -154,7 +154,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener topic = service.getTopic(MRecentItem.ON_RECENT_ITEM_CHANGED_TOPIC); topic.subscribe(topicSubscriber); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java index 1f3772bf56..49eb37bbdb 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRunningJobs.java @@ -17,7 +17,7 @@ package org.adempiere.webui.dashboard; import java.lang.ref.WeakReference; import java.util.List; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.base.event.EventManager; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.ToolBarButton; @@ -126,7 +126,7 @@ public class DPRunningJobs extends DashboardPanel implements EventListener topic = service.getTopic(MPInstance.ON_RUNNING_JOB_CHANGED_TOPIC); topic.subscribe(topicSubscriber); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java index a4df1d75dd..f3d0c57850 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java @@ -26,9 +26,9 @@ import java.util.Map; import java.util.Properties; import java.util.logging.Level; -import org.adempiere.base.Service; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.graph.IChartRendererService; import org.adempiere.webui.apps.graph.WGraph; @@ -37,7 +37,6 @@ import org.adempiere.webui.apps.graph.model.ChartModel; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.dashboard.DashboardPanel; import org.adempiere.webui.dashboard.DashboardRunnable; -import org.adempiere.webui.factory.IDashboardGadgetFactory; import org.adempiere.webui.report.HTMLExtension; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; @@ -472,14 +471,7 @@ public class DashboardController implements EventListener { { try { - Component component = null; - List f = Service.locator().list(IDashboardGadgetFactory.class).getServices(); - for (IDashboardGadgetFactory factory : f) { - component = factory.getGadget(url.toString(),content); - if(component != null) - break; - } - + Component component = Extensions.getDashboardGadget(url, content); if(component != null) { if (component instanceof Include) @@ -528,11 +520,7 @@ public class DashboardController implements EventListener { chartPanel.getChildren().clear(); ChartModel model = new ChartModel(); model.chart = chartModel; - List list = Service.locator().list(IChartRendererService.class).getServices(); - for (IChartRendererService renderer : list) { - if (renderer.renderChart(chartPanel, width, height, model)) - break; - } + renderChart(chartPanel, width, height, model); } }); } @@ -967,4 +955,12 @@ public class DashboardController implements EventListener { } } } + + private void renderChart(final Div chartPanel, int width, int height, ChartModel model) { + List list = Extensions.getChartRendererServices(); + for (IChartRendererService renderer : list) { + if (renderer.renderChart(chartPanel, width, height, model)) + break; + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChartEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChartEditor.java index 36f7445142..afd9639ea1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChartEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WChartEditor.java @@ -16,7 +16,7 @@ package org.adempiere.webui.editor; import java.util.List; -import org.adempiere.base.Service; +import org.adempiere.webui.Extensions; import org.adempiere.webui.apps.graph.IChartRendererService; import org.adempiere.webui.apps.graph.model.ChartModel; import org.compiere.model.GridField; @@ -66,7 +66,7 @@ public class WChartEditor extends WEditor chartDiv.getChildren().clear(); ChartModel model = new ChartModel(); model.chart = chartModel; - List list = Service.locator().list(IChartRendererService.class).getServices(); + List list = Extensions.getChartRendererServices(); for (IChartRendererService renderer : list) { if (renderer.renderChart(chartDiv, chartWidth, chartHeight, model)) break; @@ -156,7 +156,7 @@ public class WChartEditor extends WEditor chartDiv.getChildren().clear(); ChartModel model = new ChartModel(); model.chart = chartModel; - List list = Service.locator().list(IChartRendererService.class).getServices(); + List list = Extensions.getChartRendererServices(); for (IChartRendererService renderer : list) { if (renderer.renderChart(chartDiv, chartWidth, chartHeight, model)) break; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java index b588dd9430..9006eb8d48 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java @@ -17,13 +17,16 @@ package org.adempiere.webui.editor; +import java.util.ArrayList; import java.util.List; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.webui.factory.IEditorFactory; import org.compiere.model.GridField; import org.compiere.model.GridTab; -import org.compiere.util.CLogger; +import org.compiere.util.CCache; +import org.osgi.framework.Constants; /** * @@ -36,29 +39,61 @@ import org.compiere.util.CLogger; */ public class WebEditorFactory { - - @SuppressWarnings("unused") - private final static CLogger logger; - - static - { - logger = CLogger.getCLogger(WebEditorFactory.class); - } - + /** + * + * @param gridField + * @param tableEditor + * @return WEditor for GridField + */ public static WEditor getEditor(GridField gridField, boolean tableEditor) { return getEditor(gridField.getGridTab(), gridField, tableEditor); } + private static final CCache> s_editorFactoryCache = new CCache<>(null, "IEditorFactory", 10, false); + + /** + * + * @param gridTab + * @param gridField + * @param tableEditor + * @return WEditor for GridField + */ public static WEditor getEditor(GridTab gridTab, GridField gridField, boolean tableEditor) { + List visitedIds = new ArrayList(); + if (!s_editorFactoryCache.isEmpty()) { + Long[] keys = s_editorFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_editorFactoryCache.get(key); + if (serviceReference != null) { + IEditorFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + WEditor editor = service.getEditor(gridTab, gridField, tableEditor); + if (editor != null) + return editor; + } else { + s_editorFactoryCache.remove(key); + } + } + } + } WEditor editor = null; - List factoryList = Service.locator().list(IEditorFactory.class).getServices(); - for(IEditorFactory factory : factoryList) + List> serviceReferences = Service.locator().list(IEditorFactory.class).getServiceReferences(); + for(IServiceReferenceHolder serviceReference : serviceReferences) { - editor = factory.getEditor(gridTab, gridField, tableEditor); - if (editor != null) - break; + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + IEditorFactory service = serviceReference.getService(); + if (service != null) + { + s_editorFactoryCache.put(serviceId, serviceReference); + editor = service.getEditor(gridTab, gridField, tableEditor); + if (editor != null) + break; + } } return editor; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/InfoManager.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/InfoManager.java index cc7f04269b..46f8fa5ef4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/InfoManager.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/InfoManager.java @@ -13,14 +13,18 @@ *****************************************************************************/ package org.adempiere.webui.factory; +import java.util.ArrayList; import java.util.List; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.webui.info.InfoWindow; import org.adempiere.webui.panel.InfoPanel; import org.compiere.model.GridField; import org.compiere.model.Lookup; import org.compiere.model.MLookup; +import org.compiere.util.CCache; +import org.osgi.framework.Constants; /** * @@ -29,23 +33,74 @@ import org.compiere.model.MLookup; */ public class InfoManager { + private final static CCache> s_infoFactoryCache = new CCache>(null, "IInfoFactory", 10, false); + + /** + * + * @param WindowNo + * @param tableName + * @param keyColumn + * @param value + * @param multiSelection + * @param whereClause + * @param lookup + * @return {@link InfoPanel} + */ public static InfoPanel create (int WindowNo, String tableName, String keyColumn, String value, boolean multiSelection, String whereClause, boolean lookup) { - InfoPanel info = null; - - List factoryList = Service.locator().list(IInfoFactory.class).getServices(); - for(IInfoFactory factory : factoryList) + InfoPanel info = null; + + List visitedIds = new ArrayList(); + if (!s_infoFactoryCache.isEmpty()) { + Long[] keys = s_infoFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_infoFactoryCache.get(key); + if (serviceReference != null) { + IInfoFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + info = service.create(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, 0, lookup); + if (info != null) + return info; + } else { + s_infoFactoryCache.remove(key); + } + } + } + } + + List> serviceReferences = Service.locator().list(IInfoFactory.class).getServiceReferences(); + for(IServiceReferenceHolder serviceReference : serviceReferences) { - info = factory.create(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, 0, lookup); - if (info != null) - break; + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + IInfoFactory service = serviceReference.getService(); + if (service != null) + { + s_infoFactoryCache.put(serviceId, serviceReference); + info = service.create(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, 0, lookup); + if (info != null) + break; + } } // return info; } + /** + * + * @param lookup + * @param field + * @param tableName + * @param keyColumn + * @param queryValue + * @param multiSelection + * @param whereClause + * @return {@link InfoPanel} + */ public static InfoPanel create(Lookup lookup, GridField field, String tableName, String keyColumn, String queryValue, boolean multiSelection, String whereClause) @@ -56,26 +111,86 @@ public class InfoManager { AD_InfoWindow_ID = ((MLookup)lookup).getAD_InfoWindow_ID(); } - List factoryList = Service.locator().list(IInfoFactory.class).getServices(); - for(IInfoFactory factory : factoryList) + + List visitedIds = new ArrayList(); + if (!s_infoFactoryCache.isEmpty()) { + Long[] keys = s_infoFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_infoFactoryCache.get(key); + if (serviceReference != null) { + IInfoFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + ip = service.create(lookup, field, tableName, keyColumn, queryValue, false, whereClause, AD_InfoWindow_ID); + if (ip != null) + return ip; + } else { + s_infoFactoryCache.remove(key); + } + } + } + } + + List> serviceReferences = Service.locator().list(IInfoFactory.class).getServiceReferences(); + for(IServiceReferenceHolder serviceReference : serviceReferences) { - ip = factory.create(lookup, field, tableName, keyColumn, queryValue, false, whereClause, AD_InfoWindow_ID); - if (ip != null) - break; + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + IInfoFactory service = serviceReference.getService(); + if (service != null) + { + s_infoFactoryCache.put(serviceId, serviceReference); + ip = service.create(lookup, field, tableName, keyColumn, queryValue, false, whereClause, AD_InfoWindow_ID); + if (ip != null) + break; + } } return ip; } + /** + * + * @param AD_InfoWindow_ID + * @return {@link InfoWindow} + */ public static InfoWindow create (int AD_InfoWindow_ID) { InfoWindow info = null; - List factoryList = Service.locator().list(IInfoFactory.class).getServices(); - for(IInfoFactory factory : factoryList) + List visitedIds = new ArrayList(); + if (!s_infoFactoryCache.isEmpty()) { + Long[] keys = s_infoFactoryCache.keySet().toArray(new Long[0]); + for (Long key : keys) { + IServiceReferenceHolder serviceReference = s_infoFactoryCache.get(key); + if (serviceReference != null) { + IInfoFactory service = serviceReference.getService(); + if (service != null) { + visitedIds.add(key); + info = service.create(AD_InfoWindow_ID); + if (info != null) + return info; + } else { + s_infoFactoryCache.remove(key); + } + } + } + } + + List> serviceReferences = Service.locator().list(IInfoFactory.class).getServiceReferences(); + for(IServiceReferenceHolder serviceReference : serviceReferences) { - info = factory.create(AD_InfoWindow_ID); - if (info != null) - break; + Long serviceId = (Long) serviceReference.getServiceReference().getProperty(Constants.SERVICE_ID); + if (visitedIds.contains(serviceId)) + continue; + IInfoFactory service = serviceReference.getService(); + if (service != null) + { + s_infoFactoryCache.put(serviceId, serviceReference); + info = service.create(AD_InfoWindow_ID); + if (info != null) + break; + } } // return info; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/ChangeStateAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/ChangeStateAction.java index 0a38457e8e..c2c36032f7 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/ChangeStateAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/ChangeStateAction.java @@ -25,8 +25,7 @@ **********************************************************************/ package org.adempiere.webui.scheduler; -import org.adempiere.base.IServiceHolder; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.util.Callback; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.action.IAction; @@ -156,8 +155,7 @@ public class ChangeStateAction implements IAction, EventListener { private IServerManager getServerMgr() { IServerManager serverMgr = null; - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder != null ? holder.getService() : null; + IClusterService service = Core.getClusterService(); if (service != null) serverMgr = ClusterServerMgr.getInstance(); else diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/SchedulerStateEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/SchedulerStateEditor.java index a6f92158d2..b10c6d6484 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/SchedulerStateEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/scheduler/SchedulerStateEditor.java @@ -25,8 +25,7 @@ **********************************************************************/ package org.adempiere.webui.scheduler; -import org.adempiere.base.IServiceHolder; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.adempiere.util.Callback; import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.component.Button; @@ -329,8 +328,7 @@ public class SchedulerStateEditor extends WEditor { private IServerManager getServerMgr() { IServerManager serverMgr = null; - IServiceHolder holder = Service.locator().locate(IClusterService.class); - IClusterService service = holder != null ? holder.getService() : null; + IClusterService service = Core.getClusterService(); if (service != null) serverMgr = ClusterServerMgr.getInstance(); else diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/FeedbackManager.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/FeedbackManager.java index c53f108d12..1d6bff797e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/FeedbackManager.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/FeedbackManager.java @@ -15,6 +15,7 @@ package org.adempiere.webui.util; import javax.activation.DataSource; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.factory.IFeedbackService; @@ -52,9 +53,30 @@ public class FeedbackManager { */ public static void emailSupport(boolean errorOnly) { - IFeedbackService service = Service.locator().locate(IFeedbackService.class).getService(); + IFeedbackService service = getFeedbackService(); if (service != null) service.emailSupport(errorOnly); + } + + private static IServiceReferenceHolder s_feedbackServiceReference = null; + + /** + * + * @return {@link IFeedbackService} + */ + public static synchronized IFeedbackService getFeedbackService() { + IFeedbackService service = null; + if (s_feedbackServiceReference != null) { + service = s_feedbackServiceReference.getService(); + if (service != null) + return service; + } + IServiceReferenceHolder serviceReference = Service.locator().locate(IFeedbackService.class).getServiceReference(); + if (serviceReference != null) { + service = serviceReference.getService(); + s_feedbackServiceReference = serviceReference; + } + return service; } /** @@ -62,7 +84,7 @@ public class FeedbackManager { */ public static void createNewRequest() { - IFeedbackService service = Service.locator().locate(IFeedbackService.class).getService(); + IFeedbackService service = getFeedbackService(); if (service != null) service.createNewRequest(); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java index dd585d5ca6..19034bfa8d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewerProvider.java @@ -31,6 +31,7 @@ import org.zkoss.zk.ui.Executions; */ public class ZkReportViewerProvider implements ReportViewerProvider { + @Override public void openViewer(final ReportEngine report) { // IDEMPIERE-2499 // detect ui thread by value of Executions.getCurrent(), not office method but work diff --git a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java index 4612c719cc..078c6b3afa 100644 --- a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java +++ b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java @@ -25,11 +25,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.List; import java.util.logging.Level; -import org.adempiere.base.IPaymentExporterFactory; -import org.adempiere.base.Service; +import org.adempiere.base.Core; import org.compiere.model.MLookupFactory; import org.compiere.model.MLookupInfo; import org.compiere.model.MPaySelectionCheck; @@ -252,15 +250,7 @@ public class PayPrint { } try { - List factories = Service.locator().list(IPaymentExporterFactory.class).getServices(); - if (factories != null && !factories.isEmpty()) { - for(IPaymentExporterFactory factory : factories) { - m_PaymentExport = factory.newPaymentExporterInstance(m_PaymentExportClass); - if (m_PaymentExport != null) - break; - } - } - + m_PaymentExport = Core.getPaymentExporter(m_PaymentExportClass); if (m_PaymentExport == null) { Class clazz = Class.forName (m_PaymentExportClass); diff --git a/org.adempiere.ui/src/org/compiere/print/ReportCtl.java b/org.adempiere.ui/src/org/compiere/print/ReportCtl.java index 84b76f2bff..8b8d233435 100644 --- a/org.adempiere.ui/src/org/compiere/print/ReportCtl.java +++ b/org.adempiere.ui/src/org/compiere/print/ReportCtl.java @@ -31,6 +31,7 @@ import static org.compiere.model.SystemIDs.PROCESS_RPT_M_MOVEMENT; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.base.IServiceReferenceHolder; import org.adempiere.base.Service; import org.adempiere.exceptions.AdempiereException; import org.adempiere.util.IProcessUI; @@ -463,8 +464,29 @@ public class ReportCtl */ public static void preview(ReportEngine re) { - ReportViewerProvider viewer = Service.locator().locate(ReportViewerProvider.class).getService(); + ReportViewerProvider viewer = getReportViewerProvider(); viewer.openViewer(re); } + private static IServiceReferenceHolder s_reportViewerProviderReference = null; + + /** + * + * @return {@link ReportViewerProvider} + */ + public static synchronized ReportViewerProvider getReportViewerProvider() { + ReportViewerProvider viewer = null; + if (s_reportViewerProviderReference != null) { + viewer = s_reportViewerProviderReference.getService(); + if (viewer != null) + return viewer; + } + IServiceReferenceHolder viewerReference = Service.locator().locate(ReportViewerProvider.class).getServiceReference(); + if (viewerReference != null) { + s_reportViewerProviderReference = viewerReference; + viewer = viewerReference.getService(); + } + return viewer; + } + } // ReportCtl diff --git a/org.adempiere.ui/src/org/compiere/print/ReportViewerProvider.java b/org.adempiere.ui/src/org/compiere/print/ReportViewerProvider.java index cd2c141671..b3755d67a0 100644 --- a/org.adempiere.ui/src/org/compiere/print/ReportViewerProvider.java +++ b/org.adempiere.ui/src/org/compiere/print/ReportViewerProvider.java @@ -23,5 +23,9 @@ package org.compiere.print; * */ public interface ReportViewerProvider { + /** + * Open report viewer + * @param re + */ public void openViewer(ReportEngine re); } diff --git a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java index aee1018fab..902549e783 100644 --- a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java +++ b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java @@ -33,7 +33,6 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import java.sql.Timestamp; import java.util.Properties; import java.util.Random; diff --git a/org.idempiere.test/META-INF/MANIFEST.MF b/org.idempiere.test/META-INF/MANIFEST.MF index 9f377c9a3f..b5b6817550 100644 --- a/org.idempiere.test/META-INF/MANIFEST.MF +++ b/org.idempiere.test/META-INF/MANIFEST.MF @@ -16,5 +16,11 @@ Import-Package: org.junit.jupiter.api;version="5.6.0", org.junit.jupiter.params.aggregator;version="5.6.0", org.junit.jupiter.params.converter;version="5.6.0", org.junit.jupiter.params.provider;version="5.6.0", - org.junit.jupiter.params.support;version="5.6.0" -Require-Bundle: org.adempiere.base;bundle-version="7.1.0" + org.junit.jupiter.params.support;version="5.6.0", + org.osgi.framework;version="1.9.0" +Require-Bundle: org.adempiere.base;bundle-version="7.1.0", + org.adempiere.base.callout;bundle-version="7.1.0", + org.adempiere.base.process;bundle-version="7.1.0", + org.adempiere.payment.processor;bundle-version="7.1.0" +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.idempiere.test.TestActivator diff --git a/org.idempiere.test/idempiere.unit.test.launch b/org.idempiere.test/idempiere.unit.test.launch index c69862c945..d40adca3d2 100644 --- a/org.idempiere.test/idempiere.unit.test.launch +++ b/org.idempiere.test/idempiere.unit.test.launch @@ -480,9 +480,6 @@ - - - @@ -509,16 +506,11 @@ - - - - - - - + + + - - + @@ -547,7 +539,7 @@ - + diff --git a/org.idempiere.test/src/org/idempiere/test/TestActivator.java b/org.idempiere.test/src/org/idempiere/test/TestActivator.java new file mode 100644 index 0000000000..f51045f62e --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/TestActivator.java @@ -0,0 +1,48 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * @author hengsin + * + */ +public class TestActivator implements BundleActivator { + + public static BundleContext context = null; + + @Override + public void start(BundleContext context) throws Exception { + TestActivator.context = context; + } + + @Override + public void stop(BundleContext context) throws Exception { + TestActivator.context = null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java index aa4244c84b..3b07a62d4a 100644 --- a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java +++ b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java @@ -25,22 +25,99 @@ package org.idempiere.test.performance; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Timestamp; +import java.util.List; +import java.util.Optional; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; + +import org.adempiere.base.Core; +import org.adempiere.base.DefaultPaymentExporterFactory; +import org.adempiere.base.IAddressValidationFactory; +import org.adempiere.base.IBankStatementLoaderFactory; +import org.adempiere.base.IBankStatementMatcherFactory; +import org.adempiere.base.IColumnCallout; +import org.adempiere.base.IDisplayTypeFactory; +import org.adempiere.base.IPaymentExporterFactory; +import org.adempiere.base.IReplenishFactory; +import org.adempiere.base.IResourceFinder; +import org.adempiere.base.LookupFactoryHelper; +import org.adempiere.base.ServiceQuery; +import org.adempiere.model.IAddressValidation; +import org.adempiere.model.IShipmentProcessor; +import org.adempiere.model.ITaxProvider; +import org.adempiere.model.MShipperFacade; +import org.adempiere.model.ProductPriceValidator; +import org.compiere.acct.Doc; +import org.compiere.acct.DocManager; +import org.compiere.db.AdempiereDatabase; +import org.compiere.db.Database; +import org.compiere.impexp.BankStatementLoaderInterface; +import org.compiere.impexp.BankStatementMatcherInterface; +import org.compiere.impexp.OFXFileBankStatementLoader; +import org.compiere.model.Callout; +import org.compiere.model.GridFieldVO; +import org.compiere.model.GridTabVO; +import org.compiere.model.GridWindowVO; +import org.compiere.model.IArchiveStore; +import org.compiere.model.IAttachmentStore; +import org.compiere.model.IImageStore; import org.compiere.model.I_AD_Table; +import org.compiere.model.I_M_InventoryLine; +import org.compiere.model.Lookup; +import org.compiere.model.MAcctSchema; +import org.compiere.model.MAddressValidation; +import org.compiere.model.MBPartner; +import org.compiere.model.MBankAccountProcessor; +import org.compiere.model.MClientInfo; import org.compiere.model.MColumn; +import org.compiere.model.MDocType; +import org.compiere.model.MInvoice; +import org.compiere.model.MInvoiceLine; import org.compiere.model.MOrder; import org.compiere.model.MProduct; import org.compiere.model.MRefTable; +import org.compiere.model.MShipper; +import org.compiere.model.MStorageProvider; import org.compiere.model.MTable; +import org.compiere.model.MTaxProvider; import org.compiere.model.MWarehouse; import org.compiere.model.MZoomCondition; +import org.compiere.model.ModelValidator; +import org.compiere.model.PaymentProcessor; +import org.compiere.model.StandardTaxProvider; +import org.compiere.model.X_C_AddressValidationCfg; +import org.compiere.model.X_C_TaxProviderCfg; +import org.compiere.process.BPartnerValidate; +import org.compiere.process.DocAction; +import org.compiere.process.DocumentEngine; +import org.compiere.process.ProcessCall; +import org.compiere.process.ProcessInfo; import org.compiere.util.CCache; import org.compiere.util.CacheInterface; import org.compiere.util.CacheMgt; +import org.compiere.util.DisplayType; import org.compiere.util.Env; +import org.compiere.util.GenericPaymentExport; +import org.compiere.util.PaymentExport; +import org.compiere.util.ReplenishInterface; +import org.compiere.util.TimeUtil; +import org.compiere.wf.MWorkflow; +import org.eevolution.model.CalloutBOM; +import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO; +import org.idempiere.fa.service.api.IDepreciationMethod; +import org.idempiere.fa.service.api.IDepreciationMethodFactory; import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.TestActivator; import org.junit.jupiter.api.Test; /** @@ -77,22 +154,7 @@ public class CacheTest extends AbstractTestCase { MTable table = MTable.get(Env.getCtx(), MOrder.Table_ID); //find table cache instance - @SuppressWarnings("rawtypes") - CCache tblCache = null; - CacheInterface[] cis = CacheMgt.get().getInstancesAsArray(); - for(CacheInterface ci : cis) { - if (ci instanceof CCache) { - @SuppressWarnings("rawtypes") - CCache ccache = (CCache) ci; - if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(MTable.Table_Name)) { - if (ccache.containsKey(MOrder.Table_ID)) { - tblCache = ccache; - break; - } - } - } - } - + CCache tblCache = findByTableNameAndKey(MTable.Table_Name, MOrder.Table_ID); if (tblCache == null) fail("Table cache instance missing"); @@ -107,20 +169,7 @@ public class CacheTest extends AbstractTestCase { table = MTable.get(Env.getCtx(), MWarehouse.Table_ID); MRefTable refTable = MRefTable.get(Env.getCtx(), 197); - tblCache = null; - for(CacheInterface ci : cis) { - if (ci instanceof CCache) { - @SuppressWarnings("rawtypes") - CCache ccache = (CCache) ci; - if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(MTable.Table_Name)) { - if (ccache.containsKey(MWarehouse.Table_ID)) { - tblCache = ccache; - break; - } - } - } - } - + tblCache = findByTableNameAndKey(MTable.Table_Name, MWarehouse.Table_ID); if (tblCache == null) fail("Table cache instance missing"); @@ -129,28 +178,14 @@ public class CacheTest extends AbstractTestCase { assertEquals(hit+1, tblCache.getHit()); } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"unchecked"}) @Test public void testPOCacheAfterUpdate() { int mulch = 137; int oak = 123; //init cache MProduct p1 = MProduct.get(Env.getCtx(), mulch); - CCache pc = null; - CacheInterface[] cis = CacheMgt.get().getInstancesAsArray(); - //find product cache instance - for(CacheInterface ci : cis) { - if (ci instanceof CCache) { - CCache ccache = (CCache) ci; - if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(MProduct.Table_Name)) { - if (ccache.containsKey(mulch)) { - pc = ccache; - break; - } - } - } - } - + CCache pc = (CCache) findByTableNameAndKey(MProduct.Table_Name, mulch); if (pc == null) fail("Product cache instance missing"); @@ -214,4 +249,455 @@ public class CacheTest extends AbstractTestCase { rollback(); } + + @Test + public void testServices() { + //IResourceFinder + TestActivator.context.registerService(IResourceFinder.class, new FakeResourceFinder(), null); + IResourceFinder resourceFinder = Core.getResourceFinder(); + assertNotNull(resourceFinder, "Can't find resource finder service"); + String cacheKey = FakeResourceFinder.class.getName(); + URL url = Core.getResourceFinder().getResource(cacheKey); + assertNotNull(url); + String cacheName = "IResourceFinder"; + CCache cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + long hit = cache.getHit(); + url = Core.getResourceFinder().getResource(cacheKey); + assertNotNull(url); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IColumnCalloutFactory + List callouts = Core.findCallout(I_M_InventoryLine.Table_Name, I_M_InventoryLine.COLUMNNAME_M_Product_ID); + assertTrue(callouts.size() > 0, "Can't find callouts for " + I_M_InventoryLine.Table_Name + ", " + I_M_InventoryLine.COLUMNNAME_M_Product_ID); + cacheKey = I_M_InventoryLine.Table_Name + "." + I_M_InventoryLine.COLUMNNAME_M_Product_ID; + cacheName = "List"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + callouts = Core.findCallout(I_M_InventoryLine.Table_Name, I_M_InventoryLine.COLUMNNAME_M_Product_ID); + assertTrue(callouts.size() > 0, "Can't find callouts for " + I_M_InventoryLine.Table_Name + ", " + I_M_InventoryLine.COLUMNNAME_M_Product_ID); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //ICalloutFactory + cacheKey = CalloutBOM.class.getName() + "::" + "parent"; + Callout callout = Core.getCallout(CalloutBOM.class.getName(), "parent"); + assertNotNull(callout, "Can't find callout for " + cacheKey); + cacheName = "ICalloutFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + callout = Core.getCallout(CalloutBOM.class.getName(), "parent"); + assertNotNull(callout, "Can't find callout for " + cacheKey); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IProcessFactory + cacheKey = BPartnerValidate.class.getName(); + ProcessCall process = Core.getProcess(cacheKey); + assertNotNull(process, "Can't find process for " + cacheKey); + cacheName = "IProcessFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + process = Core.getProcess(cacheKey); + assertNotNull(process, "Can't find process for " + cacheKey); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IModelValidatorFactory + cacheKey = ProductPriceValidator.class.getName(); + ModelValidator modelValidator = Core.getModelValidator(cacheKey); + assertNotNull(modelValidator, "Can't find model validator for " + cacheKey); + cacheName = "IModelValidatorFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + modelValidator = Core.getModelValidator(cacheKey); + assertNotNull(modelValidator, "Can't find model validator for " + cacheKey); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IKeyStore + assertNotNull(Core.getKeyStore(), "Can't find key store service"); + //second call to check service reference cache is working + assertNotNull(Core.getKeyStore(), "Can't find key store service"); + + //IPaymentProcessorFactory + int pp_payflowpro_id = 100; + MBankAccountProcessor bankAccountProcessor = MBankAccountProcessor.get(Env.getCtx(), pp_payflowpro_id, pp_payflowpro_id, getTrxName()); + assertNotNull(bankAccountProcessor, "Can't load bank account processor for PP_PayFlowPro"); + PaymentProcessor paymentProcessor = Core.getPaymentProcessor(bankAccountProcessor, null); + assertNotNull(paymentProcessor, "Can't load payment processor for PP_PayFlowPro"); + cacheKey = "org.compiere.model.PP_PayFlowPro"; + cacheName = "IPaymentProcessorFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + paymentProcessor = Core.getPaymentProcessor(bankAccountProcessor, null); + assertNotNull(paymentProcessor, "Can't load payment processor for PP_PayFlowPro"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IBankStatementLoaderFactory + TestActivator.context.registerService(IBankStatementLoaderFactory.class, new FakeBankStatementLoaderFactory(), null); + cacheKey = OFXFileBankStatementLoader.class.getName(); + BankStatementLoaderInterface bankStatementLoader = Core.getBankStatementLoader(cacheKey); + assertNotNull(bankStatementLoader, "Can't find BankStatementLoader for " + cacheKey); + cacheName = "IBankStatementLoaderFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + bankStatementLoader = Core.getBankStatementLoader(cacheKey); + assertNotNull(bankStatementLoader, "Can't find BankStatementLoader for " + cacheKey); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IBankStatementMatcherFactory + TestActivator.context.registerService(IBankStatementMatcherFactory.class, new FakeBankStatementMatcherFactory(), null); + cacheKey = FakeBankStatementMatcherFactory.class.getName(); + BankStatementMatcherInterface bankStatementMatcher = Core.getBankStatementMatcher(cacheKey); + assertNotNull(bankStatementMatcher, "Can't find bank statement matcher service"); + cacheName = "IBankStatementMatcherFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + bankStatementMatcher = Core.getBankStatementMatcher(cacheKey); + assertNotNull(bankStatementMatcher, "Can't find bank statement matcher service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IShipmentProcessorFactory + int m_shipper_id=100; + MShipperFacade shipperFacade = new MShipperFacade(new MShipper(Env.getCtx(), m_shipper_id, getTrxName())); + cacheKey = shipperFacade.getShippingProcessorClass(); + cacheName = "IShipmentProcessorFactory"; + IShipmentProcessor shipmentProcessor = Core.getShipmentProcessor(shipperFacade); + assertNotNull(shipmentProcessor, "Can't find shipment processor"); + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + shipmentProcessor = Core.getShipmentProcessor(shipperFacade); + assertNotNull(shipmentProcessor, "Can't find shipment processor"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IAddressValidationFactory + X_C_AddressValidationCfg cfg = new X_C_AddressValidationCfg(Env.getCtx(), 0, getTrxName()); + cfg.setHostAddress("10.8.0.1"); + cfg.setHostPort(433); + cfg.setName("Test Cfg"); + cacheKey = FakeAddressValidationFactory.class.getName(); + cfg.setAddressValidationClass(cacheKey); + cfg.saveEx(); + MAddressValidation addressValidation = new MAddressValidation(Env.getCtx(), 0, getTrxName()); + addressValidation.setC_AddressValidationCfg_ID(cfg.get_ID()); + addressValidation.setConnectionPassword("password"); + addressValidation.setName("Test Address Validation"); + addressValidation.setUserID("userid"); + addressValidation.setSeqNo(10); + addressValidation.saveEx(); + TestActivator.context.registerService(IAddressValidationFactory.class, new FakeAddressValidationFactory(), null); + IAddressValidation addressValidationService = Core.getAddressValidation(addressValidation); + assertNotNull(addressValidationService, "Can't find address validation service"); + cacheName = "IAddressValidationFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + addressValidationService = Core.getAddressValidation(addressValidation); + assertNotNull(addressValidationService, "Can't find address validation service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //ITaxProviderFactory + X_C_TaxProviderCfg taxProviderCfg = new X_C_TaxProviderCfg(Env.getCtx(), 0, getTrxName()); + taxProviderCfg.setName("Standard Provider Configuration"); + taxProviderCfg.setTaxProviderClass(StandardTaxProvider.class.getName()); + taxProviderCfg.saveEx(); + MTaxProvider taxProvider = new MTaxProvider(Env.getCtx(), 0, getTrxName()); + taxProvider.setC_TaxProviderCfg_ID(taxProviderCfg.get_ID()); + taxProvider.setName("Standard Provider"); + taxProvider.saveEx(); + ITaxProvider taxProviderService = Core.getTaxProvider(taxProvider); + assertNotNull(taxProviderService, "Can't find tax provider service"); + cacheKey = StandardTaxProvider.class.getName(); + cacheName = "ITaxProviderFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + taxProviderService = Core.getTaxProvider(taxProvider); + assertNotNull(taxProviderService, "Can't find tax provider service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IReplenishFactory + TestActivator.context.registerService(IReplenishFactory.class, new FakeReplenishFactory(), null); + cacheKey = FakeReplenishFactory.class.getName(); + ReplenishInterface replenishService = Core.getReplenish(cacheKey); + assertNotNull(replenishService, "Can't find replenish service"); + cacheName = "IReplenishFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + replenishService = Core.getReplenish(cacheKey); + assertNotNull(replenishService, "Can't find replenish service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //ScriptEngineFactory + TestActivator.context.registerService(ScriptEngineFactory.class, new FakeScriptEngineFactory(), null); + cacheKey = FakeScriptEngineFactory.class.getName(); + ScriptEngine scriptEngine = Core.getScriptEngine(cacheKey); + assertNotNull(scriptEngine, "Can't find script engine service"); + cacheName = "ScriptEngineFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + scriptEngine = Core.getScriptEngine(cacheKey); + assertNotNull(scriptEngine, "Can't find script engine service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IPaymentExporterFactory + TestActivator.context.registerService(IPaymentExporterFactory.class, new DefaultPaymentExporterFactory(), null); + cacheKey = GenericPaymentExport.class.getName(); + PaymentExport paymentExportService = Core.getPaymentExporter(cacheKey); + assertNotNull(paymentExportService, "Can't find payment exporter service"); + cacheName = "IPaymentExporterFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + paymentExportService = Core.getPaymentExporter(cacheKey); + assertNotNull(paymentExportService, "Can't find payment exporter service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IProductPricing + assertNotNull(Core.getProductPricing(), "Can't find product pricing service"); + //second call to check service reference cache is working + assertNotNull(Core.getProductPricing(), "Can't find product pricing service"); + + //IDepreciationMethodFactory + TestActivator.context.registerService(IDepreciationMethodFactory.class, new FakeDepreciationMethodFactory(), null); + cacheKey = FakeDepreciationMethodFactory.class.getName(); + DepreciationFactoryLookupDTO dto = new DepreciationFactoryLookupDTO(); + dto.depreciationType = cacheKey; + IDepreciationMethod depreciationMethod = Core.getDepreciationMethod(dto); + assertNotNull(depreciationMethod, "Can't find depreciation method service"); + cacheName = "IDepreciationMethodFactory"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + depreciationMethod = Core.getDepreciationMethod(dto); + assertNotNull(depreciationMethod, "Can't find depreciation method service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IMessageService + assertNotNull(Core.getMessageService(), "Can't find message service"); + //second call to check service reference cache is working + assertNotNull(Core.getMessageService(), "Can't find message service"); + + //IClusterService + assertNotNull(Core.getClusterService(), "Can't find cluster service"); + //second call to check service reference cache is working + assertNotNull(Core.getClusterService(), "Can't find cluster service"); + + //ICacheService + assertNotNull(Core.getCacheService(), "Can't find cache service"); + //second call to check service reference cache is working + assertNotNull(Core.getCacheService(), "Can't find cache service"); + + //IDictionaryService + assertNotNull(Core.getDictionaryService(), "Can't find dictionary service"); + //second call to check service reference cache is working + assertNotNull(Core.getDictionaryService(), "Can't find dictionary service"); + + //ILookupFactory + int ad_window_id=143; //sales order window + int ad_tab_id=187; //sales order line + int ad_field_id=1127; //product + GridFieldVO gridField = null; + Lookup lookup = null; + GridWindowVO gridWindow = GridWindowVO.create(1, ad_window_id); + Optional optional = gridWindow.Tabs.stream().filter(e -> e.AD_Tab_ID == ad_tab_id).findFirst(); + if (optional.isPresent()) { + GridTabVO gridTabVO = optional.get(); + Optional optional1 = gridTabVO.getFields().stream().filter(e -> e.AD_Field_ID == ad_field_id).findFirst(); + if (optional1.isPresent()) { + gridField = optional1.get(); + } + } + assertNotNull(gridField, "Can't find grid field"); + lookup = LookupFactoryHelper.getLookup(gridField); + assertNotNull(lookup, "Can't find lookup service"); + cacheName = "ILookupFactory"; + cacheKey = null; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + lookup = LookupFactoryHelper.getLookup(gridField); + assertNotNull(lookup, "Can't find lookup service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + hit = cache.getHit(); + assertTrue(LookupFactoryHelper.isLookup(gridField), "Lookup should be true for " + gridField.toString()); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IDocFactory + int C_AcctSchema_ID = MClientInfo.get().getC_AcctSchema1_ID(); + cacheKey = C_AcctSchema_ID + "|" + MInvoice.Table_ID; + cacheName = "IDocFactory"; + MInvoice invoice = new MInvoice(Env.getCtx(), 0, getTrxName()); + invoice.setBPartner(MBPartner.get(Env.getCtx(), 117)); // C&W + invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_ARInvoice); + invoice.setC_DocType_ID(invoice.getC_DocTypeTarget_ID()); // required to avoid runDocumentActionWorkflow exception + invoice.setPaymentRule(MInvoice.PAYMENTRULE_Check); + invoice.setC_PaymentTerm_ID(105); // Immediate + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + invoice.setDateInvoiced(today); + invoice.setDateAcct(today); + invoice.setDocStatus(DocAction.STATUS_Drafted); + invoice.setDocAction(DocAction.ACTION_Complete); + invoice.saveEx(); + MInvoiceLine line1 = new MInvoiceLine(invoice); + line1.setLine(10); + line1.setC_Charge_ID(100); // Bank Charge + line1.setQty(new BigDecimal("1")); + line1.setPrice(Env.ONEHUNDRED); + line1.saveEx(); + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete); + invoice.load(getTrxName()); + assertFalse(info.isError()); + assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus()); + if (!invoice.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), invoice.getAD_Client_ID(), MInvoice.Table_ID, invoice.get_ID(), true, getTrxName()); + assertNull(error, "Error posting invoice: " + error); + } + MAcctSchema as = MAcctSchema.get(C_AcctSchema_ID); + Doc doc = DocManager.getDocument(as, MInvoice.Table_ID, invoice.get_ID(), getTrxName()); + assertNotNull(doc, "Failed load acct doc for invoice"); + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + doc = DocManager.getDocument(as, MInvoice.Table_ID, invoice.get_ID(), getTrxName()); + assertNotNull(doc, "Failed load acct doc for invoice"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IDatabase + AdempiereDatabase db = Database.getDatabase(Database.DB_POSTGRESQL); + assertNotNull(db, "Failed to load db service for " + Database.DB_POSTGRESQL); + cacheKey = Database.DB_POSTGRESQL; + cacheName = "IDatabase"; + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + db = Database.getDatabase(Database.DB_POSTGRESQL); + assertNotNull(db, "Failed to load db service for " + Database.DB_POSTGRESQL); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IArchiveStore + ServiceQuery dbServiceQuery = new ServiceQuery(); + dbServiceQuery.put("method", "DB"); + IArchiveStore archiveStoreService = MStorageProvider.getArchiveStoreService(dbServiceQuery); + assertNotNull(archiveStoreService, "Can't find archive store service"); + cacheName = "IArchiveStore"; + cache = findByNameAndKey(cacheName, dbServiceQuery); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + archiveStoreService = MStorageProvider.getArchiveStoreService(dbServiceQuery); + assertNotNull(archiveStoreService, "Can't find archive store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + ServiceQuery fileSystemServiceQuery = new ServiceQuery(); + fileSystemServiceQuery.put("method", "FileSystem"); + archiveStoreService = MStorageProvider.getArchiveStoreService(fileSystemServiceQuery); + assertNotNull(archiveStoreService, "Can't find archive store service"); + hit = cache.getHit(); + archiveStoreService = MStorageProvider.getArchiveStoreService(fileSystemServiceQuery); + assertNotNull(archiveStoreService, "Can't find archive store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + assertTrue(cache.size() == 2, "Size for " + cacheName + " != 2"); + + //IAttachmentStore + IAttachmentStore attachmentStoreService = MStorageProvider.getAttachmentStoreService(dbServiceQuery); + assertNotNull(attachmentStoreService, "Can't find attachment store service"); + cacheName = "IAttachmentStore"; + cache = findByNameAndKey(cacheName, dbServiceQuery); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + attachmentStoreService = MStorageProvider.getAttachmentStoreService(dbServiceQuery); + assertNotNull(attachmentStoreService, "Can't find attachment store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + attachmentStoreService = MStorageProvider.getAttachmentStoreService(fileSystemServiceQuery); + assertNotNull(attachmentStoreService, "Can't find attachment store service"); + hit = cache.getHit(); + attachmentStoreService = MStorageProvider.getAttachmentStoreService(fileSystemServiceQuery); + assertNotNull(attachmentStoreService, "Can't find attachment store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + assertTrue(cache.size() == 2, "Size for " + cacheName + " != 2"); + + //IImageStore + IImageStore imagetStoreService = MStorageProvider.getImageStoreService(dbServiceQuery); + assertNotNull(imagetStoreService, "Can't find image store service"); + cacheName = "IImageStore"; + cache = findByNameAndKey(cacheName, dbServiceQuery); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + imagetStoreService = MStorageProvider.getImageStoreService(dbServiceQuery); + assertNotNull(imagetStoreService, "Can't find image store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + imagetStoreService = MStorageProvider.getImageStoreService(fileSystemServiceQuery); + assertNotNull(imagetStoreService, "Can't find image store service"); + hit = cache.getHit(); + imagetStoreService = MStorageProvider.getImageStoreService(fileSystemServiceQuery); + assertNotNull(imagetStoreService, "Can't find image store service"); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + assertTrue(cache.size() == 2, "Size for " + cacheName + " != 2"); + + //IModelFactory + cacheName = "IModelFactory"; + cacheKey = MInvoice.Table_Name; + Class modelClass = MTable.getClass(cacheKey); + assertNotNull(modelClass, "Can't find model class for " + cacheKey); + cache = findByNameAndKey(cacheName, cacheKey); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + modelClass = MTable.getClass(cacheKey); + assertNotNull(modelClass, "Can't find model class for " + cacheKey); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + + //IDisplayTypeFactory + TestActivator.context.registerService(IDisplayTypeFactory.class, new FakeDisplayTypeFactory(), null); + cacheName = "IDisplayTypeFactory"; + boolean isText = DisplayType.isText(FakeDisplayTypeFactory.DISPLAY_TYPE); + assertTrue(isText); + cache = findByNameAndKey(cacheName, FakeDisplayTypeFactory.DISPLAY_TYPE); + assertNotNull(cache, "Can't find cache for " + cacheName); + hit = cache.getHit(); + isText = DisplayType.isText(FakeDisplayTypeFactory.DISPLAY_TYPE); + assertTrue(isText); + assertTrue(cache.getHit() > hit, "Hit for " + cacheName + " doesn't increase as expected"); + } + + private CCache findByTableNameAndKey(String tableName, Object key) { + CacheInterface[] cis = CacheMgt.get().getInstancesAsArray(); + for(CacheInterface ci : cis) { + if (ci instanceof CCache) { + @SuppressWarnings("rawtypes") + CCache ccache = (CCache) ci; + if (ccache.getName().equals(ccache.getTableName()) && ccache.getTableName().equals(tableName)) { + if (ccache.containsKey(key)) { + return ccache; + } + } + } + } + return null; + } + + private CCache findByNameAndKey(String name, Object key) { + CacheInterface[] cis = CacheMgt.get().getInstancesAsArray(); + for(CacheInterface ci : cis) { + if (ci instanceof CCache) { + @SuppressWarnings("rawtypes") + CCache ccache = (CCache) ci; + if (ccache.getTableName() == null && ccache.getName().equals(name)) { + if (key != null) { + if (ccache.containsKey(key)) { + return ccache; + } + } else { + return ccache; + } + } + } + } + return null; + } } diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeAddressValidationFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeAddressValidationFactory.java new file mode 100644 index 0000000000..0d8debf150 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeAddressValidationFactory.java @@ -0,0 +1,58 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import java.util.Properties; + +import org.adempiere.base.IAddressValidationFactory; +import org.adempiere.model.IAddressValidation; +import org.compiere.model.MAddressTransaction; + +/** + * @author hengsin + * + */ +public class FakeAddressValidationFactory implements IAddressValidationFactory { + + /** + * + */ + public FakeAddressValidationFactory() { + } + + @Override + public IAddressValidation newAddressValidationInstance(String className) { + if (FakeAddressValidationFactory.class.getName().equals(className)) { + return new IAddressValidation() { + @Override + public boolean onlineValidate(Properties ctx, MAddressTransaction addressTransaction, String trxName) { + return false; + } + }; + } + return null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementLoaderFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementLoaderFactory.java new file mode 100644 index 0000000000..404092dee3 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementLoaderFactory.java @@ -0,0 +1,50 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import org.adempiere.base.IBankStatementLoaderFactory; +import org.compiere.impexp.BankStatementLoaderInterface; +import org.compiere.impexp.OFXFileBankStatementLoader; + +/** + * @author hengsin + * + */ +public class FakeBankStatementLoaderFactory implements IBankStatementLoaderFactory { + + /** + * + */ + public FakeBankStatementLoaderFactory() { + } + + @Override + public BankStatementLoaderInterface newBankStatementLoaderInstance(String className) { + if (OFXFileBankStatementLoader.class.getName().equals(className)) + return new OFXFileBankStatementLoader(); + return null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementMatcherFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementMatcherFactory.java new file mode 100644 index 0000000000..d7883bede6 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeBankStatementMatcherFactory.java @@ -0,0 +1,64 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import org.adempiere.base.IBankStatementMatcherFactory; +import org.compiere.impexp.BankStatementMatchInfo; +import org.compiere.impexp.BankStatementMatcherInterface; +import org.compiere.model.MBankStatementLine; +import org.compiere.model.X_I_BankStatement; + +/** + * @author hengsin + * + */ +public class FakeBankStatementMatcherFactory implements IBankStatementMatcherFactory { + + /** + * + */ + public FakeBankStatementMatcherFactory() { + } + + @Override + public BankStatementMatcherInterface newBankStatementMatcherInstance(String className) { + if (FakeBankStatementMatcherFactory.class.getName().equals(className)) { + return new BankStatementMatcherInterface() { + + @Override + public BankStatementMatchInfo findMatch(X_I_BankStatement ibs) { + return null; + } + + @Override + public BankStatementMatchInfo findMatch(MBankStatementLine bsl) { + return null; + } + }; + } + return null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeDepreciationMethodFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeDepreciationMethodFactory.java new file mode 100644 index 0000000000..c737a61c83 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeDepreciationMethodFactory.java @@ -0,0 +1,69 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import java.math.BigDecimal; + +import org.idempiere.fa.service.api.DepreciationDTO; +import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO; +import org.idempiere.fa.service.api.IDepreciationMethod; +import org.idempiere.fa.service.api.IDepreciationMethodFactory; + +/** + * + * @author hengsin + * + */ +public class FakeDepreciationMethodFactory implements IDepreciationMethodFactory { + + public FakeDepreciationMethodFactory() { + } + + @Override + public IDepreciationMethod getDepreciationMethod(DepreciationFactoryLookupDTO factoryLookupDTO) { + if (FakeDepreciationMethodFactory.class.getName().equals(factoryLookupDTO.depreciationType)) { + return new IDepreciationMethod() { + + @Override + public BigDecimal caclulateDepreciation(DepreciationDTO depreciationDTO) { + return null; + } + + @Override + public long getCountPeriod(DepreciationDTO depreciationDTO) { + return 0; + } + + @Override + public boolean isPeriodAdjustment() { + return false; + } + + }; + } + return null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeDisplayTypeFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeDisplayTypeFactory.java new file mode 100644 index 0000000000..06d3d6ba4e --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeDisplayTypeFactory.java @@ -0,0 +1,77 @@ +package org.idempiere.test.performance; + +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; + +import org.adempiere.base.IDisplayTypeFactory; +import org.compiere.util.Language; + +public class FakeDisplayTypeFactory implements IDisplayTypeFactory { + + public final static int DISPLAY_TYPE = 9876543; + + public FakeDisplayTypeFactory() { + } + + @Override + public boolean isID(int displayType) { + return false; + } + + @Override + public boolean isNumeric(int displayType) { + return false; + } + + @Override + public Integer getDefaultPrecision(int displayType) { + return null; + } + + @Override + public boolean isText(int displayType) { + if (displayType == DISPLAY_TYPE) + return true; + return false; + } + + @Override + public boolean isDate(int displayType) { + return false; + } + + @Override + public boolean isLookup(int displayType) { + return false; + } + + @Override + public boolean isLOB(int displayType) { + return false; + } + + @Override + public DecimalFormat getNumberFormat(int displayType, Language language, String pattern) { + return null; + } + + @Override + public SimpleDateFormat getDateFormat(int displayType, Language language, String pattern) { + return null; + } + + @Override + public Class getClass(int displayType, boolean yesNoAsBoolean) { + return null; + } + + @Override + public String getSQLDataType(int displayType, String columnName, int fieldLength) { + return null; + } + + @Override + public String getDescription(int displayType) { + return null; + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeReplenishFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeReplenishFactory.java new file mode 100644 index 0000000000..4449a43a03 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeReplenishFactory.java @@ -0,0 +1,58 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import java.math.BigDecimal; + +import org.adempiere.base.IReplenishFactory; +import org.compiere.model.MWarehouse; +import org.compiere.model.X_T_Replenish; +import org.compiere.util.ReplenishInterface; + +/** + * + * @author hengsin + * + */ +public class FakeReplenishFactory implements IReplenishFactory { + + public FakeReplenishFactory() { + } + + @Override + public ReplenishInterface newReplenishInstance(String className) { + if (FakeReplenishFactory.class.getName().equals(className)) { + return new ReplenishInterface() { + + @Override + public BigDecimal getQtyToOrder(MWarehouse wh, X_T_Replenish replenish) { + return null; + } + }; + } + return null; + } + +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeResourceFinder.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeResourceFinder.java new file mode 100644 index 0000000000..926e1bd562 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeResourceFinder.java @@ -0,0 +1,52 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.adempiere.base.IResourceFinder; + +/** + * + * @author hengsin + * + */ +public class FakeResourceFinder implements IResourceFinder { + + public FakeResourceFinder() { + } + + @Override + public URL getResource(String name) { + if (getClass().getName().equals(name)) { + try { + return new URL("file:///TestResourceFinder.txt"); + } catch (MalformedURLException e) { + } + } + return null; + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/performance/FakeScriptEngineFactory.java b/org.idempiere.test/src/org/idempiere/test/performance/FakeScriptEngineFactory.java new file mode 100644 index 0000000000..ab3dd579cc --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/performance/FakeScriptEngineFactory.java @@ -0,0 +1,174 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.performance; + +import java.io.Reader; +import java.util.Arrays; +import java.util.List; + +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptException; + +/** + * + * @author hengsin + * + */ +public class FakeScriptEngineFactory implements ScriptEngineFactory { + + public FakeScriptEngineFactory() { + } + + @Override + public String getEngineName() { + return null; + } + + @Override + public String getEngineVersion() { + return null; + } + + @Override + public List getExtensions() { + return null; + } + + @Override + public List getMimeTypes() { + return null; + } + + @Override + public List getNames() { + return Arrays.asList(FakeScriptEngineFactory.class.getName()); + } + + @Override + public String getLanguageName() { + return null; + } + + @Override + public String getLanguageVersion() { + return null; + } + + @Override + public Object getParameter(String key) { + return null; + } + + @Override + public String getMethodCallSyntax(String obj, String m, String... args) { + return null; + } + + @Override + public String getOutputStatement(String toDisplay) { + return null; + } + + @Override + public String getProgram(String... statements) { + return null; + } + + @Override + public ScriptEngine getScriptEngine() { + return new ScriptEngine() { + + @Override + public void setContext(ScriptContext context) { + } + + @Override + public void setBindings(Bindings bindings, int scope) { + } + + @Override + public void put(String key, Object value) { + } + + @Override + public ScriptEngineFactory getFactory() { + return null; + } + + @Override + public ScriptContext getContext() { + return null; + } + + @Override + public Bindings getBindings(int scope) { + return null; + } + + @Override + public Object get(String key) { + return null; + } + + @Override + public Object eval(Reader reader, Bindings n) throws ScriptException { + return null; + } + + @Override + public Object eval(String script, Bindings n) throws ScriptException { + return null; + } + + @Override + public Object eval(Reader reader, ScriptContext context) throws ScriptException { + return null; + } + + @Override + public Object eval(String script, ScriptContext context) throws ScriptException { + return null; + } + + @Override + public Object eval(Reader reader) throws ScriptException { + return null; + } + + @Override + public Object eval(String script) throws ScriptException { + return null; + } + + @Override + public Bindings createBindings() { + return null; + } + }; + } +}