Author: bpoussin Date: 2011-12-28 19:50:45 +0100 (Wed, 28 Dec 2011) New Revision: 1259 Url: http://nuiton.org/repositories/revision/wikitty/1259 Log: Evolution #1863: Create new query api with visitor and better implementation Evolution #1864: Add query langage syntaxe old search package and method findXXXbyCriteria have been marked deprecated Proxy not yet modified Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopic.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicCountComparator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicNameComparator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResultTreeNode.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/And.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Between.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Condition.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionNary.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionUnary.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsAll.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsOne.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Element.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementExtension.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementField.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementId.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Equals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/False.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Greater.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/GreaterOrEquals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Join.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Keyword.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Less.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/LessOrEquals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Like.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Not.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotEquals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotNull.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Null.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Or.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryListOperator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryOperator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalOperator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalTernaryOperator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/True.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Unlike.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java Modified: trunk/pom.xml trunk/wikitty-api/pom.xml trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Criteria.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopic.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicCountComparator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicNameComparator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/PagedResult.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/RestrictionHelper.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Search.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/TreeNodeResult.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/And.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/AssociatedRestriction.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Between.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/BinaryOperator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Element.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/EndsWith.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Equals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/False.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Greater.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/GreaterOrEqual.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Keyword.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Less.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/LessOrEqual.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Like.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Not.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/NotEquals.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Null.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Or.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Restriction.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/RestrictionName.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SearchOperand.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/StartsWith.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SubSearch.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/True.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Unlike.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceTransaction.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngine.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/pom.xml 2011-12-28 18:50:45 UTC (rev 1259) @@ -47,7 +47,7 @@ <maven3Version>3.0.3</maven3Version> <!-- common versions used in sub-poms --> - <eugeneVersion>2.4.1-SNAPSHOT</eugeneVersion> + <eugeneVersion>2.4.1</eugeneVersion> <nuitonUtilsVersion>2.2</nuitonUtilsVersion> <nuitonI18nVersion>2.4.1</nuitonI18nVersion> <processPluginVersion>1.1</processPluginVersion> @@ -56,6 +56,7 @@ <struts2Version>2.2.3</struts2Version> <javassistVersion>3.8.0.GA</javassistVersion> <jspapiversion>2.1</jspapiversion> + <opencsvVersion>2.3</opencsvVersion> <nuitonProcessessorVersion>1.2.2</nuitonProcessessorVersion> <nuiton-struts2>1.3</nuiton-struts2> @@ -66,6 +67,19 @@ <dependencyManagement> <dependencies> + + <!-- pour le parser de requete --> + <dependency> + <groupId>org.parboiled</groupId> + <artifactId>parboiled-core</artifactId> + <version>1.0.2</version> + </dependency> + <dependency> + <groupId>org.parboiled</groupId> + <artifactId>parboiled-java</artifactId> + <version>1.0.2</version> + </dependency> + <!-- pour la communication client/serveur et la notification sur protocole cajo --> <dependency> <groupId>gnu.cajo</groupId> @@ -241,7 +255,7 @@ <dependency> <groupId>net.sf.opencsv</groupId> <artifactId>opencsv</artifactId> - <version>2.1</version> + <version>${opencsvVersion}</version> <scope>compile</scope> </dependency> Modified: trunk/wikitty-api/pom.xml =================================================================== --- trunk/wikitty-api/pom.xml 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/pom.xml 2011-12-28 18:50:45 UTC (rev 1259) @@ -17,7 +17,6 @@ <dependencies> - <!-- COMPILE --> <!-- needed to mutualise some util method (tagValueToString) --> @@ -27,6 +26,16 @@ <version>${project.version}</version> </dependency> + <!-- pour le parser de requete --> + <dependency> + <groupId>org.parboiled</groupId> + <artifactId>parboiled-core</artifactId> + </dependency> + <dependency> + <groupId>org.parboiled</groupId> + <artifactId>parboiled-java</artifactId> + </dependency> + <!-- pour la communication client/serveur et la notification sur protocole cajo --> <dependency> <groupId>gnu.cajo</groupId> Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -38,6 +38,9 @@ import java.util.Collection; import java.util.List; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; import org.nuiton.wikitty.search.TreeNodeResult; /** @@ -316,11 +319,26 @@ * @param securityToken security token * @param criteria * @return + * @deprecated since 3.3 use {@link #findAllByQuery(java.lang.String, java.util.List)} */ + @Deprecated public List<PagedResult<String>> findAllByCriteria( String securityToken, List<Criteria> criteria); /** + * Looking for Wikitty that match criteria. More than one criteria can be + * passed in parametre, for each query in parametre there is a WikittyQueryResult + * associated with the same index. + * + * @param securityToken security token + * @param query + * @return + * @since 3.3 + */ + public List<WikittyQueryResult<String>> findAllByQuery( + String securityToken, List<WikittyQuery> queries); + + /** * First lonely (or first one) wikitty object that match criteria, if no * wikitty found or first retrived is not authorized for the user return * null. for each criteria in parametre there is a result @@ -329,9 +347,24 @@ * @param securityToken security token * @param criteria * @return wikitty id object or null + * @deprecated since 3.3 use {@link #findByQuery(java.lang.String, java.util.List) } */ + @Deprecated public List<String> findByCriteria(String securityToken, List<Criteria> criteria); + /** + * First lonely (or first one) wikitty object that match query, if no + * wikitty found or first retrived is not authorized for the user return + * null. for each query in parametre there is a result + * associated with the same index. + * + * @param securityToken security token + * @param queries + * @return wikitty id object or null + * @since 3.3 + */ + public List<String> findByQuery(String securityToken, List<WikittyQuery> queries); + /* * Classification * Most of classification purpose is handle by extension mechanisms @@ -355,7 +388,7 @@ * <li> 1 return wikittyId passed in argument, and his children * <li> ... * <li> negative value return all node - * + * * if count is true, integer in return map is number of attachment in subtree * (recursively). If filter is not null only attachments that satisfy filter * are counted. @@ -368,12 +401,41 @@ * @param filter filter on attachment count * @return * @since 3.1 + * @deprecated since 3.3 use {@link #findTreeNode(java.lang.String, java.lang.String, int, boolean, org.nuiton.wikitty.query.WikittyQuery) } */ + @Deprecated public TreeNodeResult<String> findTreeNode( String securityToken, String wikittyId, int depth, boolean count, Criteria filter); + /** + * Retrieve all node from wikittyId, this node is returned too. + * Returned wikitty must include the 'WikittyTreeNode' extension. + * + * depth ask the recursively level: + * <li> 0 return only wikittyId passed in argument + * <li> 1 return wikittyId passed in argument, and his children + * <li> ... + * <li> negative value return all node + * + * if count is true, integer in return map is number of attachment in subtree + * (recursively). If filter is not null only attachments that satisfy filter + * are counted. + * if count is false, all integer are fixed to 0 + * + * @param securityToken security token + * @param wikittyId root node to begin + * @param depth depth of node returned + * @param count if true return count of attachment + * @param filter filter on attachment count + * @return + * @since 3.3 + */ + public WikittyQueryResultTreeNode<String> findTreeNode( + String securityToken, String wikittyId, + int depth, boolean count, WikittyQuery filter); + /* * history */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -48,6 +48,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -110,7 +111,7 @@ static private Log log = LogFactory.getLog(WikittyUtil.class); /** used to format date for solr */ - protected static TimeZone CANONICAL_TZ = TimeZone.getTimeZone("UTC"); + protected static final TimeZone CANONICAL_TZ = TimeZone.getTimeZone("UTC"); protected static final Locale CANONICAL_LOCALE = Locale.US; // FastDateFormat is thread-safe @@ -501,6 +502,13 @@ return result; } + /** + * Convert Object to String representation if value is not null + * Wikitty is converted to id, and Date to SolrDateFormat + * + * @param value value to convert + * @return String representation or null + */ static public String toString(Object value) { String result = null; if (value != null) { @@ -512,6 +520,8 @@ result = ((BusinessEntity) value).getWikittyId(); } else if (value instanceof Date) { result = solrDateFormat.format((Date) value); + } else if (value instanceof Calendar) { + result = solrDateFormat.format((Calendar)value); } else { // try to convert to String result = value.toString(); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -141,7 +141,7 @@ * @param value value to convert * @return object in type of this FieldType */ - protected Object getContainedValidObject( Object value ) { + public Object getContainedValidObject( Object value ) { Object result = null; switch (type) { case BINARY: Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopic.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopic.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopic.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,54 @@ +package org.nuiton.wikitty.query; + +import java.io.Serializable; + +/** + * Represente un topic d'une facet. Les topic sont utilise dans les resultats + * de requete + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class FacetTopic implements Serializable { + + /** serialVersionUID. */ + private static final long serialVersionUID = 1408493244549775810L; + + protected String facetName; + + protected String topicName; + + protected int count; + + public FacetTopic(String facetName, String topicName, int count) { + this.facetName = facetName; + this.topicName = topicName; + this.count = count; + } + + public String getFacetName() { + return facetName; + } + + public String getTopicName() { + return topicName; + } + + public int getCount() { + return count; + } + + @Override + public String toString() { + String result = String.format( + "FacetTopic(facet: '%s' topic: '%s' count: '%s')", + getFacetName(), getTopicName(), getCount()); + return result; + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicCountComparator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicCountComparator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicCountComparator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,29 @@ +package org.nuiton.wikitty.query; + +import java.util.Comparator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Comparateur de topic sur le nombre d'occurence du topic dans la facet. + * Cela permet de presenter a l'utilisateur les topics les plus rependu en premier + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class FacetTopicCountComparator implements Comparator<FacetTopic> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FacetTopicCountComparator.class); + + public int compare(FacetTopic o1, FacetTopic o2) { + int thisVal = o1.getCount(); + int anotherVal = o2.getCount(); + // code recupere de Integer.compareTo + return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicNameComparator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicNameComparator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/FacetTopicNameComparator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,41 @@ +package org.nuiton.wikitty.query; + +import java.util.Comparator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Comparateur de topic sur le nom du topic. + * Cela permet de presenter a l'utilisateur les topics dans l'ordre alphabetique + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class FacetTopicNameComparator implements Comparator<FacetTopic> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FacetTopicNameComparator.class); + + protected boolean ignoreCase = true; + + public FacetTopicNameComparator() { + } + + public FacetTopicNameComparator(boolean ignoreCase) { + this.ignoreCase = ignoreCase; + } + + public int compare(FacetTopic o1, FacetTopic o2) { + int result; + if (ignoreCase) { + result = o1.getTopicName().compareToIgnoreCase(o2.getTopicName()); + } else { + result = o1.getTopicName().compareTo(o2.getTopicName()); + } + return result; + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,325 @@ +package org.nuiton.wikitty.query; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.conditions.Condition; + +/** + * Classe permettant de faire des recherches dans les données. + * <p> + * Pour creer facilement la condition le plus simple est d'utiliser + * {@link WikittyQueryMaker} pour creer le WikittyQuery en appelant la + * method {@link WikittyQueryMaker#end()} a la fin. + * <p> + * Pour offrir au utilisateur de vos applications la possibilite d'ecrire + * eux meme des requetes vous pouvez utiliser {@link WikittyQueryParser} + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQuery implements Serializable { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQuery.class); + + private static final long serialVersionUID = 1L; + + /** Use to not limit result. */ + static final public int MAX = -1; + + /** query name */ + protected String name; + /** query condition */ + protected Condition condition; + + /** + * Use to return select ids + * Be carefull, can be long if many result is found + */ + protected String select; + + /** First index to get result. */ + protected int first = 0; + /** Number of result to retrieve. 100 by default. */ + protected int limit = 100; + + /** + * nombre minimum de valeur pour qu'une valeur apparaisse dans les facets. + * par defaut, il doit y avoir plus que 1 valeur. + */ + protected int facetMinCount = 1; + /** + * Nombre maximum de facet a retourner apres la requete. Par default on en + * retourne 100. + */ + protected int facetLimit = 100; + + /** Facet on condition. */ + protected List<Condition> facetCriteria; + /** Facet on field. */ + protected List<String> facetField; + /** if true facet is done on extension name */ + protected boolean facetExtension = false; + + /** Sort ascending on fields. */ + protected List<String> sortAscending; + /** Sort descending on fields. */ + protected List<String> sortDescending; + + + /** create anonymous query */ + public WikittyQuery() { + } + + public WikittyQuery(Condition condition) { + setCondition(condition); + } + + public WikittyQuery copy() { + WikittyQueryVisitorCopy v = new WikittyQueryVisitorCopy(); + accept(v); + return v.getQuery(); + } + + @Override + public String toString() { + WikittyQueryVisitorToString v = new WikittyQueryVisitorToString(); + accept(v); + String result = v.getText(); + return result; + } + + @Override + public boolean equals(Object o) { + boolean result; + + if (o == null) { + result = false; + } else if (ObjectUtils.equals(this.getClass(), o.getClass())) { + WikittyQuery other = (WikittyQuery)o; + result = ObjectUtils.equals(this.getName(), other.getName()) && + ObjectUtils.equals(this.getFirst(), other.getFirst()) && + ObjectUtils.equals(this.getLimit(), other.getLimit()) && + ObjectUtils.equals(this.getSelect(), other.getSelect()) && + ObjectUtils.equals(this.getFacetField(), other.getFacetField()) && + ObjectUtils.equals(this.getSortAscending(), other.getSortAscending()) && + ObjectUtils.equals(this.getSortDescending(), other.getSortDescending()) && + ObjectUtils.equals(this.getFacetLimit(), other.getFacetLimit()) && + ObjectUtils.equals(this.getFacetMinCount(), other.getFacetMinCount()) && + ObjectUtils.equals(this.getFacetCriteria(), other.getFacetCriteria()) && + ObjectUtils.equals(this.getCondition(), other.getCondition()); + } else { + result = false; + } + + return result; + } + + /** + * Inefficiant hashCode method but necessary with overloading of equals method + * This method return hashCode of object class. There is no better way to + * compute stable hashCode in time + * + * @return + */ + @Override + public int hashCode() { + int result = getClass().hashCode(); + return result; + } + + /** create named query */ + public WikittyQuery(String name) { + this.name = name; + } + + /** create named query with condition*/ + public WikittyQuery(String name, Condition condition) { + this.name = name; + setCondition(condition); + } + + public void accept(WikittyQueryVisitor visitor) { + boolean walk = visitor.visitEnter(this); + if (walk && condition != null) { + condition.accept(visitor); + } + visitor.visitLeave(this, walk); + } + + public String getName() { + return name; + } + + public WikittyQuery setName(String name) { + this.name = name; + return this; + } + + public String getSelect() { + return select; + } + + public WikittyQuery setSelect(String select) { + this.select = select; + return this; + } + + public int getFirst() { + return first; + } + + public WikittyQuery setFirst(int first) { + this.first = first; + return this; + } + + public int getLimit() { + return limit; + } + + public WikittyQuery setLimit(int count) { + this.limit = count; + return this; + } + + public int getFacetMinCount() { + return facetMinCount; + } + + public WikittyQuery setFacetMinCount(int facetMinCount) { + this.facetMinCount = facetMinCount; + return this; + } + + public int getFacetLimit() { + return facetLimit; + } + + public WikittyQuery setFacetLimit(int facetLimit) { + this.facetLimit = facetLimit; + return this; + } + + public List<Condition> getFacetCriteria() { + if (facetCriteria == null) { + facetCriteria = new LinkedList<Condition>(); + } + return facetCriteria; + } + + public WikittyQuery addFacetCriteria(Condition criteria) { + getFacetCriteria().add(criteria); + return this; + } + + public WikittyQuery setFacetCriteria(Condition ... facetCriteria) { + this.facetCriteria = new LinkedList<Condition>(Arrays.asList(facetCriteria)); + return this; + } + + public List<String> getFacetField() { + if (facetField == null) { + facetField = new LinkedList<String>(); + } + return facetField; + } + + public WikittyQuery addFacetField(String field) { + getFacetField().add(field); + return this; + } + + public WikittyQuery setFacetField(String ... facetField) { + this.facetField = new LinkedList<String>(Arrays.asList(facetField)); + return this; + } + + public WikittyQuery setFacetField(List<String> facetField) { + this.facetField = facetField; + return this; + } + + public boolean isFacetExtension() { + return facetExtension; + } + + public WikittyQuery setFacetExtension(boolean facetExtension) { + this.facetExtension = facetExtension; + return this; + } + + + /** + * Get field names where sort is configured ascending. + * + * @return field names + */ + public List<String> getSortAscending() { + if (sortAscending == null) { + sortAscending = new LinkedList<String>(); + } + return sortAscending; + } + + public WikittyQuery addSortAscending(String ... field) { + getSortAscending().addAll(Arrays.asList(field)); + return this; + } + + public WikittyQuery setSortAscending(String ... sortAscending) { + this.sortAscending = new LinkedList<String>(Arrays.asList(sortAscending)); + return this; + } + + public WikittyQuery setSortAscending(List<String> sortAscending) { + this.sortAscending = sortAscending; + return this; + } + + /** + * Get field names where sort is configured descending. + * + * @return field names + */ + public List<String> getSortDescending() { + if (sortDescending == null) { + sortDescending = new LinkedList<String>(); + } + return sortDescending; + } + + public WikittyQuery addSortDescending(String ... field) { + getSortDescending().addAll(Arrays.asList(field)); + return this; + } + + public WikittyQuery setSortDescending(String ... sortDescending) { + this.sortDescending = new LinkedList<String>(Arrays.asList(sortDescending)); + return this; + } + + public WikittyQuery setSortDescending(List<String> sortDescending) { + this.sortDescending = sortDescending; + return this; + } + + public Condition getCondition() { + return condition; + } + + public WikittyQuery setCondition(Condition condition) { + this.condition = condition; + return this; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,844 @@ +package org.nuiton.wikitty.query; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.query.conditions.And; +import org.nuiton.wikitty.query.conditions.Between; +import org.nuiton.wikitty.query.conditions.Condition; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.Element; +import org.nuiton.wikitty.query.conditions.ElementExtension; +import org.nuiton.wikitty.query.conditions.ElementField; +import org.nuiton.wikitty.query.conditions.ElementId; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.False; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.Keyword; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.Not; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Null; +import org.nuiton.wikitty.query.conditions.Or; +import org.nuiton.wikitty.query.conditions.True; +import org.nuiton.wikitty.query.conditions.Unlike; + +/** + * Cette objet sert a construire une condition a la facon d'un flux. + * <p> + * Condition c = new WikittyQueryMaker().and().eq("ext.field", "toto").eq("ext.field2", 10).getCondition(); + * <p> + * On peut aussi vouloir continuer avec un WikittyQuery pour cela on peut faire. + * <p> + * WikittyQuery q = new WikittyQueryMaker().and().[other condition].end(); + * <p> + * Si un {@link WikittyQuery} est passé en parametre du constructeur et que la + * method {@link #end()} est appeler alors la condition creee est envoyee dans + * le WikittyQuery et le constructeur est fermer (on ne peut plus ajouter de + * condition) + * <p> + * Le WikittyQuery lie avec cet objet lorsqu'on le recupere via la method + * {@link #getQuery()} a en interne comme condition la valuer courante de la + * condition en cours d'ecriture + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQueryMaker { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryMaker.class); + + /** query where to send condition when end() method called */ + protected WikittyQuery query; + + /** query condition */ + protected Condition condition; + /** stack des conditions non terminales ouvertes */ + protected Deque<Condition> openStack = new LinkedList<Condition>(); + + public WikittyQueryMaker() { + } + + public WikittyQueryMaker(WikittyQuery query) { + this.query = query; + } + + public Condition getCondition() { + return condition; + } + + /** + * La query passee dans le constructeur ou une nouvelle query si aucune + * query n'avait ete passee dans le constructeur + * + * @return + */ + public WikittyQuery getQuery() { + if (query == null) { + query = new WikittyQuery(); + } + // la condition de la query doit toujours refleter la valeur courante + // de la condition en cours de creation + query.setCondition(getCondition()); + return query; + } + + /** + * Retourne le stack courant des conditions, si le stack est null cela + * veut dire que le maker ne permet plus de modification + * @return + */ + protected Deque<Condition> getOpenStack() { + if (openStack == null) { + throw new WikittyException( + "You can't create condition if you have used setCondition method" + + " or close last condition"); + } + return openStack; + } + + /** Ajout une condition terminal */ + protected void addCondition(Condition c) { + Condition parent = getOpenStack().peek(); + + if (parent == null) { + // il n'y a rien dans la stack donc rien dans condition, il faut + // mettre cette condition dedans + condition = c; + // on ne met les conditions terminal dans le stack, que lorsque + // c'est la premiere (cela permet d'indiquer a l'utilisateur + // qu'il faut commencer par un or, and, not car une exception sera + // levee + getOpenStack().push(c); + } else { + parent.addCondition(c); + } + } + + /** + * Ajout d'une condition non terminal (or, and, not, join) + * @param c + */ + protected void addOnStack(Condition c) { + Condition parent = getOpenStack().peek(); + getOpenStack().push(c); + + if (parent == null) { + // il n'y a rien dans la stack donc rien dans condition, il faut + // mettre cette condition dedans + condition = c; + } else { + parent.addCondition(c); + } + } + + /////////////////////////////////////////////////////////////////////////// + // + // Q U E R Y F L O W C R E A T I O N + // + /////////////////////////////////////////////////////////////////////////// + + // eq(Wikitty|Date|Number|Boolean|String) + + /** + * Convertie une liste d'objet en une liste de String representant + * les objets + * + * @param l + * @return + */ + static public List<String> convertToQueryStringList(Collection l) { + List<String> result; + if (l == null) { + result = Collections.emptyList(); + } else { + result = new ArrayList<String>(l.size()); + for (Object o : l) { + String s = WikittyUtil.toString(o); + result.add(s); + } + } + return result; + } + + /** + * Contains. + * + * Search on lists (multivalued fields) that a field contains all the values + * of the list given in parameter. + * + * Ex : The field with value [toto,titi,tutu] contains [titi,tutu] but not + * [titi,tutu,tata] + * + * @param element the element on which the restriction is put + * @param values the values to search in the element + * @return {@code this} with the {@code contains} restriction added. + * @see {@link ContainsAll} + */ + public <E> WikittyQueryMaker containsAll(String fqfield, Collection<E> values) { + return containsAll(new ElementField(fqfield), values); + } + + /** + * + * @param element + * @param values + * @return + * @see {@link ContainsAll} + */ + public <E> WikittyQueryMaker containsAll(Element element, Collection<E> values) { + addCondition(new ContainsAll(element, + convertToQueryStringList(values))); + return this; + } + + /** + * Search on lists (multivalued fields) that a field contains all the values + * given in parameter. + * + * Ex : The field with value [toto,titi,tutu] contains [titi,tutu] but not + * [titi,tutu,tata] + * + * Ps : Use wildcards if you search for substrings. + * + * @param element the element on which the restriction is put + * @param value1 first value to search in the field + * @param values list of values to search in the field + * @return {@code this} with the {@code contains} restriction added. + * @see {@link ContainsAll} + */ + public <E> WikittyQueryMaker containsAll(String fqfield, E value1, E ... values) { + List<E> l = new LinkedList<E>(); + l.add(value1); + l.addAll(Arrays.asList(values)); + return containsAll(fqfield, l); + } + + /** + * Search if a field is contained in the list of values in parameter + * + * Ex : The field with value titi is in [titi,tutu] but not in + * [tutu,tata] + * + * @param element the element on which the restriction is put + * @param values list of values the field must be in + * @return {@code this} with the {@code in} restriction added. + * @see {@link ContainsOne} + */ + public <E> WikittyQueryMaker containsOne(String fqfield, Collection<E> values) { + return containsOne(new ElementField(fqfield), values); + } + + /** + * + * @param element + * @param values + * @return + * @see {@link ContainsOne} + */ + public <E> WikittyQueryMaker containsOne(Element element, Collection<E> values) { + addCondition(new ContainsOne(element, + convertToQueryStringList(values))); + return this; + } + + /** + * Search if a field is contained in the list of values in parameter + * + * Ex : The field with value titi is in [titi,tutu] but not in + * [tutu,tata] + * + * Ps : Use wildcards in the values if you search for substrings. + * + * @param element the element on which the restriction is put + * @param value1 first value the field must be in + * @param values list of values the field must be in + * @return {@code this} with the {@code in} restriction added. + * @see {@link ContainsOne} + */ + public <E> WikittyQueryMaker containsOne(String fqfield, E value1, E ... values) { + List<E> l = new LinkedList<E>(); + l.add(value1); + l.addAll(Arrays.asList(values)); + return containsOne(fqfield, l); + } + + /** + * Equals. + * + * Restrict search so that the field value equals the parameter. + * + * You might use patterns in your equality. + * + * @param element the field on which the search is made + * @param value the value the element must be equals to + * @return {@code this} + * @see {@link Equals} + */ + public WikittyQueryMaker eq(String fqfield, Object value) { + return eq(new ElementField(fqfield), value); + } + + /** + * + * @param element + * @param value + * @return + * @see {@link Equals} + */ + public WikittyQueryMaker eq(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new Equals(element, s)); + return this; + } + + /** + * Extension equals. + * + * Restrict search to wikitties that got the extension in parameter. + * + * @param s the extension to restrict the results to + * @return {@code this} with the {@code exteq} restriction added. + * @see {@link Equals} + */ + public WikittyQueryMaker exteq(String extensionName) { + return eq(new ElementExtension(), extensionName); + } + + /** + * Id equals. + * + * Restrict search to wikitties that got the id in parameter. + * + * @param value the id or wikitty to restrict the results to + * @return {@code this} with the {@code ideq} restriction added. + * @see {@link Equals} + */ + public WikittyQueryMaker ideq(Object idOrWikitty) { + return eq(new ElementId(), idOrWikitty); + } + + /** + * Extension equals. + * + * Restrict search to wikitties that got all the extensions in parameter. + * + * @param extensionNames list of the extension to restrict the results to + * @return {@code this} with the {@code exteq} restriction added. + * @see {@link ContainsAll} + */ + public WikittyQueryMaker extContainsAll(Collection<String> extensionNames) { + return containsAll(new ElementExtension(), extensionNames); + } + + /** + * @see {@link ContainsAll} + */ + public WikittyQueryMaker extContainsAll(String ext1, String ... exts) { + List<String> l = new LinkedList<String>(); + l.add(ext1); + l.addAll(Arrays.asList(exts)); + return containsAll(new ElementExtension(), l); + } + + /** + * Not equals. + * + * Restrict search to elements that are not equals to the value given in + * parameter. + * + * @param fqfield the element on which the restriction is put + * @param value the value the element must not be equals to. + * @return {@code this} with the {@code neq} restriction added. + * @see {@link NotEquals} + */ + public WikittyQueryMaker ne(String fqfield, Object value) { + return ne(new ElementField(fqfield), value); + } + + /** + * @see {@link NotEquals} + */ + public WikittyQueryMaker ne(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new NotEquals(element, s)); + return this; + } + + /** + * Extension not equals. + * + * Restrict search to wikitties that do not get the extension given in + * parameter. + * + * @param extensionName the extension that the wikitties must not have. + * @return {@code this} with the {@code extneq} restriction added. + * @see {@link NotEquals} + */ + public WikittyQueryMaker extneq(String extensionName) { + return ne(new ElementExtension(), extensionName); + } + + /** + * Id not equals. + * + * Restrict search to wikitties that do not have the id given in parameter. + * + * @param idOrWikitty the id the wikitties must not have. + * @return {@code this} with the {@code idneq} restriction added. + * @see {@link NotEquals} + */ + public WikittyQueryMaker idneq(Object idOrWikitty) { + return ne(new ElementId(), idOrWikitty); + } + + /** + * Greater than. + * + * Search if an element value is greater than the parameter. + * + * @param fqfield the element on which the restriction is put + * @param value the value to be compared to + * @return {@code this} with the {@code gt} restriction added. + * @see {@link Greater} + */ + public WikittyQueryMaker gt(String fqfield, Object value) { + return gt(new ElementField(fqfield), value); + } + + /** + * @see {@link Greater} + */ + public WikittyQueryMaker gt(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new Greater(element, s)); + return this; + } + + /** + * Greater than or equals. + * + * Search if an element value is greater than or equals to the parameter. + * + * @param fqfield the field on which the search is made + * @param value the value to be compared to + * @return {@code this} with the {@code ge} restriction added. + * @see {@link GreaterOrEquals} + */ + public WikittyQueryMaker ge(String fqfield, Object value) { + return ge(new ElementField(fqfield), value); + } + + /** + * @see {@link GreaterOrEquals} + */ + public WikittyQueryMaker ge(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new GreaterOrEquals(element, s)); + return this; + } + + /** + * Less than. + * + * Search if an element value is less than the parameter. + * + * @param fqfield the element on which the restriction is put + * @param value the value to be compared to + * @return {@code this} with the {@code lt} restriction added. + * @see {@link Less} + */ + public WikittyQueryMaker lt(String fqfield, Object value) { + return lt(new ElementField(fqfield), value); + } + + /** + * @see {@link Less} + */ + public WikittyQueryMaker lt(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new Less(element, s)); + return this; + } + + /** + * Less than or equals. + * + * Search if an element value is less than or equals to the parameter. + * + * @param fqfield the element on which the restriction is put. + * @param value the value to be compared to. + * @return {@code this} with the {@code le} restriction added. + * @see {@link LessOrEquals} + */ + public WikittyQueryMaker le(String fqfield, Object value) { + return le(new ElementField(fqfield), value); + } + + /** + * @see {@link LessOrEquals} + */ + public WikittyQueryMaker le(Element element, Object value) { + String s = WikittyUtil.toString(value); + addCondition(new LessOrEquals(element, s)); + return this; + } + + /** + * Between. + * + * Restrict search so that the element value is between the lower and upper + * values (it can also be equals). + * + * @param fqfield the element on which the restriction is put. + * @param lowerValue the lower bound. + * @param upperValue the upper bound. + * @return {@code this} with the {@code le} restriction added. + * @see {@link Between} + */ + public WikittyQueryMaker bw(String fqfield, Object lowerValue, Object upperValue) { + return bw(new ElementField(fqfield), lowerValue, upperValue); + } + + /** + * @see {@link Between} + */ + public WikittyQueryMaker bw(Element element, Object lowerValue, Object upperValue) { + String min = WikittyUtil.toString(lowerValue); + String max = WikittyUtil.toString(upperValue); + addCondition(new Between(element, min, max)); + return this; + } + + /** + * Starts with. + * + * Search if an element starts with the value in parameter. + * + * @param fqfield the element on which the restriction is put. + * @param value the value the element must start with. + * @return {@code this} with the {@code sw} restriction added. + * @see {@link Equals} + */ + public WikittyQueryMaker sw(String fqfield, Object value) { + return sw(new ElementField(fqfield), value); + } + + /** + * @see {@link Equals} + */ + public WikittyQueryMaker sw(Element element, Object value) { + String s = WikittyUtil.toString(value) + "*"; + addCondition(new Equals(element, s)); + return this; + } + + /** + * Not starts with. + * + * Search if an element does not starts with the value in parameter. + * + * @param fqfield the element on which the restriction is put. + * @param value the value the element must not start with. + * @return {@code this} with the {@code nsw} restriction added. + * @see {@link NotEquals} + */ + public WikittyQueryMaker notsw(String fqfield, Object value) { + return notsw(new ElementField(fqfield), value); + } + + /** + * @see {@link NotEquals} + */ + public WikittyQueryMaker notsw(Element element, Object value) { + String s = WikittyUtil.toString(value) + "*"; + addCondition(new NotEquals(element, s)); + return this; + } + + /** + * Ends with. + * + * Search if an element ends with the value in parameter. + * + * @param fqfield the element on which the restriction is put + * @param value the value the element must ends with. + * @return {@code this} with the {@code ew} restriction added. + * @see {@link Equals} + */ + public WikittyQueryMaker ew(String fqfield, Object value) { + return ew(new ElementField(fqfield), value); + } + + /** + * @see {@link Equals} + */ + public WikittyQueryMaker ew(Element element, Object value) { + String s = "*" + WikittyUtil.toString(value); + addCondition(new Equals(element, s)); + return this; + } + + /** + * Not ends with. + * + * Search if an element does not ends with the value in parameter. + * + * @param fqfield the element on which the restriction is put + * @param value the value the element must not ends with. + * @return {@code this} with the {@code notew} restriction added. + * @see {@link NotEquals} + */ + public WikittyQueryMaker notew(String fqfield, Object value) { + return notew(new ElementField(fqfield), value); + } + + /** + * @see {@link NotEquals} + */ + public WikittyQueryMaker notew(Element element, Object value) { + String s = "*" + WikittyUtil.toString(value); + addCondition(new NotEquals(element, s)); + return this; + } + + /** + * Keyword. + * + * Search if the value in parameter is present in any field of any + * extension. + * + * @param value the value to find. + * @return {@code this} with the {@code keyword} restriction added. + * @see {@link Keyword} + */ + public WikittyQueryMaker keyword(Object value) { + String s = WikittyUtil.toString(value); + addCondition(new Keyword(s)); + return this; + } + + /** + * Is null. + * + * Check that a field is null. + * + * @param fqfield the field that must be null. + * @return {@code this} with the {@code isNull} restriction added. + * @see {@link Null} + */ + public WikittyQueryMaker isNull(String fqfield) { + return isNull(new ElementField(fqfield)); + } + + /** + * @see {@link Null} + */ + public WikittyQueryMaker isNull(Element element) { + addCondition(new Null(element)); + return this; + } + + /** + * Is not null. + * + * Check that a field is not null. + * + * @param fqfield the field that must not be null. + * @return {@code this} with the {@code isNotNull} restriction added. + * @see {@link NotNull} + */ + public WikittyQueryMaker isNotNull(String fqfield) { + return isNotNull(new ElementField(fqfield)); + } + + /** + * @see {@link NotNull} + */ + public WikittyQueryMaker isNotNull(Element element) { + addCondition(new NotNull(element)); + return this; + } + + /** + * False. + * + * Add a restriction that always return false. + * + * @return {@code this} with the {@code rFalse} restriction added. + * @see {@link False} + */ + public WikittyQueryMaker rFalse() { + addCondition(new False()); + return this; + } + + /** + * True. + * + * Add a restriction that always return true. + * + * @return {@code this} with the {@code rTrue} restriction added. + * @see {@link True} + */ + public WikittyQueryMaker rTrue() { + addCondition(new True()); + return this; + } + + /** + * Like. + * + * Check that a string is present in a field. For example "tric" is present + * in "Restriction". + * + * @param fqfield the element on which the restriction is put + * @param value + * @param searchAs + * @return {@code this} + * @see {@link Like} + */ + public WikittyQueryMaker like(String fqfield, Object value) { + return like(new ElementField(fqfield), value); + } + + /** + * @see {@link Like} + */ + public WikittyQueryMaker like(Element element, Object value) { + String s = WikittyUtil.toString(value); + Like c = new Like(element, s); + addCondition(c); + return this; + } + + /** + * Unlike. + * + * @param fqfield the element on which the restriction is put + * @param value + * @param searchAs + * @return {@code this} + * @see {@link Unlike} + */ + public WikittyQueryMaker unlike(String fqfield, String value) { + return unlike(new ElementField(fqfield), value); + } + + /** + * @see {@link Unlike} + */ + public WikittyQueryMaker unlike(Element element, String value) { + String s = WikittyUtil.toString(value); + Unlike c = new Unlike(element, s); + addCondition(c); + return this; + } + + /** + * Not (sub query). To close this sub query you must used {@link #close()} + * <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close(); + * + * @see {@link Not} + */ + public WikittyQueryMaker not() { + Condition child = new Not(); + addOnStack(child); + return this; + } + + /** + * Or (sub query). To close this sub query you must used {@link #close()} + * <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close(); + * + * @see {@link Or} + */ + public WikittyQueryMaker or() { + Condition child = new Or(); + addOnStack(child); + return this; + } + + /** + * And (sub query). To close this sub query you must used {@link #close()} + * <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close(); + * + * @see {@link And} + */ + public WikittyQueryMaker and() { + Condition child = new And(); + addOnStack(child); + + return this; + } + + /** + * Add {@link Join} to allow search on association (like sql join). + * To close this sub query you must used {@link #close()} + * @param foreignFieldName association fieldName + * @return sub query + * @see {@link Join} + */ + public WikittyQueryMaker join(String foreignFieldName) { + return join(new ElementField(foreignFieldName)); + } + + /* + * @see {@link Join} + */ + public WikittyQueryMaker join(Element element) { + Condition child = new Join(element); + addOnStack(child); + return this; + } + + /** + * Close last non terminal condition (or, and, not, join). + * <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close(); + * @return + */ + public WikittyQueryMaker close() { + getOpenStack().pop(); + if (getOpenStack().size() == 0) { + // we just close last open condition, set stack to null, to prevent + // next condition add that is mistake + openStack = null; + } + return this; + } + + /** + * Ferme la construction de la condition et la met en place dans la + * WikittyQuery qui sera retournee + * + * @return un objet WikittyQuery soit un nouveau soit celui passe dans le + * constructeur + */ + public WikittyQuery end() { + WikittyQuery result = getQuery(); + result.setCondition(getCondition()); + // on interdit les modifications futur + openStack = null; + + return result; + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,338 @@ +package org.nuiton.wikitty.query; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.conditions.And; +import org.nuiton.wikitty.query.conditions.Between; +import org.nuiton.wikitty.query.conditions.Condition; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.Element; +import org.nuiton.wikitty.query.conditions.ElementExtension; +import org.nuiton.wikitty.query.conditions.ElementField; +import org.nuiton.wikitty.query.conditions.ElementId; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.False; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Keyword; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.Not; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.Or; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Null; +import org.nuiton.wikitty.query.conditions.True; +import org.nuiton.wikitty.query.conditions.Unlike; +import org.parboiled.BaseParser; +import org.parboiled.Parboiled; +import org.parboiled.Rule; +import org.parboiled.annotations.BuildParseTree; +import org.parboiled.errors.ErrorUtils; +import org.parboiled.parserunners.RecoveringParseRunner; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.support.ParseTreeUtils; +import org.parboiled.support.ParsingResult; +import org.parboiled.support.Var; + +/** + * Cette classe permet d'interpreter une requete faite textuellement en la + * convertisant en sa representation objet. + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +@BuildParseTree +public class WikittyQueryParser extends BaseParser<Object> { + public static final String EXTENSION = "extension"; + public static final String FALSE = "FALSE"; + public static final String ID = "id"; + + public static final String JOIN = "<-"; + public static final String LITERAL_CLOSE = "\""; + public static final String LITERAL_OPEN = "\""; + public static final String NULL = "NULL"; + public static final String TO = "TO"; + public static final String TRUE = "TRUE"; + public static final String UNLIKE = "UNLIKE"; + public static final String AND = "AND"; + public static final String COMMA = ","; + public static final String CURLY_BRACKET_CLOSE = "}"; + public static final String CURLY_BRACKET_OPEN = "{"; + public static final String EQUALS = "="; + public static final String GREATER = ">"; + public static final String GREATER_OR_EQUALS = ">="; + public static final String LESS = "<"; + public static final String LESS_OR_EQUALS = "<="; + public static final String LIKE = "LIKE"; + public static final String NOT = "NOT"; + public static final String NOT_EQUALS = "!="; + public static final String OR = "OR"; + public static final String BRACKET_CLOSE = ")"; + public static final String BRACKET_OPEN = "("; + public static final String SQUARE_BRACKET_CLOSE = "]"; + public static final String SQUARE_BRACKET_OPEN = "["; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryParser.class); + + protected Map<String, String> fieldAlias = new HashMap<String, String>(); + protected Map<String, String> valueAlias = new HashMap<String, String>(); + + public WikittyQueryParser() { + } + + static public WikittyQuery parse(String queryString) { + WikittyQueryParser parser = Parboiled.createParser(WikittyQueryParser.class); + +// ParsingResult<?> result = new RecoveringParseRunner(parser.start()).run(query); + ParsingResult<?> result = new ReportingParseRunner(parser.start()).run(queryString); + + if (result.hasErrors() || !result.matched) { + System.out.println("\nParse Errors:\n" + ErrorUtils.printParseErrors(result)); + } + + if (log.isDebugEnabled()) { + log.debug("\nParse Tree:\n" + ParseTreeUtils.printNodeTree(result) + '\n'); + } +// System.out.println("\nParse Tree:\n" + ParseTreeUtils.printNodeTree(result) + '\n'); + + Condition c = (Condition)result.resultValue; + + WikittyQuery query = new WikittyQuery(c); + return query; + } + + /** + * can be field, extension name or id element + * @param v + * @return + */ + protected Element toElement(String v) { + Element result; + if (ID.equals(v)) { + result = new ElementId(); + } else if (EXTENSION.equals(v)) { + result = new ElementExtension(); + } else { + result = new ElementField(v); + } + return result; + } + + /** + * Remove quote at beginning and ending of String in parameter if necessary + * + * <li>"toto" return toto + * <li>"toto return "toto + * <li> toto return toto" + * <li> to"to return to"to + * + * @param s + * @return + */ + protected String removeQuote(String s) { + String result = s; + if (StringUtils.startsWith(s, LITERAL_OPEN) + && StringUtils.startsWith(s, LITERAL_CLOSE)) { + result = StringUtils.substring(s, 1, -1); + } + return result; + } + + Rule start() { + return Sequence(or(), EOI); + } + + Rule or() { + return Sequence(and(), ZeroOrMore(space(), OR, space(), and(), + push(new Or((Condition)pop(1), (Condition)pop())))); + } + + Rule and() { + return Sequence(term(), ZeroOrMore( + // when no AND or OR is used, AND is default + // don't change order of FirstOf, this order is important + FirstOf(Sequence(space(), AND, space()), Sequence(space(), TestNot(OR))), + term(), + push(new And((Condition)pop(1), (Condition)pop())))); + } + + Rule term() { + return FirstOf(condition(), Parens()); + } + + Rule Parens() { + return Sequence(space(), BRACKET_OPEN, space(), or(), space(), BRACKET_CLOSE, space()); + // FIXME + } + + Rule condition() { + return FirstOf( + not(), isNull(), isNotNull(), + eq(), neq(), less(), lesseq(), greater(), greatereq(), like(), notlike(), + between(), containsAll(), containsOne(), + associated(), rTrue(), rFalse(), keyword() + ); + } + + Rule not() { + return Sequence(space(), NOT, space(), term(), + push(new Not((Condition)pop()))); + } + + /** + * gere eq, startsWith, endsWith, isNull + * @return + */ + Rule isNull() { + return Sequence(field(), push(match()), space(), EQUALS, space(), IgnoreCase(NULL), + push(new Null(toElement(pop().toString())))); + } + + /** + * gere eq, isNull + * @return + */ + Rule isNotNull() { + return Sequence(field(), push(match()), space(), NOT_EQUALS, space(), IgnoreCase(NULL), + push(new NotNull(toElement(pop().toString())))); + } + + /** + * gere eq, startsWith, endsWith, isNull + * @return + */ + Rule eq() { + return Sequence(field(), push(match()), space(), EQUALS, space(), value(), + push(new Equals(toElement(pop().toString()), removeQuote(match())))); + } + + /** + * gere eq, isNull + * @return + */ + Rule neq() { + return Sequence(field(), push(match()), space(), NOT_EQUALS, space(), value(), + push(new NotEquals(toElement(pop().toString()), removeQuote(match())))); + } + + Rule less() { + return Sequence(field(), push(match()), space(), LESS, space(), value(), + push(new Less(toElement(pop().toString()), removeQuote(match())))); + } + Rule lesseq() { + return Sequence(field(), push(match()), space(), LESS_OR_EQUALS, space(), value(), + push(new LessOrEquals(toElement(pop().toString()), removeQuote(match())))); + } + Rule greater() { + return Sequence(field(), push(match()), space(), GREATER, space(), value(), + push(new Greater(toElement(pop().toString()), removeQuote(match())))); + } + Rule greatereq() { + return Sequence(field(), push(match()), space(), GREATER_OR_EQUALS, space(), value(), + push(new GreaterOrEquals(toElement(pop().toString()), removeQuote(match())))); + } + Rule like() { + return Sequence(field(), push(match()), space(), LIKE, space(), value(), + push(new Like(toElement(pop().toString()), removeQuote(match())))); + } + Rule notlike() { + return Sequence(field(), push(match()), space(), UNLIKE, space(), value(), + push(new Unlike(toElement(pop().toString()), removeQuote(match())))); + } + Rule between() { + return Sequence(field(), push(match()), space(), EQUALS, space(), SQUARE_BRACKET_OPEN, space(), + value(), push(removeQuote(match())), space(), TO, space(), + value(), push(removeQuote(match())), space(), SQUARE_BRACKET_CLOSE, + push(new Between(toElement(pop(2).toString()), pop(1).toString(), pop().toString()))); + } + Rule containsAll() { + Var<List<String>> elems = new Var<List<String>>(new LinkedList<String>()); + return Sequence(field(), push(match()), space(), EQUALS, space(), SQUARE_BRACKET_OPEN, space(), + value(), elems.get().add(removeQuote(match())), space(), ZeroOrMore(COMMA, space(), + value(), elems.get().add(removeQuote(match())), space()), SQUARE_BRACKET_CLOSE, + push(new ContainsAll(toElement(pop().toString()), elems.get()))); + } + Rule containsOne() { + Var<List<String>> elems = new Var<List<String>>(new LinkedList<String>()); + return Sequence(field(), push(match()), space(), EQUALS, space(), CURLY_BRACKET_OPEN, space(), + value(), elems.get().add(removeQuote(match())), space(), ZeroOrMore(COMMA, space(), + value(), elems.get().add(removeQuote(match())), space()), CURLY_BRACKET_CLOSE, + push(new ContainsOne(toElement(pop().toString()), elems.get()))); + } + Rule associated() { + return Sequence(field(), push(match()), space(), JOIN, space(), term(), + push(new Join(toElement(pop().toString()), (Condition)pop()))); + } + Rule keyword() { + return Sequence(value(), push(new Keyword(removeQuote(match())))); + } + + Rule field() { + return OneOrMore(FirstOf(CharRange('0', '9'), CharRange('a', 'z'), CharRange('A', 'Z'), AnyOf("_.*"))); + } + + Rule rTrue() { + return Sequence(IgnoreCase(TRUE), push(new True())); + } + + Rule rFalse() { + return Sequence(IgnoreCase(FALSE), push(new False())); + } + + Rule value() { + return FirstOf(IgnoreCase(TRUE), IgnoreCase(FALSE), IgnoreCase(NULL), field(), StringLiteral()); + } + + Rule StringLiteral() { + return Sequence( + LITERAL_OPEN, + ZeroOrMore( + FirstOf( + Escape(), + Sequence(TestNot(AnyOf("\r\n\\"+LITERAL_OPEN+LITERAL_CLOSE)), ANY) + ) + ).suppressSubnodes(), + LITERAL_CLOSE + ); + } + + Rule Escape() { + return Sequence('\\', FirstOf(AnyOf("btnfr\'\\"+LITERAL_OPEN+LITERAL_CLOSE), OctalEscape(), UnicodeEscape())); + } + + Rule OctalEscape() { + return FirstOf( + Sequence(CharRange('0', '3'), CharRange('0', '7'), CharRange('0', '7')), + Sequence(CharRange('0', '7'), CharRange('0', '7')), + CharRange('0', '7') + ); + } + + Rule UnicodeEscape() { + return Sequence(OneOrMore('u'), HexDigit(), HexDigit(), HexDigit(), HexDigit()); + } + + Rule HexDigit() { + return FirstOf(CharRange('a', 'f'), CharRange('A', 'F'), CharRange('0', '9')); + } + + Rule space() { + return ZeroOrMore(AnyOf(" \t\f")); + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,343 @@ +package org.nuiton.wikitty.query; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.WikittyProxy; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.BusinessEntityImpl; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyExtension; + +/** + * Represente un resultat de requete {@link WikittyQuery} + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQueryResult<T> implements Serializable, Iterable<T> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryResult.class); + + private static final long serialVersionUID = 1L; + + /** nom du critere qui a ete uitilise (peut-etre null) si le critete n'avait pas de nom */ + protected String queryName; + /** indice element in global search result */ + protected int first; + /** total number of result if we call the query for all possible result */ + protected int totalResult; + /** query really executed (internal representation depend of search engine used */ + protected String queryString; + /** list of result in the wanted interval */ + protected List<T> results; + /** facet asked or null if no facet */ + protected Map<String, List<FacetTopic>> facets; + /** facet asked of null if no facet, FacetTopic are put in map with key topic name, + * To use this variable, you must used getter, because, this variable is + * lazy loaded from facets variable. + */ + protected Map<String, Map<String, FacetTopic>> facetsAsMap = null; + + + /** + * Init paged result. + * + * we don't initialize securityToken + * + * @param first indice element in global search result + * @param totalResult total number of result if we call the query for all possible result + * @param queryString query really executed + * @param facets facet asked or null if no facet + * @param results list of result in the wanted interval + */ + public WikittyQueryResult(String queryName, + int first, int totalResult, String queryString, + Map<String, List<FacetTopic>> facets, List<T> results) { + this.queryName = queryName; + this.first = first; + this.totalResult = totalResult; + this.queryString = queryString; + this.facets = facets; + this.results = Collections.unmodifiableList(results); + } + + /** + * Call {@link #cast(WikittyProxy, Class, boolean)} with + * autoconvert = true + * + * @param proxy used to retrieve securityToken and WikittyService + * @param clazz target PagedResult type + * @return new PagedResult, this result can have less elements that original + * for some reason (security, ...) + */ + public <E extends BusinessEntityImpl> WikittyQueryResult<E> cast( + WikittyProxy proxy, Class<E> clazz) { + return cast(proxy, clazz, true); + } + + /** + * Convert all result to the wikitty type and return new PagedResult with + * this new result list. + * + * @param securityToken security token + * @param ws wikitty service + * + * @return new PagedResult, this result can have less elements that original + * for some reason (security, ...) + */ + public WikittyQueryResult<Wikitty> WikittyQueryResult(String securityToken, WikittyService ws) { + List<Wikitty> castedResult; + + if (results.size() == 0) { + castedResult = new ArrayList<Wikitty>(); + } else { + if (results.get(0) instanceof String) { + // le pagedresult courant contient des Ids + // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant + // ce PagedResult ne sait pas ce qu'il fait :) + List<String> ids = (List<String>) results; + castedResult = ws.restore(securityToken, ids); + } else { + throw new ClassCastException("WikittyQueryResult don't contains" + + " wikitty String id but " + results.get(0).getClass()); + } + } + WikittyQueryResult<Wikitty> result = new WikittyQueryResult<Wikitty>(queryName, + first, totalResult, queryString, facets, castedResult); + return result; + } + + /** + * Convert all result to the wanted type and return new PagedResult with + * this new result list. If some result don't have the right extension (clazz) + * this extension is automatically added if autoconvert is true. Else + * an exception is thrown when result without extension is found. + * + * When you used autoconvert = false, you have a potentially problem when + * you have modified a BusinessEntity to have new extension and all your + * wikitty object are not uptodate in database. + * + * @param <E> class to cast into + * @param proxy used to retrieve securityToken and WikittyService + * @param autoconvert if autoconvert is false and object don't all needed + * extension, object is not put in the result + * @return new PagedResult, this result can have less elements that original + * for some reason (security, ...) + */ + public <E extends BusinessEntityImpl> WikittyQueryResult<E> cast( + WikittyProxy proxy, Class<E> clazz, boolean autoconvert) { + List<E> castedResult; + + if (results.size() > 0 && results.get(0) instanceof String) { + // le pagedresult courant contient des Ids + // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant + // ce PagedResult ne sait pas ce qu'il fait :) + List<String> ids = (List<String>)results; + castedResult = proxy.restore(clazz, ids, !autoconvert); + } else { + castedResult = new ArrayList<E>(results.size()); + E sample = WikittyUtil.newInstance(clazz); + Collection<WikittyExtension> wantedExtension = sample.getStaticExtensions(); + for (T t : results) { + if (t == null) { + castedResult.add(null); + } else { + Wikitty w = null; + if (t instanceof Wikitty) { + w = (Wikitty) t; + } else if (t instanceof BusinessEntityImpl) { + w = ((BusinessEntityImpl) t).getWikitty(); + } else { + throw new WikittyException(String.format( + "Illegal object result class '%s' can't convert it to class '%s'", + t.getClass().getName(), clazz.getName())); + } + + Collection<WikittyExtension> wikittyExtension = w.getExtensions(); + if (autoconvert || wikittyExtension.containsAll(wantedExtension)) { + E e = WikittyUtil.newInstance(proxy.getSecurityToken(), + proxy.getWikittyService(), clazz, (Wikitty) t); + castedResult.add(e); + } else { + // silently pass current object, this object is not put + // in result + if (log.isDebugEnabled()) { + log.debug(String.format( + "Illegal object result class '%s' can't convert it to '%s'" + + "there is no same extension %s != %s", + t.getClass().getName(), clazz.getName(), + wikittyExtension, wantedExtension)); + } + } + } + } + } + WikittyQueryResult<E> result = new WikittyQueryResult<E>(queryName, + first, totalResult, queryString, facets, castedResult); + return result; + } + + public String getQueryName() { + return queryName; + } + + public int getFirst() { + return first; + } + + public int getTotalResult() { + return totalResult; + } + + public String getQueryString() { + return queryString; + } + + /** + * Return name of all facet used in query. + * + * @return result's facets names + */ + public Collection<String> getFacetNames() { + Collection<String> result = facets.keySet(); + return result; + } + + /** + * Return all topic for the specified facet. + * + * @param facetName name of the wanted facet + * @return facet's topics + */ + public List<FacetTopic> getTopic(String facetName) { + List<FacetTopic> result = facets.get(facetName); + return result; + } + + /** + * Return topic for the specified facet and topic name. + * + * @param facetName name of the wanted facet + * @param topicName name of the wanted topic + * @return topic + */ + public FacetTopic getTopic(String facetName, String topicName) { + FacetTopic result = getFacetsAsMap().get(facetName).get(topicName); + return result; + } + + /** + * Return topic count for the specified facet and topic name. If facet or + * topic don't exist, return 0. + * + * @param facetName name of the wanted facet + * @param topicName name of the wanted topic + * @return topic count or 0 + */ + public int getTopicCount(String facetName, String topicName) { + int result = 0; + if (getFacetsAsMap() != null) { + Map<String, FacetTopic> topics = getFacetsAsMap().get(facetName); + if (topics != null) { + FacetTopic topic = topics.get(topicName); + if (topic != null) { + result = topic.getCount(); + } + } + } + return result; + } + + /** + * Get map represent facets. + * + * @return all facets + */ + public Map<String, List<FacetTopic>> getFacets() { + return facets; + } + + public Map<String, Map<String, FacetTopic>> getFacetsAsMap() { + if (facetsAsMap == null && facets != null) { + // use local variable to prevent multi-thread problem (multiple add) + Map<String, Map<String, FacetTopic>> localFacetsAsMap = + new HashMap<String, Map<String, FacetTopic>>(); + for (Map.Entry<String, List<FacetTopic>> e : getFacets().entrySet()) { + Map<String, FacetTopic> topics = new HashMap<String, FacetTopic>(); + localFacetsAsMap.put(e.getKey(), topics); + for (FacetTopic t : e.getValue()) { + topics.put(t.getTopicName(), t); + } + } + facetsAsMap = localFacetsAsMap; + } + return facetsAsMap; + } + + + + /** + * Return the first element in result + * + * Can throw an exception if no element available + * @return first element + */ + public T peek() { + T result = get(0); + return result; + } + + /** + * Return element at index. + * + * @param i index + * @return element at index + */ + public T get(int i) { + T result = results.get(i); + return result; + } + + /** + * Return unmodifiable list of all result. + * + * @return all results + */ + public List<T> getAll() { + return results; + } + + /** + * Return the number of result in this object. + * + * @return result number + */ + public int size() { + int result = results.size(); + return result; + } + + /** + * Iterate on result, same as getAll().iterator(). + * @return + */ + public Iterator<T> iterator() { + Iterator<T> result = getAll().iterator(); + return result; + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResultTreeNode.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResultTreeNode.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResultTreeNode.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,238 @@ +package org.nuiton.wikitty.query; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import javax.swing.tree.DefaultMutableTreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Represente le resultat de recherche sur un arbre. + * L'iteration se fait en profondeur + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQueryResultTreeNode<T extends Serializable> extends DefaultMutableTreeNode implements Iterable<WikittyQueryResultTreeNode<T>> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryResultTreeNode.class); + + private static final long serialVersionUID = 31L; + + /** optional user object */ + protected T object; + + /** + * Visitor for TreeNodeResult + * @param <T> + */ + static public interface Visitor<T extends Serializable> { + /** + * + * @param node node to visit + * @return if true visit this element + */ + public boolean visitEnter(WikittyQueryResultTreeNode<T> node); + /** + * + * @param node node visited + * @return if true visit next element + */ + public boolean visitLeave(WikittyQueryResultTreeNode<T> node); + } + + protected int attCount; + + /** + * + * @param object L'id, le wikitty ou le BusinessEntity suivant le type de T + * @param attCount le nombre d'attachment pour ce noeud (avec les sous noeud) + */ + public WikittyQueryResultTreeNode(T object, int attCount) { + this(object); + this.attCount = attCount; + } + + /** + * sletellier 20110516 : override all methods using userObject, + * because this one is transient and getter and setters are not used + */ + + /** + * Creates a tree node with no parent, no children, but which allows + * children, and initializes it with the specified user object. + * + * @param userObject an Object provided by the user that constitutes + * the node's data + */ + public WikittyQueryResultTreeNode(T userObject) { + this(userObject, true); + } + + /** + * Creates a tree node with no parent, no children, initialized with + * the specified user object, and that allows children only if + * specified. + * + * @param userObject an Object provided by the user that constitutes + * the node's data + * @param allowsChildren if true, the node is allowed to have child + * nodes -- otherwise, it is always a leaf node + */ + public WikittyQueryResultTreeNode(T userObject, boolean allowsChildren) { + super(userObject, allowsChildren); + this.object = userObject; + } + + /** + * Sets the user object for this node to <code>userObject</code>. + * + * @param userObject the Object that constitutes this node's + * user-specified data + * @see #getUserObject + * @see #toString + */ + public void setUserObject(T userObject) { + super.setUserObject(userObject); + this.object = userObject; + } + + /** + * Returns this node's user object. + * + * @return the Object stored at this node by the user + * @see #toString + */ + @Override + public T getUserObject() { + return object; + } + + /** + * Returns the result of sending <code>toString()</code> to this node's + * user object, or null if this node has no user object. + * + * @see #getUserObject + */ + @Override + public String toString() { + T userObject = getUserObject(); + if (userObject == null) { + return null; + } else { + return userObject.toString(); + } + } + + /** + * Visite en profondeur de l'arbre, il est possible d'arreter la visite + * soit en entrant dans le noeud soit en sortant du noeud, si respectivement + * visitEnter ou visitLeave retourne false. + * + * @param visitor + */ + public boolean acceptVisitor(Visitor<T> visitor) { + if (visitor.visitEnter(this)) { + for (Enumeration e = children(); e.hasMoreElements();) { + WikittyQueryResultTreeNode<T> child = (WikittyQueryResultTreeNode<T>) e.nextElement(); + if (!child.acceptVisitor(visitor)) { + break; + } + } + } + boolean result = visitor.visitLeave(this); + return result; + } + + /** + * Get direct children of this node + * + * @return + */ + public List<WikittyQueryResultTreeNode<T>> getChildren() { + List<WikittyQueryResultTreeNode<T>> result; + if (children == null) { + result = Collections.emptyList(); + } else { + result = Collections.unmodifiableList( + new ArrayList<WikittyQueryResultTreeNode<T>>(children)); + } + return result; + } + + /** + * Iterate on all children or sub-children, in depth first + * @return + */ + @Override + public Iterator<WikittyQueryResultTreeNode<T>> iterator() { + Iterator<WikittyQueryResultTreeNode<T>> result = new Iterator<WikittyQueryResultTreeNode<T>>() { + + protected Enumeration enumDepth = WikittyQueryResultTreeNode.this.depthFirstEnumeration(); + + @Override + public boolean hasNext() { + return enumDepth.hasMoreElements(); + } + + @Override + public WikittyQueryResultTreeNode<T> next() { + WikittyQueryResultTreeNode<T> result = (WikittyQueryResultTreeNode<T>)enumDepth.nextElement(); + return result; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + return result; + } + + /** + * Retourne l'objet associe avec ce noeud (id, wikitty ou BusinessEntity) + * @return l'objet associe avec ce noeud (id, wikitty ou BusinessEntity) + */ + public T getObject() { + return getUserObject(); + } + + /** + * Return TreeNodeResult where object in TreeNodeResult equals child in + * parameter + * @param child + * @return + */ + public WikittyQueryResultTreeNode<T> getChild(T child) { + WikittyQueryResultTreeNode<T> result = null; + if (child != null) { + for (Enumeration e = children(); e.hasMoreElements();) { + WikittyQueryResultTreeNode<T> r = (WikittyQueryResultTreeNode<T>) e.nextElement(); + if (child.equals(r.getObject())) { + result = r; + break; + } + } + } + return result; + } + + /** + * Retourn le nombre d'attachment pour ce noeud (avec les sous noeud) + * @return + */ + public int getAttCount() { + return attCount; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,280 @@ +package org.nuiton.wikitty.query; + +import java.lang.reflect.Method; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.query.conditions.And; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.Between; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.False; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Keyword; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.Not; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Null; +import org.nuiton.wikitty.query.conditions.Or; +import org.nuiton.wikitty.query.conditions.True; +import org.nuiton.wikitty.query.conditions.Unlike; + +/** + * Permet d'implanter un visiteur de Query ou Condition. Une fois que vous avez + * cree votre propre Visiteur pour l'utiliser + * + * <pre> + * WikittyQuery q = ...; + * MyVisitor v = new MyVisitor(); + * q.accept(v); + * v.getXXXX() + * </pre> + * + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class WikittyQueryVisitor { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryVisitor.class); + + /** + * True if we want visit sub-element, otherwize false + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean visitEnter(WikittyQuery o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void visitLeave(WikittyQuery o, boolean enterOrMiddleResult); + /** + * True if we want visit sub-element, otherwize false + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean visitEnter(And o); + /** + * True if we want visit others elements, otherwize false. If false + * visitMiddle for this node is never called + * @param o + * @return True if we want visit others elements, otherwize false + */ + abstract public boolean visitMiddle(And o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void visitLeave(And o, boolean enterOrMiddleResult); + /** + * True if we want visit sub-element, otherwize false + * visitMiddle for this node is never called + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean visitEnter(Or o); + /** + * True if we want visit others elements, otherwize false + * @param o + * @return True if we want visit others elements, otherwize false + */ + abstract public boolean visitMiddle(Or o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void visitLeave(Or o, boolean enterOrMiddleResult); + /** + * True if we want visit sub-element, otherwize false + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean visitEnter(Join o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void visitLeave(Join o, boolean enterOrMiddleResult); + /** + * True if we want visit sub-element, otherwize false + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean visitEnter(Not o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void visitLeave(Not o, boolean enterOrMiddleResult); + + abstract public void visit(Between o); + /** + * Can be used for id, extension or field + * @param o + */ + abstract public void visit(ContainsAll o); + /** + * Can be used for id, extension or field + * @param o + */ + abstract public void visit(ContainsOne o); + /** + * Can be used for id, extension or field + * @param o + */ + abstract public void visit(Equals o); + /** + * Can be used for id, extension or field + * @param o + */ + abstract public void visit(NotEquals o); + abstract public void visit(False o); + abstract public void visit(True o); + abstract public void visit(Greater o); + abstract public void visit(GreaterOrEquals o); + abstract public void visit(Keyword o); + abstract public void visit(Less o); + abstract public void visit(LessOrEquals o); + abstract public void visit(Like o); + abstract public void visit(Unlike o); + abstract public void visit(Null o); + abstract public void visit(NotNull o); + + abstract public void defaultVisit(Object o); + /** + * True if we want visit sub-element, otherwize false + * @param o + * @return True if we want visit sub-element, otherwize false + */ + abstract public boolean defaultVisitEnter(Object o); + /** + * True if we want visit others elements, otherwize false + * visitMiddle for this node is never called + * @param o + * @return True if we want visit others elements, otherwize false + */ + abstract public boolean defaultVisitMiddle(Object o); + /** + * Leave method is alway called, but evaluation of enter is passed in + * arguement + * + * @param o + * @param enterOrMiddleResult result returned by visitEnter method + */ + abstract public void defaultVisitLeave(Object o, boolean enterOrMiddleResult); + + public void visit(Object object) { + try { + Method downPolymorphic = this.getClass().getMethod("visit", + new Class[] { object.getClass() }); + + if (downPolymorphic == null) { + defaultVisit(object); + } else { + try { + downPolymorphic.invoke(this, new Object[] {object}); + } catch (Exception eee) { + throw new WikittyException("Error during visitor call", eee); + } + } + } + catch (NoSuchMethodException eee) { + log.debug("Can't call specific visit method, call defaultVisit", eee); + this.defaultVisit(object); + } + } + public boolean visitEnter(Object object) { + boolean result; + try { + Method downPolymorphic = this.getClass().getMethod("visitEnter", + new Class[] { object.getClass() }); + + if (downPolymorphic == null) { + result = defaultVisitEnter(object); + } else { + try { + result = (Boolean)downPolymorphic.invoke(this, new Object[] {object}); + } catch (Exception eee) { + throw new WikittyException("Error during visitor call", eee); + } + } + } + catch (NoSuchMethodException eee) { + log.debug("Can't call specific visit method, call defaultVisitEnter", eee); + result = defaultVisitEnter(object); + } + return result; + } + + public boolean visitMiddle(Object object) { + boolean result; + try { + Method downPolymorphic = this.getClass().getMethod("visitMiddle", + new Class[] { object.getClass() }); + + if (downPolymorphic == null) { + result = defaultVisitMiddle(object); + } else { + try { + result = (Boolean)downPolymorphic.invoke(this, new Object[] {object}); + } catch (Exception eee) { + throw new WikittyException("Error during visitor call", eee); + } + } + } + catch (NoSuchMethodException eee) { + log.debug("Can't call specific visit method, call defaultVisitMiddle", eee); + result = defaultVisitMiddle(object); + } + return result; + } + + public void visitLeave(Object object, boolean enterOrMiddleResult) { + try { + Method downPolymorphic = this.getClass().getMethod("visitLeave", + new Class[] { object.getClass(), Boolean.TYPE }); + + if (downPolymorphic == null) { + defaultVisitLeave(object, enterOrMiddleResult); + } else { + try { + downPolymorphic.invoke(this, new Object[] {object, enterOrMiddleResult}); + } catch (Exception eee) { + throw new WikittyException("Error during visitor call", eee); + } + } + } + catch (NoSuchMethodException eee) { + log.debug("Can't call specific visit method, call defaultVisitLeave", eee); + this.defaultVisitLeave(object, enterOrMiddleResult); + } + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,241 @@ +package org.nuiton.wikitty.query; + +import java.util.ArrayList; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.conditions.And; +import org.nuiton.wikitty.query.conditions.Between; +import org.nuiton.wikitty.query.conditions.Condition; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.False; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.Keyword; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.Not; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Null; +import org.nuiton.wikitty.query.conditions.Or; +import org.nuiton.wikitty.query.conditions.True; +import org.nuiton.wikitty.query.conditions.Unlike; + +/** + * This visitor make a deep copy of WikittyQuery. + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + * @see {@link WikittyQuery#copy()} + */ +public class WikittyQueryVisitorCopy extends WikittyQueryVisitor { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryVisitorCopy.class); + + protected WikittyQueryMaker queryMaker; + + protected WikittyQueryMaker getQueryMaker() { + if (queryMaker == null) { + queryMaker = new WikittyQueryMaker(); + } + return queryMaker; + } + + public WikittyQuery getQuery() { + WikittyQuery result = getQueryMaker().getQuery(); + return result; + } + + @Override + public boolean visitEnter(WikittyQuery o) { + WikittyQuery q = getQuery(); + q.setFacetField(new ArrayList<String>(o.getFacetField())); + q.setFacetLimit(o.getFacetLimit()); + q.setFacetMinCount(o.getFacetMinCount()); + q.setFirst(o.getFirst()); + q.setLimit(o.getLimit()); + q.setName(o.getName()); + q.setSelect(o.getSelect()); + q.setSortAscending(new ArrayList<String>(o.getSortAscending())); + q.setSortDescending(new ArrayList<String>(o.getSortDescending())); + + for (Condition c : o.getFacetCriteria()) { + WikittyQueryVisitorCopy v = new WikittyQueryVisitorCopy(); + c.accept(v); + Condition facetCriteria = v.getQueryMaker().getCondition(); + q.addFacetCriteria(facetCriteria); + } + return true; + } + + @Override + public void visitLeave(WikittyQuery o, boolean enterResult) { + } + + @Override + public boolean visitEnter(And o) { + getQueryMaker().and(); + return true; + } + + @Override + public boolean visitMiddle(And o) { + return true; + } + + @Override + public void visitLeave(And o, boolean enterResult) { + getQueryMaker().close(); + } + + @Override + public boolean visitEnter(Or o) { + getQueryMaker().or(); + return true; + } + + @Override + public boolean visitMiddle(Or o) { + return true; + } + + @Override + public void visitLeave(Or o, boolean enterResult) { + getQueryMaker().close(); + } + + @Override + public boolean visitEnter(Join o) { + getQueryMaker().join(o.getElement()); + return true; + } + + @Override + public void visitLeave(Join o, boolean enterResult) { + getQueryMaker().close(); + } + + @Override + public boolean visitEnter(Not o) { + getQueryMaker().not(); + return true; + } + + @Override + public void visitLeave(Not o, boolean enterResult) { + getQueryMaker().close(); + } + + @Override + public void visit(Between o) { + getQueryMaker().bw(o.getElement(), o.getMin(), o.getMax()); + } + + @Override + public void visit(ContainsAll o) { + getQueryMaker().containsAll(o.getElement(), new ArrayList<String>(o.getValues())); + } + + @Override + public void visit(ContainsOne o) { + getQueryMaker().containsOne(o.getElement(), new ArrayList<String>(o.getValues())); + } + + @Override + public void visit(Equals o) { + getQueryMaker().eq(o.getElement(), o.getValue()); + } + + @Override + public void visit(False o) { + getQueryMaker().rFalse(); + } + + @Override + public void visit(Greater o) { + getQueryMaker().gt(o.getElement(), o.getValue()); + } + + @Override + public void visit(GreaterOrEquals o) { + getQueryMaker().ge(o.getElement(), o.getValue()); + } + + @Override + public void visit(Keyword o) { + getQueryMaker().keyword(o.getValue()); + } + + @Override + public void visit(Less o) { + getQueryMaker().lt(o.getElement(), o.getValue()); + } + + @Override + public void visit(LessOrEquals o) { + getQueryMaker().le(o.getElement(), o.getValue()); + } + + @Override + public void visit(Like o) { + getQueryMaker().like(o.getElement(), o.getValue()); + } + + @Override + public void visit(NotEquals o) { + getQueryMaker().ne(o.getElement(), o.getValue()); + } + + @Override + public void visit(Null o) { + getQueryMaker().isNull(o.getElement()); + } + + @Override + public void visit(NotNull o) { + getQueryMaker().isNotNull(o.getElement()); + } + + @Override + public void visit(True o) { + getQueryMaker().rTrue(); + } + + @Override + public void visit(Unlike o) { + getQueryMaker().unlike(o.getElement(), o.getValue()); + } + + @Override + public void defaultVisit(Object o) { + throw new UnsupportedOperationException( + "Not supported (" + o.getClass().getSimpleName() + ")."); + } + + @Override + public boolean defaultVisitEnter(Object o) { + throw new UnsupportedOperationException( + "Not supported (" + o.getClass().getSimpleName() + ")."); + } + + @Override + public boolean defaultVisitMiddle(Object o) { + throw new UnsupportedOperationException( + "Not supported (" + o.getClass().getSimpleName() + ")."); + } + + @Override + public void defaultVisitLeave(Object o, boolean enterResult) { + throw new UnsupportedOperationException( + "Not supported (" + o.getClass().getSimpleName() + ")."); + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,263 @@ +package org.nuiton.wikitty.query; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.conditions.And; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.Between; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.False; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Keyword; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.Not; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Null; +import org.nuiton.wikitty.query.conditions.Or; +import org.nuiton.wikitty.query.conditions.True; +import org.nuiton.wikitty.query.conditions.Unlike; + +/** + * Genere un texte representant une query tel qu'un homme pourrait l'ecrire + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQueryVisitorToString extends WikittyQueryVisitor { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryVisitorToString.class); + + public String text = ""; + + public String getText() { + return text; + } + @Override + public boolean visitEnter(WikittyQuery o) { + text += o.getName() + "("; + return true; + } + + @Override + public void visitLeave(WikittyQuery o, boolean enterResult) { + text += ")"; + } + + @Override + public boolean visitEnter(And o) { + text += WikittyQueryParser.BRACKET_OPEN; + return true; + } + + @Override + public boolean visitMiddle(And o) { + text += " " + WikittyQueryParser.AND + " "; + return true; + } + + @Override + public void visitLeave(And o, boolean enterResult) { + text += WikittyQueryParser.BRACKET_CLOSE; + } + + @Override + public boolean visitEnter(Or o) { + text += WikittyQueryParser.BRACKET_OPEN; + return true; + } + + @Override + public boolean visitMiddle(Or o) { + text += " " + WikittyQueryParser.OR + " "; + return true; + } + + @Override + public void visitLeave(Or o, boolean enterResult) { + text += WikittyQueryParser.BRACKET_CLOSE; + } + + @Override + public boolean visitEnter(Join o) { + text += o.getElement().getValue() + WikittyQueryParser.JOIN + WikittyQueryParser.BRACKET_OPEN; + return true; + } + + @Override + public void visitLeave(Join o, boolean enterResult) { + text += WikittyQueryParser.BRACKET_CLOSE; + } + + @Override + public boolean visitEnter(Not o) { + text += WikittyQueryParser.NOT + WikittyQueryParser.BRACKET_OPEN; + return true; + } + + @Override + public void visitLeave(Not o, boolean enterResult) { + text += WikittyQueryParser.BRACKET_CLOSE; + } + + @Override + public void visit(Between o) { + text += o.getElement().getValue() + + WikittyQueryParser.EQUALS + WikittyQueryParser.SQUARE_BRACKET_OPEN + + WikittyQueryParser.LITERAL_OPEN + + o.getMin() + + WikittyQueryParser.LITERAL_CLOSE + + " " + WikittyQueryParser.TO + " " + + WikittyQueryParser.LITERAL_OPEN + + o.getMax() + + WikittyQueryParser.LITERAL_CLOSE + + WikittyQueryParser.SQUARE_BRACKET_CLOSE; + } + + @Override + public void visit(ContainsAll o) { + text += o.getElement().getValue() + + WikittyQueryParser.EQUALS + WikittyQueryParser.SQUARE_BRACKET_OPEN; + String sep = ""; + for(String e : o.getValues()) { + text += sep + WikittyQueryParser.LITERAL_OPEN + e + WikittyQueryParser.LITERAL_CLOSE; + sep = WikittyQueryParser.COMMA; + } + text += WikittyQueryParser.SQUARE_BRACKET_CLOSE; + } + + @Override + public void visit(ContainsOne o) { + text += o.getElement().getValue() + + WikittyQueryParser.EQUALS + WikittyQueryParser.CURLY_BRACKET_CLOSE; + String sep = ""; + for(String e : o.getValues()) { + text += sep + WikittyQueryParser.LITERAL_OPEN + e + WikittyQueryParser.LITERAL_CLOSE; + sep = WikittyQueryParser.COMMA; + } + text += WikittyQueryParser.CURLY_BRACKET_CLOSE; + } + + @Override + public void visit(Equals o) { + text += o.getElement().getValue() + + WikittyQueryParser.EQUALS + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(False o) { + text += WikittyQueryParser.FALSE; + } + + @Override + public void visit(Greater o) { + text += o.getElement().getValue() + + WikittyQueryParser.GREATER + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(GreaterOrEquals o) { + text += o.getElement().getValue() + + WikittyQueryParser.GREATER_OR_EQUALS + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(Keyword o) { + text += WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(Less o) { + text += o.getElement().getValue() + + WikittyQueryParser.LESS + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(LessOrEquals o) { + text += o.getElement().getValue() + + WikittyQueryParser.LESS_OR_EQUALS + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(Like o) { + text += o.getElement().getValue() + + " " + WikittyQueryParser.LIKE + " " + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(NotEquals o) { + text += o.getElement().getValue() + + WikittyQueryParser.NOT_EQUALS + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void visit(Null o) { + text += o.getElement().getValue() + + WikittyQueryParser.EQUALS + WikittyQueryParser.NULL; + } + + @Override + public void visit(NotNull o) { + text += o.getElement().getValue() + + WikittyQueryParser.NOT_EQUALS + WikittyQueryParser.NULL; + } + + @Override + public void visit(True o) { + text += WikittyQueryParser.TRUE; + } + + @Override + public void visit(Unlike o) { + text += o.getElement().getValue() + + " " + WikittyQueryParser.UNLIKE + " " + WikittyQueryParser.LITERAL_OPEN + + o.getValue() + + WikittyQueryParser.LITERAL_CLOSE; + } + + @Override + public void defaultVisit(Object o) { + throw new UnsupportedOperationException("Not supported:" + o.getClass()); + } + + @Override + public boolean defaultVisitEnter(Object o) { + throw new UnsupportedOperationException("Not supported:" + o.getClass()); + } + + @Override + public boolean defaultVisitMiddle(Object o) { + throw new UnsupportedOperationException("Not supported:" + o.getClass()); + } + + @Override + public void defaultVisitLeave(Object o, boolean enterResult) { + throw new UnsupportedOperationException("Not supported:" + o.getClass()); + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/And.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/And.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/And.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,42 @@ +package org.nuiton.wikitty.query.conditions; + +import java.util.Arrays; +import java.util.List; + +/** + * And operator is used to build conjunctive restriction for request on content. + * It take at least 2 args. <br> + * <br> + * For example, use: + * <ul> + * <li>{@link WikittyQueryMaker}.and( restriction1, restriction2 )</li> + * <li>{@link WikittyQueryMaker}.and( restriction1, restriction2, restriction3 )</li> + * <li>{@link WikittyQueryMaker}.and( my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> + * </ul> + + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class And extends ConditionNary{ + + private static final long serialVersionUID = 1L; + + public And(Condition ... c) { + super(Arrays.asList(c)); + } + + /** + * Constructor with all parameters initialized, parameter list is copied + * internaly + * + * @param restrictions + */ + public And(List<Condition> restrictions) { + super(restrictions); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Between.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Between.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Between.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,32 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Between operator is used to build restriction containing "min < element + * < max" where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.between( myElement , "15.5" , "22.5" ) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Between extends TerminalTernaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Constructor with all parameters initialized + * + * @param element + * @param min + * @param max + */ + public Between(Element element, String min, String max) { + super(element, min, max); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Condition.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Condition.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Condition.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,119 @@ +package org.nuiton.wikitty.query.conditions; + +import java.io.Serializable; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.query.WikittyQueryVisitor; +import org.nuiton.wikitty.query.WikittyQueryVisitorToString; + +/** + * This element is a symbolic interface implemented by all operators used to + * request contents (And, Or, Not, Equals, NotEquals, EndsWith, ...). + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class Condition implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public Condition() { + super(); + } + + /** + * For non terminal condition this method add subCondition. + * For terminal this method must return an exception + * + * @param c + */ + public void addCondition(Condition c) { + throw new WikittyException("Add condition is not allowed in this condition type"); + } + + public void accept(WikittyQueryVisitor visitor) { + visitor.visit(this); + } + + +// /** +// * Constructor with all parameters initialized +// * +// * @param name +// */ +// public Restriction(RestrictionName name) { +// this(); +// this.name = name; +// } + +// /** +// * Return name +// * +// * @return +// */ +// public RestrictionName getName() { +// return name; +// } +// +// /** +// * Set a value to parameter name. +// * +// * @param name +// */ +// public void setName(RestrictionName name) { +// this.name = name; +// } + + /** + * Equality test based on class equality + * + * @param other Value to compare + */ + @Override + public boolean equals(Object other) { + boolean result; + if (other == null) { + result = false; + } else if (this == other) { + result = true; + }else if (this.getClass().equals(other.getClass())) { + result = equalsDeep(other); + } else { + return false; + } + return result; + } + + /** + * Sub class must override this method to check if internal state is same + * in two object (this and other) + * + * @param other other parameter is same type that this object + * @return true if other and this are equals + */ + abstract boolean equalsDeep(Object other); + + @Override + public int hashCode() { + // equals use objects that are not constant through time + // then, unable to create hashCode from those objects + // returning a constant hash-code + return this.getClass().hashCode(); + } + + @Override + public String toString() { + WikittyQueryVisitorToString v = new WikittyQueryVisitorToString(); + accept(v); + String result = v.getText(); + return result; + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionNary.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionNary.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionNary.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,87 @@ +package org.nuiton.wikitty.query.conditions; + +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.WikittyQueryVisitor; + +/** + * Cette classe est la classe parente de tous les objets ayant en interne + * une liste de restrictions non terminale (ex: And, Or) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class ConditionNary extends Condition { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ConditionNary.class); + + protected List<Condition> conditions; + + public ConditionNary() { + } + + /** + * Initialyse condition with list passed in argument, parameter list is + * copied internaly to prevent extern modification + * + * @param c + */ + public ConditionNary(List<Condition> c) { + this.conditions = new LinkedList<Condition>(c); + } + + @Override + public void accept(WikittyQueryVisitor visitor) { + boolean walk = visitor.visitEnter(this); + if (walk && conditions != null) { + boolean notFirst = false; + for (Condition r : conditions) { + if (notFirst) { + walk = visitor.visitMiddle(this); + if (!walk) { + // le visiteur demande l'arret de la visite + break; + } + } else { + notFirst = true; + } + r.accept(visitor); + } + } + visitor.visitLeave(this, walk); + } + + @Override + boolean equalsDeep(Object other) { + ConditionNary op = (ConditionNary)other; + boolean result = ObjectUtils.equals( + this.getConditions(), op.getConditions()); + return result; + } + + /** + * Return Restriction list. This list is never null, but can be empty + * @return + */ + public List<Condition> getConditions() { + if (conditions == null) { + conditions = new LinkedList<Condition>(); + } + return conditions; + } + + @Override + public void addCondition(Condition c) { + getConditions().add(c); + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionUnary.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionUnary.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ConditionUnary.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,63 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.query.WikittyQueryVisitor; + +/** + * Cette classe est la classe parente de tous les objets ayant en interne + * une restriction non terminale (ex: Not) + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class ConditionUnary extends Condition { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ConditionUnary.class); + + protected Condition subCondition; + + public ConditionUnary() { + } + + public ConditionUnary(Condition restriction) { + this.subCondition = restriction; + } + + @Override + public void addCondition(Condition c) { + if (subCondition == null) { + this.subCondition = c; + } else { + throw new WikittyException("ConditionUnary ("+getClass().getSimpleName()+") can't have more than one condition"); + } + } + + @Override + public void accept(WikittyQueryVisitor visitor) { + boolean walk = visitor.visitEnter(this); + if (walk && subCondition != null) { + subCondition.accept(visitor); + } + visitor.visitLeave(this, walk); + } + + @Override + boolean equalsDeep(Object other) { + ConditionUnary op = (ConditionUnary)other; + boolean result = ObjectUtils.equals( + this.getSubCondition(), op.getSubCondition()); + return result; + } + + public Condition getSubCondition() { + return subCondition; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsAll.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsAll.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsAll.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,41 @@ +package org.nuiton.wikitty.query.conditions; + +import java.util.Collection; + +/** + * ContainsAll permet de definir qu'un champs doit avoir toutes une serie de + * valeur en meme temps. Cette condition ne s'applique donc qu'a des champs de + * type Collection (sauf si on fait un ContainsAll avec une seul valeur, ce qui + * revient a faire un {@link Equals}) + * <p> + * For example, use: + * <ul> + * <li>RestrictionHelper.containsAll( myElement , "value1" )</li> + * <li>RestrictionHelper.containsAll( myElement , "value1", "value2", ... )</li> + * <li>RestrictionHelper.containsAll( myElement , + * a_list_containing_at_least_one_string )</li> + * </ul> + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class ContainsAll extends TerminalBinaryListOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public ContainsAll(Element element, Collection<String> values) { + super(element, values); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsOne.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsOne.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ContainsOne.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,65 @@ +/* + * #%L + * Wikitty :: api + * + * $Id: ContainsOne.java -1 $ + * $HeadURL: http://svn.nuiton.org/svn/wikitty/trunk/wikitty-api/src/main/java/org.nuiton... $ + * %% + * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.wikitty.query.conditions; + +import java.util.Collection; + +/** + * ContainsOne permet de definir qu'un champs doit avoir au moins une des valeurs + * d'une serie de valeurs. Si cette condition est utilisee avec une seul valeur, + * cela revient a faire un {@link Equals}) + * <p> + * For example, use: + * <ul> + * <li>RestrictionHelper.containsOne( myElement , "value1" )</li> + * <li>RestrictionHelper.containsOne( myElement , "value1", "value2", ... )</li> + * <li>RestrictionHelper.containsOne( myElement , + * a_list_containing_at_least_one_string )</li> + * </ul> + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class ContainsOne extends TerminalBinaryListOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public ContainsOne(Element element, Collection<String> values) { + super(element, values); + } + + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Element.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Element.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Element.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,65 @@ +package org.nuiton.wikitty.query.conditions; + +import java.io.Serializable; +import org.apache.commons.lang.ObjectUtils; + +/** + * Class mere qui determine sur quoi porte une condition. Les classes filles + * possible sont par exemple: ElementField, ElementId, ElementExtension + * + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Element implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected String value; + + public Element() { + } + + public Element(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object obj) { + boolean result; + + if (this == obj) { + result = true; + } else if (obj == null) { + result = false; + } else if (ObjectUtils.equals(this.getClass(), obj.getClass())) { + Element e = (Element)obj; + result = ObjectUtils.equals(this.getValue(), e.getValue()); + } else { + result = false; + } + return result; + } + + @Override + public int hashCode() { + // a priori, pas de probleme pour utiliser value pour la hash car pas + // moyen de changer sa valeur, une fois l'objet cree + return ObjectUtils.hashCode(this.getValue()); + } + + @Override + public String toString() { + return value; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementExtension.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementExtension.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementExtension.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,29 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.WikittyQueryParser; + +/** + * Un element qui represente les extensions + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class ElementExtension extends Element { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ElementExtension.class); + + private static final long serialVersionUID = 1L; + + public ElementExtension() { + super(WikittyQueryParser.EXTENSION); + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementField.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementField.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementField.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,35 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyUtil; + +/** + * Element qui porte sur un champs. Le champs doit-ete de la forme + * extname.fieldname. Mais extname ou fieldname ou les deux peuvent etre + * remplace par des *. Au lieu de faire '*.*' il est preferable d'utiliser + * {@link #ALL_FIELD} + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class ElementField extends Element { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ElementField.class); + + private static final long serialVersionUID = 1L; + + static final public ElementField ALL_FIELD = + new ElementField("*" + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + "*"); + + public ElementField(String value) { + super(value); + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementId.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementId.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/ElementId.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,29 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.query.WikittyQueryParser; + +/** + * Element qui represente l'Id + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class ElementId extends Element { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ElementId.class); + + private static final long serialVersionUID = 1L; + + public ElementId() { + super(WikittyQueryParser.ID); + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Equals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Equals.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Equals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,56 @@ +/* + * #%L + * Wikitty :: api + * + * $Id: Equals.java 1136 2011-08-12 14:24:03Z tchemit $ + * $HeadURL: http://svn.nuiton.org/svn/wikitty/trunk/wikitty-api/src/main/java/org.nuiton... $ + * %% + * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.wikitty.query.conditions; + +import org.nuiton.wikitty.query.WikittyQueryMaker; + +/** + * Equals operator is used to build restriction containing "field == value" + * where value could be an Id, a String, an Integer, a Float or a Date, ... + * <p> + * For example, use: {@link WikittyQueryMaker}.eq( myElement , "REF1234567890" ) + * <p> + * This operator used for String check strict equality (case sensitive) + * You can used '*' in expression at beginning or ending for String equality. + * + * <li> {@link WikittyQueryMaker}.eq("myext.myfield", "*jour") match field "bonjour" but not "BONJOUR" + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Equals extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Equals(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/False.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/False.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/False.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,24 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Always False + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class False extends TerminalOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public False() { + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Greater.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Greater.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Greater.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,27 @@ +package org.nuiton.wikitty.query.conditions; + +import org.nuiton.wikitty.query.WikittyQueryMaker; + +/** + * Greater operator is used to build restriction containing "field > value" + * where value could be a Integer, a Float or a Date, String (must be comparable). <br> + * <br> + * For example, use: {@link WikittyQueryMaker}.less( myField , new Date()) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Greater extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Greater(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/GreaterOrEquals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/GreaterOrEquals.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/GreaterOrEquals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,27 @@ +package org.nuiton.wikitty.query.conditions; + +import org.nuiton.wikitty.query.WikittyQueryMaker; + +/** + * GreatOrEqual operator is used to build restriction containing "element >= + * value" where element could be a Integer, a Float, a Date, ... (must be Comparable)<br> + * <br> + * For example, use: {@link WikittyQueryMaker}.greatEq( myElement, new Date()) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class GreaterOrEquals extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public GreaterOrEquals(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Join.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Join.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Join.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,51 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.lang.ObjectUtils; + +/** + * Join is used to join to Wikitty type. + * + * ex: + * <li> {@link WikittyQueryMaker}.join(myfield).eq(otherwikittyfield, "toto") + * is equivalent to + * <li> {@link WikittyQueryMaker}.containsOne(myfield, id1, id2, id3) + * where [id1, id2, id3] is id retrieved by query eq(otherwikittyfield, "toto") + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Join extends ConditionUnary { + + private static final long serialVersionUID = 1L; + + protected Element element; + + public Join(Element element) { + this.element = element; + } + + public Join(Element element, Condition restriction) { + super(restriction); + this.element = element; + } + + public Element getElement() { + return element; + } + + @Override + boolean equalsDeep(Object other) { + boolean result = super.equalsDeep(other); + if (result) { + Join op = (Join)other; + result = ObjectUtils.equals(this.getElement(), op.getElement()); + } + return result; + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Keyword.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Keyword.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Keyword.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,29 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Search keyword in all wikitty. All field is converted to String + * representation and comparaison is done in ignore case mode, if one field + * contains value the wikitty must be returned. + * + * ex: + * <li>field value is 'bonjour le monde' + * <li>keyword is 'le' or 'bon' or 'nde' + * + * wikitty with this field must be returned + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Keyword extends TerminalBinaryOperator { + + private static final long serialVersionUID = 1L; + + public Keyword(String value) { + super(ElementField.ALL_FIELD, value); + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Less.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Less.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Less.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,27 @@ +package org.nuiton.wikitty.query.conditions; + +import org.nuiton.wikitty.query.WikittyQueryMaker; + +/** + * Less operator is used to build restriction containing "element < value" + * where element could be a Integer, a Float, a Date, .... (must be Comparable) <br> + * <br> + * For example, use: {@link WikittyQueryMaker}.less( myElement, new Date()) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Less extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Less(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/LessOrEquals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/LessOrEquals.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/LessOrEquals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,25 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * LessOrEqual operator is used to build restriction containing "element <= + * value" where element could be a Integer, a Float, a Date, ... (must be comparable) <br> + * <br> + * For example, use: RestrictionHelper.lessEq( myElement, new Date()) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class LessOrEquals extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public LessOrEquals(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Like.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Like.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Like.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,27 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Like is use on String field type, you can use '*' at beginning or ending + * to match all char. (ex: ext.field LIKE 'deb*' match 'debut' or 'debout' ... + * <p> + * comparaison is done in ignore case mode, if you wan't case sensitive + * comparaison you must used {@link Equals} + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ + + +public class Like extends TerminalBinaryOperator { + // serialVersionUID is used for serialization. + + private static final long serialVersionUID = 1L; + + public Like(Element element, String value) { + super(element, value); + } +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Not.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Not.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Not.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,30 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Not operator is used to build negative restriction for request on content. + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Not extends ConditionUnary { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Not() { + } + + /** + * Constructor with all parameters initialized + * + * @param restriction + */ + public Not(Condition restriction) { + super(restriction); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotEquals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotEquals.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotEquals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,31 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * NotEquals operator is used to build restriction containing "element != value" + * where element could be an Id, a String, an Integer, a Float, a Date ... <br> + * <br> + * For example, use: {@link WikittyQueryMaker}.neq( myElement , "REF1234567890" ) + * <p> + * <p> + * This operator used for String check strict equality (case sensitive) + * You can used '*' in expression at beginning or ending for String equality. + * + * <li> {@link WikittyQueryMaker}.ne("myext.myfield", "*jour") not match field "bonjour" but match "BONJOUR" + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class NotEquals extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public NotEquals(Element element, String value) { + super(element, value); + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotNull.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotNull.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/NotNull.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,21 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Is not null restriction, check if field has value (not null) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class NotNull extends TerminalBinaryOperator { + + private static final long serialVersionUID = 1L; + + public NotNull(Element element) { + super(element, null); + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Null.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Null.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Null.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,21 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * Is null restriction, check if field has no value (null) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Null extends TerminalBinaryOperator { + + private static final long serialVersionUID = 1L; + + public Null(Element element) { + super(element, null); + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Or.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Or.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Or.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,40 @@ +package org.nuiton.wikitty.query.conditions; + +import java.util.Arrays; +import java.util.List; + +/** + * Or operator is used to build disjunctive restriction for request on content. + * It take at least 2 args. <br> + * <br> + * For example, use: + * <ul> + * <li>{@link WikittyQueryMaker}.or( restriction1, restriction2 )</li> + * <li>{@link WikittyQueryMaker}.or( restriction1, restriction2, restriction3 )</li> + * <li>{@link WikittyQueryMaker}.or( my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> + * </ul> + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Or extends ConditionNary { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Or(Condition ... c) { + super(Arrays.asList(c)); + } + /** + * Constructor with all parameters initialized + * + * @param restrictions + */ + public Or(List<Condition> conditions) { + super(conditions); + } +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryListOperator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryListOperator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryListOperator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,50 @@ +package org.nuiton.wikitty.query.conditions; + +import java.util.Collection; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Classe mere des des operateurs binaire prenant une liste comme valeur possible + * (ex: ContainsAll, ContainsOne) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class TerminalBinaryListOperator extends TerminalOperator{ + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TerminalBinaryListOperator.class); + + private static final long serialVersionUID = 1L; + + protected Element element; + protected Collection<String> values; + + public TerminalBinaryListOperator(Element element, Collection<String> values) { + this.element = element; + this.values = values; + } + + public Element getElement() { + return element; + } + + public Collection<String> getValues() { + return values; + } + + @Override + boolean equalsDeep(Object other) { + TerminalBinaryListOperator op = (TerminalBinaryListOperator)other; + boolean result = ObjectUtils.equals(this.getElement(), op.getElement()) + && ObjectUtils.equals(this.getValues(), op.getValues()); + return result; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryOperator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryOperator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalBinaryOperator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,53 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.lang.ObjectUtils; + +/** + * classe mere des operateurs unaire et binaire. Lorsqu'on l'utilise pour un + * unaire seul element ou value est different de null, mais pas les deux en + * meme temps. + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class TerminalBinaryOperator extends TerminalOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Element element; + protected String value; + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public TerminalBinaryOperator(Element element, String value) { + this.element = element; + this.value = value; + } + + public Element getElement() { + return element; + } + + public String getValue() { + return value; + } + + @Override + boolean equalsDeep(Object other) { + TerminalBinaryOperator op = (TerminalBinaryOperator)other; + boolean result = ObjectUtils.equals(this.getElement(), op.getElement()) + && ObjectUtils.equals(this.getValue(), op.getValue()); + return result; + } + + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalOperator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalOperator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalOperator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,36 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Class mere de tous les operateurs terminaux sans parametre + * (ex: True, False) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class TerminalOperator extends Condition { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TerminalOperator.class); + + public TerminalOperator() { + } + + /** + * Pour les operateurs sans paramatre, le {@link Restriction#equals} est + * suffisant car il verifie deja que les classes des objets sont idendiques + * @param other + * @return + */ + @Override + boolean equalsDeep(Object other) { + return true; + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalTernaryOperator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalTernaryOperator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/TerminalTernaryOperator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,56 @@ +package org.nuiton.wikitty.query.conditions; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Classe mere des operateurs ternaire (ex: Between) + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class TerminalTernaryOperator extends TerminalOperator { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TerminalTernaryOperator.class); + + private static final long serialVersionUID = 1L; + + protected Element element; + protected String min; + protected String max; + + public TerminalTernaryOperator(Element element, String min, String max) { + this.element = element; + this.min = min; + this.max = max; + } + + public Element getElement() { + return element; + } + + public String getMin() { + return min; + } + + public String getMax() { + return max; + } + + @Override + boolean equalsDeep(Object other) { + TerminalTernaryOperator op = (TerminalTernaryOperator)other; + boolean result = ObjectUtils.equals(this.getElement(), op.getElement()) + && ObjectUtils.equals(this.getMin(), op.getMin()) + && ObjectUtils.equals(this.getMax(), op.getMax()); + return result; + } + + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/True.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/True.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/True.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,24 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * always True + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class True extends TerminalOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public True() { + } + +} \ No newline at end of file Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Unlike.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Unlike.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Unlike.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,23 @@ +package org.nuiton.wikitty.query.conditions; + +/** + * UnLike is use on String field type, you can use '*' at beginning or ending + * to match all char. (ex: ext.field UNLIKE 'deb*' not match 'debut' or 'debout' ... + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class Unlike extends TerminalBinaryOperator { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + public Unlike(Element element, String value) { + super(element, value); + } + +} Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Criteria.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Criteria.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Criteria.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -52,7 +52,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Criteria implements Serializable, Cloneable { /** serialVersionUID. */ private static final long serialVersionUID = 2590223960861630283L; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopic.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopic.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopic.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -33,7 +33,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class FacetTopic implements Serializable { /** serialVersionUID. */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicCountComparator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicCountComparator.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicCountComparator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -35,7 +35,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class FacetTopicCountComparator implements Comparator<FacetTopic> { /** to use log facility, just put in your code: log.info(\"...\"); */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicNameComparator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicNameComparator.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/FacetTopicNameComparator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -35,7 +35,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class FacetTopicNameComparator implements Comparator<FacetTopic> { /** to use log facility, just put in your code: log.info(\"...\"); */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/PagedResult.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/PagedResult.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/PagedResult.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -55,7 +55,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class PagedResult<T> implements Serializable, Iterable<T> { /** to use log facility, just put in your code: log.info(\"...\"); */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/RestrictionHelper.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/RestrictionHelper.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/RestrictionHelper.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -81,7 +81,9 @@ * new ElementDto(ElementName.ATTRIBUTE, "ATT_REF_ID", OperandType.STRING), "REF1234567890")) * ); * </pre> + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class RestrictionHelper { public static Restriction eq(Element element, String value) { Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Search.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Search.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/Search.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -52,7 +52,9 @@ * Some patterns might be available depending on the restriction used. They are : * * '*' replace any number of characters * * '?' replace one character + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Search { /** Default operator type between all search condition. */ @@ -286,7 +288,10 @@ * @param values list of values that the element must be equals to * @return {@code this} with the {@code ideq} restriction added. */ + @Deprecated public Search eq(String element, Collection<String> values) { + // erreur, car si le search est fait avec un OR au lieu d'un AND + // on a pas ce que l'on veut. for (String value : values) { restrictions.add(RestrictionHelper.eq(elt(element), value)); } @@ -302,6 +307,8 @@ * @return {@code this} with the {@code exteq} restriction added. */ public Search exteq(Collection<String> values) { + // erreur, car si le search est fait avec un OR au lieu d'un AND + // on a pas ce que l'on veut. for (String value : values) { restrictions.add(RestrictionHelper.eq(elt(Element.ELT_EXTENSION), value)); } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/TreeNodeResult.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/TreeNodeResult.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/TreeNodeResult.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -44,7 +44,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class TreeNodeResult<T extends Serializable> extends DefaultMutableTreeNode implements Iterable<TreeNodeResult<T>> { /** to use log facility, just put in your code: log.info(\"...\"); */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/And.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/And.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/And.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -38,7 +38,9 @@ * <li>RestrictionHelper.and( * my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> * </ul> + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class And extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/AssociatedRestriction.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/AssociatedRestriction.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/AssociatedRestriction.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -24,6 +24,10 @@ */ package org.nuiton.wikitty.search.operators; +/** + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} + */ +@Deprecated public class AssociatedRestriction extends Restriction { private static final long serialVersionUID = 1L; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Between.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Between.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Between.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -31,7 +31,9 @@ * < max" where element could be a Integer, a Float or a Date. <br> * <br> * For example, use: RestrictionHelper.between( myElement , "15.5" , "22.5" ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Between extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/BinaryOperator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/BinaryOperator.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/BinaryOperator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -29,7 +29,9 @@ /** * This class is an abstract class that's used to factor each operator that * handle two parameters (=, !=, <, <=, >, >=, end, begin). + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class BinaryOperator extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Element.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Element.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Element.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -30,7 +30,9 @@ * Search on field. * * @author ruchaud + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Element implements Serializable { /** Represent a element on extension */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/EndsWith.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/EndsWith.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/EndsWith.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * <br> * For example, use: RestrictionHelper.end( myElement , "value" ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class EndsWith extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Equals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Equals.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Equals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * Integer, a Float or a Date. <br> * <br> * For example, use: RestrictionHelper.eq( myElement , "REF1234567890" ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Equals extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/False.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/False.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/False.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -29,7 +29,9 @@ /** * User: couteau * Date: 08/04/11 + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class False extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Greater.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Greater.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Greater.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * For example, use: RestrictionHelper.less( myElement , * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Greater extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/GreaterOrEqual.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/GreaterOrEqual.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/GreaterOrEqual.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * For example, use: RestrictionHelper.greatEq( myElement , * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class GreaterOrEqual extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Keyword.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Keyword.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Keyword.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -28,7 +28,9 @@ * Search keyword in all wikitty. * * @author ruchaud + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Keyword extends Restriction { private static final long serialVersionUID = 1L; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Less.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Less.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Less.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * For example, use: RestrictionHelper.less( myElement , * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Less extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/LessOrEqual.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/LessOrEqual.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/LessOrEqual.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * For example, use: RestrictionHelper.lessEq( myElement , * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class LessOrEqual extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Like.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Like.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Like.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -27,16 +27,16 @@ import java.io.Serializable; /** - * Like is use on String field type, to precise some particularity on search. - * - * @author ruchaud - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ - - + * Like is use on String field type, to precise some particularity on search. + * + * @author ruchaud + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} + */ +@Deprecated public class Like extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Not.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Not.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Not.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * For example, use: RestrictionHelper.not( RestrictionHelper.eq( myElement , * "myValue" ) ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Not extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/NotEquals.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/NotEquals.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/NotEquals.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * Integer, a Float or a Date. <br> * <br> * For example, use: RestrictionHelper.neq( myElement , "REF1234567890" ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class NotEquals extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Null.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Null.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Null.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -28,7 +28,9 @@ * Is null or is not null restriction * * @author ruchaud + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Null extends Restriction { private static final long serialVersionUID = 1L; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Or.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Or.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Or.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -38,7 +38,9 @@ * <li>RestrictionHelper.or( * my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> * </ul> + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Or extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Restriction.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Restriction.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Restriction.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -29,7 +29,9 @@ /** * This element is a symbolic interface implemented by all operators used to * request contents (And, Or, Not, Equals, NotEquals, EndsWith, ...). + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/RestrictionName.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/RestrictionName.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/RestrictionName.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -29,7 +29,9 @@ * This enum contains all kind of restriction used to request content. It's used * by parser to create lucene request from RestrictionDto. * </p> + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public enum RestrictionName { EQUALS, NOT_EQUALS, Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SearchOperand.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SearchOperand.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SearchOperand.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -28,7 +28,9 @@ * Represents the possible operands for client search. The supported type of * each AttributeSearchDto depends of its type. * @deprecated ne semble pas utilise, interet ??? + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public enum SearchOperand { EQUALS, NOT_EQUALS, LESS, LESS_OR_EQUALS, GREATER, GREATER_OR_EQUALS, BEGINS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS, BETWEEN Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/StartsWith.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/StartsWith.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/StartsWith.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -32,7 +32,9 @@ * <br> * <br> * For example, use: RestrictionHelper.start( myElement , "value" ) + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class StartsWith extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SubSearch.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SubSearch.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/SubSearch.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -26,6 +26,10 @@ import org.nuiton.wikitty.search.Search; +/** + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} + */ +@Deprecated public class SubSearch extends Search { protected String foreignName; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/True.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/True.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/True.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -29,7 +29,9 @@ /** * User: couteau * Date: 08/04/11 + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} */ +@Deprecated public class True extends Restriction implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Unlike.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Unlike.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/search/operators/Unlike.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -27,17 +27,17 @@ import java.io.Serializable; /** - * UnLike is use on String field type, to precise some particularity on search - * (case insensitive for example). - * - * @author martel - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ - - + * UnLike is use on String field type, to precise some particularity on search + * (case insensitive for example). + * + * @author martel + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + * @deprecated since 3.3 use new query api {@link org.nuiton.wikitty.query.WikittyQuery} + */ +@Deprecated public class Unlike extends BinaryOperator implements Serializable { // serialVersionUID is used for serialization. Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -31,6 +31,9 @@ import org.nuiton.wikitty.entities.Wikitty; import org.nuiton.wikitty.entities.WikittyExtension; import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; import org.nuiton.wikitty.search.TreeNodeResult; /** @@ -181,8 +184,24 @@ public TreeNodeResult<String> findTreeNode(String securityToken, String wikittyId, int depth, boolean count, Criteria filter) { return delegate.findTreeNode(securityToken, wikittyId, depth, count, filter); } - + @Override + public List<WikittyQueryResult<String>> findAllByQuery( + String securityToken, List<WikittyQuery> queries) { + return delegate.findAllByQuery(securityToken, queries); + } + + @Override + public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) { + return delegate.findByQuery(securityToken, queries); + } + + @Override + public WikittyQueryResultTreeNode<String> findTreeNode(String securityToken, String wikittyId, int depth, boolean count, WikittyQuery filter) { + return delegate.findTreeNode(securityToken, wikittyId, depth, count, filter); + } + + @Override public WikittyEvent deleteTree(String securityToken, String wikittyId) { return delegate.deleteTree(securityToken, wikittyId); } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -53,6 +53,10 @@ import org.nuiton.wikitty.entities.WikittyTreeNode; import org.nuiton.wikitty.entities.WikittyTreeNodeHelper; import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; import org.nuiton.wikitty.search.Search; import org.nuiton.wikitty.search.TreeNodeResult; import org.nuiton.wikitty.search.operators.Element; @@ -368,11 +372,11 @@ // check that all extensions are not used for(String name : extNames) { // only name are stored in index, search only on name - Criteria criteria = Search.query().eq(Element.ELT_EXTENSION, name).criteria(); - criteria.setEndIndex(0); // result is not use, just numFound - PagedResult<String> wikittyWithExt = findAllByCriteria( - securityToken, Collections.singletonList(criteria)).get(0); - int numFound = wikittyWithExt.getNumFound(); + WikittyQuery query = new WikittyQueryMaker().exteq(name).end(); + query.setLimit(0); // result is not use, just numFound + WikittyQueryResult<String> wikittyWithExt = findAllByQuery( + securityToken, Collections.singletonList(query)).get(0); + int numFound = wikittyWithExt.getTotalResult(); if (numFound > 0) { throw new WikittyException(String.format( "Can't delete %s extension, this extension" @@ -710,11 +714,11 @@ } // Store node with have deleted node as parent - Criteria criteria = - Search.query().eq(WikittyTreeNode. - FQ_FIELD_WIKITTYTREENODE_PARENT, id).criteria(); - List<String> wikittyNodesId = findAllByCriteria( - securityToken, Collections.singletonList(criteria)) + WikittyQuery query = + new WikittyQueryMaker().eq(WikittyTreeNode. + FQ_FIELD_WIKITTYTREENODE_PARENT, id).end(); + List<String> wikittyNodesId = findAllByQuery( + securityToken, Collections.singletonList(query)) .get(0).getAll(); for (String wikittyNodeId : wikittyNodesId) { if (!idSet.contains(wikittyNodeId)) { @@ -726,10 +730,10 @@ } // Store node with have deleted child - criteria = Search.query().eq(WikittyTreeNode. - FQ_FIELD_WIKITTYTREENODE_ATTACHMENT, id).criteria(); - wikittyNodesId = findAllByCriteria( - securityToken, Collections.singletonList(criteria)) + query = new WikittyQueryMaker().eq(WikittyTreeNode. + FQ_FIELD_WIKITTYTREENODE_ATTACHMENT, id).end(); + wikittyNodesId = findAllByQuery( + securityToken, Collections.singletonList(query)) .get(0).getAll(); for (String wikittyNodeId : wikittyNodesId) { if (!idSet.contains(wikittyNodeId)) { @@ -905,7 +909,104 @@ } } + /** + * Assume that this PagedResult contains wikitty id as result and + * return new PagedResult with Wikitty instance + */ @Override + public List<WikittyQueryResult<String>> findAllByQuery( + String securityToken, List<WikittyQuery> queries) { + WikittyTransaction tx = WikittyTransaction.get(); + boolean txBeginHere = false; + try { + if (!tx.isStarted()) { + tx.begin(); + txBeginHere = true; + } + + List<WikittyQueryResult<String>> result = + new ArrayList<WikittyQueryResult<String>>(queries.size()); + for (WikittyQuery c : queries) { + if (c == null) { + result.add(null); + } else { + WikittyQueryResult<String> searchResult = + getSearchEngine().findAllByQuery(tx, c); + result.add(searchResult); + } + } + + if (txBeginHere) { + tx.commit(); + } + if (queries.size() != result.size()) { + log.error(String.format("Query input list (%s) has not same size that result list (%s)", + queries.size(), result.size())); + } + return result; + } catch (WikittyException ex) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw ex; + } catch (Exception eee) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw new WikittyException("Error during find", eee); + } + } + + @Override + public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) { + WikittyTransaction tx = WikittyTransaction.get(); + boolean txBeginHere = false; + try { + if (!tx.isStarted()) { + tx.begin(); + txBeginHere = true; + } + + List<String> result = new ArrayList<String>(queries.size()); + List<WikittyQuery> queriesLimited = new ArrayList<WikittyQuery>(queries.size()); + for (WikittyQuery c : queries) { + WikittyQuery cLimit = c.copy().setFirst(0).setLimit(1); + queriesLimited.add(cLimit); + } + + List<WikittyQueryResult<String>> idsList = + findAllByQuery(securityToken, queriesLimited); + + for (WikittyQueryResult<String> ids : idsList) { + if (ids.size() > 0) { + result.add(ids.peek()); + } else { + result.add(null); + } + } + + if (txBeginHere) { + tx.commit(); + } + if (queries.size() != result.size()) { + log.error(String.format("Query input list (%s) has not same size that result list (%s)", + queries.size(), result.size())); + } + return result; + } catch (WikittyException ex) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw ex; + } catch (Exception eee) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw new WikittyException("Error during find", eee); + } + } + + @Override public WikittyEvent deleteTree(String securityToken, String thesaurusId) { WikittyTransaction tx = WikittyTransaction.get(); boolean txBeginHere = false; @@ -944,12 +1045,11 @@ * @return all id of {@code treeNodeId}'s children */ protected List<String> getRecursiveTreeNodeId(String securityToken, String treeNodeId) { - Search search = Search.query(); - search = search.eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, treeNodeId); - Criteria criteria = search.criteria(); - - PagedResult<String> childTreeNodeIds = findAllByCriteria( - securityToken, Collections.singletonList(criteria)).get(0); + WikittyQuery query = new WikittyQueryMaker() + .eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, treeNodeId).end(); + + WikittyQueryResult<String> childTreeNodeIds = findAllByQuery( + securityToken, Collections.singletonList(query)).get(0); List<String> treeNodeIds = new ArrayList<String>(); treeNodeIds.add(treeNodeId); for (String childTreeNodeId : childTreeNodeIds.getAll()) { @@ -995,6 +1095,41 @@ } @Override + public WikittyQueryResultTreeNode<String> findTreeNode(String securityToken, + String wikittyId, int depth, boolean count, WikittyQuery filter) { + WikittyTransaction tx = WikittyTransaction.get(); + boolean txBeginHere = false; + try { + if (!tx.isStarted()) { + tx.begin(); + txBeginHere = true; + } + + WikittyQueryResultTreeNode<String> result = null; + Wikitty w = restore(securityToken, wikittyId); + if(w != null) { + result = getSearchEngine().findAllChildrenCount( + tx, wikittyId, depth, count, filter); + } + + if (txBeginHere) { + tx.commit(); + } + return result; + } catch (WikittyException ex) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw ex; + } catch (Exception eee) { + if (tx != null && tx.isStarted()) { + tx.rollback(); + } + throw new WikittyException("Can't restore children", eee); + } + } + + @Override public Wikitty restoreVersion(String securityToken, String wikittyId, String version) { throw new UnsupportedOperationException("Not supported yet."); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceTransaction.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceTransaction.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceTransaction.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -44,6 +44,9 @@ import org.nuiton.wikitty.entities.WikittyExtension; import org.nuiton.wikitty.WikittyService; import org.nuiton.wikitty.WikittyServiceFactory; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; import org.nuiton.wikitty.search.Search; import org.nuiton.wikitty.search.TreeNodeResult; @@ -360,7 +363,7 @@ Criteria climit = Search.query(c).criteria().setFirstIndex(0).setEndIndex(1); criteriaLimit.add(climit); } - + List<PagedResult<String>> idsList = findAllByCriteria( securityToken, criteriaLimit); @@ -388,6 +391,89 @@ } @Override + public List<WikittyQueryResult<String>> findAllByQuery( + String securityToken, List<WikittyQuery> queries) { + List<WikittyQueryResult<String>> resultTxList = + tx.findAllByQuery(securityToken, queries); + List<WikittyQueryResult<String>> resultWsList = + ws.findAllByQuery(securityToken, queries); + + List<WikittyQueryResult<String>> result = + new ArrayList<WikittyQueryResult<String>>(resultWsList.size()); + for (int i=0; i<queries.size(); i++) { + WikittyQueryResult<String> resultTx = resultTxList.get(i); + WikittyQueryResult<String> resultWs = resultWsList.get(i); + // Il faut fusionner les deux resultats + // - ne pas avoir de doublon + // - ne pas retenir ceux supprimer dans la transaction + // - fusionner les facettes (comment faire ?) + // - respecter le range demander (comment faire, avec les suppressions possible ?) + LinkedHashSet<String> ids = + new LinkedHashSet<String>(resultTx.size() + resultWs.size()); + ids.addAll(resultTx.getAll()); + for (String id : resultWs.getAll()) { + if (!tx.exists(securityToken, id) || !tx.isDeleted(securityToken, id)) { + ids.add(id); + } + } + + String queryName = resultWs.getQueryName(); + int firstIndice = resultWs.getFirst(); + // FIXME le resultat est faux, le nombre total n'est pas la somme des deux :( + int numFound = resultTx.getTotalResult() + resultWs.getTotalResult(); + String queryString = resultWs.getQueryString(); + // FIXME les facettes sont fausses :( + Map<String, List<org.nuiton.wikitty.query.FacetTopic>> facets = resultWs.getFacets(); + List<String> results = new ArrayList<String>(ids); + + result.add(new WikittyQueryResult<String>(queryName, + firstIndice, numFound, queryString, facets, results)); + } + + if (queries.size() != result.size()) { + log.error(String.format("Queries input list (%s) has not same size that result list (%s)", + queries.size(), result.size())); + } + + return result; + } + + @Override + public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) { + List<String> result = new ArrayList<String>(queries.size()); + List<WikittyQuery> queriesLimited = new ArrayList<WikittyQuery>(queries.size()); + for (WikittyQuery c : queries) { + WikittyQuery climit = c.copy().setFirst(0).setLimit(1); + queriesLimited.add(climit); + } + + List<WikittyQueryResult<String>> idsList = findAllByQuery( + securityToken, queriesLimited); + + for (WikittyQueryResult<String> ids : idsList) { + if (ids.size() > 0) { + result.add(ids.peek()); + } else { + result.add(null); + } + } + + if (queries.size() != result.size()) { + log.error(String.format("Query input list (%s) has not same size that result list (%s)", + queries.size(), result.size())); + } + + return result; + } + + @Override + public WikittyQueryResultTreeNode<String> findTreeNode(String securityToken, + String wikittyId, int depth, boolean count, WikittyQuery filter) { + // FIXME + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public WikittyEvent deleteTree(String securityToken, String treeNodeId) { // FIXME throw new UnsupportedOperationException("Not supported yet."); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngine.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngine.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngine.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -30,6 +30,9 @@ import org.nuiton.wikitty.search.PagedResult; import org.nuiton.wikitty.entities.Wikitty; import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; import org.nuiton.wikitty.search.TreeNodeResult; import org.nuiton.wikitty.services.WikittyTransaction; @@ -68,8 +71,22 @@ */ public void delete(WikittyTransaction transaction, Collection<String> idList) throws WikittyException; + + /** + * @deprecated since 3.3 use {@link #findAllByCriteria(org.nuiton.wikitty.services.WikittyTransaction, org.nuiton.wikitty.search.Criteria)} + */ + @Deprecated + public PagedResult<String> findAllByCriteria(WikittyTransaction transaction, Criteria criteria); - public PagedResult<String> findAllByCriteria(WikittyTransaction transaction, Criteria criteria); + /** + * Find all wikitties that satisfy queries constraint + * + * @param transaction + * @param queries + * @return id of wikitties + * @since 3.3 + */ + public WikittyQueryResult<String> findAllByQuery(WikittyTransaction transaction, WikittyQuery queries); /** * Find all children ids with attachment count for a node wikitty. @@ -106,8 +123,50 @@ * @param filter filter on attachment count * @return Tree start with wikittyId as root * @throws WikittyException if wikittyId is not WikittyTreeNode + * @deprecated since 3.3 use {@link #findAllChildrenCount(org.nuiton.wikitty.services.WikittyTransaction, java.lang.String, int, boolean, org.nuiton.wikitty.query.WikittyQuery) } */ + @Deprecated public TreeNodeResult<String> findAllChildrenCount(WikittyTransaction transaction, String wikittyId, int depth, boolean count, Criteria filter); + /** + * Find all children ids with attachment count for a node wikitty. + * If same attachment found many time in subtree this attachment is count + * only once. + * + * If we have: + * <ul> + * <li> w Node (4) + * <ul> + * <li> child1 (3) </li> + * <li> child2 (4) </li> + * <li> child3 (2) + * <ul> + * <li> subchild1 (1) </li> + * <li> subchild2 (5) </li> + * </ul> + * </li> + * <li> child4 (3) </li> + * <li> child5 (7) </li> + * </ul> + * </li> + * </ul> + * + * return count for: child1(3), child2(4), child3(8), child4(3), child5(7) + * and for the child3 count we have count of subchild1 and subchild2 in + * + * Node and subchild are returned according to depth + * + * @param transaction + * @param wikittyId root node to begin + * @param depth depth of node returned, -1 to retrieve all child level + * @param count if true return count of attachment + * @param filter filter on attachment count + * @return Tree start with wikittyId as root + * @throws WikittyException if wikittyId is not WikittyTreeNode + * @since 3.3 + */ + public WikittyQueryResultTreeNode<String> findAllChildrenCount(WikittyTransaction transaction, + String wikittyId, int depth, boolean count, WikittyQuery filter); + } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java 2011-12-01 09:50:20 UTC (rev 1258) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -28,16 +28,45 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.WikittyUtil; import org.nuiton.wikitty.entities.FieldType; import org.nuiton.wikitty.entities.FieldType.TYPE; import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; +import org.nuiton.wikitty.query.WikittyQueryVisitor; +import org.nuiton.wikitty.query.conditions.Condition; +import org.nuiton.wikitty.query.conditions.ContainsAll; +import org.nuiton.wikitty.query.conditions.ContainsOne; +import org.nuiton.wikitty.query.conditions.ElementExtension; +import org.nuiton.wikitty.query.conditions.ElementId; +import org.nuiton.wikitty.query.conditions.Equals; +import org.nuiton.wikitty.query.conditions.Greater; +import org.nuiton.wikitty.query.conditions.GreaterOrEquals; +import org.nuiton.wikitty.query.conditions.Join; +import org.nuiton.wikitty.query.conditions.Less; +import org.nuiton.wikitty.query.conditions.LessOrEquals; +import org.nuiton.wikitty.query.conditions.Like; +import org.nuiton.wikitty.query.conditions.NotEquals; +import org.nuiton.wikitty.query.conditions.NotNull; +import org.nuiton.wikitty.query.conditions.Unlike; import org.nuiton.wikitty.search.Criteria; import org.nuiton.wikitty.search.PagedResult; import org.nuiton.wikitty.search.TreeNodeResult; @@ -60,6 +89,9 @@ public class WikittySearchEngineInMemory implements WikittySearchEngine { + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittySearchEngineInMemory.class); + protected WikittyStorageInMemory wikittyStorage; public WikittySearchEngineInMemory(WikittyStorageInMemory wikittyStorage) { @@ -73,17 +105,900 @@ @Override public void store(WikittyTransaction transaction, Collection<Wikitty> wikitties, boolean force) { + // do nothing } @Override public void delete(WikittyTransaction transaction, Collection<String> idList) throws WikittyException { + // do nothing } -// @Override -// public void delete(Collection<String> idList) throws WikittyException { -// } + private boolean checkRestriction(WikittyTransaction transaction, + Condition condition, Wikitty w) { + WikittyQueryVisitorCheckCondition v = + new WikittyQueryVisitorCheckCondition(this, transaction, w); + condition.accept(v); + boolean result = v.getResult(); + return result; + } + + @Override + public WikittyQueryResult<String> findAllByQuery(WikittyTransaction transaction, WikittyQuery query) { + // throw new UnsupportedOperationException("Not supported yet."); + int first = query.getFirst(); + int limit = query.getLimit(); + List<String> ids = new LinkedList<String>(); + int currentIndex = 0; + for (Entry<String, Wikitty> entry : wikittyStorage.getWikitties().entrySet()) { + Wikitty w = entry.getValue(); + String id = entry.getKey(); + Condition c = query.getCondition(); + if (!w.isDeleted() && checkRestriction(transaction, c, w)) { + currentIndex++; + if (currentIndex > first) { + ids.add(id); + } + if (ids.size() >= limit) { + break; + } + } + } + return new WikittyQueryResult<String>(query.getName(), + first, ids.size(), query.getCondition().toString(), null, ids); + } - public boolean checkRestriction(WikittyTransaction transaction, + @Override + public WikittyQueryResultTreeNode<String> findAllChildrenCount(WikittyTransaction transaction, + String wikittyId, int depth, boolean count, WikittyQuery filter) { + // FIXME + throw new UnsupportedOperationException("Not supported yet."); + } + + static public class WikittyQueryVisitorCheckCondition extends WikittyQueryVisitor { + + protected WikittySearchEngine searchEngine; + /** transaction used to check wikitty */ + protected WikittyTransaction tx; + /** wikitty to check */ + protected Wikitty w; + /** la pile d'evaluation des differencetes contraintes */ + protected Deque<Boolean> evalStack = new LinkedList<Boolean>(); + + public boolean getResult() { + Boolean result = evalStack.poll(); + if (result == null) { + // s'il n'y avait pas de condition, la stack est vide, donc + // c'est vrai + result = Boolean.TRUE; + } + return result; + } + + public WikittyQueryVisitorCheckCondition( + WikittySearchEngine searchEngine, WikittyTransaction tx, Wikitty w) { + this.searchEngine = searchEngine; + this.tx = tx; + this.w = w; + } + + /** + * Interface permettant de verifier une condition sur deux collections + */ + static private interface Predicate { + /** + * retourne vrai si la condition est validee + * @param type type des elements des collections. Si null alors les + * collection contiennent des String (id ou nom extension) + * @param value l'ensemble des valeur du champs + * @param expected l'ensemble des valeurs attendue + * @return vrai si la condition est validee + */ + boolean check(FieldType type, Collection values, Collection expected); + } + + static private Predicate BetweenPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() == 2) { + // si on a pas deux valeur, c'est qu'on a pas min et max + Iterator i = expected.iterator(); + Object min = i.next(); + Object max = i.next(); + for (Object fieldValue : values) { + // fieldValue doit etre comparable + if (fieldValue instanceof Comparable) { + // recupere le type de la valeur + + result = ((Comparable) fieldValue).compareTo(min) >= 0 + && ((Comparable) fieldValue).compareTo(max) <= 0; + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + } + return result; + } + }; + + static private Predicate ContainsAllPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + if (values != null) { + expected = CollectionUtils.subtract(expected, values); + // si lorsqu'on retire tous les elements en commun avec la valeur + // du champs il ne reste plus rien, c'est que le containsAll est + // vrai + result = expected.isEmpty(); + } + return result; + + } + }; + + static private Predicate ContainsOnePredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + if (values != null) { + expected = CollectionUtils.retainAll(expected, values); + // si lorsqu'on retient tous les elements en commun avec la valeur + // du champs il ne reste plus rien, c'est que le containsOne est + // faux, donc il faut qu'il en reste + result = !expected.isEmpty(); + } + return result; + } + }; + + static private Predicate EqualsPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + if (values != null && expected.size() > 0) { + // gestion des type STRING differement car il peut y avoir des '*' + if (type != null && type.getType() == TYPE.STRING) { + Iterator i = expected.iterator(); + String exp = String.valueOf(i.next()); + for (Object fieldValue : values) { + String val = String.valueOf(fieldValue); + result = matchString(val, exp, false); + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } else { + expected = CollectionUtils.subtract(expected, values); + // si lorsqu'on retire tous les elements en commun avec la valeur + // du champs il ne reste plus rien, c'est que le equals est + // vrai + result = expected.isEmpty(); + } + } + return result; + + } + }; + + static private Predicate NotEqualsPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + if (values != null && expected.size() > 0) { + // gestion des type STRING differement car il peut y avoir des '*' + if (type != null && type.getType() == TYPE.STRING) { + Iterator i = expected.iterator(); + String exp = String.valueOf(i.next()); + for (Object fieldValue : values) { + String val = String.valueOf(fieldValue); + result = !matchString(val, exp, false); + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } else { + expected = CollectionUtils.subtract(expected, values); + // si lorsqu'on retire tous les elements en commun avec la valeur + // du champs il ne reste plus rien, c'est que le equals est + // vrai et donc le not equals est faux + result = !expected.isEmpty(); + } + } + return result; + + } + }; + + static private Predicate GreaterPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + Object val = i.next(); + for (Object fieldValue : values) { + // fieldValue doit etre comparable + if (fieldValue instanceof Comparable) { + // recupere le type de la valeur + result = ((Comparable) fieldValue).compareTo(val) > 0; + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + } + return result; + } + }; + + static private Predicate GreaterOrEqualsPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + Object val = i.next(); + for (Object fieldValue : values) { + // fieldValue doit etre comparable + if (fieldValue instanceof Comparable) { + // recupere le type de la valeur + result = ((Comparable) fieldValue).compareTo(val) >= 0; + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + } + return result; + } + }; + + static private Predicate LessPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + Object val = i.next(); + for (Object fieldValue : values) { + // fieldValue doit etre comparable + if (fieldValue instanceof Comparable) { + // recupere le type de la valeur + result = ((Comparable) fieldValue).compareTo(val) < 0; + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + } + return result; + } + }; + + static private Predicate LessOrEqualsPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + Object val = i.next(); + for (Object fieldValue : values) { + // fieldValue doit etre comparable + if (fieldValue instanceof Comparable) { + // recupere le type de la valeur + result = ((Comparable) fieldValue).compareTo(val) <= 0; + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + } + return result; + } + }; + + static private Predicate KeywordPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + String exp = String.valueOf(i.next()); + for (Object fieldValue : values) { + String val = String.valueOf(fieldValue); + // TODO poussin 20111228 verifie que le containsIgnoreCase + // supprime les accents, si ce n'est pas le cas, il faut + // trouver comment faire + result = StringUtils.containsIgnoreCase(val, exp); + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + return result; + } + }; + + static private Predicate LikePredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + String exp = String.valueOf(i.next()); + for (Object fieldValue : values) { + String val = String.valueOf(fieldValue); + result = matchString(val, exp, true); + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + return result; + } + }; + + static private Predicate UnlikePredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = false; + + if (values != null && expected.size() > 0) { + // si on a pas une valeur, c'est pas bon :( + Iterator i = expected.iterator(); + String exp = String.valueOf(i.next()); + for (Object fieldValue : values) { + String val = String.valueOf(fieldValue); + result = !matchString(val, exp, true); + if (result) { + // si une des valeurs correspond, on retourne true + break; + } + } + } + return result; + } + }; + + static private Predicate NullPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = values == null || values.contains(null); + return result; + } + }; + + static private Predicate NotNullPredicate = new Predicate() { + public boolean check(FieldType type, Collection values, Collection expected) { + boolean result = values != null && !values.contains(null); + return result; + } + }; + + + + /** + * check if string match other string. + * + * @param s string + * @param sub string to match with 's' parameter. This string can start + * or and with star '*' + * @param ignoreCase if true match is done in ingore case mode + * @return true if sub match s + */ + static private boolean matchString(String s, String sub, boolean ignoreCase) { + // TODO poussin 20111228 verifie que le containsIgnoreCase + // supprime les accents, si ce n'est pas le cas, il faut + // trouver comment faire + + boolean result = false; + if (sub.startsWith("*") && sub.endsWith("*")) { + sub = StringUtils.substring(sub, 1, -1); + if (ignoreCase) { + result = StringUtils.containsIgnoreCase(s, sub); + } else { + result = StringUtils.contains(s, sub); + } + } else if (sub.startsWith("*")) { + sub = StringUtils.substring(sub, 1); + if (ignoreCase) { + result = StringUtils.endsWithIgnoreCase(s, sub); + } else { + result = StringUtils.endsWith(s, sub); + } + } else if (sub.endsWith("*")) { + sub = StringUtils.substring(sub, 0, -1); + if (ignoreCase) { + result = StringUtils.startsWithIgnoreCase(s, sub); + } else { + result = StringUtils.startsWith(s, sub); + } + } else { + if (ignoreCase) { + result = StringUtils.equalsIgnoreCase(s, sub); + } else { + result = StringUtils.equals(s, sub); + } + } + + return result; + } + + /** + * Collecte les valeur possible de l'element demande + * + * @param e l'element demande. Peut etre l'id, l'extension ou un champs. + * le champs pouvant contenir des * pour remplacer le nom de extension + * ou le nom du champs (ex: *.name, myext.*) + * @param values une map avec en cle le nom du champs et en valeur + * la valeur du champs + */ + protected void collectFieldValue( + org.nuiton.wikitty.query.conditions.Element e, + Map<String, Collection> values) { + if (e instanceof ElementId) { + values.put(e.getValue(), Collections.singleton(w.getId())); + } else if (e instanceof ElementExtension) { + values.put(e.getValue(), w.getExtensionNames()); + } else { + String fqf = e.getValue(); + if (w.hasField(fqf)) { + Object v = w.getFqField(fqf); + values.put(fqf, convert(null, v)); + } else { + String extName = WikittyExtension.extractExtensionName(fqf); + String fieldName = WikittyExtension.extractFieldName(fqf); + if ("*".equals(extName) && "*".equals(fieldName)) { + // on ajoute tous les champs de toutes les extensions + for (String f : w.getAllFieldNames()) { + Object v = w.getFqField(f); + values.put(f, convert(null, v)); + } + } else if ("*".equals(fieldName)){ + // on ajoute tous les champs de l'extension demandee + for (String f : w.getExtension(extName).getFieldNames()) { + String fq = WikittyUtil.getFQFieldName(extName, f); + Object v = w.getFqField(fq); + values.put(fq, convert(null, v)); + } + } else if ("*".equals(extName)){ + // on ajoute tous les champs ayant le nom demande + // quelque soit l'extension + for (String ext : w.getExtensionNames()) { + for (String f : w.getExtension(ext).getFieldNames()) { + if (f.equals(fieldName)) { + String fq = WikittyUtil.getFQFieldName(ext, f); + Object v = w.getFqField(fq); + values.put(fq, convert(null, v)); + } + } + } + } + } + } + } + + /** + * Converti o en une list de valeur compatible avec type + * @param type le type dans lequel doit etre converti o + * @param o la valeur a convertir, si o est une collection, chaque + * element de la collection est converti + * + * @return une nouvelle collection avec les elements dans le bon type + */ + protected Collection convert(FieldType type, Object o) { + Collection result; + try { + if (o instanceof Collection) { + // order of collection must be maintained, for that use LinkedHashSet + if (type == null) { + // if type is null don't change type (in case of id or extension + // or when we know object is already in right type) + result = new LinkedHashSet((Collection)o); + } else { + result = new LinkedHashSet(); + for (Object v : (Collection)o) { + result.add(type.getContainedValidObject(v)); + } + } + } else { + if (type != null) { + // if type is null don't change type (in case of id or extension + // or when we know object is already in right type) + o = type.getContainedValidObject(o); + } + result = Collections.singleton(o); + } + } catch (Exception eee) { + // si on arrive pas a convertir on retourne null + result = null; + if (log.isTraceEnabled()) { + log.trace("not an error but can't convert string to wanted type", eee); + } + } + return result; + } + + /** + * Verifie qu'un predicat est vrai pour un element et une valeur attendu + * @param predicate le predicat a verifier + * @param element l'element mis en cause (id, extension, field) + * @param expected la/les valeur(s) attendu(s) + * @return vrai si le predicat est verifie + */ + protected boolean check(Predicate predicate, + org.nuiton.wikitty.query.conditions.Element element, Object expected) { + boolean result = false; + + Map<String, Collection> fieldValues = new HashMap<String, Collection>(); + collectFieldValue(element, fieldValues); + for (String fqf : fieldValues.keySet()) { + FieldType type = null; + if (w.hasField(fqf)) { + type = w.getFieldType(fqf); + } + Collection<Object> contained = convert(type, expected); + if (contained != null) { + // si on a reussi a convertir dans le bon type on fait la verif + Collection values; + values = (Collection)fieldValues.get(fqf); + + result = predicate.check(type, values, contained); + if (result) { + // on a reussi a verifie le predicat pour au moins un champs + // on renvoie donc true + break; + } + } + } + return result; + } + + + @Override + public boolean visitEnter(WikittyQuery o) { + // nothing to do + return true; + } + + @Override + public void visitLeave(WikittyQuery o, boolean enterOrMiddleResult) { + // nothing to do + } + + @Override + public boolean visitEnter(org.nuiton.wikitty.query.conditions.And o) { + evalStack.push(Boolean.TRUE); + return true; + } + + @Override + public boolean visitMiddle(org.nuiton.wikitty.query.conditions.And o) { + // l'evaluation du dernier element du and + Boolean last = evalStack.pop(); + // la valeur courante du and + Boolean currentValue = evalStack.pop(); + + Boolean result = currentValue && last; + evalStack.push(result); + + // si le and est deja faut ca ne sert a rien de d'evaluer la suite + return result; + } + + @Override + public void visitLeave(org.nuiton.wikitty.query.conditions.And o, boolean enterOrMiddleResult) { + Boolean last = Boolean.TRUE; + if (enterOrMiddleResult && o.getConditions().size()>0) { + // si enter ou middle on renvoye false, alors on a pas + // de nouvelle condition a prendre dans la pile sinon + // l'evaluation du dernier element du and + last = evalStack.pop(); + } + // la valeur courante du and + Boolean currentValue = evalStack.pop(); + + Boolean result = currentValue && last; + evalStack.push(result); + } + + @Override + public boolean visitEnter(org.nuiton.wikitty.query.conditions.Or o) { + // si le or n'a aucun element, alors il est vrai + if (o.getConditions().isEmpty()) { + evalStack.push(Boolean.TRUE); + } else { + // sinon, il faut qu'un de ses elements soit vrai pour etre vrai + evalStack.push(Boolean.FALSE); + } + return true; + } + + @Override + public boolean visitMiddle(org.nuiton.wikitty.query.conditions.Or o) { + // l'evaluation du dernier element du or + Boolean last = evalStack.pop(); + // la valeur courante du or + Boolean currentValue = evalStack.pop(); + + Boolean result = currentValue || last; + evalStack.push(result); + + // si le or est deja vrai, ca ne sert a rien d'evaluer la suite + return !result; + } + + @Override + public void visitLeave(org.nuiton.wikitty.query.conditions.Or o, boolean enterOrMiddleResult) { + Boolean last = Boolean.TRUE; + if (enterOrMiddleResult && o.getConditions().size()>0) { + // si enter ou middle on renvoye false, alors on a pas + // de nouvelle condition a prendre dans la pile sinon + // l'evaluation du dernier element du or + last = evalStack.pop(); + } + // la valeur courante du or + Boolean currentValue = evalStack.pop(); + + Boolean result = currentValue || last; + evalStack.push(result); + } + + @Override + public boolean visitEnter(Join o) { + boolean evalResult = false; + String fqfieldName = o.getElement().getValue(); +// Object fieldValue = w.getFqField(fqfieldName); + + // il faut que le champs exist et que la valeur soit un String (pas null) + if (w.hasField(fqfieldName) && (w.getFieldType(fqfieldName).getType() == TYPE.WIKITTY)) { + + //Get sub-restriction + Condition sub = o.getSubCondition(); + + WikittyQuery query = new WikittyQuery(sub); + + //find everything that validate the sub-restriction + WikittyQueryResult<String> associatedResult = + searchEngine.findAllByQuery(tx, query); + + List<String> associatedList = associatedResult.getAll(); + + //Check that my field is contained in the sub-restriction results. + evalResult = check(ContainsOnePredicate, o.getElement(), associatedList); +// associatedList.contains(String.valueOf(fieldValue)); + } + + evalStack.push(evalResult); + + // on ne parcours pas la sous requete + return false; + } + + @Override + public void visitLeave(Join o, boolean enterOrMiddleResult) { + // nothing to do + } + + @Override + public boolean visitEnter(org.nuiton.wikitty.query.conditions.Not o) { + // nothing to do + return true; + } + + @Override + public void visitLeave(org.nuiton.wikitty.query.conditions.Not o, boolean enterOrMiddleResult) { + Boolean val = evalStack.pop(); + Boolean result = !val; + evalStack.push(result); + } + + @Override + public void visit(org.nuiton.wikitty.query.conditions.Between o) { + boolean result = false; + Collection expected = new ArrayList(2); + expected.add(o.getMin()); + expected.add(o.getMax()); + result = check(BetweenPredicate, o.getElement(), expected); + + evalStack.push(result); + } + + @Override + public void visit(ContainsAll o) { + boolean result = false; + + result = check(ContainsAllPredicate, o.getElement(), o.getValues()); + + evalStack.push(result); + } + + @Override + public void visit(ContainsOne o) { + boolean result = false; + + result = check(ContainsOnePredicate, o.getElement(), o.getValues()); + + evalStack.push(result); + } + + @Override + public void visit(Equals o) { + boolean result = false; + + result = check(EqualsPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(NotEquals o) { + boolean result = false; + + result = check(NotEqualsPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(org.nuiton.wikitty.query.conditions.False o) { + evalStack.push(Boolean.FALSE); + } + + @Override + public void visit(org.nuiton.wikitty.query.conditions.True o) { + evalStack.push(Boolean.TRUE); + } + + @Override + public void visit(Greater o) { + boolean result = false; + + result = check(GreaterPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(GreaterOrEquals o) { + boolean result = false; + + result = check(GreaterOrEqualsPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(org.nuiton.wikitty.query.conditions.Keyword o) { + boolean result = false; + + result = check(KeywordPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(Less o) { + boolean result = false; + + result = check(LessPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(LessOrEquals o) { + boolean result = false; + + result = check(LessOrEqualsPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(Like o) { + boolean result = false; + + result = check(LikePredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(Unlike o) { + boolean result = false; + + result = check(UnlikePredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(org.nuiton.wikitty.query.conditions.Null o) { + boolean result = false; + + result = check(NullPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void visit(NotNull o) { + boolean result = false; + + result = check(NotNullPredicate, o.getElement(), o.getValue()); + + evalStack.push(result); + } + + @Override + public void defaultVisit(Object o) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean defaultVisitEnter(Object o) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean defaultVisitMiddle(Object o) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void defaultVisitLeave(Object o, boolean enterOrMiddleResult) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + + + @Override + public PagedResult<String> findAllByCriteria(WikittyTransaction transaction, Criteria criteria) { + // throw new UnsupportedOperationException("Not supported yet."); + int firstIndex = criteria.getFirstIndex(); + int endIndex = criteria.getEndIndex(); + List<String> ids = new LinkedList<String>(); + int currentIndex = 0; + for (Entry<String, Wikitty> entry : wikittyStorage.getWikitties().entrySet()) { + Wikitty w = entry.getValue(); + String id = entry.getKey(); + Restriction dto = criteria.getRestriction(); + if (!w.isDeleted() && checkRestriction(transaction, dto, w)) { + currentIndex++; + if (currentIndex > firstIndex) { + ids.add(id); + } + if (endIndex >= 0 && currentIndex >= endIndex) { + break; + } + } + } + return new PagedResult<String>(criteria.getName(), + firstIndex, ids.size(), criteria.getRestriction().toString(), null, ids); + } + + @Override + public TreeNodeResult<String> findAllChildrenCount(WikittyTransaction transaction, + String wikittyId, int depth, boolean count, Criteria filter) { + // FIXME + throw new UnsupportedOperationException("Not supported yet."); + } + + private boolean checkRestriction(WikittyTransaction transaction, Restriction restriction, Wikitty w) { if (restriction instanceof BinaryOperator) { BinaryOperator binOp = (BinaryOperator) restriction; @@ -132,7 +1047,7 @@ if (RestrictionName.NOT_EQUALS == restriction.getName()) { return true; } - + return false; } // recupere la valeur dans le wikitty @@ -152,7 +1067,7 @@ } value = t.getValidValue(value); boolean checked = false; - + switch (restriction.getName()) { case EQUALS: if (value instanceof String && o instanceof String) { @@ -232,7 +1147,7 @@ } return checked; - + } else if (restriction instanceof In) { In in = (In) restriction; String fqfieldName = in.getElement().getName(); @@ -400,35 +1315,6 @@ } } - @Override - public PagedResult<String> findAllByCriteria(WikittyTransaction transaction, Criteria criteria) { - // throw new UnsupportedOperationException("Not supported yet."); - int firstIndex = criteria.getFirstIndex(); - int endIndex = criteria.getEndIndex(); - List<String> ids = new LinkedList<String>(); - int currentIndex = 0; - for (Entry<String, Wikitty> entry : wikittyStorage.getWikitties().entrySet()) { - Wikitty w = entry.getValue(); - String id = entry.getKey(); - Restriction dto = criteria.getRestriction(); - if (!w.isDeleted() && checkRestriction(transaction, dto, w)) { - currentIndex++; - if (currentIndex > firstIndex) { - ids.add(id); - } - if (endIndex >= 0 && currentIndex >= endIndex) { - break; - } - } - } - return new PagedResult<String>(criteria.getName(), - firstIndex, ids.size(), criteria.getRestriction().toString(), null, ids); - } - @Override - public TreeNodeResult<String> findAllChildrenCount(WikittyTransaction transaction, - String wikittyId, int depth, boolean count, Criteria filter) { - // FIXME - throw new UnsupportedOperationException("Not supported yet."); - } + } Added: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java (rev 0) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,378 @@ +package org.nuiton.wikitty.query; + +import java.util.Date; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyImpl; + +/** + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyQueryTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyQueryTest.class); + + @Test + public void testParseEachElement() throws Exception { + Wikitty w = new WikittyImpl(); + + { + WikittyQuery query = new WikittyQueryMaker().and().rFalse().rFalse().end(); + String queryString = query.getCondition().toString(); + System.out.println("queryString:" + queryString); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + + { + WikittyQuery query = new WikittyQueryMaker().bw("ext.field", 0, 10).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().containsAll("ext.field", new Date(), new Date()).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().extContainsAll("ext1", "ext2").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().eq("ext.field", w).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().exteq("ext").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().rFalse().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().gt("ext.field", 13.3).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().ge("ext.field", 20.5).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().keyword("value").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().lt("ext.field", new Date()).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().le("ext.field", 30).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().like("ext.field", "truc").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().ne("ext.field", w).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().isNotNull("ext.field").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().isNull("ext.field").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().rTrue().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().unlike("ext.field", "titi").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().sw("ext.field", "debut").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().ew("ext.field", "fin").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().notsw("ext.field", "pasdebut").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().notew("ext.field", "pasfin").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().not().rTrue().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().rFalse().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().or().rFalse().rTrue().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().eq("ext.field", w).end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().not().and().eq("ext.field", 1).eq("ext.field", 2).close().close().end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + { + WikittyQuery query = new WikittyQueryMaker().eq("ext.field", "truc").end(); + String queryString = query.getCondition().toString(); + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + String queryParsedString = queryParsed.getCondition().toString(); + System.out.println("queryString:" + queryString); + System.out.println("queryParsed:" + queryParsedString); + Assert.assertEquals(query, queryParsed); + Assert.assertEquals(queryString, queryParsedString); + } + } + + @Test + public void testParse() throws Exception { + Wikitty w = new WikittyImpl(); + + // creation d'une query avec toutes les conditions possibles + // et tous les types possibles (string, boolean, Wikitty, Date) + WikittyQueryMaker cc = new WikittyQueryMaker(); + // on ecrit pas la requete en flux pour savoir s'il y une erreur a dans + // quelle methode elle arrive + cc.and(); + cc.bw("ext.field", 0, 10); + cc.containsAll("ext.field", new Date(), new Date()); + cc.extContainsAll("ext1", "ext2"); + cc.eq("ext.field", w); + cc.exteq("ext"); + cc.rFalse(); + cc.gt("ext.field", 13.3); + cc.ge("ext.field", 20.5); + cc.keyword("value"); + cc.lt("ext.field", new Date()); + cc.le("ext.field", 30); + cc.like("ext.field", "truc"); + cc.ne("ext.field", w); + cc.isNotNull("ext.field"); + cc.isNull("ext.field"); + cc.rTrue(); + cc.unlike("ext.field", "titi"); + cc.sw("ext.field", "debut"); + cc.ew("ext.field", "fin"); + cc.notsw("ext.field", "pasdebut"); + cc.notew("ext.field", "pasfin"); + cc.not(); + cc.rFalse(); + cc.close(); + cc.or(); + cc.eq("ext.field", w); + cc.not().and().eq("ext.field", 1).eq("ext.field", 2).close().close(); + cc.eq("ext.field", "truc"); + cc.close(); + WikittyQuery query = cc.end(); + + // transformation en string (test du visiteur to String) + String queryString = query.getCondition().toString(); + System.out.println("queryString:" + queryString); + + // test de la copie de query + WikittyQuery queryCopy = query.copy(); + System.out.println("queryCopy:" + queryCopy.getCondition()); + + // parsing du query genere + WikittyQuery queryParsed = WikittyQueryParser.parse(queryString); + System.out.println("queryParsed:" + queryParsed.getCondition()); + + String queryCopyString = queryCopy.getCondition().toString(); + System.out.println("queryCopyString:" + queryCopyString); + + // parsing du query genere a partir de la copy + WikittyQuery queryCopyParsed = WikittyQueryParser.parse(queryCopyString); + System.out.println("queryParsed:" + queryParsed.getCondition()); + + // test d'equalite sur les 2 query + Assert.assertEquals(query, queryCopy); + + // test d'equalite sur les representation string des 2 query + Assert.assertEquals(queryParsed.toString(), queryCopyParsed.toString()); + } +} Added: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java (rev 0) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java 2011-12-28 18:50:45 UTC (rev 1259) @@ -0,0 +1,181 @@ +package org.nuiton.wikitty.storage; + +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyGroup; +import org.nuiton.wikitty.entities.WikittyGroupImpl; +import org.nuiton.wikitty.entities.WikittyImpl; +import org.nuiton.wikitty.entities.WikittyLabel; +import org.nuiton.wikitty.entities.WikittyLabelImpl; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; +import org.nuiton.wikitty.query.WikittyQueryResult; + +/** + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittySearchEngineInMemoryTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittySearchEngineInMemoryTest.class); + + @Test + public void testfindAllByQuery() throws Exception { + + // initialisation des données + WikittyLabelImpl l1 = new WikittyLabelImpl(new WikittyImpl("l1")); + l1.addLabels("toutou"); + l1.addLabels("titi"); + + WikittyLabelImpl l2 = new WikittyLabelImpl(new WikittyImpl("l2")); + + WikittyGroupImpl g1 = new WikittyGroupImpl(new WikittyImpl("g1")); + g1.setName("MonGroup1"); + g1.addMembers(l1.getWikittyId()); + + WikittyGroupImpl g2 = new WikittyGroupImpl(new WikittyImpl("g2")); + g2.setName("MonGroup2"); + g2.addMembers(l2.getWikittyId()); + + WikittyGroupImpl g3 = new WikittyGroupImpl(new WikittyImpl("g3")); + g3.setName("MonGroup3"); + g3.addMembers(l1.getWikittyId()); + g3.addMembers(l2.getWikittyId()); + + + Collection<Wikitty> wikitties = new LinkedList<Wikitty>(); + wikitties.add(l1.getWikitty()); + wikitties.add(l2.getWikitty()); + wikitties.add(g1.getWikitty()); + wikitties.add(g2.getWikitty()); + wikitties.add(g3.getWikitty()); + + WikittyStorageInMemory storage = new WikittyStorageInMemory(); + storage.store(null, wikitties, false); + + WikittySearchEngineInMemory se = new WikittySearchEngineInMemory(storage); + + { + // recherche des labels + WikittyQuery q = new WikittyQueryMaker().eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "toutou").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // seul l1 doit etre retrouve + Assert.assertEquals(1, result.size()); + Assert.assertEquals(l1.getWikittyId(), result.peek()); + } + + { + // recherche des du keyword 'i' + WikittyQuery q = new WikittyQueryMaker().keyword("i").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // seul l1 doit etre retrouve + Assert.assertEquals(1, result.size()); + Assert.assertEquals(l1.getWikittyId(), result.peek()); + } + + { + // recherche des du keyword 'ou' + WikittyQuery q = new WikittyQueryMaker().keyword("ou").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // l1 et g1, g2, g3 doivent etre retrouve + Assert.assertEquals(4, result.size()); + Assert.assertTrue(result.getAll().containsAll(Arrays.asList( + l1.getWikittyId(), g1.getWikittyId(), g2.getWikittyId(), g3.getWikittyId()))); + } + + { + // recherche des du keyword 'ou' + WikittyQuery q = new WikittyQueryMaker().and().exteq(WikittyGroup.EXT_WIKITTYGROUP).keyword("ou").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // g1, g2, g3 doivent etre retrouve mais pas l1 (pas la bonne extension) + Assert.assertEquals(3, result.size()); + Assert.assertTrue(result.getAll().containsAll(Arrays.asList( + g1.getWikittyId(), g2.getWikittyId(), g3.getWikittyId()))); + } + + { + // recherche des labels + WikittyQuery q = new WikittyQueryMaker().isNull(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS).end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // seul l2 doit etre retrouve + Assert.assertEquals(1, result.size()); + Assert.assertEquals(l2.getWikittyId(), result.peek()); + } + + { + WikittyQuery q = new WikittyQueryMaker().like(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, "*P2").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // seul g2 doit etre retrouve + Assert.assertEquals(1, result.size()); + Assert.assertEquals(g2.getWikittyId(), result.peek()); + } + + { + WikittyQuery q = new WikittyQueryMaker().ew(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, "p2").end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // seul g2 doit etre retrouve + Assert.assertEquals(1, result.size()); + Assert.assertEquals(g2.getWikittyId(), result.peek()); + } + + { // test join + WikittyQuery q = new WikittyQueryMaker() + .join(WikittyGroup.FQ_FIELD_WIKITTYGROUP_MEMBERS) + .eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi") + .end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // g1, g3 doivent etre retrouve via le join + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.getAll().containsAll(Arrays.asList( + g1.getWikittyId(), g3.getWikittyId()))); + } + + { // test join + WikittyQuery q = new WikittyQueryMaker() + .or() + .ideq(g2.getWikittyId()) + .join(WikittyGroup.FQ_FIELD_WIKITTYGROUP_MEMBERS).eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi") + .end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // g1, g2, g3 doivent etre retrouve (g2 via ideq, et g1, g3 via le join) + Assert.assertEquals(3, result.size()); + Assert.assertTrue(result.getAll().containsAll(Arrays.asList( + g1.getWikittyId(), g2.getWikittyId(), g3.getWikittyId()))); + } + + { // test join + WikittyQuery q = new WikittyQueryMaker() + .and() + .not().ideq(g1.getWikittyId()).close() + .join(WikittyGroup.FQ_FIELD_WIKITTYGROUP_MEMBERS).eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi") + .end(); + WikittyQueryResult<String> result = se.findAllByQuery(null, q); + // g3 doit etre retrouve via le join, et g1 est exclue via la not(ideq) + Assert.assertEquals(1, result.size()); + Assert.assertTrue(result.getAll().containsAll(Arrays.asList( + g3.getWikittyId()))); + } + + // TODO poussin 20111228 do more test to test all possible condition + + } + + @Test + public void findAllChildrenCount() throws Exception { + // don't test it not yet implemented :( + } + +} +