diff --git a/org.adempiere.base/OSGI-INF/groovyfactory.xml b/org.adempiere.base/OSGI-INF/groovyfactory.xml
new file mode 100644
index 0000000000..fdfd354b81
--- /dev/null
+++ b/org.adempiere.base/OSGI-INF/groovyfactory.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java
index 91a36a2fb9..c84d24890d 100644
--- a/org.adempiere.base/src/org/adempiere/base/Core.java
+++ b/org.adempiere.base/src/org/adempiere/base/Core.java
@@ -25,6 +25,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
+import javax.script.ScriptEngine;
+
+import org.adempiere.base.osgi.OSGiScriptEngineManager;
import org.adempiere.model.IAddressValidation;
import org.adempiere.model.IShipmentProcessor;
import org.adempiere.model.ITaxProvider;
@@ -43,6 +46,7 @@ import org.compiere.model.StandardTaxProvider;
import org.compiere.process.ProcessCall;
import org.compiere.util.CLogger;
import org.compiere.util.ReplenishInterface;
+import org.osgi.framework.FrameworkUtil;
/**
* This is a facade class for the Service Locator.
@@ -50,6 +54,8 @@ import org.compiere.util.ReplenishInterface;
*
* @author viola
* @author hengsin
+ * @author Silvano Trinchero, www.freepath.it
+ *
IDEMPIERE-3243 added getScriptEngine to manage both registered engines and engines provided by osgi bundles
*/
public class Core {
@@ -395,4 +401,18 @@ public class Core {
return myReplenishInstance;
}
+
+
+ /** Get script engine, checking classpath first, and then osgi plugins
+ *
+ * @param engineName
+ * @return ScriptEngine found, or null
+ */
+ public static ScriptEngine getScriptEngine(String engineName)
+ {
+ OSGiScriptEngineManager osgiFactory = new OSGiScriptEngineManager( FrameworkUtil.getBundle(Core.class).getBundleContext());
+ ScriptEngine engine = osgiFactory.getEngineByName(engineName);
+
+ return engine;
+ }
}
diff --git a/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngine.java b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngine.java
new file mode 100644
index 0000000000..31619a0428
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngine.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.adempiere.base.osgi;
+
+import java.io.Reader;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+
+/**
+ * Imported from Apache Felix project.
+ * Original file:
+ * http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngine.java
+ *
+ */
+
+
+public class OSGiScriptEngine implements ScriptEngine{
+ private ScriptEngine engine;
+ private OSGiScriptEngineFactory factory;
+ public OSGiScriptEngine(ScriptEngine engine, OSGiScriptEngineFactory factory){
+ this.engine=engine;
+ this.factory=factory;
+ }
+ public Bindings createBindings() {
+ return engine.createBindings();
+ }
+ public Object eval(Reader reader, Bindings n) throws ScriptException {
+ return engine.eval(reader, n);
+ }
+ public Object eval(Reader reader, ScriptContext context) throws ScriptException {
+ return engine.eval(reader, context);
+ }
+ public Object eval(Reader reader) throws ScriptException {
+ return engine.eval(reader);
+ }
+ public Object eval(String script, Bindings n) throws ScriptException {
+ return engine.eval(script, n);
+ }
+ public Object eval(String script, ScriptContext context) throws ScriptException {
+ return engine.eval(script, context);
+ }
+ public Object eval(String script) throws ScriptException {
+ return engine.eval(script);
+ }
+ public Object get(String key) {
+ return engine.get(key);
+ }
+ public Bindings getBindings(int scope) {
+ return engine.getBindings(scope);
+ }
+ public ScriptContext getContext() {
+ return engine.getContext();
+ }
+ public ScriptEngineFactory getFactory() {
+ return factory;
+ }
+ public void put(String key, Object value) {
+ engine.put(key, value);
+ }
+ public void setBindings(Bindings bindings, int scope) {
+ engine.setBindings(bindings, scope);
+ }
+ public void setContext(ScriptContext context) {
+ engine.setContext(context);
+ }
+
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java
new file mode 100644
index 0000000000..e071878fc7
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.adempiere.base.osgi;
+
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+/**
+ * This is a wrapper class for the ScriptEngineFactory class that deals with context class loader issues
+ * It is necessary because engines (at least ruby) use the context classloader to find their resources (i.e., their "native" classes)
+ *
+ */
+
+/**
+ * Imported from Apache Felix project.
+ * Original file:
+ * http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngineFactory.java
+ *
+ */
+public class OSGiScriptEngineFactory implements ScriptEngineFactory{
+ private ScriptEngineFactory factory;
+ private ClassLoader contextClassLoader;
+ public OSGiScriptEngineFactory (ScriptEngineFactory factory, ClassLoader contextClassLoader){
+ this.factory=factory;
+ this.contextClassLoader=contextClassLoader;
+ }
+ public String getEngineName() {
+ return factory.getEngineName();
+ }
+ public String getEngineVersion() {
+ return factory.getEngineVersion();
+ }
+ public List getExtensions() {
+ return factory.getExtensions();
+ }
+ public String getLanguageName() {
+ return factory.getLanguageName();
+ }
+ public String getLanguageVersion() {
+ return factory.getLanguageVersion();
+ }
+ public String getMethodCallSyntax(String obj, String m, String... args) {
+ return factory.getMethodCallSyntax(obj, m, args);
+ }
+ public List getMimeTypes() {
+ return factory.getMimeTypes();
+ }
+ public List getNames() {
+ return factory.getNames();
+ }
+ public String getOutputStatement(String toDisplay) {
+ return factory.getOutputStatement(toDisplay);
+ }
+ public Object getParameter(String key) {
+ return factory.getParameter(key);
+ }
+ public String getProgram(String... statements) {
+ return factory.getProgram(statements);
+ }
+ public ScriptEngine getScriptEngine() {
+ ScriptEngine engine=null;
+ if(contextClassLoader!=null){
+ ClassLoader old=Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ engine=factory.getScriptEngine();
+ Thread.currentThread().setContextClassLoader(old);
+ }
+ else engine=factory.getScriptEngine();
+ return engine;
+ }
+
+
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java
new file mode 100644
index 0000000000..a020533875
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.adempiere.base.osgi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.script.Bindings;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleBindings;
+
+import org.adempiere.base.Service;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This class acts as a delegate for all the available ScriptEngineManagers. Unluckily, the standard did not
+ * define it as an interface, so we need to extend it to allow polymorphism. However, no calls to super are used.
+ * It wraps all available ScriptEngineManagers in the OSGi ServicePlatform into a merged ScriptEngineManager.
+ *
+ * Internally, what this class does is creating ScriptEngineManagers for each bundle
+ * that contains a ScriptEngineFactory and includes a META-INF/services/javax.script.ScriptEngineFactory file.
+ * It assumes that the file contains a list of @link ScriptEngineFactory classes. For each bundle, it creates a
+ * ScriptEngineManager, then merges them. @link ScriptEngineFactory objects are wrapped
+ * into @link OSGiScriptEngineFactory objects to deal with problems of context class loader:
+ * Those scripting engines that rely on the ContextClassloader for finding resources need to use this wrapper
+ * and the @link OSGiScriptFactory. Mainly, jruby does.
+ *
+ * Note that even if no context classloader issues arose, it would still be needed to search manually for the
+ * factories and either use them directly (losing the mimeType/extension/shortName mechanisms for finding engines
+ * or manually registering them) or still use this class, which would be smarter. In the latter case,
+ * it would only be needed to remove the hack that temporarily sets the context classloader to the appropriate,
+ * bundle-related, class loader.
+ *
+ * Caveats:
+ * -
+ * All factories are wrapped with an {@link OSGiScriptEngineFactory}. As Engines are not wrapped,
+ * calls like
+ *
+ * ScriptEngineManager osgiManager=new OSGiScriptEngineManager(context);
+ * ScriptEngine engine=osgiManager.getEngineByName("ruby");
+ * ScriptEngineFactory factory=engine.getFactory() //this does not return the OSGiFactory wrapper
+ * factory.getScriptEngine(); //this might fail, as it does not use OSGiScriptEngineFactory wrapper
+ *
+ * might result in unexpected errors. Future versions may wrap the ScriptEngine with a OSGiScriptEngine to solve this
+ * issue, but for the moment it is not needed.
+ *
+ *
+ */
+
+/**
+ * Imported from Apache Felix project.
+ * Original file:
+ * http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngineManager.java
+ *
+ * @author Silvano Trinchero, www.freepath.it
+ * - IDEMPIERE-3243 fixed class discovery to avoid comment lines
+ *
+ */
+
+public class OSGiScriptEngineManager extends ScriptEngineManager{
+ private Bindings bindings;
+ private Map classLoaders;
+ private BundleContext context;
+
+ public OSGiScriptEngineManager(BundleContext context){
+ this.context=context;
+ bindings=new SimpleBindings();
+ this.classLoaders=findManagers(context);
+ }
+ /**
+ * This method is the only one that is visible and not part of the ScriptEngineManager class.
+ * Its purpose is to find new managers that weren't available before, but keeping the globalScope bindings
+ * set.
+ * If you want to clean the bindings you can either get a fresh instance of OSGiScriptManager or
+ * setting up a new bindings object.
+ * This can be done with:
+ *
+ * ScriptEngineManager manager=new OSGiScriptEngineManager(context);
+ * (...)//do stuff
+ * osgiManager=(OSGiScriptEngineManager)manager;//cast to ease reading
+ * osgiManager.reloadManagers();
+ *
+ * manager.setBindings(new OSGiBindings());//or you can use your own bindings implementation
+ *
+ *
+ *
+ */
+ public void reloadManagers(){
+ this.classLoaders=findManagers(context);
+ }
+
+ public Object get(String key) {
+ return bindings.get(key);
+ }
+
+ public Bindings getBindings() {
+ return bindings;
+ }
+
+ public ScriptEngine getEngineByExtension(String extension) {
+ //TODO this is a hack to deal with context class loader issues
+ ScriptEngine engine=null;
+ for(ScriptEngineManager manager: classLoaders.keySet()){
+ ClassLoader old=Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoaders.get(manager));
+ engine=manager.getEngineByExtension(extension);
+ Thread.currentThread().setContextClassLoader(old);
+ if (engine!=null) break;
+ }
+ return engine;
+ }
+
+ public ScriptEngine getEngineByMimeType(String mimeType) {
+ //TODO this is a hack to deal with context class loader issues
+ ScriptEngine engine=null;
+ for(ScriptEngineManager manager: classLoaders.keySet()){
+ ClassLoader old=Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoaders.get(manager));
+ engine=manager.getEngineByMimeType(mimeType);
+ Thread.currentThread().setContextClassLoader(old);
+ if (engine!=null) break;
+ }
+ return engine;
+ }
+
+ public ScriptEngine getEngineByName(String shortName) {
+ //TODO this is a hack to deal with context class loader issues
+ for(ScriptEngineManager manager: classLoaders.keySet()){
+ ClassLoader old=Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoaders.get(manager));
+ ScriptEngine engine=manager.getEngineByName(shortName);
+ Thread.currentThread().setContextClassLoader(old);
+ if (engine!=null){
+ return new OSGiScriptEngine(engine, new OSGiScriptEngineFactory(engine.getFactory(), classLoaders.get(manager)));
+ }
+ }
+ return null;
+ }
+ public List getEngineFactories() {
+ List osgiFactories=new ArrayList();
+ for(ScriptEngineManager engineManager: classLoaders.keySet()){
+ for (ScriptEngineFactory factory : engineManager.getEngineFactories()){
+ osgiFactories.add(new OSGiScriptEngineFactory(factory, classLoaders.get(engineManager)));
+ }
+ }
+ return osgiFactories;
+ }
+
+ public void put(String key, Object value) {
+ bindings.put(key, value);
+ }
+
+ public void registerEngineExtension(String extension, ScriptEngineFactory factory) {
+ for(ScriptEngineManager engineManager: classLoaders.keySet())
+ engineManager.registerEngineExtension(extension, factory);
+ }
+
+ public void registerEngineMimeType(String type, ScriptEngineFactory factory) {
+ for(ScriptEngineManager engineManager: classLoaders.keySet())
+ engineManager.registerEngineMimeType(type, factory);
+ }
+
+ public void registerEngineName(String name, ScriptEngineFactory factory) {
+ for(ScriptEngineManager engineManager: classLoaders.keySet())
+ engineManager.registerEngineName(name, factory);
+ }
+ /**
+ * Follows the same behavior of @link javax.script.ScriptEngineManager#setBindings(Bindings)
+ * This means that the same bindings are applied to all the underlying managers.
+ * @param bindings
+ */
+ public void setBindings(Bindings bindings) {
+ this.bindings=bindings;
+ for(ScriptEngineManager manager: classLoaders.keySet()){
+ manager.setBindings(bindings);
+ }
+
+ }
+
+ private Map findManagers(BundleContext context) {
+
+ Map managers=new HashMap();
+
+ List seFactoryList =
+ Service.locator().list(ScriptEngineFactory.class).getServices();
+ if (seFactoryList != null) {
+ for(ScriptEngineFactory seFactory : seFactoryList) {
+ ClassLoader factoryLoader = seFactory.getClass().getClassLoader();
+ ScriptEngineManager manager=new ScriptEngineManager(factoryLoader);
+ manager.setBindings(bindings);
+ managers.put(manager, factoryLoader);
+ }
+ }
+
+ return managers;
+ }
+
+}
diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java b/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java
index eafa8c67e2..9cb6f14d1f 100644
--- a/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java
+++ b/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java
@@ -202,7 +202,7 @@ public class Doc_MatchPO extends Doc
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
{
MOrder order = m_oLine.getParent();
- Timestamp dateAcct = order.getDateAcct();
+ Timestamp dateAcct = inOut.getDateAcct();
BigDecimal rate = MConversionRate.getRate(
order.getC_Currency_ID(), as.getC_Currency_ID(),
dateAcct, order.getC_ConversionType_ID(),
@@ -236,7 +236,7 @@ public class Doc_MatchPO extends Doc
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
{
MOrder order = m_oLine.getParent();
- Timestamp dateAcct = order.getDateAcct();
+ Timestamp dateAcct = inOut.getDateAcct();
BigDecimal rate = MConversionRate.getRate(
order.getC_Currency_ID(), as.getC_Currency_ID(),
dateAcct, order.getC_ConversionType_ID(),
diff --git a/org.adempiere.base/src/org/compiere/acct/Fact.java b/org.adempiere.base/src/org/compiere/acct/Fact.java
index 4565ec1622..37026839f4 100644
--- a/org.adempiere.base/src/org/compiere/acct/Fact.java
+++ b/org.adempiere.base/src/org/compiere/acct/Fact.java
@@ -253,6 +253,18 @@ public final class Fact
// No lines -> balanced
if (m_lines.size() == 0 || m_doc.isMultiCurrency())
return true;
+
+ // If there is more than 1 currency in fact lines, it is a multi currency doc
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < m_lines.size(); i++){
+ FactLine line = (FactLine)m_lines.get(i);
+ if (line.getC_Currency_ID() > 0 && !list.contains(line.getC_Currency_ID()))
+ list.add(line.getC_Currency_ID());
+
+ }
+ if (list.size() > 1 )
+ return true;
+
BigDecimal balance = getSourceBalance();
boolean retValue = balance.signum() == 0;
if (retValue) {
@@ -328,7 +340,17 @@ public final class Fact
// No lines -> balanced
if (m_lines.size() == 0 || m_doc.isMultiCurrency())
return true;
-
+
+ // If there is more than 1 currency in fact lines, it is a multi currency doc
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < m_lines.size(); i++){
+ FactLine line = (FactLine)m_lines.get(i);
+ if (line.getC_Currency_ID() > 0 && !list.contains(line.getC_Currency_ID()))
+ list.add(line.getC_Currency_ID());
+ }
+ if (list.size() > 1 )
+ return true;
+
MAcctSchemaElement[] elements = m_acctSchema.getAcctSchemaElements();
// check all balancing segments
for (int i = 0; i < elements.length; i++)
diff --git a/org.adempiere.base/src/org/compiere/model/MRule.java b/org.adempiere.base/src/org/compiere/model/MRule.java
index 457cd50ffc..bb87a37f07 100644
--- a/org.adempiere.base/src/org/compiere/model/MRule.java
+++ b/org.adempiere.base/src/org/compiere/model/MRule.java
@@ -24,8 +24,8 @@ import java.util.List;
import java.util.Properties;
import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
+import org.adempiere.base.Core;
import org.compiere.util.CCache;
import org.compiere.util.CLogger;
import org.compiere.util.Msg;
@@ -34,7 +34,10 @@ import org.compiere.util.Util;
/**
* Persistent Rule Model
* @author Carlos Ruiz
+ * @author Silvano Trinchero, www.freepath.it
+ * - IDEMPIERE-3243 refactored getScriptEngine to use Core.getScriptEngine
* @version $Id: MRule.java
+ *
*/
public class MRule extends X_AD_Rule
{
@@ -129,8 +132,6 @@ public class MRule extends X_AD_Rule
@SuppressWarnings("unused")
private static CLogger s_log = CLogger.getCLogger (MRule.class);
- /* Engine Manager */
- private ScriptEngineManager factory = null;
/* The Engine */
ScriptEngine engine = null;
@@ -195,10 +196,12 @@ public class MRule extends X_AD_Rule
* @return ScriptEngine
*/
public ScriptEngine getScriptEngine() {
- factory = new ScriptEngineManager(getClass().getClassLoader());
+
String engineName = getEngineName();
- if (engineName != null)
- engine = factory.getEngineByName(getEngineName());
+
+ if(engineName != null)
+ engine = Core.getScriptEngine(engineName);
+
return engine;
}
diff --git a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java
index e94add42a9..d7e79c60db 100644
--- a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java
+++ b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java
@@ -33,8 +33,7 @@ public class MSalesRegion extends X_C_SalesRegion
/**
*
*/
- private static final long serialVersionUID = 8582026748675153489L;
-
+ private static final long serialVersionUID = -6166934441386906620L;
/**
* Get SalesRegion from Cache
@@ -80,18 +79,6 @@ public class MSalesRegion extends X_C_SalesRegion
super(ctx, rs, trxName);
} // MSalesRegion
- /**
- * Before Save
- * @param newRecord new
- * @return true
- */
- protected boolean beforeSave (boolean newRecord)
- {
- if (getAD_Org_ID() != 0)
- setAD_Org_ID(0);
- return true;
- } // beforeSave
-
/**
* After Save.
* Insert
diff --git a/org.adempiere.base/src/org/compiere/util/Login.java b/org.adempiere.base/src/org/compiere/util/Login.java
index e5ac854e0b..1cbeb5b695 100644
--- a/org.adempiere.base/src/org/compiere/util/Login.java
+++ b/org.adempiere.base/src/org/compiere/util/Login.java
@@ -121,17 +121,13 @@ public class Login
{
// Java System version check
String jVersion = System.getProperty("java.version");
- //vpj-cd e-evolution support to java 6
- if (jVersion.startsWith("1.6.0"))
- return true;
- //end
- if (jVersion.startsWith("1.7.0"))
+ if (jVersion.startsWith("1.8.0"))
return true;
// Error Message
StringBuilder msg = new StringBuilder();
msg.append(System.getProperty("java.vm.name")).append(" - ").append(jVersion);
- msg.append(" <> 1.6.0 | 1.7.0");
+ msg.append(" <> 1.8.0");
//
if (isClient)
JOptionPane.showMessageDialog(null, msg.toString(),
diff --git a/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF b/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF
index 22fecf6bdc..452ee3df31 100644
--- a/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF
+++ b/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF
@@ -343,3 +343,4 @@ Import-Package: bsh,
org.krysalis.barcode4j.servlet,
org.krysalis.barcode4j.tools,
org.krysalis.barcode4j.xalan
+DynamicImport-Package: *
diff --git a/org.adempiere.ui.swing-feature/swingclient.product.launch b/org.adempiere.ui.swing-feature/swingclient.product.launch
index 0a89e35972..cbf3ece2be 100644
--- a/org.adempiere.ui.swing-feature/swingclient.product.launch
+++ b/org.adempiere.ui.swing-feature/swingclient.product.launch
@@ -22,7 +22,7 @@
-
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
index 71e3bbfe41..854521b354 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
@@ -125,7 +125,7 @@ public class FindWindow extends Window implements EventListener, ValueCha
/**
*
*/
- private static final long serialVersionUID = -1264106685431608207L;
+ private static final long serialVersionUID = -5747652133096022993L;
// values and label for history combo
private static final String HISTORY_DAY_ALL = "All";
@@ -133,6 +133,14 @@ public class FindWindow extends Window implements EventListener, ValueCha
private static final String HISTORY_DAY_MONTH = "Month";
private static final String HISTORY_DAY_WEEK = "Week";
private static final String HISTORY_DAY_DAY = "Day";
+ ValueNamePair[] historyItems = new ValueNamePair[] {
+ new ValueNamePair("", " "),
+ new ValueNamePair(HISTORY_DAY_ALL, Msg.getMsg(Env.getCtx(), HISTORY_DAY_ALL)),
+ new ValueNamePair(HISTORY_DAY_YEAR, Msg.getMsg(Env.getCtx(), HISTORY_DAY_YEAR)),
+ new ValueNamePair(HISTORY_DAY_MONTH, Msg.getMsg(Env.getCtx(), HISTORY_DAY_MONTH)),
+ new ValueNamePair(HISTORY_DAY_WEEK, Msg.getMsg(Env.getCtx(), HISTORY_DAY_WEEK)),
+ new ValueNamePair(HISTORY_DAY_DAY, Msg.getMsg(Env.getCtx(), HISTORY_DAY_DAY))
+ };
private static final String HISTORY_LABEL= "History";
/** Main Window for the Lookup Panel */
private MultiTabPart winMain;
@@ -597,16 +605,14 @@ public class FindWindow extends Window implements EventListener, ValueCha
private void prepareHistoryCombo()
{
historyCombo.setAutodrop(true);
- historyCombo.setAutocomplete(false);
+ historyCombo.setAutocomplete(true);
historyCombo.setButtonVisible(true);
- historyCombo.setReadonly(true);
+ historyCombo.setReadonly(false);
historyCombo.setId("historyCombo");
- historyCombo.appendItem(" ", "");
- historyCombo.appendItem((Msg.getMsg(Env.getCtx(), HISTORY_DAY_ALL)),HISTORY_DAY_ALL);
- historyCombo.appendItem((Msg.getMsg(Env.getCtx(), HISTORY_DAY_YEAR)), HISTORY_DAY_YEAR);
- historyCombo.appendItem((Msg.getMsg(Env.getCtx(), HISTORY_DAY_MONTH)), HISTORY_DAY_MONTH);
- historyCombo.appendItem((Msg.getMsg(Env.getCtx(), HISTORY_DAY_WEEK)), HISTORY_DAY_WEEK);
- historyCombo.appendItem((Msg.getMsg(Env.getCtx(), HISTORY_DAY_DAY)), HISTORY_DAY_DAY);
+ for (ValueNamePair vnp : historyItems) {
+ historyCombo.appendItem(vnp.getName(), vnp.getValue());
+ }
+ historyCombo.addEventListener(Events.ON_CHANGE, this);
}
/**
@@ -1117,7 +1123,29 @@ public class FindWindow extends Window implements EventListener, ValueCha
public void onEvent(Event event) throws Exception
{
m_createNew = false;
- if (Events.ON_SELECT.equals(event.getName()))
+ if (Events.ON_CHANGE.equals(event.getName()))
+ {
+ if (event.getTarget() == historyCombo)
+ {
+ // do not allow values out of the list
+ String value = historyCombo.getValue();
+ boolean valid = false;
+ if (value == null) {
+ valid = true;
+ } else {
+ for (ValueNamePair vnp : historyItems) {
+ if (value.equals(vnp.getName())) {
+ valid = true;
+ break;
+ }
+ }
+ }
+ if (! valid) {
+ historyCombo.setSelectedIndex(0);
+ }
+ }
+ }
+ else if (Events.ON_SELECT.equals(event.getName()))
{
if (event.getTarget() instanceof Listbox)
{