All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.topia.replication.TopiaReplicationModelBuilder Maven / Gradle / Ivy

There is a newer version: 4.0
Show newest version
/*
 * #%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 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 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 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 k : types) { log.debug(k); } } return types; } finally { ctxt.closeContext(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy