first development for the export filter
authorAndreas Müller <a.mueller@bgbm.org>
Wed, 25 Jun 2014 09:49:06 +0000 (09:49 +0000)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 25 Jun 2014 09:49:06 +0000 (09:49 +0000)
.gitattributes
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/LogicFilter.java [new file with mode: 0644]
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilter.java [new file with mode: 0644]
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilterDaoHibernateImpl.java [new file with mode: 0644]
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/tmp/TaxonNodeFilterDaoHibernateImplTest.java [new file with mode: 0644]

index e993583922711b947e0bf0419d1a5b9fd5a78bce..04b5690b667672026bcb5a6143bb2c9d0a7fbf57 100644 (file)
@@ -1429,6 +1429,9 @@ cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/statistics/ISt
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/IClassificationDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/ITaxonDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/ITaxonNodeDao.java -text
+cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/LogicFilter.java -text
+cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilter.java -text
+cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilterDaoHibernateImpl.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/fetch/CdmFetch.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGenerator.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/CdmDataChangeEvent.java -text
@@ -1544,6 +1547,7 @@ cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/stat
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplBenchmark.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.java -text
+cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/tmp/TaxonNodeFilterDaoHibernateImplTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibenate/permission/CdmAuthorityTest.java -text
 cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/hibenate/permission/CdmPermissionClassTest.java -text
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/LogicFilter.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/LogicFilter.java
new file mode 100644 (file)
index 0000000..5661d10
--- /dev/null
@@ -0,0 +1,79 @@
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+\r
+package eu.etaxonomy.cdm.persistence.dao.taxon.tmp;\r
+\r
+import java.util.UUID;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.ITreeNode;\r
+\r
+/**\r
+ * Preliminary class which represents a filter for an export on a CdmBase object, combined \r
+ * with a logical operation.\r
+ * Added to an existing filter it may e.g. allow operations like "filter1 or filter(TaxonNode:123)"\r
+ * It includes the logical operators as enums.\r
+ * \r
+ * @author a.mueller\r
+ *\r
+ */\r
+public class LogicFilter<T extends CdmBase> {\r
+\r
+       public enum Op{\r
+               OR, AND, NOT;\r
+//             OR(" OR "), AND(" AND "), NOT(" NOT ");\r
+//                     String str;\r
+//             \r
+//             private Op(String opStr){\r
+//                     str = opStr;\r
+//             }\r
+       }\r
+       \r
+       private static final Op defaultOperator = Op.OR;\r
+       \r
+       private Op operator = defaultOperator;\r
+       \r
+       private UUID uuid;\r
+       private String treeIndex;\r
+       \r
+\r
+       \r
+       public LogicFilter(T cdmBase){\r
+               this(cdmBase, defaultOperator);\r
+       }\r
+\r
+       public LogicFilter(T cdmBase, Op operator){\r
+               if (cdmBase == null){\r
+                       throw new IllegalArgumentException("Null object not allowed as filter criteria");\r
+               }\r
+               if (operator == null){\r
+                       operator = defaultOperator;\r
+               }\r
+               \r
+               this.uuid = cdmBase.getUuid();\r
+               this.operator = operator;\r
+               CdmBase cdmBase2 = CdmBase.deproxy(cdmBase, CdmBase.class);\r
+               if (cdmBase2 instanceof ITreeNode){\r
+                       this.treeIndex = ((ITreeNode<?>)cdmBase2).treeIndex();\r
+               }\r
+       }\r
+\r
+       public Op getOperator() {\r
+               return operator;\r
+       }\r
+\r
+       public UUID getUuid() {\r
+               return uuid;\r
+       }\r
+       \r
+       public String getTreeIndex() {\r
+               return treeIndex;\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilter.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilter.java
new file mode 100644 (file)
index 0000000..3503345
--- /dev/null
@@ -0,0 +1,90 @@
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+\r
+package eu.etaxonomy.cdm.persistence.dao.taxon.tmp;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.tmp.LogicFilter.Op;\r
+\r
+/**\r
+ * \r
+ * Preliminary.\r
+ * @author a.mueller\r
+ *\r
+ */\r
+public class TaxonNodeFilter {\r
+       \r
+       List<LogicFilter<TaxonNode>> taxonNodes = new ArrayList<LogicFilter<TaxonNode>>();\r
+       \r
+       List<LogicFilter<NamedArea>> areaFilter = new ArrayList<LogicFilter<NamedArea>>();\r
+\r
+       @SuppressWarnings("rawtypes")\r
+       List<LogicFilter<PresenceAbsenceTermBase>> distributionStatusFilter = new ArrayList<LogicFilter<PresenceAbsenceTermBase>>();\r
+       \r
+\r
+       public void reset(){\r
+               taxonNodes = new ArrayList<LogicFilter<TaxonNode>>();\r
+               \r
+               resetArea();\r
+               \r
+               resetDistributionStatus();\r
+       }\r
+\r
+       @SuppressWarnings("rawtypes")\r
+       private void resetDistributionStatus() {\r
+               distributionStatusFilter = new ArrayList<LogicFilter<PresenceAbsenceTermBase>>();\r
+       }\r
+\r
+       private void resetArea() {\r
+               areaFilter = new ArrayList<LogicFilter<NamedArea>>();\r
+       }\r
+       \r
+       public TaxonNodeFilter(TaxonNode node){\r
+               reset();\r
+               LogicFilter<TaxonNode> filter = new LogicFilter<TaxonNode>(node);\r
+               taxonNodes.add(filter);\r
+       }\r
+       \r
+       public List<LogicFilter<TaxonNode>>getTaxonNodesFilter(){\r
+               return Collections.unmodifiableList(taxonNodes);\r
+       }\r
+       \r
+       public List<LogicFilter<NamedArea>>getAreaFilter(){\r
+               return Collections.unmodifiableList(areaFilter);\r
+       }\r
+       \r
+       @SuppressWarnings("rawtypes")\r
+       public List<LogicFilter<PresenceAbsenceTermBase>>getDistributionStatusFilter(){\r
+               return Collections.unmodifiableList(distributionStatusFilter);\r
+       }\r
+       \r
+       public TaxonNodeFilter or(TaxonNode taxonNode){\r
+               taxonNodes.add( new LogicFilter<TaxonNode>(taxonNode, Op.OR));\r
+               return this;\r
+       }\r
+       \r
+       public TaxonNodeFilter not(TaxonNode taxonNode){\r
+               taxonNodes.add( new LogicFilter<TaxonNode>(taxonNode, Op.NOT));\r
+               return this;\r
+       }\r
+       \r
+       public TaxonNodeFilter set(NamedArea area){\r
+               resetArea();\r
+               areaFilter.add( new LogicFilter<NamedArea>(area, Op.AND));\r
+               return this;\r
+       }\r
+\r
+       \r
+}\r
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilterDaoHibernateImpl.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/tmp/TaxonNodeFilterDaoHibernateImpl.java
new file mode 100644 (file)
index 0000000..5e2ff59
--- /dev/null
@@ -0,0 +1,80 @@
+/**\r
+ * \r
+ */\r
+package eu.etaxonomy.cdm.persistence.dao.taxon.tmp;\r
+\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+import org.hibernate.Query;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
+import eu.etaxonomy.cdm.persistence.dao.hibernate.common.AnnotatableDaoImpl;\r
+import eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmEntityDaoBase;\r
+import eu.etaxonomy.cdm.persistence.dao.hibernate.taxon.TaxonNodeDaoHibernateImpl;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.tmp.LogicFilter.Op;\r
+\r
+/**\r
+ * Preliminary implementation for testing filtered taxa\r
+ * @author a.mueller\r
+ *\r
+ */\r
+@Repository\r
+public class TaxonNodeFilterDaoHibernateImpl extends CdmEntityDaoBase<TaxonNode> {\r
+       \r
+       public TaxonNodeFilterDaoHibernateImpl() {\r
+               super(TaxonNode.class);\r
+       }\r
+\r
+\r
+       //maybe we will later want to have ordering included\r
+       public List<UUID> listUuids(TaxonNodeFilter filter){\r
+               String select = " SELECT m.uuid ";\r
+               String from = "FROM TaxonNode m ";\r
+               String nodeCondition = getNodeFilter(filter);\r
+               \r
+               \r
+               String fullQuery = select + from + " WHERE " + nodeCondition; \r
+               System.out.println(fullQuery);\r
+               Query query = getSession().createQuery(fullQuery);\r
+               List<UUID> list = castToUuidList(query.list());\r
+               return list;\r
+       }\r
+       \r
+       \r
+       \r
+       \r
+       private String getNodeFilter(TaxonNodeFilter filter) {\r
+               String result = "";\r
+               List<LogicFilter<TaxonNode>> nodesFilter = filter.getTaxonNodesFilter();\r
+               boolean isFirst = true;\r
+               for (LogicFilter<TaxonNode> singleFilter : nodesFilter){\r
+                       String treeIndex = singleFilter.getTreeIndex();\r
+                       String op = isFirst ? "" : op2Hql(singleFilter.getOperator());\r
+                       result = String.format("(%s%s(m.treeIndex like '%s%%'))", result, op, treeIndex);\r
+                       System.out.println(result);\r
+                       isFirst = false;\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       \r
+       private String op2Hql(Op op){\r
+               return op == Op.NOT ? " AND NOT " : op.toString();\r
+       }\r
+\r
+//\r
+//\r
+//     public static void main(String[] args){\r
+//             String r = String.format(" main.treeIndex like '%s%%'", "aa");\r
+//             System.out.println(r);\r
+//     }\r
+       \r
+\r
+       @SuppressWarnings("unchecked")\r
+       private List<UUID> castToUuidList(List<?> queryList){\r
+               return (List<UUID>) queryList;\r
+       }\r
+\r
+}\r
diff --git a/cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/tmp/TaxonNodeFilterDaoHibernateImplTest.java b/cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/tmp/TaxonNodeFilterDaoHibernateImplTest.java
new file mode 100644 (file)
index 0000000..c96267b
--- /dev/null
@@ -0,0 +1,112 @@
+/**\r
+ * \r
+ */\r
+package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon.tmp;\r
+\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.unitils.spring.annotation.SpringBeanByType;\r
+\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.taxon.Classification;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.tmp.TaxonNodeFilter;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.tmp.TaxonNodeFilterDaoHibernateImpl;\r
+import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;\r
+\r
+/**\r
+ * @author a.mueller\r
+ * @date 2014/06/13\r
+ *\r
+ */\r
+public class TaxonNodeFilterDaoHibernateImplTest extends CdmTransactionalIntegrationTest {\r
+\r
+    @SpringBeanByType\r
+    private ITaxonNodeDao taxonNodeDao;\r
+       \r
+    @SpringBeanByType\r
+    private IClassificationDao classificationDao;\r
+    \r
+    @SpringBeanByType\r
+    private TaxonNodeFilterDaoHibernateImpl filterDao;\r
+    \r
+    \r
+\r
+\r
+       \r
+       private Classification classification1;\r
+       private TaxonNode node1;\r
+       private TaxonNode node2;\r
+       private TaxonNode node3;\r
+       private TaxonNode node4;\r
+       private TaxonNode node5;\r
+       \r
+       /**\r
+        * @throws java.lang.Exception\r
+        */\r
+       @Before\r
+       public void setUp() throws Exception {\r
+               classification1 = Classification.NewInstance("TestClassification");\r
+               Reference<?> citation = null;\r
+               String microCitation = null;\r
+               Taxon taxon1 = Taxon.NewInstance(null, null);\r
+               Taxon taxon2 = Taxon.NewInstance(null, null);\r
+               Taxon taxon3 = Taxon.NewInstance(null, null);\r
+               Taxon taxon4 = Taxon.NewInstance(null, null);\r
+               Taxon taxon5 = Taxon.NewInstance(null, null);\r
+               node1 = classification1.addChildTaxon(taxon1, citation, microCitation);\r
+               node2 = classification1.addChildTaxon(taxon2, citation, microCitation);\r
+               node3 = node1.addChildTaxon(taxon3, citation, microCitation);\r
+               node4 = node3.addChildTaxon(taxon4, citation, microCitation);\r
+               node5 = node3.addChildTaxon(taxon5, citation, microCitation);\r
+               classificationDao.save(classification1);\r
+               \r
+       }\r
+\r
+       /**\r
+        * Test method for {@link eu.etaxonomy.cdm.persistence.dao.taxon.tmp.TaxonNodeFilterDaoHibernateImpl#listUuids(eu.etaxonomy.cdm.persistence.dao.taxon.tmp.TaxonNodeFilter)}.\r
+        */\r
+       @Test\r
+       public void testListUuids() {\r
+               Classification classification = classificationDao.findByUuid(classification1.getUuid());\r
+               TaxonNodeFilter filter = new TaxonNodeFilter(node1);\r
+               List<UUID> listUuid = filterDao.listUuids(filter);\r
+               Assert.assertEquals("All 4 children should be returned", 4, listUuid.size());\r
+               Assert.assertTrue(listUuid.contains(node4.getUuid()));\r
+               Assert.assertFalse(listUuid.contains(node2.getUuid()));\r
+               Assert.assertFalse(listUuid.contains(classification.getRootNode().getUuid()));\r
+               \r
+               \r
+               filter = new TaxonNodeFilter(classification.getRootNode());\r
+               listUuid = filterDao.listUuids(filter);\r
+               //FIXME still unclear if (empty) root node should be part of the result\r
+               Assert.assertEquals("All 6 children should be returned", 6, listUuid.size());\r
+               \r
+               filter = new TaxonNodeFilter(node3);\r
+               listUuid = filterDao.listUuids(filter);\r
+               Assert.assertEquals("All 3 children should be returned", 3, listUuid.size());\r
+\r
+               filter.or(node2);\r
+               listUuid = filterDao.listUuids(filter);\r
+               Assert.assertEquals("All 3 children and node 2 should be returned", 4, listUuid.size());\r
+               Assert.assertTrue(listUuid.contains(node2.getUuid()));\r
+               \r
+               filter = new TaxonNodeFilter(node1).not(node4);\r
+               listUuid = filterDao.listUuids(filter);\r
+               Assert.assertEquals("Node and 2 children but not node4 should be returned", 3, listUuid.size());\r
+               Assert.assertFalse(listUuid.contains(node4.getUuid()));\r
+\r
+               \r
+\r
+               \r
+               \r
+       }\r
+\r
+}\r