Author: bpoussin Date: 2011-12-29 20:04:15 +0100 (Thu, 29 Dec 2011) New Revision: 1266 Url: http://nuiton.org/repositories/revision/wikitty/1266 Log: Evolution #1863: Create new query api with visitor and better implementation Evolution #1864: Add query langage syntaxe Implantation de WikittyClient en remplacement de WikittyProxy qui est maintenant deprecated Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyProxy.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/BusinessEntity.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyClient.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -0,0 +1,1449 @@ +package org.nuiton.wikitty; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; + +import org.apache.commons.lang.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.entities.BusinessEntity; +import org.nuiton.wikitty.entities.BusinessEntityImpl; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.entities.WikittyGroup; +import org.nuiton.wikitty.entities.WikittyUser; +import org.nuiton.wikitty.services.WikittyEvent; +import org.nuiton.wikitty.services.WikittySecurityUtil; +import org.nuiton.wikitty.services.WikittyServiceEnhanced; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections.CollectionUtils; +import org.nuiton.wikitty.entities.WikittyField; +import org.nuiton.wikitty.entities.WikittyTokenHelper; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; +import org.nuiton.wikitty.query.WikittyQueryResult; +import org.nuiton.wikitty.query.WikittyQueryResultTreeNode; + +/** + * Wikitty client is object used in client side to access WikittyService. + * It is used to transform wikitty object used by {@link WikittyService} + * into business objects used by applications. + * + * It also manage {@link #securityToken} for {@link org.nuiton.wikitty.services.WikittyServiceSecurity}. + * + * @author poussin + * @version $Revision$ + * @since 3.3 + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyClient { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + final static private Log log = LogFactory.getLog(WikittyClient.class); + final static private TimeLog timeLog = new TimeLog(WikittyClient.class); + + /** Delegated wikitty service. */ + protected WikittyServiceEnhanced wikittyService; + + /** + * Security token. + * + * @see org.nuiton.wikitty.services.WikittyServiceSecurity#login(String, String) + */ + protected String securityToken; + + /** + * Empty constructor (uninitialized wikittyService). + */ + public WikittyClient() { + } + + public WikittyClient(ApplicationConfig config) { + if (config != null) { + long timeToLogInfo = config.getOptionAsInt(WikittyConfigOption. + WIKITTY_PROXY_TIME_TO_LOG_INFO.getKey()); + long timeToLogWarn = config.getOptionAsInt(WikittyConfigOption. + WIKITTY_PROXY_TIME_TO_LOG_WARN.getKey()); + timeLog.setTimeToLogInfo(timeToLogInfo); + timeLog.setTimeToLogWarn(timeToLogWarn); + } + } + + /** + * Constructor with wikittyService. + * + * @param wikittyService wikitty service + */ + public WikittyClient(WikittyService wikittyService) { + this(); + setWikittyService(wikittyService); + } + + public WikittyClient(ApplicationConfig config, WikittyService wikittyService) { + this(config); + setWikittyService(wikittyService); + } + + static public TimeLog getTimeTrace() { + return timeLog; + } + + static public Map<String, TimeLog.CallStat> getCallCount() { + return timeLog.getCallCount(); + } + + public void login(String login, String password) { + long start = TimeLog.getTime(); + String result = wikittyService.login(login, password); + setSecurityToken(result); + + timeLog.log(start, "login"); + } + + public void logout() { + long start = TimeLog.getTime(); + wikittyService.logout(securityToken); + + timeLog.log(start, "logout"); + } + + public String getSecurityToken() { + return securityToken; + } + + public void setSecurityToken(String securityToken) { + this.securityToken = securityToken; + } + + /** + * get current wikittyUser logged or null if no user logged + * @return null if no user logged + */ + public WikittyUser getUser() { + WikittyUser result = getUser(WikittyUser.class); + return result; + } + + /** + * get current logged user wikitty object + * @param clazz Business class used as User in your application, + * this extension should be require WikittyUser. + * @return null if no user logged + */ + public <E extends BusinessEntity> E getUser(Class<E> clazz) { + E result = null; + if (securityToken != null) { + //Get the token + Wikitty securityTokenWikitty = restore(securityToken); + if (securityTokenWikitty != null) { + //Get the user + String userId = WikittyTokenHelper.getUser(securityTokenWikitty); + result = restore(clazz, userId); + } + } + return result; + } + + public WikittyService getWikittyService() { + return wikittyService.getDelegate(); + } + + public void setWikittyService(WikittyService wikittyService) { + this.wikittyService = new WikittyServiceEnhanced(wikittyService); + } + + public <E extends BusinessEntity> E store(E e) { + Wikitty w = ((BusinessEntityImpl)e).getWikitty(); + store(w); + return e; + } + + public Wikitty store(Wikitty w) { + long start = TimeLog.getTime(); + WikittyEvent resp = wikittyService.store(securityToken, w); + // update object + resp.update(w); + + timeLog.log(start, "store"); + return w; + } + + public <E extends BusinessEntity> E[] store(E e1, E e2, E... eN) { + List<E> es = new ArrayList<E>(eN.length + 2); + Collections.addAll(es, e1, e2); + Collections.addAll(es, eN); + + List<E> list = store(es); + + E[] result = list.toArray((E[])Array.newInstance( + eN.getClass().getComponentType(), list.size())); + return result; + } + + public Wikitty[] store(Wikitty w1, Wikitty w2, Wikitty... wN) { + List<Wikitty> ws = new ArrayList<Wikitty>(wN.length + 2); + Collections.addAll(ws, w1, w2); + Collections.addAll(ws, wN); + + List<Wikitty> resultList = storeWikitty(ws); + Wikitty[] result = resultList.toArray(new Wikitty[resultList.size()]); + return result; + } + + /** + * Store to WikittyService objects. + * + * @param <E> object type + * @param objets list + * @return updated objects list + */ + public <E extends BusinessEntity> List<E> store(List<E> objets) { + long start = TimeLog.getTime(); + // prepare data to send to service + List<Wikitty> wikitties = new ArrayList<Wikitty>(objets.size()); + for (E e : objets) { + if (e == null) { + wikitties.add(null); + } else { + Wikitty w = ((BusinessEntityImpl)e).getWikitty(); + wikitties.add(w); + } + } + + // call the service with Wikitty + WikittyEvent resp = wikittyService.store(securityToken, wikitties); + + // update object + for (Wikitty w : wikitties) { + resp.update(w); + } + + timeLog.log(start, "store<list>"); + return objets; + } + + public List<Wikitty> storeWikitty(List<Wikitty> wikitties) { + long start = TimeLog.getTime(); + + // call the service with Wikitty + WikittyEvent resp = wikittyService.store(securityToken, wikitties); + + // update object + for (Wikitty w : wikitties) { + resp.update(w); + } + + timeLog.log(start, "storeWikitty<list>"); + return wikitties; + } + + /** + * Restore wikitty entity with specified id or {@code null} if entity can't be found. + * + * @param <E> object type + * @param clazz entity class + * @param id entity id + * @param checkExtension if true check that Wikitty result has all extension + * declared in clazz + * @return wikitty entity with specified id or {@code null} if entity can't be found + */ + public <E extends BusinessEntity> E restore(Class<E> clazz, String id, boolean checkExtension) { + try { + long start = TimeLog.getTime(); + E result = null; + if (id != null) { + HashSet<String> extNames = null; + + Wikitty wikitty = wikittyService.restore(securityToken, id); + if (wikitty != null) { + if (checkExtension) { + extNames = new HashSet<String>(wikitty.getExtensionNames()); + } + result = WikittyUtil.newInstance( + securityToken, wikittyService, clazz, wikitty); + + if (checkExtension) { + // WikittyUtil.newInstance instanciate only BusinessEntityWikittyImpl + BusinessEntityImpl b = (BusinessEntityImpl) result; + Collection<WikittyExtension> BusinessEntityStaticExtensions = b.getStaticExtensions(); + for (WikittyExtension ext : BusinessEntityStaticExtensions) { + String extensionName = ext.getName(); + if (!extNames.contains(extensionName)) { + // extension wanted by BusinessEntity (clazz) + // is not in wikitty, then wikitty is not good type + // for business + result = null; + break; + } + } + } + } + } + + timeLog.log(start, "restore<Business>"); + return result; + } catch (SecurityException eee) { + throw eee; + } catch (Exception eee) { + throw new WikittyException("Can't restore wikitty", eee); + } + } + + /** + * Restore wikitty entity with specified id or {@code null} if entity can't be found. + * + * @param id entity id + * @return wikitty entity with specified id or {@code null} if entity can't be found + */ + public Wikitty restore(String id) { + long start = TimeLog.getTime(); + Wikitty result = null; + if (id != null) { + result = wikittyService.restore(securityToken, id); + } + + timeLog.log(start, "restore"); + return result; + } + + /** + * Restore wikitty entity with specified id or {@code null} if entity can't be found. + * + * @param <E> object type + * @param clazz entity class + * @param id entity id + * @return wikitty entity with specified id or {@code null} if entity can't be found + */ + public <E extends BusinessEntity> E restore(Class<E> clazz, String id) { + E result = restore(clazz, id, false); + return result; + } + + /** + * Restore wikitty entity with specified id or {@code null} if entity can't be be found. + * + * @param id entity ids if null return is empty list + * @return wikitty entity with specified id or {@code null} if entity can't be found + */ + public List<Wikitty> restore(List<String> id) { + long start = TimeLog.getTime(); + + List<Wikitty> result; + if (id == null) { + result = new ArrayList<Wikitty>(); + } else { + result = wikittyService.restore(securityToken, id); + } + + timeLog.log(start, "restoreWikitty<list>"); + return result; + } + + /** + * Restore wikitty entity with specified id or {@code null} if entity + * can't be be found, or checkExtension is true and wikitty don't match + * extension wanted. + * + * @param <E> object type + * @param clazz entity class + * @param id entity ids if null return is empty list + * @param checkExtension if true check that Wikitty result has all extension + * @return wikitty entity with specified id or {@code null} if entity + * can't be found or if one wikitty don't have extension wanted by E type + */ + public <E extends BusinessEntity> List<E> restore( + Class<E> clazz, List<String> id, boolean checkExtension) { + long start = TimeLog.getTime(); + List<E> result = new ArrayList<E>(); + + if (id != null) { + List<Wikitty> wikitties = wikittyService.restore(securityToken, id); + + Collection<String> businessExtension = null; + if (checkExtension) { + // Recuperation de la liste des extensions du BusinessEntity resultats + BusinessEntityImpl sample = + (BusinessEntityImpl) WikittyUtil.newInstance(clazz); + businessExtension = sample.getExtensionNames(); + } + + for (Wikitty w : wikitties) { + E dto = null; + if (!checkExtension || + // on ne check pas les extensions ou ... + CollectionUtils.subtract(businessExtension, w.getExtensionNames()).isEmpty()) { + // ... on a retrouve toutes les extensions du wikitty dans l'objet + // on le prend dans les resultats + dto = WikittyUtil.newInstance(clazz, w); + } // sinon on ne prend pas l'objet + + // add entity to result after checkExtension + result.add(dto); + } + } + timeLog.log(start, "restore<list>"); + return result; + } + + public <E extends BusinessEntity> List<E> restore(Class<E> clazz, List<String> id) { + List<E> result = restore(clazz, id, false); + return result; + } + + public Set<Wikitty> restore(Set<String> id) { + ArrayList<String> list = null; + if (id != null) { + list = new ArrayList<String>(id); + } + List<Wikitty> resultList = restore(list); + Set<Wikitty> result = new HashSet<Wikitty>(resultList); + return result; + } + + public <E extends BusinessEntity> Set<E> restore(Class<E> clazz, Set<String> id) { + Set<E> result = restore(clazz, id, false); + return result; + } + + public <E extends BusinessEntity> Set<E> restore(Class<E> clazz, Set<String> id, boolean checkExtension) { + ArrayList<String> list = null; + if (id != null) { + list = new ArrayList<String>(id); + } + List<E> resultList = restore(clazz, list, checkExtension); + Set<E> result = new HashSet<E>(resultList); + return result; + } + + public void delete(String id) { + long start = TimeLog.getTime(); + wikittyService.delete(securityToken, id); + + timeLog.log(start, "delete"); + } + + public <E extends BusinessEntity> void delete(E object) { + long start = TimeLog.getTime(); + if (object != null) { + String id = object.getWikittyId(); + wikittyService.delete(securityToken, id); + } + timeLog.log(start, "delete(BusinessEntity)"); + } + + public void delete(Collection<String> ids) { + long start = TimeLog.getTime(); + wikittyService.delete(securityToken, ids); + + timeLog.log(start, "delete<list>"); + } + + public <E extends BusinessEntity> void delete(List<E> objets) { + long start = TimeLog.getTime(); + + // prepare data to send to service + List<String> ids = new ArrayList<String>(objets.size()); + for (E e : objets) { + if (e != null) { + String id = e.getWikittyId(); + ids.add(id); + } + } + + // call the service with Wikitty + wikittyService.delete(securityToken, ids); + + timeLog.log(start, "delete<list<BusinessEntity>>"); + } + + /** + * Null field are not used in search request. + * + * @param e sample wikitty + * @param firstIndex + * @param endIndex + * @param fieldFacet + * @return + */ + public <E extends BusinessEntityImpl> WikittyQueryResult<E> findAllByExample(E e, + int first, int limit, String ... fieldFacet ) { + long start = TimeLog.getTime(); + + WikittyQuery query = new WikittyQueryMaker().wikitty(e).end() + .setFirst(first).setLimit(limit) + .setFacetField(fieldFacet); + + WikittyQueryResult<String> queryResult = findAllIdByQuery(query); + WikittyQueryResult<E> result = (WikittyQueryResult<E>)castTo( + e.getClass(), queryResult); + + timeLog.log(start, "findAllByExample<limit>"); + return result; + } + + /** + * Null field are not used in search request. + * + * @param e sample wikitty + * @return + */ + public <E extends BusinessEntityImpl> E findByExample(E e) { + long start = TimeLog.getTime(); + WikittyQuery query = new WikittyQueryMaker().wikitty(e).end(); + + String id = findIdByQuery(query); + E result = (E)restore(e.getClass(), id); + + timeLog.log(start, "findByExample"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND ALL BY CRITERIA <E> + // + /////////////////////////////////////////////////////////////////////////// + + /** + * Search object that correspond to criteria and that have all extension + * needed by BusinessEntity (clazz). If one criteria is null, find all extensions + * for this criteria else if criteria is empty return nothing. + * + * @param <E> object type + * @param clazz entity class + * @param criterias criterias + * @return paged result + */ + public <E extends BusinessEntity> List<WikittyQueryResult<E>> findAllByQuery( + Class<E> clazz, List<WikittyQuery> criterias) { + long start = TimeLog.getTime(); + List<WikittyQueryResult<E>> result = null; + if (criterias != null) { + // newInstance only return BusinessEntityWikittyImpl + BusinessEntityImpl sample = + (BusinessEntityImpl) WikittyUtil.newInstance(clazz); + + Wikitty wikitty = sample.getWikitty(); + Collection<String> extensions = wikitty.getExtensionNames(); + + List<WikittyQuery> serviceCriterias = new ArrayList<WikittyQuery>(criterias.size()); + for (WikittyQuery criteria : criterias) { + + // on ajoute la condition sur les extensions dans le critere + // du coup, pour ne pas modifier le critere qui vient en parametre + // il faut creer un nouveau critere ... + WikittyQuery serviceCriteria = null; + if (criteria != null) { + serviceCriteria = criteria.copy(); + + // Dont add contraint if using select + if (StringUtils.isEmpty(criteria.getSelect())) { + + // utilisation de cette nouvelle contrainte sur le nouvel objet + // creation de la nouvelle contrainte + WikittyQueryMaker queryMaker = new WikittyQueryMaker() + .and().condition(serviceCriteria.getCondition()) + .extContainsAll(extensions); + + serviceCriteria.setCondition(queryMaker.getCondition()); + } + } + + // ajout de ce criteria dans la liste de tous les criteres + serviceCriterias.add(serviceCriteria); + } + + List<WikittyQueryResult<String>> pagedResult = wikittyService.findAllByQuery( + securityToken, serviceCriterias); + + // TODO poussin 20110318 optimize cast. Try to cast all pagedResult id + // in one call to service. Currently each PagedResult.cast do a call + result = new ArrayList<WikittyQueryResult<E>>(pagedResult.size()); + for (WikittyQueryResult<String> p : pagedResult) { + result.add((WikittyQueryResult<E>)castTo(sample.getClass(), p)); + } + } + timeLog.log(start, "findAllByCriteria<Business>(List)"); + return result; + } + + /** + * Search object that correspond to criteria and that have all extension + * needed by BusinessEntity (clazz). If criteria is null, find all extensions + * else if criteria is empty return nothing. + * + * @param <E> object type + * @param clazz entity class + * @param criteria criteria + * @return paged result + */ + public <E extends BusinessEntity> WikittyQueryResult<E> findAllByCriteria( + Class<E> clazz, WikittyQuery criteria) { + long start = TimeLog.getTime(); + WikittyQueryResult<E> result = findAllByQuery(clazz, + Collections.singletonList(criteria)).get(0); + timeLog.log(start, "findAllByCriteria<Business>(One)"); + return result; + } + + /** + * Search object that correspond to criteria and that have all extension + * needed by BusinessEntity (clazz). If criteria is null, find all extensions + * else if criteria is empty return nothing. + * + * @param <E> object type + * @param clazz entity class + * @param c1 criteria 1 + * @param c2 criteria 2 + * @param otherCriteria otherCriteria + * @return paged result + */ + public <E extends BusinessEntity> WikittyQueryResult<E>[] findAllByQuery( + Class<E> clazz, 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<E>> resultList = findAllByQuery(clazz, criterias); + WikittyQueryResult<E>[] result = resultList.toArray(new WikittyQueryResult[criterias.size()]); + timeLog.log(start, "findAllByCriteria<Business>(Varargs)"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND ALL BY CRITERIA <Wikitty> + // + /////////////////////////////////////////////////////////////////////////// + + public List<WikittyQueryResult<Wikitty>> findAllByQuery(List<WikittyQuery> criteria) { + long start = TimeLog.getTime(); + List<WikittyQueryResult<Wikitty>> result = null; + if (criteria != null) { + List<WikittyQueryResult<String>> resultId = + wikittyService.findAllByQuery(securityToken, criteria); + + // TODO poussin 20110318 optimize cast. Try to cast all pagedResult id + // in one call to service. Currently each PagedResult.cast do a call + result = new ArrayList<WikittyQueryResult<Wikitty>>(resultId.size()); + for (WikittyQueryResult<String> p : resultId) { + result.add(castTo(Wikitty.class, p)); + } + } + timeLog.log(start, "findAllByCriteria(List)"); + return result; + } + + public WikittyQueryResult<Wikitty> findAllByQuery(WikittyQuery criteria) { + long start = TimeLog.getTime(); + WikittyQueryResult<Wikitty> result = null; + if (criteria != null) { + result = findAllByQuery(Collections.singletonList(criteria)).get(0); + } + timeLog.log(start, "findAllByCriteria(One)"); + return result; + } + + public WikittyQueryResult<Wikitty>[] findAllByQuery( + 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<Wikitty>> resultList = findAllByQuery(criterias); + WikittyQueryResult<Wikitty>[] result = resultList.toArray(new WikittyQueryResult[criterias.size()]); + + timeLog.log(start, "findAllByCriteria(Varargs)"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND ALL ID BY CRITERIA <String> + // + /////////////////////////////////////////////////////////////////////////// + + public List<WikittyQueryResult<String>> findAllIdByQuery(List<WikittyQuery> criteria) { + long start = TimeLog.getTime(); + List<WikittyQueryResult<String>> result = null; + if (criteria != null) { + result = wikittyService.findAllByQuery(securityToken, criteria); + } + timeLog.log(start, "findAllIdByCriteria(List)"); + return result; + } + + public WikittyQueryResult<String> findAllIdByQuery(WikittyQuery criteria) { + long start = TimeLog.getTime(); + WikittyQueryResult<String> result = null; + if (criteria != null) { + result = findAllIdByQuery( + Collections.singletonList(criteria)).get(0); + } + timeLog.log(start, "findAllIdByCriteria(One)"); + return result; + } + + public WikittyQueryResult<String>[] findAllIdByQuery( + 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<String>> resultList = findAllIdByQuery(criterias); + WikittyQueryResult<String>[] result = resultList.toArray(new WikittyQueryResult[criterias.size()]); + + timeLog.log(start, "findAllIdByCriteria(Varargs)"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND ID BY CRITERIA <String> + // + /////////////////////////////////////////////////////////////////////////// + + public List<String> findIdByQuery(List<WikittyQuery> criteria) { + long start = TimeLog.getTime(); + List<String> result = null; + if (criteria != null) { + result = wikittyService.findByQuery(securityToken, criteria); + } + timeLog.log(start, "findIdByCriteria(List)"); + return result; + } + + public String findIdByQuery(WikittyQuery criteria) { + long start = TimeLog.getTime(); + String result = null; + if (criteria != null) { + result = findIdByQuery(Collections.singletonList(criteria)).get(0); + } + timeLog.log(start, "findIdByCriteria(One)"); + return result; + } + + public String[] findIdByQuery( + 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<String> resultList = findIdByQuery(criterias); + String[] result = resultList.toArray(new String[criterias.size()]); + + timeLog.log(start, "findIdByCriteria(Varargs)"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND BY CRITERIA <E> + // + /////////////////////////////////////////////////////////////////////////// + + public <E extends BusinessEntity> List<E> findByQuery( + Class<E> clazz, List<WikittyQuery> criterias) { + long start = TimeLog.getTime(); + List<E> result = null; + if (criterias != null) { + BusinessEntityImpl sample = + (BusinessEntityImpl) WikittyUtil.newInstance(clazz); + + Wikitty wikitty = sample.getWikitty(); + Collection<String> extensions = wikitty.getExtensionNames(); + List<WikittyQuery> serviceCriterias = new ArrayList<WikittyQuery>(criterias.size()); + for (WikittyQuery criteria : criterias) { + // on a pas besoin de recuperer les limits du query puisqu'on en + // veut qu'un et donc qu'on ne retourne pas de WikittyQueryResult + // donc on ne fait pas une copie, on en cree un nouveau directement + // a partir de la condition + WikittyQuery q = new WikittyQueryMaker() + .and().condition(criteria.getCondition()) + .extContainsAll(extensions).end(); + serviceCriterias.add(q); + } + + List<String> id = findIdByQuery(serviceCriterias); + result = restore(clazz, id); + } + timeLog.log(start, "multiFindByCriteria<Business>(List>"); + return result; + } + + public <E extends BusinessEntity> E findByQuery( + Class<E> clazz, WikittyQuery criteria) { + long start = TimeLog.getTime(); + E result = null; + if (criteria != null) { + List<E> criterias = findByQuery(clazz, Collections.singletonList(criteria)); + if (!criterias.isEmpty()) { + result = criterias.get(0); + } + } + timeLog.log(start, "findByCriteria<Business>(One)"); + return result; + } + + public <E extends BusinessEntity> E[] findByQuery( + Class<E> clazz, 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<E> resultList = findByQuery(clazz, criterias); + E[] result = resultList.toArray((E[])Array.newInstance(clazz, resultList.size())); + + timeLog.log(start, "findByCriteria<Business>(Varargs)"); + return result; + } + + /////////////////////////////////////////////////////////////////////////// + // + // FIND BY CRITERIA <Wikitty> + // + /////////////////////////////////////////////////////////////////////////// + + public List<Wikitty> findByQuery(List<WikittyQuery> criteria) { + long start = TimeLog.getTime(); + List<Wikitty> result = null; + if (criteria != null) { + List<String> id = findIdByQuery(criteria); + result = restore(id); + } + timeLog.log(start, "findByCriteria(List)"); + return result; + } + + public Wikitty findByQuery(WikittyQuery criteria) { + long start = TimeLog.getTime(); + String id = findIdByQuery(criteria); + Wikitty wikitty = restore(id); + timeLog.log(start, "findByCriteria(One)"); + return wikitty; + } + + public Wikitty[] findByQuery( + 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<String> resultList = findIdByQuery(criterias); + List<Wikitty> wikitties = restore(resultList); + Wikitty[] result = wikitties.toArray(new Wikitty[resultList.size()]); + + timeLog.log(start, "findByCriteria(Varargs)"); + return result; + } + + + /////////////////////////////////////////////////////////////////////////// + // + // FIND BY TREE NODE + // + /////////////////////////////////////////////////////////////////////////// + + /** + * Recupere une portion d'arbre a partir de l'id passer en parametre. L'id + * doit etre celui d'un WikittyTreeNode. Ce WikittyTreeNode est alors le + * root de l'arbre retourne. + * + * Return Wikitty in result, those Wikitties have WikittyTreeNode extension + * + * @param wikittyId root + * @param depth profondeur de noeud a recuperer + * @param count vrai si l'on veut le nombre de piece attaches sur le noeud + * (piece des enfants compris) + * @param filter filter pour compter les pieces attachees + * @return treeNodeResult of wikitty + * + * @since 3.1 + */ + public WikittyQueryResultTreeNode<Wikitty> findTreeNode( + String wikittyId, int depth, boolean count, WikittyQuery filter) { + long start = TimeLog.getTime(); + + WikittyQueryResultTreeNode<String> resultId = wikittyService.findTreeNode( + securityToken, wikittyId, depth, count, filter); + + RetrieveIdVisitor retrieveIdVisitor = new RetrieveIdVisitor(); + resultId.acceptVisitor(retrieveIdVisitor); + + List<String> ids = retrieveIdVisitor.getIds(); + List<Wikitty> wikitties = restore(ids); + + IdToObjectConverter<Wikitty> converter = + new IdToObjectConverter<Wikitty>(ids, wikitties); + + ConvertTreeVisitor<Wikitty> convertVisitor = + new ConvertTreeVisitor<Wikitty>(converter); + + resultId.acceptVisitor(convertVisitor); + + WikittyQueryResultTreeNode<Wikitty> result = convertVisitor.getTree(); + timeLog.log(start, "findTreeNode<Wikitty>"); + return result; + } + + /** + * Recupere une portion d'arbre a partir de l'id passer en parametre. L'id + * doit etre celui d'un WikittyTreeNode. Ce WikittyTreeNode est alors le + * root de l'arbre retourne. + * + * Return E in result + * + * @param clazz business class wanted to replace id in TreeNodeResult + * @param wikittyId root + * @param depth profondeur de noeud a recuperer + * @param count vrai si l'on veut le nombre de piece attaches sur le noeud (piece des enfants compris) + * @param filter filter pour compter les pieces attachees + * @return + * + * @since 3.1 + */ + public <E extends BusinessEntity> WikittyQueryResultTreeNode<E> findTreeNode( + Class<E> clazz, String wikittyId, int depth, + boolean count, WikittyQuery filter) { + long start = TimeLog.getTime(); + + WikittyQueryResultTreeNode<String> resultId = wikittyService.findTreeNode( + securityToken, wikittyId, depth, count, filter); + + RetrieveIdVisitor retrieveIdVisitor = new RetrieveIdVisitor(); + resultId.acceptVisitor(retrieveIdVisitor); + + List<String> ids = retrieveIdVisitor.getIds(); + List<E> wikitties = restore(clazz, ids); + + IdToObjectConverter<E> converter = + new IdToObjectConverter<E>(ids, wikitties); + + ConvertTreeVisitor<E> convertVisitor = + new ConvertTreeVisitor<E>(converter); + + resultId.acceptVisitor(convertVisitor); + + WikittyQueryResultTreeNode<E> result = convertVisitor.getTree(); + timeLog.log(start, "findTreeNode"); + return result; + } + + /** + * Used to collect all node id + * @since 3.1 + */ + static private class RetrieveIdVisitor implements WikittyQueryResultTreeNode.Visitor<String> { + + protected List<String> ids = new ArrayList<String>(); + + public List<String> getIds() { + return ids; + } + + @Override + public boolean visitEnter(WikittyQueryResultTreeNode<String> node) { + String id = node.getObject(); + ids.add(id); + return true; + } + + @Override + public boolean visitLeave(WikittyQueryResultTreeNode<String> node) { + return true; + } + } + + /** + * Converti un id en son object WikittyTreeNode + * @since 3.1 + */ + static private class IdToObjectConverter<T> implements ConvertTreeVisitor.Converter<String, T> { + protected Map<String, T> objects = new HashMap<String, T>(); + protected String securityToken; + protected WikittyService wikittyService; + public IdToObjectConverter(List<String> ids, List<T> objectList) { + + for (int i = 0; i < ids.size(); i++) { + this.objects.put(ids.get(i), objectList.get(i)); + } + } + + @Override + public T convert(String id) { + T result = objects.get(id); + return result; + } + } + + /** + * Parcours un TreeNodeResult et en fait une copie en modifiant le type + * d'objet stocker dans le noeud grace a un converter, si le converter + * est null une exception est levee + * + * @param <TARGET> le type d'objet pour le nouvel arbre + * @since 3.1 + */ + static private class ConvertTreeVisitor<TARGET extends Serializable> + implements WikittyQueryResultTreeNode.Visitor<String> { + + static private interface Converter<SOURCE, TARGET> { + public TARGET convert(SOURCE o); + } + protected Converter<String, TARGET> converter; + protected WikittyQueryResultTreeNode<TARGET> tree = null; + protected LinkedList<WikittyQueryResultTreeNode<TARGET>> stack = + new LinkedList<WikittyQueryResultTreeNode<TARGET>>(); + + public ConvertTreeVisitor(Converter<String, TARGET> converter) { + this.converter = converter; + if (converter == null) { + throw new IllegalArgumentException("Converter can't be null"); + } + } + + public WikittyQueryResultTreeNode<TARGET> getTree() { + return tree; + } + + @Override + public boolean visitEnter(WikittyQueryResultTreeNode<String> node) { + String id = node.getObject(); + int count = node.getAttCount(); + + TARGET object = converter.convert(id); + WikittyQueryResultTreeNode<TARGET> newNode = new WikittyQueryResultTreeNode<TARGET>( + object, count); + + WikittyQueryResultTreeNode<TARGET> parent = stack.peekLast(); + if (parent == null) { + // le premier noeud, donc le root a retourner plus tard + tree = newNode; + } else { + parent.add(newNode); + } + + stack.offerLast(newNode); + + return true; + } + + @Override + public boolean visitLeave(WikittyQueryResultTreeNode<String> node) { + stack.pollLast(); + return true; + } + } + + /** + * Recupere une portion d'arbre a partir de l'id passer en parametre. L'id + * doit etre celui d'un WikittyTreeNode. Ce WikittyTreeNode est alors le + * root de l'arbre retourne. + * + * Return just wikitty Id in result + * + * @param wikittyId + * @param depth + * @param count + * @param filter + * @return + * @since 3.1 + */ + public WikittyQueryResultTreeNode<String> findAllIdTreeNode( + String wikittyId, int depth, boolean count, WikittyQuery filter) { + long start = TimeLog.getTime(); + WikittyQueryResultTreeNode<String> result = wikittyService.findTreeNode( + securityToken, wikittyId, depth, count, filter); + + timeLog.log(start, "findAllIdTreeNode"); + return result; + } + + /** + * Delete specified tree node and all sub nodes. + * + * @param treeNodeId tree node id to delete + * @return {@true} if at least one node has been deleted + */ + public WikittyEvent deleteTree(String treeNodeId) { + long start = TimeLog.getTime(); + WikittyEvent result = wikittyService.deleteTree(securityToken,treeNodeId); + + timeLog.log(start, "deleteTree"); + return result; + } + + public Wikitty restoreVersion(String wikittyId, String version) { + long start = TimeLog.getTime(); + Wikitty result = wikittyService.restoreVersion( + securityToken, wikittyId, version); + + timeLog.log(start, "restoreVersion"); + return result; + } + + /** + * Manage Update and creation. + * + * @param ext extension to be persisted + * @return update response + */ + public WikittyEvent storeExtension(WikittyExtension ext) { + long start = TimeLog.getTime(); + WikittyEvent response = + wikittyService.storeExtension(securityToken, ext); + + timeLog.log(start, "storeExtension"); + return response; + } + + /** + * Manage Update and creation. + * + * @param exts list of wikitty extension to be persisted + * @return update response + */ + public WikittyEvent storeExtension(Collection<WikittyExtension> exts) { + long start = TimeLog.getTime(); + WikittyEvent response = + wikittyService.storeExtension(securityToken, exts); + + timeLog.log(start, "storeExtension<list>"); + return response; + } + + /** + * Load extension from id. Id is 'name[version]'. + * + * @param extensionId extension id to restore + * @return the corresponding object, exception if no such object found. + */ + public WikittyExtension restoreExtension(String extensionId) { + long start = TimeLog.getTime(); + WikittyExtension extension = wikittyService.restoreExtension(securityToken, extensionId); + + timeLog.log(start, "restoreExtension"); + return extension; + } + + /** + * Search extension with name in last version. + * + * @param extensionName extension name + * @return the corresponding object, exception if no such object found. + */ + public WikittyExtension restoreExtensionLastVersion(String extensionName) { + long start = TimeLog.getTime(); + WikittyExtension extension = wikittyService.restoreExtensionLastVersion(securityToken, extensionName); + + timeLog.log(start, "restoreExtensionLastVersion"); + return extension; + } + + /** + * Search extension with name in last version. + * + * @param extensionNames extension name + * @return extension wanted with dependencies extensions at head of list + */ + public List<WikittyExtension> restoreExtensionAndDependenciesLastVesion(Collection<String> extensionNames) { + long start = TimeLog.getTime(); + List<WikittyExtension> result = + wikittyService.restoreExtensionAndDependenciesLastVesion( + securityToken, extensionNames); + + timeLog.log(start, "restoreExtensionAndDependenciesLastVesion"); + return result; + + } + + public void deleteExtension(String extName) { + long start = TimeLog.getTime(); + wikittyService.deleteExtension(securityToken, extName); + + timeLog.log(start, "deleteExtension"); + } + + public void deleteExtension(Collection<String> extNames) { + long start = TimeLog.getTime(); + wikittyService.deleteExtension(securityToken, extNames); + + timeLog.log(start, "deleteExtension<list>"); + } + + /** + * Return all extension id (ex: "extName[version])"). + * + * @return extension id list + */ + public List<String> getAllExtensionIds() { + long start = TimeLog.getTime(); + List<String> result = wikittyService.getAllExtensionIds(securityToken); + + timeLog.log(start, "getAllExtensionIds"); + return result; + } + + /** + * Return all extension id (ex: "extName[version])") where + * {@code extensionName} is required. + * + * @param extensionName extension name + * @return extensions + */ + public List<String> getAllExtensionsRequires(String extensionName) { + long start = TimeLog.getTime(); + List<String> result = wikittyService.getAllExtensionsRequires(securityToken, extensionName); + + timeLog.log(start, "getAllExtensionsRequires"); + return result; + } + + /** + * Use with caution : It will delete ALL indexes from search engine ! + * This operation should be disabled in production environment. + */ + public WikittyEvent clear() { + long start = TimeLog.getTime(); + WikittyEvent result = wikittyService.clear(securityToken); + + timeLog.log(start, "clear"); + return result; + } + + /** + * Synchronize search engine with wikitty storage engine, i.e. clear and + * reindex all object. + */ + public void syncSearchEngine() { + long start = TimeLog.getTime(); + wikittyService.syncSearchEngine(securityToken); + + timeLog.log(start, "syncSearchEngine"); + } + + /** + * Method to get the Wikitty encapsulated into a BusinessEntity + * + * This method can go to serveur side, if BusinessEntity is not + * BusinessEntityImpl, this append when use GWT + * + * @param entity the BusinessEntity encapsulating the Wikitty + * @return the wikitty encapsulated + */ + public Wikitty getWikitty(BusinessEntity entity){ + long start = TimeLog.getTime(); + Wikitty result; + + if (entity instanceof BusinessEntityImpl) { + result = ((BusinessEntityImpl) entity).getWikitty(); + } else { + String id = entity.getWikittyId(); + + result = restore(id); + + //try settings all fields except version + try { + //get all fields + Class entityClass = entity.getClass(); + Field[] fields = entityClass.getDeclaredFields(); + + for(Field field:fields){ + //for each field that got WikittyField annotation + if (field.isAnnotationPresent(WikittyField.class)){ + + //get the attribute's wikitty fqn + WikittyField annotation = field.getAnnotation(WikittyField.class); + String fieldFQN = annotation.fqn(); + + //set the value + Method m = entityClass.getMethod("get" + StringUtils.capitalize(field.getName())); + Object value = m.invoke(entity); + + result.setFqField(fieldFQN, value); + } + } + } catch (Exception eee) { + throw new WikittyException("Could not transform entity to Wikitty", eee); + } + + //manually set version + result.setVersion(entity.getWikittyVersion()); + } + + timeLog.log(start, "getWikitty"); + return result; + } + + /** + * Check that the logged in user is in a group. A #SecurityException might + * be thrown at runtime if the #WikittyUser session timed out. + * @param groupName the name of the group to check + * @return true is the logged in user is in the group + */ + public boolean isMember(String groupName) { + long start = TimeLog.getTime(); + boolean result = false; + + WikittyUser user = getLoggedInUser(); + + //Find the group from its name + WikittyQuery criteria = new WikittyQueryMaker().and() + .exteq(WikittyGroup.EXT_WIKITTYGROUP) + .eq(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, groupName) + .end(); + + Wikitty group = findByQuery(criteria); + + if (group != null && user != null) { + result = WikittySecurityUtil.isMember(wikittyService, securityToken, + user.getWikittyId(), group.getId()); + } + + timeLog.log(start, "isMember"); + return result; + } + + /** + * Get the #WikittyUser that is logged in. A #SecurityException might be + * thrown at runtime if the #WikittyUser session timed out. + * @return the logged in #WikittyUser + */ + public WikittyUser getLoggedInUser() { + long start = TimeLog.getTime(); + + String userId = WikittySecurityUtil.getUserForToken(wikittyService, + securityToken); + + WikittyUser user = restore(WikittyUser.class, userId); + + timeLog.log(start, "getLoggedInUser"); + return user; + } + + /** + * Convert all result to the wanted type and return new WikittyQueryResult + * with this new result list. For business object transformation, if some + * result don't have the right extension (clazz) this extension is + * automatically added. + * + * @param queryResult result to convert + * @param target to cast into. + * Can be Wikitty, BusinessEntity, String, Date, BigDecimal, Boolean, byte[] + * @return new WikittyQueryResult with element in right class or Exception + * if conversion is impossible + */ + public <E> WikittyQueryResult<E> castTo(Class<E> target, + WikittyQueryResult queryResult) { + List<E> castedResult; + + if (queryResult.size() == 0) { + // on ne fait rien on met juste une nouvelle liste vide + castedResult = new ArrayList<E>(); + } else if (target.isAssignableFrom(Wikitty.class)) { + // On veut des Wikitties en sortie + + if (queryResult.peek() instanceof Wikitty) { + // W, rien a faire + castedResult = queryResult.getAll(); + } else if (queryResult.peek() instanceof BusinessEntityImpl) { + // BusinessEntityImpl, il faut recuperer les wikitty + castedResult = new ArrayList<E>(queryResult.size()); + for (BusinessEntityImpl e : (WikittyQueryResult<BusinessEntityImpl>)queryResult) { + castedResult.add((E)e.getWikitty()); + } + } else if (queryResult.peek() instanceof String) { + // String, il faut faire un restore + // le queryResult courant contient des Ids + // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant + // ce queryResult ne sait pas ce qu'il fait :) + List<String> ids = (List<String>) queryResult.getAll(); + castedResult = (List<E>)getWikittyService().restore(securityToken, ids); + } else { + throw new ClassCastException("WikittyQueryResult don't contains" + + " object convertible to Wikitty" + + " (accepted Wikitty, BusinessEntityImpl, String id) but " + + queryResult.peek().getClass()); + } + } else if (target.isAssignableFrom(BusinessEntityImpl.class)) { + // on commence par tout mettre en Wikitty, en utilisant le if du dessus + WikittyQueryResult<Wikitty> resultTmp = castTo(Wikitty.class, queryResult); + castedResult = (List<E>)WikittyUtil.newInstance((Class<BusinessEntity>)target, resultTmp.getAll()); + } else if (target.isAssignableFrom(BigDecimal.class)) { + castedResult = new ArrayList<E>(queryResult.size()); + for (Object o : queryResult) { + BigDecimal v = WikittyUtil.toBigDecimal(o); + castedResult.add((E)v); + } + } else if (target.isAssignableFrom(Date.class)) { + castedResult = new ArrayList<E>(queryResult.size()); + for (Object o : queryResult) { + Date v = WikittyUtil.toDate(o); + castedResult.add((E)v); + } + } else if (target.isAssignableFrom(Boolean.class)) { + castedResult = new ArrayList<E>(queryResult.size()); + for (Object o : queryResult) { + Boolean v = WikittyUtil.toBoolean(o); + castedResult.add((E)v); + } + } else if (target.isAssignableFrom(byte[].class)) { + castedResult = new ArrayList<E>(queryResult.size()); + for (Object o : queryResult) { + byte[] v = WikittyUtil.toBinary(o); + castedResult.add((E)v); + } + } else if (target.isAssignableFrom(String.class)) { + castedResult = new ArrayList<E>(queryResult.size()); + for (Object o : queryResult) { + String v = WikittyUtil.toString(o); + castedResult.add((E)v); + } + }else { + throw new ClassCastException(String.format( + "WikittyQueryResult don't contains" + + " object convertible to %s" + + " (accepted Wikitty, BusinessEntityImpl, String id, Date," + + " BigDecimal, Boolean, byte[]) but '%s'", + target.getName(), queryResult.peek().getClass())); + } + + WikittyQueryResult<E> result = new WikittyQueryResult<E>( + queryResult.getQueryName(), + queryResult.getFirst(), queryResult.getTotalResult(), + queryResult.getQueryString(), queryResult.getFacets(), + castedResult); + return result; + } + + + +} Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyProxy.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyProxy.java 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyProxy.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -72,7 +72,9 @@ * * Last update: $Date$ * by : $Author$ + * @deprecated since 3.3 use {@link WikittyClient} */ +@Deprecated public class WikittyProxy { /** to use log facility, just put in your code: log.info(\"...\"); */ @@ -1235,6 +1237,19 @@ return result; } + /** + * XXX poussin 20111229 cette methode n'est pas documentee et ne semble pas + * utilisee, heureusement car son implantation est fausse :(. + * On cree un BusinessEntity autour d'un wikitty puis ensuite on check les + * extension, or lors de la creation du BusinessEntity sur le wikitty celui + * ci a ajouter toutes les extensions. donc cette methode doit toujours + * retourne vrai :( + * + * @param <E> + * @param clazz + * @param wikittyId + * @return + */ public <E extends BusinessEntity> boolean hasType(Class<E> clazz, String wikittyId) { try { long start = TimeLog.getTime(); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -741,7 +741,7 @@ if (!BusinessEntityImpl.class .isAssignableFrom(clazzInstanciable)) { throw new WikittyException(String.format( - "Your class '%s' don't extends WikittyDto", clazz + "Your class '%s' don't extends BusinessEntityImpl", clazz .getName())); } @@ -755,6 +755,49 @@ } /** + * Create new Business Entity with specified Wikitty + * @param target Business Entity class + * @param w wikitty to used + * @return + */ + static public <E extends BusinessEntity> E newInstance(Class<E> target, Wikitty w) { + E result = newInstance(target); + BusinessEntityImpl bean = (BusinessEntityImpl) result; + bean.setWikitty(w); + + return result; + } + + /** + * Cast Business object to another Business Object + * If source don't have target extension, this extension is added + * + * @param source business entity source + * @param target business entity class wanted + * @return new instance of object wanted + */ + public <E extends BusinessEntity> E newInstance(Class<E> target, BusinessEntityImpl source) { + E result = newInstance(target, source.getWikitty()); + return result; + } + + + /** + * Create new Business Entity List from wikitties + * @param target Business Entity class + * @param wikitties list of wikitties + * @return new list of Business Entity + */ + static public <E extends BusinessEntity> List<E> newInstance(Class<E> target, List<Wikitty> wikitties) { + List<E> result = new ArrayList<E>(wikitties.size()); + for (Wikitty w : wikitties) { + result.add(newInstance(target, w)); + } + return result; + } + + + /** * Create new instance of BusinessEntity from Wikitty object passed in argument. * If argument is Interface try to add 'Impl' to find instanciable class. * <p> @@ -766,7 +809,12 @@ * @param clazz class of the new instance * @param w wikitty object to use internaly for in new instance * @return new instance + * + * @deprecated since 3.3 il n'est pas coherent d'acceder au serveur lorsqu'on + * instancie un objet. La verification de la securite de toute facon ne + * se fait qu'au moment de la sauvegarde. */ + @Deprecated static public <E extends BusinessEntity> E newInstance(String securityToken, WikittyService wikittyService, Class<E> clazz, Wikitty w) { try { @@ -786,7 +834,7 @@ if (!BusinessEntityImpl.class .isAssignableFrom(clazzInstanciable)) { throw new WikittyException(String.format( - "Your class '%s' don't extends WikittyDto", clazz + "Your class '%s' don't extends BusinessEntityImpl", clazz .getName())); } @@ -800,6 +848,9 @@ result = (E) cons.newInstance(parms); BusinessEntityImpl bean = (BusinessEntityImpl) result; + // FIXME poussin 20111229 on ne devrait pas avoir besoin + // d'acceder au serveur ici :(. Voir si le check est vraiment + // util checkExtensionVersion(securityToken, wikittyService, w, bean); bean.setWikitty(w); @@ -1106,6 +1157,15 @@ return result; } + /** + * + * @param service + * @param securityToken + * @param entity + * @return + * @deprecated since 3.3 use {@link WikittyClient#getWikitty(org.nuiton.wikitty.entities.BusinessEntity)} + */ + @Deprecated static public Wikitty getWikitty(WikittyService service, String securityToken, BusinessEntity entity) { Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/BusinessEntity.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/BusinessEntity.java 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/BusinessEntity.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -30,7 +30,10 @@ import java.util.Collection; /** - * Used as parent interface to all Business class + * Used as parent interface to all Business class. + * + * getWikitty and setWikitty is not in interface because this objet for some + * implementation (GWT) is to complexe * * @author poussin * @version $Revision$ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -46,6 +46,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.util.ObjectUtil; +import org.nuiton.util.VersionUtil; import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.WikittyUtil; import org.nuiton.wikitty.generator.WikittyTransformerUtil; @@ -289,6 +290,19 @@ */ @Override public void addExtension(WikittyExtension ext) { + // on check qu'on avait pas deja cette extension dans une version plus + // recente, dans ce cas, on leve une exception en disant qu'il faut + // se mettre a jour + WikittyExtension currentExt = extensions.get(ext.getName()); + if (currentExt != null && + VersionUtil.greaterThan(currentExt.getVersion(), ext.getVersion())) { + throw new WikittyException(String.format( + "You try to put extension '%s' in older version (%s) than" + + " current version (%s). You must update your software.", + ext.getName(), ext.getVersion(), currentExt.getVersion())); + } + + // on check les dependances List required = ext.getRequires(); if (required != null && !required.isEmpty() && !extensions.keySet().containsAll(required)) { @@ -297,6 +311,7 @@ " required not available extension '%s' in this wikitty", ext.getName(), required)); } + extensions.put(ext.name, ext); } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryMaker.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -11,6 +11,10 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.BusinessEntity; +import org.nuiton.wikitty.entities.BusinessEntityImpl; +import org.nuiton.wikitty.entities.FieldType; +import org.nuiton.wikitty.entities.Wikitty; import org.nuiton.wikitty.query.conditions.And; import org.nuiton.wikitty.query.conditions.Between; import org.nuiton.wikitty.query.conditions.Condition; @@ -193,6 +197,49 @@ } /** + * Ajoute une contrainte qui cree les conditions en prenant comme exemple + * l'objet passer en parametre. Seuls les champs non null sont utilises ainsi + * que la liste des extensions de l'objet + * + * @param w le wikitty a prendre comme exemple + * @return {@code this} with the {@code w} restriction added. + */ + public WikittyQueryMaker wikitty(Wikitty w) { + WikittyQueryMaker result = new WikittyQueryMaker().and(); + + // result object must have same extension that wikitty example + result.extContainsAll(w.getExtensionNames()); + + for (String fqfieldName : w.fieldNames()) { + Object value = w.getFqField(fqfieldName); + if (value != null) { + FieldType type = w.getFieldType(fqfieldName); + if (type.isCollection()) { + result.containsAll(fqfieldName, (Collection<?>)value); + } else { + result.eq(fqfieldName, value); + } + } + } + addCondition(result.getCondition()); + + return this; + } + + /** + * Ajoute une contrainte qui cree les conditions en prenant comme exemple + * l'objet passer en parametre. Seuls les champs non null sont utilises ainsi + * que la liste des extensions de l'objet + * + * @param e l'objet a prendre comme exemple + * @return {@code this} with the {@code e} restriction added. + */ + public WikittyQueryMaker wikitty(BusinessEntityImpl e) { + Wikitty w = e.getWikitty(); + return wikitty(w); + } + + /** * Contains. * * Search on lists (multivalued fields) that a field contains all the values 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 2011-12-29 14:29:52 UTC (rev 1265) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryResult.java 2011-12-29 19:04:15 UTC (rev 1266) @@ -1,7 +1,6 @@ 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; @@ -10,16 +9,12 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.nuiton.wikitty.WikittyException; -import org.nuiton.wikitty.WikittyProxy; -import org.nuiton.wikitty.WikittyService; -import org.nuiton.wikitty.WikittyUtil; -import org.nuiton.wikitty.entities.BusinessEntityImpl; -import org.nuiton.wikitty.entities.Wikitty; -import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.WikittyClient; /** - * Represente un resultat de requete {@link WikittyQuery} + * Represente un resultat de requete {@link WikittyQuery}. Pour caster les + * valeurs dans une autre representation vous pouvez utiliser la methode + * {@link WikittyClient#cast(org.nuiton.wikitty.query.WikittyQueryResult, java.lang.Class)} * * @author poussin * @version $Revision$ @@ -76,122 +71,6 @@ this.results = Collections.unmodifiableList(results); } - /** - * Call {@link #cast(WikittyProxy, Class, boolean)} with - * autoconvert = true - * - * @param proxy used to retrieve securityToken and WikittyService - * @param clazz target PagedResult type - * @return new PagedResult, this result can have less elements that original - * for some reason (security, ...) - */ - public <E extends BusinessEntityImpl> WikittyQueryResult<E> cast( - WikittyProxy proxy, Class<E> clazz) { - return cast(proxy, clazz, true); - } - - /** - * Convert all result to the wikitty type and return new PagedResult with - * this new result list. - * - * @param securityToken security token - * @param ws wikitty service - * - * @return new PagedResult, this result can have less elements that original - * for some reason (security, ...) - */ - public WikittyQueryResult<Wikitty> WikittyQueryResult(String securityToken, WikittyService ws) { - List<Wikitty> castedResult; - - if (results.size() == 0) { - castedResult = new ArrayList<Wikitty>(); - } else { - if (results.get(0) instanceof String) { - // le pagedresult courant contient des Ids - // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant - // ce PagedResult ne sait pas ce qu'il fait :) - List<String> ids = (List<String>) results; - castedResult = ws.restore(securityToken, ids); - } else { - throw new ClassCastException("WikittyQueryResult don't contains" + - " wikitty String id but " + results.get(0).getClass()); - } - } - WikittyQueryResult<Wikitty> result = new WikittyQueryResult<Wikitty>(queryName, - first, totalResult, queryString, facets, castedResult); - return result; - } - - /** - * Convert all result to the wanted type and return new PagedResult with - * this new result list. If some result don't have the right extension (clazz) - * this extension is automatically added if autoconvert is true. Else - * an exception is thrown when result without extension is found. - * - * When you used autoconvert = false, you have a potentially problem when - * you have modified a BusinessEntity to have new extension and all your - * wikitty object are not uptodate in database. - * - * @param <E> class to cast into - * @param proxy used to retrieve securityToken and WikittyService - * @param autoconvert if autoconvert is false and object don't all needed - * extension, object is not put in the result - * @return new PagedResult, this result can have less elements that original - * for some reason (security, ...) - */ - public <E extends BusinessEntityImpl> WikittyQueryResult<E> cast( - WikittyProxy proxy, Class<E> clazz, boolean autoconvert) { - List<E> castedResult; - - if (results.size() > 0 && results.get(0) instanceof String) { - // le pagedresult courant contient des Ids - // Si ce n'est pas le cas, ca veut dire que le developpeur utilisant - // ce PagedResult ne sait pas ce qu'il fait :) - List<String> ids = (List<String>)results; - castedResult = proxy.restore(clazz, ids, !autoconvert); - } else { - castedResult = new ArrayList<E>(results.size()); - E sample = WikittyUtil.newInstance(clazz); - Collection<WikittyExtension> wantedExtension = sample.getStaticExtensions(); - for (T t : results) { - if (t == null) { - castedResult.add(null); - } else { - Wikitty w = null; - if (t instanceof Wikitty) { - w = (Wikitty) t; - } else if (t instanceof BusinessEntityImpl) { - w = ((BusinessEntityImpl) t).getWikitty(); - } else { - throw new WikittyException(String.format( - "Illegal object result class '%s' can't convert it to class '%s'", - t.getClass().getName(), clazz.getName())); - } - - Collection<WikittyExtension> wikittyExtension = w.getExtensions(); - if (autoconvert || wikittyExtension.containsAll(wantedExtension)) { - E e = WikittyUtil.newInstance(proxy.getSecurityToken(), - proxy.getWikittyService(), clazz, (Wikitty) t); - castedResult.add(e); - } else { - // silently pass current object, this object is not put - // in result - if (log.isDebugEnabled()) { - log.debug(String.format( - "Illegal object result class '%s' can't convert it to '%s'" + - "there is no same extension %s != %s", - t.getClass().getName(), clazz.getName(), - wikittyExtension, wantedExtension)); - } - } - } - } - } - WikittyQueryResult<E> result = new WikittyQueryResult<E>(queryName, - first, totalResult, queryString, facets, castedResult); - return result; - } - public String getQueryName() { return queryName; }