r527 - in trunk: wikitty-api/src/main/java/org/nuiton/wikitty wikitty-api/src/main/java/org/nuiton/wikitty/entities wikitty-api/src/main/java/org/nuiton/wikitty/services wikitty-api/src/main/resources wikitty-api/src/test/java/org/nuiton/wikitty wikitty-api/src/test/java/org/nuiton/wikitty/api wikitty-api/src/test/java/org/nuiton/wikitty/entities wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/jdbc wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/services wikitty-solr-impl/src/test/ja
Author: bpoussin Date: 2010-11-26 14:57:13 +0100 (Fri, 26 Nov 2010) New Revision: 527 Url: http://nuiton.org/repositories/revision/wikitty/527 Log: rename method 'Wikitty.replace' to 'Wikitty.replaceWith' rename class 'WikittyServiceImpl' to 'WikittyServiceStorage' move bad package test entities to right place add test on Wikitty.replaceWith method fix bug in Wikitty.replaceWith method Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/BusinessEntityImplTest.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/WikittyCopyOnWriteTest.java Removed: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceImpl.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/Wikitty.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyCopyOnWrite.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyEvent.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemory.java trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/jdbc/WikittyServiceJDBC.java trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemoryJdbcSolr.java trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/WikittyServiceSolr.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfig.java 2010-11-26 13:57:13 UTC (rev 527) @@ -44,7 +44,7 @@ * <li> pas de notification reseau * <li> /tmp pour les exports * - * Si on utilise WikittyServiceImpl au lieu de WikittyServiceInMemory par defaut + * Si on utilise WikittyServiceStorage au lieu de WikittyServiceInMemory par defaut * <li> base h2 embarque * <li> solr * @@ -182,7 +182,7 @@ WIKITTY_WIKITTYSERVICE_COMPONENTS( "wikitty.WikittyService.components", _("WikittyService to use (list must be in right order. " - + "ex: org.nuiton.wikitty.WikittyServiceImpl,org.nuiton.wikitty.WikittyServiceNotifier,org.nuiton.wikitty.WikittyServiceCached,org.nuiton.wikitty.WikittyServiceSecurity)"), + + "ex: org.nuiton.wikitty.WikittyServiceStorage,org.nuiton.wikitty.WikittyServiceNotifier,org.nuiton.wikitty.WikittyServiceCached,org.nuiton.wikitty.WikittyServiceSecurity)"), WikittyServiceInMemory.class.getName(), String.class, false, false), WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE( @@ -195,9 +195,9 @@ "/tmp/wikitty-inmemory.ser", File.class, false, false), - WIKITTY_WIKITTYSERVICEIMPL_COMPONENTS( - "wikitty.WikittyServiceImpl.components", - _("WikittyServiceImpl component to use (ExtensionStorage, WikittyStorage, SearchEngine)"), + WIKITTY_WIKITTYSERVICESTORAGE_COMPONENTS( + "wikitty.WikittyServiceStorage.components", + _("WikittyServiceStorage component to use (ExtensionStorage, WikittyStorage, SearchEngine)"), "org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC," + "org.nuiton.wikitty.jdbc.WikittyStorageJDBC," + "org.nuiton.wikitty.solr.WikittySearchEnginSolr", String.class, false, false), Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2010-11-26 13:57:13 UTC (rev 527) @@ -39,10 +39,10 @@ /** * Wikitty service. * - * The main implementation for this interface is {@link WikittyServiceImpl}. + * The main implementation for this interface is {@link WikittyServiceStorage}. * It can be used alone but this implementation doesn't deal with all * stuffs described in this interface. Thus, other functionalities are added - * to the implementation through objects that decorate WikittyServiceImpl : + * to the implementation through objects that decorate WikittyServiceStorage : * * <dl> * <dt>{@link WikittyServiceCached}</dt> Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyUtil.java 2010-11-26 13:57:13 UTC (rev 527) @@ -219,7 +219,7 @@ if(tagValues != null) { for (String tag : tagValues.keySet()) { String value = tagValues.get(tag); - // replace " in string with \" + // replaceWith " in string with \" value = value.replaceAll("\"", "\\\\\""); // quote value with "..." result += " " + tag + "=\"" + tagValues.get(tag) +"\""; Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/Wikitty.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/Wikitty.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/Wikitty.java 2010-11-26 13:57:13 UTC (rev 527) @@ -49,7 +49,7 @@ * This two wikitty must have same id * @param w wikitty where we take information */ - void replace(Wikitty w); + void replaceWith(Wikitty w); String getId(); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyCopyOnWrite.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyCopyOnWrite.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyCopyOnWrite.java 2010-11-26 13:57:13 UTC (rev 527) @@ -64,25 +64,19 @@ } @Override - public void replace(Wikitty w) { - // test make a the copy once - if (targetIsACopy) { - target.replace(w); - } else { - try { - target = w.clone(); - if (log.isTraceEnabled()) { - log.trace(this + " now has for target " + target); - } - } catch (CloneNotSupportedException eee) { - throw new WikittyException(String.format( - "unable to clone wikitty %s", target), eee); - } - targetIsACopy = true; + public void replaceWith(Wikitty w) { + if (this == w) { + return; } + substituteTargetWithCopy(); + target.replaceWith(w); } - /** replace {@link #target} with a clone + public Wikitty getTarget() { + return target; + } + + /** replaceWith {@link #target} with a clone * * this method must be called to prevent any modification on target */ @@ -91,6 +85,7 @@ if (! targetIsACopy) { try { target = target.clone(); + targetIsACopy = true; if (log.isTraceEnabled()) { log.trace(this + " now has for target " + target); } @@ -98,7 +93,6 @@ throw new WikittyException(String.format( "unable to clone wikitty %s", target), eee); } - targetIsACopy = true; } } 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 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2010-11-26 13:57:13 UTC (rev 527) @@ -120,12 +120,16 @@ * @param w wikitty where we take information */ @Override - public void replace(Wikitty w) { + public void replaceWith(Wikitty w) { // il faut que ce soit le meme objet mais pas la meme instance // car ca ne sert a rien de copier un objet sur lui meme if (this == w) { return; } + // all time search for WikittyImpl to do copy (prevent error) + if (w instanceof WikittyCopyOnWrite) { + replaceWith(((WikittyCopyOnWrite)w).getTarget()); + } if (this.getId().equals(w.getId())) { this.extensions.clear(); this.fieldValue.clear(); @@ -926,7 +930,7 @@ @Override public WikittyImpl clone() throws CloneNotSupportedException { WikittyImpl result = new WikittyImpl(this.id); - result.replace(this); + result.replaceWith(this); return result; } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyEvent.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyEvent.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyEvent.java 2010-11-26 13:57:13 UTC (rev 527) @@ -273,7 +273,7 @@ } else { if (type.contains(WikittyEventType.PUT_WIKITTY)) { Wikitty newWikitty = getWikitties().get(id); - e.replace(newWikitty); + e.replaceWith(newWikitty); } if (type.contains(WikittyEventType.REMOVE_WIKITTY)) { Date date = getRemoveDate().get(id); Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java 2010-11-26 13:57:13 UTC (rev 527) @@ -90,7 +90,7 @@ Wikitty result = new WikittyImpl(wikittyId); result.setVersion(wikittyVersion); - // Add all extension and replace old by the new + // Add all extension and replaceWith old by the new for (WikittyExtension extension : wikitty.getExtensions()) { // add one by one to manage require Deleted: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceImpl.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceImpl.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceImpl.java 2010-11-26 13:57:13 UTC (rev 527) @@ -1,1150 +0,0 @@ -/* - * #%L - * Wikitty :: api - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -package org.nuiton.wikitty.services; - -import org.nuiton.wikitty.storage.WikittyExtensionStorage; -import org.nuiton.wikitty.storage.WikittySearchEngin; -import org.nuiton.wikitty.storage.WikittyStorage; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.AbstractMap.SimpleEntry; -import java.util.LinkedHashSet; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.wikitty.search.Criteria; -import org.nuiton.wikitty.entities.FieldType; -import org.nuiton.wikitty.search.PagedResult; -import org.nuiton.wikitty.entities.Wikitty; -import org.nuiton.wikitty.WikittyException; -import org.nuiton.wikitty.entities.WikittyExtension; -import org.nuiton.wikitty.WikittyService; -import org.nuiton.wikitty.WikittyTree; -import org.nuiton.wikitty.entities.WikittyTreeNode; -import org.nuiton.wikitty.entities.WikittyTreeNodeHelper; -import org.nuiton.wikitty.entities.WikittyTreeNodeImpl; -import org.nuiton.wikitty.WikittyUtil; -import org.nuiton.wikitty.entities.ExtensionFactory; -import org.nuiton.wikitty.search.Search; -import org.nuiton.wikitty.search.operators.Element; - -/** - * WikittyService is main service - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class WikittyServiceImpl implements WikittyService { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(WikittyServiceImpl.class); - - /** Default migration use to migrate a wikitty in last extension version */ - protected WikittyExtensionMigration defaultExtensionMigration = - new WikittyExtensionMigrationRename(); - - protected WikittySearchEngin searchEngin; - protected WikittyExtensionStorage extensionStorage; - protected WikittyStorage wikittyStorage; - - /** - * TODO poussin 20101027 remove it when all used WikittyServiceHelper.build - * - * Used by specific child - * {@link org.nuiton.wikitty.jdbc.WikittyServiceJDBC} - * {@link org.nuiton.wikitty.jdbc.WikittyServiceJPA} - * {@link org.nuiton.wikitty.jdbc.WikittyServiceHbase} - */ - protected WikittyServiceImpl() { - } - - public WikittyServiceImpl(WikittyExtensionStorage extensionStorage, - WikittyStorage wikittyStorage, - WikittySearchEngin searchEngin) { - this.extensionStorage = extensionStorage; - this.wikittyStorage = wikittyStorage; - this.searchEngin = searchEngin; - } - - protected WikittySearchEngin getSearchEngin() { - return searchEngin; - } - - protected WikittyExtensionStorage getExtensionStorage() { - return extensionStorage; - } - - protected WikittyStorage getWikittyStorage() { - return wikittyStorage; - } - - /* - * @see org.nuiton.wikitty.WikittyService#addWikittyServiceListener(org.nuiton.wikitty.WikittyListener, org.nuiton.wikitty.WikittyService.ServiceListenerType) - */ - @Override - public void addWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { - throw new UnsupportedOperationException("Can't add listener on " + WikittyServiceImpl.class.getName()); - } - - /* - * @see org.nuiton.wikitty.WikittyService#removeWikittyServiceListener(org.nuiton.wikitty.WikittyListener, org.nuiton.wikitty.WikittyService.ServiceListenerType) - */ - @Override - public void removeWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { - throw new UnsupportedOperationException("Can't remove listener on " + WikittyServiceImpl.class.getName()); - } - - @Override - public String login(String login, String password) { - log.warn("login asked, but there is no security service"); - return null; - } - - @Override - public void logout(String securityToken) { - log.warn("logout asked, but there is no security service"); - } - - @Override - public boolean canWrite(String securityToken, Wikitty wikitty) { - return true; - } - - @Override - public boolean canDelete(String securityToken, String wikittyId) { - return true; - } - - @Override - public boolean canRead(String securityToken, String wikittyId) { - return true; - } - - protected void checkConstraint(Collection<Wikitty> wikitties) { - for(Wikitty w : wikitties) { - for(WikittyExtension ext : w.getExtensions()) { - for (String fieldName : ext.getFieldNames()) { - FieldType type = ext.getFieldType(fieldName); - if (type.isNotNull()) { - if (null == w.getFieldAsObject(ext.getName(), fieldName)) { - throw new WikittyException(String.format( - "Field %s must not be null", fieldName)); - } - } - } - } - } - } - -// @Override -// public UpdateResponse store(String securityToken, WikittyTransaction transaction, -// Collection<Wikitty> wikitties, boolean force) { -// if (!(wikitties instanceof Set)) { -// // use all time Set to prevent duplicated wikitty in collection -// wikitties = new LinkedHashSet<Wikitty>(wikitties); -// } -// checkConstraint(wikitties); -// -// // update/store extension if necessary -// Set<WikittyExtension> allExtensions = new LinkedHashSet<WikittyExtension>(); -// for (Wikitty w : wikitties) { -// // collect all extensions used by all wikitties -// allExtensions.addAll(w.getExtensions()); -// } -// -// // try to commit command -// UpdateResponse extUpdate = getExtensionStorage().store(transaction, allExtensions); -// UpdateResponse wikUpdate = getWikittyStorage().store(transaction, wikitties, force); -// UpdateResponse indexUpdate = getSearchEngin().store(transaction, wikitties); -// -// UpdateResponse result = new UpdateResponse(); -// // prepare update client response -// result.add(extUpdate); -// result.add(wikUpdate); -// result.add(indexUpdate); -// -// return result; -// } - @Override - public WikittyEvent store(String securityToken, - Collection<Wikitty> wikitties, boolean force) { - WikittyEvent result = store(securityToken, null, wikitties, force); - return result; - } - - protected WikittyEvent store(String securityToken, - WikittyTransaction transaction, - Collection<Wikitty> wikitties, boolean force) { - if (!(wikitties instanceof Set)) { - // use all time Set to prevent duplicated wikitty in collection - wikitties = new LinkedHashSet<Wikitty>(wikitties); - } - checkConstraint(wikitties); - - // update/store extension if necessary - Set<WikittyExtension> allExtensions = new LinkedHashSet<WikittyExtension>(); - for (Wikitty w : wikitties) { - // collect all extensions used by all wikitties - allExtensions.addAll(w.getExtensions()); - } - - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - // try to commit command - WikittyEvent extUpdate = - getExtensionStorage().store(transaction, allExtensions); - WikittyEvent wikUpdate = - getWikittyStorage().store(transaction, wikitties, force); - getSearchEngin().store(transaction, wikitties); - - WikittyEvent result = new WikittyEvent(this); - // prepare update client response - result.add(extUpdate); - result.add(wikUpdate); - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't store wikitty", eee); - } - } - - @Override - public List<String> getAllExtensionIds(String securityToken) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - List<String> result = getExtensionStorage().getAllExtensionIds(transaction); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't retrieve all extension's ids", eee); - } - } - - @Override - public List<String> getAllExtensionsRequires( - String securityToken, String extensionName) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - List<String> result = getExtensionStorage() - .getAllExtensionsRequires(transaction, extensionName); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException(String.format( - "Can't retrieve all required extension for %s", extensionName), eee); - } - } - - @Override - public WikittyEvent storeExtension( - String securityToken, Collection<WikittyExtension> exts) { - WikittyEvent result = storeExtension(securityToken, null, exts); - return result; - } - - @Override - public WikittyEvent deleteExtension( - String securityToken, Collection<String> extNames) { - WikittyEvent result = deleteExtension(securityToken, null, extNames); - return result; - } - - protected WikittyEvent storeExtension(String securityToken, - WikittyTransaction transaction, Collection<WikittyExtension> exts) { - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - WikittyEvent result = - getExtensionStorage().store(transaction, exts); - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't store extensions", eee); - } - } - - protected WikittyEvent deleteExtension(String securityToken, - WikittyTransaction transaction, Collection<String> extNames) { - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - // check that all extensions are not used - for(String name : extNames) { - // only name are stored in index, search only on name - Criteria criteria = Search.query().eq(Element.ELT_EXTENSION, name).criteria(); - criteria.setEndIndex(0); // result is not use, just numFound - PagedResult<String> wikittyWithExt = findAllByCriteria( - securityToken, transaction, criteria); - int numFound = wikittyWithExt.getNumFound(); - if (numFound > 0) { - throw new WikittyException(String.format( - "Can't delete %s extension, this extension" - + " is in used by %s wikitty", - name, numFound)); - } - } - - WikittyEvent result = - getExtensionStorage().delete(transaction, extNames); - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't delete extensions", eee); - } - } - - @Override - public WikittyExtension restoreExtension( - String securityToken, String extensionId) { - WikittyExtension result = restoreExtension(securityToken, null, extensionId); - return result; - } - - protected WikittyExtension restoreExtension( - String securityToken, WikittyTransaction transaction, String extensionId) { - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - //split the id to ensure that version is normalized - String name = WikittyExtension.computeName(extensionId); - String version = WikittyExtension.computeVersion(extensionId); - - WikittyExtension result = getExtensionStorage().restore(transaction, name, version); - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't restore extensions", eee); - } - } - - @Override - public WikittyExtension restoreExtensionLastVersion( - String securityToken, String name) { - WikittyExtension result = restoreExtensionLastVersion(securityToken, null, name); - return result; - } - - protected WikittyExtension restoreExtensionLastVersion(String securityToken, - WikittyTransaction transaction, String name) { - String version = getExtensionStorage().getLastVersion(transaction, name); - if(version == null) { - return null; - } - - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - WikittyExtension result = getExtensionStorage().restore(transaction, name, version); - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't store extensions", eee); - } - } - - protected Wikitty restore(String securityToken, - WikittyTransaction transaction, String id) { - if (id == null) { - return null; - } - if (!getWikittyStorage().exists(transaction, id)) { - // object doesn't exist, we return null - return null; - } - - if (getWikittyStorage().isDeleted(transaction, id)) { - // object deleted, we return null - return null; - } - Wikitty result = getWikittyStorage().restore(transaction, id); - if(result != null) { - result = upgradeData(securityToken, transaction, result); - } - return result; - } - - @Override - public List<Wikitty> restore(String securityToken, List<String> ids) { - List<Wikitty> result = restore(securityToken, null, ids); - return result; - } - - protected List<Wikitty> restore(String securityToken, - WikittyTransaction transaction, List<String> ids) { - - List<Wikitty> result = new ArrayList<Wikitty>(); - boolean txCreated = false; - try { - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - for (String id : ids) { - Wikitty w = restore(securityToken, transaction, id); - // on l'ajoutde tout le temps, meme si w est nul lorsqu'il y a - // une demande et qu'elle echoue on ajout - // bien null, pour qu'il y ait une correspondance 1 pour 1 - // avec la demande - result.add(w); - } - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Can't restore wikitty", eee); - } - } - - // FIXME poussin 20101029 use WikittyServiceTransaction and remove other transaction - protected Wikitty upgradeData(String securityToken, - WikittyTransaction transaction, Wikitty wikitty) { - Wikitty result = wikitty; - - Collection<WikittyExtension> extensions = wikitty.getExtensions(); - for (WikittyExtension extension : extensions) { - String extensionName = extension.getName(); - - if (log.isDebugEnabled()) { - log.debug("extensionName=" + extensionName); - } - - WikittyExtension currentExtension = extension; - String currentExtensionVersion = currentExtension.getVersion(); - - WikittyExtension lastExtension = restoreExtensionLastVersion( - securityToken, transaction, extensionName); - String lastExtensionVersion = lastExtension.getVersion(); - - if (log.isDebugEnabled()) { - log.debug("lastExtensionVersion=" + lastExtensionVersion); - } - - WikittyExtensionMigration migration = - WikittyExtensionMigration.migrationRegistry.get(extensionName); - if (migration == null) { - migration = defaultExtensionMigration; - } - - // Loop on between extension in wikitty and last version - while(WikittyUtil.versionGreaterThan(lastExtensionVersion, currentExtensionVersion)) { - - // Get extension after the current version - String nextExtensionVersion = - WikittyUtil.incrementMajorRevision(currentExtensionVersion); - String nextExtensionId = - WikittyExtension.computeId(extensionName, nextExtensionVersion); - WikittyExtension nextExtension = restoreExtension( - securityToken, transaction, nextExtensionId); - - if (log.isDebugEnabled()) { - log.debug("currentExtensionVersion=" + currentExtensionVersion); - log.debug("nextExtensionVersion=" + nextExtensionVersion); - } - - // Test if extension is never use in this version - if(nextExtension != null) { - result = migration.migrate(this, result, - currentExtension, nextExtension); - currentExtension = nextExtension; - } - - // Follow - currentExtensionVersion = nextExtensionVersion; - } - } - - return result; - } - - protected WikittyEvent delete(String securityToken, WikittyTransaction transaction, - Collection<String> ids) throws WikittyException { - // work only on valid id - Collection<Wikitty> storedWikitties = new LinkedHashSet<Wikitty>(); - // copy ids because we can remove some element, and modify it - // use set to prevent id duplication and preformance (contains method call) - Set<String> idSet = new LinkedHashSet<String>(ids); - for (Iterator<String> i = idSet.iterator(); i.hasNext();) { - String id = i.next(); - // test if wikitty exists - if (!getWikittyStorage().exists(transaction, id)) { - // don't exist, remove this id in id list - i.remove(); - // go to the next id, because this id doesn't exist and can't - // be used in tree - continue; - } - if (getWikittyStorage().isDeleted(transaction, id)) { - // already deleted, remove this id in id list - i.remove(); - // go to the next id, because this id already deleted and can't - // be used in tree - continue; - } - - // Store node with have deleted node as parent - Criteria criteria = - Search.query().eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, id).criteria(); - List<String> wikittyNodesId = findAllByCriteria( - securityToken, transaction, criteria).getAll(); - for (String wikittyNodeId : wikittyNodesId) { - if(!idSet.contains(wikittyNodeId)) { - Wikitty treeNode = restore( - securityToken, transaction, wikittyNodeId); - WikittyTreeNodeHelper.setParent(treeNode, null); - storedWikitties.add(treeNode); - } - } - - // Store node with have deleted child - criteria = Search.query().eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_ATTACHMENT, id).criteria(); - wikittyNodesId = findAllByCriteria( - securityToken, transaction, criteria).getAll(); - for (String wikittyNodeId : wikittyNodesId) { - if(!idSet.contains(wikittyNodeId)) { - Wikitty treeNode = restore( - securityToken, transaction, wikittyNodeId); - WikittyTreeNodeHelper.removeAttachment(treeNode, id); - storedWikitties.add(treeNode); - } - } - } - - WikittyEvent eventDelete = - getWikittyStorage().delete(transaction, idSet); - getSearchEngin().delete(transaction, idSet); - - WikittyEvent eventStore = - store(securityToken, transaction, storedWikitties, false); - - WikittyEvent result = new WikittyEvent(this); - result.add(eventDelete); - result.add(eventStore); - - return result; - } - - @Override - public WikittyEvent delete(String securityToken, Collection<String> ids){ - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - WikittyEvent result = delete(securityToken, transaction, ids); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't delete wikitty", eee); - } - } - - /** - * Use with caution : It will delete ALL indexes from search engine ! - * This operation should be disabled in production environment. - */ - @Override - public WikittyEvent clear(String securityToken) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - - WikittyEvent result = clear(securityToken, transaction); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't clear all data", eee); - } - } - - /** - * Use with caution : It will delete ALL indexes from search engine ! - * This operation should be disabled in production environment. - */ - protected WikittyEvent clear(String securityToken, WikittyTransaction tx) { - getSearchEngin().clear(tx); - WikittyEvent eventWik = getWikittyStorage().clear(tx); - WikittyEvent eventExt = getExtensionStorage().clear(tx); - - WikittyEvent result = new WikittyEvent(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 - */ - @Override - public PagedResult<String> findAllByCriteria( - String securityToken, Criteria criteria) { - PagedResult<String> result = findAllByCriteria(securityToken, null, criteria); - return result; - } - - protected PagedResult<String> findAllByCriteria(String securityToken, - WikittyTransaction transaction, Criteria criteria) { - try { - boolean txCreated = false; - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - PagedResult<String> result = - getSearchEngin().findAllByCriteria(transaction, criteria); - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Error during find", eee); - } - } - - @Override - public Wikitty findByCriteria(String securityToken, Criteria criteria) { - Wikitty result = findByCriteria(securityToken, null, criteria); - return result; - } - - protected Wikitty findByCriteria(String securityToken, - WikittyTransaction transaction, Criteria criteria) { - try { - boolean txCreated = false; - if (transaction == null) { - transaction = new WikittyTransaction(); - txCreated = true; - transaction.begin(); - } - - criteria.setFirstIndex(0).setEndIndex(1); - PagedResult<String> pages = findAllByCriteria( - securityToken, transaction, criteria); - - Wikitty result = null; - if (pages.size() > 0) { - String id = pages.getFirst(); - result = restore(securityToken, transaction, id); - } - - if (txCreated) { - transaction.commit(); - } - return result; - } catch (WikittyException ex) { - if (transaction != null) { - transaction.rollback(); - } - throw ex; - } catch (Exception eee) { - if (transaction != null) { - transaction.rollback(); - } - throw new WikittyException("Error during find", eee); - } - } - - protected WikittyTree restoreTree(String securityToken, - WikittyTransaction transaction, String wikittyId) { - Wikitty w = restore(securityToken, transaction, wikittyId); - if(w == null) { - return null; - } - - if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { - throw new WikittyException(String.format( - "Wikitty '%s' do not handle extension %s", - wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); - } - WikittyTree tree = new WikittyTree(); - WikittyTreeNode node = new WikittyTreeNodeImpl(w); - tree.setNode(node); - - WikittyTreeNodeImpl exempleNode = new WikittyTreeNodeImpl(); - exempleNode.setParent(wikittyId); - - Criteria criteria = Search.query(exempleNode.getWikitty()).criteria() - .setFirstIndex(0).setEndIndex(Criteria.ALL_ELEMENTS); - PagedResult<String> childNodesId = findAllByCriteria( - securityToken, transaction, criteria); - for (String childNodeId : childNodesId.getAll()) { - tree.addChild(restoreTree(securityToken, transaction, childNodeId)); - } - - return tree; - } - - @Override - public WikittyTree restoreTree(String securityToken, String wikittyId) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - WikittyTree tree = restoreTree(securityToken, transaction, wikittyId); - - transaction.commit(); - return tree; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't restore tree", eee); - } - } - - @Override - public WikittyEvent deleteTree(String securityToken, String thesaurusId) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - WikittyEvent result = deleteTree(securityToken, transaction, thesaurusId); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't delete tree", eee); - } - } - - /** - * Delete specified treenode and sub treenode. - * - * @param securityToken security token - * @param transaction transaction - * @param treeNodeId thesaurusId to delete - * @return all id of delete nodes - */ - protected WikittyEvent deleteTree(String securityToken, WikittyTransaction transaction, String treeNodeId) { - List<String> allTreeNodeId = getRecursiveTreeNodeId(securityToken, transaction, treeNodeId); - WikittyEvent result = delete(securityToken, transaction, allTreeNodeId); - return result; - } - - /** - * Get recursive id of tree node children of {@code treeNodeId}. - * - * @param securityToken security token - * @param transaction transaction - * @param treeNodeId tree node id - * @return all id of {@code treeNodeId}'s children - */ - protected List<String> getRecursiveTreeNodeId(String securityToken, WikittyTransaction transaction, String treeNodeId) { - - Search search = Search.query(); - search = search.eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, treeNodeId); - Criteria criteria = search.criteria(); - - PagedResult<String> childTreeNodeIds = findAllByCriteria(securityToken, transaction, criteria); - List<String> treeNodeIds = new ArrayList<String>(); - treeNodeIds.add(treeNodeId); - for (String childTreeNodeId : childTreeNodeIds.getAll()) { - List<String> subTreeNodeIds = getRecursiveTreeNodeId(securityToken, transaction, childTreeNodeId); - treeNodeIds.addAll(subTreeNodeIds); - } - return treeNodeIds; - } - - @Override - public Map.Entry<WikittyTreeNode, Integer> restoreNode(String securityToken, - String wikittyId, Criteria filter) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - Wikitty w = restore(securityToken, transaction, wikittyId); - if(w == null) { - transaction.commit(); - return null; - } - - if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { - throw new WikittyException(String.format( - "Wikitty '%s' do not handle extension %s", - wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); - } - - WikittyTreeNode node = new WikittyTreeNodeImpl(w); - Integer count = getSearchEngin().findNodeCount(transaction, w, filter); - - HashMap.SimpleEntry<WikittyTreeNode, Integer> result = - new SimpleEntry<WikittyTreeNode, Integer>(node, count); - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't restore node", eee); - } - } - - @Override - public Map<WikittyTreeNode, Integer> restoreChildren(String securityToken, - String wikittyId, Criteria filter) { - WikittyTransaction transaction = new WikittyTransaction(); - try { - transaction.begin(); - - Wikitty w = restore(securityToken, transaction, wikittyId); - if(w == null) { - transaction.commit(); - return null; - } - - if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { - throw new WikittyException(String.format( - "Wikitty '%s' do not handle extension %s", - wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); - } - - Map<WikittyTreeNode, Integer> result = new LinkedHashMap<WikittyTreeNode, Integer>(); - - Map<String, Integer> search = getSearchEngin().findAllChildrenCount( - transaction, w, filter); - Set<Entry<String, Integer>> children = search.entrySet(); - for (Entry<String, Integer> child : children) { - Integer count = child.getValue(); - - String id = child.getKey(); - Wikitty wikitty = restore(securityToken, transaction, id); - WikittyTreeNode node = new WikittyTreeNodeImpl(wikitty); - - result.put(node, count); - } - - transaction.commit(); - return result; - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't restore children", eee); - } - } - - @Override - public Wikitty restoreVersion(String securityToken, - String wikittyId, String version) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void syncEngin(final String securityToken) { - final WikittyTransaction transaction = new WikittyTransaction(); - try { - final int numberForCommit = 1000; - final WikittySearchEngin searchEngin = getSearchEngin(); - final List<Wikitty> wikitties = new ArrayList<Wikitty>(numberForCommit); - - transaction.begin(); - searchEngin.clear(transaction); - transaction.commit(); - transaction.begin(); - - getWikittyStorage().scanWikitties(transaction, new WikittyStorage.Scanner() { - int count = 0; - - @Override - public void scan(String wikittyId) { - Wikitty wikitty = restore(securityToken, transaction, wikittyId); - Date deleteDate = wikitty.getDeleteDate(); - if(deleteDate == null) { - count ++; - wikitties.add(wikitty); - - if(count == numberForCommit) { - // Reindex - searchEngin.store(transaction, wikitties); - transaction.commit(); - // Reinit - count = 0; - wikitties.clear(); - transaction.begin(); - } - } - } - }); - - // Last wikitties - searchEngin.store(transaction, wikitties); - transaction.commit(); - } catch (Exception eee) { - transaction.rollback(); - throw new WikittyException("Can't sync searchable index with data", eee); - } - } - - /** - * 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 WikittyEvent replay( - String securityToken, List<WikittyEvent> events, boolean force) { - // 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>(); - // toutes les extensions a supprimer - Set<String> toDeleteExt = new LinkedHashSet<String>(); - - // 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 (WikittyEvent 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( - WikittyEvent.WikittyEventType.CLEAR_WIKITTY) - || e.getType().contains( - WikittyEvent.WikittyEventType.CLEAR_EXTENSION)) { - mustClear = true; - toAddWikitty.clear(); - toRemoveWikitty.clear(); - toAddExt.clear(); - } - if (e.getType().contains(WikittyEvent.WikittyEventType.PUT_WIKITTY)) { - for (Wikitty w : e.getWikitties().values()) { - toAddWikitty.put(w.getId(), w); - } - } - if (e.getType().contains(WikittyEvent.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(WikittyEvent.WikittyEventType.PUT_EXTENSION)) { - for (WikittyExtension ext : e.getExtensions().values()) { - toAddExt.add(ext); - } - } - if (e.getType().contains(WikittyEvent.WikittyEventType.REMOVE_EXTENSION)) { - for (String extName : e.getDeletedExtensions()) { - toDeleteExt.add(extName); - } - } - } - - WikittyTransaction tx = new WikittyTransaction(); - try { - tx.begin(); - - WikittyEvent result = new WikittyEvent(this); - if (mustClear) { - WikittyEvent eventClear = clear(securityToken, tx); - result.add(eventClear); - } - WikittyEvent eventStoreExtension = - storeExtension(securityToken, tx, toAddExt); - result.add(eventStoreExtension); - - WikittyEvent eventDeleteExtension = - deleteExtension(securityToken, tx, toDeleteExt); - result.add(eventDeleteExtension); - - WikittyEvent eventStoreWikitty = - store(securityToken, tx, toAddWikitty.values(), force); - result.add(eventStoreWikitty); - - WikittyEvent 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/services/WikittyServiceInMemory.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemory.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemory.java 2010-11-26 13:57:13 UTC (rev 527) @@ -53,7 +53,7 @@ * Last update: $Date$ * by : $Author$ */ -public class WikittyServiceInMemory extends WikittyServiceImpl { +public class WikittyServiceInMemory extends WikittyServiceStorage { //TODO InMemory implementation is not usable for production. Must be reviewed. //TODO The version increment must be done in 'prepare' method Copied: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java (from rev 519, trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceImpl.java) =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2010-11-26 13:57:13 UTC (rev 527) @@ -0,0 +1,1149 @@ +/* + * #%L + * Wikitty :: api + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.wikitty.services; + +import org.nuiton.wikitty.storage.WikittyExtensionStorage; +import org.nuiton.wikitty.storage.WikittySearchEngin; +import org.nuiton.wikitty.storage.WikittyStorage; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.AbstractMap.SimpleEntry; +import java.util.LinkedHashSet; +import java.util.Map.Entry; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.search.Criteria; +import org.nuiton.wikitty.entities.FieldType; +import org.nuiton.wikitty.search.PagedResult; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.WikittyTree; +import org.nuiton.wikitty.entities.WikittyTreeNode; +import org.nuiton.wikitty.entities.WikittyTreeNodeHelper; +import org.nuiton.wikitty.entities.WikittyTreeNodeImpl; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.search.Search; +import org.nuiton.wikitty.search.operators.Element; + +/** + * WikittyService is main service + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceStorage implements WikittyService { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceStorage.class); + + /** Default migration use to migrate a wikitty in last extension version */ + protected WikittyExtensionMigration defaultExtensionMigration = + new WikittyExtensionMigrationRename(); + + protected WikittySearchEngin searchEngin; + protected WikittyExtensionStorage extensionStorage; + protected WikittyStorage wikittyStorage; + + /** + * TODO poussin 20101027 remove it when all used WikittyServiceHelper.build + * + * Used by specific child + * {@link org.nuiton.wikitty.jdbc.WikittyServiceJDBC} + * {@link org.nuiton.wikitty.jdbc.WikittyServiceJPA} + * {@link org.nuiton.wikitty.jdbc.WikittyServiceHbase} + */ + protected WikittyServiceStorage() { + } + + public WikittyServiceStorage(WikittyExtensionStorage extensionStorage, + WikittyStorage wikittyStorage, + WikittySearchEngin searchEngin) { + this.extensionStorage = extensionStorage; + this.wikittyStorage = wikittyStorage; + this.searchEngin = searchEngin; + } + + protected WikittySearchEngin getSearchEngin() { + return searchEngin; + } + + protected WikittyExtensionStorage getExtensionStorage() { + return extensionStorage; + } + + protected WikittyStorage getWikittyStorage() { + return wikittyStorage; + } + + /* + * @see org.nuiton.wikitty.WikittyService#addWikittyServiceListener(org.nuiton.wikitty.WikittyListener, org.nuiton.wikitty.WikittyService.ServiceListenerType) + */ + @Override + public void addWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { + throw new UnsupportedOperationException("Can't add listener on " + WikittyServiceStorage.class.getName()); + } + + /* + * @see org.nuiton.wikitty.WikittyService#removeWikittyServiceListener(org.nuiton.wikitty.WikittyListener, org.nuiton.wikitty.WikittyService.ServiceListenerType) + */ + @Override + public void removeWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { + throw new UnsupportedOperationException("Can't remove listener on " + WikittyServiceStorage.class.getName()); + } + + @Override + public String login(String login, String password) { + log.warn("login asked, but there is no security service"); + return null; + } + + @Override + public void logout(String securityToken) { + log.warn("logout asked, but there is no security service"); + } + + @Override + public boolean canWrite(String securityToken, Wikitty wikitty) { + return true; + } + + @Override + public boolean canDelete(String securityToken, String wikittyId) { + return true; + } + + @Override + public boolean canRead(String securityToken, String wikittyId) { + return true; + } + + protected void checkConstraint(Collection<Wikitty> wikitties) { + for(Wikitty w : wikitties) { + for(WikittyExtension ext : w.getExtensions()) { + for (String fieldName : ext.getFieldNames()) { + FieldType type = ext.getFieldType(fieldName); + if (type.isNotNull()) { + if (null == w.getFieldAsObject(ext.getName(), fieldName)) { + throw new WikittyException(String.format( + "Field %s must not be null", fieldName)); + } + } + } + } + } + } + +// @Override +// public UpdateResponse store(String securityToken, WikittyTransaction transaction, +// Collection<Wikitty> wikitties, boolean force) { +// if (!(wikitties instanceof Set)) { +// // use all time Set to prevent duplicated wikitty in collection +// wikitties = new LinkedHashSet<Wikitty>(wikitties); +// } +// checkConstraint(wikitties); +// +// // update/store extension if necessary +// Set<WikittyExtension> allExtensions = new LinkedHashSet<WikittyExtension>(); +// for (Wikitty w : wikitties) { +// // collect all extensions used by all wikitties +// allExtensions.addAll(w.getExtensions()); +// } +// +// // try to commit command +// UpdateResponse extUpdate = getExtensionStorage().store(transaction, allExtensions); +// UpdateResponse wikUpdate = getWikittyStorage().store(transaction, wikitties, force); +// UpdateResponse indexUpdate = getSearchEngin().store(transaction, wikitties); +// +// UpdateResponse result = new UpdateResponse(); +// // prepare update client response +// result.add(extUpdate); +// result.add(wikUpdate); +// result.add(indexUpdate); +// +// return result; +// } + @Override + public WikittyEvent store(String securityToken, + Collection<Wikitty> wikitties, boolean force) { + WikittyEvent result = store(securityToken, null, wikitties, force); + return result; + } + + protected WikittyEvent store(String securityToken, + WikittyTransaction transaction, + Collection<Wikitty> wikitties, boolean force) { + if (!(wikitties instanceof Set)) { + // use all time Set to prevent duplicated wikitty in collection + wikitties = new LinkedHashSet<Wikitty>(wikitties); + } + checkConstraint(wikitties); + + // update/store extension if necessary + Set<WikittyExtension> allExtensions = new LinkedHashSet<WikittyExtension>(); + for (Wikitty w : wikitties) { + // collect all extensions used by all wikitties + allExtensions.addAll(w.getExtensions()); + } + + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + // try to commit command + WikittyEvent extUpdate = + getExtensionStorage().store(transaction, allExtensions); + WikittyEvent wikUpdate = + getWikittyStorage().store(transaction, wikitties, force); + getSearchEngin().store(transaction, wikitties); + + WikittyEvent result = new WikittyEvent(this); + // prepare update client response + result.add(extUpdate); + result.add(wikUpdate); + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't store wikitty", eee); + } + } + + @Override + public List<String> getAllExtensionIds(String securityToken) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + List<String> result = getExtensionStorage().getAllExtensionIds(transaction); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't retrieve all extension's ids", eee); + } + } + + @Override + public List<String> getAllExtensionsRequires( + String securityToken, String extensionName) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + List<String> result = getExtensionStorage() + .getAllExtensionsRequires(transaction, extensionName); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException(String.format( + "Can't retrieve all required extension for %s", extensionName), eee); + } + } + + @Override + public WikittyEvent storeExtension( + String securityToken, Collection<WikittyExtension> exts) { + WikittyEvent result = storeExtension(securityToken, null, exts); + return result; + } + + @Override + public WikittyEvent deleteExtension( + String securityToken, Collection<String> extNames) { + WikittyEvent result = deleteExtension(securityToken, null, extNames); + return result; + } + + protected WikittyEvent storeExtension(String securityToken, + WikittyTransaction transaction, Collection<WikittyExtension> exts) { + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + WikittyEvent result = + getExtensionStorage().store(transaction, exts); + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't store extensions", eee); + } + } + + protected WikittyEvent deleteExtension(String securityToken, + WikittyTransaction transaction, Collection<String> extNames) { + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + // check that all extensions are not used + for(String name : extNames) { + // only name are stored in index, search only on name + Criteria criteria = Search.query().eq(Element.ELT_EXTENSION, name).criteria(); + criteria.setEndIndex(0); // result is not use, just numFound + PagedResult<String> wikittyWithExt = findAllByCriteria( + securityToken, transaction, criteria); + int numFound = wikittyWithExt.getNumFound(); + if (numFound > 0) { + throw new WikittyException(String.format( + "Can't delete %s extension, this extension" + + " is in used by %s wikitty", + name, numFound)); + } + } + + WikittyEvent result = + getExtensionStorage().delete(transaction, extNames); + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't delete extensions", eee); + } + } + + @Override + public WikittyExtension restoreExtension( + String securityToken, String extensionId) { + WikittyExtension result = restoreExtension(securityToken, null, extensionId); + return result; + } + + protected WikittyExtension restoreExtension( + String securityToken, WikittyTransaction transaction, String extensionId) { + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + //split the id to ensure that version is normalized + String name = WikittyExtension.computeName(extensionId); + String version = WikittyExtension.computeVersion(extensionId); + + WikittyExtension result = getExtensionStorage().restore(transaction, name, version); + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't restore extensions", eee); + } + } + + @Override + public WikittyExtension restoreExtensionLastVersion( + String securityToken, String name) { + WikittyExtension result = restoreExtensionLastVersion(securityToken, null, name); + return result; + } + + protected WikittyExtension restoreExtensionLastVersion(String securityToken, + WikittyTransaction transaction, String name) { + String version = getExtensionStorage().getLastVersion(transaction, name); + if(version == null) { + return null; + } + + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + WikittyExtension result = getExtensionStorage().restore(transaction, name, version); + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't store extensions", eee); + } + } + + protected Wikitty restore(String securityToken, + WikittyTransaction transaction, String id) { + if (id == null) { + return null; + } + if (!getWikittyStorage().exists(transaction, id)) { + // object doesn't exist, we return null + return null; + } + + if (getWikittyStorage().isDeleted(transaction, id)) { + // object deleted, we return null + return null; + } + Wikitty result = getWikittyStorage().restore(transaction, id); + if(result != null) { + result = upgradeData(securityToken, transaction, result); + } + return result; + } + + @Override + public List<Wikitty> restore(String securityToken, List<String> ids) { + List<Wikitty> result = restore(securityToken, null, ids); + return result; + } + + protected List<Wikitty> restore(String securityToken, + WikittyTransaction transaction, List<String> ids) { + + List<Wikitty> result = new ArrayList<Wikitty>(); + boolean txCreated = false; + try { + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + for (String id : ids) { + Wikitty w = restore(securityToken, transaction, id); + // on l'ajoutde tout le temps, meme si w est nul lorsqu'il y a + // une demande et qu'elle echoue on ajout + // bien null, pour qu'il y ait une correspondance 1 pour 1 + // avec la demande + result.add(w); + } + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Can't restore wikitty", eee); + } + } + + // FIXME poussin 20101029 use WikittyServiceTransaction and remove other transaction + protected Wikitty upgradeData(String securityToken, + WikittyTransaction transaction, Wikitty wikitty) { + Wikitty result = wikitty; + + Collection<WikittyExtension> extensions = wikitty.getExtensions(); + for (WikittyExtension extension : extensions) { + String extensionName = extension.getName(); + + if (log.isDebugEnabled()) { + log.debug("extensionName=" + extensionName); + } + + WikittyExtension currentExtension = extension; + String currentExtensionVersion = currentExtension.getVersion(); + + WikittyExtension lastExtension = restoreExtensionLastVersion( + securityToken, transaction, extensionName); + String lastExtensionVersion = lastExtension.getVersion(); + + if (log.isDebugEnabled()) { + log.debug("lastExtensionVersion=" + lastExtensionVersion); + } + + WikittyExtensionMigration migration = + WikittyExtensionMigration.migrationRegistry.get(extensionName); + if (migration == null) { + migration = defaultExtensionMigration; + } + + // Loop on between extension in wikitty and last version + while(WikittyUtil.versionGreaterThan(lastExtensionVersion, currentExtensionVersion)) { + + // Get extension after the current version + String nextExtensionVersion = + WikittyUtil.incrementMajorRevision(currentExtensionVersion); + String nextExtensionId = + WikittyExtension.computeId(extensionName, nextExtensionVersion); + WikittyExtension nextExtension = restoreExtension( + securityToken, transaction, nextExtensionId); + + if (log.isDebugEnabled()) { + log.debug("currentExtensionVersion=" + currentExtensionVersion); + log.debug("nextExtensionVersion=" + nextExtensionVersion); + } + + // Test if extension is never use in this version + if(nextExtension != null) { + result = migration.migrate(this, result, + currentExtension, nextExtension); + currentExtension = nextExtension; + } + + // Follow + currentExtensionVersion = nextExtensionVersion; + } + } + + return result; + } + + protected WikittyEvent delete(String securityToken, WikittyTransaction transaction, + Collection<String> ids) throws WikittyException { + // work only on valid id + Collection<Wikitty> storedWikitties = new LinkedHashSet<Wikitty>(); + // copy ids because we can remove some element, and modify it + // use set to prevent id duplication and preformance (contains method call) + Set<String> idSet = new LinkedHashSet<String>(ids); + for (Iterator<String> i = idSet.iterator(); i.hasNext();) { + String id = i.next(); + // test if wikitty exists + if (!getWikittyStorage().exists(transaction, id)) { + // don't exist, remove this id in id list + i.remove(); + // go to the next id, because this id doesn't exist and can't + // be used in tree + continue; + } + if (getWikittyStorage().isDeleted(transaction, id)) { + // already deleted, remove this id in id list + i.remove(); + // go to the next id, because this id already deleted and can't + // be used in tree + continue; + } + + // Store node with have deleted node as parent + Criteria criteria = + Search.query().eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, id).criteria(); + List<String> wikittyNodesId = findAllByCriteria( + securityToken, transaction, criteria).getAll(); + for (String wikittyNodeId : wikittyNodesId) { + if(!idSet.contains(wikittyNodeId)) { + Wikitty treeNode = restore( + securityToken, transaction, wikittyNodeId); + WikittyTreeNodeHelper.setParent(treeNode, null); + storedWikitties.add(treeNode); + } + } + + // Store node with have deleted child + criteria = Search.query().eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_ATTACHMENT, id).criteria(); + wikittyNodesId = findAllByCriteria( + securityToken, transaction, criteria).getAll(); + for (String wikittyNodeId : wikittyNodesId) { + if(!idSet.contains(wikittyNodeId)) { + Wikitty treeNode = restore( + securityToken, transaction, wikittyNodeId); + WikittyTreeNodeHelper.removeAttachment(treeNode, id); + storedWikitties.add(treeNode); + } + } + } + + WikittyEvent eventDelete = + getWikittyStorage().delete(transaction, idSet); + getSearchEngin().delete(transaction, idSet); + + WikittyEvent eventStore = + store(securityToken, transaction, storedWikitties, false); + + WikittyEvent result = new WikittyEvent(this); + result.add(eventDelete); + result.add(eventStore); + + return result; + } + + @Override + public WikittyEvent delete(String securityToken, Collection<String> ids){ + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + WikittyEvent result = delete(securityToken, transaction, ids); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't delete wikitty", eee); + } + } + + /** + * Use with caution : It will delete ALL indexes from search engine ! + * This operation should be disabled in production environment. + */ + @Override + public WikittyEvent clear(String securityToken) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + + WikittyEvent result = clear(securityToken, transaction); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't clear all data", eee); + } + } + + /** + * Use with caution : It will delete ALL indexes from search engine ! + * This operation should be disabled in production environment. + */ + protected WikittyEvent clear(String securityToken, WikittyTransaction tx) { + getSearchEngin().clear(tx); + WikittyEvent eventWik = getWikittyStorage().clear(tx); + WikittyEvent eventExt = getExtensionStorage().clear(tx); + + WikittyEvent result = new WikittyEvent(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 + */ + @Override + public PagedResult<String> findAllByCriteria( + String securityToken, Criteria criteria) { + PagedResult<String> result = findAllByCriteria(securityToken, null, criteria); + return result; + } + + protected PagedResult<String> findAllByCriteria(String securityToken, + WikittyTransaction transaction, Criteria criteria) { + try { + boolean txCreated = false; + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + PagedResult<String> result = + getSearchEngin().findAllByCriteria(transaction, criteria); + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Error during find", eee); + } + } + + @Override + public Wikitty findByCriteria(String securityToken, Criteria criteria) { + Wikitty result = findByCriteria(securityToken, null, criteria); + return result; + } + + protected Wikitty findByCriteria(String securityToken, + WikittyTransaction transaction, Criteria criteria) { + try { + boolean txCreated = false; + if (transaction == null) { + transaction = new WikittyTransaction(); + txCreated = true; + transaction.begin(); + } + + criteria.setFirstIndex(0).setEndIndex(1); + PagedResult<String> pages = findAllByCriteria( + securityToken, transaction, criteria); + + Wikitty result = null; + if (pages.size() > 0) { + String id = pages.getFirst(); + result = restore(securityToken, transaction, id); + } + + if (txCreated) { + transaction.commit(); + } + return result; + } catch (WikittyException ex) { + if (transaction != null) { + transaction.rollback(); + } + throw ex; + } catch (Exception eee) { + if (transaction != null) { + transaction.rollback(); + } + throw new WikittyException("Error during find", eee); + } + } + + protected WikittyTree restoreTree(String securityToken, + WikittyTransaction transaction, String wikittyId) { + Wikitty w = restore(securityToken, transaction, wikittyId); + if(w == null) { + return null; + } + + if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { + throw new WikittyException(String.format( + "Wikitty '%s' do not handle extension %s", + wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); + } + WikittyTree tree = new WikittyTree(); + WikittyTreeNode node = new WikittyTreeNodeImpl(w); + tree.setNode(node); + + WikittyTreeNodeImpl exempleNode = new WikittyTreeNodeImpl(); + exempleNode.setParent(wikittyId); + + Criteria criteria = Search.query(exempleNode.getWikitty()).criteria() + .setFirstIndex(0).setEndIndex(Criteria.ALL_ELEMENTS); + PagedResult<String> childNodesId = findAllByCriteria( + securityToken, transaction, criteria); + for (String childNodeId : childNodesId.getAll()) { + tree.addChild(restoreTree(securityToken, transaction, childNodeId)); + } + + return tree; + } + + @Override + public WikittyTree restoreTree(String securityToken, String wikittyId) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + WikittyTree tree = restoreTree(securityToken, transaction, wikittyId); + + transaction.commit(); + return tree; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't restore tree", eee); + } + } + + @Override + public WikittyEvent deleteTree(String securityToken, String thesaurusId) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + WikittyEvent result = deleteTree(securityToken, transaction, thesaurusId); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't delete tree", eee); + } + } + + /** + * Delete specified treenode and sub treenode. + * + * @param securityToken security token + * @param transaction transaction + * @param treeNodeId thesaurusId to delete + * @return all id of delete nodes + */ + protected WikittyEvent deleteTree(String securityToken, WikittyTransaction transaction, String treeNodeId) { + List<String> allTreeNodeId = getRecursiveTreeNodeId(securityToken, transaction, treeNodeId); + WikittyEvent result = delete(securityToken, transaction, allTreeNodeId); + return result; + } + + /** + * Get recursive id of tree node children of {@code treeNodeId}. + * + * @param securityToken security token + * @param transaction transaction + * @param treeNodeId tree node id + * @return all id of {@code treeNodeId}'s children + */ + protected List<String> getRecursiveTreeNodeId(String securityToken, WikittyTransaction transaction, String treeNodeId) { + + Search search = Search.query(); + search = search.eq(WikittyTreeNode.FQ_FIELD_WIKITTYTREENODE_PARENT, treeNodeId); + Criteria criteria = search.criteria(); + + PagedResult<String> childTreeNodeIds = findAllByCriteria(securityToken, transaction, criteria); + List<String> treeNodeIds = new ArrayList<String>(); + treeNodeIds.add(treeNodeId); + for (String childTreeNodeId : childTreeNodeIds.getAll()) { + List<String> subTreeNodeIds = getRecursiveTreeNodeId(securityToken, transaction, childTreeNodeId); + treeNodeIds.addAll(subTreeNodeIds); + } + return treeNodeIds; + } + + @Override + public Map.Entry<WikittyTreeNode, Integer> restoreNode(String securityToken, + String wikittyId, Criteria filter) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + Wikitty w = restore(securityToken, transaction, wikittyId); + if(w == null) { + transaction.commit(); + return null; + } + + if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { + throw new WikittyException(String.format( + "Wikitty '%s' do not handle extension %s", + wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); + } + + WikittyTreeNode node = new WikittyTreeNodeImpl(w); + Integer count = getSearchEngin().findNodeCount(transaction, w, filter); + + HashMap.SimpleEntry<WikittyTreeNode, Integer> result = + new SimpleEntry<WikittyTreeNode, Integer>(node, count); + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't restore node", eee); + } + } + + @Override + public Map<WikittyTreeNode, Integer> restoreChildren(String securityToken, + String wikittyId, Criteria filter) { + WikittyTransaction transaction = new WikittyTransaction(); + try { + transaction.begin(); + + Wikitty w = restore(securityToken, transaction, wikittyId); + if(w == null) { + transaction.commit(); + return null; + } + + if ( !w.hasExtension(WikittyTreeNode.EXT_WIKITTYTREENODE) ) { + throw new WikittyException(String.format( + "Wikitty '%s' do not handle extension %s", + wikittyId, WikittyTreeNode.EXT_WIKITTYTREENODE )); + } + + Map<WikittyTreeNode, Integer> result = new LinkedHashMap<WikittyTreeNode, Integer>(); + + Map<String, Integer> search = getSearchEngin().findAllChildrenCount( + transaction, w, filter); + Set<Entry<String, Integer>> children = search.entrySet(); + for (Entry<String, Integer> child : children) { + Integer count = child.getValue(); + + String id = child.getKey(); + Wikitty wikitty = restore(securityToken, transaction, id); + WikittyTreeNode node = new WikittyTreeNodeImpl(wikitty); + + result.put(node, count); + } + + transaction.commit(); + return result; + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't restore children", eee); + } + } + + @Override + public Wikitty restoreVersion(String securityToken, + String wikittyId, String version) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void syncEngin(final String securityToken) { + final WikittyTransaction transaction = new WikittyTransaction(); + try { + final int numberForCommit = 1000; + final WikittySearchEngin searchEngin = getSearchEngin(); + final List<Wikitty> wikitties = new ArrayList<Wikitty>(numberForCommit); + + transaction.begin(); + searchEngin.clear(transaction); + transaction.commit(); + transaction.begin(); + + getWikittyStorage().scanWikitties(transaction, new WikittyStorage.Scanner() { + int count = 0; + + @Override + public void scan(String wikittyId) { + Wikitty wikitty = restore(securityToken, transaction, wikittyId); + Date deleteDate = wikitty.getDeleteDate(); + if(deleteDate == null) { + count ++; + wikitties.add(wikitty); + + if(count == numberForCommit) { + // Reindex + searchEngin.store(transaction, wikitties); + transaction.commit(); + // Reinit + count = 0; + wikitties.clear(); + transaction.begin(); + } + } + } + }); + + // Last wikitties + searchEngin.store(transaction, wikitties); + transaction.commit(); + } catch (Exception eee) { + transaction.rollback(); + throw new WikittyException("Can't sync searchable index with data", eee); + } + } + + /** + * 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 WikittyEvent replay( + String securityToken, List<WikittyEvent> events, boolean force) { + // 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>(); + // toutes les extensions a supprimer + Set<String> toDeleteExt = new LinkedHashSet<String>(); + + // 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 (WikittyEvent 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( + WikittyEvent.WikittyEventType.CLEAR_WIKITTY) + || e.getType().contains( + WikittyEvent.WikittyEventType.CLEAR_EXTENSION)) { + mustClear = true; + toAddWikitty.clear(); + toRemoveWikitty.clear(); + toAddExt.clear(); + } + if (e.getType().contains(WikittyEvent.WikittyEventType.PUT_WIKITTY)) { + for (Wikitty w : e.getWikitties().values()) { + toAddWikitty.put(w.getId(), w); + } + } + if (e.getType().contains(WikittyEvent.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(WikittyEvent.WikittyEventType.PUT_EXTENSION)) { + for (WikittyExtension ext : e.getExtensions().values()) { + toAddExt.add(ext); + } + } + if (e.getType().contains(WikittyEvent.WikittyEventType.REMOVE_EXTENSION)) { + for (String extName : e.getDeletedExtensions()) { + toDeleteExt.add(extName); + } + } + } + + WikittyTransaction tx = new WikittyTransaction(); + try { + tx.begin(); + + WikittyEvent result = new WikittyEvent(this); + if (mustClear) { + WikittyEvent eventClear = clear(securityToken, tx); + result.add(eventClear); + } + WikittyEvent eventStoreExtension = + storeExtension(securityToken, tx, toAddExt); + result.add(eventStoreExtension); + + WikittyEvent eventDeleteExtension = + deleteExtension(securityToken, tx, toDeleteExt); + result.add(eventDeleteExtension); + + WikittyEvent eventStoreWikitty = + store(securityToken, tx, toAddWikitty.values(), force); + result.add(eventStoreWikitty); + + WikittyEvent 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/resources/wikitty-config-sample-inmemory.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties 2010-11-26 13:57:13 UTC (rev 527) @@ -32,11 +32,11 @@ wikitty.storage.jdbc.xadatasource.org.h2.jdbcx.JdbcDataSource.user=${wikitty.storage.jdbc.login} wikitty.storage.jdbc.xadatasource.org.h2.jdbcx.JdbcDataSource.password=${wikitty.storage.jdbc.password} wikitty.searchengine.solr.directory.factory=solr.RAMDirectoryFactory -wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceImpl,\ +wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceStorage,\ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceSecurity -wikitty.WikittyServiceImpl.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ +wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ org.nuiton.wikitty.solr.WikittySearchEnginSolr wikitty.addon.export.threadnumber=1 Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties 2010-11-26 13:57:13 UTC (rev 527) @@ -33,13 +33,13 @@ wikitty.storage.jdbc.xadatasource.org.h2.jdbcx.JdbcDataSource.password=${wikitty.storage.jdbc.password} wikitty.searchengine.solr.directory.data=/var/lib/wikitty/data/solr wikitty.searchengine.solr.directory.factory=solr.StandardDirectoryFactory -wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceImpl,\ +wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceStorage,\ org.nuiton.wikitty.services.WikittyServiceSlave,\ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceSecurity,\ org.nuiton.wikitty.services.WikittyServiceHessianServer -wikitty.WikittyServiceImpl.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ +wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ org.nuiton.wikitty.solr.WikittySearchEnginSolr wikitty.service.server.url=http://services-slave.codelutin.com/wikitty Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties 2010-11-26 13:57:13 UTC (rev 527) @@ -33,12 +33,12 @@ wikitty.storage.jdbc.xadatasource.org.h2.jdbcx.JdbcDataSource.password=${wikitty.storage.jdbc.password} wikitty.searchengine.solr.directory.data=/var/lib/wikitty/data/solr wikitty.searchengine.solr.directory.factory=solr.StandardDirectoryFactory -wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceImpl,\ +wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceStorage,\ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceSecurity,\ org.nuiton.wikitty.services.WikittyServiceHessianServer -wikitty.WikittyServiceImpl.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ +wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ org.nuiton.wikitty.solr.WikittySearchEnginSolr wikitty.service.server.url=http://services.codelutin.com/wikitty Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java 2010-11-26 13:57:13 UTC (rev 527) @@ -25,7 +25,7 @@ package org.nuiton.wikitty.api; -import entities.BusinessEntityImplTest; +import org.nuiton.wikitty.entities.BusinessEntityImplTest; import java.beans.PropertyChangeListener; import java.math.BigDecimal; import java.text.ParseException; Copied: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/BusinessEntityImplTest.java (from rev 519, trunk/wikitty-api/src/test/java/entities/BusinessEntityImplTest.java) =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/BusinessEntityImplTest.java (rev 0) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/BusinessEntityImplTest.java 2010-11-26 13:57:13 UTC (rev 527) @@ -0,0 +1,43 @@ +package org.nuiton.wikitty.entities; + + +import java.beans.PropertyDescriptor; +import java.util.Arrays; +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.beanutils.BeanUtilsBean; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.WikittyLabel; +import org.nuiton.wikitty.entities.WikittyLabelImpl; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class BusinessEntityImplTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(BusinessEntityImplTest.class); + + @Test + public void testCopyFrom() throws Exception { + WikittyLabel source = new WikittyLabelImpl(); + source.addLabels("1erLabel"); + source.addLabels("2emeLabel"); + + WikittyLabel dest = new WikittyLabelImpl(); + + dest.copyFrom(source); + Assert.assertFalse(source.getWikittyId().equals(dest.getWikittyId())); + Assert.assertEquals(source.getWikittyVersion(), dest.getWikittyVersion()); + Assert.assertEquals(source.getLabels(), dest.getLabels()); + } + +} Added: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/WikittyCopyOnWriteTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/WikittyCopyOnWriteTest.java (rev 0) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/entities/WikittyCopyOnWriteTest.java 2010-11-26 13:57:13 UTC (rev 527) @@ -0,0 +1,73 @@ +package org.nuiton.wikitty.entities; + + +import java.util.Collection; +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 WikittyCopyOnWriteTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyCopyOnWriteTest.class); + + @Test + public void testReplace() throws Exception { + WikittyLabelImpl label = new WikittyLabelImpl(); + label.addLabels("toto"); + + Wikitty w = label.getWikitty(); + WikittyCopyOnWrite copy = new WikittyCopyOnWrite(w); + WikittyCopyOnWrite copy2 = new WikittyCopyOnWrite(w); + + WikittyLabelHelper.addLabels(copy, "titi"); + + System.out.println("copy:" + copy); + + // test de replaceWith d'un WImpl vers un WCopyOnWrite + { + Assert.assertFalse(WikittyLabelHelper.getLabels(w).equals(WikittyLabelHelper.getLabels(copy))); + Assert.assertEquals(w.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + w.replaceWith(copy); + Assert.assertEquals(WikittyLabelHelper.getLabels(w), WikittyLabelHelper.getLabels(copy)); + Assert.assertEquals(w.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + } + + // test de replaceWith d'un WCopyOnWrite vers un WImpl + { + WikittyLabelHelper.addLabels(w, "tyty"); + Assert.assertFalse(WikittyLabelHelper.getLabels(w).equals(WikittyLabelHelper.getLabels(copy))); + Assert.assertEquals(w.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + copy.replaceWith(w); + Assert.assertEquals(WikittyLabelHelper.getLabels(w), WikittyLabelHelper.getLabels(copy)); + Assert.assertEquals(w.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + } + + System.out.println("copy:" + copy + "\n" + copy2); + // test de replaceWith d'un WCopyOnWrite vers un WCopyOnWrite + { + Assert.assertFalse(WikittyLabelHelper.getLabels(copy).equals(WikittyLabelHelper.getLabels(copy2))); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy2.getExtensionNames(), Collections.singleton("WikittyLabel")); + copy2.replaceWith(copy); + Assert.assertEquals(WikittyLabelHelper.getLabels(copy), WikittyLabelHelper.getLabels(copy2)); + Assert.assertEquals(copy.getExtensionNames(), Collections.singleton("WikittyLabel")); + Assert.assertEquals(copy2.getExtensionNames(), Collections.singleton("WikittyLabel")); + } + + } +} Modified: trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/jdbc/WikittyServiceJDBC.java =================================================================== --- trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/jdbc/WikittyServiceJDBC.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/jdbc/WikittyServiceJDBC.java 2010-11-26 13:57:13 UTC (rev 527) @@ -28,7 +28,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.util.ApplicationConfig; -import org.nuiton.wikitty.services.WikittyServiceImpl; +import org.nuiton.wikitty.services.WikittyServiceStorage; import org.nuiton.wikitty.solr.WikittySearchEnginSolr; /** @@ -38,7 +38,7 @@ * Last update: $Date$ * by : $Author$ */ -public class WikittyServiceJDBC extends WikittyServiceImpl { +public class WikittyServiceJDBC extends WikittyServiceStorage { /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(WikittyServiceJDBC.class); Modified: trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemoryJdbcSolr.java =================================================================== --- trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemoryJdbcSolr.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-jdbc-impl/src/main/java/org/nuiton/wikitty/services/WikittyServiceInMemoryJdbcSolr.java 2010-11-26 13:57:13 UTC (rev 527) @@ -43,7 +43,7 @@ * Last update: $Date$ * by : $Author$ */ -public class WikittyServiceInMemoryJdbcSolr extends WikittyServiceImpl { +public class WikittyServiceInMemoryJdbcSolr extends WikittyServiceStorage { /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(WikittyServiceInMemoryJdbcSolr.class); Modified: trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/WikittyServiceSolr.java =================================================================== --- trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/WikittyServiceSolr.java 2010-11-26 13:57:08 UTC (rev 526) +++ trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/WikittyServiceSolr.java 2010-11-26 13:57:13 UTC (rev 527) @@ -26,7 +26,7 @@ package org.nuiton.wikitty.solr.test; import org.nuiton.util.ApplicationConfig; -import org.nuiton.wikitty.services.WikittyServiceImpl; +import org.nuiton.wikitty.services.WikittyServiceStorage; import org.nuiton.wikitty.solr.WikittySearchEnginSolr; import org.nuiton.wikitty.storage.WikittyExtensionStorageInMemory; import org.nuiton.wikitty.storage.WikittyStorageInMemory; @@ -39,7 +39,7 @@ * Last update: $Date$ * by : $Author$ */ -public class WikittyServiceSolr extends WikittyServiceImpl { +public class WikittyServiceSolr extends WikittyServiceStorage { public WikittyServiceSolr(ApplicationConfig config) { extensionStorage = new WikittyExtensionStorageInMemory();
participants (1)
-
bpoussin@users.nuiton.org