org.nuiton.topia.replication.TopiaReplicationModelBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of topia-service-replication Show documentation
Show all versions of topia-service-replication Show documentation
Hibernate based replication service
/*
* #%L
* ToPIA :: Service Replication
*
* $Id: TopiaReplicationModelBuilder.java 2245 2011-04-14 12:47:09Z tchemit $
* $HeadURL: http://svn.nuiton.org/svn/topia/tags/topia-2.6.6/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java $
* %%
* Copyright (C) 2004 - 2010 CodeLutin
* %%
* 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.topia.replication;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaContext;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.Arrays;
import java.util.Set;
import static org.nuiton.i18n.I18n._;
/**
* Builder of {@link ReplicationModel}.
*
* @author tchemit
* @since 2.4.3
*/
public class TopiaReplicationModelBuilder {
/** Logger */
private static final Log log =
LogFactory.getLog(TopiaReplicationModelBuilder.class);
/** Provider of {@link TopiaReplicationOperation}. */
protected TopiaReplicationOperationProvider operationProvider;
public TopiaReplicationOperationProvider getOperationProvider() {
if (operationProvider == null) {
operationProvider = new TopiaReplicationOperationProvider();
}
return operationProvider;
}
/**
* Prepare le modele de replication pour les entites données dans
* {@code topiaIds} et de leur couverture.
*
* Le paramètre {@code computeOrder} détermine si on doit calculer l'ordre
* de replication des données (valeur à {@code true}), sinon (valeur
* à {@code false}) on utilise l'ordre induit par le paramètre
* {@code contracts}.
*
* @param context le context de la base source (peut être utilisé
* pour calculer l'ordre)
* @param contracts les contrats des types a repliquer
* @param computeOrder drapeau positionné à {@code true} si on doit calculer
* l'ordre de réplication, {@code false} si on utilise
* l'ordre induit par le paramètre {@code contracts}.
* @param topiaIds les ids des entités à répliquer
* @return le modele pour la replication
* @throws TopiaException pour toute erreur rencontree
*/
public ReplicationModel prepare(TopiaContext context,
TopiaEntityEnum[] contracts,
boolean computeOrder,
String... topiaIds) throws TopiaException {
ReplicationModel model =
createModel(context, contracts, computeOrder, topiaIds);
initModel(model, computeOrder);
return model;
}
/**
* Prepare le modele de replication pour toutes les entites des types
* donnes.
*
* La méthode calcule l'ordre de replication des données.
*
* Actuellement, on n'est pas capable de calculer l'ordre si le graphe des
* entités contient des cycles.
*
* TODO : faire en sorte de pouvoir gérer les cycles.
*
* @param contracts les contrats des types a repliquer
* @return le modele pour la replication
* @throws TopiaException pour toute erreur rencontree
*/
public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
ReplicationModel model = createModelForAll(contracts);
initModel(model, true);
return model;
}
public void createOperation(ReplicationModel model,
TopiaEntityEnum type,
ReplicationOperationPhase phase,
Class extends TopiaReplicationOperation> operationClass,
Object... parameters) {
TopiaEntityHelper.checkNotNull("createOperation", "model", model);
TopiaEntityHelper.checkNotNull("createOperation", "type", type);
TopiaEntityHelper.checkNotNull("createOperation", "phase", phase);
TopiaEntityHelper.checkNotNull("createOperation", "operationClass", operationClass);
TopiaReplicationOperation operation =
getOperationProvider().getOperation(operationClass);
if (operation == null) {
throw new IllegalArgumentException(
_("topia.replication.error.unkown.operation",
operationClass.getSimpleName(),
Arrays.toString(getOperationProvider().getOperations()))
);
}
ReplicationNode node = model.getNode(type);
if (node == null) {
throw new IllegalArgumentException(
_("topia.replication.error.unkown.owner.node",
type,
operationClass.getSimpleName(),
model.getNodes())
);
}
operation.register(model, node, phase, parameters);
}
/**
* Ajouter une nouvelle operation pre-replication, sur un type de donnee.
*
* @param model le modele de replication
* @param type le type du noeud de replication
* @param operationClass l'implantation de l'operation
* @param parameters les parametres supplementaires pour l'operation
*/
public void addBeforeOperation(ReplicationModel model,
TopiaEntityEnum type,
Class extends TopiaReplicationOperation> operationClass,
Object... parameters) {
createOperation(
model,
type,
ReplicationOperationPhase.before,
operationClass,
parameters
);
}
/**
* Ajouter une nouvelle operation post-replication, sur un type de donnee.
*
* @param model le modele de replication
* @param type le type du noeud de replication
* @param operationClass l'implantation de l'operation
* @param parameters les parametres supplementaires pour l'operation
*/
public void addAfterOperation(ReplicationModel model,
TopiaEntityEnum type,
Class extends TopiaReplicationOperation> operationClass,
Object... parameters) {
createOperation(
model,
type,
ReplicationOperationPhase.after,
operationClass,
parameters
);
}
/**
* Instantie un nouveau modèle de réplication pour les entités données par
* leur ids.
*
* L'ordre de réplication dépend du paramètre {@code computeOrder}. Si
* celui-ci vaut {@code true}, on calcule l'ordre de réplication, sinon on
* utilise l'ordre induit par les {@code contracts}.
*
* @param context le context Topia pour récupérer certainnes
* informations de la base source si nécessaire.
* @param contracts les types d'entités
* @param computeOrder drapeau pour calculer l'ordre de réplication
* (valeur à {@code true}), sinon on utilise l'ordre
* induit par les {@code contracts}.
* @param topiaIds les ids à dupliquer
* @return le modèle crée mais non initialisé.
* @throws TopiaException pour toute erreur lors de la création du modèle
*/
public ReplicationModel createModel(TopiaContext context,
TopiaEntityEnum[] contracts,
boolean computeOrder,
String... topiaIds)
throws TopiaException {
ReplicationModel model;
if (computeOrder) {
// determines types to use
Set> detectTypes =
detectTypes(context, contracts, topiaIds);
model = new ReplicationModel(contracts, detectTypes, topiaIds);
} else {
model = new ReplicationModel(contracts, false, topiaIds);
}
return model;
}
/**
* Instantie un nouveau modèle de réplication en respectant l'ordre induit
* par les {@code contracts}.
*
* @param contracts les types d'entités
* @param topiaIds les ids à dupliquer
* @return le modèle crée mais non initialisé.
* @throws TopiaException pour toute erreur lors de la création du modèle
* @deprecated since 2.4.3, prefer use method {@link #createModel(TopiaContext, TopiaEntityEnum[], boolean, String...)}
*/
@Deprecated
public ReplicationModel createModelWithComputedOrder(TopiaEntityEnum[] contracts,
String... topiaIds)
throws TopiaException {
ReplicationModel model;
model = new ReplicationModel(contracts, false, topiaIds);
return model;
}
/**
* Instantie un nouveau modèle de réplication pour toutes les entitées.
*
* Ici, l'ordre est toujours calculé.
*
* @param contracts les types d'entités
* @return le modèle crée mais non initialisé.
* @throws TopiaException pour toute erreur lors de la création du modèle
*/
public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
throws TopiaException {
ReplicationModel model = new ReplicationModel(contracts, true);
return model;
}
public ReplicationModel initModel(ReplicationModel model,
boolean computeOrder) throws TopiaException {
TopiaEntityHelper.checkNotNull("initModel", "model", model);
model.detectAssociations();
model.detectDirectDependencies();
if (computeOrder) {
model.detectShell();
model.detectDependencies();
}
model.detectObjectsToDettach();
model.detectOperations();
return model;
}
protected Set> detectTypes(TopiaContext context,
TopiaEntityEnum[] contracts,
String... ids) throws TopiaException {
TopiaContext ctxt = context.beginTransaction();
try {
TopiaEntity[] entities = TopiaEntityHelper.getEntities(ctxt, ids);
// on detecte tous les types connus pour les entites données
Set> types =
TopiaEntityHelper.detectTypes(contracts, entities);
if (log.isDebugEnabled()) {
log.debug("for type : " + entities.getClass());
for (Class extends TopiaEntity> k : types) {
log.debug(k);
}
}
return types;
} finally {
ctxt.closeContext();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy