IDEMPIERE-359 Add OSGi Service support for existing extension point

This commit is contained in:
Heng Sin Low 2012-11-06 11:39:23 +08:00
parent b4fa3b4c34
commit 2dfa60b73e
52 changed files with 945 additions and 266 deletions

View File

@ -279,7 +279,9 @@ Import-Package: com.sun.mail.auth;version="1.4.5",
org.eclipse.osgi.framework.console;version="1.1.0", org.eclipse.osgi.framework.console;version="1.1.0",
org.eclipse.osgi.service.datalocation, org.eclipse.osgi.service.datalocation,
org.osgi.framework, org.osgi.framework,
org.osgi.service.component;version="1.1.0",
org.osgi.service.event;version="1.2.0", org.osgi.service.event;version="1.2.0",
org.osgi.util.tracker;version="1.5.0",
org.restlet, org.restlet,
org.restlet.data, org.restlet.data,
org.restlet.representation, org.restlet.representation,
@ -287,6 +289,6 @@ Import-Package: com.sun.mail.auth;version="1.4.5",
Eclipse-BuddyPolicy: registered Eclipse-BuddyPolicy: registered
Eclipse-ExtensibleAPI: true Eclipse-ExtensibleAPI: true
Bundle-Activator: org.adempiere.base.BaseActivator Bundle-Activator: org.adempiere.base.BaseActivator
Service-Component: OSGI-INF/eventmanager.xml Service-Component: OSGI-INF/eventmanager.xml, OSGI-INF/dslocator.xml, OSGI-INF/extensionlocator.xml, OSGI-INF/serverbean.xml, OSGI-INF/statusbean.xml
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Require-Bundle: org.eclipse.equinox.app;bundle-version="1.3.1" Require-Bundle: org.eclipse.equinox.app;bundle-version="1.3.1"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.ds.locator">
<property name="service.ranking" type="Integer" value="1"/>
<service>
<provide interface="org.adempiere.base.IServiceLocator"/>
</service>
<implementation class="org.adempiere.base.ds.DynamicServiceLocator"/>
</scr:component>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.equinox.service.locator">
<property name="service.ranking" type="Integer" value="0"/>
<service>
<provide interface="org.adempiere.base.IServiceLocator"/>
</service>
<implementation class="org.adempiere.base.equinox.EquinoxServiceLocator"/>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.interfaces.server">
<implementation class="org.compiere.interfaces.impl.ServerBean"/>
<service>
<provide interface="org.compiere.interfaces.Server"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.interfaces.status">
<implementation class="org.compiere.interfaces.impl.StatusBean"/>
<service>
<provide interface="org.compiere.interfaces.Status"/>
</service>
</scr:component>

View File

@ -16,7 +16,11 @@ bin.includes = META-INF/,\
groovy-all-1.7.5.jar,\ groovy-all-1.7.5.jar,\
vt-dictionary-3.0.jar,\ vt-dictionary-3.0.jar,\
vt-password-3.1.1.jar,\ vt-password-3.1.1.jar,\
super-csv-2.0.0-beta-1.jar super-csv-2.0.0-beta-1.jar,\
OSGI-INF/dslocator.xml,\
OSGI-INF/extensionlocator.xml,\
OSGI-INF/serverbean.xml,\
OSGI-INF/statusbean.xml
output.base.jar = build/ output.base.jar = build/
source.base.jar = src/
src.includes = schema/ src.includes = schema/
source.base.jar = src/

View File

@ -23,6 +23,8 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.adempiere.base.equinox.StackTraceCommand; import org.adempiere.base.equinox.StackTraceCommand;
@ -30,6 +32,8 @@ import org.compiere.Adempiere;
import org.eclipse.osgi.framework.console.CommandProvider; import org.eclipse.osgi.framework.console.CommandProvider;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.util.tracker.ServiceTracker;
/** /**
* @author hengsin * @author hengsin
@ -102,10 +106,55 @@ public class BaseActivator implements BundleActivator {
@Override @Override
public void stop(BundleContext context) throws Exception { public void stop(BundleContext context) throws Exception {
bundleContext = null; bundleContext = null;
for(Map<String, ServiceTracker<?,?>> cacheMap : trackerCache.values()) {
for(ServiceTracker<?,?> cacheTracker : cacheMap.values()) {
if (cacheTracker.getTrackingCount() != -1) {
cacheTracker.close();
}
}
}
trackerCache.clear();
Adempiere.stop(); Adempiere.stop();
} }
/**
* @return bundle context
*/
public static BundleContext getBundleContext() { public static BundleContext getBundleContext() {
return bundleContext; return bundleContext;
} }
private static Map<String, Map<String, ServiceTracker<?,?>>> trackerCache = new HashMap<String, Map<String,ServiceTracker<?,?>>>();
@SuppressWarnings("unchecked")
/**
* @param type
* @param filter
* @return service tracker
*/
public static <T> ServiceTracker<T, T> getServiceTracker(Class<T> type, Filter filter) {
ServiceTracker<T, T> tracker = null;
String className = type.getName();
Map<String, ServiceTracker<?,?>> cacheMap = null;
synchronized (trackerCache) {
cacheMap = trackerCache.get(className);
if (cacheMap == null) {
cacheMap = new HashMap<String, ServiceTracker<?,?>>();
trackerCache.put(className, cacheMap);
}
}
String filterKey = filter.toString();
synchronized (cacheMap) {
ServiceTracker<?, ?> cacheTracker = cacheMap.get(filterKey);
if (cacheTracker == null) {
tracker = new ServiceTracker<T, T>(bundleContext, filter, null);
cacheMap.put(filterKey, tracker);
} else {
tracker = (ServiceTracker<T, T>) cacheTracker;
}
}
return tracker;
}
} }

View File

@ -49,7 +49,7 @@ public class Core {
return new IResourceFinder() { return new IResourceFinder() {
public URL getResource(String name) { public URL getResource(String name) {
List<IResourceFinder> f = Service.list(IResourceFinder.class); List<IResourceFinder> f = Service.locator().list(IResourceFinder.class).getServices();
for (IResourceFinder finder : f) { for (IResourceFinder finder : f) {
URL url = finder.getResource(name); URL url = finder.getResource(name);
if (url!=null) if (url!=null)
@ -71,39 +71,37 @@ public class Core {
query.put("tableName", tableName); query.put("tableName", tableName);
query.put("columnName", columnName); query.put("columnName", columnName);
return Service.list(IColumnCallout.class, query); return Service.locator().list(IColumnCallout.class, query).getServices();
} }
/** /**
* *
* @param extensionId * @param serviceId
* @return ProcessCall instance or null if extensionId not found * @return ProcessCall instance or null if serviceId not found
*/ */
public static ProcessCall getProcess(String extensionId) { public static ProcessCall getProcess(String serviceId) {
ServiceQuery query = new ServiceQuery(); return Service.locator().locate(ProcessCall.class, "org.adempiere.base.Process", serviceId, null).getService();
query.put(ServiceQuery.EXTENSION_ID, extensionId);
return Service.locate(ProcessCall.class, "org.adempiere.base.Process", query);
} }
/** /**
* *
* @param extensionId * @param serviceId
* @return ModelValidator instance of null if extensionId not found * @return ModelValidator instance of null if serviceId not found
*/ */
public static ModelValidator getModelValidator(String extensionId) { public static ModelValidator getModelValidator(String serviceId) {
ServiceQuery query = new ServiceQuery(); return Service.locator().locate(ModelValidator.class, "org.adempiere.base.ModelValidator", serviceId, null).getService();
query.put(ServiceQuery.EXTENSION_ID, extensionId);
return Service.locate(ModelValidator.class, "org.adempiere.base.ModelValidator", query);
} }
/** /**
* Factory * Get payment processor instance
* @param mpp payment processor model * @param mpp payment processor model
* @param mp payment model * @param mp payment model
* @return initialized PaymentProcessor or null * @return initialized PaymentProcessor or null
*/ */
public static PaymentProcessor getPaymentProcessor(MPaymentProcessor mpp, PaymentInterface mp) { public static PaymentProcessor getPaymentProcessor(MPaymentProcessor mpp, PaymentInterface mp) {
s_log.info("create for " + mpp); if (s_log.isLoggable(Level.FINE))
s_log.fine("create for " + mpp);
String className = mpp.getPayProcessorClass(); String className = mpp.getPayProcessorClass();
if (className == null || className.length() == 0) { if (className == null || className.length() == 0) {
s_log.log(Level.SEVERE, "No PaymentProcessor class name in " + mpp); s_log.log(Level.SEVERE, "No PaymentProcessor class name in " + mpp);
@ -111,10 +109,9 @@ public class Core {
} }
// //
PaymentProcessor myProcessor = null; PaymentProcessor myProcessor = null;
ServiceQuery query = new ServiceQuery(); myProcessor = Service.locator().locate(PaymentProcessor.class, className, null).getService();
query.put(ServiceQuery.EXTENSION_ID, className);
myProcessor = Service.locate(PaymentProcessor.class, query);
if (myProcessor == null) { if (myProcessor == null) {
//fall back to dynamic java class loadup
try { try {
Class<?> ppClass = Class.forName(className); Class<?> ppClass = Class.forName(className);
if (ppClass != null) if (ppClass != null)
@ -128,7 +125,7 @@ public class Core {
} }
} }
if (myProcessor == null) { if (myProcessor == null) {
s_log.log(Level.SEVERE, "Not found in extension registry and classpath"); s_log.log(Level.SEVERE, "Not found in service/extension registry and classpath");
return null; return null;
} }

View File

@ -0,0 +1,64 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base;
import java.util.ArrayList;
import java.util.List;
/**
* @author hengsin
*
*/
public class DelegatingServiceHolder<T> implements IServiceHolder<T>,
IServicesHolder<T> {
private List<IServiceHolder<T>> serviceHolder = new ArrayList<IServiceHolder<T>>();
private List<IServicesHolder<T>> servicesHolder = new ArrayList<IServicesHolder<T>>();
/**
*
*/
public DelegatingServiceHolder() {
}
public void addServiceHolder(IServiceHolder<T> holder) {
serviceHolder.add(holder);
}
public void addServicesHolder(IServicesHolder<T> holder) {
servicesHolder.add(holder);
}
@Override
public List<T> getServices() {
List<T> list = new ArrayList<T>();
for(IServicesHolder<T> holder : servicesHolder) {
List<T> t = holder.getServices();
if (t != null && !t.isEmpty())
list.addAll(t);
}
return list;
}
@Override
public T getService() {
T t = null;
for(IServiceHolder<T> holder : serviceHolder) {
t = holder.getService();
if (t != null) break;
}
return t;
}
}

View File

@ -0,0 +1,181 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base;
import java.util.List;
import org.adempiere.base.ds.DynamicServiceLocator;
/**
* Delegate to available service locator
* @author hengsin
*
*/
public class DelegatingServiceLocator implements IServiceLocator {
private IServicesHolder<IServiceLocator> locatorsHolder;
public DelegatingServiceLocator() {
DynamicServiceLocator serviceLocator = new DynamicServiceLocator();
locatorsHolder = serviceLocator.list(IServiceLocator.class);
}
private IServiceLocator[] getLocators() {
List<IServiceLocator> locators = locatorsHolder.getServices();
return locators.toArray(new IServiceLocator[0]);
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServiceHolder<T> t = locator.locate(type);
if (t != null)
holder.addServiceHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceType) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServiceHolder<T> t = locator.locate(type, serviceType);
if (t != null)
holder.addServiceHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServiceHolder<T> t = locator.locate(type, query);
if (t != null)
holder.addServiceHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceId, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServiceHolder<T> t = locator.locate(type, serviceId, query);
if (t != null)
holder.addServiceHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceType,
String serviceId, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServiceHolder<T> t = locator.locate(type, serviceType, serviceId, query);
if (t != null)
holder.addServiceHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServicesHolder<T> t = locator.list(type);
if (t != null)
holder.addServicesHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceType) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServicesHolder<T> t = locator.list(type, serviceType);
if (t != null)
holder.addServicesHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServicesHolder<T> t = locator.list(type, query);
if (t != null)
holder.addServicesHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceId, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServicesHolder<T> t = locator.list(type, serviceId, query);
if (t != null)
holder.addServicesHolder(t);
}
return holder;
}
/* (non-Javadoc)
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceType,
String serviceId, ServiceQuery query) {
DelegatingServiceHolder<T> holder = new DelegatingServiceHolder<T>();
for(IServiceLocator locator : getLocators()) {
IServicesHolder<T> t = locator.list(type, serviceType, serviceId, query);
if (t != null)
holder.addServicesHolder(t);
}
return holder;
}
}

View File

@ -0,0 +1,30 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base;
/**
*
* @author hengsin
*
* @param <T>
*/
public interface IServiceHolder<T> {
/**
*
* @return service instance. null if not available or no matching service found
*/
public T getService();
}

View File

@ -16,25 +16,99 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.base; package org.adempiere.base;
import java.util.List;
/** /**
* A service locator looks up services. * A service locator looks up services.
* This is the central authority for adempiere service definition, * This is the central authority for adempiere service definition,
* because each service defined has to be looked up via this interface. * because each service defined has to be looked up via this interface.
* *
* A service in adempiere is an interface extended from the tagging interface IService. * A service in adempiere is an implementation for the registered interface, expose through osgi service registry or equinox extension registry
* *
* @author viola * @author viola
* *
*/ */
public interface IServiceLocator { public interface IServiceLocator {
<T> T locate(Class<T> type); /**
<T> T locate(Class<T> type, String extensionPointId); *
<T> T locate(Class<T> type, ServiceQuery query); * @param type service interface
<T> T locate(Class<T> type, String extensionPointId, ServiceQuery query); * @return holder for dynamic service
<T> List<T> list(Class<T> type); */
<T> List<T> list(Class<T> type, String extensionPointId); <T> IServiceHolder<T> locate(Class<T> type);
<T> List<T> list(Class<T> type, ServiceQuery query);
<T> List<T> list(Class<T> type, String extensionPointId, ServiceQuery query); /**
*
* @param type
* @param serviceType equinox extension point id, ignore by osgi service locator
* type.getName
* @return holder for dynamic service
*/
<T> IServiceHolder<T> locate(Class<T> type, String serviceType);
/**
*
* @param type
* @param query
* @return
*/
<T> IServiceHolder<T> locate(Class<T> type, ServiceQuery query);
/**
*
* @param type
* @param serviceId component name or extension id
* @param query
* @return holder for dynamic service
*/
<T> IServiceHolder<T> locate(Class<T> type, String serviceId, ServiceQuery query);
/**
*
* @param type
* @param serviceType equinox extension point id, ignore by osgi service locator
* @param serviceId component name or extension id
* @param query
* @return holder for dynamic service
*/
<T> IServiceHolder<T> locate(Class<T> type, String serviceType, String serviceId, ServiceQuery query);
/**
*
* @param type
* @return holder for list of dynamic service
*/
<T> IServicesHolder<T> list(Class<T> type);
/**
*
* @param type
* @param serviceType equinox extension point id, ignore by osgi service locator
* @return holder for list of dynamic service
*/
<T> IServicesHolder<T> list(Class<T> type, String serviceType);
/**
*
* @param type
* @param query
* @return holder for list of dynamic service
*/
<T> IServicesHolder<T> list(Class<T> type, ServiceQuery query);
/**
*
* @param type
* @param serviceId component name or extension id
* @param query
* @return holder for list of dynamic service
*/
<T> IServicesHolder<T> list(Class<T> type, String serviceId, ServiceQuery query);
/**
*
* @param type
* @param serviceType equinox extension point id, ignore by osgi service locator
* @param serviceId component name or extension id
* @param query
* @return holder for list of dynamic service
*/
<T> IServicesHolder<T> list(Class<T> type, String serviceType, String serviceId, ServiceQuery query);
} }

View File

@ -0,0 +1,32 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base;
import java.util.List;
/**
*
* @author hengsin
*
* @param <T>
*/
public interface IServicesHolder<T> {
/**
*
* @return list of service instance. null if not available or no matching service found
*/
public List<T> getServices();
}

View File

@ -16,8 +16,6 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.base; package org.adempiere.base;
import java.util.List;
/** /**
* This is a very simple factory for service locators * This is a very simple factory for service locators
* *
@ -26,66 +24,13 @@ import java.util.List;
*/ */
public class Service { public class Service {
private static final String LOCATOR_CLASS = "ServiceLocator"; private static IServiceLocator theLocator = new DelegatingServiceLocator();
private static final String DEFAULT_LOCATOR_CLASS = "org.adempiere.base.equinox.EquinoxServiceLocator";
private static IServiceLocator theLocator;
/**
*
* @return service locator instance
*/
public static IServiceLocator locator() { public static IServiceLocator locator() {
if (theLocator == null) {
synchronized (Service.class) {
if (theLocator == null) {
theLocator = createServiceLocator();
}
}
}
return theLocator; return theLocator;
} }
private static IServiceLocator createServiceLocator() {
String className = System.getProperty(LOCATOR_CLASS);
if (className==null)
className = DEFAULT_LOCATOR_CLASS;
try {
Class<?> clazz = Class.forName(className);
IServiceLocator locator = (IServiceLocator) clazz.newInstance();
System.out.println("Started service locator: " + locator);
return locator;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static <T> T locate(Class<T> type) {
return locate(type, type.getName());
}
public static <T> T locate(Class<T> type, String id) {
return locator().locate(type, id);
}
public static <T> T locate(Class<T> type, ServiceQuery query) {
return locate(type, type.getName(), query);
}
public static <T> T locate(Class<T> type, String id, ServiceQuery query) {
return locator().locate(type, id, query);
}
public static <T> List<T> list(Class<T> type) {
return list(type, type.getName());
}
public static <T> List<T> list(Class<T> type, String id) {
return locator().list(type, id);
}
public static <T> List<T> list(Class<T> type, ServiceQuery query) {
return locator().list(type, type.getName(), query);
}
public static <T> List<T> list(Class<T> type, String id, ServiceQuery query) {
return locator().list(type, id, query);
}
} }

View File

@ -1,10 +1,13 @@
package org.adempiere.base; package org.adempiere.base;
import java.util.HashMap; import java.util.LinkedHashMap;
public class ServiceQuery extends HashMap<String, String> { /**
* A sequence of name value pair filter
* @author hengsin
*
*/
public class ServiceQuery extends LinkedHashMap<String, String> {
private static final long serialVersionUID = -3624488575106821781L; private static final long serialVersionUID = -3624488575106821781L;
public static final String EXTENSION_ID = "Extension.ID";
} }

View File

@ -0,0 +1,63 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base.ds;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.adempiere.base.IServiceHolder;
import org.adempiere.base.IServicesHolder;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
/**
* @author hengsin
*
*/
public class DynamicServiceHolder<T> implements IServiceHolder<T>, IServicesHolder<T> {
private ServiceTracker<T, T> serviceTracker;
/**
* @param tracker
*/
public DynamicServiceHolder(ServiceTracker<T, T> tracker) {
serviceTracker = tracker;
if (serviceTracker.getTrackingCount() == -1)
serviceTracker.open();
}
@Override
public T getService() {
T service = serviceTracker.getService();
return service;
}
@Override
public List<T> getServices() {
List<T> services = new ArrayList<T>();
ServiceReference<T>[] objects = serviceTracker.getServiceReferences();
List<ServiceReference<T>> references = new ArrayList<ServiceReference<T>>();
if (objects != null && objects.length > 0) {
references = Arrays.asList(objects);
}
Collections.sort(references, Collections.reverseOrder());
for(ServiceReference<T> reference : references) {
services.add(serviceTracker.getService(reference));
}
return services;
}
}

View File

@ -0,0 +1,166 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base.ds;
import org.adempiere.base.BaseActivator;
import org.adempiere.base.IServiceHolder;
import org.adempiere.base.IServiceLocator;
import org.adempiere.base.IServicesHolder;
import org.adempiere.base.ServiceQuery;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.component.ComponentConstants;
import org.osgi.util.tracker.ServiceTracker;
/**
* @author hengsin
*
*/
public class DynamicServiceLocator implements IServiceLocator {
/**
*
*/
public DynamicServiceLocator() {
}
/**
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type) {
Filter filter = filter(type, null, null);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceType) {
return locate(type);
}
/**
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, ServiceQuery query) {
if (query == null || query.isEmpty())
return locate(type);
Filter filter = filter(type, null, query);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceId, ServiceQuery query) {
if ((query == null || query.isEmpty()) && (serviceId == null || serviceId.trim().length() == 0))
return locate(type);
Filter filter = filter(type, serviceId, query);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#locate(java.lang.Class, java.lang.String, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceType, String serviceId,
ServiceQuery query) {
return locate(type, serviceId, query);
}
/**
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type) {
Filter filter = filter(type, null, null);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceType) {
return list(type);
}
/**
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, ServiceQuery query) {
if (query == null || query.isEmpty())
return list(type);
Filter filter = filter(type, null, query);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceId, ServiceQuery query) {
if ((query == null || query.isEmpty()) && (serviceId == null || serviceId.trim().length() == 0))
return list(type);
Filter filter = filter(type, serviceId, query);
ServiceTracker<T, T> tracker = BaseActivator.getServiceTracker(type, filter);
return new DynamicServiceHolder<T>(tracker);
}
/**
* @see org.adempiere.base.IServiceLocator#list(java.lang.Class, java.lang.String, java.lang.String, org.adempiere.base.ServiceQuery)
*/
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceType,
String serviceId, ServiceQuery query) {
return list(type, serviceId, query);
}
private Filter filter(Class<?> type, String serviceId, ServiceQuery query) {
StringBuilder builder = new StringBuilder("(&(objectclass=");
builder.append(type.getName()).append(")");
if (query != null) {
for(String key : query.keySet()) {
String value = query.get(key);
builder.append("(").append(key).append("=").append(value).append(")");
}
}
if (serviceId != null && serviceId.trim().length() > 0) {
builder.append("(").append(ComponentConstants.COMPONENT_NAME).append("=").append(serviceId.trim()).append(")");
}
builder.append(")");
try {
return BaseActivator.getBundleContext().createFilter(builder.toString());
} catch (InvalidSyntaxException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,46 @@
/******************************************************************************
* Copyright (C) 2012 Heng Sin Low *
* Copyright (C) 2012 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.base.equinox;
import java.util.List;
import org.adempiere.base.IServiceHolder;
import org.adempiere.base.IServicesHolder;
/**
* @author hengsin
*
*/
public class EquinoxServiceHolder<T> implements IServiceHolder<T>, IServicesHolder<T> {
private ExtensionList<T> extensionList;
/**
* @param list
*/
public EquinoxServiceHolder(ExtensionList<T> list) {
extensionList = list;
}
@Override
public T getService() {
return extensionList.first();
}
@Override
public List<T> getServices() {
return extensionList.asList();
}
}

View File

@ -16,9 +16,9 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.base.equinox; package org.adempiere.base.equinox;
import java.util.List; import org.adempiere.base.IServiceHolder;
import org.adempiere.base.IServiceLocator; import org.adempiere.base.IServiceLocator;
import org.adempiere.base.IServicesHolder;
import org.adempiere.base.ServiceQuery; import org.adempiere.base.ServiceQuery;
@ -32,44 +32,60 @@ import org.adempiere.base.ServiceQuery;
*/ */
public class EquinoxServiceLocator implements IServiceLocator { public class EquinoxServiceLocator implements IServiceLocator {
public <T> List<T> list(Class<T> type) { @Override
public <T> IServicesHolder<T> list(Class<T> type) {
return list(type, type.getName()); return list(type, type.getName());
} }
@Override @Override
public <T> List<T> list(Class<T> type, String extensionPointId) { public <T> IServicesHolder<T> list(Class<T> type, String serviceType) {
ExtensionList<T> list = new ExtensionList<T>(type, extensionPointId); ExtensionList<T> list = new ExtensionList<T>(type, serviceType);
return list.asList(); return new EquinoxServiceHolder<T>(list);
} }
public <T> List<T> list(Class<T> type, ServiceQuery query) { @Override
return list(type, type.getName(), query); public <T> IServicesHolder<T> list(Class<T> type, ServiceQuery query) {
return list(type, type.getName(), null, query);
} }
@Override @Override
public <T> List<T> list(Class<T> type, String extensionPointId, public <T> IServicesHolder<T> list(Class<T> type, String serviceId, ServiceQuery query) {
ExtensionList<T> list = new ExtensionList<T>(type, null, serviceId, query);
return new EquinoxServiceHolder<T>(list);
}
@Override
public <T> IServicesHolder<T> list(Class<T> type, String serviceType, String serviceId,
ServiceQuery query) { ServiceQuery query) {
ExtensionList<T> list = new ExtensionList<T>(type, extensionPointId, query); ExtensionList<T> list = new ExtensionList<T>(type, serviceType, serviceId, query);
return list.asList(); return new EquinoxServiceHolder<T>(list);
} }
public <T> T locate(Class<T> type) { @Override
public <T> IServiceHolder<T> locate(Class<T> type) {
return locate(type, type.getName()); return locate(type, type.getName());
} }
@Override @Override
public <T> T locate(Class<T> type, String extensionPointId) { public <T> IServiceHolder<T> locate(Class<T> type, String serviceType) {
ExtensionList<T> list = new ExtensionList<T>(type, extensionPointId); ExtensionList<T> list = new ExtensionList<T>(type, serviceType);
return list.first(); return new EquinoxServiceHolder<T>(list);
} }
public <T> T locate(Class<T> type, ServiceQuery query) { @Override
return locate(type, type.getName(), query); public <T> IServiceHolder<T> locate(Class<T> type, ServiceQuery query) {
return locate(type, type.getName(), null, query);
} }
@Override @Override
public <T> T locate(Class<T> type, String extensionPointId, ServiceQuery query) { public <T> IServiceHolder<T> locate(Class<T> type, String serviceId, ServiceQuery query) {
ExtensionList<T> list = new ExtensionList<T>(type, extensionPointId, query); ExtensionList<T> list = new ExtensionList<T>(type, null, serviceId, query);
return list.first(); return new EquinoxServiceHolder<T>(list);
}
@Override
public <T> IServiceHolder<T> locate(Class<T> type, String serviceType, String serviceId, ServiceQuery query) {
ExtensionList<T> list = new ExtensionList<T>(type, serviceType, serviceId, query);
return new EquinoxServiceHolder<T>(list);
} }
} }

View File

@ -41,7 +41,7 @@ import org.eclipse.core.runtime.Platform;
*/ */
public class ExtensionList<T> implements Iterable<T>{ public class ExtensionList<T> implements Iterable<T>{
public class ExtensionIterator<T> implements Iterator<T> { public class ExtensionIterator<E extends T> implements Iterator<T> {
private int index = 0; private int index = 0;
@ -59,23 +59,22 @@ public class ExtensionList<T> implements Iterable<T>{
} }
private boolean accept(IConfigurationElement element) { private boolean accept(IConfigurationElement element) {
if (extensionId != null) {
String id = element.getDeclaringExtension().getUniqueIdentifier();
if (!extensionId.equals(id))
return false;
}
for (String name : filters.keySet()) { for (String name : filters.keySet()) {
String expected = filters.get(name); String expected = filters.get(name);
if (name.equals(ServiceQuery.EXTENSION_ID)) { String actual = element.getAttribute(name);
String id = element.getDeclaringExtension().getUniqueIdentifier(); if (!expected.equals(actual))
if (!expected.equals(id)) return false;
return false;
} else {
String actual = element.getAttribute(name);
if (!expected.equals(actual))
return false;
}
} }
return true; return true;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T next() { public E next() {
iterateUntilAccepted(); iterateUntilAccepted();
IConfigurationElement e = elements[index++]; IConfigurationElement e = elements[index++];
if (e.getAttribute("class") == null) { if (e.getAttribute("class") == null) {
@ -90,7 +89,7 @@ public class ExtensionList<T> implements Iterable<T>{
} }
} }
try { try {
return (T) e.createExecutableExtension("class"); return (E) e.createExecutableExtension("class");
} catch (CoreException ex) { } catch (CoreException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@ -104,8 +103,16 @@ public class ExtensionList<T> implements Iterable<T>{
private IConfigurationElement[] elements; private IConfigurationElement[] elements;
private HashMap<String, String> filters = new HashMap<String, String>(); private HashMap<String, String> filters = new HashMap<String, String>();
private String extensionId;
/**
* @param clazz
* @param extensionPointId
*/
public ExtensionList(Class<T> clazz, String extensionPointId) { public ExtensionList(Class<T> clazz, String extensionPointId) {
if (extensionPointId == null)
extensionPointId = clazz.getName();
try { try {
elements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointId); elements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointId);
if (elements != null && elements.length > 1) { if (elements != null && elements.length > 1) {
@ -116,6 +123,16 @@ public class ExtensionList<T> implements Iterable<T>{
} }
} }
public ExtensionList(Class<T> type, String extensionPointId, String extensionId, ServiceQuery query) {
this(type, extensionPointId);
this.extensionId = extensionId;
if (query != null) {
for (String key : query.keySet()) {
addFilter(key, query.get(key));
}
}
}
private IConfigurationElement[] sort(IConfigurationElement[] elementArray) { private IConfigurationElement[] sort(IConfigurationElement[] elementArray) {
IConfigurationElement[] result = elementArray; IConfigurationElement[] result = elementArray;
TreeMap<Integer, List<IConfigurationElement>> elementMap = new TreeMap<Integer, List<IConfigurationElement>>(); TreeMap<Integer, List<IConfigurationElement>> elementMap = new TreeMap<Integer, List<IConfigurationElement>>();
@ -152,13 +169,6 @@ public class ExtensionList<T> implements Iterable<T>{
return result; return result;
} }
public ExtensionList(Class<T> type, String extensionPointId, ServiceQuery query) {
this(type, extensionPointId);
for (String key : query.keySet()) {
addFilter(key, query.get(key));
}
}
public Iterator<T> iterator() { public Iterator<T> iterator() {
return new ExtensionIterator<T>(); return new ExtensionIterator<T>();
} }

View File

@ -135,7 +135,7 @@ public class DocManager {
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("gaap", as.getGAAP()); query.put("gaap", as.getGAAP());
List<IDocFactory> factoryList = Service.list(IDocFactory.class, query); List<IDocFactory> factoryList = Service.locator().list(IDocFactory.class, query).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IDocFactory factory : factoryList) for(IDocFactory factory : factoryList)
@ -148,7 +148,7 @@ public class DocManager {
query.clear(); query.clear();
query.put("gaap", "*"); query.put("gaap", "*");
factoryList = Service.list(IDocFactory.class, query); factoryList = Service.locator().list(IDocFactory.class, query).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IDocFactory factory : factoryList) for(IDocFactory factory : factoryList)
@ -175,7 +175,7 @@ public class DocManager {
{ {
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("gaap", as.getGAAP()); query.put("gaap", as.getGAAP());
List<IDocFactory> factoryList = Service.list(IDocFactory.class,query); List<IDocFactory> factoryList = Service.locator().list(IDocFactory.class,query).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IDocFactory factory : factoryList) for(IDocFactory factory : factoryList)
@ -188,7 +188,7 @@ public class DocManager {
query.clear(); query.clear();
query.put("gaap", "*"); query.put("gaap", "*");
factoryList = Service.list(IDocFactory.class,query); factoryList = Service.locator().list(IDocFactory.class,query).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IDocFactory factory : factoryList) for(IDocFactory factory : factoryList)

View File

@ -379,7 +379,7 @@ public class CConnection implements Serializable, Cloneable
try try
{ {
Status status = Service.locate(Status.class); Status status = Service.locator().locate(Status.class).getService();
m_version = status.getDateVersion(); m_version = status.getDateVersion();
} }
catch (Throwable t) catch (Throwable t)
@ -408,7 +408,7 @@ public class CConnection implements Serializable, Cloneable
{ {
if (m_server == null) if (m_server == null)
{ {
m_server = Service.locate(Server.class); m_server = Service.locator().locate(Server.class).getService();
} }
return m_server; return m_server;
} // getServer } // getServer
@ -1400,7 +1400,7 @@ public class CConnection implements Serializable, Cloneable
return m_okApps; // false return m_okApps; // false
} }
Status status = Service.locate(Status.class); Status status = Service.locator().locate(Status.class).getService();
try { try {
updateInfoFromServer(status); updateInfoFromServer(status);
m_okApps = true; m_okApps = true;

View File

@ -60,7 +60,7 @@ public class Database
{ {
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("id", type); query.put("id", type);
AdempiereDatabase db = Service.locate(AdempiereDatabase.class, query); AdempiereDatabase db = Service.locator().locate(AdempiereDatabase.class, query).getService();
return db; return db;
} }

View File

@ -2886,7 +2886,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
String className = cmd.substring(0,methodStart); String className = cmd.substring(0,methodStart);
//first, check matching extension id in extension registry //first, check matching extension id in extension registry
call = Service.locate(Callout.class, className); call = Service.locator().locate(Callout.class, className).getService();
if (call == null) { if (call == null) {
//no match from extension registry, check java classpath //no match from extension registry, check java classpath
Class<?> cClass = Class.forName(className); Class<?> cClass = Class.forName(className);

View File

@ -163,7 +163,7 @@ public class MTable extends X_AD_Table
*/ */
public static Class<?> getClass (String tableName) public static Class<?> getClass (String tableName)
{ {
List<IModelFactory> factoryList = Service.list(IModelFactory.class); List<IModelFactory> factoryList = Service.locator().list(IModelFactory.class).getServices();
if (factoryList == null) if (factoryList == null)
return null; return null;
for(IModelFactory factory : factoryList) { for(IModelFactory factory : factoryList) {
@ -322,7 +322,7 @@ public class MTable extends X_AD_Table
} }
PO po = null; PO po = null;
List<IModelFactory> factoryList = Service.list(IModelFactory.class); List<IModelFactory> factoryList = Service.locator().list(IModelFactory.class).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IModelFactory factory : factoryList) for(IModelFactory factory : factoryList)
@ -359,7 +359,7 @@ public class MTable extends X_AD_Table
String tableName = getTableName(); String tableName = getTableName();
PO po = null; PO po = null;
List<IModelFactory> factoryList = Service.list(IModelFactory.class); List<IModelFactory> factoryList = Service.locator().list(IModelFactory.class).getServices();
if (factoryList != null) if (factoryList != null)
{ {
for(IModelFactory factory : factoryList) { for(IModelFactory factory : factoryList) {

View File

@ -79,7 +79,7 @@ public class ConfigurationData
private void initDatabaseConfig() private void initDatabaseConfig()
{ {
List<IDatabaseConfig> configList = Service.list(IDatabaseConfig.class); List<IDatabaseConfig> configList = Service.locator().list(IDatabaseConfig.class).getServices();
m_databaseConfig = new IDatabaseConfig[configList.size()]; m_databaseConfig = new IDatabaseConfig[configList.size()];
DBTYPE = new String[m_databaseConfig.length]; DBTYPE = new String[m_databaseConfig.length];
for(int i = 0; i < configList.size(); i++) for(int i = 0; i < configList.size(); i++)

View File

@ -36,11 +36,11 @@ public class OSGiHandlerRegistry implements IHandlerRegistry {
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("id", id); query.put("id", id);
handler = Service.locate(ElementHandler.class, SERVICE_ID, query); handler = Service.locator().locate(ElementHandler.class, SERVICE_ID, null, query).getService();
if (handler == null) { if (handler == null) {
id = TABLE_GENERIC_HANDLER; id = TABLE_GENERIC_HANDLER;
query.put("id", id); query.put("id", id);
handler = Service.locate(ElementHandler.class, SERVICE_ID, query); handler = Service.locator().locate(ElementHandler.class, SERVICE_ID, null, query).getService();
} }
return handler; return handler;
} }
@ -53,7 +53,7 @@ public class OSGiHandlerRegistry implements IHandlerRegistry {
ElementHandler handler = null; ElementHandler handler = null;
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("id", name); query.put("id", name);
handler = Service.locate(ElementHandler.class, SERVICE_ID, query); handler = Service.locator().locate(ElementHandler.class, SERVICE_ID, null, query).getService();
return handler; return handler;
} }
} }

View File

@ -74,7 +74,7 @@ public class AdempiereActivator implements BundleActivator {
protected void packIn(String trxName) { protected void packIn(String trxName) {
URL packout = context.getBundle().getEntry("/META-INF/2Pack.zip"); URL packout = context.getBundle().getEntry("/META-INF/2Pack.zip");
if (packout != null) { if (packout != null) {
IDictionaryService service = Service.locate(IDictionaryService.class); IDictionaryService service = Service.locator().locate(IDictionaryService.class).getService();
try { try {
// copy the resource to a temporary file to process it with 2pack // copy the resource to a temporary file to process it with 2pack
InputStream stream = context.getBundle().getEntry("/META-INF/2Pack.zip").openStream(); InputStream stream = context.getBundle().getEntry("/META-INF/2Pack.zip").openStream();

View File

@ -671,7 +671,7 @@ public class ReportStarter implements ProcessCall, ClientProcess
// JasperExportManager.exportReportToPdfFile(jasperPrint, "BasicReport.pdf"); // JasperExportManager.exportReportToPdfFile(jasperPrint, "BasicReport.pdf");
} else { } else {
log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName());
JRViewerProvider viewerLauncher = Service.locate(JRViewerProvider.class); JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService();
viewerLauncher.openViewer(jasperPrint, pi.getTitle()+" - " + reportPath); viewerLauncher.openViewer(jasperPrint, pi.getTitle()+" - " + reportPath);
} }
} }

View File

@ -182,7 +182,7 @@ public class AdempiereServerMgr
} }
//osgi server //osgi server
List<IServerFactory> serverFactoryList = Service.list(IServerFactory.class); List<IServerFactory> serverFactoryList = Service.locator().list(IServerFactory.class).getServices();
if (serverFactoryList != null && !serverFactoryList.isEmpty()) if (serverFactoryList != null && !serverFactoryList.isEmpty())
{ {
for(IServerFactory factory : serverFactoryList ) for(IServerFactory factory : serverFactoryList )

View File

@ -37,9 +37,7 @@ public class Client {
* @return * @return
*/ */
public static FormPanel getFormPanel(String extensionId) { public static FormPanel getFormPanel(String extensionId) {
ServiceQuery query = new ServiceQuery(); return Service.locator().locate(FormPanel.class, "org.adempiere.apps.Form", extensionId, null).getService();
query.put(ServiceQuery.EXTENSION_ID, extensionId);
return Service.locate(FormPanel.class, "org.adempiere.apps.Form", query);
} }
} }

View File

@ -47,7 +47,7 @@ public class InfoManager
boolean multiSelection, String whereClause) boolean multiSelection, String whereClause)
{ {
Info info = null; Info info = null;
List<IInfoFactory> factoryList = Service.list(IInfoFactory.class); List<IInfoFactory> factoryList = Service.locator().list(IInfoFactory.class).getServices();
for(IInfoFactory factory : factoryList) for(IInfoFactory factory : factoryList)
{ {
info = factory.create(frame, true, lookup, field, tableName, keyColumn, info = factory.create(frame, true, lookup, field, tableName, keyColumn,
@ -77,7 +77,7 @@ public class InfoManager
{ {
Info info = null; Info info = null;
List<IInfoFactory> factoryList = Service.list(IInfoFactory.class); List<IInfoFactory> factoryList = Service.locator().list(IInfoFactory.class).getServices();
for(IInfoFactory factory : factoryList) for(IInfoFactory factory : factoryList)
{ {
info = factory.create(frame, modal, WindowNo, tableName, keyColumn, value, info = factory.create(frame, modal, WindowNo, tableName, keyColumn, value,

View File

@ -55,7 +55,7 @@ public class AExport
// //
exporterMap = new HashMap<String, IGridTabExporter>(); exporterMap = new HashMap<String, IGridTabExporter>();
extensionMap = new HashMap<String, String>(); extensionMap = new HashMap<String, String>();
List<IGridTabExporter> exporterList = Service.list(IGridTabExporter.class); List<IGridTabExporter> exporterList = Service.locator().list(IGridTabExporter.class).getServices();
for(IGridTabExporter exporter : exporterList) for(IGridTabExporter exporter : exporterList)
{ {
String extension = exporter.getFileExtension(); String extension = exporter.getFileExtension();

View File

@ -58,7 +58,7 @@ public class VEditorFactory
public static VEditor getEditor (GridTab mTab, GridField mField, boolean tableEditor) public static VEditor getEditor (GridTab mTab, GridField mField, boolean tableEditor)
{ {
VEditor editor = null; VEditor editor = null;
List<IEditorFactory> factoryList = Service.list(IEditorFactory.class); List<IEditorFactory> factoryList = Service.locator().list(IEditorFactory.class).getServices();
for(IEditorFactory factory : factoryList) for(IEditorFactory factory : factoryList)
{ {
editor = factory.getEditor(mTab, mField, tableEditor); editor = factory.getEditor(mTab, mField, tableEditor);

View File

@ -89,7 +89,7 @@ public class ExportAction implements IAction, EventListener<Event> {
private void doExport() { private void doExport() {
exporterMap = new HashMap<String, IGridTabExporter>(); exporterMap = new HashMap<String, IGridTabExporter>();
extensionMap = new HashMap<String, String>(); extensionMap = new HashMap<String, String>();
List<IGridTabExporter> exporterList = Service.list(IGridTabExporter.class); List<IGridTabExporter> exporterList = Service.locator().list(IGridTabExporter.class).getServices();
for(IGridTabExporter exporter : exporterList) for(IGridTabExporter exporter : exporterList)
{ {
String extension = exporter.getFileExtension(); String extension = exporter.getFileExtension();

View File

@ -12,8 +12,6 @@ Import-Package: javax.servlet,
org.apache.ecs.xhtml, org.apache.ecs.xhtml,
org.compiere.css, org.compiere.css,
org.osgi.framework;version="1.5.0", org.osgi.framework;version="1.5.0",
org.osgi.service.component;version="1.1.0",
org.osgi.util.tracker;version="1.5.0",
org.slf4j;version="1.6.1", org.slf4j;version="1.6.1",
org.slf4j.helpers;version="1.6.1", org.slf4j.helpers;version="1.6.1",
org.slf4j.spi;version="1.6.1" org.slf4j.spi;version="1.6.1"
@ -59,3 +57,4 @@ Bundle-Activator: org.adempiere.webui.WebUIActivator
Eclipse-ExtensibleAPI: true Eclipse-ExtensibleAPI: true
Eclipse-RegisterBuddy: org.zkoss.zk.library Eclipse-RegisterBuddy: org.zkoss.zk.library
Web-ContextPath: webui Web-ContextPath: webui
Service-Component: OSGI-INF/reportviewerprovider.xml, OSGI-INF/defaultinfofactory.xml, OSGI-INF/defaulteditorfactory.xml, OSGI-INF/jrviewerprovider.xml, OSGI-INF/resourcefinder.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.ui.zk.editor.factory">
<implementation class="org.adempiere.webui.factory.DefaultEditorFactory"/>
<service>
<provide interface="org.adempiere.webui.factory.IEditorFactory"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.ui.zk.info.factory">
<implementation class="org.adempiere.webui.factory.DefaultInfoFactory"/>
<service>
<provide interface="org.adempiere.webui.factory.IInfoFactory"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.ui.zk.jrviewer.provider">
<implementation class="org.adempiere.webui.window.ZkJRViewerProvider"/>
<service>
<provide interface="org.compiere.report.JRViewerProvider"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.ui.zk.reportviewer.provider">
<implementation class="org.adempiere.webui.window.ZkReportViewerProvider"/>
<service>
<provide interface="org.compiere.print.ReportViewerProvider"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.ui.zk.resource.finder">
<implementation class="org.adempiere.webui.util.WebUIResourceFinder"/>
<service>
<provide interface="org.adempiere.base.IResourceFinder"/>
</service>
</scr:component>

View File

@ -38,8 +38,6 @@ public class Extensions {
* @return IFormController instance or null if extensionId not found * @return IFormController instance or null if extensionId not found
*/ */
public static IFormController getForm(String extensionId) { public static IFormController getForm(String extensionId) {
ServiceQuery query = new ServiceQuery(); return Service.locator().locate(IFormController.class, "org.adempiere.webui.Form", extensionId, null).getService();
query.put(ServiceQuery.EXTENSION_ID, extensionId);
return Service.locate(IFormController.class, "org.adempiere.webui.Form", query);
} }
} }

View File

@ -16,13 +16,9 @@ package org.adempiere.webui.action;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.adempiere.webui.WebUIActivator; import org.adempiere.base.IServiceHolder;
import org.adempiere.base.Service;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.component.ComponentConstants;
import org.osgi.util.tracker.ServiceTracker;
import org.zkoss.image.AImage; import org.zkoss.image.AImage;
/** /**
@ -33,36 +29,24 @@ import org.zkoss.image.AImage;
public class Actions { public class Actions {
private static final String ACTION_IMAGES_PATH = "/action/images/"; private static final String ACTION_IMAGES_PATH = "/action/images/";
private static CCache<String, ServiceTracker<IAction, IAction>> trackerCache = new CCache<String, ServiceTracker<IAction,IAction>>("ActionsServiceTracker", 5); private static CCache<String, IServiceHolder<IAction>> trackerCache = new CCache<String, IServiceHolder<IAction>>("ActionsServiceTracker", 5);
private static CCache<String, AImage> imageCache = new CCache<String, AImage>("ActionsImages",5); private static CCache<String, AImage> imageCache = new CCache<String, AImage>("ActionsImages",5);
private static final String COMPONENT_FILTER = "(&(objectclass=org.adempiere.webui.action.IAction)(" public static IServiceHolder<IAction> getAction(String actionId) {
+ ComponentConstants.COMPONENT_NAME + "=?))"; IServiceHolder<IAction> action = null;
public static ServiceTracker<IAction, IAction> getActionTracker(String actionId) {
ServiceTracker<IAction, IAction> actionTracker = null;
synchronized (trackerCache) { synchronized (trackerCache) {
actionTracker = trackerCache.get(actionId); action = trackerCache.get(actionId);
} }
if (actionTracker != null) if (action != null)
return actionTracker; return action;
BundleContext context = WebUIActivator.getBundleContext();
Filter filter = null; action = Service.locator().locate(IAction.class, actionId, null);
try { if (action != null) {
String sFilter = COMPONENT_FILTER.replaceFirst("[?]", actionId);
filter = context.createFilter(sFilter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
actionTracker = new ServiceTracker<IAction, IAction>(context, filter, null);
if (actionTracker != null) {
actionTracker.open();
synchronized (trackerCache) { synchronized (trackerCache) {
trackerCache.put(actionId, actionTracker); trackerCache.put(actionId, action);
} }
} }
return actionTracker; return action;
} }
public static AImage getActionImage(String actionId) { public static AImage getActionImage(String actionId) {

View File

@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.base.IServiceHolder;
import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.AdempiereIdGenerator;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.action.Actions; import org.adempiere.webui.action.Actions;
@ -42,7 +43,6 @@ import org.compiere.model.X_AD_ToolBarButton;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.osgi.util.tracker.ServiceTracker;
import org.zkoss.image.AImage; import org.zkoss.image.AImage;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
@ -609,8 +609,8 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
if (mToolbarButtons != null && mToolbarButtons.length > 0) { if (mToolbarButtons != null && mToolbarButtons.length > 0) {
for (MToolBarButton mToolBarButton : mToolbarButtons) { for (MToolBarButton mToolBarButton : mToolbarButtons) {
String actionId = mToolBarButton.getActionClassName(); String actionId = mToolBarButton.getActionClassName();
ServiceTracker<IAction, IAction> serviceTracker = Actions.getActionTracker(actionId); IServiceHolder<IAction> serviceHolder = Actions.getAction(actionId);
if (serviceTracker != null && serviceTracker.size() > 0) { if (serviceHolder != null && serviceHolder.getService() != null) {
String labelKey = actionId + ".label"; String labelKey = actionId + ".label";
String tooltipKey = actionId + ".tooltip"; String tooltipKey = actionId + ".tooltip";
String label = Msg.getMsg(Env.getCtx(), labelKey); String label = Msg.getMsg(Env.getCtx(), labelKey);

View File

@ -13,13 +13,13 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui.adwindow; package org.adempiere.webui.adwindow;
import org.adempiere.base.IServiceHolder;
import org.adempiere.webui.action.Actions; import org.adempiere.webui.action.Actions;
import org.adempiere.webui.action.IAction; import org.adempiere.webui.action.IAction;
import org.compiere.model.MToolBarButton; import org.compiere.model.MToolBarButton;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Evaluatee; import org.compiere.util.Evaluatee;
import org.compiere.util.Evaluator; import org.compiere.util.Evaluator;
import org.osgi.util.tracker.ServiceTracker;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
@ -43,9 +43,9 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
ServiceTracker<IAction, IAction> serviceTracker = Actions.getActionTracker(actionId); IServiceHolder<IAction> serviceHolder = Actions.getAction(actionId);
if (serviceTracker != null) { if (serviceHolder != null) {
IAction action = serviceTracker.getService(); IAction action = serviceHolder.getService();
if (action != null) { if (action != null) {
action.execute(ADWindow.get(windowNo)); action.execute(ADWindow.get(windowNo));
} }

View File

@ -20,13 +20,10 @@ package org.adempiere.webui.editor;
import java.util.List; import java.util.List;
import org.adempiere.base.Service; import org.adempiere.base.Service;
import org.adempiere.webui.component.EditorBox;
import org.adempiere.webui.component.NumberBox;
import org.adempiere.webui.factory.IEditorFactory; import org.adempiere.webui.factory.IEditorFactory;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.GridTab; import org.compiere.model.GridTab;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.zkoss.zul.impl.InputElement;
/** /**
* *
@ -56,7 +53,7 @@ public class WebEditorFactory
public static WEditor getEditor(GridTab gridTab, GridField gridField, boolean tableEditor) public static WEditor getEditor(GridTab gridTab, GridField gridField, boolean tableEditor)
{ {
WEditor editor = null; WEditor editor = null;
List<IEditorFactory> factoryList = Service.list(IEditorFactory.class); List<IEditorFactory> factoryList = Service.locator().list(IEditorFactory.class).getServices();
for(IEditorFactory factory : factoryList) for(IEditorFactory factory : factoryList)
{ {
editor = factory.getEditor(gridTab, gridField, tableEditor); editor = factory.getEditor(gridTab, gridField, tableEditor);

View File

@ -33,7 +33,7 @@ public class InfoManager
{ {
InfoPanel info = null; InfoPanel info = null;
List<IInfoFactory> factoryList = Service.list(IInfoFactory.class); List<IInfoFactory> factoryList = Service.locator().list(IInfoFactory.class).getServices();
for(IInfoFactory factory : factoryList) for(IInfoFactory factory : factoryList)
{ {
info = factory.create(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, lookup); info = factory.create(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, lookup);
@ -49,7 +49,7 @@ public class InfoManager
String whereClause) String whereClause)
{ {
InfoPanel ip = null; InfoPanel ip = null;
List<IInfoFactory> factoryList = Service.list(IInfoFactory.class); List<IInfoFactory> factoryList = Service.locator().list(IInfoFactory.class).getServices();
for(IInfoFactory factory : factoryList) for(IInfoFactory factory : factoryList)
{ {
ip = factory.create(lookup, field, tableName, keyColumn, queryValue, false, whereClause); ip = factory.create(lookup, field, tableName, keyColumn, queryValue, false, whereClause);

View File

@ -78,7 +78,7 @@ public class ExportAction implements EventListener<Event>
{ {
exporterMap = new HashMap<String, IGridTabExporter>(); exporterMap = new HashMap<String, IGridTabExporter>();
extensionMap = new HashMap<String, String>(); extensionMap = new HashMap<String, String>();
List<IGridTabExporter> exporterList = Service.list(IGridTabExporter.class); List<IGridTabExporter> exporterList = Service.locator().list(IGridTabExporter.class).getServices();
for(IGridTabExporter exporter : exporterList) for(IGridTabExporter exporter : exporterList)
{ {
String extension = exporter.getFileExtension(); String extension = exporter.getFileExtension();

View File

@ -108,7 +108,7 @@ public class FileImportAction implements EventListener<Event>
importerMap = new HashMap<String, IGridTabImporter>(); importerMap = new HashMap<String, IGridTabImporter>();
extensionMap = new HashMap<String, String>(); extensionMap = new HashMap<String, String>();
List<IGridTabImporter> importerList = Service.list(IGridTabImporter.class); List<IGridTabImporter> importerList = Service.locator().list(IGridTabImporter.class).getServices();
for(IGridTabImporter importer : importerList) for(IGridTabImporter importer : importerList)
{ {
String extension = importer.getFileExtension(); String extension = importer.getFileExtension();

View File

@ -1,4 +1,3 @@
source.. = WEB-INF/src/
output.. = WEB-INF/classes/ output.. = WEB-INF/classes/
bin.includes = META-INF/,\ bin.includes = META-INF/,\
WEB-INF/,\ WEB-INF/,\
@ -22,7 +21,12 @@ bin.includes = META-INF/,\
calendar.zul,\ calendar.zul,\
calendar_mini.zul,\ calendar_mini.zul,\
divarrow.zul,\ divarrow.zul,\
divtab.zul divtab.zul,\
OSGI-INF/reportviewerprovider.xml,\
OSGI-INF/defaultinfofactory.xml,\
OSGI-INF/defaulteditorfactory.xml,\
OSGI-INF/jrviewerprovider.xml,\
OSGI-INF/resourcefinder.xml
src.includes = WEB-INF/classes/,\ src.includes = WEB-INF/classes/,\
WEB-INF/tld/,\ WEB-INF/tld/,\
WEB-INF/web.xml,\ WEB-INF/web.xml,\
@ -41,5 +45,6 @@ src.includes = WEB-INF/classes/,\
calendar_mini.zul,\ calendar_mini.zul,\
divarrow.zul,\ divarrow.zul,\
divtab.zul divtab.zul
source.. = WEB-INF/src/
bin.excludes = WEB-INF/src/,\ bin.excludes = WEB-INF/src/,\
WEB-INF/web-2.5.xml WEB-INF/web-2.5.xml

View File

@ -4,54 +4,5 @@
<extension-point id="org.adempiere.webui.Form" name="Web Form" schema="schema/org.adempiere.webui.Form.exsd"/> <extension-point id="org.adempiere.webui.Form" name="Web Form" schema="schema/org.adempiere.webui.Form.exsd"/>
<extension-point id="org.adempiere.webui.factory.IInfoFactory" name="Info Factory extension" schema="schema/org.adempiere.webui.factory.IInfoFactory.exsd"/> <extension-point id="org.adempiere.webui.factory.IInfoFactory" name="Info Factory extension" schema="schema/org.adempiere.webui.factory.IInfoFactory.exsd"/>
<extension-point id="org.adempiere.webui.factory.IEditorFactory" name="Field editor factory" schema="schema/org.adempiere.webui.factory.IEditorFactory.exsd"/> <extension-point id="org.adempiere.webui.factory.IEditorFactory" name="Field editor factory" schema="schema/org.adempiere.webui.factory.IEditorFactory.exsd"/>
<extension
point="org.compiere.print.ReportViewerProvider">
<provider
class="org.adempiere.webui.window.ZkReportViewerProvider">
</provider>
</extension>
<extension
point="org.compiere.report.JRViewerProvider">
<provider
class="org.adempiere.webui.window.ZkJRViewerProvider">
</provider>
</extension>
<extension
point="org.compiere.interfaces.Server">
<interface
class="org.compiere.interfaces.impl.ServerBean">
</interface>
</extension>
<extension
point="org.compiere.interfaces.Status">
<interface
class="org.compiere.interfaces.impl.StatusBean">
</interface>
</extension>
<extension
id="org.adempiere.webui.factory.DefaultInfoFactory"
name="Default Info Factory"
point="org.adempiere.webui.factory.IInfoFactory">
<factory
class="org.adempiere.webui.factory.DefaultInfoFactory"
priority="0">
</factory>
</extension>
<extension
id="org.adempiere.webui.factory.DefaultEditorFactory"
name="Default field editor factory"
point="org.adempiere.webui.factory.IEditorFactory">
<factory
class="org.adempiere.webui.factory.DefaultEditorFactory"
priority="0">
</factory>
</extension>
<extension
id="org.adempiere.ui.zk.WebUIResourceFinder"
point="org.adempiere.base.IResourceFinder">
<finder
class="org.adempiere.webui.util.WebUIResourceFinder">
</finder>
</extension>
</plugin> </plugin>

View File

@ -377,7 +377,7 @@ public class ReportCtl
*/ */
public static void preview(ReportEngine re) public static void preview(ReportEngine re)
{ {
ReportViewerProvider viewer = Service.locate(ReportViewerProvider.class); ReportViewerProvider viewer = Service.locator().locate(ReportViewerProvider.class).getService();
viewer.openViewer(re); viewer.openViewer(re);
} }