Wikitty-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
February 2013
- 2 participants
- 31 discussions
r1536 - trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr
by bpoussin@users.nuiton.org 22 Feb '13
by bpoussin@users.nuiton.org 22 Feb '13
22 Feb '13
Author: bpoussin
Date: 2013-02-22 23:04:56 +0100 (Fri, 22 Feb 2013)
New Revision: 1536
Url: http://nuiton.org/projects/wikitty/repository/revisions/1536
Log:
on ne met pas dans la map destine au calcul du select les champs
purement fait pour l'indexation solr (il commence par #)
Modified:
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2013-02-22 22:03:30 UTC (rev 1535)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2013-02-22 22:04:56 UTC (rev 1536)
@@ -231,30 +231,35 @@
String fieldName = ElementModifier.convertToField(solrField);
String fieldType = StringUtils.substringAfter(solrField, fieldName);
- FieldType type;
- if (fieldType.startsWith(SUFFIX_BOOLEAN)) {
- type = new FieldType(WikittyTypes.BOOLEAN, 0, Integer.MAX_VALUE);
- } else if (fieldType.startsWith(SUFFIX_DATE)) {
- type = new FieldType(WikittyTypes.DATE, 0, Integer.MAX_VALUE);
- } else if (fieldType.startsWith(SUFFIX_NUMERIC)) {
- type = new FieldType(WikittyTypes.NUMERIC, 0, Integer.MAX_VALUE);
- } else {
- type = new FieldType(WikittyTypes.STRING, 0, Integer.MAX_VALUE);
- }
+ // si on a encore le prefix c'est un champs pure SolR, on ne le
+ // mais pas dans la map retournee
+ if (!StringUtils.startsWith(fieldName, WikittySolrConstant.SOLR_WIKITTY_PREFIX)) {
- Collection values = doc.getFieldValues(solrField);
- values = (Collection)type.getValidValue(values);
+ FieldType type;
+ if (fieldType.startsWith(SUFFIX_BOOLEAN)) {
+ type = new FieldType(WikittyTypes.BOOLEAN, 0, Integer.MAX_VALUE);
+ } else if (fieldType.startsWith(SUFFIX_DATE)) {
+ type = new FieldType(WikittyTypes.DATE, 0, Integer.MAX_VALUE);
+ } else if (fieldType.startsWith(SUFFIX_NUMERIC)) {
+ type = new FieldType(WikittyTypes.NUMERIC, 0, Integer.MAX_VALUE);
+ } else {
+ type = new FieldType(WikittyTypes.STRING, 0, Integer.MAX_VALUE);
+ }
- Object value;
- if (values.isEmpty()) {
- value = null;
- } else if (values.size() == 1) {
- value = values.iterator().next();
- } else {
- value = values;
+ Collection values = doc.getFieldValues(solrField);
+ values = (Collection)type.getValidValue(values);
+
+ Object value;
+ if (values.isEmpty()) {
+ value = null;
+ } else if (values.size() == 1) {
+ value = values.iterator().next();
+ } else {
+ value = values;
+ }
+
+ result.put(fieldName, value);
}
-
- result.put(fieldName, value);
}
return result;
}
1
0
r1535 - trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function
by bpoussin@users.nuiton.org 22 Feb '13
by bpoussin@users.nuiton.org 22 Feb '13
22 Feb '13
Author: bpoussin
Date: 2013-02-22 23:03:30 +0100 (Fri, 22 Feb 2013)
New Revision: 1535
Url: http://nuiton.org/projects/wikitty/repository/revisions/1535
Log:
si le champs demande sur l'objet n'existe pas, on ajoute null
dans la liste au lieu de ne rien mettre (ce qui faisait un decalage
et donc des choses bizarre)
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java 2013-02-22 22:02:30 UTC (rev 1534)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java 2013-02-22 22:03:30 UTC (rev 1535)
@@ -61,15 +61,13 @@
ListObjectOrMap result = new ListObjectOrMap();
for (Map<String, Object> m : data) {
- if (m.containsKey(field)) {
- Object val = m.get(field);
- if (val instanceof Collection) {
- for (Object o : (Collection)val) {
- result.add(field, o);
- }
- } else {
- result.add(field, val);
+ Object val = m.get(field);
+ if (val instanceof Collection) {
+ for (Object o : (Collection)val) {
+ result.add(field, o);
}
+ } else {
+ result.add(field, val);
}
}
1
0
r1534 - trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query
by bpoussin@users.nuiton.org 22 Feb '13
by bpoussin@users.nuiton.org 22 Feb '13
22 Feb '13
Author: bpoussin
Date: 2013-02-22 23:02:30 +0100 (Fri, 22 Feb 2013)
New Revision: 1534
Url: http://nuiton.org/projects/wikitty/repository/revisions/1534
Log:
correction des nom de fonction qui peuvent comporte un # lorsqu'on indique une methode d'un objet
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-21 19:18:13 UTC (rev 1533)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-22 22:02:30 UTC (rev 1534)
@@ -515,7 +515,7 @@
Rule function() {
Var<String> alias = new Var<String>();
- return Sequence(field(), push(match()), BRACKET_OPEN,
+ return Sequence(OneOrMore(FirstOf(field(), AnyOf("#"))), push(match()), BRACKET_OPEN,
push(new LinkedList()),
Optional(functionOrFieldOrString(), ZeroOrMore(COMMA, functionOrFieldOrString())),
BRACKET_CLOSE, Optional(alias(alias)),
1
0
r1533 - in trunk/wikitty-api/src/main/java/org/nuiton/wikitty: query services
by bpoussin@users.nuiton.org 21 Feb '13
by bpoussin@users.nuiton.org 21 Feb '13
21 Feb '13
Author: bpoussin
Date: 2013-02-21 20:18:13 +0100 (Thu, 21 Feb 2013)
New Revision: 1533
Url: http://nuiton.org/projects/wikitty/repository/revisions/1533
Log:
amelioration des logs
le toString de FunctionValue ajouter des " autour de la valeur
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-21 14:32:58 UTC (rev 1532)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-21 19:18:13 UTC (rev 1533)
@@ -36,7 +36,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyUtil;
-import org.nuiton.wikitty.query.conditions.Aggregate;
import org.nuiton.wikitty.query.conditions.And;
import org.nuiton.wikitty.query.conditions.Between;
import org.nuiton.wikitty.query.conditions.Condition;
@@ -62,7 +61,6 @@
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
import org.nuiton.wikitty.query.function.FunctionFieldValue;
-import org.nuiton.wikitty.query.function.FunctionFusion;
import org.nuiton.wikitty.query.function.FunctionValue;
import org.parboiled.BaseParser;
import org.parboiled.Context;
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java 2013-02-21 14:32:58 UTC (rev 1532)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java 2013-02-21 19:18:13 UTC (rev 1533)
@@ -24,6 +24,7 @@
*/
package org.nuiton.wikitty.query;
+import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -364,7 +365,7 @@
@Override
public void visit(FunctionValue function) {
- text += String.valueOf(function.getValue());
+ text += '"' + String.valueOf(function.getValue()).replaceAll("\"", "\\\"") + '"';
}
@Override
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 2013-02-21 14:32:58 UTC (rev 1532)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2013-02-21 19:18:13 UTC (rev 1533)
@@ -977,12 +977,17 @@
if (c == null) {
result.add(null);
} else {
- long startTime = System.nanoTime();
- WikittyQueryResult<Map<String, Object>> searchResult =
- getSearchEngine().findAllByQuery(tx, c);
- long estimatedTime = System.nanoTime() - startTime;
- searchResult.setTimeQuery(estimatedTime);
- result.add(searchResult);
+ try {
+ long startTime = System.nanoTime();
+ WikittyQueryResult<Map<String, Object>> searchResult =
+ getSearchEngine().findAllByQuery(tx, c);
+ long estimatedTime = System.nanoTime() - startTime;
+ searchResult.setTimeQuery(estimatedTime);
+ result.add(searchResult);
+ } catch (Exception eee) {
+ throw new WikittyException(String.format(
+ "Can't evaluate query '%s'", c), eee);
+ }
}
}
1
0
r1532 - trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query
by bpoussin@users.nuiton.org 21 Feb '13
by bpoussin@users.nuiton.org 21 Feb '13
21 Feb '13
Author: bpoussin
Date: 2013-02-21 15:32:58 +0100 (Thu, 21 Feb 2013)
New Revision: 1532
Url: http://nuiton.org/projects/wikitty/repository/revisions/1532
Log:
oups, getClass().getSimpleName() there is no pacakge :(
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-21 14:28:35 UTC (rev 1531)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-21 14:32:58 UTC (rev 1532)
@@ -516,7 +516,7 @@
*/
public M function(String method, String alias, Object ... args) {
if (StringUtils.startsWith(method, "#")) {
- method = this.getClass().getSimpleName() + method;
+ method = this.getClass().getName() + method;
}
WikittyQueryFunctionWrapper f = new WikittyQueryFunctionWrapper(method, alias);
boolean mustClose = false;
1
0
r1531 - in trunk: wikitty-api/src/main/java/org/nuiton/wikitty wikitty-api/src/main/java/org/nuiton/wikitty/query wikitty-api/src/main/java/org/nuiton/wikitty/query/function wikitty-api/src/main/java/org/nuiton/wikitty/storage wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr
by bpoussin@users.nuiton.org 21 Feb '13
by bpoussin@users.nuiton.org 21 Feb '13
21 Feb '13
Author: bpoussin
Date: 2013-02-21 15:28:35 +0100 (Thu, 21 Feb 2013)
New Revision: 1531
Url: http://nuiton.org/projects/wikitty/repository/revisions/1531
Log:
debuggage et am?\195?\169lioration des nouveaux select
Added:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/ListObjectOrMap.java
Removed:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -60,6 +60,7 @@
import org.nuiton.wikitty.entities.WikittyTokenHelper;
import org.nuiton.wikitty.entities.WikittyTypes;
import org.nuiton.wikitty.entities.WikittyUser;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryMaker;
import org.nuiton.wikitty.query.WikittyQueryResult;
@@ -738,8 +739,38 @@
*/
protected <E> List<WikittyQueryResult<E>> findAllByQuery(
Class<E> clazz, List<WikittyQuery> queries, boolean limitToFirst) {
+ List<WikittyQueryResult<Map<String, E>>> tmp =
+ findAllByQueryAsMap(clazz, queries, limitToFirst);
+
+ List<WikittyQueryResult<E>> result = new ArrayList<WikittyQueryResult<E>>(tmp.size());
+ for (WikittyQueryResult p : tmp) {
+ result.add(p.convertMapToSimple());
+// result.add(castTo(clazz, p));
+ }
+
+ return result;
+ }
+
+ /**
+ * Cette method doit etre l'unique methode finalement utilise par toutes
+ * les methodes find avec un cast vers clazz
+ *
+ * Search object that correspond to criteria and that have all extension
+ * needed by BusinessEntity (clazz), if clazz is BusinessEntity class.
+ * If one criteria is empty, find all extensions
+ * for this criteria else if criteria is null return null.
+ *
+ * @param <E> object type
+ * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
+ * @param clazz entity class, can be null for no conversion
+ * @param queries criterias
+ * @param limitToFirst if true limit result to first result (first = 0, limit = 1)
+ * @return paged result
+ */
+ protected <E> List<WikittyQueryResult<Map<String, E>>> findAllByQueryAsMap(
+ Class<E> clazz, List<WikittyQuery> queries, boolean limitToFirst) {
long start = TimeLog.getTime();
- List<WikittyQueryResult<E>> result = null;
+ List<WikittyQueryResult<Map<String, E>>> result = null;
List<WikittyQuery> serviceQueries;
if (queries != null) {
if (clazz != null && BusinessEntity.class.isAssignableFrom(clazz)) {
@@ -817,12 +848,12 @@
List<WikittyQueryResult<Map<String, Object>>> pagedResult =
findAllByQueryAsMap(serviceQueries);
- result = new ArrayList<WikittyQueryResult<E>>(pagedResult.size());
- for (WikittyQueryResult<Map<String, Object>> p : pagedResult) {
- result.add((WikittyQueryResult<E>)castTo(clazz, p));
+ result = new ArrayList<WikittyQueryResult<Map<String, E>>>(pagedResult.size());
+ for (WikittyQueryResult p : pagedResult) {
+ result.add((WikittyQueryResult<Map<String, E>>)castToMap(clazz, p));
}
}
- timeLog.log(start, "findAllByQuery<E>(List, limitToFirst)");
+ timeLog.log(start, "findAllByQuery<Map<String, E>>(List, limitToFirst)");
return result;
}
@@ -1074,9 +1105,27 @@
}
}
timeLog.log(start, "findByQuery(List)");
- return result;
+ return result;
}
+ public <E> List<Map<String, E>> findByQueryAsMap(Class<E> clazz, List<WikittyQuery> query) {
+ long start = TimeLog.getTime();
+ List<Map<String, E>> result = null;
+ if (query != null) {
+ List<WikittyQueryResult<Map<String, E>>> tmp = findAllByQueryAsMap(clazz, query, true);
+ result = new ArrayList<Map<String, E>>(tmp.size());
+ for (WikittyQueryResult<Map<String, E>> wqr : tmp) {
+ if (wqr.size() == 0) {
+ result.add(null);
+ } else {
+ result.add(wqr.peek());
+ }
+ }
+ }
+ timeLog.log(start, "findByQuery(List)");
+ return result;
+ }
+
public String findByQuery(WikittyQuery query) {
long start = TimeLog.getTime();
String result = null;
@@ -1094,9 +1143,19 @@
result = findByQueryAsMap(Collections.singletonList(query)).get(0);
}
timeLog.log(start, "findByQuery(One)");
- return result;
+ return result;
}
+ public <E> Map<String, E> findByQueryAsMap(Class<E> clazz, WikittyQuery query) {
+ long start = TimeLog.getTime();
+ Map<String, E> result = null;
+ if (query != null) {
+ result = findByQueryAsMap(clazz, Collections.singletonList(query)).get(0);
+ }
+ timeLog.log(start, "findByQuery(One)");
+ return result;
+ }
+
public String[] findByQuery(
WikittyQuery q1, WikittyQuery q2, WikittyQuery... otherQueries) {
long start = TimeLog.getTime();
@@ -1699,180 +1758,213 @@
}
- /**
- * Convert all objects in list parameter to the wanted type and return
- * new List.
- * For business object transformation, if some
- * result don't have the right extension (clazz) this extension is
- * automatically added.
- *
- * If possible this method don't instanciated new Object. If e is Wikitty
- * and wanted target is Wikitty a simple cast is done.
- *
- * @param target to cast into.
- * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
- * @param objects objects to convert
- * @return List objects in right class or Exception.
- * if conversion is impossible
- * @since 3.4
- */
- public <E, F> List<E> castTo(Class<E> target, List<F> objects) {
- List<E> result;
+// /**
+// * Convert all objects in list parameter to the wanted type and return
+// * new List.
+// * For business object transformation, if some
+// * result don't have the right extension (clazz) this extension is
+// * automatically added.
+// *
+// * If possible this method don't instanciated new Object. If e is Wikitty
+// * and wanted target is Wikitty a simple cast is done.
+// *
+// * @param target to cast into.
+// * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
+// * @param objects objects to convert
+// * @return List objects in right class or Exception.
+// * if conversion is impossible
+// * @since 3.4
+// */
+// public <E, F> List<E> castTo(Class<E> target, List<F> objects) {
+// List<E> result;
+//
+// if (objects == null) {
+// result = null;
+// } else if (target.isAssignableFrom(Object.class)) {
+// // on demande la conversion en Object, donc aucune conversion
+// result = new ArrayList<E>((List<E>)objects);
+// }else if (objects.size() == 0) {
+// // on ne fait rien on met juste une nouvelle liste vide
+// result = new ArrayList<E>();
+// } else if (Wikitty.class.isAssignableFrom(target)) {
+// // On veut des Wikitties en sortie
+//
+// Object first = objects.get(0);
+// if (first instanceof Wikitty) {
+// // W, rien a faire
+// result = (List<E>)objects;
+// } else if (first instanceof BusinessEntityImpl) {
+// // BusinessEntityImpl, il faut recuperer les wikitty
+// result = new ArrayList<E>(objects.size());
+// for (BusinessEntityImpl e : (List<BusinessEntityImpl>)objects) {
+// result.add((E)e.getWikitty());
+// }
+// } else if (first instanceof BusinessEntity) {
+// // BusinessEntity, il faut faire un restore puis remettre la
+// // valeur des champs dans les wikitties recuperes
+//
+// // on collecte tous les ids
+// List<String> ids = new ArrayList(objects.size());
+// for (BusinessEntity e : (List<BusinessEntity>)objects) {
+// ids.add(e.getWikittyId());
+// }
+//
+// List<BusinessEntity> business = (List<BusinessEntity>)objects;
+// List<Wikitty> wikitties = restore(ids);
+// Class entityClass = first.getClass();
+//
+// result = (List<E>)createWikittyFromBusinessEntity(entityClass, business, wikitties);
+// } else if (first instanceof String) {
+// // String, il faut faire un restore
+// // le queryResult courant contient des Ids
+// // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant
+// // ce queryResult ne sait pas ce qu'il fait :)
+// List<String> ids = (List<String>) objects;
+// result = (List<E>)restore(ids);
+// } else {
+// throw new ClassCastException("WikittyQueryResult don't contains"
+// + " object convertible to Wikitty"
+// + " (accepted Wikitty, BusinessEntityImpl, String id) but not "
+// + first.getClass());
+// }
+// } else if (BusinessEntity.class.isAssignableFrom(target)) {
+// // on commence par tout mettre en Wikitty, en utilisant le if du dessus
+// List<Wikitty> resultTmp = castTo(Wikitty.class, objects);
+// result = (List<E>)WikittyUtil.newInstance((Class<BusinessEntity>)target, resultTmp);
+// } else if (Number.class.isAssignableFrom(target)) {
+// result = new ArrayList<E>(objects.size());
+// for (Object o : objects) {
+// BigDecimal v = WikittyUtil.toBigDecimal(o);
+// Number n = WikittyUtil.toNumber(target, v);
+// result.add((E)n);
+// }
+// } else if (Date.class.isAssignableFrom(target)) {
+// result = new ArrayList<E>(objects.size());
+// for (Object o : objects) {
+// Date v = WikittyUtil.toDate(o);
+// result.add((E)v);
+// }
+// } else if (Boolean.class.isAssignableFrom(target)) {
+// result = new ArrayList<E>(objects.size());
+// for (Object o : objects) {
+// Boolean v = WikittyUtil.toBoolean(o);
+// result.add((E)v);
+// }
+// } else if (byte[].class.isAssignableFrom(target)) {
+// result = new ArrayList<E>(objects.size());
+// for (Object o : objects) {
+// byte[] v = WikittyUtil.toBinary(o);
+// result.add((E)v);
+// }
+// } else if (String.class.isAssignableFrom(target)) {
+// result = new ArrayList<E>(objects.size());
+// for (Object o : objects) {
+// String v = WikittyUtil.toString(o);
+// result.add((E)v);
+// }
+// }else {
+// throw new ClassCastException(String.format(
+// "Object list don't contains"
+// + " object convertible to %s"
+// + " (accepted Wikitty, BusinessEntityImpl, String id, Date,"
+// + " BigDecimal, Boolean, byte[]) but not '%s'",
+// target.getName(), objects.get(0).getClass()));
+// }
+//
+// return result;
+// }
+//
+// /**
+// * Convert all objects in list parameter to the wanted type and return
+// * new List.
+// * For business object transformation, if some
+// * result don't have the right extension (clazz) this extension is
+// * automatically added.
+// *
+// * If possible this method don't instanciated new Object. If e is Wikitty
+// * and wanted target is Wikitty a simple cast is done.
+// *
+// * @param target to cast into.
+// * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
+// * @param objects objects to convert
+// * @return List objects in right class or Exception.
+// * if conversion is impossible
+// * @since 3.4
+// */
+// public <E, F> List<Map<String, E>> castToMap(Class<E> target, List<Map> objects) {
+// List<Map<String, E>> result;
+//
+// if (objects == null) {
+// result = null;
+// } else if (target.isAssignableFrom(Object.class)) {
+// // on demande la conversion en Object, donc aucune conversion
+// result = new ArrayList(objects);
+// } else if (objects.size() == 0) {
+// // on ne fait rien on met juste une nouvelle liste vide
+// result = new ArrayList<Map<String, E>>();
+// } else {
+// for (Map map : objects) {
+// if (map != null) {
+// Set<Map.Entry> s = map.entrySet();
+// for (Map.Entry entry : s) {
+// Object value = entry.getValue();
+// if (Wikitty.class.isAssignableFrom(target)) {
+// // On veut des Wikitties en sortie
+// if (value == null) {
+// // rien a faire
+// } else if (value instanceof Wikitty) {
+// // W, rien a faire
+// } else if (value instanceof String) {
+// // String, il faut faire un restore
+// // le queryResult courant contient des Ids
+// // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant
+// // ce queryResult ne sait pas ce qu'il fait :)
+// entry.setValue((E)restore((String)value));
+// } else {
+// throw new ClassCastException("WikittyQueryResult don't contains"
+// + " object convertible to Wikitty"
+// + " (accepted Wikitty, String id) but not "
+// + value.getClass());
+// }
+// } else if (BusinessEntity.class.isAssignableFrom(target)) {
+// // on commence par tout mettre en Wikitty, en utilisant le if du dessus
+// Wikitty resultTmp = castTo(Wikitty.class, value);
+// E business = (E)WikittyUtil.newInstance((Class<BusinessEntity>)target, resultTmp);
+// entry.setValue(business);
+// } else if (Number.class.isAssignableFrom(target)) {
+// BigDecimal v = WikittyUtil.toBigDecimal(value);
+// Number n = WikittyUtil.toNumber(target, v);
+// entry.setValue((E)n);
+// } else if (Date.class.isAssignableFrom(target)) {
+// Date v = WikittyUtil.toDate(value);
+// entry.setValue((E)v);
+// } else if (Boolean.class.isAssignableFrom(target)) {
+// Boolean v = WikittyUtil.toBoolean(value);
+// entry.setValue((E)v);
+// } else if (byte[].class.isAssignableFrom(target)) {
+// byte[] v = WikittyUtil.toBinary(value);
+// entry.setValue((E)v);
+// } else if (String.class.isAssignableFrom(target)) {
+// String v = WikittyUtil.toString(value);
+// entry.setValue((E)v);
+// }else {
+// throw new ClassCastException(String.format(
+// "Object list don't contains"
+// + " object convertible to %s"
+// + " (accepted Wikitty, BusinessEntityImpl, String id, Date,"
+// + " BigDecimal, Boolean, byte[]) but not '%s'",
+// target.getName(), objects.get(0).getClass()));
+// }
+// }
+// }
+// }
+// // tous les objets ont ete converti, on force le cast
+// result = (List)objects;
+// }
+//
+// return result;
+// }
- if (objects == null) {
- result = null;
- } else if (target.isAssignableFrom(Object.class)) {
- // on demande la conversion en Object, donc aucune conversion
- result = new ArrayList<E>((List<E>)objects);
- }else if (objects.size() == 0) {
- // on ne fait rien on met juste une nouvelle liste vide
- result = new ArrayList<E>();
- } else if (Wikitty.class.isAssignableFrom(target)) {
- // On veut des Wikitties en sortie
-
- Object first = objects.get(0);
- if (first instanceof Wikitty) {
- // W, rien a faire
- result = (List<E>)objects;
- } else if (first instanceof BusinessEntityImpl) {
- // BusinessEntityImpl, il faut recuperer les wikitty
- result = new ArrayList<E>(objects.size());
- for (BusinessEntityImpl e : (List<BusinessEntityImpl>)objects) {
- result.add((E)e.getWikitty());
- }
- } else if (first instanceof BusinessEntity) {
- // BusinessEntity, il faut faire un restore puis remettre la
- // valeur des champs dans les wikitties recuperes
-
- // on collecte tous les ids
- List<String> ids = new ArrayList(objects.size());
- for (BusinessEntity e : (List<BusinessEntity>)objects) {
- ids.add(e.getWikittyId());
- }
-
- result = (List<E>)restore(ids);
-
- // on copie les champs des entities dans les wikitties recuperes
- // try settings all fields except version
- try {
- // les entites a mettre dans les wikitties
- BusinessEntity[] entities = objects.toArray(new BusinessEntity[objects.size()]);
- // les wikitties qui seront les resultats
- Wikitty[] wikitties = result.toArray(new Wikitty[result.size()]);
-
- //get all fields
- Class entityClass = first.getClass();
- Field[] fields = entityClass.getDeclaredFields();
-
- for(Field field:fields){
- //for each field that got WikittyField annotation
- if (field.isAnnotationPresent(WikittyField.class)){
-
- //get the attribute's wikitty fqn
- WikittyField annotation = field.getAnnotation(WikittyField.class);
- String fieldFQN = annotation.fqn();
-
- //set the value
- Method m = entityClass.getMethod("get" + StringUtils.capitalize(field.getName()));
-
- for(int i=0; i<entities.length; i++) {
- if (wikitties[i] != null) {
- // le wikitty peut etre null, par exemple a cause de la security
- Object value = m.invoke(entities[i]);
- wikitties[i].setFqField(fieldFQN, value);
- }
- }
- }
- }
- //manually set version
- for(int i=0; i<entities.length; i++) {
- if (wikitties[i] != null) {
- // le wikitty peut etre null, par exemple a cause de la security
- wikitties[i].setWikittyVersion(entities[i].getWikittyVersion());
- }
- }
- } catch (Exception eee) {
- throw new WikittyException("Could not transform entity to Wikitty", eee);
- }
- } else if (first instanceof String) {
- // String, il faut faire un restore
- // le queryResult courant contient des Ids
- // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant
- // ce queryResult ne sait pas ce qu'il fait :)
- List<String> ids = (List<String>) objects;
- result = (List<E>)restore(ids);
- } else {
- throw new ClassCastException("WikittyQueryResult don't contains"
- + " object convertible to Wikitty"
- + " (accepted Wikitty, BusinessEntityImpl, String id) but not "
- + first.getClass());
- }
- } else if (BusinessEntity.class.isAssignableFrom(target)) {
- // on commence par tout mettre en Wikitty, en utilisant le if du dessus
- List<Wikitty> resultTmp = castTo(Wikitty.class, objects);
- result = (List<E>)WikittyUtil.newInstance((Class<BusinessEntity>)target, resultTmp);
- } else if (Number.class.isAssignableFrom(target)) {
- result = new ArrayList<E>(objects.size());
- for (Object o : objects) {
- BigDecimal v = WikittyUtil.toBigDecimal(o);
- Number n = toNumber(target, v);
- result.add((E)n);
- }
- } else if (Date.class.isAssignableFrom(target)) {
- result = new ArrayList<E>(objects.size());
- for (Object o : objects) {
- Date v = WikittyUtil.toDate(o);
- result.add((E)v);
- }
- } else if (Boolean.class.isAssignableFrom(target)) {
- result = new ArrayList<E>(objects.size());
- for (Object o : objects) {
- Boolean v = WikittyUtil.toBoolean(o);
- result.add((E)v);
- }
- } else if (byte[].class.isAssignableFrom(target)) {
- result = new ArrayList<E>(objects.size());
- for (Object o : objects) {
- byte[] v = WikittyUtil.toBinary(o);
- result.add((E)v);
- }
- } else if (String.class.isAssignableFrom(target)) {
- result = new ArrayList<E>(objects.size());
- for (Object o : objects) {
- String v = WikittyUtil.toString(o);
- result.add((E)v);
- }
- }else {
- throw new ClassCastException(String.format(
- "Object list don't contains"
- + " object convertible to %s"
- + " (accepted Wikitty, BusinessEntityImpl, String id, Date,"
- + " BigDecimal, Boolean, byte[]) but not '%s'",
- target.getName(), objects.get(0).getClass()));
- }
-
- return result;
- }
-
- protected Number toNumber(Class target, BigDecimal v) {
- Number result = v;
- if (Byte.class.isAssignableFrom(target)) {
- result = v.byteValue();
- } else if (Double.class.isAssignableFrom(target)) {
- result = v.doubleValue();
- } else if (Float.class.isAssignableFrom(target)) {
- result = v.floatValue();
- } else if (Integer.class.isAssignableFrom(target)) {
- result = v.intValue();
- } else if (Long.class.isAssignableFrom(target)) {
- result = v.longValue();
- } else if (Short.class.isAssignableFrom(target)) {
- result = v.shortValue();
- } else if (BigInteger.class.isAssignableFrom(target)) {
- result = v.toBigInteger();
- }
- return result;
- }
/**
* Convert e parameter to the wanted type and return it.
* For business object transformation, if some
@@ -1895,7 +1987,7 @@
if (e == null) {
result = null;
} else {
- List<E> tmp = castTo(target, Collections.singletonList(e));
+ List<E> tmp = castTo(target, WikittyUtil.singletonList(e));
result = tmp.get(0);
}
@@ -1937,4 +2029,185 @@
return result;
}
+ /**
+ * Convert all result to the wanted type and return new WikittyQueryResult
+ * with this new result list. For business object transformation, if some
+ * result don't have the right extension (clazz) this extension is
+ * automatically added.
+ *
+ * @param queryResult result to convert
+ * @param target to cast into.
+ * Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
+ * @return new WikittyQueryResult with element in right class or Exception
+ * if conversion is impossible
+ */
+ public <E> WikittyQueryResult<Map<String, E>> castToMap(Class<E> target,
+ WikittyQueryResult<Map> queryResult) {
+ WikittyQueryResult<Map<String, E>> result;
+
+ long startTime = System.nanoTime();
+
+ List<Map<String, E>> castedResult = castToMap(target, queryResult.getAll());
+ long estimatedTime = System.nanoTime() - startTime;
+
+ result = new WikittyQueryResult<Map<String, E>>(
+ queryResult.getQueryName(),
+ queryResult.getOffset(), queryResult.getTotalResult(),
+ queryResult.getQueryString(), queryResult.getFacets(),
+ castedResult,
+ queryResult.getTimeQuery(), estimatedTime);
+
+ return result;
+ }
+
+
+
+
+ public <O, N, E extends Map<String, O>, F extends Map<String, N>> List<E> castToMap(Class<O> target, List<F> objects) {
+ List result = castTo(target, objects);
+ return result;
+ }
+
+
+ public <E, F> List<E> castTo(Class<E> target, List<F> objects) {
+ List<E> result = (List<E>)objects;
+
+ if (objects == null
+ || target == null
+ || objects.size() == 0
+ // on demande la conversion en Object, donc aucune conversion
+ ||target.isAssignableFrom(Object.class)) {
+ // on ne fait rien
+ } else if (BusinessEntity.class.isAssignableFrom(target)) {
+ // on commence par tout mettre en Wikitty, en utilisant une autre regle
+ List<Wikitty> resultTmp = castTo(Wikitty.class, objects);
+ ListObjectOrMap list = new ListObjectOrMap(resultTmp);
+ // ensuite on cree les businessEntity
+ for (ListObjectOrMap.ListObjectOrMapIterator i = list.iter(); i.hasNext();) {
+ Wikitty o = (Wikitty)i.next();
+ Object business = WikittyUtil.newInstance((Class<BusinessEntity>)target, o);
+ i.setValue(business);
+ }
+ } else {
+ ListObjectOrMap list = new ListObjectOrMap(objects);
+ // les ids a collecter et restorer, et en valeur si besoin le BusinessEntity associe
+ Map<String, ListObjectOrMap.Key> ids = new HashMap();
+
+ for (ListObjectOrMap.ListObjectOrMapIterator i = list.iter(); i.hasNext();) {
+ Object o = i.next();
+
+ if (Number.class.isAssignableFrom(target)) {
+ BigDecimal v = WikittyUtil.toBigDecimal(o);
+ Number n = WikittyUtil.toNumber(target, v);
+ i.setValue(n);
+ } else if (Date.class.isAssignableFrom(target)) {
+ Date v = WikittyUtil.toDate(o);
+ i.setValue(v);
+ } else if (Boolean.class.isAssignableFrom(target)) {
+ Boolean v = WikittyUtil.toBoolean(o);
+ i.setValue(v);
+ } else if (byte[].class.isAssignableFrom(target)) {
+ byte[] v = WikittyUtil.toBinary(o);
+ i.setValue(v);
+ } else if (String.class.isAssignableFrom(target)) {
+ String v = WikittyUtil.toString(o);
+ i.setValue(v);
+ } else if (Wikitty.class.isAssignableFrom(target)) {
+ // On veut des Wikitties en sortie
+
+ if (o instanceof Wikitty) {
+ // W, rien a faire
+ } else if (o instanceof BusinessEntityImpl) {
+ // BusinessEntityImpl, il faut recuperer les wikitties
+ i.setValue(((BusinessEntityImpl)o).getWikitty());
+ } else if (o instanceof BusinessEntity) {
+ // on collecte tous les ids
+ String id = ((BusinessEntity)o).getWikittyId();
+ ids.put(id, i.getKey());
+ } else if (o instanceof String) {
+ // String, il faudra faire un restore
+ ids.put((String)o, i.getKey());
+ } else {
+ throw new ClassCastException("WikittyQueryResult don't contains"
+ + " object convertible to Wikitty"
+ + " (accepted Wikitty, BusinessEntityImpl, String id) but not "
+ + o.getClass());
+ }
+ } else {
+ throw new ClassCastException(String.format(
+ "Object list don't contains"
+ + " object convertible to %s"
+ + " (accepted Wikitty, BusinessEntityImpl, String id, Date,"
+ + " BigDecimal, Boolean, byte[]) but not '%s'",
+ target.getName(), o.getClass()));
+ }
+ }
+
+ if (!ids.isEmpty()) {
+ Set<Wikitty> wikitties = restore(ids.keySet());
+ for (Wikitty w : wikitties) {
+ String id = w.getWikittyId();
+ ListObjectOrMap.Key key = ids.get(id);
+ Object o = key.getValue();
+ if (o instanceof BusinessEntity) {
+ // il faut mettre a jour le wikitty avec les champs de BusinessEntity
+ WikittyUtil.updateWikitty(w, (BusinessEntity)o);
+ }
+ key.setValue(w);
+ }
+ }
+ }
+ return result;
+ }
+
+
+
+
+
+//
+// protected List<Wikitty> createWikittyFromBusinessEntity(Class entityClass, List<BusinessEntity> objects, List<Wikitty> w) {
+// // on copie les champs des entities dans les wikitties recuperes
+// // try settings all fields except version
+// try {
+// // les entites a mettre dans les wikitties
+// BusinessEntity[] entities = objects.toArray(new BusinessEntity[objects.size()]);
+// // les wikitties qui seront les resultats
+// Wikitty[] wikitties = w.toArray(new Wikitty[w.size()]);
+//
+// //get all fields
+// Field[] fields = entityClass.getDeclaredFields();
+//
+// for(Field field:fields){
+// //for each field that got WikittyField annotation
+// if (field.isAnnotationPresent(WikittyField.class)){
+//
+// //get the attribute's wikitty fqn
+// WikittyField annotation = field.getAnnotation(WikittyField.class);
+// String fieldFQN = annotation.fqn();
+//
+// //set the value
+// Method m = entityClass.getMethod("get" + StringUtils.capitalize(field.getName()));
+//
+// for(int i=0; i<entities.length; i++) {
+// if (wikitties[i] != null) {
+// // le wikitty peut etre null, par exemple a cause de la security
+// Object value = m.invoke(entities[i]);
+// wikitties[i].setFqField(fieldFQN, value);
+// }
+// }
+// }
+// }
+// //manually set version
+// for(int i=0; i<entities.length; i++) {
+// if (wikitties[i] != null) {
+// // le wikitty peut etre null, par exemple a cause de la security
+// wikitties[i].setWikittyVersion(entities[i].getWikittyVersion());
+// }
+// }
+// return w;
+// } catch (Exception eee) {
+// throw new WikittyException("Could not transform entity to Wikitty", eee);
+// }
+//
+// }
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -43,6 +43,7 @@
import org.nuiton.wikitty.services.WikittyServiceEnhanced;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -749,6 +750,35 @@
}
/**
+ * Converti un BigDecimal en un nombre
+ *
+ * @param target la class du nombre
+ * @param v
+ * @return
+ */
+ static public Number toNumber(Class target, BigDecimal v) {
+ Number result = v;
+ if (BigDecimal.class.isAssignableFrom(target)) {
+ result = v;
+ } else if (Byte.TYPE.isAssignableFrom(target) || Byte.class.isAssignableFrom(target)) {
+ result = v.byteValue();
+ } else if (Double.TYPE.isAssignableFrom(target) || Double.class.isAssignableFrom(target)) {
+ result = v.doubleValue();
+ } else if (Float.TYPE.isAssignableFrom(target) || Float.class.isAssignableFrom(target)) {
+ result = v.floatValue();
+ } else if (Integer.TYPE.isAssignableFrom(target) || Integer.class.isAssignableFrom(target)) {
+ result = v.intValue();
+ } else if (Long.TYPE.isAssignableFrom(target) || Long.class.isAssignableFrom(target)) {
+ result = v.longValue();
+ } else if (Short.TYPE.isAssignableFrom(target) || Short.class.isAssignableFrom(target)) {
+ result = v.shortValue();
+ } else if (BigInteger.class.isAssignableFrom(target)) {
+ result = v.toBigInteger();
+ }
+ return result;
+ }
+
+ /**
* Convert object o for export CSV/XML.
*
* @param field field description
@@ -1601,6 +1631,47 @@
static public WikittyDateConverter dateConverter = new WikittyDateConverter();
/**
+ * Met a jout les donnees d'un wikitty via les informations d'un BusinessEntity
+ * @param w le wikitty a mettre a jour (peut-etre null)
+ * @param be le business entity utilise pour mettre a jour le wikitty
+ */
+ static public void updateWikitty(Wikitty w, BusinessEntity be) {
+ // le wikitty peut etre null, par exemple a cause de la security
+ if (w == null) {
+ return;
+ }
+
+ // on copie les champs des entities dans les wikitties recuperes
+ // try settings all fields except version
+ try {
+ Class entityClass = be.getClass();
+ //get all fields
+ Field[] fields = entityClass.getDeclaredFields();
+
+ for(Field field:fields){
+ //for each field that got WikittyField annotation
+ if (field.isAnnotationPresent(WikittyField.class)){
+
+ //get the attribute's wikitty fqn
+ WikittyField annotation = field.getAnnotation(WikittyField.class);
+ String fieldFQN = annotation.fqn();
+
+ //set the value
+ Method m = entityClass.getMethod("get" + StringUtils.capitalize(field.getName()));
+
+ Object value = m.invoke(be);
+ w.setFqField(fieldFQN, value);
+ }
+ }
+ //manually set version
+ w.setWikittyVersion(be.getWikittyVersion());
+ } catch (Exception eee) {
+ throw new WikittyException("Could not transform entity to Wikitty", eee);
+ }
+ }
+
+
+ /**
* Copy all properties (get/set) from source to destination,
* except wikitty property
*
@@ -1681,4 +1752,32 @@
}
}
+ /**
+ * Creation d'une map contenant une seule valeur. On utilise pas
+ * {@link Collections#singletonMap} car on ne peut plus changer la valeur
+ * alors qu'on en a besoin dans Wikitty, lorsqu'on converti des donnees
+ *
+ * @param k la cle
+ * @param v la valeur
+ * @return une nouvelle map avec 1 seul element et un load factor a 1
+ */
+ static public Map singletonMap(Object k, Object v) {
+ HashMap result = new HashMap(1, 1);
+ result.put(k, v);
+ return result;
+ }
+
+ /**
+ * Creation d'une list contenant une seule valeur. On utilise pas
+ * {@link Collections#singletonList} car on ne peut plus changer la valeur
+ * alors qu'on en a besoin dans Wikitty, lorsqu'on converti des donnees
+ *
+ * @param o la valeur
+ * @return une nouvelle list avec 1 seul element et une taille initiale de 1
+ */
+ static public List singletonList(Object o) {
+ List result = new ArrayList(1);
+ result.add(o);
+ return result;
+ }
}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/ListObjectOrMap.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/ListObjectOrMap.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/ListObjectOrMap.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -0,0 +1,321 @@
+package org.nuiton.wikitty.query;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Encapsule une liste pour permettre une iteration et une modification facile
+ * des valeurs de cette listes. Les valeurs peuvent etre dans des maps, il est
+ * donc penible de parcourrir la liste, puis les maps, puis de modifier les
+ * valeurs de ces maps. La method {@link iter} retourne un iterator qui permet
+ * d'avance aussi bien dans la liste si celle-ci ne contient pas de Map ou dans
+ * les valeurs des Map si la liste est constituee de Map.
+ * Il est alors possible de recupere la valeur courante, modifier la valeur
+ * courante ou recuperer une Key qui permettra de mettre a jour l'element
+ * plus tard. Cette Class est surtout utilise pour la methode
+ * {@link WikittyClient#castTo}
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class ListObjectOrMap implements List {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(ListObjectOrMap.class);
+
+ protected List list;
+
+ public ListObjectOrMap() {
+ this.list = new ArrayList();
+ }
+
+ public ListObjectOrMap(List list) {
+ this.list = list;
+ }
+
+ @Override
+ public String toString() {
+ return list.toString();
+ }
+
+ /**
+ * Ajoute une nouvelle map dans la liste avec les elements fournis en parametre
+ * @param key
+ * @param value
+ */
+ public void add(String key, Object value) {
+ Map map = new HashMap();
+ map.put(key, value);
+ add(map);
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public ListObjectOrMapIterator iter() {
+ return new ListObjectOrMapIterator();
+ }
+
+ public interface Key {
+ public Object getValue();
+ public void setValue(Object v);
+ public void remove();
+ }
+
+ class KeyMap implements Key {
+ protected Map map;
+ protected Object key;
+
+ public KeyMap(Map map, Object key) {
+ this.map = map;
+ this.key = key;
+ }
+
+ @Override
+ public Object getValue() {
+ return map.get(key);
+ }
+
+ @Override
+ public void setValue(Object v) {
+ map.put(key, v);
+ }
+
+ @Override
+ public void remove() {
+ map.remove(key);
+ }
+ }
+
+ class KeyList implements Key {
+ protected List list;
+ protected int i;
+
+ public KeyList(List list, int i) {
+ this.list = list;
+ this.i = i;
+ }
+
+ @Override
+ public Object getValue() {
+ return list.get(i);
+ }
+
+ @Override
+ public void setValue(Object v) {
+ list.set(i, v);
+ }
+
+ @Override
+ public void remove() {
+ list.remove(i);
+ }
+
+ }
+
+ public class ListObjectOrMapIterator implements Iterator {
+ protected boolean isMap;
+
+ protected List list;
+ protected Object[] listEntry;
+ protected int listIndex;
+
+ protected Map map;
+ protected Map.Entry[] mapEntry;
+ protected int mapIndex;
+
+ protected Object next;
+ protected Key key;
+
+
+ public ListObjectOrMapIterator() {
+ list = ListObjectOrMap.this.list;
+ listEntry = list.toArray();
+ listIndex = 0;
+ }
+
+ @Override
+ public boolean hasNext() {
+ boolean result = false;
+ if (mapEntry != null && mapIndex < mapEntry.length) {
+ result = true;
+ } else {
+ while (!result && listIndex < listEntry.length) {
+ next = listEntry[listIndex++];
+ isMap = next instanceof Map;
+ if (isMap) {
+ map = (Map)next;
+ Set<Map.Entry> entry = map.entrySet();
+ if (!entry.isEmpty()) {
+ mapEntry = entry.toArray(new Map.Entry[entry.size()]);
+ mapIndex = 0;
+ result = true;
+ }
+ } else {
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public Object next() {
+ if (isMap) {
+ Map.Entry e = mapEntry[mapIndex++];
+ key = new KeyMap(map, e.getKey());
+ return e.getValue();
+ } else {
+ key = new KeyList(list, listIndex-1);
+ return next;
+ }
+ }
+
+ public Key nextKey() {
+ next();
+ return key;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public void setValue(Object v) {
+ key.setValue(v);
+ }
+
+ @Override
+ public void remove() {
+ key.remove();
+ }
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return list.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return list.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return list.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return list.toArray();
+ }
+
+ @Override
+ public Object[] toArray(Object[] a) {
+ return list.toArray(a);
+ }
+
+ @Override
+ public boolean add(Object e) {
+ return list.add(e);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return list.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection c) {
+ return list.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection c) {
+ return list.addAll(c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection c) {
+ return list.addAll(index, c);
+ }
+
+ @Override
+ public boolean removeAll(Collection c) {
+ return list.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection c) {
+ return list.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ list.clear();
+ }
+
+ @Override
+ public Object get(int index) {
+ return list.get(index);
+ }
+
+ @Override
+ public Object set(int index, Object element) {
+ return list.set(index, element);
+ }
+
+ @Override
+ public void add(int index, Object element) {
+ list.add(index, element);
+ }
+
+ @Override
+ public Object remove(int index) {
+ return list.remove(index);
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return list.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return list.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ return list.listIterator();
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return list.listIterator(index);
+ }
+
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ return list.subList(fromIndex, toIndex);
+ }
+
+}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -264,7 +264,7 @@
} else if (current instanceof FunctionFusion) {
current.addArgs(root);
} else {
- FunctionFusion fusion = new FunctionFusion(root);
+ FunctionFusion fusion = new FunctionFusion(select.getFunction(), root);
select.setFunction(fusion);
}
}
@@ -284,89 +284,164 @@
///////////////////////////////////////////////////////////////////////////
public M fieldValue(String fieldName) {
- FunctionFieldValue f = new FunctionFieldValue(null, fieldName);
- addFunction(f);
- return close();
+ return fieldValue(fieldName, null);
}
public M fieldValue(Element fieldName) {
+ return fieldValue(fieldName.getValue(), null);
+ }
+
+ public M fieldValue(Element fieldName, String alias) {
return fieldValue(fieldName.getValue());
}
+
+ public M fieldValue(String fieldName, String alias) {
+ FunctionFieldValue f = new FunctionFieldValue(alias, fieldName);
+ addFunction(f);
+ return close();
+ }
+
public M avg() {
- FunctionAvg f = new FunctionAvg(null);
- return addFunction(f);
+ return avg((String)null, null);
}
public M avg(String field) {
- FunctionAvg f = new FunctionAvg(null, new FunctionFieldValue(null, field));
- addFunction(f);
- return close();
+ return avg(field, null);
}
public M avg(Element field) {
- return avg(field.getValue());
+ return avg(field.getValue(), null);
}
+ public M avg(Element field, String alias) {
+ return avg(field.getValue(), alias);
+ }
+
+ public M avg(String field, String alias) {
+ if (field == null) {
+ FunctionAvg f = new FunctionAvg(alias);
+ addFunction(f);
+ } else {
+ FunctionAvg f = new FunctionAvg(alias, new FunctionFieldValue(null, field));
+ addFunction(f);
+ close();
+ }
+ return this.asM();
+ }
+
public M count() {
- FunctionCount f = new FunctionCount(null);
- return addFunction(f);
+ return count((String)null, null);
}
public M count(String field) {
- FunctionCount f = new FunctionCount(null, new FunctionFieldValue(null, field));
- addFunction(f);
- return close();
+ return count(field, null);
}
public M count(Element field) {
- return count(field.getValue());
+ return count(field.getValue(), null);
}
+ public M count(Element field, String alias) {
+ return count(field.getValue(), alias);
+ }
+
+ public M count(String field, String alias) {
+ if (field == null) {
+ FunctionCount f = new FunctionCount(alias);
+ addFunction(f);
+ } else {
+ FunctionCount f = new FunctionCount(alias, new FunctionFieldValue(null, field));
+ addFunction(f);
+ close();
+ }
+ return this.asM();
+ }
+
public M max() {
- FunctionMax f = new FunctionMax(null);
- return addFunction(f);
+ return max((String)null, null);
}
public M max(String field) {
- FunctionMax f = new FunctionMax(null, new FunctionFieldValue(null, field));
- addFunction(f);
- return close();
+ return max(field, null);
}
public M max(Element field) {
- return max(field.getValue());
+ return max(field.getValue(), null);
}
+ public M max(Element field, String alias) {
+ return max(field.getValue(), alias);
+ }
+
+ public M max(String field, String alias) {
+ if (field == null) {
+ FunctionMax f = new FunctionMax(alias);
+ addFunction(f);
+ } else {
+ FunctionMax f = new FunctionMax(alias, new FunctionFieldValue(null, field));
+ addFunction(f);
+ close();
+ }
+ return this.asM();
+ }
+
public M min() {
- FunctionMin f = new FunctionMin(null);
- return addFunction(f);
+ return min((String)null, null);
}
public M min(String field) {
- FunctionMin f = new FunctionMin(null, new FunctionFieldValue(null, field));
- addFunction(f);
- return close();
+ return min(field, null);
}
public M min(Element field) {
- return min(field.getValue());
+ return min(field.getValue(), null);
}
+ public M min(Element field, String alias) {
+ return min(field.getValue(), alias);
+ }
+
+ public M min(String field, String alias) {
+ if (field == null) {
+ FunctionMin f = new FunctionMin(alias);
+ addFunction(f);
+ } else {
+ FunctionMin f = new FunctionMin(alias, new FunctionFieldValue(null, field));
+ addFunction(f);
+ close();
+ }
+ return this.asM();
+
+ }
+
public M sum() {
- FunctionSum f = new FunctionSum(null);
- return addFunction(f);
+ return sum((String)null, null);
}
public M sum(String field) {
- FunctionSum f = new FunctionSum(null, new FunctionFieldValue(null, field));
- addFunction(f);
- return close();
+ return sum(field, null);
}
public M sum(Element field) {
- return sum(field.getValue());
+ return sum(field.getValue(), null);
}
+ public M sum(Element field, String alias) {
+ return sum(field.getValue(), alias);
+ }
+
+ public M sum(String field, String alias) {
+ if (field == null) {
+ FunctionSum f = new FunctionSum(alias);
+ addFunction(f);
+ } else {
+ FunctionSum f = new FunctionSum(alias, new FunctionFieldValue(null, field));
+ addFunction(f);
+ close();
+ }
+ return this.asM();
+ }
+
/**
* You need to close this distinct
* @return
@@ -424,7 +499,26 @@
* package.class#method. Il faut ensuite ajouter des arguments a la methode
*/
public M function(String method, Object ... args) {
- WikittyQueryFunctionWrapper f = new WikittyQueryFunctionWrapper(method, null);
+ return function(method, null, args);
+ }
+
+ /**
+ * ajoute une methode definit par l'utilisateur, la syntaxe de methode est
+ * [package.class]#method. Il faut ensuite ajouter des arguments a la methode
+ *
+ * @param method la methode utilisee comme fonction, si l'argument commence
+ * par #, le nom de la classe courante lui est ajoute. Cela permet de creer
+ * une sous classe a WikittyQueryMakerAbstract pour son projet et d'y mettre
+ * l'ensemble des fonctions que l'on utilise dans son projet.
+ * @param alias l'alias assigne au resultat
+ * @param args les parametre de la fonction, si vide, il faut alors explicitement
+ * appeler {@link #close} pour fermer la definition de cette fonction.
+ */
+ public M function(String method, String alias, Object ... args) {
+ if (StringUtils.startsWith(method, "#")) {
+ method = this.getClass().getSimpleName() + method;
+ }
+ WikittyQueryFunctionWrapper f = new WikittyQueryFunctionWrapper(method, alias);
boolean mustClose = false;
if (args != null && args.length > 0) {
mustClose = true;
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -25,6 +25,7 @@
package org.nuiton.wikitty.query;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -74,9 +75,16 @@
protected WikittyQueryMaker queryMaker;
protected List<WikittyQueryFunction> functions = new ArrayList<WikittyQueryFunction>();
- protected List<WikittyQueryFunction> getAndClearFunction() {
- List<WikittyQueryFunction> result = functions;
- functions = new ArrayList<WikittyQueryFunction>();
+ /**
+ * Prend le nombre d'arg passe en parametre et les supprime de la list
+ * @param size le nombre de parametre a prendre
+ * @return
+ */
+ protected List<WikittyQueryFunction> getAndClearFunction(int size) {
+ int last = functions.size();
+ List<WikittyQueryFunction> tmp = functions.subList(last-size, last);
+ List<WikittyQueryFunction> result = new ArrayList<WikittyQueryFunction>(tmp);
+ tmp.clear();
return result;
}
protected void addFunction(WikittyQueryFunction f) {
@@ -173,17 +181,18 @@
@Override
public boolean visitMiddle(Select o) {
- List<WikittyQueryFunction> fs = getAndClearFunction();
-
- WikittyQueryFunction f;
- if (fs.isEmpty()) {
- throw new IllegalStateException("Select must have WikittyQueryFunction");
- } else if (fs.size() > 1) {
+ WikittyQueryFunction f = null;
+ if (o.getFunction() != null) {
+ List<WikittyQueryFunction> fs = getAndClearFunction(1);
+ // normalement il ne devrait rester qu'une element dans functions et on
+ // vient de le prendre, si ce n'est pas le cas, c'est un probleme
+ if (!functions.isEmpty()) {
+ throw new IllegalStateException("function list must be empty here");
+ }
f = fs.get(0);
- } else {
- f = new FunctionFusion(fs);
}
getQueryMaker().select(f);
+ getQueryMaker().where();
return true;
}
@@ -395,7 +404,7 @@
@Override
public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult) {
- List<WikittyQueryFunction> args = getAndClearFunction();
+ List<WikittyQueryFunction> args = getAndClearFunction(function.getArgs().size());
WikittyQueryFunction f = WikittyQueryFunction.create(function.getMethodName(), function.getName(), args);
addFunction(f);
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -8,6 +8,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyUtil;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -78,8 +79,9 @@
}
BigDecimal avg = total.divide(new BigDecimal(cpt));
- Map<String, Object> val = Collections.singletonMap(getName(), (Object)avg);
- List<Map<String, Object>> result = Collections.singletonList(val);
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), avg);
+
return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -6,6 +6,7 @@
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -72,8 +73,9 @@
}
}
- Map<String, Object> val = Collections.singletonMap(getName(), (Object)cpt);
- List<Map<String, Object>> result = Collections.singletonList(val);
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), cpt);
+
return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -10,6 +10,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.entities.Element;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -57,16 +58,17 @@
String field = getUniqueValue(fieldName).toString();
- List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(data.size());
+ ListObjectOrMap result = new ListObjectOrMap();
+
for (Map<String, Object> m : data) {
if (m.containsKey(field)) {
Object val = m.get(field);
if (val instanceof Collection) {
for (Object o : (Collection)val) {
- result.add(Collections.singletonMap(field, o));
+ result.add(field, o);
}
} else {
- result.add(Collections.singletonMap(field, val));
+ result.add(field, val);
}
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -7,6 +7,7 @@
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.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -41,13 +42,18 @@
WikittySearchEngine searchEngine, WikittyTransaction tx,
WikittyQuery query, List<Map<String, Object>> data) {
- List<List<Map<String, Object>>> all = new ArrayList<List<Map<String, Object>>>();
- for (WikittyQueryFunction f : getArgs()) {
- all.add(f.call(searchEngine, tx, query, data));
+ try {
+ List<List<Map<String, Object>>> all = new ArrayList<List<Map<String, Object>>>();
+ for (WikittyQueryFunction f : getArgs()) {
+ all.add(f.call(searchEngine, tx, query, data));
+ }
+
+ List<Map<String, Object>> result = fusion(all);
+ return result;
+ } catch (Exception eee) {
+ throw new WikittyException(String.format(
+ "Can't evaluate function %s", this), eee);
}
-
- List<Map<String, Object>> result = fusion(all);
- return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -6,6 +6,7 @@
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -71,8 +72,8 @@
}
}
- List<Map<String, Object>> result = Collections.singletonList(
- Collections.singletonMap(getName(), (Object)candidate));
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), candidate);
return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -6,6 +6,7 @@
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -71,8 +72,8 @@
}
}
- List<Map<String, Object>> result = Collections.singletonList(
- Collections.singletonMap(getName(), (Object)candidate));
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), candidate);
return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -8,6 +8,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyUtil;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -73,8 +74,9 @@
}
}
}
- Map<String, Object> val = Collections.singletonMap(getName(), (Object)total);
- List<Map<String, Object>> result = Collections.singletonList(val);
+
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), total);
return result;
}
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -7,6 +7,7 @@
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.ListObjectOrMap;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryVisitor;
import org.nuiton.wikitty.services.WikittyTransaction;
@@ -46,8 +47,8 @@
public List<Map<String, Object>> call(
WikittySearchEngine searchEngine, WikittyTransaction tx,
WikittyQuery query, List<Map<String, Object>> data) {
- List<Map<String, Object>> result =
- Collections.singletonList(Collections.singletonMap(getName(), value));
+ ListObjectOrMap result = new ListObjectOrMap();
+ result.add(getName(), getValue());
return result;
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -15,6 +15,7 @@
import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryVisitor;
+import org.nuiton.wikitty.query.WikittyQueryVisitorToString;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -186,6 +187,16 @@
WikittySearchEngine searchEngine, WikittyTransaction tx,
WikittyQuery query, List<Map<String, Object>> data);
+ @Override
+ public String toString() {
+ WikittyQueryVisitorToString v = new WikittyQueryVisitorToString();
+ accept(v);
+ String result = v.getText();
+ return result;
+ }
+
+
+
protected List<Map<String, Object>> fusion(List<List<Map<String, Object>>> listData) {
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
// check size, all list must have same size
@@ -195,7 +206,9 @@
size = e.size();
} else {
if (size != e.size()) {
- throw new IllegalArgumentException("Each list must have same size");
+ throw new IllegalArgumentException(String.format(
+ "Each list must have same size %s != %s (%s)",
+ size, e.size(), listData));
}
}
}
@@ -262,14 +275,17 @@
* @return
*/
protected Method getMethod(String fqMethod) {
- List<Method> methods = ObjectUtil.getMethod(name, true);
+ List<Method> methods = ObjectUtil.getMethod(fqMethod, true);
- Method result = null;
- if (methods.size() > 0) {
+ Method result;
+ if (methods.isEmpty()) {
+ throw new IllegalArgumentException(String.format(
+ "Can't find method '%s'", fqMethod));
+ } else {
if (methods.size() > 1) {
log.warn(String.format(
- "More than one method found, used the first: %s",
- methods));
+ "More than one method found for '%s', used the first: %s",
+ fqMethod, methods));
}
result = methods.get(0);
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -1,15 +1,18 @@
package org.nuiton.wikitty.query.function;
-
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Date;
+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.util.ObjectUtil;
+import org.nuiton.wikitty.WikittyException;
+import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittySearchEngine;
@@ -41,13 +44,13 @@
WikittySearchEngine searchEngine, WikittyTransaction tx,
WikittyQuery query, List<Map<String, Object>> data) {
List<List<Map<String, Object>>> param = new ArrayList<List<Map<String, Object>>>();
-
+
+ // on evalue les parametres que l'on passera a la fonction
for (WikittyQueryFunction f : getArgs()) {
param.add(f.call(searchEngine, tx, query, data));
}
- data = fusion(param);
-
+ // on recherche la fonction et on instancie si besoin un objet pour l'executer
Method method = getMethod(methodName);
Object target = null;
if (!Modifier.isStatic(method.getModifiers())) {
@@ -61,22 +64,134 @@
}
}
- for (Map<String, Object> o : data) {
- String[] args = new String[o.size()];
- int i=0;
- for (Object v : o.values()) {
- args[i++] = String.valueOf(v);
+ // on initialise tous les iterateurs qui fourniront les parametres
+ List<Iterator<Map<String, Object>>> paramIterator = new ArrayList<Iterator<Map<String, Object>>>();
+ for(List<Map<String, Object>> l : param) {
+ paramIterator.add(l.iterator());
+ }
+
+ List<Map<String, Object>> resultListMap = new ArrayList<Map<String, Object>>();
+ List<Map<String, Object>> p = null;
+ while (hasNext(paramIterator)) {
+ // on recupere dans p les parametre a utiliser pour le prochain appel
+ p = next(paramIterator, p);
+ // on appelle la fonction
+ Object result = invoke(target, method, p);
+ // si le retour n'est pas une map, on le transforme en map
+ if (!(result instanceof Map)) {
+ result = WikittyUtil.singletonMap(getName(), result);
}
- try {
- Object r = ObjectUtil.call(target, method, args);
- } catch (Exception eee) {
- throw new IllegalStateException(String.format(
- "Can't call function '%s'",
- methodName), eee);
+ resultListMap.add((Map)result);
+ }
+
+ return resultListMap;
+ }
+
+ /**
+ * Il y a un suivant tant qu'un des iterators a un suivant
+ *
+ * @param paramIterator
+ * @return
+ */
+ protected boolean hasNext(List<Iterator<Map<String, Object>>> paramIterator) {
+ boolean result = false;
+ for (Iterator i : paramIterator) {
+ result = result || i.hasNext();
+ }
+ return result;
+ }
+
+ /**
+ * Retourne le suivant de chaque iterator, si un iterator n'a plus de suivant,
+ * on reutilise l'ancien resultat
+ * @param paramIterator
+ * @return
+ */
+ protected List<Map<String, Object>> next(List<Iterator<Map<String, Object>>> paramIterator,
+ List<Map<String, Object>> last) {
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
+
+ int cpt=0;
+ for (Iterator<Map<String, Object>> i : paramIterator) {
+ if(i.hasNext()) {
+ result.add(i.next());
+ } else {
+ if (last != null) {
+ result.add(last.get(cpt));
+ } else {
+ result.add(null);
+ }
}
+ cpt++;
}
- return data;
+
+ return result;
}
+ /**
+ *
+ * @param target l'objet sur lequel appeler la methode
+ * @param method la methode a appeler
+ * @param p les arguments a convertir le mieux possible pour pouvoir appeler la methode
+ * @return
+ */
+ protected Object invoke(Object target, Method method, List<Map<String, Object>> p) {
+ Class[] pClass = method.getParameterTypes();
+ Object[] param = new Object[pClass.length];
+ int cpt = 0;
+ for (Class c : pClass) {
+ Object value;
+ if (Map.class.isAssignableFrom(c)) {
+ value = p.get(cpt);
+ } else if (Number.class.isAssignableFrom(c)
+ || Byte.TYPE.isAssignableFrom(c)
+ || Short.TYPE.isAssignableFrom(c)
+ || Integer.TYPE.isAssignableFrom(c)
+ || Long.TYPE.isAssignableFrom(c)
+ || Float.TYPE.isAssignableFrom(c)
+ || Double.TYPE.isAssignableFrom(c)) {
+ value = WikittyUtil.toNumber(c, WikittyUtil.toBigDecimal(takeValue(p.get(cpt))));
+ } else if (Date.class.isAssignableFrom(c)) {
+ value = WikittyUtil.toDate(takeValue(p.get(cpt)));
+ } else if (Boolean.TYPE.isAssignableFrom(c) || Boolean.class.isAssignableFrom(c)) {
+ value = WikittyUtil.toBoolean(takeValue(p.get(cpt)));
+ } else if (byte[].class.isAssignableFrom(c)) {
+ value = WikittyUtil.toBinary(takeValue(p.get(cpt)));
+ } else if (String.class.isAssignableFrom(c)) {
+ value = WikittyUtil.toString(takeValue(p.get(cpt)));
+ }else {
+ throw new ClassCastException(String.format(
+ "Object '%s' is not convertible to '%s'"
+ + " (accepted Number, String, Date,"
+ + " Boolean, byte[], Map)",
+ p.get(cpt), c.getName()));
+ }
+ param[cpt] = value;
+ cpt++;
+ }
+
+ try {
+ Object result = method.invoke(target, param);
+ return result;
+ } catch (Exception eee) {
+ throw new WikittyException(String.format(
+ "Can't execute function (method: '%s' args:'%s')",
+ method, Arrays.toString(param)), eee);
+ }
+ }
+
+ /**
+ * Prend la valeur de la map, la map ne doit contenir qu'une valeur
+ * @param map
+ * @return null si la map est vide
+ */
+ protected Object takeValue(Map<String, Object> map) {
+ if (map != null) {
+ for(Object v : map.values()) {
+ return v;
+ }
+ }
+ return null;
+ }
}
Deleted: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -1,239 +0,0 @@
-/*
- * #%L
- * Wikitty :: api
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2012 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.storage;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-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.WikittyUtil;
-import org.nuiton.wikitty.entities.Element;
-import org.nuiton.wikitty.entities.WikittyExtension;
-import org.nuiton.wikitty.query.function.WikittyQueryFunction;
-import org.nuiton.wikitty.query.FacetSortType;
-import org.nuiton.wikitty.query.FacetTopic;
-import org.nuiton.wikitty.query.WikittyQuery;
-import org.nuiton.wikitty.query.WikittyQueryMaker;
-import org.nuiton.wikitty.query.WikittyQueryResult;
-import org.nuiton.wikitty.query.conditions.Condition;
-import org.nuiton.wikitty.query.conditions.Select;
-import org.nuiton.wikitty.services.WikittyTransaction;
-
-/**
- * Ensemble de methode reutilisable dans differente implantation de
- * {@link WikittySearchEngine}
- *
- * @author poussin
- * @version $Revision$
- *
- * Last update: $Date$
- * by : $Author$
- */
-public class WikittySearchEngineHelper {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- static private Log log = LogFactory.getLog(WikittySearchEngineHelper.class);
-
-// /**
-// * Gere le travail pour les requetes ayant un {@link Select}
-// *
-// * @param searchEngine le searchEngine a utiliser pour les sous requetes
-// * @param transaction la transaction a utiliser
-// * @param query la requete qui debute par un {@link Select}
-// * @return
-// */
-// static public WikittyQueryResult<String> findAllByQueryWithSelectOLD(
-// WikittySearchEngine searchEngine, WikittyTransaction transaction,
-// WikittyQuery query) {
-//
-// if (!(query.getCondition() instanceof Select)) {
-// throw new WikittyException("Query don't start with Select condition");
-// } else {
-// // gere les conditions qui commence par select
-// // il faut recreer deux query, une pour le select, une pour les facettes s'il y en a
-// // car le select est execute via une facette, mais cette facette
-// // n'a pas les meme limites que les autres facette
-//
-// Select select = (Select)query.getCondition();
-// boolean isAggregate = select.getAggregate() != null;
-// boolean isDistinct = select.isDistinct();
-//
-// Condition newCond;
-// if(WikittyExtension.isFqField(select.getElement().getValue())) {
-// String extName = WikittyExtension.extractExtensionName(
-// select.getElement().getValue());
-// newCond = new WikittyQueryMaker()
-// .and()
-// .exteq(extName)
-// .condition(select.getSubCondition())
-// .getCondition();
-// } else {
-// newCond = select.getSubCondition();
-// }
-//
-// // copy de la query pour les facettes
-// WikittyQuery queryFacet = query.copy();
-// queryFacet.setCondition(newCond);
-// queryFacet.setLimit(0);
-//
-// // copy de la query pour le select
-// // on part de facet qui a deja la bonne condition
-// WikittyQuery querySelect = queryFacet.copy();
-// querySelect.setLimit(0);
-// // ne surtout pas mettre 0, sinon toutes les valeurs possibles sont
-// // retournee pas seulement celle qui satisfont la contrainte
-// querySelect.setFacetMinCount(1);
-// querySelect.setFacetLimit(Integer.MAX_VALUE);
-// // on force le sort pour toujours utiliser le meme
-// querySelect.setFacetSort(FacetSortType.name);
-// // on supprime toutes les facettes, et on ajoute la notre
-// querySelect.setFacetQuery();
-// querySelect.setFacetField(select.getElement());
-//
-// // execution des requetes
-// WikittyQueryResult<String> resultFacet =
-// searchEngine.findAllByQuery(transaction, queryFacet);
-// WikittyQueryResult<String> resultSelect =
-// searchEngine.findAllByQuery(transaction, querySelect);
-//
-// // creation des resultats via la facette select
-// List<FacetTopic> topics = resultSelect.getFacets().get(select.getElement().getValue());
-//
-// List<String> selectList = new ArrayList<String>(topics.size());
-// for (FacetTopic topic : topics) {
-// if (isDistinct) {
-// selectList.add(topic.getTopicName());
-// } else {
-// // on ajoute la valeur le nombre de fois qu'il y a de count dans la facette
-// for (int i=0, max=topic.getCount(); i<max; i++) {
-// selectList.add(topic.getTopicName());
-// }
-// }
-// }
-//
-// boolean sortDesc = query.getSortDescending().contains(select.getElement());
-// // tri selon l'ordre demande
-// if (sortDesc) {
-// // par defaut la facette est deja trie par ordre alphabetique
-// // donc il n'y a qu'a l'inverser pour avoir l'ordre inverse
-// Collections.reverse(selectList);
-// }
-//
-// // on ne garde que ce qui est demande
-// int offset = query.getOffset();
-// int limit = query.getLimit();
-// if (limit == Integer.MAX_VALUE) {
-// // WARNING It is necessary to substract 'offset' otherwise,
-// // there is a capacity overlow
-// limit = Integer.MAX_VALUE - offset;
-// }
-// int first = Math.min(selectList.size(), offset);
-// int last = Math.min(selectList.size(), offset + limit);
-// selectList = selectList.subList(first, last);
-//
-//
-//
-// // gestion des agregats
-// if (isAggregate) {
-// switch(select.getAggregate()) {
-// case AVG: {
-// // convert all to number
-// BigDecimal result = new BigDecimal(0);
-// for (String s : selectList) {
-// BigDecimal v = WikittyUtil.toBigDecimal(s);
-// result = result.add(v);
-// }
-// result = result.divide(new BigDecimal(selectList.size()));
-// selectList = new ArrayList<String>();
-// selectList.add(WikittyUtil.toString(result));
-// }
-// break;
-// case COUNT: {
-// // convert all to number
-// BigDecimal result = new BigDecimal(selectList.size());
-// selectList = new ArrayList<String>();
-// selectList.add(WikittyUtil.toString(result));
-// }
-// break;
-// case MAX: {
-// if (!selectList.isEmpty()) {
-// String result;
-// if (sortDesc) {
-// result = selectList.get(0);
-// } else {
-// result = selectList.get(selectList.size()-1);
-// }
-// selectList = new ArrayList<String>();
-// selectList.add(WikittyUtil.toString(result));
-// }
-// }
-// break;
-// case MIN: {
-// if (!selectList.isEmpty()) {
-// String result;
-// if (sortDesc) {
-// result = selectList.get(selectList.size()-1);
-// } else {
-// result = selectList.get(0);
-// }
-// selectList = new ArrayList<String>();
-// selectList.add(WikittyUtil.toString(result));
-// }
-// }
-// break;
-// case SUM: {
-// // convert all to number
-// BigDecimal result = new BigDecimal(0);
-// for (String s : selectList) {
-// BigDecimal v = WikittyUtil.toBigDecimal(s);
-// result = result.add(v);
-// }
-// selectList = new ArrayList<String>();
-// selectList.add(WikittyUtil.toString(result));
-// }
-// break;
-// }
-// }
-//
-// // fusion des resultats
-// WikittyQueryResult<String> result = new WikittyQueryResult<String>(
-// query.getName(),
-// query.getOffset(),
-// topics.size(),
-// resultSelect.getQueryString(),
-// resultFacet.getFacets(),
-// selectList,
-// 0, 0);
-//
-// return result;
-// }
-// }
-
-}
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 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -26,7 +26,6 @@
import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultiset;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -374,7 +373,7 @@
if (select == null) {
String idTag = org.nuiton.wikitty.entities.Element.ID.getValue();
for (Object id : ids) {
- values.add(Collections.singletonMap(idTag, id));
+ values.add(WikittyUtil.singletonMap(idTag, id));
}
} else {
// Extract data
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2013-02-20 11:31:06 UTC (rev 1530)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2013-02-21 14:28:35 UTC (rev 1531)
@@ -26,10 +26,8 @@
package org.nuiton.wikitty.storage.solr;
import java.io.File;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -76,7 +74,6 @@
import org.nuiton.wikitty.services.WikittyTransaction;
import org.nuiton.wikitty.storage.WikittyExtensionStorage;
import org.nuiton.wikitty.storage.WikittySearchEngine;
-import org.nuiton.wikitty.storage.WikittySearchEngineHelper;
/**
*
@@ -813,7 +810,7 @@
String idTag = org.nuiton.wikitty.entities.Element.ID.getValue();
for (SolrDocument doc : solrResults) {
Object id = SolrUtil.getStringFieldValue(doc, SOLR_ID);
- values.add(Collections.singletonMap(idTag, id));
+ values.add(WikittyUtil.singletonMap(idTag, id));
}
} else {
// Extract data
@@ -838,158 +835,6 @@
}
}
- // TODO Remove it
-// @Override
-// public WikittyQueryResult<String> findAllByQueryOLD(WikittyTransaction transaction, WikittyQuery query) {
-// try {
-// WikittyQueryResult<String> result;
-//
-// if (query.getCondition() instanceof Select) {
-// result = WikittySearchEngineHelper.findAllByQueryWithSelect(
-// this, transaction, query);
-// } else {
-//
-// // Create querySolr
-// WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr(
-// transaction, this, elementModifier, query.getWikittyFieldSearchDepth());
-// query.getCondition().accept(v);
-// String queryString = v.getSolrQuery();
-// SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString);
-//
-// // Add paged
-// int offset = query.getOffset();
-// int limit = query.getLimit();
-//
-// if (limit == Integer.MAX_VALUE) {
-// // WARNING It is necessary to substract 'start' otherwise,
-// // there is a capacity overlow in solR
-// limit = Integer.MAX_VALUE - offset;
-// }
-// querySolr.setStart(offset);
-// querySolr.setRows(limit);
-//
-// // Add sorting
-// List<Element> sortAscending = query.getSortAscending();
-// if(sortAscending != null) {
-// for (Element sort : sortAscending) {
-// String tranform = elementModifier.convertToSolr(transaction, sort);
-// tranform += WikittySolrConstant.SUFFIX_SORTABLE;
-// querySolr.addSortField(tranform, SolrQuery.ORDER.asc);
-// }
-// }
-//
-// List<Element> sortDescending = query.getSortDescending();
-// if(sortDescending != null) {
-// for (Element sort : sortDescending) {
-// String tranform = elementModifier.convertToSolr(transaction, sort);
-// tranform += WikittySolrConstant.SUFFIX_SORTABLE;
-// querySolr.addSortField(tranform, SolrQuery.ORDER.desc);
-// }
-// }
-//
-// // Add faceting
-// boolean isFacetExtension = query.isFacetExtension();
-// List<Element> facetField = query.getFacetField();
-// List<FacetQuery> facetQuery = query.getFacetQuery();
-//
-// // use to map query string to criteria facet name
-// Map<String, String> facetQueryToName = new HashMap<String, String>();
-//
-// if (isFacetExtension
-// || CollectionUtils.isNotEmpty(facetField)
-// || CollectionUtils.isNotEmpty(facetQuery)) {
-// querySolr.setFacet(true);
-// querySolr.setFacetMinCount(query.getFacetMinCount());
-// querySolr.setFacetLimit(query.getFacetLimit());
-// querySolr.setFacetSort(query.getFacetSort().solrValue);
-//
-// if (isFacetExtension) {
-// querySolr.addFacetField(WikittySolrConstant.SOLR_EXTENSIONS);
-// }
-//
-// // field facetisation
-// if (facetField != null) {
-// for (Element fqfieldName : facetField) {
-// String tranform = elementModifier.convertToSolr(transaction, fqfieldName);
-// querySolr.addFacetField(tranform);
-// }
-// }
-//
-// // query facetisation
-// if (facetQuery != null) {
-// for (FacetQuery facet : facetQuery) {
-// v = new WikittyQueryVisitorToSolr(
-// transaction, this, elementModifier, 0); // pas de recherche recursive sur les champs wikitty pour les facettes
-// facet.getCondition().accept(v);
-// String queryFacet = v.getSolrQuery();
-// facetQueryToName.put(queryFacet, facet.getName());
-// querySolr.addFacetQuery(queryFacet);
-// }
-// }
-// }
-//
-// QueryResponse resp = SolrUtil.executeQuery(solrServer, querySolr);
-// SolrDocumentList solrResults = resp.getResults();
-//
-// Map<String, List<FacetTopic>> facets = new HashMap<String, List<FacetTopic>>();
-//
-// // la facet sur les extensions est directement et convenablement
-// // gere comme un champs
-// if (isFacetExtension || CollectionUtils.isNotEmpty(facetField)) {
-// for (FacetField facet : resp.getFacetFields()) {
-// String facetName = elementModifier.convertToField(facet.getName());
-// List<FacetTopic> topics = new ArrayList<FacetTopic>();
-// if (facet.getValues() != null) {
-// for (FacetField.Count value : facet.getValues()) {
-// String topicName = value.getName();
-// int topicCount = (int) value.getCount();
-// FacetTopic topic = new FacetTopic(facetName, topicName, topicCount);
-// topics.add(topic);
-// }
-// }
-// facets.put(facetName, topics);
-// }
-// }
-//
-// if (CollectionUtils.isNotEmpty(facetQuery)) {
-// for (Map.Entry<String, Integer> facet : resp.getFacetQuery().entrySet()) {
-// String facetName = facet.getKey();
-// // don't use contains because, map can have key with null value
-// if (null != facetQueryToName.get(facetName)) {
-// facetName = facetQueryToName.get(facetName);
-// }
-// Integer count = facet.getValue();
-// List<FacetTopic> topics = new ArrayList<FacetTopic>();
-// FacetTopic topic = new FacetTopic(facetName, facetName, count);
-// topics.add(topic);
-// facets.put(facetName, topics);
-// }
-// }
-//
-// // Extract ids
-// List<String> ids = new ArrayList<String>(solrResults.size());
-// for (SolrDocument doc : solrResults) {
-//
-// String id = SolrUtil.getStringFieldValue(doc, SOLR_ID);
-// ids.add(id);
-// }
-//
-// // Get total num found
-// int numFound = (int)resp.getResults().getNumFound();
-//
-// // Build paged result
-// result = new WikittyQueryResult<String>(
-// query.getName(),
-// offset, numFound, queryString, facets, ids, 0, 0);
-//
-// }
-// return result;
-// } catch (SolrServerException eee) {
-// throw new WikittyException(String.format(
-// "Error during find of query '%s'", query), eee);
-// }
-// }
-
/**
* Si l'argument n'est pas un TreeNode, une exception est levee
*
1
0
Author: bpoussin
Date: 2013-02-20 12:31:06 +0100 (Wed, 20 Feb 2013)
New Revision: 1530
Url: http://nuiton.org/projects/wikitty/repository/revisions/1530
Log:
fixes #2533: Make select clause more useful: return more than one value, use user function, ...
Added:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionDistinct.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java
Modified:
trunk/pom.xml
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.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/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/Select.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittySecurityHelper.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAccessStat.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthentication.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationAbstract.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationLDAP.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.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/WikittySearchEngineHelper.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java
trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java
trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java
trunk/wikitty-api/src/test/java/org/nuiton/wikitty/services/WikittyServiceHelperTest.java
trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/ElementModifier.java
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java
trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/pom.xml 2013-02-20 11:31:06 UTC (rev 1530)
@@ -53,7 +53,7 @@
<!-- common versions used in sub-poms -->
<eugeneVersion>2.4.2</eugeneVersion>
- <nuitonUtilsVersion>2.4.4</nuitonUtilsVersion>
+ <nuitonUtilsVersion>2.6.9-SNAPSHOT</nuitonUtilsVersion>
<nuitonI18nVersion>2.4.1</nuitonI18nVersion>
<processPluginVersion>1.1</processPluginVersion>
<jettyVersion>7.4.2.v20110526</jettyVersion>
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -683,12 +683,12 @@
long start = TimeLog.getTime();
WikittyQuery query = new WikittyQueryMaker().wikitty(e).end()
- .setFirst(first).setLimit(limit)
+ .setOffset(first).setLimit(limit)
.setFacetField(fieldFacet);
- WikittyQueryResult<String> queryResult = findAllByQuery(query);
- WikittyQueryResult<E> result = (WikittyQueryResult<E>)castTo(
- e.getClass(), queryResult);
+ WikittyQueryResult<E> result =
+ findAllByQuery((Class<E>)e.getClass(),
+ Collections.singletonList(query), false).get(0);
timeLog.log(start, "findAllByExample<limit>");
return result;
@@ -704,8 +704,11 @@
long start = TimeLog.getTime();
WikittyQuery query = new WikittyQueryMaker().wikitty(e).end();
- String id = findByQuery(query);
- E result = (E)restore(e.getClass(), id);
+ WikittyQueryResult<E> queryResult =
+ findAllByQuery((Class<E>)e.getClass(),
+ Collections.singletonList(query), true).get(0);
+
+ E result = queryResult.peek();
timeLog.log(start, "findByExample");
return result;
@@ -728,7 +731,7 @@
*
* @param <E> object type
* Can be Wikitty, BusinessEntity, String, Date, Number (returned is BigDecimal), Boolean, byte[]
- * @param clazz entity class
+ * @param clazz entity class, can be null for no conversion
* @param queries criterias
* @param limitToFirst if true limit result to first result (first = 0, limit = 1)
* @return paged result
@@ -739,7 +742,7 @@
List<WikittyQueryResult<E>> result = null;
List<WikittyQuery> serviceQueries;
if (queries != null) {
- if (BusinessEntity.class.isAssignableFrom(clazz)) {
+ if (clazz != null && BusinessEntity.class.isAssignableFrom(clazz)) {
// on demande un business entity donc on modifie
// pas les criteres pour ajouter les contraintes sur les
// extensions
@@ -769,7 +772,7 @@
// alors il faut modifier la condition du select
Select select = (Select)serviceQuery.getCondition();
queryMaker = new WikittyQueryMaker()
- .select(select.getElement())
+ .select(select.getFunction())
.and().condition(select.getSubCondition())
.extContainsAll(extensions);
@@ -794,10 +797,11 @@
if (limitToFirst) {
for (WikittyQuery query : serviceQueries) {
- // si on a une fonction d'aggreagation (SUM, MIN, ...) il ne
- // faut pas modifier l'offset ni le limit
- if (!(query.getCondition() instanceof Select) ||
- ((Select)query.getCondition()).getAggregate() == null ) {
+ // FIXME, il faudrait faire des copies pour ne pas modifier les querys de l'utilisateur
+
+ // si on a un SELECT, il ne faut pas modifier l'offset ni le limit,
+ // car il peut y avoir des methods d'agregats qui ont besoin de toutes les donnees
+ if (!(query.getCondition() instanceof Select)) {
query.setOffset(0);
query.setLimit(1);
}
@@ -810,11 +814,11 @@
}
}
- List<WikittyQueryResult<String>> pagedResult =
- findAllByQuery(serviceQueries);
+ List<WikittyQueryResult<Map<String, Object>>> pagedResult =
+ findAllByQueryAsMap(serviceQueries);
result = new ArrayList<WikittyQueryResult<E>>(pagedResult.size());
- for (WikittyQueryResult<String> p : pagedResult) {
+ for (WikittyQueryResult<Map<String, Object>> p : pagedResult) {
result.add((WikittyQueryResult<E>)castTo(clazz, p));
}
}
@@ -950,8 +954,6 @@
* Retourne les ids des wikitties qui correspondent au critere, chaque
* query passees en argument et retourne un WikittyQueryResult.
*
- * Cette method est la seul a reellement faire un appel a findAllByQuery
- * du wikitty service.
*
* @param query
* @return
@@ -960,23 +962,49 @@
long start = TimeLog.getTime();
List<WikittyQueryResult<String>> result = null;
if (query != null) {
- result = wikittyService.findAllByQuery(securityToken, query);
+ result = findAllByQuery(String.class, query);
}
timeLog.log(start, "findAllByQuery(List)");
return result;
}
+ /**
+ * Cette method est la seul a reellement faire un appel a findAllByQuery
+ * du wikitty service.
+ *
+ * @param query
+ * @return
+ */
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQueryAsMap(List<WikittyQuery> query) {
+ long start = TimeLog.getTime();
+ List<WikittyQueryResult<Map<String, Object>>> result = null;
+ if (query != null) {
+ result = wikittyService.<Map<String, Object>>findAllByQuery(securityToken, query);
+ }
+ timeLog.log(start, "findAllByQuery(List)");
+ return result;
+ }
+
public WikittyQueryResult<String> findAllByQuery(WikittyQuery query) {
long start = TimeLog.getTime();
WikittyQueryResult<String> result = null;
if (query != null) {
- result = findAllByQuery(
- Collections.singletonList(query)).get(0);
+ result = findAllByQuery(Collections.singletonList(query)).get(0);
}
timeLog.log(start, "findAllByQuery(One)");
- return result;
+ return result;
}
+ public WikittyQueryResult<Map<String, Object>> findAllByQueryAsMap(WikittyQuery query) {
+ long start = TimeLog.getTime();
+ WikittyQueryResult<Map<String, Object>> result = null;
+ if (query != null) {
+ result = findAllByQueryAsMap(Collections.singletonList(query)).get(0);
+ }
+ timeLog.log(start, "findAllByQuery(One)");
+ return result;
+ }
+
public WikittyQueryResult<String>[] findAllByQuery(
WikittyQuery c1, WikittyQuery c2, WikittyQuery ... otherCriteria) {
long start = TimeLog.getTime();
@@ -989,9 +1017,24 @@
WikittyQueryResult<String>[] result = resultList.toArray(new WikittyQueryResult[criterias.size()]);
timeLog.log(start, "findAllByCriteria(Varargs)");
- return result;
+ return result;
}
+ public WikittyQueryResult<Map<String, Object>>[] findAllByQueryAsMap(
+ WikittyQuery c1, WikittyQuery c2, WikittyQuery ... otherCriteria) {
+ long start = TimeLog.getTime();
+
+ List<WikittyQuery> criterias = new ArrayList<WikittyQuery>(otherCriteria.length + 2);
+ Collections.addAll(criterias, c1, c2);
+ Collections.addAll(criterias, otherCriteria);
+
+ List<WikittyQueryResult<Map<String, Object>>> resultList = findAllByQueryAsMap(criterias);
+ WikittyQueryResult<Map<String, Object>>[] result = resultList.toArray(new WikittyQueryResult[criterias.size()]);
+
+ timeLog.log(start, "findAllByCriteria(Varargs)");
+ return result;
+ }
+
///////////////////////////////////////////////////////////////////////////
//
// FIND ID BY CRITERIA <String>
@@ -1002,12 +1045,38 @@
long start = TimeLog.getTime();
List<String> result = null;
if (query != null) {
- result = wikittyService.findByQuery(securityToken, query);
+ List<WikittyQueryResult<String>> tmp = findAllByQuery(String.class, query, true);
+ result = new ArrayList<String>(tmp.size());
+ for (WikittyQueryResult<String> wqr : tmp) {
+ if (wqr.size() == 0) {
+ result.add(null);
+ } else {
+ result.add(wqr.peek());
+ }
+ }
}
timeLog.log(start, "findByQuery(List)");
return result;
}
+ public List<Map<String, Object>> findByQueryAsMap(List<WikittyQuery> query) {
+ long start = TimeLog.getTime();
+ List<Map<String, Object>> result = null;
+ if (query != null) {
+ List<WikittyQueryResult<Map<String, Object>>> tmp = findAllByQuery(null, query, true);
+ result = new ArrayList<Map<String, Object>>(tmp.size());
+ for (WikittyQueryResult<Map<String, Object>> wqr : tmp) {
+ if (wqr.size() == 0) {
+ result.add(null);
+ } else {
+ result.add(wqr.peek());
+ }
+ }
+ }
+ timeLog.log(start, "findByQuery(List)");
+ return result;
+ }
+
public String findByQuery(WikittyQuery query) {
long start = TimeLog.getTime();
String result = null;
@@ -1018,6 +1087,16 @@
return result;
}
+ public Map<String, Object> findByQueryAsMap(WikittyQuery query) {
+ long start = TimeLog.getTime();
+ Map<String, Object> result = null;
+ if (query != null) {
+ result = findByQueryAsMap(Collections.singletonList(query)).get(0);
+ }
+ timeLog.log(start, "findByQuery(One)");
+ return result;
+ }
+
public String[] findByQuery(
WikittyQuery q1, WikittyQuery q2, WikittyQuery... otherQueries) {
long start = TimeLog.getTime();
@@ -1033,6 +1112,21 @@
return result;
}
+ public Map<String, Object>[] findByQueryAsMap(
+ WikittyQuery q1, WikittyQuery q2, WikittyQuery... otherQueries) {
+ long start = TimeLog.getTime();
+
+ List<WikittyQuery> queries = new ArrayList<WikittyQuery>(otherQueries.length + 2);
+ Collections.addAll(queries, q1, q2);
+ Collections.addAll(queries, otherQueries);
+
+ List<Map<String, Object>> resultList = findByQueryAsMap(queries);
+ Map<String, Object>[] result = resultList.toArray(new Map[queries.size()]);
+
+ timeLog.log(start, "findByQuery(Varargs)");
+ return result;
+ }
+
///////////////////////////////////////////////////////////////////////////
//
// FIND BY TREE NODE
@@ -1627,7 +1721,10 @@
if (objects == null) {
result = null;
- } else if (objects.size() == 0) {
+ } else if (target.isAssignableFrom(Object.class)) {
+ // on demande la conversion en Object, donc aucune conversion
+ result = new ArrayList<E>((List<E>)objects);
+ }else if (objects.size() == 0) {
// on ne fait rien on met juste une nouvelle liste vide
result = new ArrayList<E>();
} else if (Wikitty.class.isAssignableFrom(target)) {
@@ -1819,16 +1916,23 @@
*/
public <E> WikittyQueryResult<E> castTo(Class<E> target,
WikittyQueryResult queryResult) {
+ WikittyQueryResult<E> result;
- long startTime = System.nanoTime();
- List<E> castedResult = castTo(target, queryResult.getAll());
- long estimatedTime = System.nanoTime() - startTime;
+ if (target == null || Map.class.isAssignableFrom(target)) {
+ result = (WikittyQueryResult<E>)queryResult;
+ } else {
+ long startTime = System.nanoTime();
+ WikittyQueryResult queryResultFlated = queryResult.convertMapToSimple();
- WikittyQueryResult<E> result = new WikittyQueryResult<E>(
- queryResult.getQueryName(),
- queryResult.getOffset(), queryResult.getTotalResult(),
- queryResult.getQueryString(), queryResult.getFacets(),
- castedResult, queryResult.getTimeQuery(), estimatedTime);
+ List<E> castedResult = castTo(target, queryResultFlated.getAll());
+ long estimatedTime = System.nanoTime() - startTime;
+
+ result = new WikittyQueryResult<E>(
+ queryResult.getQueryName(),
+ queryResult.getOffset(), queryResult.getTotalResult(),
+ queryResult.getQueryString(), queryResult.getFacets(),
+ castedResult, queryResult.getTimeQuery(), estimatedTime);
+ }
return result;
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -26,14 +26,13 @@
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
-
-import static org.nuiton.i18n.I18n._;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.util.ApplicationConfig;
import org.nuiton.util.ArgumentsParserException;
+import static org.nuiton.i18n.I18n._;
+
/**
* Configuration de tous les modules Wikitty. La configuration par defaut doit
* permettre un bon fonctionnement de wikitty pour quelqu'un souhaitant faire un
@@ -96,18 +95,18 @@
static public ApplicationConfig getConfig(
Properties props, String configFilename, String ... args) {
- ApplicationConfig conf = new ApplicationConfig(
- WikittyConfigOption.class, WikittyConfigAction.class,
- props, configFilename);
+ ApplicationConfig config = new ApplicationConfig(props, configFilename);
+ config.loadDefaultOptions(WikittyConfigOption.values());
+ config.loadActions(WikittyConfigAction.values());
try {
- conf.parse(args);
+ config.parse(args);
} catch (ArgumentsParserException eee) {
if (log.isErrorEnabled()) {
log.error("Can't load wikitty configuration", eee);
}
}
- return conf;
+ return config;
}
/**
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -40,11 +40,11 @@
*/
public enum WikittyConfigOption implements OptionDef {
- WIKITTY_CONFIG_FILE(
- ApplicationConfig.CONFIG_FILE_NAME,
- n_("Main configuration wikitty file"),
- "wikitty-config.properties",
- String.class, true, true),
+// WIKITTY_CONFIG_FILE(
+// ApplicationConfig.CONFIG_FILE_NAME,
+// n_("Main configuration wikitty file"),
+// "wikitty-config.properties",
+// String.class, true, true),
WIKITTY_DATA_DIR(
"wikitty.data.directory",
n_("Data directory where wikitty store data"),
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,6 +25,7 @@
package org.nuiton.wikitty;
+import java.io.Serializable;
import org.nuiton.wikitty.entities.WikittyExtension;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.search.PagedResult;
@@ -36,7 +37,9 @@
import org.nuiton.wikitty.services.WikittyServiceStorage;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryResult;
import org.nuiton.wikitty.query.WikittyQueryResultTreeNode;
@@ -336,7 +339,7 @@
* @return
* @since 3.3
*/
- public List<WikittyQueryResult<String>> findAllByQuery(
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQuery(
String securityToken, List<WikittyQuery> queries);
/**
@@ -364,7 +367,7 @@
* @return wikitty id object or null
* @since 3.3
*/
- public List<String> findByQuery(String securityToken, List<WikittyQuery> queries);
+ public List<Map<String, Object>> findByQuery(String securityToken, List<WikittyQuery> queries);
/*
* Classification
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -32,10 +32,12 @@
import java.util.Date;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyClient;
@@ -130,8 +132,10 @@
if (field.hasMinQuery()) {
String query = field.getMinQuery();
WikittyQuery q = WikittyQueryParser.parse(query);
- List<String> queryResult = ws.findByQuery(token, Collections.singletonList(q));
- min = queryResult.get(0);
+ WikittyQueryResult queryResult = ws.findAllByQuery(token, Collections.singletonList(q)).get(0).convertMapToSimple();
+ if (queryResult.size() > 0 && queryResult.peek() != null) {
+ min = String.valueOf(queryResult.peek());
+ }
}
if (min == null && field.hasMin()) {
@@ -157,8 +161,10 @@
if (field.hasMaxQuery()) {
String query = field.getMaxQuery();
WikittyQuery q = WikittyQueryParser.parse(query);
- List<String> queryResult = ws.findByQuery(token, Collections.singletonList(q));
- max = queryResult.get(0);
+ WikittyQueryResult queryResult = ws.findAllByQuery(token, Collections.singletonList(q)).get(0).convertMapToSimple();
+ if (queryResult.size() > 0 && queryResult.peek() != null) {
+ max = String.valueOf(queryResult.peek());
+ }
}
if (max == null && field.hasMax()) {
@@ -249,7 +255,7 @@
.containsOne(Element.ID, ids).end()
.setOffset(0).setLimit(WikittyQuery.MAX);
WikittyQueryResult<String> queryResult =
- ws.findAllByQuery(token, Collections.singletonList(checkQuery)).get(0);
+ ws.<String>findAllByQuery(token, Collections.singletonList(checkQuery)).get(0).convertMapToSimple();
List<String> idResult = queryResult.getAll();
result = idResult.size() == ids.size();
@@ -341,9 +347,9 @@
String query = field.getAllowedQuery();
WikittyQuery q = WikittyQueryParser.parse(query);
q.setOffset(0).setLimit(WikittyQuery.MAX);
- List<WikittyQueryResult<String>> queryResult =
- ws.findAllByQuery(token, Collections.singletonList(q));
- allowed = queryResult.get(0).getAll();
+ WikittyQueryResult<String> queryResult =
+ ws.findAllByQuery(token, Collections.singletonList(q)).get(0).convertMapToSimple();
+ allowed = queryResult.getAll();
result = allowed.containsAll(values);
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -212,6 +212,15 @@
setCondition(condition);
}
+ /**
+ * Indique si la query commence par une clause Select
+ * @return
+ */
+ public boolean isSelectQuery() {
+ boolean result = condition instanceof Select;
+ return result;
+ }
+
public void accept(WikittyQueryVisitor visitor) {
boolean walk = visitor.visitEnter(this);
if (walk && condition != null) {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,6 +24,7 @@
*/
package org.nuiton.wikitty.query;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
@@ -38,7 +39,6 @@
import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.entities.FieldType;
import org.nuiton.wikitty.entities.Wikitty;
-import org.nuiton.wikitty.query.conditions.Aggregate;
import org.nuiton.wikitty.query.conditions.And;
import org.nuiton.wikitty.query.conditions.Between;
import org.nuiton.wikitty.query.conditions.Condition;
@@ -62,6 +62,17 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionAvg;
+import org.nuiton.wikitty.query.function.FunctionCount;
+import org.nuiton.wikitty.query.function.FunctionDistinct;
+import org.nuiton.wikitty.query.function.FunctionFieldValue;
+import org.nuiton.wikitty.query.function.FunctionFusion;
+import org.nuiton.wikitty.query.function.FunctionMax;
+import org.nuiton.wikitty.query.function.FunctionMin;
+import org.nuiton.wikitty.query.function.FunctionSum;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
+import org.nuiton.wikitty.query.function.WikittyQueryFunctionWrapper;
/**
* Cette objet sert a construire une condition a la facon d'un flux.
@@ -118,6 +129,8 @@
protected Condition condition;
/** stack des conditions non terminales ouvertes */
protected Deque<Condition> openStack = new LinkedList<Condition>();
+ /** stack des function ouvertes */
+ protected Deque<WikittyQueryFunction> openStackFunction = new LinkedList<WikittyQueryFunction>();
public WikittyQueryMakerAbstract() {
}
@@ -213,9 +226,225 @@
openStack = null;
}
}
-
+
+ protected Deque<WikittyQueryFunction> getOpenStackFunction() {
+ Condition c = getOpenStack().peek();
+ if (c instanceof Select) {
+ return openStackFunction;
+ } else {
+ throw new IllegalStateException("You can use function only in Select clause");
+ }
+ }
+
+ public M addFunction(WikittyQueryFunction f) {
+ WikittyQueryFunction parent = getOpenStackFunction().peek();
+ getOpenStackFunction().push(f);
+
+ if (parent != null) {
+ parent.addArgs(f);
+ }
+ return this.asM();
+ }
+
+ /**
+ * Assigne les functions au Select et prepare l'ecriture de la condition
+ * @return
+ */
+ public M where() {
+ Condition c = getOpenStack().peek();
+ if (c != null) { // pas de condition on ne fait rien
+ if (c instanceof Select) {
+ // un select on lui assigne la premiere function
+ WikittyQueryFunction root = getOpenStackFunction().peekLast();
+ if (root != null) {
+ Select select = (Select)c;
+ WikittyQueryFunction current = select.getFunction();
+ if (current == null) {
+ select.setFunction(root);
+ } else if (current instanceof FunctionFusion) {
+ current.addArgs(root);
+ } else {
+ FunctionFusion fusion = new FunctionFusion(root);
+ select.setFunction(fusion);
+ }
+ }
+ // et on vide la stack de function
+ getOpenStackFunction().clear();
+ } else {
+ throw new IllegalStateException("You can use Where only after select or at beginning of condition");
+ }
+ }
+ return this.asM();
+ }
+
///////////////////////////////////////////////////////////////////////////
//
+ // F U N C T I O N F L O W C R E A T I O N
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ public M fieldValue(String fieldName) {
+ FunctionFieldValue f = new FunctionFieldValue(null, fieldName);
+ addFunction(f);
+ return close();
+ }
+
+ public M fieldValue(Element fieldName) {
+ return fieldValue(fieldName.getValue());
+ }
+ public M avg() {
+ FunctionAvg f = new FunctionAvg(null);
+ return addFunction(f);
+ }
+
+ public M avg(String field) {
+ FunctionAvg f = new FunctionAvg(null, new FunctionFieldValue(null, field));
+ addFunction(f);
+ return close();
+ }
+
+ public M avg(Element field) {
+ return avg(field.getValue());
+ }
+
+ public M count() {
+ FunctionCount f = new FunctionCount(null);
+ return addFunction(f);
+ }
+
+ public M count(String field) {
+ FunctionCount f = new FunctionCount(null, new FunctionFieldValue(null, field));
+ addFunction(f);
+ return close();
+ }
+
+ public M count(Element field) {
+ return count(field.getValue());
+ }
+
+ public M max() {
+ FunctionMax f = new FunctionMax(null);
+ return addFunction(f);
+ }
+
+ public M max(String field) {
+ FunctionMax f = new FunctionMax(null, new FunctionFieldValue(null, field));
+ addFunction(f);
+ return close();
+ }
+
+ public M max(Element field) {
+ return max(field.getValue());
+ }
+
+ public M min() {
+ FunctionMin f = new FunctionMin(null);
+ return addFunction(f);
+ }
+
+ public M min(String field) {
+ FunctionMin f = new FunctionMin(null, new FunctionFieldValue(null, field));
+ addFunction(f);
+ return close();
+ }
+
+ public M min(Element field) {
+ return min(field.getValue());
+ }
+
+ public M sum() {
+ FunctionSum f = new FunctionSum(null);
+ return addFunction(f);
+ }
+
+ public M sum(String field) {
+ FunctionSum f = new FunctionSum(null, new FunctionFieldValue(null, field));
+ addFunction(f);
+ return close();
+ }
+
+ public M sum(Element field) {
+ return sum(field.getValue());
+ }
+
+ /**
+ * You need to close this distinct
+ * @return
+ */
+ public M distinct() {
+ FunctionDistinct f = new FunctionDistinct();
+ return addFunction(f);
+ }
+
+ /**
+ * if field is passed in argument then this this distinct is auto closed,
+ * otherwize you must clause this distinct with call to {@link #close}
+ * or {@link #where} method
+ * @return
+ */
+ public M distinct(String ... fields) {
+ boolean mustClose = false;
+ FunctionDistinct f = new FunctionDistinct();
+ if (fields != null && fields.length > 0) {
+ mustClose = true;
+ for (String fieldName : fields) {
+ f.addArgs(new FunctionFieldValue(null, fieldName));
+ }
+ }
+ addFunction(f);
+ if (mustClose) {
+ close();
+ }
+
+ return this.asM();
+ }
+
+ /**
+ * this distinct is auto closed if argument is not null
+ *
+ * @param one use to differenciate this method with Element argument with same with String argument
+ * @param fields other element
+ * @return
+ */
+ public M distinct(Element one, Element ... fields) {
+ List<String> l = new ArrayList<String>();
+ if (one != null) {
+ l.add(one.getValue());
+ }
+ if (fields != null) {
+ for (Element e : fields) {
+ l.add(e.getValue());
+ }
+ }
+ return distinct(l.toArray(new String[l.size()]));
+ }
+
+ /**
+ * ajoute une methode definit par l'utilisateur, la syntaxe de methode est
+ * package.class#method. Il faut ensuite ajouter des arguments a la methode
+ */
+ public M function(String method, Object ... args) {
+ WikittyQueryFunctionWrapper f = new WikittyQueryFunctionWrapper(method, null);
+ boolean mustClose = false;
+ if (args != null && args.length > 0) {
+ mustClose = true;
+ for (Object o : args) {
+ if (o instanceof WikittyQueryFunction) {
+ f.addArgs((WikittyQueryFunction)o);
+ } else {
+ f.addArgs(new FunctionValue(null, o));
+ }
+ }
+ }
+ addFunction(f);
+ if (mustClose) {
+ close();
+ }
+ return this.asM();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
// Q U E R Y F L O W C R E A T I O N
//
///////////////////////////////////////////////////////////////////////////
@@ -233,9 +462,21 @@
return result;
}
+ /**
+ * Ajout d'une valeur soit pour une condition soit pour une function de la clause select
+ * @param value
+ * @return
+ */
public M value(Object value) {
- ConditionValue v = convertToConditionValue(value);
- addCondition(v);
+ Condition c = getOpenStack().peek();
+ if (c instanceof Select) {
+ FunctionValue f = new FunctionValue(null, value);
+ addFunction(f);
+ close();
+ } else {
+ ConditionValue v = convertToConditionValue(value);
+ addCondition(v);
+ }
return this.asM();
}
@@ -1142,81 +1383,68 @@
* @return {@code this}
* @see {@link Select}
*/
- public M select(String element) {
- return select(Element.get(element));
- }
+// public M select() {
+// return select(null);
+// }
- /**
- * Add {@link Select}, this condition must be first or
- * @param element le champs dont il faut extraire les donnees
- * @return {@code this}
+ /*
* @see {@link Select}
*/
- public M select(String element, Aggregate aggregate) {
- return select(Element.get(element), aggregate);
+ public M select() {
+ return select((WikittyQueryFunction)null);
}
/*
* @see {@link Select}
*/
- public M select(Element element) {
- return select(element, null);
- }
+ public M select(WikittyQueryFunction f) {
+ Condition child = new Select(f);
- /*
- * @see {@link Select}
- */
- public M select(Element element, Aggregate aggregate) {
- Condition child = new Select(element, aggregate);
addCondition(child);
return this.asM();
}
- /**
- * Add {@link Select}, this condition must be first or
- * @param element le champs dont il faut extraire les donnees
- * @return {@code this}
- * @see {@link Select}
- */
- public M select(String element, boolean distinct) {
- return select(Element.get(element), distinct);
- }
-
- /**
- * Add {@link Select}, this condition must be first or
- * @param element le champs dont il faut extraire les donnees
- * @return {@code this}
- * @see {@link Select}
- */
- public M select(String element, Aggregate aggregate, boolean distinct) {
- return select(Element.get(element), aggregate, distinct);
- }
-
/*
* @see {@link Select}
*/
- public M select(Element element, boolean distinct) {
- return select(element, null, distinct);
+ public M select(String e) {
+ return select(Element.get(e));
}
/*
* @see {@link Select}
*/
- public M select(Element element, Aggregate aggregate, boolean distinct) {
- Condition child = new Select(element, aggregate, distinct);
- addCondition(child);
- return this.asM();
+ public M select(Element e) {
+ return select(new FunctionFieldValue(null, e.getValue()));
}
+// public M addFunction(WikittyQueryFunction f) {
+// // ajout function sur select ou args de function
+// // close sur function
+// }
+
/**
- * Close last non terminal condition (or, and, not, in).
+ * Close last non terminal condition (or, and, not, in). Or Last Function in select clause
* <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close();
* @return
*/
public M close() {
- getOpenStack().pop(); // on en ferme 1 obligatoirement
- // on cherche a en fermer plus
- closeIfNecessary();
+ Condition c = getOpenStack().peek();
+ WikittyQueryFunction f = openStackFunction.peek();
+ if (c instanceof Select && f != null) {
+ if (openStackFunction.size() == 1) {
+ // si on enleve l'element, il n'y a plus rien, ce close est donc
+ // l'equivalent d'un Where
+ where();
+ } else {
+ // on depile (il avait deja ete ajoute au parent, rien d'autre a faire)
+ openStackFunction.pop();
+ }
+ } else {
+ getOpenStack().pop(); // on en ferme 1 obligatoirement
+ // on cherche a en fermer plus
+ closeIfNecessary();
+ }
return this.asM();
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,6 +24,8 @@
*/
package org.nuiton.wikitty.query;
+import java.util.Collection;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
@@ -59,6 +61,9 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionFieldValue;
+import org.nuiton.wikitty.query.function.FunctionFusion;
+import org.nuiton.wikitty.query.function.FunctionValue;
import org.parboiled.BaseParser;
import org.parboiled.Context;
import org.parboiled.Parboiled;
@@ -91,13 +96,8 @@
@BuildParseTree
public class WikittyQueryParser extends BaseParser<Object> {
+ public static final String AS = "AS";
public static final String DATE = "DATE";
- public static final String AVG = "AVG";
- public static final String COUNT = "COUNT";
- public static final String MAX = "MAX";
- public static final String MIN = "MIN";
- public static final String SUM = "SUM";
- public static final String DISTINCT = "DISTINCT";
public static final String SELECT = "SELECT";
public static final String WHERE = "WHERE";
public static final String IN = "IN";
@@ -143,12 +143,6 @@
public Rule icNOT = IgnoreCase(NOT);
public Rule icAND = IgnoreCase(AND);
public Rule icOR = IgnoreCase(OR);
- public Rule icAVG = IgnoreCase(AVG);
- public Rule icCOUNT = IgnoreCase(COUNT);
- public Rule icMAX = IgnoreCase(MAX);
- public Rule icMIN = IgnoreCase(MIN);
- public Rule icSUM = IgnoreCase(SUM);
- public Rule icDISTINCT = IgnoreCase(DISTINCT);
public Rule icSELECT = IgnoreCase(SELECT);
public Rule icWHERE = IgnoreCase(WHERE);
public Rule icIN = IgnoreCase(IN);
@@ -159,6 +153,7 @@
public Rule icUNLIKE = IgnoreCase(UNLIKE);
public Rule icNULL = IgnoreCase(NULL);
public Rule icDATE = IgnoreCase(DATE);
+ public Rule icAS = IgnoreCase(AS);
/** to use log facility, just put in your code: log.info(\"...\"); */
static private Log log = LogFactory.getLog(WikittyQueryParser.class);
@@ -329,6 +324,16 @@
return result;
}
+ /**
+ * @param list la collection en object pour eviter le cast dans les Rules
+ * @param e l'element a ajouter a la liste
+ * @return la liste passee en parametre
+ */
+ protected Object addToList(Object list, Object e) {
+ ((Collection)list).add(e);
+ return list;
+ }
+
Rule start() {
return Sequence(FirstOf(or(), empty()), push(new WikittyQuery((Condition)pop())),
offset(), limit(), depth(), space(), EOI);
@@ -494,42 +499,49 @@
push(new ContainsOne(toElement(pop().toString()), elems.get())));
}
Rule select() {
- Var<Aggregate> aggregate = new Var<Aggregate>();
- Var<Boolean> distinct = new Var<Boolean>(Boolean.FALSE);
return Sequence(icSELECT, space(),
- Optional(distinct(distinct)), space(),
- Optional(aggregate(aggregate)), space(),
- field(), push(match()), space(),
+ functionOrFieldList() /*, field(), push(match())*/, space(),
FirstOf(Sequence(icWHERE, space(), term()), empty()),
- push(new Select(toElement(pop(1).toString()), aggregate.get(), (Condition)pop())));
+ push(new Select(((WikittyQueryFunction)pop(1)), (Condition)pop())));
}
- Rule distinct(Var<Boolean> distinct) {
- return Sequence(icDISTINCT, distinct.set(Boolean.TRUE));
- }
- Rule aggregate(Var<Aggregate> aggregate) {
- return FirstOf(avg(aggregate), count(aggregate), max(aggregate), min(aggregate), sum(aggregate));
+ Rule functionOrFieldList() {
+ return Sequence(push(new LinkedList()), functionOrFieldOrString(), ZeroOrMore(COMMA, functionOrFieldOrString()),
+ push(WikittyQueryFunction.createFusionIfNeeded((List)pop())));
}
+ Rule functionOrFieldOrString() {
+ return Sequence(FirstOf(function(), fieldFunction(), stringFunction()),
+ push(addToList(pop(1), pop())));
+ }
- Rule avg(Var<Aggregate> aggregate) {
- return Sequence(icAVG, aggregate.set(Aggregate.AVG));
+ Rule function() {
+ Var<String> alias = new Var<String>();
+ return Sequence(field(), push(match()), BRACKET_OPEN,
+ push(new LinkedList()),
+ Optional(functionOrFieldOrString(), ZeroOrMore(COMMA, functionOrFieldOrString())),
+ BRACKET_CLOSE, Optional(alias(alias)),
+ push(WikittyQueryFunction.create(pop(1).toString(), alias.get(), (List)pop())));
}
- Rule count(Var<Aggregate> aggregate) {
- return Sequence(icCOUNT, aggregate.set(Aggregate.COUNT));
+ Rule fieldFunction() {
+ Var<String> alias = new Var<String>();
+ return Sequence(field(), push(toElement(match())), Optional(alias(alias)),
+ push(new FunctionFieldValue(alias.get(), pop().toString())));
}
- Rule max(Var<Aggregate> aggregate) {
- return Sequence(icMAX, aggregate.set(Aggregate.MAX));
+ Rule stringFunction() {
+ Var<String> alias = new Var<String>();
+ return Sequence(valueText(), Optional(alias(alias)),
+ push(new FunctionValue(alias.get(), ((ConditionValueString)pop()).getValue() )));
}
- Rule min(Var<Aggregate> aggregate) {
- return Sequence(icMIN, aggregate.set(Aggregate.MIN));
+ Rule alias(Var<String> alias) {
+ return Sequence(space(), icAS, space(), field(), alias.set(match()));
}
- Rule sum(Var<Aggregate> aggregate) {
- return Sequence(icSUM, aggregate.set(Aggregate.SUM));
+ Rule element() {
+ return Sequence(field(), push(toElement(match())));
}
Rule keyword() {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,6 +25,7 @@
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;
@@ -34,6 +35,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyClient;
+import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.entities.Element;
/**
@@ -103,6 +105,54 @@
this.timeConvertion = timeConvertion;
}
+ /**
+ * if this WikittyQueryResult contains Map<String, Object>, and
+ * each Map contains only one value, this methode return
+ * new WikittyQueryResult with value only (no more map).
+ *
+ * If this WikittyQueryResult don't contains Map, then this is returned
+ *
+ * @return
+ */
+ public <E> WikittyQueryResult<E> convertMapToSimple() {
+ WikittyQueryResult<E> result;
+
+ if (results.isEmpty() || !(results.get(0) instanceof Map)) {
+ result = (WikittyQueryResult<E>)this;
+ } else {
+ List<E> data = new ArrayList<E>(results.size());
+
+ for (Map map : (List<Map>)results) {
+ if (map.size() != 1) {
+ throw new IllegalStateException(String.format(
+ "Map must have ONE element (currently %s", map.size()));
+ }
+ data.addAll(map.values());
+ }
+
+ result = new WikittyQueryResult<E>(
+ queryName, offset, totalResult, queryString, facets,
+ data, timeQuery, timeConvertion);
+ }
+
+ return result;
+ }
+
+ public WikittyQueryResult<String> convertMapToSimpleString() {
+ List dataObject = convertMapToSimple().getAll();
+
+ List<String> data = new ArrayList<String>(dataObject.size());
+ for (Object o : dataObject) {
+ data.add(WikittyUtil.toString(o));
+ }
+
+ WikittyQueryResult<String> result = new WikittyQueryResult<String>(
+ queryName, offset, totalResult, queryString, facets,
+ data, timeQuery, timeConvertion);
+
+ return result;
+ }
+
public String getQueryName() {
return queryName;
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitor.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -50,6 +50,8 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
/**
* Permet d'implanter un visiteur de Query ou Condition. Une fois que vous avez
@@ -145,6 +147,12 @@
*/
abstract public boolean visitEnter(Select 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(Select o);
+ /**
* Leave method is alway called, but evaluation of enter is passed in
* arguement
*
@@ -202,6 +210,11 @@
abstract public void visit(ConditionValueString o);
+ abstract public boolean visitEnter(WikittyQueryFunction function);
+ abstract public boolean visitMiddle(WikittyQueryFunction function);
+ abstract public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult);
+ abstract public void visit(FunctionValue function);
+
abstract public void defaultVisit(Object o);
/**
* True if we want visit sub-element, otherwize false
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,6 +25,7 @@
package org.nuiton.wikitty.query;
import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.query.conditions.And;
@@ -50,6 +51,9 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionFusion;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
/**
* This visitor make a deep copy of WikittyQuery.
@@ -68,7 +72,17 @@
static private Log log = LogFactory.getLog(WikittyQueryVisitorCopy.class);
protected WikittyQueryMaker queryMaker;
+ protected List<WikittyQueryFunction> functions = new ArrayList<WikittyQueryFunction>();
+ protected List<WikittyQueryFunction> getAndClearFunction() {
+ List<WikittyQueryFunction> result = functions;
+ functions = new ArrayList<WikittyQueryFunction>();
+ return result;
+ }
+ protected void addFunction(WikittyQueryFunction f) {
+ functions.add(f);
+ }
+
protected WikittyQueryMaker getQueryMaker() {
if (queryMaker == null) {
queryMaker = new WikittyQueryMaker();
@@ -154,11 +168,26 @@
@Override
public boolean visitEnter(Select o) {
- getQueryMaker().select(o.getElement(), o.getAggregate());
return true;
}
@Override
+ public boolean visitMiddle(Select o) {
+ List<WikittyQueryFunction> fs = getAndClearFunction();
+
+ WikittyQueryFunction f;
+ if (fs.isEmpty()) {
+ throw new IllegalStateException("Select must have WikittyQueryFunction");
+ } else if (fs.size() > 1) {
+ f = fs.get(0);
+ } else {
+ f = new FunctionFusion(fs);
+ }
+ getQueryMaker().select(f);
+ return true;
+ }
+
+ @Override
public void visitLeave(Select o, boolean enterOrMiddleResult) {
// do nothing, close is automatic
}
@@ -353,7 +382,30 @@
getQueryMaker().isNotNull(o.getElement());
}
+
@Override
+ public boolean visitEnter(WikittyQueryFunction function) {
+ return true;
+ }
+
+ @Override
+ public boolean visitMiddle(WikittyQueryFunction function) {
+ return true;
+ }
+
+ @Override
+ public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult) {
+ List<WikittyQueryFunction> args = getAndClearFunction();
+ WikittyQueryFunction f = WikittyQueryFunction.create(function.getMethodName(), function.getName(), args);
+ addFunction(f);
+ }
+
+ @Override
+ public void visit(FunctionValue function) {
+ addFunction(new FunctionValue(function.getName(), function.getValue()));
+ }
+
+ @Override
public void defaultVisit(Object o) {
throw new UnsupportedOperationException(
"Not supported (" + o.getClass().getSimpleName() + ").");
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorToString.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,6 +24,7 @@
*/
package org.nuiton.wikitty.query;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.query.conditions.And;
@@ -47,6 +48,9 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionFieldValue;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
/**
* Genere un texte representant une query tel qu'un homme pourrait l'ecrire
@@ -116,16 +120,17 @@
@Override
public boolean visitEnter(Select o) {
- String agg = "";
- if (o.getAggregate() != null) {
- agg = o.getAggregate().name() + " ";
- }
- text += WikittyQueryParser.SELECT + " " + agg + o.getElement().getValue()
- + " " + WikittyQueryParser.WHERE + " " + WikittyQueryParser.BRACKET_OPEN;
+ text += WikittyQueryParser.SELECT + " ";
return true;
}
@Override
+ public boolean visitMiddle(Select o) {
+ text += " " + WikittyQueryParser.WHERE + " " + WikittyQueryParser.BRACKET_OPEN;
+ return true;
+ }
+
+ @Override
public void visitLeave(Select o, boolean enterOrMiddleResult) {
text += WikittyQueryParser.BRACKET_CLOSE;
}
@@ -338,6 +343,31 @@
}
@Override
+ public boolean visitEnter(WikittyQueryFunction function) {
+ text += function.getMethodName() + WikittyQueryParser.BRACKET_OPEN;
+ return true;
+ }
+
+ @Override
+ public boolean visitMiddle(WikittyQueryFunction function) {
+ text += WikittyQueryParser.COMMA;
+ return true;
+ }
+
+ @Override
+ public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult) {
+ text += WikittyQueryParser.BRACKET_CLOSE;
+ if (StringUtils.isNotBlank(function.getName())) {
+ text += " " + WikittyQueryParser.AS + " " + function.getName();
+ }
+ }
+
+ @Override
+ public void visit(FunctionValue function) {
+ text += String.valueOf(function.getValue());
+ }
+
+ @Override
public void defaultVisit(Object o) {
throw new UnsupportedOperationException("Not supported:" + o.getClass());
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -26,6 +26,8 @@
import org.nuiton.wikitty.entities.Element;
import org.apache.commons.lang3.ObjectUtils;
+import org.nuiton.wikitty.query.WikittyQueryVisitor;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
/**
* Cette condition n'accept pas d'etre utilise dans une autre condition.
@@ -50,64 +52,47 @@
private static final long serialVersionUID = 1L;
- protected boolean distinct = false;
- protected Aggregate aggregate;
- protected Element element;
+ protected WikittyQueryFunction function;
- public Select(Element element) {
- this(element, null, false, null);
+ public Select(WikittyQueryFunction function) {
+ this.function = function;
}
- public Select(Element element, boolean distinct) {
- this(element, null, distinct, null);
- }
-
- public Select(Element element, Aggregate aggregate) {
- this(element, aggregate, false, null);
- }
-
- public Select(Element element, Aggregate aggregate, boolean distinct) {
- this(element, aggregate, distinct, null);
- }
-
- public Select(Element element, Condition restriction) {
- this(element, null, false, restriction);
- }
-
- public Select(Element element, boolean distinct, Condition restriction) {
- this(element, null, distinct, restriction);
- }
-
- public Select(Element element, Aggregate aggregate, Condition restriction) {
- this(element, aggregate, false, restriction);
- }
-
- public Select(Element element, Aggregate aggregate, boolean distinct, Condition restriction) {
+ public Select(WikittyQueryFunction function, Condition restriction) {
super(restriction);
- this.element = element;
- this.aggregate = aggregate;
- this.distinct = distinct;
+ this.function = function;
}
- public Aggregate getAggregate() {
- return aggregate;
+ public WikittyQueryFunction getFunction() {
+ return function;
}
- public Element getElement() {
- return element;
+ public void setFunction(WikittyQueryFunction function) {
+ this.function = function;
}
- public boolean isDistinct() {
- return distinct;
- }
-
@Override
boolean equalsDeep(Object other) {
boolean result = super.equalsDeep(other);
if (result) {
Select op = (Select)other;
- result = ObjectUtils.equals(this.getElement(), op.getElement());
+ result = ObjectUtils.equals(this.getFunction(), op.getFunction());
}
return result;
}
+
+ @Override
+ public void accept(WikittyQueryVisitor visitor) {
+ boolean walk = visitor.visitEnter(this);
+ if (walk && function != null) {
+ function.accept(visitor);
+ }
+ walk = visitor.visitMiddle(this);
+ if (walk && subCondition != null) {
+ subCondition.accept(visitor);
+ }
+ visitor.visitLeave(this, walk);
+ }
+
+
}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionAvg.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,85 @@
+package org.nuiton.wikitty.query.function;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.WikittyUtil;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionAvg extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionAvg.class);
+
+ public FunctionAvg(String name) {
+ super("Avg", name, null);
+ }
+
+ public FunctionAvg(String name, WikittyQueryFunction arg) {
+ super("Avg", name, Collections.singletonList(arg));
+ }
+
+ public FunctionAvg(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("Sum accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ data = f.call(searchEngine, tx, query, data);
+
+ BigDecimal total = new BigDecimal(0);
+ int cpt = 0;
+ for (Map<String, Object> o : data) {
+ if (o.size() > 1) {
+ throw new IllegalStateException("Avg function can't take data, with more than one field");
+ } else {
+ // on fait un for mais en fait, il n'y a 0 ou 1 element.
+ // Mais je ne vois pas de solution plus simple a ecrire
+ for (Object s : o.values()) {
+ if (s instanceof Collection) {
+ for (Object e : (Collection)s) {
+ BigDecimal v = WikittyUtil.toBigDecimal(e);
+ total = total.add(v);
+ cpt++;
+ }
+ } else {
+ BigDecimal v = WikittyUtil.toBigDecimal(s);
+ total = total.add(v);
+ cpt++;
+ }
+ }
+ }
+ }
+ BigDecimal avg = total.divide(new BigDecimal(cpt));
+
+ Map<String, Object> val = Collections.singletonMap(getName(), (Object)avg);
+ List<Map<String, Object>> result = Collections.singletonList(val);
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionCount.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,79 @@
+package org.nuiton.wikitty.query.function;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionCount extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionCount.class);
+
+ public FunctionCount(String name) {
+ super("Count", name, null);
+ }
+
+ public FunctionCount(String name, WikittyQueryFunction arg) {
+ super("Count", name, Collections.singletonList(arg));
+ }
+
+ public FunctionCount(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("Sum accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ data = f.call(searchEngine, tx, query, data);
+
+ int cpt = 0;
+ for (Map<String, Object> o : data) {
+ if (o.size() > 1) {
+ // il y a plus de 1 element dans la map, on a donc des objets 'complets', on
+ // compte donc le nombre d'objet et non pas le nombre de valeur
+ // d'un champs
+ cpt = data.size();
+ break;
+ } else {
+ // on fait un for mais en fait, il n'y a 0 ou 1 element.
+ // Mais je ne vois pas de solution plus simple a ecrire
+ for (Object s : o.values()) {
+ if (s instanceof Collection) {
+ cpt+=((Collection)s).size();
+ } else {
+ cpt++;
+ }
+ }
+ }
+ }
+
+ Map<String, Object> val = Collections.singletonMap(getName(), (Object)cpt);
+ List<Map<String, Object>> result = Collections.singletonList(val);
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionDistinct.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionDistinct.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionDistinct.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,76 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionDistinct extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionDistinct.class);
+
+ public FunctionDistinct(WikittyQueryFunction... args) {
+ super("Distinct", null, Arrays.asList(args));
+ }
+
+ public FunctionDistinct(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ List<List<Map<String, Object>>> extractedData =
+ new ArrayList<List<Map<String, Object>>>();
+
+ for (WikittyQueryFunction f : getArgs()) {
+ List<Map<String, Object>> r = f.call(searchEngine, tx, query, data);
+ extractedData.add(r);
+ }
+
+ List<Map<String, Object>> result = fusion(extractedData);
+
+ // on collecte tous les doublons
+ Object[] all = result.toArray();
+ // on utilise un set, car il ne faut pas supprimer plusieurs fois le meme element
+ Set<Integer> toRemove = new HashSet<Integer>();
+ for (int i=0; i<all.length; i++) {
+ for (int j=i+1; j<all.length; j++) {
+ if (all[i].equals(all[j])) {
+ toRemove.add(j);
+ }
+ }
+ }
+
+ // on supprime les doublons
+ List<Integer> index = new ArrayList<Integer>(toRemove);
+ Collections.sort(index);
+ Collections.reverse(index);
+ for (int i : index) {
+ result.remove(i);
+ }
+
+ return result;
+ }
+
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFieldValue.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,76 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.entities.Element;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ * Permet de recuperer la valeur d'un champs, les Maps retournees contiennent
+ * seulement un champs
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionFieldValue extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionFieldValue.class);
+
+ public FunctionFieldValue(String name, String fieldName) {
+ super("fieldValue",
+ StringUtils.isNotBlank(name)?name:Element.get(fieldName).getValue(),
+ Collections.singletonList((WikittyQueryFunction)new FunctionValue(null, Element.get(fieldName).getValue())));
+ }
+
+ public FunctionFieldValue(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("FieldValue accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ List<Map<String, Object>> fieldName = f.call(searchEngine, tx, query, data);
+
+ String field = getUniqueValue(fieldName).toString();
+
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(data.size());
+ for (Map<String, Object> m : data) {
+ if (m.containsKey(field)) {
+ Object val = m.get(field);
+ if (val instanceof Collection) {
+ for (Object o : (Collection)val) {
+ result.add(Collections.singletonMap(field, o));
+ }
+ } else {
+ result.add(Collections.singletonMap(field, val));
+ }
+ }
+ }
+
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionFusion.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,53 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionFusion extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionFusion.class);
+
+ public FunctionFusion(WikittyQueryFunction... args) {
+ super("Fusion", null, Arrays.asList(args));
+ }
+
+ public FunctionFusion(List<WikittyQueryFunction> args) {
+ super("Fusion", null, args);
+ }
+
+ public FunctionFusion(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ List<List<Map<String, Object>>> all = new ArrayList<List<Map<String, Object>>>();
+ for (WikittyQueryFunction f : getArgs()) {
+ all.add(f.call(searchEngine, tx, query, data));
+ }
+
+ List<Map<String, Object>> result = fusion(all);
+ return result;
+ }
+
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMax.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,78 @@
+package org.nuiton.wikitty.query.function;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionMax extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionMax.class);
+
+ public FunctionMax(String name) {
+ super("Max", name, null);
+ }
+
+ public FunctionMax(String name, WikittyQueryFunction arg) {
+ super("Max", name, Collections.singletonList(arg));
+ }
+
+ public FunctionMax(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("Sum accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ data = f.call(searchEngine, tx, query, data);
+
+ Comparable candidate = null;
+ for (Map<String, Object> m : data) {
+ Object v = getUniqueValue(m);
+ if (v instanceof Collection) {
+ for (Object o : (Collection)v) {
+ if (o instanceof Comparable) {
+ if (candidate == null || candidate.compareTo(o) < 0) {
+ candidate = (Comparable)o;
+ }
+ }
+ }
+ } else {
+ if (v instanceof Comparable) {
+ if (candidate == null || candidate.compareTo(v) < 0) {
+ candidate = (Comparable)v;
+ }
+ }
+ }
+ }
+
+ List<Map<String, Object>> result = Collections.singletonList(
+ Collections.singletonMap(getName(), (Object)candidate));
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionMin.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,78 @@
+package org.nuiton.wikitty.query.function;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionMin extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionMin.class);
+
+ public FunctionMin(String name) {
+ super("Min", name, null);
+ }
+
+ public FunctionMin(String name, WikittyQueryFunction arg) {
+ super("Min", name, Collections.singletonList(arg));
+ }
+
+ public FunctionMin(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("Sum accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ data = f.call(searchEngine, tx, query, data);
+
+ Comparable candidate = null;
+ for (Map<String, Object> m : data) {
+ Object v = getUniqueValue(m);
+ if (v instanceof Collection) {
+ for (Object o : (Collection)v) {
+ if (o instanceof Comparable) {
+ if (candidate == null || candidate.compareTo(o) > 0) {
+ candidate = (Comparable)o;
+ }
+ }
+ }
+ } else {
+ if (v instanceof Comparable) {
+ if (candidate == null || candidate.compareTo(v) > 0) {
+ candidate = (Comparable)v;
+ }
+ }
+ }
+ }
+
+ List<Map<String, Object>> result = Collections.singletonList(
+ Collections.singletonMap(getName(), (Object)candidate));
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionSum.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,80 @@
+package org.nuiton.wikitty.query.function;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.WikittyUtil;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionSum extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionSum.class);
+
+ public FunctionSum(String name) {
+ super("Sum", name, null);
+ }
+
+ public FunctionSum(String name, WikittyQueryFunction arg) {
+ super("Sum", name, Collections.singletonList(arg));
+ }
+
+ public FunctionSum(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+ if (args.size() != 1) {
+ throw new IllegalArgumentException("Sum accept only one argument");
+ }
+ }
+
+ @Override
+ public int getNumArg() {
+ return 1;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+
+ WikittyQueryFunction f = getArgs().get(0);
+ data = f.call(searchEngine, tx, query, data);
+
+ BigDecimal total = new BigDecimal(0);
+ for (Map<String, Object> o : data) {
+ if (o.size() > 1) {
+ throw new IllegalStateException("Sum function can't take data, with more than one field");
+ } else {
+ // on fait un for mais en fait, il n'y a 0 ou 1 element.
+ // Mais je ne vois pas de solution plus simple a ecrire
+ for (Object s : o.values()) {
+ if (s instanceof Collection) {
+ for (Object e : (Collection)s) {
+ BigDecimal v = WikittyUtil.toBigDecimal(e);
+ total = total.add(v);
+ }
+ } else {
+ BigDecimal v = WikittyUtil.toBigDecimal(s);
+ total = total.add(v);
+ }
+ }
+ }
+ }
+ Map<String, Object> val = Collections.singletonMap(getName(), (Object)total);
+ List<Map<String, Object>> result = Collections.singletonList(val);
+ return result;
+ }
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/FunctionValue.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,66 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.query.WikittyQueryVisitor;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ * Permet de stocker une valeur.
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class FunctionValue extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(FunctionValue.class);
+
+ protected Object value;
+
+ public FunctionValue(String name, Object value) {
+ super(null, name, null);
+ this.value = value;
+ }
+
+ @Override
+ public int getNumArg() {
+ return 0;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+ List<Map<String, Object>> result =
+ Collections.singletonList(Collections.singletonMap(getName(), value));
+ return result;
+ }
+
+ @Override
+ public void accept(WikittyQueryVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result = super.equals(o)
+ && ObjectUtils.equals(this.getValue(), ((FunctionValue)o).getValue());
+ return result;
+ }
+
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunction.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,279 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.util.ObjectUtil;
+import org.nuiton.wikitty.WikittyUtil;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.query.WikittyQueryVisitor;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ * Herite de Element et utilise value pour stocker la methode a appeler
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public abstract class WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(WikittyQueryFunction.class);
+
+ private static final long serialVersionUID = 1L;
+
+ /** le nom de la methode a appeler */
+ protected String methodName;
+ /** le nom que l'utilisateur a donné au resultat: ex: Sum(amount) as Toto */
+ protected String name;
+ /** la liste des arguments de la fonction */
+ protected List<WikittyQueryFunction> args = new ArrayList<WikittyQueryFunction>();
+ /** le nombre d'argument que la function peut prendre. Integer.MAX_VALUE = infini */
+ protected int numArg = Integer.MAX_VALUE;
+
+
+ static public WikittyQueryFunction createFusionIfNeeded(List<WikittyQueryFunction> args) {
+ WikittyQueryFunction result;
+ if (args.size() == 1) {
+ result = args.get(0);
+ } else {
+ result = new FunctionFusion(args);
+ }
+ return result;
+ }
+
+ static public WikittyQueryFunction create(String methodName, String name, List<WikittyQueryFunction> args) {
+ WikittyQueryFunction result;
+ if ("fieldValue".equalsIgnoreCase(methodName)) {
+ result = new FunctionFieldValue(methodName, name, args);
+ } else if ("Fusion".equalsIgnoreCase(methodName)) {
+ result = new FunctionFusion(methodName, name, args);
+ } else if ("sum".equalsIgnoreCase(methodName)) {
+ result = new FunctionSum(methodName, name, args);
+ } else if ("min".equalsIgnoreCase(methodName)) {
+ result = new FunctionMin(methodName, name, args);
+ } else if ("max".equalsIgnoreCase(methodName)) {
+ result = new FunctionMax(methodName, name, args);
+ } else if ("avg".equalsIgnoreCase(methodName)) {
+ result = new FunctionAvg(methodName, name, args);
+ } else if ("count".equalsIgnoreCase(methodName)) {
+ result = new FunctionCount(methodName, name, args);
+ } else if ("distinct".equalsIgnoreCase(methodName)) {
+ result = new FunctionDistinct(methodName, name, args);
+ } else if ("toBigDecimal".equalsIgnoreCase(methodName)) {
+ result = new WikittyQueryFunctionWrapper(WikittyUtil.class.getName() + "#toBigDecimal", name, args);
+ } else if ("toBoolean".equalsIgnoreCase(methodName)) {
+ result = new WikittyQueryFunctionWrapper(WikittyUtil.class.getName() + "#toBoolean", name, args);
+ } else if ("toString".equalsIgnoreCase(methodName)) {
+ result = new WikittyQueryFunctionWrapper(WikittyUtil.class.getName() + "#toString", name, args);
+ } else if ("toDate".equalsIgnoreCase(methodName)) {
+ result = new WikittyQueryFunctionWrapper(WikittyUtil.class.getName() + "#toDate", name, args);
+ } else {
+ result = new WikittyQueryFunctionWrapper(methodName, name, args);
+ }
+
+ return result;
+ }
+
+ public WikittyQueryFunction(String methodName, String name, List<WikittyQueryFunction> args) {
+ this.methodName = methodName;
+ if (name == null) {
+ this.name = UUID.randomUUID().toString();
+ } else {
+ this.name = name;
+ }
+
+ addArgs(args);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o == null) {
+ result = false;
+ } else if (this == o) {
+ result = true;
+ }else if (this.getClass().equals(o.getClass())) {
+ WikittyQueryFunction other = (WikittyQueryFunction)o;
+ result = StringUtils.equals(this.getMethodName(), other.getMethodName())
+ // TODO a revoir
+ // name est genere pour etre unique s'il n'est pas fixe, donc on ne peut pas faire de check dessus
+ // est-ce que laisser null, si name n'est pas fixer ne serait pas preferable ? Est-ce que les map accept null comme cle ?
+// && StringUtils.equals(this.getName(), other.getName())
+ && ObjectUtils.equals(this.getArgs(), other.getArgs());
+ } else {
+ return false;
+ }
+ return result;
+ }
+
+ public void accept(WikittyQueryVisitor visitor) {
+ boolean walk = visitor.visitEnter(this);
+ if (walk && args != null) {
+ boolean notFirst = false;
+ for(WikittyQueryFunction a : args) {
+ if (notFirst) {
+ walk = visitor.visitMiddle(this);
+ if (!walk) {
+ // le visiteur demande l'arret de la visite
+ break;
+ }
+ } else {
+ notFirst = true;
+ }
+ a.accept(visitor);
+ }
+ }
+ visitor.visitLeave(this, walk);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public List<WikittyQueryFunction> getArgs() {
+ return args;
+ }
+
+ public void addArgs(List<WikittyQueryFunction> args) {
+ if (args != null) {
+ if (this.args.size() + args.size() <= getNumArg()) {
+ this.args.addAll(args);
+ } else {
+ throw new IllegalStateException(String.format(
+ "This function '%s' can't take more arguments than %s, currently '%s', you try to add %s arguments",
+ this.getClass().getSimpleName(), getNumArg(), this.args.size(), args.size()));
+ }
+ }
+ }
+
+ public void addArgs(WikittyQueryFunction arg) {
+ if (acceptMoreArgs()) {
+ args.add(arg);
+ } else {
+ throw new IllegalStateException(String.format(
+ "This function '%s' can't take more arguments, currently '%s'",
+ this.getClass().getSimpleName(), args.size()));
+ }
+ }
+
+ public int getNumArg() {
+ return numArg;
+ }
+
+ public boolean acceptMoreArgs() {
+ boolean result = args.size() < getNumArg();
+ return result;
+ }
+
+ abstract public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data);
+
+ protected List<Map<String, Object>> fusion(List<List<Map<String, Object>>> listData) {
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
+ // check size, all list must have same size
+ int size = -1;
+ for (List<Map<String, Object>> e : listData) {
+ if (size == -1) {
+ size = e.size();
+ } else {
+ if (size != e.size()) {
+ throw new IllegalArgumentException("Each list must have same size");
+ }
+ }
+ }
+
+ // init des maps
+ for (int i=0; i<size; i++) {
+ result.add(new LinkedHashMap<String, Object>());
+ }
+
+ // ajout de chaque map dans la map du resultat
+ for (List<Map<String, Object>> e : listData) {
+ int i=0;
+ for (Map<String, Object> m : e) {
+ Map<String, Object> r = result.get(i++);
+ r.putAll(m);
+ }
+
+ }
+
+ return result;
+ }
+
+ protected Object getUniqueValue(List<Map<String, Object>> data) {
+ Object result = null;
+ if (data.size() != 1) {
+ throw new IllegalStateException("Data don't contains 1 value exactly");
+ }
+ for (Map<String, Object> o : data) {
+ if (o.size() != 1) {
+ throw new IllegalStateException("Map don't contains 1 value exactly");
+ } else {
+ for (Object s : o.values()) {
+ result = s;
+ }
+ }
+ }
+ return result;
+ }
+
+ protected Object getUniqueValue(Map<String, Object> o) {
+ Object result = null;
+ if (o.size() != 1) {
+ throw new IllegalStateException("Map don't contains 1 value exactly");
+ } else {
+ for (Object s : o.values()) {
+ result = s;
+ }
+ }
+ return result;
+ }
+
+ protected Object getFirstFieldName(List<Map<String, Object>> data) {
+ for (Map<String, Object> o : data) {
+ for (Object s : o.keySet()) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param fqMethod une methode d du style le.package.objet#method
+ * @return
+ */
+ protected Method getMethod(String fqMethod) {
+ List<Method> methods = ObjectUtil.getMethod(name, true);
+
+ Method result = null;
+ if (methods.size() > 0) {
+ if (methods.size() > 1) {
+ log.warn(String.format(
+ "More than one method found, used the first: %s",
+ methods));
+ }
+ result = methods.get(0);
+ }
+ return result;
+ }
+
+}
Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java (rev 0)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/function/WikittyQueryFunctionWrapper.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -0,0 +1,82 @@
+package org.nuiton.wikitty.query.function;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.util.ObjectUtil;
+import org.nuiton.wikitty.query.WikittyQuery;
+import org.nuiton.wikitty.services.WikittyTransaction;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class WikittyQueryFunctionWrapper extends WikittyQueryFunction {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(WikittyQueryFunctionWrapper.class);
+
+ public WikittyQueryFunctionWrapper(String methodName, String name, WikittyQueryFunction... args) {
+ super(methodName, name, Arrays.asList(args));
+ }
+
+ public WikittyQueryFunctionWrapper(String methodName, String name, List<WikittyQueryFunction> args) {
+ super(methodName, name, args);
+
+ }
+
+ @Override
+ public List<Map<String, Object>> call(
+ WikittySearchEngine searchEngine, WikittyTransaction tx,
+ WikittyQuery query, List<Map<String, Object>> data) {
+ List<List<Map<String, Object>>> param = new ArrayList<List<Map<String, Object>>>();
+
+ for (WikittyQueryFunction f : getArgs()) {
+ param.add(f.call(searchEngine, tx, query, data));
+ }
+
+ data = fusion(param);
+
+ Method method = getMethod(methodName);
+ Object target = null;
+ if (!Modifier.isStatic(method.getModifiers())) {
+ Class clazz = method.getDeclaringClass();
+ try {
+ target = clazz.newInstance();
+ } catch (Exception eee) {
+ throw new IllegalStateException(String.format(
+ "Can't instanciate object needed to call function %s",
+ methodName), eee);
+ }
+ }
+
+ for (Map<String, Object> o : data) {
+ String[] args = new String[o.size()];
+ int i=0;
+ for (Object v : o.values()) {
+ args[i++] = String.valueOf(v);
+ }
+ try {
+ Object r = ObjectUtil.call(target, method, args);
+ } catch (Exception eee) {
+ throw new IllegalStateException(String.format(
+ "Can't call function '%s'",
+ methodName), eee);
+ }
+ }
+ return data;
+ }
+
+
+}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittySecurityHelper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittySecurityHelper.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittySecurityHelper.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -86,7 +86,7 @@
static public String getUserWikittyId(WikittyClient client, String login) {
WikittyQuery query = new WikittyQueryMaker().eq(
WikittyUser.FQ_FIELD_WIKITTYUSER_LOGIN, login).end();
- String userWikittyId = client.findByQuery(query);
+ String userWikittyId = client.findByQuery(String.class, query);
return userWikittyId;
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAccessStat.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAccessStat.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAccessStat.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,10 +25,17 @@
package org.nuiton.wikitty.services;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.util.ApplicationConfig;
-import org.nuiton.wikitty.WikittyConfig;
+import org.nuiton.wikitty.WikittyConfigOption;
import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.entities.BusinessEntity;
import org.nuiton.wikitty.entities.Wikitty;
@@ -36,15 +43,6 @@
import org.nuiton.wikitty.entities.WikittyAccessStatImpl;
import org.nuiton.wikitty.entities.WikittyTokenHelper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.nuiton.wikitty.WikittyConfigOption;
-
/**
*
* @author poussin
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthentication.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthentication.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthentication.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,7 +24,6 @@
*/
package org.nuiton.wikitty.services;
-import java.util.Collections;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -96,8 +95,7 @@
// recherche de l'utilisateur
WikittyQuery criteria = new WikittyQueryMaker()
.eq(WikittyUser.FQ_FIELD_WIKITTYUSER_LOGIN, login).end();
- String userId = getDelegate().findByQuery(null,
- Collections.singletonList(criteria)).get(0);
+ String userId = getAnonymousClient().findByQuery(criteria);
if (userId == null) {
if (log.isDebugEnabled()) {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationAbstract.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationAbstract.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationAbstract.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,7 +25,6 @@
package org.nuiton.wikitty.services;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -105,8 +104,7 @@
.end()
.setLimit(1);
- String tokenId = getDelegate().findByQuery(
- null, Collections.singletonList(query)).get(0);
+ String tokenId = getAnonymousClient().findByQuery(query);
// on a retrouve un ancien token, on le reutilise peut-etre
if (tokenId != null) {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationLDAP.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationLDAP.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthenticationLDAP.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -120,8 +120,7 @@
WikittyQuery criteria = new WikittyQueryMaker()
.eq(WikittyUser.FQ_FIELD_WIKITTYUSER_LOGIN, login).end();
- String userId = getDelegate().findByQuery(null,
- Collections.singletonList(criteria)).get(0);
+ String userId = getAnonymousClient().findByQuery(criteria);
boolean authenticated = false;
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -28,6 +28,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
@@ -208,7 +209,7 @@
* @return
*/
@Override
- public List<WikittyQueryResult<String>> findAllByQuery(
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQuery(
String securityToken, List<WikittyQuery> queries) {
List<WikittyQuery> qs = new ArrayList<WikittyQuery>(queries.size());
for (WikittyQuery q : queries) {
@@ -230,7 +231,7 @@
* @return
*/
@Override
- public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) {
+ public List<Map<String, Object>> findByQuery(String securityToken, List<WikittyQuery> queries) {
List<WikittyQuery> qs = new ArrayList<WikittyQuery>(queries.size());
for (WikittyQuery q : queries) {
if (q != null && q.isCheckAuthorisation()) {
@@ -805,8 +806,7 @@
WikittyQuery criteria = new WikittyQueryMaker()
.eq(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME,
WikittySecurityHelper.WIKITTY_APPADMIN_GROUP_NAME).end();
- String groupId = getDelegate().findByQuery(
- securityToken, Collections.singletonList(criteria)).get(0);
+ String groupId = getClient(securityToken).findByQuery(criteria);
appAdminGroupId = groupId;
group = WikittyServiceEnhanced.restore(
getDelegate(), securityToken, appAdminGroupId);
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 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceDelegator.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,8 +24,11 @@
*/
package org.nuiton.wikitty.services;
+import java.io.Serializable;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import org.nuiton.wikitty.WikittyClient;
import org.nuiton.wikitty.search.Criteria;
import org.nuiton.wikitty.search.PagedResult;
import org.nuiton.wikitty.entities.Wikitty;
@@ -54,6 +57,7 @@
/** Delegated wikitty service. */
protected WikittyService delegate;
+ protected WikittyClient anonymousClient;
public WikittyServiceDelegator() {
}
@@ -71,6 +75,17 @@
return delegate;
}
+ public WikittyClient getAnonymousClient() {
+ if (anonymousClient == null) {
+ anonymousClient = new WikittyClient(null, delegate);
+ }
+ return anonymousClient;
+ }
+
+ public WikittyClient getClient(String token) {
+ return new WikittyClient(null, delegate, token);
+ }
+
/**
* Set delegated service.
*
@@ -186,13 +201,13 @@
}
@Override
- public List<WikittyQueryResult<String>> findAllByQuery(
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQuery(
String securityToken, List<WikittyQuery> queries) {
return delegate.findAllByQuery(securityToken, queries);
}
@Override
- public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) {
+ public List<Map<String, Object>> findByQuery(String securityToken, List<WikittyQuery> queries) {
return delegate.findByQuery(securityToken, queries);
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -35,6 +35,7 @@
import org.nuiton.util.ApplicationConfig;
import org.nuiton.wikitty.ScriptEvaluator;
import org.nuiton.wikitty.WikittyService;
+import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.entities.WikittyExtension;
import org.nuiton.wikitty.entities.WikittyHook;
@@ -97,8 +98,7 @@
.exteq(WikittyHook.EXT_WIKITTYHOOK)
.eq(WikittyHook.FQ_FIELD_WIKITTYHOOK_ACTIONTOHOOK, actionName)
.end();
- WikittyQueryResult<String> ids = getDelegate().findAllByQuery(securityToken,
- Collections.singletonList(query)).get(0);
+ WikittyQueryResult<String> ids = getClient(securityToken).findAllByQuery(query);
List<Wikitty> result = getDelegate().restore(securityToken, ids.getAll());
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,8 +24,6 @@
*/
package org.nuiton.wikitty.services;
-import static org.nuiton.i18n.I18n._;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -35,12 +33,13 @@
import java.util.Set;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.util.ApplicationConfig;
import org.nuiton.util.TimeLog;
import org.nuiton.wikitty.WikittyConfigOption;
+import org.nuiton.wikitty.WikittyService;
+import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.entities.WikittyAuthorisation;
import org.nuiton.wikitty.entities.WikittyAuthorisationHelper;
@@ -49,15 +48,15 @@
import org.nuiton.wikitty.entities.WikittyGroupHelper;
import org.nuiton.wikitty.entities.WikittyImpl;
import org.nuiton.wikitty.entities.WikittyMetaExtensionUtil;
-import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.entities.WikittyTokenHelper;
import org.nuiton.wikitty.entities.WikittyTreeNode;
import org.nuiton.wikitty.entities.WikittyUser;
import org.nuiton.wikitty.entities.WikittyUserHelper;
-import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryMaker;
+import static org.nuiton.i18n.I18n._;
+
/**
*
* FIXME add security policy level two on wikittyAuthorisation to prevent writing
@@ -127,8 +126,7 @@
WikittyQuery criteria = new WikittyQueryMaker()
.eq(WikittyUser.FQ_FIELD_WIKITTYUSER_LOGIN, login).end();
- String userId = getDelegate().findByQuery(null,
- Collections.singletonList(criteria)).get(0);
+ String userId = getAnonymousClient().findByQuery(String.class, criteria);
boolean authenticated = false;
if (auth != null) {
@@ -831,8 +829,7 @@
WikittyQuery criteria = new WikittyQueryMaker()
.eq(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME,
WikittySecurityHelper.WIKITTY_APPADMIN_GROUP_NAME).end();
- String groupId = getDelegate().findByQuery(
- securityToken, Collections.singletonList(criteria)).get(0);
+ String groupId = getClient(securityToken).findByQuery(criteria);
appAdminGroupId = groupId;
group = WikittyServiceEnhanced.restore(
getDelegate(), securityToken, appAdminGroupId);
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 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,47 +25,43 @@
package org.nuiton.wikitty.services;
-import org.nuiton.wikitty.storage.WikittyExtensionStorage;
-import org.nuiton.wikitty.storage.WikittySearchEngine;
-import org.nuiton.wikitty.storage.WikittyStorage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.regex.Pattern;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.util.ApplicationConfig;
import org.nuiton.util.TimeLog;
-import org.nuiton.wikitty.search.Criteria;
+import org.nuiton.wikitty.WikittyException;
+import org.nuiton.wikitty.WikittyService;
+import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.entities.FieldType;
-import org.nuiton.wikitty.search.PagedResult;
+import org.nuiton.wikitty.entities.FieldTypeConstaintChecker;
import org.nuiton.wikitty.entities.Wikitty;
-import org.nuiton.wikitty.WikittyException;
import org.nuiton.wikitty.entities.WikittyExtension;
-import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.entities.WikittyTreeNode;
import org.nuiton.wikitty.entities.WikittyTreeNodeHelper;
-import org.nuiton.wikitty.WikittyUtil;
-import org.nuiton.wikitty.entities.FieldTypeConstaintChecker;
-import org.nuiton.wikitty.entities.WikittyTypes;
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.Criteria;
+import org.nuiton.wikitty.search.PagedResult;
import org.nuiton.wikitty.search.Search;
import org.nuiton.wikitty.search.TreeNodeResult;
-import org.nuiton.wikitty.search.operators.Element;
+import org.nuiton.wikitty.storage.WikittyExtensionStorage;
+import org.nuiton.wikitty.storage.WikittySearchEngine;
+import org.nuiton.wikitty.storage.WikittyStorage;
/**
* WikittyService is main service
@@ -405,7 +401,7 @@
// only name are stored in index, search only on name
WikittyQuery query = new WikittyQueryMaker().exteq(name).end();
query.setLimit(0); // result is not use, just numFound
- WikittyQueryResult<String> wikittyWithExt = findAllByQuery(
+ WikittyQueryResult<Map<String, Object>> wikittyWithExt = findAllByQuery(
securityToken, Collections.singletonList(query)).get(0);
int numFound = wikittyWithExt.getTotalResult();
if (numFound > 0) {
@@ -766,7 +762,7 @@
FQ_FIELD_WIKITTYTREENODE_PARENT, id).end();
List<String> wikittyNodesId = findAllByQuery(
securityToken, Collections.singletonList(query))
- .get(0).getAll();
+ .get(0).convertMapToSimpleString().getAll();
for (String wikittyNodeId : wikittyNodesId) {
if (!idSet.contains(wikittyNodeId)) {
Wikitty treeNode = restore(
@@ -781,7 +777,7 @@
FQ_FIELD_WIKITTYTREENODE_ATTACHMENT, id).end();
wikittyNodesId = findAllByQuery(
securityToken, Collections.singletonList(query))
- .get(0).getAll();
+ .get(0).convertMapToSimpleString().getAll();
for (String wikittyNodeId : wikittyNodesId) {
if (!idSet.contains(wikittyNodeId)) {
Wikitty treeNode = restore(
@@ -965,7 +961,7 @@
* return new PagedResult with Wikitty instance
*/
@Override
- public List<WikittyQueryResult<String>> findAllByQuery(
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQuery(
String securityToken, List<WikittyQuery> queries) {
WikittyTransaction tx = WikittyTransaction.get();
boolean txBeginHere = false;
@@ -975,14 +971,14 @@
txBeginHere = true;
}
- List<WikittyQueryResult<String>> result =
- new ArrayList<WikittyQueryResult<String>>(queries.size());
+ List<WikittyQueryResult<Map<String, Object>>> result =
+ new ArrayList<WikittyQueryResult<Map<String, Object>>>(queries.size());
for (WikittyQuery c : queries) {
if (c == null) {
result.add(null);
} else {
long startTime = System.nanoTime();
- WikittyQueryResult<String> searchResult =
+ WikittyQueryResult<Map<String, Object>> searchResult =
getSearchEngine().findAllByQuery(tx, c);
long estimatedTime = System.nanoTime() - startTime;
searchResult.setTimeQuery(estimatedTime);
@@ -1013,7 +1009,7 @@
}
@Override
- public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) {
+ public List<Map<String, Object>> findByQuery(String securityToken, List<WikittyQuery> queries) {
WikittyTransaction tx = WikittyTransaction.get();
boolean txBeginHere = false;
try {
@@ -1022,17 +1018,17 @@
txBeginHere = true;
}
- List<String> result = new ArrayList<String>(queries.size());
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(queries.size());
List<WikittyQuery> queriesLimited = new ArrayList<WikittyQuery>(queries.size());
for (WikittyQuery c : queries) {
- WikittyQuery cLimit = c.copy().setFirst(0).setLimit(1);
+ WikittyQuery cLimit = c.copy().setOffset(0).setLimit(1);
queriesLimited.add(cLimit);
}
- List<WikittyQueryResult<String>> idsList =
+ List<WikittyQueryResult<Map<String, Object>>> idsList =
findAllByQuery(securityToken, queriesLimited);
- for (WikittyQueryResult<String> ids : idsList) {
+ for (WikittyQueryResult<Map<String, Object>> ids : idsList) {
if (ids.size() > 0) {
result.add(ids.peek());
} else {
@@ -1106,10 +1102,10 @@
.eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, treeNodeId).end();
WikittyQueryResult<String> childTreeNodeIds = findAllByQuery(
- securityToken, Collections.singletonList(query)).get(0);
+ securityToken, Collections.singletonList(query)).get(0).convertMapToSimpleString();
List<String> treeNodeIds = new ArrayList<String>();
treeNodeIds.add(treeNodeId);
- for (String childTreeNodeId : childTreeNodeIds.getAll()) {
+ for (String childTreeNodeId : childTreeNodeIds) {
List<String> subTreeNodeIds = getRecursiveTreeNodeId(securityToken, childTreeNodeId);
treeNodeIds.addAll(subTreeNodeIds);
}
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 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceTransaction.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,6 +25,7 @@
package org.nuiton.wikitty.services;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -44,6 +45,7 @@
import org.nuiton.wikitty.entities.WikittyExtension;
import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.WikittyServiceFactory;
+import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryResult;
import org.nuiton.wikitty.query.WikittyQueryResultTreeNode;
@@ -390,44 +392,50 @@
throw new UnsupportedOperationException("Not supported yet.");
}
+ // FIXME poussin 20130218 a revoir car, lorsqu'elle a ete implanter, on ne retournait que des ids. Il est maintenantes possible de retourner des Maps
@Override
- public List<WikittyQueryResult<String>> findAllByQuery(
+ public List<WikittyQueryResult<Map<String, Object>>> findAllByQuery(
String securityToken, List<WikittyQuery> queries) {
- List<WikittyQueryResult<String>> resultTxList =
+ List<WikittyQueryResult<Map<String, Object>>> resultTxList =
tx.findAllByQuery(securityToken, queries);
- List<WikittyQueryResult<String>> resultWsList =
+ List<WikittyQueryResult<Map<String, Object>>> resultWsList =
ws.findAllByQuery(securityToken, queries);
- List<WikittyQueryResult<String>> result =
- new ArrayList<WikittyQueryResult<String>>(resultWsList.size());
+ List<WikittyQueryResult<Map<String, Object>>> result =
+ new ArrayList<WikittyQueryResult<Map<String, Object>>>(resultWsList.size());
for (int i=0; i<queries.size(); i++) {
- WikittyQueryResult<String> resultTx = resultTxList.get(i);
- WikittyQueryResult<String> resultWs = resultWsList.get(i);
+ WikittyQueryResult<Map<String, Object>> resultTx = resultTxList.get(i);
+ WikittyQueryResult<Map<String, Object>> resultWs = resultWsList.get(i);
// Il faut fusionner les deux resultats
// - ne pas avoir de doublon
// - ne pas retenir ceux supprimer dans la transaction
+ // en respectant l'ordre de tri demande (comment faire?)
// - 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());
+ LinkedHashSet<Map<String, Object>> ids =
+ new LinkedHashSet<Map<String, Object>>(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);
+ for (Map<String, Object> map : resultWs.getAll()) {
+ String id = (String)map.get(Element.ID.getValue());
+ if ((!tx.exists(securityToken, id) || !tx.isDeleted(securityToken, id))) {
+ ids.add(map);
+ } else {
+ // pas un id, donc on ne sais pas encore comment faire :(. On l'ajoute
+ ids.add(map);
}
}
String queryName = resultWs.getQueryName();
- int firstIndice = resultWs.getFirst();
+ int firstIndice = resultWs.getOffset();
// 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);
+ List<Map<String, Object>> results = new ArrayList<Map<String, Object>>(ids);
long timeQuery = resultTx.getTimeQuery() + resultWs.getTimeQuery();
- result.add(new WikittyQueryResult<String>(queryName,
+ result.add(new WikittyQueryResult<Map<String, Object>>(queryName,
firstIndice, numFound, queryString, facets, results, timeQuery, 0));
}
@@ -440,18 +448,18 @@
}
@Override
- public List<String> findByQuery(String securityToken, List<WikittyQuery> queries) {
- List<String> result = new ArrayList<String>(queries.size());
+ public List<Map<String, Object>> findByQuery(String securityToken, List<WikittyQuery> queries) {
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(queries.size());
List<WikittyQuery> queriesLimited = new ArrayList<WikittyQuery>(queries.size());
for (WikittyQuery c : queries) {
- WikittyQuery climit = c.copy().setFirst(0).setLimit(1);
+ WikittyQuery climit = c.copy().setOffset(0).setLimit(1);
queriesLimited.add(climit);
}
- List<WikittyQueryResult<String>> idsList = findAllByQuery(
+ List<WikittyQueryResult<Map<String, Object>>> idsList = findAllByQuery(
securityToken, queriesLimited);
- for (WikittyQueryResult<String> ids : idsList) {
+ for (WikittyQueryResult<Map<String, Object>> ids : idsList) {
if (ids.size() > 0) {
result.add(ids.peek());
} else {
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 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngine.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -25,7 +25,9 @@
package org.nuiton.wikitty.storage;
+import java.io.Serializable;
import java.util.Collection;
+import java.util.Map;
import org.nuiton.wikitty.search.Criteria;
import org.nuiton.wikitty.search.PagedResult;
import org.nuiton.wikitty.entities.Wikitty;
@@ -82,14 +84,16 @@
* Find all values that satisfy queries constraint. Values is Wikitty's id
* if there is no Select condition, otherwize is String that represent
* field value and can be String representation of
- * Wikitty, Date, Boolean, Numeric, Binary, String
+ * Wikitty, Date, Boolean, Numeric, Binary, String.
+ * Or TODO (map? array?)
*
* @param transaction
* @param queries
* @return id of wikitties
* @since 3.3
*/
- public WikittyQueryResult<String> findAllByQuery(WikittyTransaction transaction, WikittyQuery queries);
+ public WikittyQueryResult<Map<String, Object>> findAllByQuery(
+ WikittyTransaction transaction, WikittyQuery queries);
/**
* Find all children ids with attachment count for a node wikitty.
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -24,15 +24,19 @@
*/
package org.nuiton.wikitty.storage;
+import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
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.WikittyUtil;
+import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.entities.WikittyExtension;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
import org.nuiton.wikitty.query.FacetSortType;
import org.nuiton.wikitty.query.FacetTopic;
import org.nuiton.wikitty.query.WikittyQuery;
@@ -57,178 +61,179 @@
/** to use log facility, just put in your code: log.info(\"...\"); */
static private Log log = LogFactory.getLog(WikittySearchEngineHelper.class);
- /**
- * Gere le travail pour les requetes ayant un {@link Select}
- *
- * @param searchEngine le searchEngine a utiliser pour les sous requetes
- * @param transaction la transaction a utiliser
- * @param query la requete qui debute par un {@link Select}
- * @return
- */
- static public WikittyQueryResult<String> findAllByQueryWithSelect(
- WikittySearchEngine searchEngine, WikittyTransaction transaction,
- WikittyQuery query) {
+// /**
+// * Gere le travail pour les requetes ayant un {@link Select}
+// *
+// * @param searchEngine le searchEngine a utiliser pour les sous requetes
+// * @param transaction la transaction a utiliser
+// * @param query la requete qui debute par un {@link Select}
+// * @return
+// */
+// static public WikittyQueryResult<String> findAllByQueryWithSelectOLD(
+// WikittySearchEngine searchEngine, WikittyTransaction transaction,
+// WikittyQuery query) {
+//
+// if (!(query.getCondition() instanceof Select)) {
+// throw new WikittyException("Query don't start with Select condition");
+// } else {
+// // gere les conditions qui commence par select
+// // il faut recreer deux query, une pour le select, une pour les facettes s'il y en a
+// // car le select est execute via une facette, mais cette facette
+// // n'a pas les meme limites que les autres facette
+//
+// Select select = (Select)query.getCondition();
+// boolean isAggregate = select.getAggregate() != null;
+// boolean isDistinct = select.isDistinct();
+//
+// Condition newCond;
+// if(WikittyExtension.isFqField(select.getElement().getValue())) {
+// String extName = WikittyExtension.extractExtensionName(
+// select.getElement().getValue());
+// newCond = new WikittyQueryMaker()
+// .and()
+// .exteq(extName)
+// .condition(select.getSubCondition())
+// .getCondition();
+// } else {
+// newCond = select.getSubCondition();
+// }
+//
+// // copy de la query pour les facettes
+// WikittyQuery queryFacet = query.copy();
+// queryFacet.setCondition(newCond);
+// queryFacet.setLimit(0);
+//
+// // copy de la query pour le select
+// // on part de facet qui a deja la bonne condition
+// WikittyQuery querySelect = queryFacet.copy();
+// querySelect.setLimit(0);
+// // ne surtout pas mettre 0, sinon toutes les valeurs possibles sont
+// // retournee pas seulement celle qui satisfont la contrainte
+// querySelect.setFacetMinCount(1);
+// querySelect.setFacetLimit(Integer.MAX_VALUE);
+// // on force le sort pour toujours utiliser le meme
+// querySelect.setFacetSort(FacetSortType.name);
+// // on supprime toutes les facettes, et on ajoute la notre
+// querySelect.setFacetQuery();
+// querySelect.setFacetField(select.getElement());
+//
+// // execution des requetes
+// WikittyQueryResult<String> resultFacet =
+// searchEngine.findAllByQuery(transaction, queryFacet);
+// WikittyQueryResult<String> resultSelect =
+// searchEngine.findAllByQuery(transaction, querySelect);
+//
+// // creation des resultats via la facette select
+// List<FacetTopic> topics = resultSelect.getFacets().get(select.getElement().getValue());
+//
+// List<String> selectList = new ArrayList<String>(topics.size());
+// for (FacetTopic topic : topics) {
+// if (isDistinct) {
+// selectList.add(topic.getTopicName());
+// } else {
+// // on ajoute la valeur le nombre de fois qu'il y a de count dans la facette
+// for (int i=0, max=topic.getCount(); i<max; i++) {
+// selectList.add(topic.getTopicName());
+// }
+// }
+// }
+//
+// boolean sortDesc = query.getSortDescending().contains(select.getElement());
+// // tri selon l'ordre demande
+// if (sortDesc) {
+// // par defaut la facette est deja trie par ordre alphabetique
+// // donc il n'y a qu'a l'inverser pour avoir l'ordre inverse
+// Collections.reverse(selectList);
+// }
+//
+// // on ne garde que ce qui est demande
+// int offset = query.getOffset();
+// int limit = query.getLimit();
+// if (limit == Integer.MAX_VALUE) {
+// // WARNING It is necessary to substract 'offset' otherwise,
+// // there is a capacity overlow
+// limit = Integer.MAX_VALUE - offset;
+// }
+// int first = Math.min(selectList.size(), offset);
+// int last = Math.min(selectList.size(), offset + limit);
+// selectList = selectList.subList(first, last);
+//
+//
+//
+// // gestion des agregats
+// if (isAggregate) {
+// switch(select.getAggregate()) {
+// case AVG: {
+// // convert all to number
+// BigDecimal result = new BigDecimal(0);
+// for (String s : selectList) {
+// BigDecimal v = WikittyUtil.toBigDecimal(s);
+// result = result.add(v);
+// }
+// result = result.divide(new BigDecimal(selectList.size()));
+// selectList = new ArrayList<String>();
+// selectList.add(WikittyUtil.toString(result));
+// }
+// break;
+// case COUNT: {
+// // convert all to number
+// BigDecimal result = new BigDecimal(selectList.size());
+// selectList = new ArrayList<String>();
+// selectList.add(WikittyUtil.toString(result));
+// }
+// break;
+// case MAX: {
+// if (!selectList.isEmpty()) {
+// String result;
+// if (sortDesc) {
+// result = selectList.get(0);
+// } else {
+// result = selectList.get(selectList.size()-1);
+// }
+// selectList = new ArrayList<String>();
+// selectList.add(WikittyUtil.toString(result));
+// }
+// }
+// break;
+// case MIN: {
+// if (!selectList.isEmpty()) {
+// String result;
+// if (sortDesc) {
+// result = selectList.get(selectList.size()-1);
+// } else {
+// result = selectList.get(0);
+// }
+// selectList = new ArrayList<String>();
+// selectList.add(WikittyUtil.toString(result));
+// }
+// }
+// break;
+// case SUM: {
+// // convert all to number
+// BigDecimal result = new BigDecimal(0);
+// for (String s : selectList) {
+// BigDecimal v = WikittyUtil.toBigDecimal(s);
+// result = result.add(v);
+// }
+// selectList = new ArrayList<String>();
+// selectList.add(WikittyUtil.toString(result));
+// }
+// break;
+// }
+// }
+//
+// // fusion des resultats
+// WikittyQueryResult<String> result = new WikittyQueryResult<String>(
+// query.getName(),
+// query.getOffset(),
+// topics.size(),
+// resultSelect.getQueryString(),
+// resultFacet.getFacets(),
+// selectList,
+// 0, 0);
+//
+// return result;
+// }
+// }
- if (!(query.getCondition() instanceof Select)) {
- throw new WikittyException("Query don't start with Select condition");
- } else {
- // gere les conditions qui commence par select
- // il faut recreer deux query, une pour le select, une pour les facettes s'il y en a
- // car le select est execute via une facette, mais cette facette
- // n'a pas les meme limites que les autres facette
-
- Select select = (Select)query.getCondition();
- boolean isAggregate = select.getAggregate() != null;
- boolean isDistinct = select.isDistinct();
-
- Condition newCond;
- if(WikittyExtension.isFqField(select.getElement().getValue())) {
- String extName = WikittyExtension.extractExtensionName(
- select.getElement().getValue());
- newCond = new WikittyQueryMaker()
- .and()
- .exteq(extName)
- .condition(select.getSubCondition())
- .getCondition();
- } else {
- newCond = select.getSubCondition();
- }
-
- // copy de la query pour les facettes
- WikittyQuery queryFacet = query.copy();
- queryFacet.setCondition(newCond);
- queryFacet.setLimit(0);
-
- // copy de la query pour le select
- // on part de facet qui a deja la bonne condition
- WikittyQuery querySelect = queryFacet.copy();
- querySelect.setLimit(0);
- // ne surtout pas mettre 0, sinon toutes les valeurs possibles sont
- // retournee pas seulement celle qui satisfont la contrainte
- querySelect.setFacetMinCount(1);
- querySelect.setFacetLimit(Integer.MAX_VALUE);
- // on force le sort pour toujours utiliser le meme
- querySelect.setFacetSort(FacetSortType.name);
- // on supprime toutes les facettes, et on ajoute la notre
- querySelect.setFacetQuery();
- querySelect.setFacetField(select.getElement());
-
- // execution des requetes
- WikittyQueryResult<String> resultFacet =
- searchEngine.findAllByQuery(transaction, queryFacet);
- WikittyQueryResult<String> resultSelect =
- searchEngine.findAllByQuery(transaction, querySelect);
-
- // creation des resultats via la facette select
- List<FacetTopic> topics = resultSelect.getFacets().get(select.getElement().getValue());
-
- List<String> selectList = new ArrayList<String>(topics.size());
- for (FacetTopic topic : topics) {
- if (isDistinct) {
- selectList.add(topic.getTopicName());
- } else {
- // on ajoute la valeur le nombre de fois qu'il y a de count dans la facette
- for (int i=0, max=topic.getCount(); i<max; i++) {
- selectList.add(topic.getTopicName());
- }
- }
- }
-
- boolean sortDesc = query.getSortDescending().contains(select.getElement());
- // tri selon l'ordre demande
- if (sortDesc) {
- // par defaut la facette est deja trie par ordre alphabetique
- // donc il n'y a qu'a l'inverser pour avoir l'ordre inverse
- Collections.reverse(selectList);
- }
-
- // on ne garde que ce qui est demande
- int offset = query.getOffset();
- int limit = query.getLimit();
- if (limit == Integer.MAX_VALUE) {
- // WARNING It is necessary to substract 'offset' otherwise,
- // there is a capacity overlow
- limit = Integer.MAX_VALUE - offset;
- }
- int first = Math.min(selectList.size(), offset);
- int last = Math.min(selectList.size(), offset + limit);
- selectList = selectList.subList(first, last);
-
-
-
- // gestion des agregats
- if (isAggregate) {
- switch(select.getAggregate()) {
- case AVG: {
- // convert all to number
- BigDecimal result = new BigDecimal(0);
- for (String s : selectList) {
- BigDecimal v = WikittyUtil.toBigDecimal(s);
- result = result.add(v);
- }
- result = result.divide(new BigDecimal(selectList.size()));
- selectList = new ArrayList<String>();
- selectList.add(WikittyUtil.toString(result));
- }
- break;
- case COUNT: {
- // convert all to number
- BigDecimal result = new BigDecimal(selectList.size());
- selectList = new ArrayList<String>();
- selectList.add(WikittyUtil.toString(result));
- }
- break;
- case MAX: {
- if (!selectList.isEmpty()) {
- String result;
- if (sortDesc) {
- result = selectList.get(0);
- } else {
- result = selectList.get(selectList.size()-1);
- }
- selectList = new ArrayList<String>();
- selectList.add(WikittyUtil.toString(result));
- }
- }
- break;
- case MIN: {
- if (!selectList.isEmpty()) {
- String result;
- if (sortDesc) {
- result = selectList.get(selectList.size()-1);
- } else {
- result = selectList.get(0);
- }
- selectList = new ArrayList<String>();
- selectList.add(WikittyUtil.toString(result));
- }
- }
- break;
- case SUM: {
- // convert all to number
- BigDecimal result = new BigDecimal(0);
- for (String s : selectList) {
- BigDecimal v = WikittyUtil.toBigDecimal(s);
- result = result.add(v);
- }
- selectList = new ArrayList<String>();
- selectList.add(WikittyUtil.toString(result));
- }
- break;
- }
- }
-
- // fusion des resultats
- WikittyQueryResult<String> result = new WikittyQueryResult<String>(
- query.getName(),
- query.getOffset(),
- topics.size(),
- resultSelect.getQueryString(),
- resultFacet.getFacets(),
- selectList,
- 0, 0);
-
- return result;
- }
- }
}
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 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemory.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -26,6 +26,7 @@
import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultiset;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -34,6 +35,7 @@
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
@@ -79,6 +81,8 @@
import org.nuiton.wikitty.query.conditions.NotNull;
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
import org.nuiton.wikitty.search.Criteria;
import org.nuiton.wikitty.search.PagedResult;
import org.nuiton.wikitty.search.TreeNodeResult;
@@ -315,48 +319,80 @@
}
@Override
- public WikittyQueryResult<String> findAllByQuery(WikittyTransaction transaction, WikittyQuery query) {
- WikittyQueryResult<String> result;
+ public WikittyQueryResult<Map<String, Object>> findAllByQuery(WikittyTransaction transaction, WikittyQuery query) {
+ // la condition select du query, sera traite a la fin
+ Select select = null;
+ WikittyQuery queryWithoutSelect = query;
+
if (query.getCondition() instanceof Select) {
- result = WikittySearchEngineHelper.findAllByQueryWithSelect(
- this, transaction, query);
- } else {
- int offset = query.getOffset();
- int limit = query.getLimit();
- List<String> ids = new LinkedList<String>();
- FacetPredicate facets = new FacetPredicate(this, transaction, query);
+ select = (Select)query.getCondition();
+ Condition newCond = select.getSubCondition();
+ if (newCond == null) {
+ newCond = new org.nuiton.wikitty.query.conditions.True();
+ }
- ArrayList<Wikitty> wikitties =
- new ArrayList<Wikitty>(wikittyStorage.getWikitties().values());
+ // copy de la query sans le select
+ queryWithoutSelect = query.copy();
+ queryWithoutSelect.setCondition(newCond);
+ }
- // on tri les wikitties selon l'ordre demande ...
- if (!query.getSortAscending().isEmpty()
- || !query.getSortDescending().isEmpty() ) {
- Collections.sort(wikitties, new WikittyComparator(
- query.getSortAscending(), query.getSortDescending()));
- }
- int totalResult = 0;
- for (Wikitty w : wikitties) {
- String id = w.getWikittyId();
- Condition c = query.getCondition();
- if (!w.isDeleted()) {
- if (checkRestriction(this, transaction, c, w)) {
- totalResult++;
- if (totalResult > offset && ids.size() < limit) {
- // ajout en tant que resultat
- ids.add(id);
- }
- facets.add(w);
+
+ int offset = queryWithoutSelect.getOffset();
+ int limit = queryWithoutSelect.getLimit();
+ List<String> ids = new LinkedList<String>();
+ FacetPredicate facets = new FacetPredicate(this, transaction, queryWithoutSelect);
+
+ ArrayList<Wikitty> wikitties =
+ new ArrayList<Wikitty>(wikittyStorage.getWikitties().values());
+
+ // on tri les wikitties selon l'ordre demande ...
+ if (!queryWithoutSelect.getSortAscending().isEmpty()
+ || !queryWithoutSelect.getSortDescending().isEmpty() ) {
+ Collections.sort(wikitties, new WikittyComparator(
+ queryWithoutSelect.getSortAscending(), queryWithoutSelect.getSortDescending()));
+ }
+
+ int totalResult = 0;
+ for (Wikitty w : wikitties) {
+ String id = w.getWikittyId();
+ Condition c = queryWithoutSelect.getCondition();
+ if (!w.isDeleted()) {
+ if (checkRestriction(this, transaction, c, w)) {
+ totalResult++;
+ if (totalResult > offset && ids.size() < limit) {
+ // ajout en tant que resultat
+ ids.add(id);
}
+ facets.add(w);
}
}
+ }
- result = new WikittyQueryResult<String>(query.getName(),
- offset, totalResult, query.getCondition().toString(),
- facets.getFacets(), ids, 0, 0);
+ List<Map<String, Object>> values = new ArrayList<Map<String, Object>>(ids.size());
+ if (select == null) {
+ String idTag = org.nuiton.wikitty.entities.Element.ID.getValue();
+ for (Object id : ids) {
+ values.add(Collections.singletonMap(idTag, id));
+ }
+ } else {
+ // Extract data
+ for (String id : ids) {
+ Wikitty w = wikittyStorage.getWikitties().get(id);
+ Map<String, Object> map = new LinkedHashMap<String, Object>(w.getFieldValue());
+ map.put(org.nuiton.wikitty.entities.Element.ID.getValue(), id);
+ values.add(map);
+ }
+
+ values = select.getFunction().call(this, transaction, query, values);
}
+
+
+ WikittyQueryResult<Map<String, Object>> result = new WikittyQueryResult<Map<String, Object>>(queryWithoutSelect.getName(),
+ offset, totalResult, queryWithoutSelect.getCondition().toString(),
+ facets.getFacets(), values, 0, 0);
+
return result;
}
@@ -944,6 +980,13 @@
}
@Override
+ public boolean visitMiddle(Select o) {
+ // do nothing
+ return true;
+ }
+
+
+ @Override
public void visitLeave(Select o, boolean enterOrMiddleResult) {
// do nothing
}
@@ -962,7 +1005,7 @@
WikittyQuery query = new WikittyQuery(o);
// eval select
WikittyQueryResult<String> selectResult =
- searchEngine.findAllByQuery(tx, query);
+ searchEngine.findAllByQuery(tx, query).convertMapToSimpleString();
result.addAll(selectResult.getAll());
} else if (o instanceof ConditionValueString) {
result.add(((ConditionValueString)o).getValue());
@@ -980,7 +1023,7 @@
WikittyQuery query = new WikittyQuery(o);
// eval select
WikittyQueryResult<String> selectResult =
- searchEngine.findAllByQuery(tx, query);
+ searchEngine.findAllByQuery(tx, query).convertMapToSimpleString();
if (selectResult.size() == 0) {
throw new WikittyException(String.format(
"Select return no result query was '%s' transformed to '%s'",
@@ -1274,6 +1317,28 @@
}
@Override
+ public boolean visitEnter(WikittyQueryFunction function) {
+ // do nothing
+ return true;
+ }
+
+ @Override
+ public boolean visitMiddle(WikittyQueryFunction function) {
+ // do nothing
+ return true;
+ }
+
+ @Override
+ public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult) {
+ // do nothing
+ }
+
+ @Override
+ public void visit(FunctionValue function) {
+ // do nothing
+ }
+
+ @Override
public void defaultVisit(Object o) {
throw new UnsupportedOperationException("Not supported yet.");
}
Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java
===================================================================
--- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -69,7 +69,12 @@
import org.nuiton.wikitty.query.WikittyQueryParser;
import org.nuiton.wikitty.query.WikittyQueryResult;
import org.nuiton.wikitty.query.WikittyQueryResultTreeNode;
-import org.nuiton.wikitty.query.conditions.Aggregate;
+import org.nuiton.wikitty.query.function.FunctionAvg;
+import org.nuiton.wikitty.query.function.FunctionCount;
+import org.nuiton.wikitty.query.function.FunctionFieldValue;
+import org.nuiton.wikitty.query.function.FunctionMax;
+import org.nuiton.wikitty.query.function.FunctionMin;
+import org.nuiton.wikitty.query.function.FunctionSum;
import org.nuiton.wikitty.services.WikittyEvent;
import org.nuiton.wikitty.test.CatalogNode;
import org.nuiton.wikitty.test.Category;
@@ -1695,8 +1700,7 @@
query1.setOffset(0);
query1.setLimit(2);
WikittyQueryResult<Double> results1 = wikittyClient.findAllByQuery(Double.class, query1);
- // 17 books, but only 11 differents prices ?
- Assert.assertEquals(11, results1.getTotalResult());
+ Assert.assertEquals(17, results1.getTotalResult());
Assert.assertEquals(2, results1.getAll().size());
Assert.assertEquals(Double.valueOf(13), results1.get(0));
@@ -1712,7 +1716,7 @@
query1.setOffset(0);
query1.setLimit(0);
results1 = wikittyClient.findAllByQuery(Double.class, query1);
- Assert.assertEquals(11, results1.getTotalResult());
+ Assert.assertEquals(17, results1.getTotalResult());
Assert.assertEquals(0, results1.getAll().size());
}
@@ -1773,45 +1777,45 @@
// test aggregate
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.AVG).end();
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionAvg(null, new FunctionFieldValue(null, "Test.number"))).end();
WikittyQueryResult<String> result = wikittyClient.findAllByQuery(q);
System.out.println("q: " + result);
Assert.assertEquals("3", result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.COUNT).end();
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionCount(null, new FunctionFieldValue(null, "Test.number"))).end();
WikittyQueryResult<String> result = wikittyClient.findAllByQuery(q);
System.out.println("q: " + result);
Assert.assertEquals("4", result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.MAX).end();
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionMax(null, new FunctionFieldValue(null, "Test.number"))).end();
WikittyQueryResult<Double> result = wikittyClient.findAllByQuery(Double.class, q);
System.out.println("q: " + result);
Assert.assertEquals(Double.valueOf(10), result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.MAX).end()
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionMax(null, new FunctionFieldValue(null, "Test.number"))).end()
.addSortDescending(new ElementField("Test", "number"));
WikittyQueryResult<Double> result = wikittyClient.findAllByQuery(Double.class, q);
System.out.println("q: " + result);
Assert.assertEquals(Double.valueOf(10), result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.MIN).end();
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionMin(null, new FunctionFieldValue(null, "Test.number"))).end();
WikittyQueryResult<Double> result = wikittyClient.findAllByQuery(Double.class, q);
System.out.println("q: " + result);
Assert.assertEquals(Double.valueOf(-4.0), result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.MIN).end()
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionMin(null, new FunctionFieldValue(null, "Test.number"))).end()
.addSortDescending(new ElementField("Test", "number"));
WikittyQueryResult<Double> result = wikittyClient.findAllByQuery(Double.class, q);
System.out.println("q: " + result);
Assert.assertEquals(Double.valueOf(-4.0), result.peek());
}
{
- WikittyQuery q = new WikittyQueryMaker().select("Test.number", Aggregate.SUM).end();
+ WikittyQuery q = new WikittyQueryMaker().select(new FunctionSum(null, new FunctionFieldValue(null, "Test.number"))).end();
WikittyQueryResult<Double> result = wikittyClient.findAllByQuery(Double.class, q);
System.out.println("q: " + result);
Assert.assertEquals(Double.valueOf(12), result.peek());
@@ -1973,7 +1977,7 @@
WikittyQueryResult<String> result = wikittyClient.findAllByQuery(query);
System.out.println(result.getAll());
- Assert.assertEquals(2, result.getTotalResult());
+ Assert.assertEquals(2, result.size());
}
{
Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java
===================================================================
--- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/query/WikittyQueryTest.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -50,6 +50,14 @@
@Test
public void testParseAliasAndTree() throws Exception {
WikittyQueryParser parser = new WikittyQueryParser();
+ System.out.println("---------------------------------------------------------------");
+
+ WikittyQueryParser.parse("Select WikittyGroup.name Where WikittyGroup.name=Group*");
+ System.out.println("***************************************************************");
+
+ WikittyQueryParser.parse("Select WikittyGroup.name Where WikittyGroup.name=Group*");
+
+ System.out.println("---------------------------------------------------------------");
parser.addAlias("MyAlias\\((.*), (.*)\\)",
"id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=$1)}"
Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/services/WikittyServiceHelperTest.java
===================================================================
--- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/services/WikittyServiceHelperTest.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/services/WikittyServiceHelperTest.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -53,12 +53,11 @@
@Test
public void testBuild() throws Exception {
- Properties props = new Properties();
- props.setProperty(WikittyConfigOption.WIKITTY_WIKITTYSERVICE_COMPONENTS.getKey(),
+ ApplicationConfig config = WikittyConfig.getConfig();
+ config.setOption(WikittyConfigOption.WIKITTY_WIKITTYSERVICE_COMPONENTS.getKey(),
WikittyServiceInMemory.class.getName() + "," +
WikittyServiceNotifier.class.getName() + "," +
WikittyServiceCached.class.getName());
- ApplicationConfig config = WikittyConfig.getConfig(props);
WikittyService ws = WikittyServiceFactory.buildWikittyService(config);
Assert.assertEquals(WikittyServiceCached.class, ws.getClass());
Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java
===================================================================
--- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/storage/WikittySearchEngineInMemoryTest.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -31,6 +31,7 @@
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Test;
+import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.entities.WikittyGroup;
import org.nuiton.wikitty.entities.WikittyGroupImpl;
@@ -40,7 +41,6 @@
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryMaker;
import org.nuiton.wikitty.query.WikittyQueryResult;
-import org.nuiton.wikitty.entities.Element;
/**
*
@@ -99,7 +99,7 @@
// recherche des labels
WikittyQuery q = new WikittyQueryMaker()
.eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "toutou").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// seul l1 doit etre retrouve
Assert.assertEquals(1, result.size());
Assert.assertEquals(l1.getWikittyId(), result.peek());
@@ -108,7 +108,7 @@
{
// recherche des du keyword 'i'
WikittyQuery q = new WikittyQueryMaker().keyword("i").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// seul l1 doit etre retrouve
Assert.assertEquals(1, result.size());
Assert.assertEquals(l1.getWikittyId(), result.peek());
@@ -117,7 +117,7 @@
{
// recherche des du keyword 'ou'
WikittyQuery q = new WikittyQueryMaker().keyword("ou").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// l1 et g1, g2, g3 doivent etre retrouve
Assert.assertEquals(4, result.size());
Assert.assertTrue(result.getAll().containsAll(Arrays.asList(
@@ -128,7 +128,7 @@
// recherche des du keyword 'ou'
WikittyQuery q = new WikittyQueryMaker()
.and().exteq(WikittyGroup.EXT_WIKITTYGROUP).keyword("ou").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// 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(
@@ -139,7 +139,7 @@
// recherche des labels
WikittyQuery q = new WikittyQueryMaker()
.isNull(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS).end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// seul l2 doit etre retrouve
Assert.assertEquals(1, result.size());
Assert.assertEquals(l2.getWikittyId(), result.peek());
@@ -148,7 +148,7 @@
{
WikittyQuery q = new WikittyQueryMaker()
.like(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, "*P2").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// seul g2 doit etre retrouve
Assert.assertEquals(1, result.size());
Assert.assertEquals(g2.getWikittyId(), result.peek());
@@ -157,7 +157,7 @@
{
WikittyQuery q = new WikittyQueryMaker()
.ew(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, "p2").end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// seul g2 doit etre retrouve
Assert.assertEquals(1, result.size());
Assert.assertEquals(g2.getWikittyId(), result.peek());
@@ -169,7 +169,7 @@
.select(Element.ID)
.eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi")
.end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// g1, g3 doivent etre retrouve via le join
Assert.assertEquals(2, result.size());
Assert.assertTrue(result.getAll().containsAll(Arrays.asList(
@@ -184,7 +184,7 @@
.select(Element.ID)
.eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi")
.end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// 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(
@@ -200,7 +200,7 @@
.select(Element.ID)
.eq(WikittyLabel.FQ_FIELD_WIKITTYLABEL_LABELS, "titi")
.end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
// 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(
@@ -212,7 +212,7 @@
.select(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME)
.eq(WikittyGroup.FQ_FIELD_WIKITTYGROUP_MEMBERS, l1)
.end();
- WikittyQueryResult<String> result = se.findAllByQuery(null, q);
+ WikittyQueryResult<String> result = se.findAllByQuery(null, q).convertMapToSimple();
System.out.println("dd:" + result.getAll());
// g3 doit etre retrouve via le join, et g1 est exclue via la not(ideq)
Assert.assertEquals(2, result.size());
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/ElementModifier.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/ElementModifier.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/ElementModifier.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -222,15 +222,17 @@
return result;
}
- public String convertToField(String solrName) {
+ static public String convertToField(String solrName) {
String fieldName = solrName.replaceAll(
+ "(" + SUFFIX_SORTABLE + "$)"
+ , "");
+ fieldName = fieldName.replaceAll(
"(" + SUFFIX_BINARY + "$)"
+ "|(" + SUFFIX_BOOLEAN + "$)"
+ "|(" + SUFFIX_DATE + "$)"
+ "|(" + SUFFIX_STRING + "$)"
+ "|(" + SUFFIX_WIKITTY + "$)"
+ "|(" + SUFFIX_NUMERIC + "$)"
- + "|(" + SUFFIX_SORTABLE + "$)"
, "");
if (SOLR_ID.equals(fieldName)) {
fieldName = Element.ID.getValue();
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -27,8 +27,10 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery;
@@ -40,6 +42,7 @@
import org.apache.solr.common.SolrInputDocument;
import org.nuiton.util.TimeLog;
import org.nuiton.wikitty.WikittyException;
+import org.nuiton.wikitty.entities.FieldType;
import org.nuiton.wikitty.entities.WikittyTreeNode;
import org.nuiton.wikitty.entities.WikittyTypes;
@@ -216,6 +219,47 @@
}
/**
+ * Converti un document Solr en une map dont les elements sont types
+ * (les boolean, date, numeric sont convertis dans leur type)
+ *
+ * @param doc
+ * @return
+ */
+ static public Map<String, Object> convertToTypedMap(SolrDocument doc) {
+ Map<String, Object> result = new LinkedHashMap<String, Object>();
+ for (String solrField : doc.getFieldNames()) {
+ String fieldName = ElementModifier.convertToField(solrField);
+ String fieldType = StringUtils.substringAfter(solrField, fieldName);
+
+ FieldType type;
+ if (fieldType.startsWith(SUFFIX_BOOLEAN)) {
+ type = new FieldType(WikittyTypes.BOOLEAN, 0, Integer.MAX_VALUE);
+ } else if (fieldType.startsWith(SUFFIX_DATE)) {
+ type = new FieldType(WikittyTypes.DATE, 0, Integer.MAX_VALUE);
+ } else if (fieldType.startsWith(SUFFIX_NUMERIC)) {
+ type = new FieldType(WikittyTypes.NUMERIC, 0, Integer.MAX_VALUE);
+ } else {
+ type = new FieldType(WikittyTypes.STRING, 0, Integer.MAX_VALUE);
+ }
+
+ Collection values = doc.getFieldValues(solrField);
+ values = (Collection)type.getValidValue(values);
+
+ Object value;
+ if (values.isEmpty()) {
+ value = null;
+ } else if (values.size() == 1) {
+ value = values.iterator().next();
+ } else {
+ value = values;
+ }
+
+ result.put(fieldName, value);
+ }
+ return result;
+ }
+
+ /**
* if you change this method, change
* {@link FieldModifier#convertToField(org.nuiton.wikitty.services.WikittyTransaction, java.lang.String)}
* too
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -66,6 +66,8 @@
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.query.conditions.True;
import org.nuiton.wikitty.query.conditions.Unlike;
+import org.nuiton.wikitty.query.function.FunctionValue;
+import org.nuiton.wikitty.query.function.WikittyQueryFunction;
import org.nuiton.wikitty.services.WikittyTransaction;
/**
@@ -185,7 +187,7 @@
WikittyQuery query = new WikittyQuery(o);
// eval select
WikittyQueryResult<String> selectResult =
- searchEngine.findAllByQuery(tx, query);
+ searchEngine.findAllByQuery(tx, query).convertMapToSimpleString();
for (String s : selectResult) {
result.add(escape2solr(s));
}
@@ -202,10 +204,10 @@
protected String evalConditionValue(ConditionValue o) {
String result;
if (o instanceof Select) {
- WikittyQuery query = new WikittyQuery(o);
+ WikittyQuery query = new WikittyQuery(o).setLimit(WikittyQuery.MAX);
// eval select
WikittyQueryResult<String> selectResult =
- searchEngine.findAllByQuery(tx, query);
+ searchEngine.findAllByQuery(tx, query).convertMapToSimpleString();
if (selectResult.size() == 0) {
throw new WikittyException(String.format(
"Select return no result query was '%s' transformed to '%s'",
@@ -268,7 +270,7 @@
.setWikittyFieldSearchDepth(wikittyFieldSearchDepth - 1);
// eval sub
WikittyQueryResult<String> subResult =
- searchEngine.findAllByQuery(tx, sub);
+ searchEngine.findAllByQuery(tx, sub).convertMapToSimpleString();
// si on a bien des resultat en plus on modifie la requete
if (subResult.size() > 0) {
@@ -404,6 +406,13 @@
}
@Override
+ public boolean visitMiddle(Select o) {
+ // nothing to do
+ // select is done in WikittySearchEngineSolr method
+ return true;
+ }
+
+ @Override
public void visitLeave(Select o, boolean enterOrMiddleResult) {
// nothing to do
}
@@ -718,6 +727,28 @@
}
@Override
+ public boolean visitEnter(WikittyQueryFunction function) {
+ // do nothing
+ return true;
+ }
+
+ @Override
+ public boolean visitMiddle(WikittyQueryFunction function) {
+ // do nothing
+ return true;
+ }
+
+ @Override
+ public void visitLeave(WikittyQueryFunction function, boolean enterOrMiddleResult) {
+ // do nothing
+ }
+
+ @Override
+ public void visit(FunctionValue function) {
+ // do nothing
+ }
+
+ @Override
public void defaultVisit(Object o) {
throw new UnsupportedOperationException("Not supported:" + o.getClass());
}
Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java
===================================================================
--- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2013-02-16 16:18:19 UTC (rev 1529)
+++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2013-02-20 11:31:06 UTC (rev 1530)
@@ -26,8 +26,10 @@
package org.nuiton.wikitty.storage.solr;
import java.io.File;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -65,6 +67,7 @@
import org.nuiton.wikitty.query.WikittyQueryMaker;
import org.nuiton.wikitty.query.WikittyQueryResult;
import org.nuiton.wikitty.query.WikittyQueryResultTreeNode;
+import org.nuiton.wikitty.query.conditions.Condition;
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.search.Criteria;
import org.nuiton.wikitty.search.PagedResult;
@@ -664,149 +667,170 @@
}
@Override
- public WikittyQueryResult<String> findAllByQuery(WikittyTransaction transaction, WikittyQuery query) {
+ public WikittyQueryResult<Map<String, Object>> findAllByQuery(WikittyTransaction transaction, WikittyQuery query) {
try {
- WikittyQueryResult<String> result;
+ // la condition select du query, sera traite a la fin
+ Select select = null;
+ WikittyQuery queryWithoutSelect = query;
+
if (query.getCondition() instanceof Select) {
- result = WikittySearchEngineHelper.findAllByQueryWithSelect(
- this, transaction, query);
- } else {
+ select = (Select)query.getCondition();
+ Condition newCond = select.getSubCondition();
+ if (newCond == null) {
+ newCond = new org.nuiton.wikitty.query.conditions.True();
+ }
- // Create querySolr
- WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr(
- transaction, this, elementModifier, query.getWikittyFieldSearchDepth());
- query.getCondition().accept(v);
- String queryString = v.getSolrQuery();
- SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString);
+ // copy de la query sans le select
+ queryWithoutSelect = query.copy();
+ queryWithoutSelect.setCondition(newCond);
+ }
- // Add paged
- int offset = query.getOffset();
- int limit = query.getLimit();
+ // Create querySolr
+ WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr(
+ transaction, this, elementModifier, queryWithoutSelect.getWikittyFieldSearchDepth());
+ queryWithoutSelect.getCondition().accept(v);
+ String queryString = v.getSolrQuery();
+ SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString);
- if (limit == Integer.MAX_VALUE) {
- // WARNING It is necessary to substract 'start' otherwise,
- // there is a capacity overlow in solR
- limit = Integer.MAX_VALUE - offset;
- }
- querySolr.setStart(offset);
- querySolr.setRows(limit);
+ // Add paged
+ int offset = queryWithoutSelect.getOffset();
+ int limit = queryWithoutSelect.getLimit();
- // Add sorting
- List<Element> sortAscending = query.getSortAscending();
- if(sortAscending != null) {
- for (Element sort : sortAscending) {
- String tranform = elementModifier.convertToSolr(transaction, sort);
- tranform += WikittySolrConstant.SUFFIX_SORTABLE;
- querySolr.addSortField(tranform, SolrQuery.ORDER.asc);
- }
+ if (limit == Integer.MAX_VALUE) {
+ // WARNING It is necessary to substract 'start' otherwise,
+ // there is a capacity overlow in solR
+ limit = Integer.MAX_VALUE - offset;
+ }
+ querySolr.setStart(offset);
+ querySolr.setRows(limit);
+
+ // Add sorting
+ List<Element> sortAscending = queryWithoutSelect.getSortAscending();
+ if(sortAscending != null) {
+ for (Element sort : sortAscending) {
+ String tranform = elementModifier.convertToSolr(transaction, sort);
+ tranform += WikittySolrConstant.SUFFIX_SORTABLE;
+ querySolr.addSortField(tranform, SolrQuery.ORDER.asc);
}
+ }
- List<Element> sortDescending = query.getSortDescending();
- if(sortDescending != null) {
- for (Element sort : sortDescending) {
- String tranform = elementModifier.convertToSolr(transaction, sort);
- tranform += WikittySolrConstant.SUFFIX_SORTABLE;
- querySolr.addSortField(tranform, SolrQuery.ORDER.desc);
- }
+ List<Element> sortDescending = queryWithoutSelect.getSortDescending();
+ if(sortDescending != null) {
+ for (Element sort : sortDescending) {
+ String tranform = elementModifier.convertToSolr(transaction, sort);
+ tranform += WikittySolrConstant.SUFFIX_SORTABLE;
+ querySolr.addSortField(tranform, SolrQuery.ORDER.desc);
}
+ }
- // Add faceting
- boolean isFacetExtension = query.isFacetExtension();
- List<Element> facetField = query.getFacetField();
- List<FacetQuery> facetQuery = query.getFacetQuery();
+ // Add faceting
+ boolean isFacetExtension = queryWithoutSelect.isFacetExtension();
+ List<Element> facetField = queryWithoutSelect.getFacetField();
+ List<FacetQuery> facetQuery = queryWithoutSelect.getFacetQuery();
- // use to map query string to criteria facet name
- Map<String, String> facetQueryToName = new HashMap<String, String>();
+ // use to map query string to criteria facet name
+ Map<String, String> facetQueryToName = new HashMap<String, String>();
- if (isFacetExtension
- || CollectionUtils.isNotEmpty(facetField)
- || CollectionUtils.isNotEmpty(facetQuery)) {
- querySolr.setFacet(true);
- querySolr.setFacetMinCount(query.getFacetMinCount());
- querySolr.setFacetLimit(query.getFacetLimit());
- querySolr.setFacetSort(query.getFacetSort().solrValue);
+ if (isFacetExtension
+ || CollectionUtils.isNotEmpty(facetField)
+ || CollectionUtils.isNotEmpty(facetQuery)) {
+ querySolr.setFacet(true);
+ querySolr.setFacetMinCount(queryWithoutSelect.getFacetMinCount());
+ querySolr.setFacetLimit(queryWithoutSelect.getFacetLimit());
+ querySolr.setFacetSort(queryWithoutSelect.getFacetSort().solrValue);
- if (isFacetExtension) {
- querySolr.addFacetField(WikittySolrConstant.SOLR_EXTENSIONS);
- }
+ if (isFacetExtension) {
+ querySolr.addFacetField(WikittySolrConstant.SOLR_EXTENSIONS);
+ }
- // field facetisation
- if (facetField != null) {
- for (Element fqfieldName : facetField) {
- String tranform = elementModifier.convertToSolr(transaction, fqfieldName);
- querySolr.addFacetField(tranform);
- }
+ // field facetisation
+ if (facetField != null) {
+ for (Element fqfieldName : facetField) {
+ String tranform = elementModifier.convertToSolr(transaction, fqfieldName);
+ querySolr.addFacetField(tranform);
}
+ }
- // query facetisation
- if (facetQuery != null) {
- for (FacetQuery facet : facetQuery) {
- v = new WikittyQueryVisitorToSolr(
+ // query facetisation
+ if (facetQuery != null) {
+ for (FacetQuery facet : facetQuery) {
+ v = new WikittyQueryVisitorToSolr(
transaction, this, elementModifier, 0); // pas de recherche recursive sur les champs wikitty pour les facettes
- facet.getCondition().accept(v);
- String queryFacet = v.getSolrQuery();
- facetQueryToName.put(queryFacet, facet.getName());
- querySolr.addFacetQuery(queryFacet);
- }
+ facet.getCondition().accept(v);
+ String queryFacet = v.getSolrQuery();
+ facetQueryToName.put(queryFacet, facet.getName());
+ querySolr.addFacetQuery(queryFacet);
}
}
+ }
- QueryResponse resp = SolrUtil.executeQuery(solrServer, querySolr);
- SolrDocumentList solrResults = resp.getResults();
+ QueryResponse resp = SolrUtil.executeQuery(solrServer, querySolr);
+ SolrDocumentList solrResults = resp.getResults();
- Map<String, List<FacetTopic>> facets = new HashMap<String, List<FacetTopic>>();
+ Map<String, List<FacetTopic>> facets = new HashMap<String, List<FacetTopic>>();
- // la facet sur les extensions est directement et convenablement
- // gere comme un champs
- if (isFacetExtension || CollectionUtils.isNotEmpty(facetField)) {
- for (FacetField facet : resp.getFacetFields()) {
- String facetName = elementModifier.convertToField(facet.getName());
- List<FacetTopic> topics = new ArrayList<FacetTopic>();
- if (facet.getValues() != null) {
- for (FacetField.Count value : facet.getValues()) {
- String topicName = value.getName();
- int topicCount = (int) value.getCount();
- FacetTopic topic = new FacetTopic(facetName, topicName, topicCount);
- topics.add(topic);
- }
+ // la facet sur les extensions est directement et convenablement
+ // gere comme un champs
+ if (isFacetExtension || CollectionUtils.isNotEmpty(facetField)) {
+ for (FacetField facet : resp.getFacetFields()) {
+ String facetName = elementModifier.convertToField(facet.getName());
+ List<FacetTopic> topics = new ArrayList<FacetTopic>();
+ if (facet.getValues() != null) {
+ for (FacetField.Count value : facet.getValues()) {
+ String topicName = value.getName();
+ int topicCount = (int) value.getCount();
+ FacetTopic topic = new FacetTopic(facetName, topicName, topicCount);
+ topics.add(topic);
}
- facets.put(facetName, topics);
}
+ facets.put(facetName, topics);
}
+ }
- if (CollectionUtils.isNotEmpty(facetQuery)) {
- for (Map.Entry<String, Integer> facet : resp.getFacetQuery().entrySet()) {
- String facetName = facet.getKey();
- // don't use contains because, map can have key with null value
- if (null != facetQueryToName.get(facetName)) {
- facetName = facetQueryToName.get(facetName);
- }
- Integer count = facet.getValue();
- List<FacetTopic> topics = new ArrayList<FacetTopic>();
- FacetTopic topic = new FacetTopic(facetName, facetName, count);
- topics.add(topic);
- facets.put(facetName, topics);
+ if (CollectionUtils.isNotEmpty(facetQuery)) {
+ for (Map.Entry<String, Integer> facet : resp.getFacetQuery().entrySet()) {
+ String facetName = facet.getKey();
+ // don't use contains because, map can have key with null value
+ if (null != facetQueryToName.get(facetName)) {
+ facetName = facetQueryToName.get(facetName);
}
+ Integer count = facet.getValue();
+ List<FacetTopic> topics = new ArrayList<FacetTopic>();
+ FacetTopic topic = new FacetTopic(facetName, facetName, count);
+ topics.add(topic);
+ facets.put(facetName, topics);
}
+ }
+ // Get total num found
+ int numFound = (int)resp.getResults().getNumFound();
+
+ List<Map<String, Object>> values =
+ new ArrayList<Map<String, Object>>(solrResults.size());
+ if (select == null) {
// Extract ids
- List<String> ids = new ArrayList<String>(solrResults.size());
+ String idTag = org.nuiton.wikitty.entities.Element.ID.getValue();
for (SolrDocument doc : solrResults) {
-
- String id = SolrUtil.getStringFieldValue(doc, SOLR_ID);
- ids.add(id);
+ Object id = SolrUtil.getStringFieldValue(doc, SOLR_ID);
+ values.add(Collections.singletonMap(idTag, id));
}
+ } else {
+ // Extract data
+ for (SolrDocument doc : solrResults) {
+ Map<String, Object> map = SolrUtil.convertToTypedMap(doc);
+ values.add(map);
+ }
- // Get total num found
- int numFound = (int)resp.getResults().getNumFound();
+ values = select.getFunction().call(this, transaction, query, values);
- // Build paged result
- result = new WikittyQueryResult<String>(
- query.getName(),
- offset, numFound, queryString, facets, ids, 0, 0);
+ }
+
- }
+ // Build paged result
+ WikittyQueryResult result = new WikittyQueryResult(query.getName(),
+ offset, numFound, queryString, facets, values, 0, 0);
+
return result;
} catch (SolrServerException eee) {
throw new WikittyException(String.format(
@@ -814,6 +838,158 @@
}
}
+ // TODO Remove it
+// @Override
+// public WikittyQueryResult<String> findAllByQueryOLD(WikittyTransaction transaction, WikittyQuery query) {
+// try {
+// WikittyQueryResult<String> result;
+//
+// if (query.getCondition() instanceof Select) {
+// result = WikittySearchEngineHelper.findAllByQueryWithSelect(
+// this, transaction, query);
+// } else {
+//
+// // Create querySolr
+// WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr(
+// transaction, this, elementModifier, query.getWikittyFieldSearchDepth());
+// query.getCondition().accept(v);
+// String queryString = v.getSolrQuery();
+// SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString);
+//
+// // Add paged
+// int offset = query.getOffset();
+// int limit = query.getLimit();
+//
+// if (limit == Integer.MAX_VALUE) {
+// // WARNING It is necessary to substract 'start' otherwise,
+// // there is a capacity overlow in solR
+// limit = Integer.MAX_VALUE - offset;
+// }
+// querySolr.setStart(offset);
+// querySolr.setRows(limit);
+//
+// // Add sorting
+// List<Element> sortAscending = query.getSortAscending();
+// if(sortAscending != null) {
+// for (Element sort : sortAscending) {
+// String tranform = elementModifier.convertToSolr(transaction, sort);
+// tranform += WikittySolrConstant.SUFFIX_SORTABLE;
+// querySolr.addSortField(tranform, SolrQuery.ORDER.asc);
+// }
+// }
+//
+// List<Element> sortDescending = query.getSortDescending();
+// if(sortDescending != null) {
+// for (Element sort : sortDescending) {
+// String tranform = elementModifier.convertToSolr(transaction, sort);
+// tranform += WikittySolrConstant.SUFFIX_SORTABLE;
+// querySolr.addSortField(tranform, SolrQuery.ORDER.desc);
+// }
+// }
+//
+// // Add faceting
+// boolean isFacetExtension = query.isFacetExtension();
+// List<Element> facetField = query.getFacetField();
+// List<FacetQuery> facetQuery = query.getFacetQuery();
+//
+// // use to map query string to criteria facet name
+// Map<String, String> facetQueryToName = new HashMap<String, String>();
+//
+// if (isFacetExtension
+// || CollectionUtils.isNotEmpty(facetField)
+// || CollectionUtils.isNotEmpty(facetQuery)) {
+// querySolr.setFacet(true);
+// querySolr.setFacetMinCount(query.getFacetMinCount());
+// querySolr.setFacetLimit(query.getFacetLimit());
+// querySolr.setFacetSort(query.getFacetSort().solrValue);
+//
+// if (isFacetExtension) {
+// querySolr.addFacetField(WikittySolrConstant.SOLR_EXTENSIONS);
+// }
+//
+// // field facetisation
+// if (facetField != null) {
+// for (Element fqfieldName : facetField) {
+// String tranform = elementModifier.convertToSolr(transaction, fqfieldName);
+// querySolr.addFacetField(tranform);
+// }
+// }
+//
+// // query facetisation
+// if (facetQuery != null) {
+// for (FacetQuery facet : facetQuery) {
+// v = new WikittyQueryVisitorToSolr(
+// transaction, this, elementModifier, 0); // pas de recherche recursive sur les champs wikitty pour les facettes
+// facet.getCondition().accept(v);
+// String queryFacet = v.getSolrQuery();
+// facetQueryToName.put(queryFacet, facet.getName());
+// querySolr.addFacetQuery(queryFacet);
+// }
+// }
+// }
+//
+// QueryResponse resp = SolrUtil.executeQuery(solrServer, querySolr);
+// SolrDocumentList solrResults = resp.getResults();
+//
+// Map<String, List<FacetTopic>> facets = new HashMap<String, List<FacetTopic>>();
+//
+// // la facet sur les extensions est directement et convenablement
+// // gere comme un champs
+// if (isFacetExtension || CollectionUtils.isNotEmpty(facetField)) {
+// for (FacetField facet : resp.getFacetFields()) {
+// String facetName = elementModifier.convertToField(facet.getName());
+// List<FacetTopic> topics = new ArrayList<FacetTopic>();
+// if (facet.getValues() != null) {
+// for (FacetField.Count value : facet.getValues()) {
+// String topicName = value.getName();
+// int topicCount = (int) value.getCount();
+// FacetTopic topic = new FacetTopic(facetName, topicName, topicCount);
+// topics.add(topic);
+// }
+// }
+// facets.put(facetName, topics);
+// }
+// }
+//
+// if (CollectionUtils.isNotEmpty(facetQuery)) {
+// for (Map.Entry<String, Integer> facet : resp.getFacetQuery().entrySet()) {
+// String facetName = facet.getKey();
+// // don't use contains because, map can have key with null value
+// if (null != facetQueryToName.get(facetName)) {
+// facetName = facetQueryToName.get(facetName);
+// }
+// Integer count = facet.getValue();
+// List<FacetTopic> topics = new ArrayList<FacetTopic>();
+// FacetTopic topic = new FacetTopic(facetName, facetName, count);
+// topics.add(topic);
+// facets.put(facetName, topics);
+// }
+// }
+//
+// // Extract ids
+// List<String> ids = new ArrayList<String>(solrResults.size());
+// for (SolrDocument doc : solrResults) {
+//
+// String id = SolrUtil.getStringFieldValue(doc, SOLR_ID);
+// ids.add(id);
+// }
+//
+// // Get total num found
+// int numFound = (int)resp.getResults().getNumFound();
+//
+// // Build paged result
+// result = new WikittyQueryResult<String>(
+// query.getName(),
+// offset, numFound, queryString, facets, ids, 0, 0);
+//
+// }
+// return result;
+// } catch (SolrServerException eee) {
+// throw new WikittyException(String.format(
+// "Error during find of query '%s'", query), eee);
+// }
+// }
+
/**
* Si l'argument n'est pas un TreeNode, une exception est levee
*
@@ -874,14 +1050,14 @@
}
WikittyQuery attQuery =
attQueryMaker.eq(TREENODE_ATTACHED_ALL, wikittyId).end()
- .setFirst(0).setLimit(0)
+ .setOffset(0).setLimit(0)
.addFacetField(new ElementField(TREENODE_ATTACHED_ALL))
// l'arbre peut avoir beaucoup de branche, il
// faut que toutes les branches aient un count
// des attachments
.setFacetLimit(Integer.MAX_VALUE);
WikittyQueryResult<String> attSearch =
- findAllByQuery(transaction, attQuery);
+ findAllByQuery(transaction, attQuery).convertMapToSimple();
List<FacetTopic> topics = attSearch.getTopic(TREENODE_ATTACHED_ALL);
if (topics != null) {
for (FacetTopic topic : topics) {
1
0
r1529 - in trunk: src/site/rst/user wikitty-api/src/main/java/org/nuiton/wikitty/query
by bpoussin@users.nuiton.org 16 Feb '13
by bpoussin@users.nuiton.org 16 Feb '13
16 Feb '13
Author: bpoussin
Date: 2013-02-16 17:18:19 +0100 (Sat, 16 Feb 2013)
New Revision: 1529
Url: http://nuiton.org/projects/wikitty/repository/revisions/1529
Log:
fixes #2370: add a date format translator in the query parser when the field to compare is a date
Modified:
trunk/src/site/rst/user/query.rst
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
Modified: trunk/src/site/rst/user/query.rst
===================================================================
--- trunk/src/site/rst/user/query.rst 2013-02-16 15:44:22 UTC (rev 1528)
+++ trunk/src/site/rst/user/query.rst 2013-02-16 16:18:19 UTC (rev 1529)
@@ -724,6 +724,21 @@
Spécificité de WikittyQueryParser
---------------------------------
+Date
+~~~~
+
+Pour simplifier l'écriture des dates, il est possible d'utiliser la fonction date,
+ce qui évite de devoir écrire les dates dans un format spécifique.::
+
+ WikittyQuery q = WikittyQueryParser.parse(
+ "SELECT MIN Person.birthday WHERE Person.firstname=Jean and Person.birthday < date(01/01/2000)");
+
+Ici on recherche une personne s'appelant 'Jean' ayant l'âge le plus petit, mais
+dont l'âge est tout de même avant l'an 2000.
+
+Alias
+~~~~~
+
Vous pouvez ajouter des alias pour simplifier l'écriture de certaines requêtes.
Par exemple si vous utilisez souvent une longue requête comme::
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-16 15:44:22 UTC (rev 1528)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-16 16:18:19 UTC (rev 1529)
@@ -25,6 +25,7 @@
package org.nuiton.wikitty.query;
import java.util.Collections;
+import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -32,6 +33,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.query.conditions.Aggregate;
import org.nuiton.wikitty.query.conditions.And;
import org.nuiton.wikitty.query.conditions.Between;
@@ -89,6 +91,7 @@
@BuildParseTree
public class WikittyQueryParser extends BaseParser<Object> {
+ public static final String DATE = "DATE";
public static final String AVG = "AVG";
public static final String COUNT = "COUNT";
public static final String MAX = "MAX";
@@ -155,6 +158,7 @@
public Rule icLIKE = IgnoreCase(LIKE);
public Rule icUNLIKE = IgnoreCase(UNLIKE);
public Rule icNULL = IgnoreCase(NULL);
+ public Rule icDATE = IgnoreCase(DATE);
/** to use log facility, just put in your code: log.info(\"...\"); */
static private Log log = LogFactory.getLog(WikittyQueryParser.class);
@@ -316,6 +320,15 @@
return result;
}
+ protected String toDate(Object s) {
+ if (s instanceof ConditionValueString) {
+ s = ((ConditionValueString)s).getValue();
+ }
+ Date d = WikittyUtil.toDate(s);
+ String result = WikittyUtil.toString(d);
+ return result;
+ }
+
Rule start() {
return Sequence(FirstOf(or(), empty()), push(new WikittyQuery((Condition)pop())),
offset(), limit(), depth(), space(), EOI);
@@ -536,9 +549,14 @@
}
Rule value() {
- return FirstOf(select(), valueText());
+ return FirstOf(select(), date(), valueText());
}
+ Rule date() {
+ return Sequence(icDATE, BRACKET_OPEN, valueText() ,BRACKET_CLOSE,
+ push(new ConditionValueString(toDate(pop()))));
+ }
+
Rule valueText() {
return Sequence(FirstOf(StringLiteralDouble(), StringLiteralSimple(), SimpleString()),
push(new ConditionValueString(removeQuote(match()))));
1
0
r1528 - in trunk: src/site/rst/user wikitty-api/src/main/java/org/nuiton/wikitty/query wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions wikitty-api/src/main/java/org/nuiton/wikitty/storage
by bpoussin@users.nuiton.org 16 Feb '13
by bpoussin@users.nuiton.org 16 Feb '13
16 Feb '13
Author: bpoussin
Date: 2013-02-16 16:44:22 +0100 (Sat, 16 Feb 2013)
New Revision: 1528
Url: http://nuiton.org/projects/wikitty/repository/revisions/1528
Log:
fixes #2531: Add DISTINT clause for SELECT query
Modified:
trunk/src/site/rst/user/query.rst
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java
Modified: trunk/src/site/rst/user/query.rst
===================================================================
--- trunk/src/site/rst/user/query.rst 2013-02-15 14:38:58 UTC (rev 1527)
+++ trunk/src/site/rst/user/query.rst 2013-02-16 15:44:22 UTC (rev 1528)
@@ -446,7 +446,7 @@
Dans l'exemple suivant au lieu de retourner
l'id des employés en CDI, on retourne leur nom. Si deux personnes avait le même
-nom, ce nom ne serai retourné qu'une seule fois.::
+nom, ce nom serait retourné deux fois sauf si la clause DISTINCT a été utilisé.::
WikittyQuery q = new WikittyQueryMaker()
select("Employee.name").eq("Employee.contract", "CDI").end();
@@ -467,8 +467,35 @@
Il est possible d'ajouter des fonctions d'aggrégats dans le Select. Dans ce cas
le résultat retourné ne contient qu'un seul élément. L'aggrégat est fait sur les
-élements retournés (de first à first+Limit)
+élements retournés (de first à first+Limit). Il est aussi possible d'ajouter
+la clause DISTINCT pour que les éléments retournés ou les aggrégats se fassent
+seulement sur les éléments distincts.
+DISTINCT
+~~~~~~~~
+
+Retourne une liste sans doublon::
+
+ WikittyQuery q = new WikittyQueryMaker()
+ .select("Person.age", true).eq("Person.firstname", "Jean").end();
+
+ WikittyQuery q = WikittyQueryParser.parse(
+ "SELECT DISTINCT Person.age WHERE Person.firstname=Jean");
+
+Dans ces exemples si plusieurs personnes portant le prénom 'Jean' ont le même
+âge, cet âge n'est retourné qu'une seule fois. Par exemple si la liste dans le
+DISTINCT retourne: 12, 18, 18, 33. Avec le DISTINCT le résultat sera: 12, 18, 33
+
+Il est possible de couplé DISTINCT est une fonction d'aggrégat::
+
+ WikittyQuery q = new WikittyQueryMaker()
+ .select("Person.age", Aggregate.AVG, true).eq("Person.firstname", "Jean").end();
+
+ WikittyQuery q = WikittyQueryParser.parse(
+ "SELECT DISTINCT AVG Person.age WHERE Person.firstname=Jean");
+
+Dans cette exemple la moyenne est fait sur: 12, 18, 33 soit 21
+
AVG
~~~
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-15 14:38:58 UTC (rev 1527)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMakerAbstract.java 2013-02-16 15:44:22 UTC (rev 1528)
@@ -1173,6 +1173,42 @@
}
/**
+ * Add {@link Select}, this condition must be first or
+ * @param element le champs dont il faut extraire les donnees
+ * @return {@code this}
+ * @see {@link Select}
+ */
+ public M select(String element, boolean distinct) {
+ return select(Element.get(element), distinct);
+ }
+
+ /**
+ * Add {@link Select}, this condition must be first or
+ * @param element le champs dont il faut extraire les donnees
+ * @return {@code this}
+ * @see {@link Select}
+ */
+ public M select(String element, Aggregate aggregate, boolean distinct) {
+ return select(Element.get(element), aggregate, distinct);
+ }
+
+ /*
+ * @see {@link Select}
+ */
+ public M select(Element element, boolean distinct) {
+ return select(element, null, distinct);
+ }
+
+ /*
+ * @see {@link Select}
+ */
+ public M select(Element element, Aggregate aggregate, boolean distinct) {
+ Condition child = new Select(element, aggregate, distinct);
+ addCondition(child);
+ return this.asM();
+ }
+
+ /**
* Close last non terminal condition (or, and, not, in).
* <li>ex: WikittyQueryMaker().not().rTrue().close().and().rTrue().rFalse().close().or().rTrue().rFalse().close();
* @return
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-15 14:38:58 UTC (rev 1527)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryParser.java 2013-02-16 15:44:22 UTC (rev 1528)
@@ -94,6 +94,7 @@
public static final String MAX = "MAX";
public static final String MIN = "MIN";
public static final String SUM = "SUM";
+ public static final String DISTINCT = "DISTINCT";
public static final String SELECT = "SELECT";
public static final String WHERE = "WHERE";
public static final String IN = "IN";
@@ -144,6 +145,7 @@
public Rule icMAX = IgnoreCase(MAX);
public Rule icMIN = IgnoreCase(MIN);
public Rule icSUM = IgnoreCase(SUM);
+ public Rule icDISTINCT = IgnoreCase(DISTINCT);
public Rule icSELECT = IgnoreCase(SELECT);
public Rule icWHERE = IgnoreCase(WHERE);
public Rule icIN = IgnoreCase(IN);
@@ -480,10 +482,19 @@
}
Rule select() {
Var<Aggregate> aggregate = new Var<Aggregate>();
- return Sequence(icSELECT, space(), Optional(aggregate(aggregate)), space(), field(), push(match()), space(),
+ Var<Boolean> distinct = new Var<Boolean>(Boolean.FALSE);
+ return Sequence(icSELECT, space(),
+ Optional(distinct(distinct)), space(),
+ Optional(aggregate(aggregate)), space(),
+ field(), push(match()), space(),
+
FirstOf(Sequence(icWHERE, space(), term()), empty()),
push(new Select(toElement(pop(1).toString()), aggregate.get(), (Condition)pop())));
}
+ Rule distinct(Var<Boolean> distinct) {
+ return Sequence(icDISTINCT, distinct.set(Boolean.TRUE));
+ }
+
Rule aggregate(Var<Aggregate> aggregate) {
return FirstOf(avg(aggregate), count(aggregate), max(aggregate), min(aggregate), sum(aggregate));
}
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java 2013-02-15 14:38:58 UTC (rev 1527)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/conditions/Select.java 2013-02-16 15:44:22 UTC (rev 1528)
@@ -50,27 +50,43 @@
private static final long serialVersionUID = 1L;
+ protected boolean distinct = false;
protected Aggregate aggregate;
protected Element element;
public Select(Element element) {
- this.element = element;
+ this(element, null, false, null);
}
+ public Select(Element element, boolean distinct) {
+ this(element, null, distinct, null);
+ }
+
public Select(Element element, Aggregate aggregate) {
- this.element = element;
- this.aggregate = aggregate;
+ this(element, aggregate, false, null);
}
+ public Select(Element element, Aggregate aggregate, boolean distinct) {
+ this(element, aggregate, distinct, null);
+ }
+
public Select(Element element, Condition restriction) {
- super(restriction);
- this.element = element;
+ this(element, null, false, restriction);
}
+ public Select(Element element, boolean distinct, Condition restriction) {
+ this(element, null, distinct, restriction);
+ }
+
public Select(Element element, Aggregate aggregate, Condition restriction) {
+ this(element, aggregate, false, restriction);
+ }
+
+ public Select(Element element, Aggregate aggregate, boolean distinct, Condition restriction) {
super(restriction);
this.element = element;
this.aggregate = aggregate;
+ this.distinct = distinct;
}
public Aggregate getAggregate() {
@@ -81,6 +97,10 @@
return element;
}
+ public boolean isDistinct() {
+ return distinct;
+ }
+
@Override
boolean equalsDeep(Object other) {
boolean result = super.equalsDeep(other);
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-15 14:38:58 UTC (rev 1527)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/storage/WikittySearchEngineHelper.java 2013-02-16 15:44:22 UTC (rev 1528)
@@ -78,6 +78,9 @@
// n'a pas les meme limites que les autres facette
Select select = (Select)query.getCondition();
+ boolean isAggregate = select.getAggregate() != null;
+ boolean isDistinct = select.isDistinct();
+
Condition newCond;
if(WikittyExtension.isFqField(select.getElement().getValue())) {
String extName = WikittyExtension.extractExtensionName(
@@ -120,11 +123,14 @@
List<FacetTopic> topics = resultSelect.getFacets().get(select.getElement().getValue());
List<String> selectList = new ArrayList<String>(topics.size());
- if (query.getOffset() < topics.size()) {
- // il faut que le premier demande soit inferieur a la taille,
- // sinon on ne fait rien
- for (FacetTopic topic : topics) {
+ for (FacetTopic topic : topics) {
+ if (isDistinct) {
selectList.add(topic.getTopicName());
+ } else {
+ // on ajoute la valeur le nombre de fois qu'il y a de count dans la facette
+ for (int i=0, max=topic.getCount(); i<max; i++) {
+ selectList.add(topic.getTopicName());
+ }
}
}
@@ -137,22 +143,21 @@
}
// on ne garde que ce qui est demande
- if (query.getOffset() < topics.size()) {
- int offset = query.getOffset();
- int limit = query.getLimit();
+ int offset = query.getOffset();
+ int limit = query.getLimit();
+ if (limit == Integer.MAX_VALUE) {
+ // WARNING It is necessary to substract 'offset' otherwise,
+ // there is a capacity overlow
+ limit = Integer.MAX_VALUE - offset;
+ }
+ int first = Math.min(selectList.size(), offset);
+ int last = Math.min(selectList.size(), offset + limit);
+ selectList = selectList.subList(first, last);
- if (limit == Integer.MAX_VALUE) {
- // WARNING It is necessary to substract 'offset' otherwise,
- // there is a capacity overlow
- limit = Integer.MAX_VALUE - offset;
- }
- int last = Math.min(topics.size(), offset + limit);
- selectList = selectList.subList(offset, last);
- }
// gestion des agregats
- if (select.getAggregate() != null) {
+ if (isAggregate) {
switch(select.getAggregate()) {
case AVG: {
// convert all to number
1
0
r1527 - in trunk: wikitty-api/src/main/java/org/nuiton/wikitty/entities wikitty-api/src/main/java/org/nuiton/wikitty/services wikitty-generators/src/main/java/org/nuiton/wikitty/generator
by bpoussin@users.nuiton.org 15 Feb '13
by bpoussin@users.nuiton.org 15 Feb '13
15 Feb '13
Author: bpoussin
Date: 2013-02-15 15:38:58 +0100 (Fri, 15 Feb 2013)
New Revision: 1527
Url: http://nuiton.org/projects/wikitty/repository/revisions/1527
Log:
Evolution #2530: add default value tag for wikitty field definition
Modified:
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java
trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java
trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java
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 2013-02-15 11:17:45 UTC (rev 1526)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java 2013-02-15 14:38:58 UTC (rev 1527)
@@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -160,6 +161,10 @@
* @throws WikittyException if value can't be obtained
*/
public Object getValidValue(Object value) throws WikittyException {
+ if (value == null && hasDefault()) {
+ value = getDefault();
+ }
+
if (value == null && isNotNull()) {
throw new WikittyException("Value can't be null for this field");
}
@@ -281,6 +286,27 @@
}
/**
+ * @see #TAG_DEFAULT_VALUE
+ */
+ public boolean hasDefault() {
+ return tagValues.containsKey(TAG_DEFAULT_VALUE);
+ }
+
+ public Object getDefault() {
+ Object result = null;
+
+ Object val = tagValues.get(TAG_DEFAULT_VALUE);
+ if (val != null) {
+ if (isCollection()) {
+ val = Collections.singleton(val);
+ }
+ result = getValidValue(val);
+ }
+
+ return result;
+ }
+
+ /**
* @see #TAG_UNIQUE
*/
public boolean isUnique() {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java 2013-02-15 11:17:45 UTC (rev 1526)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java 2013-02-15 14:38:58 UTC (rev 1527)
@@ -108,6 +108,23 @@
return result;
}
+ /**
+ * Si le champs n'a pas de valeur (null) met en place la valeur par defaut
+ *
+ * @param w
+ * @param fqfield
+ * @param type
+ * @param value
+ */
+ public Object checkDefault(Wikitty w, String fqfield, FieldType type, Object value) {
+ Object result = value;
+ if (value == null && type.hasDefault()) {
+ result = type.getDefault();
+ w.setFqField(fqfield, result);
+ }
+ return result;
+ }
+
public Object getMin(FieldType field) {
String min = null;
if (field.hasMinQuery()) {
Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java
===================================================================
--- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2013-02-15 11:17:45 UTC (rev 1526)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2013-02-15 14:38:58 UTC (rev 1527)
@@ -405,6 +405,14 @@
extensions.put(ext.name, ext);
incrementVersion(ext.name);
+
+ // mise en place des valeurs par defaut des champs de l'extension
+ for (String fieldName : ext.getFieldNames()) {
+ FieldType type = ext.getFieldType(fieldName);
+ if (type.hasDefault()) {
+ setField(ext.name, fieldName, type.getDefault());
+ }
+ }
}
public void removeExtension(String ext) {
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 2013-02-15 11:17:45 UTC (rev 1526)
+++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2013-02-15 14:38:58 UTC (rev 1527)
@@ -86,7 +86,7 @@
protected WikittyExtensionMigration defaultExtensionMigration =
new WikittyExtensionMigrationRename();
- protected FieldTypeConstaintChecker contraintChecker =
+ protected FieldTypeConstaintChecker constraintChecker =
new FieldTypeConstaintChecker(this);
protected ApplicationConfig config;
@@ -170,9 +170,10 @@
/**
* Check les contraintes sur les champs:
- * <li> notNull
- * <li> pattern
- * <li> extensionAllowed
+ * <li> notNull: exception
+ * <li> pattern: exception
+ * <li> extensionAllowed: exception
+ * <li> default: changement de la valeur null par default
*
* @param wikitties
*/
@@ -186,7 +187,9 @@
List<String> errors = new LinkedList<String>();
- if (!contraintChecker.isValid(fqfield, type, value, errors)) {
+ value = constraintChecker.checkDefault(w, fqfield, type, value);
+
+ if (!constraintChecker.isValid(fqfield, type, value, errors)) {
throw new WikittyException(String.format(
"Field constraint error %s",
StringUtils.join(errors, "\n")));
Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java
===================================================================
--- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java 2013-02-15 11:17:45 UTC (rev 1526)
+++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java 2013-02-15 14:38:58 UTC (rev 1527)
@@ -107,6 +107,13 @@
public static final String TAG_NOT_NULL = "notNull";
/**
+ * default: indique la valeur par defaut si le champs est null.
+ * <li> target: field
+ * @since 2.9
+ */
+ public static final String TAG_DEFAULT_VALUE = "default";
+
+ /**
* pattern: pour une String indique que le champs doit respecter un certain
* pattern, sinon la sauvegarde echoue. Pour un numeric ou une date pattern
* peut-etre utilise comme masque de saisie. Exemple:
1
0