From 263759c138c2f7f1ded9959fbf8f21cf12db6c90 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 14 Nov 2016 17:49:06 +0800 Subject: [PATCH 1/8] IDEMPIERE-3235 Posting error when currency rate is different between MR and PO. --- .../src/org/compiere/acct/Doc_MatchPO.java | 4 ++-- .../src/org/compiere/acct/Fact.java | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) 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++) From 5f9427c39ee5bcb4e5bee976a3b53c8bba90fcf8 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 18 Nov 2016 17:40:03 +0100 Subject: [PATCH 2/8] IDEMPIERE-3244 Jasper reports cannot run core classes / implement fix suggested by hieplq --- org.adempiere.report.jasper.library/META-INF/MANIFEST.MF | 1 + 1 file changed, 1 insertion(+) 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: * From c8245e755505628ae16f032b79a0c79f4f1ba55b Mon Sep 17 00:00:00 2001 From: freepath Date: Fri, 18 Nov 2016 13:02:23 +0100 Subject: [PATCH 3/8] IDEMPIERE-3243 fixed by using classes from apache felix project. No other classes needed modifications since script-enabled classes relies on MRule --- .../src/org/adempiere/base/Core.java | 27 ++ .../adempiere/base/osgi/OSGiScriptEngine.java | 85 ++++++ .../base/osgi/OSGiScriptEngineFactory.java | 89 ++++++ .../base/osgi/OSGiScriptEngineManager.java | 263 ++++++++++++++++++ .../src/org/compiere/model/MRule.java | 15 +- 5 files changed, 473 insertions(+), 6 deletions(-) create mode 100644 org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngine.java create mode 100644 org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java create mode 100644 org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java index 91a36a2fb9..426ae8fe6a 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -25,6 +25,10 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +import org.adempiere.base.osgi.OSGiScriptEngineManager; import org.adempiere.model.IAddressValidation; import org.adempiere.model.IShipmentProcessor; import org.adempiere.model.ITaxProvider; @@ -43,6 +47,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 +55,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 +402,24 @@ 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) + { + ScriptEngineManager factory = new ScriptEngineManager(Core.class.getClassLoader()); + ScriptEngine engine = factory.getEngineByName(engineName); + + if(engine == null) + { + OSGiScriptEngineManager osgiFactory = new OSGiScriptEngineManager( FrameworkUtil.getBundle(Core.class).getBundleContext()); + 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..15f45a32ea --- /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..e19832314f --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java @@ -0,0 +1,263 @@ +/* + * 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.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +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.compiere.util.Util; +import org.osgi.framework.Bundle; +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(); + try { + for(String factoryName: findFactoryCandidates(context)){ + //We do not really need the class, but we need the classloader + ClassLoader factoryLoader=Class.forName(factoryName).getClassLoader(); + ScriptEngineManager manager=new ScriptEngineManager(factoryLoader); + manager.setBindings(bindings); + managers.put(manager, factoryLoader); + } + return managers; + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } catch (ClassNotFoundException cnfe) { + throw new RuntimeException(cnfe); + } + } + /** + * Iterates through all bundles to get the available @link ScriptEngineFactory classes + * @return the names of the available ScriptEngineFactory classes + * @throws IOException + */ + private List findFactoryCandidates(BundleContext context) throws IOException{ + Bundle[] bundles = context.getBundles(); + List factoryCandidates = new ArrayList(); + for (Bundle bundle : bundles) { + // IDEMPIERE-3243: removed print and small improvements on enumeration + // System.out.println(bundle.getSymbolicName()); + if(bundle.getSymbolicName().equals("system.bundle")) continue; + Enumeration urls = bundle.findEntries("META-INF/services", + "javax.script.ScriptEngineFactory", false); + if (urls == null) + continue; + while (urls.hasMoreElements()) { + URL u = urls.nextElement(); + BufferedReader reader = new BufferedReader( + new InputStreamReader(u.openStream())); + String line; + while ((line = reader.readLine()) != null) + { + // IDEMPIERE-3243: removed comment lines + + int commentIdx = line.indexOf('#'); + + if(commentIdx >= 0) + line = line.substring(0, commentIdx); + + line = line.trim(); + + if(Util.isEmpty(line) == false) + { + factoryCandidates.add(line); + } + } + } + } + return factoryCandidates; + } +} 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; } From 7bceecdb88a2411a7a75712b4f7a52f4ed766ce2 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 23 Nov 2016 21:08:46 +0100 Subject: [PATCH 4/8] IDEMPIERE-3243 - peer review --- org.adempiere.base/OSGI-INF/groovyfactory.xml | 7 ++ .../src/org/adempiere/base/Core.java | 13 +--- .../base/osgi/OSGiScriptEngineFactory.java | 8 +-- .../base/osgi/OSGiScriptEngineManager.java | 69 +++---------------- 4 files changed, 25 insertions(+), 72 deletions(-) create mode 100644 org.adempiere.base/OSGI-INF/groovyfactory.xml 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 426ae8fe6a..c84d24890d 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.logging.Level; import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; import org.adempiere.base.osgi.OSGiScriptEngineManager; import org.adempiere.model.IAddressValidation; @@ -411,15 +410,9 @@ public class Core { */ public static ScriptEngine getScriptEngine(String engineName) { - ScriptEngineManager factory = new ScriptEngineManager(Core.class.getClassLoader()); - ScriptEngine engine = factory.getEngineByName(engineName); - - if(engine == null) - { - OSGiScriptEngineManager osgiFactory = new OSGiScriptEngineManager( FrameworkUtil.getBundle(Core.class).getBundleContext()); - engine = osgiFactory.getEngineByName(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/OSGiScriptEngineFactory.java b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java index 15f45a32ea..e071878fc7 100644 --- a/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java +++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineFactory.java @@ -76,10 +76,10 @@ public class OSGiScriptEngineFactory implements ScriptEngineFactory{ 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); + 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 index e19832314f..a020533875 100644 --- a/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java +++ b/org.adempiere.base/src/org/adempiere/base/osgi/OSGiScriptEngineManager.java @@ -16,12 +16,7 @@ */ package org.adempiere.base.osgi; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,8 +27,7 @@ import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.script.SimpleBindings; -import org.compiere.util.Util; -import org.osgi.framework.Bundle; +import org.adempiere.base.Service; import org.osgi.framework.BundleContext; /** @@ -201,63 +195,22 @@ public class OSGiScriptEngineManager extends ScriptEngineManager{ } - private Map findManagers(BundleContext context) { + Map managers=new HashMap(); - try { - for(String factoryName: findFactoryCandidates(context)){ - //We do not really need the class, but we need the classloader - ClassLoader factoryLoader=Class.forName(factoryName).getClassLoader(); + + 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; - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } catch (ClassNotFoundException cnfe) { - throw new RuntimeException(cnfe); } + + return managers; } - /** - * Iterates through all bundles to get the available @link ScriptEngineFactory classes - * @return the names of the available ScriptEngineFactory classes - * @throws IOException - */ - private List findFactoryCandidates(BundleContext context) throws IOException{ - Bundle[] bundles = context.getBundles(); - List factoryCandidates = new ArrayList(); - for (Bundle bundle : bundles) { - // IDEMPIERE-3243: removed print and small improvements on enumeration - // System.out.println(bundle.getSymbolicName()); - if(bundle.getSymbolicName().equals("system.bundle")) continue; - Enumeration urls = bundle.findEntries("META-INF/services", - "javax.script.ScriptEngineFactory", false); - if (urls == null) - continue; - while (urls.hasMoreElements()) { - URL u = urls.nextElement(); - BufferedReader reader = new BufferedReader( - new InputStreamReader(u.openStream())); - String line; - while ((line = reader.readLine()) != null) - { - // IDEMPIERE-3243: removed comment lines - - int commentIdx = line.indexOf('#'); - - if(commentIdx >= 0) - line = line.substring(0, commentIdx); - - line = line.trim(); - - if(Util.isEmpty(line) == false) - { - factoryCandidates.add(line); - } - } - } - } - return factoryCandidates; - } + } From c93e10ff2e6a43b214a765400548eaa3a2201fc5 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Thu, 24 Nov 2016 21:01:54 +0100 Subject: [PATCH 5/8] swing client not starting --- org.adempiere.ui.swing-feature/swingclient.product.launch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 @@ - + From a35e66141a2bf7adb08454e3472eec26ecffbf27 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 25 Nov 2016 11:37:11 +0100 Subject: [PATCH 6/8] swing client not running --- org.adempiere.base/src/org/compiere/util/Login.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) 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(), From 8bf9c7bb6219ecc9e214a15a0655048731532ad6 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 25 Nov 2016 13:36:39 +0100 Subject: [PATCH 7/8] IDEMPIERE-3245 Sales Region force to be in * org --- .../src/org/compiere/model/MSalesRegion.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) 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 From e0be0231b2c964cf0c4dd8b17ff4554484ac2cb0 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 25 Nov 2016 18:07:43 +0100 Subject: [PATCH 8/8] IDEMPIERE-3248 Select a value in the History records returns an error --- .../adempiere/webui/window/FindWindow.java | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) 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) {