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) {