
org.nuiton.wikitty.services.WikittyServiceTransaction Maven / Gradle / Ivy
The newest version!
/*
* #%L
* Wikitty :: api
* %%
* 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
* .
* #L%
*/
package org.nuiton.wikitty.services;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.config.ApplicationConfig;
import org.nuiton.wikitty.search.Criteria;
import org.nuiton.wikitty.search.FacetTopic;
import org.nuiton.wikitty.search.PagedResult;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.entities.WikittyExtension;
import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.WikittyServiceFactory;
import org.nuiton.wikitty.WikittyUtil;
import org.nuiton.wikitty.entities.Element;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryResult;
import org.nuiton.wikitty.query.WikittyQueryResultTreeNode;
import org.nuiton.wikitty.query.conditions.Select;
import org.nuiton.wikitty.search.Search;
import org.nuiton.wikitty.search.TreeNodeResult;
/**
*
* @author poussin
* @version $Revision$
*
* Last update: $Date$
* by : $Author$
*/
public class WikittyServiceTransaction implements WikittyService {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private Log log = LogFactory.getLog(WikittyServiceTransaction.class);
/** Real WikittyService */
protected WikittyService ws;
/** WikittyService used to store modified object */
protected WikittyService tx;
protected List events;
/** if autoCommit > 0 all time events numbers element equals to this
* autoCommit commit is call */
protected int autoCommit = -1;
public WikittyServiceTransaction(ApplicationConfig config, WikittyService ws) {
this.ws = ws;
// use WikittyService in Memory
// use configuration to retrive transaction in memory implementation
// you must used WikittyServiceInMemoryJdbcSolr implementation
this.tx = WikittyServiceFactory.buildWikittyServiceTransaction(config);
events = new LinkedList();
}
public void setAutoCommit(int autoCommit) {
this.autoCommit = autoCommit;
}
public int getAutoCommit() {
return autoCommit;
}
protected void addEvent(String securityToken, WikittyEvent e) {
events.add(e);
if (autoCommit > 0 && events.size() >= autoCommit) {
commit(securityToken);
}
}
public void commit(String securityToken) {
ws.replay(securityToken, events, false);
this.tx.clear(null);
events.clear();
}
public void commit(String securityToken, boolean force) {
ws.replay(securityToken, events, force);
this.tx.clear(null);
events.clear();
}
public void rollback(String securityToken) {
this.tx.clear(null);
events.clear();
}
@Override
public void addWikittyServiceListener(WikittyListener listener, ServiceListenerType type) {
throw new UnsupportedOperationException(
"You try to add listener on WikittyServiceTransaction,"
+ "this is an error desgin, you must add WikittyServiceNotifier"
+ "front of your WikittyServiceTransaction.");
}
@Override
public void removeWikittyServiceListener(WikittyListener listener, ServiceListenerType type) {
throw new UnsupportedOperationException(
"You try to remove listener on WikittyServiceTransaction,"
+ "this is an error desgin, you must add WikittyServiceNotifier"
+ "front of your WikittyServiceTransaction.");
}
@Override
public String login(String login, String password) {
return ws.login(login, password);
}
/**
* Question: est un comportement normale, lorsqu'on se delogue depuis une
* transaction, on est deloguer partout ? je pense que oui
* @param securityToken
*/
@Override
public void logout(String securityToken) {
ws.logout(securityToken);
}
@Override
public String getToken(String user) {
return ws.getToken(user);
}
@Override
public WikittyEvent clear(String securityToken) {
WikittyEvent e = tx.clear(securityToken);
addEvent(securityToken, e);
return e;
}
@Override
public boolean canWrite(String securityToken, Wikitty wikitty) {
// in transaction, we can do all. But not during commit
return true;
}
@Override
public boolean canDelete(String securityToken, String wikittyId) {
// in transaction, we can do all. But not during commit
return true;
}
@Override
public boolean canRead(String securityToken, String wikittyId) {
boolean result = tx.exists(securityToken, wikittyId);
if (!result) {
// on ne l'a pas en local on va voir si on peut le lire en distant
result = ws.canRead(securityToken, wikittyId);
}
return result;
}
@Override
public WikittyEvent replay(
String securityToken, List events, boolean force) {
WikittyEvent e = tx.replay(securityToken, events, force);
events.add(e);
return e;
}
@Override
public WikittyEvent store(
String securityToken, Collection wikitties, boolean force) {
WikittyEvent e = tx.store(securityToken, wikitties, force);
addEvent(securityToken, e);
return e;
}
@Override
public List getAllExtensionIds(String securityToken) {
HashSet tmp = new HashSet();
tmp.addAll(tx.getAllExtensionIds(securityToken));
tmp.addAll(ws.getAllExtensionIds(securityToken));
List result = new ArrayList(tmp);
return result;
}
@Override
public List getAllExtensionsRequires(String securityToken, String extensionName) {
HashSet tmp = new HashSet();
tmp.addAll(tx.getAllExtensionsRequires(securityToken, extensionName));
tmp.addAll(ws.getAllExtensionsRequires(securityToken, extensionName));
List result = new ArrayList(tmp);
return result;
}
@Override
public WikittyEvent storeExtension(
String securityToken, Collection exts) {
WikittyEvent e = tx.storeExtension(securityToken, exts);
addEvent(securityToken, e);
return e;
}
@Override
public WikittyEvent deleteExtension(
String securityToken, Collection extNames) {
WikittyEvent e = tx.deleteExtension(securityToken, extNames);
addEvent(securityToken, e);
return e;
}
@Override
public WikittyExtension restoreExtension(
String securityToken, String extensionId) {
WikittyExtension result = tx.restoreExtension(securityToken, extensionId);
if (result == null) {
result = ws.restoreExtension(securityToken, extensionId);
}
return result;
}
@Override
public WikittyExtension restoreExtensionLastVersion(
String securityToken, String name) {
WikittyExtension result =
tx.restoreExtensionLastVersion(securityToken, name);
if (result == null) {
result = ws.restoreExtensionLastVersion(securityToken, name);
}
return result;
}
@Override
public List restoreExtensionAndDependenciesLastVesion(String securityToken, Collection extensionNames) {
List result = new ArrayList();
for (String extName : extensionNames) {
WikittyExtension ext = restoreExtensionLastVersion(
securityToken, extName);
if (ext != null) {
// on recherche les dependances de cette extension ...
List requires = ext.getRequires();
if (CollectionUtils.isNotEmpty(requires)) {
List dependencies =
restoreExtensionAndDependenciesLastVesion(
securityToken, requires);
// ... et on les ajoute avant dans le resultat
result .addAll(dependencies);
}
result.add(ext);
}
}
return result;
}
@Override
public List restore(String securityToken, List ids) {
List resultWS = ws.restore(securityToken, ids);
List resultTx = tx.restore(securityToken, ids);
Wikitty[] result = resultWS.toArray(new Wikitty[resultWS.size()]);
int i = 0;
for (Wikitty w : resultTx) {
String id = ids.get(i);
// il faut prendre en compte que l'objet a pu etre supprime dans la
// transaction donc meme s'il est null dans tx et pas dans ws, il
// faut le mettre a null
// si w n'a pas ete restore (null), mais qu'il exist, alors cela
// veut dire qu'il est supprime.
if (w != null || tx.exists(securityToken, id)) {
// on remplace tout par les nouveaux de la transaction
result[i] = w;
}
i++;
}
return Arrays.asList(result);
}
@Override
public WikittyEvent delete(String securityToken, Collection ids) {
// pour que tout fonctionne bien, il faut que les objets supprimer soit
// dans la tx, car il faut avoir une vrai trace de cette suppression dans la tx
List wikitties = ws.restore(securityToken, new ArrayList(ids));
tx.store(securityToken, wikitties, true);
WikittyEvent e = tx.delete(securityToken, ids);
addEvent(securityToken, e);
return e;
}
@Override
public List> findAllByCriteria(
String securityToken, List criteria) {
List> resultTxList =
tx.findAllByCriteria(securityToken, criteria);
List> resultWsList =
ws.findAllByCriteria(securityToken, criteria);
List> result =
new ArrayList>(resultWsList.size());
for (int i=0; i resultTx = resultTxList.get(i);
PagedResult resultWs = resultWsList.get(i);
// Il faut fusionner les deux resultats
// - ne pas avoir de doublon
// - ne pas retenir ceux supprimer dans la transaction
// - fusionner les facettes (comment faire ?)
// - respecter le range demander (comment faire, avec les suppressions possible ?)
LinkedHashSet ids =
new LinkedHashSet(resultTx.size() + resultWs.size());
ids.addAll(resultTx.getAll());
for (String id : resultWs.getAll()) {
if (!tx.exists(securityToken, id) || !tx.isDeleted(securityToken, id)) {
ids.add(id);
}
}
String criteriaName = resultWs.getCriteriaName();
int firstIndice = resultWs.getFirstIndice();
// FIXME le resultat est faux, le nombre total n'est pas la somme des deux :(
int numFound = resultTx.getNumFound() + resultWs.getNumFound();
String queryString = resultWs.getQueryString();
// FIXME les facettes sont fausses :(
Map> facets = resultWs.getFacets();
List results = new ArrayList(ids);
result.add(new PagedResult(criteriaName,
firstIndice, numFound, queryString, facets, results));
}
if (criteria.size() != result.size()) {
log.error(String.format("Criteria input list (%s) has not same size that result list (%s)",
criteria.size(), result.size()));
}
return result;
}
@Override
public List findByCriteria(String securityToken, List criteria) {
List result = new ArrayList(criteria.size());
List criteriaLimit = new ArrayList(criteria.size());
for (Criteria c : criteria) {
Criteria climit = Search.query(c).criteria().setFirstIndex(0).setEndIndex(1);
criteriaLimit.add(climit);
}
List> idsList = findAllByCriteria(
securityToken, criteriaLimit);
for (PagedResult ids : idsList) {
if (ids.size() > 0) {
result.add(ids.getFirst());
} else {
result.add(null);
}
}
if (criteria.size() != result.size()) {
log.error(String.format("Criteria input list (%s) has not same size that result list (%s)",
criteria.size(), result.size()));
}
return result;
}
@Override
public TreeNodeResult findTreeNode(String securityToken,
String wikittyId, int depth, boolean count, Criteria filter) {
// FIXME
throw new UnsupportedOperationException("Not supported yet.");
}
// FIXME poussin 20130218 a revoir car les order by, les facets, limit et offset ne sont pas respecte :(
@Override
public List>> findAllByQuery(
String securityToken, List queries) {
// on recree une liste avec seulement les clause where
List queriesWhere = new ArrayList();
for (WikittyQuery q : queries) {
if (q.isSelectQuery()) {
queriesWhere.add(q.getWhereQuery());
} else {
queriesWhere.add(q);
}
}
// on ne joue que les clauses where car le select sera rejouer completement
List>> resultTxList =
tx.findAllByQuery(securityToken, queriesWhere);
List>> resultWsList =
ws.findAllByQuery(securityToken, queriesWhere);
List>> result =
new ArrayList>>(queries.size());
for (int i=0; i> resultTx = resultTxList.get(i);
WikittyQueryResult
© 2015 - 2025 Weber Informatics LLC | Privacy Policy