From 126038207241770d26ab2e974a95fb10963d29a3 Mon Sep 17 00:00:00 2001 From: Federico De Faveri Date: Fri, 3 May 2013 16:54:49 +0000 Subject: [PATCH] git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/branches/data-access/spd-having-engine/1.0@74499 82a268e6-3cf1-43bd-a215-b396298e98cf --- .classpath | 36 +++++ .project | 23 ++++ .settings/org.eclipse.core.resources.prefs | 6 + .settings/org.eclipse.jdt.core.prefs | 5 + .settings/org.eclipse.m2e.core.prefs | 4 + distro/INSTALL | 0 distro/LICENSE | 6 + distro/MAINTAINERS | 1 + distro/README | 41 ++++++ distro/changelog.xml | 5 + distro/descriptor.xml | 42 ++++++ distro/profile.xml | 28 ++++ distro/svnpath.txt | 1 + pom.xml | 98 ++++++++++++++ .../spd/havingengine/HavingStatement.java | 20 +++ .../havingengine/HavingStatementFactory.java | 21 +++ .../spd/havingengine/exl/HavingContext.java | 126 ++++++++++++++++++ .../spd/havingengine/exl/HavingFunctions.java | 123 +++++++++++++++++ .../spd/havingengine/exl/HavingMapper.java | 30 +++++ .../exl/HavingStatementFactoryEXL.java | 78 +++++++++++ .../havingengine/test/TestHavingEngine.java | 48 +++++++ .../test/TestHavingEngineSpeed.java | 49 +++++++ .../spd/havingengine/test/model/Person.java | 109 +++++++++++++++ .../spd/havingengine/test/model/Product.java | 27 ++++ src/test/resources/log4j.properties | 8 ++ 25 files changed, 935 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 distro/INSTALL create mode 100644 distro/LICENSE create mode 100644 distro/MAINTAINERS create mode 100644 distro/README create mode 100644 distro/changelog.xml create mode 100644 distro/descriptor.xml create mode 100644 distro/profile.xml create mode 100644 distro/svnpath.txt create mode 100644 pom.xml create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatement.java create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatementFactory.java create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingContext.java create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingFunctions.java create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingMapper.java create mode 100644 src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingStatementFactoryEXL.java create mode 100644 src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngine.java create mode 100644 src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngineSpeed.java create mode 100644 src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Person.java create mode 100644 src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Product.java create mode 100644 src/test/resources/log4j.properties diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..534b5e5 --- /dev/null +++ b/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..72d22dd --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + having-engine + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..60105c1 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/distro/INSTALL b/distro/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..630ba97 --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,6 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS new file mode 100644 index 0000000..5f8cf02 --- /dev/null +++ b/distro/MAINTAINERS @@ -0,0 +1 @@ +Lucio lelii (lucio.lelii@isti.cnr.it), CNR Pisa, Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". \ No newline at end of file diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..bb663c7 --- /dev/null +++ b/distro/README @@ -0,0 +1,41 @@ +The gCube System - Having engine +------------------------------------------------------------ + +This work has been partially supported by the following European projects: DILIGENT (FP6-2003-IST-2), +D4Science (FP7-INFRA-2007-1.2.2), D4Science-II (FP7-INFRA-2008-1.2.2), iMarine (FP7-INFRASTRUCTURES-2011-2), +and EUBrazilOpenBio (FP7-ICT-2011-EU-Brazil). + + +Authors +------- + +* Federico De Faveri (federico.defaveri@isti.cnr.it), CNR Pisa, Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" + +Version and Release Date +------------------------ + +v. 1.0.0 (19-04-2013) + * First release + +Description +----------- +Having engine + + +Download information +-------------------- +https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-access/having-engine + + +Documentation +------------- +https://gcube.wiki.gcube-system.org/gcube/index.php + + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. + + + diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..3b64bc5 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,5 @@ + + + First release + + \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..21d8c88 --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,42 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + INSTALL + MAINTAINERS + changelog.xml + + 755 + true + + + + + ${distroDirectory}/profile.xml + / + true + + + target/${build.finalName}.jar + /${artifactId} + + + ${distroDirectory}/svnpath.txt + /${artifactId} + true + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..62b13c8 --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,28 @@ + + + + Service + + ${description} + DataAccess + ${artifactId} + 1.0.0 + + + ${description} + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + library + + ${build.finalName}.jar + + + + + + diff --git a/distro/svnpath.txt b/distro/svnpath.txt new file mode 100644 index 0000000..cb50fdf --- /dev/null +++ b/distro/svnpath.txt @@ -0,0 +1 @@ +https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-access/having-engine \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7c0eae3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,98 @@ + + 4.0.0 + + org.gcube.data.spd + having-engine + 1.0.0-SNAPSHOT + + + maven-parent + org.gcube.tools + 1.0.0 + + + + + + ${project.basedir}/distro + + + + + org.apache.commons + commons-jexl + 2.1.1 + + + com.thoughtworks.xstream + xstream + 1.4.4 + + + org.slf4j + slf4j-api + 1.6.4 + + + + org.slf4j + slf4j-log4j12 + 1.7.5 + runtime + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + ${distroDirectory}/descriptor.xml + + + + + servicearchive + install + + single + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatement.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatement.java new file mode 100644 index 0000000..c18f847 --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatement.java @@ -0,0 +1,20 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + * @param the type of the element checked. + */ +public interface HavingStatement { + + /** + * Checks if the passed element can be accepted. + * @param element the element to check. + * @return true if it is accepted, false otherwise. + */ + public boolean accept(T element); + +} diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatementFactory.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatementFactory.java new file mode 100644 index 0000000..49ec901 --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/HavingStatementFactory.java @@ -0,0 +1,21 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine; + +/** + * {@link HavingStatement} factory. + * @author "Federico De Faveri defaveri@isti.cnr.it" + */ +public interface HavingStatementFactory { + + + /** + * Compile the passed expression for the target class. + * @param expression the expression to compile. + * @return the compiled statement. + * @throws Exception if an error occurs during the compilation. + */ + public abstract HavingStatement compile(String expression) throws Exception; + +} diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingContext.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingContext.java new file mode 100644 index 0000000..92a8754 --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingContext.java @@ -0,0 +1,126 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.exl; + +import java.io.ByteArrayInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.jexl2.JexlContext; +import org.apache.commons.jexl2.JexlEngine; +import org.apache.commons.jexl2.ObjectContext; +import org.apache.commons.jexl2.ReadonlyContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +/** + * Enhanced {@link JexlContext} that let retrieve XML version of the object and the original object. + * @author "Federico De Faveri defaveri@isti.cnr.it" + */ +public class HavingContext implements JexlContext { + + protected static Logger logger = LoggerFactory.getLogger(HavingContext.class); + + protected static XStream XSTREAM = new XStream() { + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new HavingMapper(next); + } + }; + + protected static DocumentBuilder builder; + + static { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new RuntimeException("Error initializing the builder", e); + } + } + + protected JexlContext context; + protected JexlEngine engine; + protected T wrapped; + protected Document doc; + + public HavingContext(JexlEngine engine, T wrapped) + { + context = new ReadonlyContext(new ObjectContext(engine, wrapped)); + this.wrapped = wrapped; + this.engine = engine; + } + + /** + * @return the engine + */ + public JexlEngine getEngine() { + return engine; + } + + /** + * @return the wrapped + */ + public T getWrapped() { + return wrapped; + } + + + public Document getDocument() { + if (doc == null) doc = buildDocument(); + return doc; + } + + /** + * Build XML document and parse it. + * @return + */ + protected Document buildDocument() + { + try { + String xml = XSTREAM.toXML(wrapped); + logger.trace("xml {}", xml); + ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes()); + Document doc = builder.parse(stream); + return doc; + } catch(Exception e) + { + logger.error("Error converting item to XML", e); + throw new RuntimeException("An error occurred building the document", e); + } + } + + /** + * @param name + * @return + * @see org.apache.commons.jexl2.ObjectContext#get(java.lang.String) + */ + public Object get(String name) { + return context.get(name); + } + + /** + * @param name + * @param value + * @see org.apache.commons.jexl2.ObjectContext#set(java.lang.String, java.lang.Object) + */ + public void set(String name, Object value) { + context.set(name, value); + } + + /** + * @param name + * @return + * @see org.apache.commons.jexl2.ObjectContext#has(java.lang.String) + */ + public boolean has(String name) { + return context.has(name); + } + +} diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingFunctions.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingFunctions.java new file mode 100644 index 0000000..1eae77d --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingFunctions.java @@ -0,0 +1,123 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.exl; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.jexl2.Expression; +import org.apache.commons.jexl2.JexlContext; +import org.apache.commons.jexl2.JexlEngine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + */ +public class HavingFunctions { + + protected static Logger logger = LoggerFactory.getLogger(HavingFunctions.class); + + protected static Map expression_cache; + + static { + expression_cache = new HashMap(); + } + + protected HavingContext context; + + /** + * @param context + * @throws ParserConfigurationException + */ + public HavingFunctions(JexlContext context) { + this.context = (HavingContext) context; + } + + + /** + * Xpath function. + * @param xpath the xpath expression to evaluate. + * @return true if the expression is evaluated true, false otherwise. + * @throws SAXException if an error occurs. + * @throws IOException if an error occurs. + * @throws XPathExpressionException if an error occurs. + */ + public boolean xpath(String xpath) throws SAXException, IOException, XPathExpressionException + { + logger.debug("xpath {} ", xpath); + Document doc = context.getDocument(); + XPathExpression expression = getExpression(xpath); + boolean eval = (Boolean) expression.evaluate(doc, XPathConstants.BOOLEAN); + logger.trace("xpath eval: {}",eval); + return eval; + } + + /** + * Retrieved the compiled expression. + * @param xpathExpression + * @return + * @throws XPathExpressionException + */ + protected XPathExpression getExpression(String xpathExpression) throws XPathExpressionException + { + logger.trace("getExpression xpathExpression {}", xpathExpression); + XPathExpression expression = expression_cache.get(xpathExpression); + if (expression == null) { + logger.trace("Building xpath expression"); + expression = buildExpression(xpathExpression); + expression_cache.put(xpathExpression, expression); + } else logger.trace("XPath expression already cached"); + return expression; + } + + /** + * Compiles the passed expression + * @param xpathExpression + * @return + * @throws XPathExpressionException + */ + protected XPathExpression buildExpression(String xpathExpression) throws XPathExpressionException + { + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr = xpath.compile(xpathExpression); + return expr; + } + + /** + * EXL function. + * @param exlExpression the exl expression to evaluate. + * @return + */ + public boolean exl(String exlExpression) { + logger.debug("exl exlExpression: {}", exlExpression); + + JexlEngine engine = context.getEngine(); + Expression expression = engine.createExpression(exlExpression); + boolean eval = (Boolean) expression.evaluate(context); + logger.trace("xpath eval: {}",eval); + return eval; + } + + public boolean lucio(String expression) { + logger.debug("lucio expression: {}", expression); + boolean eval = ("oh".equalsIgnoreCase(expression)) || ("fro".equalsIgnoreCase(expression)); + logger.trace("xpath eval: {}",eval); + return eval; + } + + +} diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingMapper.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingMapper.java new file mode 100644 index 0000000..0378a3f --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingMapper.java @@ -0,0 +1,30 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.exl; + +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +/** + * {@link MapperWrapper} that generare short class names and in lower case. + * @author "Federico De Faveri defaveri@isti.cnr.it" + */ +public class HavingMapper extends MapperWrapper { + + public HavingMapper(Mapper wrapped) { + super(wrapped); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("rawtypes") + @Override + public String serializedClass(Class type) { + return type.getSimpleName().toLowerCase(); + } + + + +} diff --git a/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingStatementFactoryEXL.java b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingStatementFactoryEXL.java new file mode 100644 index 0000000..c450b53 --- /dev/null +++ b/src/main/java/org/gcube/dataaccess/spd/havingengine/exl/HavingStatementFactoryEXL.java @@ -0,0 +1,78 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.exl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.jexl2.Expression; +import org.apache.commons.jexl2.JexlContext; +import org.apache.commons.jexl2.JexlEngine; +import org.gcube.dataaccess.spd.havingengine.HavingStatement; +import org.gcube.dataaccess.spd.havingengine.HavingStatementFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + */ +public class HavingStatementFactoryEXL implements HavingStatementFactory { + + protected Logger logger = LoggerFactory.getLogger(HavingStatementFactoryEXL.class); + + protected JexlEngine engine; + + public HavingStatementFactoryEXL() + { + engine = new JexlEngine(); + Map functions = new HashMap(); + functions.put(null, HavingFunctions.class); + engine.setFunctions(functions); + } + + /** + * {@inheritDoc} + */ + @Override + public HavingStatement compile(String expression) throws Exception { + logger.debug("compile {}",expression); + Expression expr = engine.createExpression(expression); + return new HavingStatementJEXL(engine, expr); + } + + protected class HavingStatementJEXL implements HavingStatement { + + protected Logger logger = LoggerFactory.getLogger(HavingStatementJEXL.class); + + protected JexlEngine engine; + protected Expression expression; + + /** + * @param engine + * @param expression + */ + private HavingStatementJEXL(JexlEngine engine, Expression expression) { + this.engine = engine; + this.expression = expression; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean accept(T element) { + try { + JexlContext context = new HavingContext(engine, element); + return (Boolean)expression.evaluate(context); + } catch (Exception e) + { + logger.debug("Error evaluating expression", e); + return false; + } + } + + } + +} diff --git a/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngine.java b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngine.java new file mode 100644 index 0000000..24a6615 --- /dev/null +++ b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngine.java @@ -0,0 +1,48 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; + +import org.gcube.dataaccess.spd.havingengine.HavingStatement; +import org.gcube.dataaccess.spd.havingengine.HavingStatementFactory; +import org.gcube.dataaccess.spd.havingengine.exl.HavingStatementFactoryEXL; +import org.gcube.dataaccess.spd.havingengine.test.model.Person; +import org.gcube.dataaccess.spd.havingengine.test.model.Product; +import org.gcube.dataaccess.spd.havingengine.test.model.Product.Type; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + */ +public class TestHavingEngine { + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + + List persons = new ArrayList(); + persons.add(new Person("Federico", "De Faveri", 31, Calendar.getInstance(), new ArrayList(Arrays.asList(new Product(Type.TAXON, 12), new Product(Type.OCCURRENCE, 13))))); + persons.add(new Person("Valentina", "Marioli", 27, Calendar.getInstance(), new ArrayList(Arrays.asList(new Product(Type.OCCURRENCE, 13))))); + persons.add(new Person("Roberto", "Cirillo", 31, Calendar.getInstance(), new ArrayList(Arrays.asList(new Product(Type.OCCURRENCE, 0))))); + persons.add(new Person("Lucio", "Lelii", 33, Calendar.getInstance(), new ArrayList(Arrays.asList(new Product(Type.TAXON, 0))))); + + HavingStatementFactory factory = new HavingStatementFactoryEXL(); + HavingStatement personFilter = factory.compile("xpath(\"//product[type='TAXON' and counter>0]\")"); + + for (Person person:persons) { + System.out.println("Evaluating "+person); + boolean accept = personFilter.accept(person); + System.out.println(accept?"ACCEPTED":"NOT ACCEPTED"); + System.out.println(); + } + + } + +} diff --git a/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngineSpeed.java b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngineSpeed.java new file mode 100644 index 0000000..fde9cf3 --- /dev/null +++ b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/TestHavingEngineSpeed.java @@ -0,0 +1,49 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; + +import org.gcube.dataaccess.spd.havingengine.HavingStatement; +import org.gcube.dataaccess.spd.havingengine.HavingStatementFactory; +import org.gcube.dataaccess.spd.havingengine.exl.HavingStatementFactoryEXL; +import org.gcube.dataaccess.spd.havingengine.test.model.Person; +import org.gcube.dataaccess.spd.havingengine.test.model.Product; +import org.gcube.dataaccess.spd.havingengine.test.model.Product.Type; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + */ +public class TestHavingEngineSpeed { + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + List persons = new ArrayList(); + + for (int i = 0; i<100000; i++) persons.add(new Person("name"+i, "surname"+i, i, Calendar.getInstance(), new ArrayList(Arrays.asList(new Product(Type.OCCURRENCE, 11+i))))); + + long start = System.currentTimeMillis(); + HavingStatementFactory factory = new HavingStatementFactoryEXL(); + HavingStatement personFilter = factory.compile("age<31 || xpath(\"/Person/surname = 'Marioli'\")"); + long time = System.currentTimeMillis()-start; + System.out.println("setup in "+time); + + start = System.currentTimeMillis(); + long accepted = 0; + for (Person person:persons) { + boolean accept = personFilter.accept(person); + if (accept) accepted++; + } + time = System.currentTimeMillis()-start; + System.out.println("accepted "+accepted+" in "+time+" over "+persons.size()+" elements"); + } + +} diff --git a/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Person.java b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Person.java new file mode 100644 index 0000000..12e80a7 --- /dev/null +++ b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Person.java @@ -0,0 +1,109 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.test.model; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.List; + +/** + * @author Federico De Faveri defaveri@gmail.com + * + */ +public class Person { + + protected static final SimpleDateFormat spd = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z"); + + protected String name; + protected String surname; + protected int age; + protected Calendar birthDate; + + protected List products; + + + + /** + * @param name + * @param surname + * @param age + * @param birthDate + */ + public Person(String name, String surname, int age, Calendar birthDate, List products) { + this.name = name; + this.surname = surname; + this.age = age; + this.birthDate = birthDate; + this.products = products; + } + /** + * @return the name + */ + public String getName() { + return name; + } + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + /** + * @return the surname + */ + public String getSurname() { + return surname; + } + /** + * @param surname the surname to set + */ + public void setSurname(String surname) { + this.surname = surname; + } + /** + * @return the age + */ + public int getAge() { + return age; + } + /** + * @param age the age to set + */ + public void setAge(int age) { + this.age = age; + } + /** + * @return the birthDate + */ + public Calendar getBirthDate() { + return birthDate; + } + /** + * @param birthDate the birthDate to set + */ + public void setBirthDate(Calendar birthDate) { + this.birthDate = birthDate; + } + /** + * {@inheritDoc} + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Person [name="); + builder.append(name); + builder.append(", surname="); + builder.append(surname); + builder.append(", age="); + builder.append(age); + builder.append(", birthDate="); + if (birthDate!=null) builder.append(spd.format(birthDate.getTime())); + else builder.append(birthDate); + builder.append("]"); + return builder.toString(); + } + + + +} diff --git a/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Product.java b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Product.java new file mode 100644 index 0000000..51d7c47 --- /dev/null +++ b/src/test/java/org/gcube/dataaccess/spd/havingengine/test/model/Product.java @@ -0,0 +1,27 @@ +/** + * + */ +package org.gcube.dataaccess.spd.havingengine.test.model; + +/** + * @author "Federico De Faveri defaveri@isti.cnr.it" + * + */ +public class Product { + public enum Type {TAXON, OCCURRENCE} + + protected Type type; + protected int counter; + + /** + * @param type + * @param counter + */ + public Product(Type type, int counter) { + this.type = type; + this.counter = counter; + } + + + +} diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties new file mode 100644 index 0000000..baea92b --- /dev/null +++ b/src/test/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=TRACE, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file