r457 - in trunk/wikitty-api/src: main/java/org/nuiton/wikitty test/java/org/nuiton/wikitty test/java/org/nuiton/wikitty/notification
Author: bpoussin Date: 2010-10-29 02:35:39 +0200 (Fri, 29 Oct 2010) New Revision: 457 Url: http://nuiton.org/repositories/revision/wikitty/457 Log: add WikittyServiceTransaction and small test http://www.nuiton.org/issues/show/1000 Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceTransaction.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyServiceTransactionTest.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceCached.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceDelegator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceEvent.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceImpl.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceInMemory.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceListener.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceNotifier.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceSecurity.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/notification/WikittyServiceNotificationTest.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2010-10-29 00:35:39 UTC (rev 457) @@ -167,6 +167,34 @@ public boolean canRead(String securityToken, String wikittyId); /** + * true if wikitty with id exists, even wikitty is deleted + */ + public boolean exists(String securityToken, String wikittyId); + + /** + * true if wikitty is deleted, throw an exception if id don't exist + * @param securityToken + * @param wikittyId + * @return + */ + public boolean isDeleted(String securityToken, String wikittyId); + + /** + * Replay all events in argument on this WikittyService + * + * @param securityToken security token + * @param events event to replay + * @return new event that represent all event passed in argument. + * if arguement have: store, store, delete, clear, store. Return event + * resume all by only one clear + store, because all action before clear is + * not necessary. Similarly for store + delete for the same object. + * (note: perhaps this broke history, when history are implanted and + * two serveur must have same history ?) + */ + public WikittyServiceEvent replay( + String securityToken, List<WikittyServiceEvent> events); + + /** * Manage Update and creation, action is done in transaction passed in * argument. * Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceCached.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceCached.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceCached.java 2010-10-29 00:35:39 UTC (rev 457) @@ -429,4 +429,19 @@ ws.syncEngin(securityToken); } + @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + return ws.replay(securityToken, events); + } + + @Override + public boolean exists(String securityToken, String wikittyId) { + return ws.exists(securityToken, wikittyId); + } + + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + return ws.isDeleted(securityToken, wikittyId); + } + } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceDelegator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceDelegator.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceDelegator.java 2010-10-29 00:35:39 UTC (rev 457) @@ -96,6 +96,11 @@ } @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + return delegate.replay(securityToken, events); + } + + @Override public WikittyServiceEvent store(String securityToken, WikittyTransaction transaction, Collection<Wikitty> wikitties, boolean force) { @@ -202,4 +207,14 @@ public boolean canRead(String securityToken, String wikittyId) { return delegate.canRead(securityToken, wikittyId); } + + @Override + public boolean exists(String securityToken, String wikittyId) { + return delegate.exists(securityToken, wikittyId); + } + + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + return delegate.isDeleted(securityToken, wikittyId); + } } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceEvent.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceEvent.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceEvent.java 2010-10-29 00:35:39 UTC (rev 457) @@ -61,7 +61,8 @@ REMOVE_WIKITTY(WikittyServiceListener.REMOVE_WIKITTY_METHOD), CLEAR_WIKITTY(WikittyServiceListener.CLEAR_WIKITTY_METHOD), PUT_EXTENSION(WikittyServiceListener.PUT_EXTENSION_METHOD), - REMOVE_EXTENSION(WikittyServiceListener.REMOVE_EXTENSION_METHOD), + // il est impossible actuellement de supprimer des extensions +// REMOVE_EXTENSION(WikittyServiceListener.REMOVE_EXTENSION_METHOD), CLEAR_EXTENSION(WikittyServiceListener.CLEAR_EXTENSION_METHOD); /** le nom de la methode du listener a appeler pour ce type d'event */ Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceImpl.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceImpl.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceImpl.java 2010-10-29 00:35:39 UTC (rev 457) @@ -599,14 +599,9 @@ try { transaction.begin(); - getSearchEngin().clear(transaction); - WikittyServiceEvent eventWik = getWikittyStorage().clear(transaction); - WikittyServiceEvent eventExt = getExtensionStorage().clear(transaction); + + WikittyServiceEvent result = clear(securityToken, transaction); - WikittyServiceEvent result = new WikittyServiceEvent(this); - result.add(eventWik); - result.add(eventExt); - transaction.commit(); return result; } catch (Exception eee) { @@ -616,6 +611,21 @@ } /** + * Use with caution : It will delete ALL indexes from search engine ! + * This operation should be disabled in production environment. + */ + protected WikittyServiceEvent clear(String securityToken, WikittyTransaction tx) { + getSearchEngin().clear(tx); + WikittyServiceEvent eventWik = getWikittyStorage().clear(tx); + WikittyServiceEvent eventExt = getExtensionStorage().clear(tx); + + WikittyServiceEvent result = new WikittyServiceEvent(this); + result.add(eventWik); + result.add(eventExt); + return result; + } + + /** * Assume that this PagedResult contains wikitty id as result and * return new PagedResult with Wikitty instance */ @@ -913,4 +923,122 @@ } } + /** + * Question: + * <li> on ne force pas le store de wikitty, ils vont donc avoir potentiellement + * des versions differentes sur plusieurs serveurs, est-ce problematique ? + * <li> on ne passe pas la date de suppression des wikitties, ils vont donc + * avoir différente date de suppression sur différent serveur, est-ce problematique ? + * + * + * @param securityToken + * @param events + * @return + */ + @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + // indique qu'il faut vider la base avant de faire les ajouts + boolean mustClear = false; + + // tous les objets a sauver + Map<String, Wikitty> toAddWikitty = new LinkedHashMap<String, Wikitty>(); + // tous les id a supprimer + Map<String, Date> toRemoveWikitty = new LinkedHashMap<String, Date>(); + + // toutes les extensions a sauver + Set<WikittyExtension> toAddExt = new LinkedHashSet<WikittyExtension>(); + + // recherche un event avec un clear pour ne pas jouer des events inutiles + // recherche un store + delete du meme wikitty + // recherche le dernier store du wikitty + for (WikittyServiceEvent e : events) { + // check clear must be the first, if event have clear and other type + // clear is all time play first + if (e.getType().contains( + WikittyServiceEvent.WikittyEventType.CLEAR_WIKITTY) + || e.getType().contains( + WikittyServiceEvent.WikittyEventType.CLEAR_EXTENSION)) { + mustClear = true; + toAddWikitty.clear(); + toRemoveWikitty.clear(); + toAddExt.clear(); + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.PUT_WIKITTY)) { + for (Wikitty w : e.getWikitties().values()) { + toAddWikitty.put(w.getId(), w); + } + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.REMOVE_WIKITTY)) { + for (Map.Entry<String, Date> entry : e.getRemoveDate().entrySet()) { + toAddWikitty.remove(entry.getKey()); + toRemoveWikitty.put(entry.getKey(), entry.getValue()); + } + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.PUT_EXTENSION)) { + for (WikittyExtension ext : e.getExtensions().values()) { + toAddExt.add(ext); + } + } + } + + WikittyTransaction tx = new WikittyTransaction(); + try { + tx.begin(); + + // Actuellement il n'y a pas moyen de supprimer une extension (par surete) + // donc on ne fait rien avec toRemoveExt + WikittyServiceEvent result = new WikittyServiceEvent(this); + if (mustClear) { + WikittyServiceEvent eventClear = clear(securityToken, tx); + result.add(eventClear); + } + WikittyServiceEvent eventStoreExtension = + storeExtension(securityToken, tx, toAddExt); + result.add(eventStoreExtension); + + WikittyServiceEvent eventStoreWikitty = + store(securityToken, tx, toAddWikitty.values(), false); + result.add(eventStoreWikitty); + + WikittyServiceEvent eventDeleteWikitty = + delete(securityToken, tx, toRemoveWikitty.keySet()); + result.add(eventDeleteWikitty); + + tx.commit(); + return result; + } catch (Exception eee) { + tx.rollback(); + throw new WikittyException("Can't replay data", eee); + } + + } + + @Override + public boolean exists(String securityToken, String wikittyId) { + WikittyTransaction tx = new WikittyTransaction(); + try { + tx.begin(); + boolean result = getWikittyStorage().exists(null, wikittyId); + tx.commit(); + return result; + } catch (Exception eee) { + tx.rollback(); + throw new WikittyException("Can't test existance", eee); + } + } + + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + WikittyTransaction tx = new WikittyTransaction(); + try { + tx.begin(); + boolean result = getWikittyStorage().isDeleted(tx, wikittyId); + tx.commit(); + return result; + } catch (Exception eee) { + tx.rollback(); + throw new WikittyException("Can't test existance", eee); + } + } + } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceInMemory.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceInMemory.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceInMemory.java 2010-10-29 00:35:39 UTC (rev 457) @@ -146,8 +146,10 @@ Date now = new Date(); for (String id : idList) { Wikitty w = restore(transaction, id); - w.setDeleteDate(now); - result.addRemoveDate(id, now); + if (w != null) { + w.setDeleteDate(now); + result.addRemoveDate(id, now); + } } return result; } @@ -176,9 +178,6 @@ if (result.isDeleted()) { result = null; } - if (result == null) { - throw new WikittyException(String.format("No wikitty with id '%s'", id)); - } return result; } @@ -442,12 +441,14 @@ searchEngin = new WikittySearchEnginInMemory( (WikittyStorageInMemory) wikittyStorage); - boolean persist = config.getOptionAsBoolean( - WikittyConfig.Option.WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE.getKey()); - if (persist) { - persistenceFile = config.getOptionAsFile( - WikittyConfig.Option.WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE_FILE.getKey()); - restoreFromPersistenceFile(persistenceFile); + if (config != null) { + boolean persist = config.getOptionAsBoolean( + WikittyConfig.Option.WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE.getKey()); + if (persist) { + persistenceFile = config.getOptionAsFile( + WikittyConfig.Option.WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE_FILE.getKey()); + restoreFromPersistenceFile(persistenceFile); + } } } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceListener.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceListener.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceListener.java 2010-10-29 00:35:39 UTC (rev 457) @@ -52,7 +52,6 @@ /** toto[1.0] */ public void putExtension(WikittyServiceEvent event); - public void removeExtension(WikittyServiceEvent event); public void clearExtension(WikittyServiceEvent event); } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceNotifier.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceNotifier.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceNotifier.java 2010-10-29 00:35:39 UTC (rev 457) @@ -34,7 +34,6 @@ import java.util.TreeMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.apache.commons.beanutils.ConstructorUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -353,6 +352,24 @@ super.finalize(); } + @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + WikittyServiceEvent result = ws.replay(securityToken, events); + // notify listeners + fireEvent(result); + return result; + } + + @Override + public boolean exists(String securityToken, String wikittyId) { + return ws.exists(securityToken, wikittyId); + } + + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + return ws.isDeleted(securityToken, wikittyId); + } + /** * Thread utilise pour envoyer les events. On rend accessible ce thread * pour pouvoir y acceder depuis l'exterieur (pour l'instant pour les tests @@ -672,20 +689,6 @@ } /* - * @see org.nuiton.wikitty.WikittyServiceListener#removeExtension(java.lang.String[]) - */ - @Override - public void removeExtension(WikittyServiceEvent event) { - if (propagateEvent) { - sendMessage(event); - } else { - if (log.isDebugEnabled()) { - log.debug("Not master cache, do not propagate removeExtension event"); - } - } - } - - /* * @see org.nuiton.wikitty.WikittyServiceListener#clearExtension() */ @Override Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceSecurity.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceSecurity.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceSecurity.java 2010-10-29 00:35:39 UTC (rev 457) @@ -124,6 +124,38 @@ } } + @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + String userId = getUserId(securityToken); + for (WikittyServiceEvent e : events) { + if (e.getType().contains( + WikittyServiceEvent.WikittyEventType.CLEAR_WIKITTY) + || e.getType().contains( + WikittyServiceEvent.WikittyEventType.CLEAR_EXTENSION)) { + if (isAppAdmin(securityToken, userId)) { + // seul les AppAdmin on le droit a cette method + // les AppAdmin on meme le droit de tout faire, donc on + // peut sortir de la boucle + break; + } else { + throw new SecurityException(_("user %s can't clear data", userId)); + } + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.PUT_WIKITTY)) { + checkStore(securityToken, e.getWikitties().values()); + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.REMOVE_WIKITTY)) { + checkDelete(securityToken, e.getRemoveDate().keySet()); + } + if (e.getType().contains(WikittyServiceEvent.WikittyEventType.PUT_EXTENSION)) { + checkStoreExtension(securityToken, e.getExtensions().values()); + } + } + WikittyServiceEvent result = ws.replay(securityToken, events); + return result; + } + + /** * if app-admin group exists, return true if given userId is app-admin * if app-admin group doesn't exists, return true if user is anonymous @@ -154,9 +186,18 @@ return result; } + /** + * FIXME poussin 20101028 pourquoi retourner une liste ? soit on a le droit + * de faire un store sur tout, on bien on refuse avec une exception + * verifier que result ne sert bien a rien (surtout pas a filtrer) + * + * @param securityToken + * @param wikitties + * @return + */ protected Collection<Wikitty> checkStore(String securityToken, Collection<Wikitty> wikitties) { String userId = getUserId(securityToken); - List<Wikitty> wikittiesToStore = new ArrayList<Wikitty>(); + List<Wikitty> result = new ArrayList<Wikitty>(); for (Wikitty wikitty : wikitties) { // usual case, a user want to store a wikitty @@ -219,9 +260,9 @@ } } - wikittiesToStore.add(wikitty); + result.add(wikitty); } - return wikittiesToStore; + return result; } @Override @@ -326,6 +367,17 @@ @Override public WikittyServiceEvent delete(String securityToken, Collection<String> ids) { + checkDelete(securityToken, ids); + WikittyServiceEvent result = ws.delete(securityToken, ids); + return result; + } + + /** + * Check if we can delete all id passed in argument + * @param securityToken + * @param ids + */ + public void checkDelete(String securityToken, Collection<String> ids) { String userId = getUserId(securityToken); List<String> idsAsList = new ArrayList<String>(ids); List<Wikitty> wikitties = ws.restore(securityToken, null, idsAsList); @@ -338,8 +390,6 @@ } } } - WikittyServiceEvent result = ws.delete(securityToken, ids); - return result; } @Override @@ -755,5 +805,17 @@ return wikittyAuthorisation; } + @Override + public boolean exists(String securityToken, String wikittyId) { + // no need security check for this action + return ws.exists(securityToken, wikittyId); + } + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + // no need security check for this action + return ws.isDeleted(securityToken, wikittyId); + } + + } Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceTransaction.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceTransaction.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyServiceTransaction.java 2010-10-29 00:35:39 UTC (rev 457) @@ -0,0 +1,306 @@ +package org.nuiton.wikitty; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ApplicationConfig; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceTransaction implements WikittyService { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceTransaction.class); + + /** Real WikittyService */ + protected WikittyService ws; + /** WikittyService used to store modified object */ + protected WikittyService tx; + + protected List<WikittyServiceEvent> events; + + public WikittyServiceTransaction(ApplicationConfig config, WikittyService ws) { + this.ws = ws; + // create new WikittyServiceInMemory not configured with default config + // this WikittyServiceInMemory must be only in memory + this.tx = new WikittyServiceInMemory(null); + events = new LinkedList<WikittyServiceEvent>(); + } + + public void commit(String securityToken) { + ws.replay(securityToken, events); + this.tx.clear(null); + events.clear(); + } + + public void rollback(String securityToken) { + this.tx.clear(null); + events.clear(); + } + + @Override + public void addWikittyServiceListener(WikittyServiceListener listener, ServiceListenerType type) { + throw new UnsupportedOperationException( + "You try to add listener on WikittyServiceTransaction," + + "this is an error desgin, you must add WikittyServiceNotifier" + + "front of your WikittyServiceTransaction."); + } + + @Override + public void removeWikittyServiceListener(WikittyServiceListener listener, ServiceListenerType type) { + throw new UnsupportedOperationException( + "You try to remove listener on WikittyServiceTransaction," + + "this is an error desgin, you must add WikittyServiceNotifier" + + "front of your WikittyServiceTransaction."); + } + + @Override + public String login(String login, String password) { + return ws.login(login, password); + } + + /** + * Question: est un comportement normale, lorsqu'on se delogue depuis une + * transaction, on est deloguer partout ? je pense que oui + * @param securityToken + */ + @Override + public void logout(String securityToken) { + ws.logout(securityToken); + } + + @Override + public WikittyServiceEvent clear(String securityToken) { + WikittyServiceEvent e = tx.clear(securityToken); + events.add(e); + return e; + } + + @Override + public boolean canWrite(String securityToken, Wikitty wikitty) { + // in transaction, we can do all. But not during commit + return true; + } + + @Override + public boolean canDelete(String securityToken, String wikittyId) { + // in transaction, we can do all. But not during commit + return true; + } + + @Override + public boolean canRead(String securityToken, String wikittyId) { + boolean result = tx.exists(securityToken, wikittyId); + if (!result) { + // on ne l'a pas en local on va voir si on peut le lire en distant + result = ws.canRead(securityToken, wikittyId); + } + return result; + } + + @Override + public WikittyServiceEvent replay(String securityToken, List<WikittyServiceEvent> events) { + WikittyServiceEvent e = tx.replay(securityToken, events); + events.add(e); + return e; + } + + @Override + public WikittyServiceEvent store(String securityToken, WikittyTransaction transaction, Collection<Wikitty> wikitties, boolean force) { + WikittyServiceEvent e = tx.store(securityToken, transaction, wikitties, force); + events.add(e); + return e; + } + + @Override + public List<String> getAllExtensionIds(String securityToken) { + HashSet<String> tmp = new HashSet<String>(); + + tmp.addAll(tx.getAllExtensionIds(securityToken)); + tmp.addAll(ws.getAllExtensionIds(securityToken)); + + List<String> result = new ArrayList<String>(tmp); + return result; + } + + @Override + public List<String> getAllExtensionsRequires(String securityToken, String extensionName) { + HashSet<String> tmp = new HashSet<String>(); + + tmp.addAll(tx.getAllExtensionsRequires(securityToken, extensionName)); + tmp.addAll(ws.getAllExtensionsRequires(securityToken, extensionName)); + + List<String> result = new ArrayList<String>(tmp); + return result; + } + + @Override + public WikittyServiceEvent storeExtension(String securityToken, WikittyTransaction transaction, Collection<WikittyExtension> exts) { + WikittyServiceEvent e = tx.storeExtension(securityToken, transaction, exts); + events.add(e); + return e; + } + + @Override + public WikittyExtension restoreExtension(String securityToken, WikittyTransaction transaction, String extensionId) { + WikittyExtension result = tx.restoreExtension(securityToken, transaction, extensionId); + if (result == null) { + result = ws.restoreExtension(securityToken, transaction, extensionId); + } + return result; + } + + @Override + public WikittyExtension restoreExtensionLastVersion(String securityToken, WikittyTransaction transaction, String name) { + WikittyExtension result = tx.restoreExtensionLastVersion(securityToken, transaction, name); + if (result == null) { + result = ws.restoreExtension(securityToken, transaction, name); + } + return result; + } + + @Override + public List<Wikitty> restore(String securityToken, WikittyTransaction transaction, List<String> ids) { + List<Wikitty> resultWS = ws.restore(securityToken, transaction, ids); + List<Wikitty> resultTx = tx.restore(securityToken, transaction, ids); + Wikitty[] result = resultWS.toArray(new Wikitty[resultWS.size()]); + int i = 0; + for (Wikitty w : resultTx) { + String id = ids.get(i); + // il faut prendre en compte que l'objet a pu etre supprime dans la + // transaction donc meme s'il est null dans tx et pas dans ws, il + // faut le mettre a null + // si w n'a pas ete restore (null), mais qu'il exist, alors cela + // veut dire qu'il est supprime. + if (w != null || tx.exists(securityToken, id)) { + // on remplace tout par les nouveaux de la transaction + result[i] = w; + } + i++; + } + return Arrays.asList(result); + } + + @Override + public WikittyServiceEvent delete(String securityToken, Collection<String> ids) { + // pour que tout fonctionne bien, il faut que les objets supprimer soit + // dans la tx, car il faut avoir une vrai trace de cette suppression dans la tx + List<Wikitty> wikitties = ws.restore(securityToken, null, new ArrayList<String>(ids)); + tx.store(securityToken, null, wikitties, true); + + WikittyServiceEvent e = tx.delete(securityToken, ids); + events.add(e); + return e; + } + + @Override + public PagedResult<String> findAllByCriteria(String securityToken, WikittyTransaction transaction, Criteria criteria) { + PagedResult<String> resultTx = tx.findAllByCriteria(securityToken, transaction, criteria); + PagedResult<String> resultWs = ws.findAllByCriteria(securityToken, transaction, criteria); + + // Il faut fusionner les deux resultats + // - ne pas avoir de doublon + // - ne pas retenir ceux supprimer dans la transaction + // - fusionner les facettes (comment faire ?) + // - respecter le range demander (comment faire, avec les suppressions possible ?) + LinkedHashSet<String> ids = new LinkedHashSet<String>(); + ids.addAll(resultTx.getAll()); + ids.addAll(resultWs.getAll()); + + int firstIndice = resultWs.getFirstIndice(); + // FIXME le resultat est faut, le nombre total n'est pas la somme des deux :( + int numFound = resultTx.getNumFound() + resultWs.getNumFound(); + String queryString = resultWs.getQueryString(); + // FIXME les facettes sont fausses :( + Map<String, List<FacetTopic>> facets = resultWs.getFacets(); + List<String> results = new ArrayList<String>(ids); + + PagedResult<String> result = new PagedResult<String>( + firstIndice, numFound, queryString, facets, results); + return result; + } + + @Override + public Wikitty findByCriteria(String securityToken, WikittyTransaction transaction, Criteria criteria) { + Wikitty result = null; + PagedResult<String> ids = findAllByCriteria(securityToken, transaction, criteria); + List<String> results = ids.getAll(); + if (results.size() > 0) { + String id = results.get(0); + List<Wikitty> wikitties = restore( + securityToken, transaction, Collections.singletonList(id)); + result = wikitties.get(0); + } + return result; + } + + @Override + public WikittyTree restoreTree(String securityToken, String wikittyId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public WikittyServiceEvent deleteTree(String securityToken, String treeNodeId) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entry<WikittyTreeNode, Integer> restoreNode(String securityToken, String wikittyId, Criteria filter) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map<WikittyTreeNode, Integer> restoreChildren(String securityToken, String wikittyId, Criteria filter) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Wikitty restoreVersion(String securityToken, String wikittyId, String version) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void syncEngin(String securityToken) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean exists(String securityToken, String wikittyId) { + boolean result = tx.exists(securityToken, wikittyId); + if (!result) { + if (!tx.isDeleted(securityToken, wikittyId)) { + result = ws.exists(securityToken, wikittyId); + } + } + return result; + } + + @Override + public boolean isDeleted(String securityToken, String wikittyId) { + boolean result = tx.isDeleted(securityToken, wikittyId); + // pas efface, peut-etre qu'il existe + if (!result && !tx.exists(securityToken, wikittyId)) { + // il n'est pas efface et il n'existe pas dans la tx, + // on recherche dans ws + result = ws.isDeleted(securityToken, wikittyId); + } + return result; + } + +} Added: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyServiceTransactionTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyServiceTransactionTest.java (rev 0) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyServiceTransactionTest.java 2010-10-29 00:35:39 UTC (rev 457) @@ -0,0 +1,56 @@ +package org.nuiton.wikitty; + +import java.util.Collections; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceTransactionTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceTransactionTest.class); + + public WikittyServiceTransactionTest() { + } + + @Test + public void testTransaction() throws Exception { + WikittyConfig config = new WikittyConfig(); + WikittyServiceInMemory ws = new WikittyServiceInMemory(config); + WikittyServiceTransaction tx = new WikittyServiceTransaction(config, ws); + + // ajout d'objet hors transaction + WikittyLabel label = new WikittyLabelImpl(); + label.addLabels("coucou"); + ws.store(null, null, Collections.singleton(label.getWikitty()), false); + + // on doit le retrouver dans la transation (meme si elle a ete ouverte avant) + Wikitty wTx = WikittyServiceEnhanced.restore(tx, null, label.getWikittyId()); + Assert.assertEquals(label.getWikitty(), wTx); + + // on creer un objet dans la transaction + WikittyLabel labelTx = new WikittyLabelImpl(); + labelTx.addLabels("coucouTx"); + tx.store(null, null, Collections.singleton(labelTx.getWikitty()), false); + + // on ne doit pas le retrouver hors de la transation + Wikitty w = WikittyServiceEnhanced.restore(ws, null, labelTx.getWikittyId()); + Assert.assertEquals(null, w); + + // on commit, du coup on doit retrouver l'objet + tx.commit(null); + w = WikittyServiceEnhanced.restore(ws, null, labelTx.getWikittyId()); + Assert.assertEquals(labelTx.getWikitty(), w); + + } + +} Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/notification/WikittyServiceNotificationTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/notification/WikittyServiceNotificationTest.java 2010-10-28 13:59:11 UTC (rev 456) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/notification/WikittyServiceNotificationTest.java 2010-10-29 00:35:39 UTC (rev 457) @@ -46,8 +46,8 @@ wsn.removeWikittyServiceListener(l, ServiceListenerType.ALL); sendEvent(wsn, false); - // donc au total seulement 6 events on du etre envoye - Assert.assertEquals(6, nbEvent); + // donc au total seulement 5 events on du etre envoye + Assert.assertEquals(5, nbEvent); } @@ -117,20 +117,6 @@ } { WikittyServiceEvent event = new WikittyServiceEvent("test"); - event.addType(WikittyServiceEvent.WikittyEventType.REMOVE_EXTENSION); - wsn.processRemoteEvent(event); - wsn.getEventThread().waitFor(event.getTime()); - if (hasListener) { - Assert.assertEquals( - EnumSet.of(WikittyServiceEvent.WikittyEventType.REMOVE_EXTENSION), - lastEvent); - } else { - Assert.assertEquals(null, lastEvent); - } - lastEvent = null; - } - { - WikittyServiceEvent event = new WikittyServiceEvent("test"); event.addType(WikittyServiceEvent.WikittyEventType.CLEAR_EXTENSION); wsn.processRemoteEvent(event); wsn.getEventThread().waitFor(event.getTime()); @@ -187,15 +173,6 @@ } @Override - public void removeExtension(WikittyServiceEvent event) { - nbEvent++; - Assert.assertEquals( - EnumSet.of(WikittyServiceEvent.WikittyEventType.REMOVE_EXTENSION), - event.getType()); - lastEvent = event.getType(); - } - - @Override public void clearExtension(WikittyServiceEvent event) { nbEvent++; Assert.assertEquals(
participants (1)
-
bpoussin@users.nuiton.org