fr.certu.chouette.manager.AbstractNeptuneManager.java Source code

Java tutorial

Introduction

Here is the source code for fr.certu.chouette.manager.AbstractNeptuneManager.java

Source

/**
 * Projet CHOUETTE
 *
 * ce projet est sous license libre
 * voir LICENSE.txt pour plus de details
 *
 */
package fr.certu.chouette.manager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import lombok.Getter;
import lombok.Setter;

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.transaction.annotation.Transactional;

import fr.certu.chouette.common.ChouetteException;
import fr.certu.chouette.core.CoreException;
import fr.certu.chouette.core.CoreExceptionCode;
import fr.certu.chouette.core.CoreRuntimeException;
import fr.certu.chouette.dao.IDaoTemplate;
import fr.certu.chouette.filter.Filter;
import fr.certu.chouette.model.neptune.NeptuneIdentifiedObject;
import fr.certu.chouette.model.user.User;
import fr.certu.chouette.plugin.exchange.FormatDescription;
import fr.certu.chouette.plugin.exchange.IExportPlugin;
import fr.certu.chouette.plugin.exchange.IImportPlugin;
import fr.certu.chouette.plugin.exchange.ParameterValue;
import fr.certu.chouette.plugin.report.ReportHolder;
import fr.certu.chouette.plugin.validation.ICheckPointPlugin;
import fr.certu.chouette.plugin.validation.report.PhaseReportItem;
import fr.certu.chouette.service.geographic.IGeographicService;

/**
 * @author michel
 * 
 * @param <T>
 */
public abstract class AbstractNeptuneManager<T extends NeptuneIdentifiedObject> implements INeptuneManager<T> {
    private static final Logger localLogger = Logger.getLogger(AbstractNeptuneManager.class);
    // data storage access by hibernate
    @Getter
    @Setter
    private IDaoTemplate<T> dao;

    // data storage access by jdbc
    @Getter
    @Setter
    private IDaoTemplate<T> jdbcDao;

    @Getter
    @Setter
    private String objectIdDefaultPrefix;

    private static Random random = new Random(System.currentTimeMillis());

    private Map<String, IImportPlugin<T>> importPluginMap = new HashMap<String, IImportPlugin<T>>();
    private Map<String, IExportPlugin<T>> exportPluginMap = new HashMap<String, IExportPlugin<T>>();
    private Map<String, IExportPlugin<T>> exportDeletionPluginMap = new HashMap<String, IExportPlugin<T>>();
    private List<ICheckPointPlugin<T>> validationPluginList = new ArrayList<ICheckPointPlugin<T>>();

    private static Map<Class<?>, INeptuneManager<?>> managers = new HashMap<Class<?>, INeptuneManager<?>>();

    protected abstract Logger getLogger();

    /**
     * 
     */
    private Class<?> neptuneType;

    @Getter
    private String objectIdKey;

    @Getter
    @Setter
    private IGeographicService geographicService;

    public AbstractNeptuneManager(Class<?> neptuneType, String objectIdKey) {
        managers.put(neptuneType, this);
        this.neptuneType = neptuneType;
        this.objectIdKey = objectIdKey;
    }

    @SuppressWarnings("unchecked")
    public T getNewInstance(User user) throws ChouetteException {
        try {
            return (T) neptuneType.getConstructor(new Class[0]).newInstance(new Object[0]);
        } catch (Exception e) {
            throw new CoreRuntimeException(CoreExceptionCode.FATAL, e);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#setObjectId(fr.certu.chouette
     * .model.user.User, fr.certu.chouette.model.neptune.NeptuneIdentifiedObject,
     * java.lang.String)
     */
    @Override
    public void setObjectId(User user, T bean, String prefix) throws ChouetteException {
        if (bean.getId() == null)
            return;
        String objectId = (prefix == null ? objectIdDefaultPrefix : prefix) + ":" + objectIdKey + ":"
                + bean.getId().toString();
        bean.setObjectId(objectId);
    }

    /**
     * @param neptuneType
     * @return
     */
    public static INeptuneManager<? extends NeptuneIdentifiedObject> getManager(
            Class<? extends NeptuneIdentifiedObject> neptuneType) {
        return managers.get(neptuneType);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#addImportPlugin(fr.certu.chouette
     * .plugin.exchange.IImportPlugin)
     */
    @Override
    public void addImportPlugin(IImportPlugin<T> plugin) {
        importPluginMap.put(plugin.getDescription().getName(), plugin);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#addExportPlugin(fr.certu.chouette
     * .plugin.exchange.IExportPlugin)
     */
    @Override
    public void addExportPlugin(IExportPlugin<T> plugin) {
        exportPluginMap.put(plugin.getDescription().getName(), plugin);
    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.certu.chouette.manager.INeptuneManager#addExportDeletionPlugin(fr.
     * certu .chouette.plugin.exchange.IExportPlugin)
     */
    @Override
    public void addExportDeletionPlugin(IExportPlugin<T> plugin) {
        exportDeletionPluginMap.put(plugin.getDescription().getName(), plugin);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#addValidationPlugin(fr.certu
     * .chouette.plugin.validation.IValidationPlugin)
     */
    @Override
    public void addCheckPointPlugin(ICheckPointPlugin<T> plugin) {
        validationPluginList.add(plugin);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#addNew(fr.certu.chouette.model
     * .user.User, fr.certu.chouette.model.neptune.NeptuneObject)
     */
    @Transactional
    @Override
    public T addNew(User user, T bean) throws ChouetteException {
        save(user, bean, false);
        return bean;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#exists(fr.certu.chouette.model
     * .user.User, fr.certu.chouette.model.neptune.NeptuneObject)
     */
    @Transactional
    @Override
    public boolean exists(User user, T bean) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        // TODO : check user access
        if (bean.getId() != null) {
            return getDao().exists(bean.getId());
        }
        if (bean.getObjectId() != null && !bean.getObjectId().isEmpty()) {
            return getDao().exists(bean.getObjectId());
        }
        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#get(fr.certu.chouette.model.
     * user.User, fr.certu.chouette.filter.Filter,
     * fr.certu.chouette.filter.DetailLevelEnum)
     */
    @Transactional
    @Override
    public T get(User user, Filter filter) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        // TODO : check user access
        if (filter.getType().equals(Filter.Type.EQUALS)) {
            T bean = null;
            if (filter.getAttribute().equals("id")) {
                bean = getDao().get((Long) filter.getFirstValue());
            } else if (filter.getAttribute().equals("objectId")) {
                bean = getDao().getByObjectId((String) filter.getFirstValue());
            } else {
                throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "invalid filter");
            }
            // bean.expand(level);
            return bean;
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#getAll(fr.certu.chouette.model
     * .user.User, fr.certu.chouette.filter.Filter,
     * fr.certu.chouette.filter.DetailLevelEnum)
     */
    @Transactional
    @Override
    public List<T> getAll(User user, Filter filter) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        // TODO : check user access
        List<T> beans = getDao().select(filter);

        return beans;
    }

    @Transactional
    @Override
    public List<T> getAll(User user) throws ChouetteException {
        // TODO check User access
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        return getDao().getAll();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#count(fr.certu.chouette.model
     * .user.User, fr.certu.chouette.filter.Filter)
     */
    @Override
    public long count(User user, Filter clause) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        return getDao().count(clause);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#purge(fr.certu.chouette.model
     * .user.User, boolean)
     */
    @Override
    public int purge(User user) throws ChouetteException {
        if (getJdbcDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        return getJdbcDao().purge();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.NeptuneBeanManager#update(fr.certu.chouette.
     * model.user.User, fr.certu.chouette.model.neptune.NeptuneBean)
     */
    @Transactional
    @Override
    public T update(User user, T bean) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");

        return getDao().update(bean);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.NeptuneBeanManager#isRemovable(fr.certu.chouette
     * .model.user.User, fr.certu.chouette.model.neptune.NeptuneBean)
     */
    @Transactional
    @Override
    public boolean isRemovable(User user, T bean) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.NeptuneBeanManager#remove(fr.certu.chouette.
     * model.user.User, fr.certu.chouette.model.neptune.NeptuneBean)
     */
    @Transactional
    @Override
    public void remove(User user, T bean, boolean propagate) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        getLogger().debug("removing object :" + bean.getObjectId());
        getDao().remove(bean.getId());
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.NeptuneBeanManager#removeAll(fr.certu.chouette
     * .model.user.User, fr.certu.chouette.manager.Filter)
     */
    @Transactional
    @Override
    public void removeAll(User user, List<T> objects, boolean propagate) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        /*
         * for (T t : objects) { remove(user, t, propagate); }
         */
        getDao().removeAll(objects);
    }

    @Transactional
    @Override
    public int removeAll(User user, Filter filter) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        return 0;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#getImportFormats(fr.certu.chouette
     * .model.user.User)
     */
    @Override
    public List<FormatDescription> getImportFormats(User user) throws ChouetteException {
        List<FormatDescription> formats = new ArrayList<FormatDescription>();

        for (IImportPlugin<T> plugin : importPluginMap.values()) {
            formats.add(plugin.getDescription());
        }

        return formats;
    }

    @Override
    public List<T> doImport(User user, String formatDescriptor, List<ParameterValue> parameters,
            ReportHolder importReport, ReportHolder validationReport) throws ChouetteException {
        IImportPlugin<T> plugin = importPluginMap.get(formatDescriptor);
        if (plugin == null)
            throw new CoreException(CoreExceptionCode.NO_PLUGIN_AVAILABLE, "unknown format :" + formatDescriptor);

        return plugin.doImport(parameters, importReport, validationReport);

    }

    @Transactional
    @Override
    public void save(User user, T object, boolean propagate) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");

        String prefix = null;
        if (object.getId() == null) {
            if (object.getObjectId() != null && !object.getObjectId().isEmpty()) {
                if (!object.getObjectId().contains(":")) {
                    prefix = object.getObjectId();
                    object.setObjectId(null);
                }
            }
            if (object.getObjectId() == null || object.getObjectId().isEmpty())
                object.setObjectId("::pending_Id::" + random.nextLong()); // mandatory
            // in
            // database
            getDao().save(object);
        }
        if (object.getObjectId() == null || object.getObjectId().isEmpty()
                || object.getObjectId().startsWith("::pending_Id::"))
            setObjectId(user, object, prefix);
        getLogger().debug("saving object :" + object.getObjectId());
        if (object.getCreationTime() == null)
            object.setCreationTime(new Date());
        if (object.getObjectVersion() <= 0)
            object.setObjectVersion(1);
        getDao().update(object);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#saveAll(fr.certu.chouette.model
     * .user.User, java.util.List)
     */
    // @Override
    // public final void saveAll(User user, List<T> beans,boolean propagate)
    // throws ChouetteException
    // {
    //
    // // if(getJdbcDao() == null)
    // // throw new CoreException(CoreExceptionCode.NO_JDBC_DAO_AVAILABLE,
    // "unavailable resource");
    // //
    // // getJdbcDao().saveOrUpdateAll(beans);
    // }

    @Transactional
    @Override
    public void saveAll(User user, List<T> beans, boolean propagate, boolean fast) throws ChouetteException {
        Date creationTime = new Date();
        for (T object : beans) {
            if (object.getCreationTime() == null)
                object.setCreationTime(creationTime);
        }
        if (fast) {
            if (getJdbcDao() == null)
                throw new CoreException(CoreExceptionCode.NO_JDBC_DAO_AVAILABLE, "unavailable resource");
            if (getDao() == null)
                throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
            // maybe resave fast allready connected object
            // getDao().detach(beans);
            // save
            getJdbcDao().saveOrUpdateAll(beans);
        } else {
            if (getDao() == null)
                throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
            getLogger().debug("saving " + beans.size() + " " + neptuneType.getSimpleName());

            getDao().saveOrUpdateAll(beans);

        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.NeptuneBeanManager#saveOrUpdateAll(fr.certu.
     * chouette.model.user.User, java.util.List)
     */
    @Transactional
    @Override
    public void saveOrUpdateAll(User user, List<T> beans) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        getDao().saveOrUpdateAll(beans);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#getExportFormats(fr.certu.chouette
     * .model.user.User)
     */
    @Override
    public List<FormatDescription> getExportFormats(User user) throws ChouetteException {
        List<FormatDescription> formats = new ArrayList<FormatDescription>();

        for (IExportPlugin<T> plugin : exportPluginMap.values()) {
            formats.add(plugin.getDescription());
        }
        return formats;
    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.certu.chouette.manager.INeptuneManager#doExport(fr.certu.chouette.
     * model .user.User, java.util.List, java.lang.String, java.util.List,
     * fr.certu.chouette.plugin.report.ReportHolder)
     */
    @Override
    public void doExport(User user, List<T> beans, String formatDescriptor, List<ParameterValue> parameters,
            ReportHolder report) throws ChouetteException {
        IExportPlugin<T> plugin = exportPluginMap.get(formatDescriptor);
        if (plugin == null)
            throw new CoreException(CoreExceptionCode.NO_PLUGIN_AVAILABLE, "unknown format :" + formatDescriptor);

        plugin.doExport(beans, parameters, report);

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#doExportFromDatabase(fr.certu
     * .chouette.model.user.User, java.util.List, java.lang.String,
     * java.util.List, fr.certu.chouette.plugin.report.ReportHolder)
     */
    @Override
    public void doExportFromDatabase(User user, List<Long> beanIds, String formatDescriptor,
            List<ParameterValue> parameters, ReportHolder report) throws ChouetteException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");
        IExportPlugin<T> plugin = exportPluginMap.get(formatDescriptor);
        if (plugin == null)
            throw new CoreException(CoreExceptionCode.NO_PLUGIN_AVAILABLE, "unknown format :" + formatDescriptor);
        Filter clause = Filter.getNewInFilter("id", beanIds);
        List<T> beans = getDao().select(clause);
        if (!beans.isEmpty()) {
            plugin.doExport(beans, parameters, report);
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#getDeleteExportFormats(fr.certu
     * .chouette.model.user.User)
     */
    @Override
    public List<FormatDescription> getDeleteExportFormats(User user) throws ChouetteException {
        List<FormatDescription> formats = new ArrayList<FormatDescription>();

        for (IExportPlugin<T> plugin : exportDeletionPluginMap.values()) {
            formats.add(plugin.getDescription());
        }
        return formats;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#doExportDeleted(fr.certu.chouette
     * .model.user.User, java.util.List, java.lang.String, java.util.List,
     * fr.certu.chouette.plugin.report.ReportHolder)
     */
    @Override
    public void doExportDeleted(User user, List<T> beans, String formatDescriptor, List<ParameterValue> parameters,
            ReportHolder report) throws ChouetteException {
        IExportPlugin<T> plugin = exportDeletionPluginMap.get(formatDescriptor);
        if (plugin == null)
            throw new CoreException(CoreExceptionCode.NO_PLUGIN_AVAILABLE, "unknown format :" + formatDescriptor);

        plugin.doExport(beans, parameters, report);

    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.certu.chouette.manager.INeptuneManager#canValidate()
     */
    @Override
    public boolean canValidate() {
        return validationPluginList.size() > 0;

    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.certu.chouette.manager.INeptuneManager#validate(fr.certu.chouette.
     * model .user.User, java.util.List,
     * fr.certu.chouette.plugin.validation.ValidationParameters)
     */
    @Override
    public final void validate(User user, List<T> beans, JSONObject parameters, PhaseReportItem report,
            Map<String, Object> validationContext, Boolean propagate) throws ChouetteException {
        if (validationPluginList.size() == 0)
            throw new CoreException(CoreExceptionCode.NO_VALIDATION_PLUGIN_AVAILABLE, "");

        boolean hasToPropagate = propagate;

        if (validationContext == null)
            validationContext = new HashMap<>();

        for (ICheckPointPlugin<T> plugin : validationPluginList) {
            plugin.check(beans, parameters, report, validationContext);

        }

        if (hasToPropagate) {
            propagateValidation(user, beans, parameters, report, validationContext, hasToPropagate);
        }

        return;
    }

    protected void propagateValidation(User user, List<T> beans, JSONObject parameters, PhaseReportItem report,
            Map<String, Object> validationContext, boolean propagate) throws ChouetteException {
        return;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#getValidationSteps(fr.certu.
     * chouette.model.user.User)
     */
    // @Override
    // public List<ValidationStepDescription> getValidationSteps(User user)
    // throws ChouetteException
    // {
    //
    // return null;
    // }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.certu.chouette.manager.INeptuneManager#validateStep(fr.certu.chouette
     * .model.user.User, java.util.List, java.lang.String,
     * fr.certu.chouette.plugin.validation.ValidationParameters)
     */
    // @Override
    // public ReportItem validateStep(User user, List<T> beans, String
    // stepDescriptor, ValidationParameters parameters)
    // throws ChouetteException
    // {
    //
    // return null;
    // }

    @Override
    public void completeObject(User user, T bean) throws ChouetteException {
    }

    @Transactional
    @Override
    public T getByObjectId(String objectId) throws CoreException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");

        T bean = getDao().getByObjectId(objectId);
        // bean.expand(DetailLevelEnum.ATTRIBUTE);
        return bean;
    }

    @Override
    public T getById(Long id) throws CoreException {
        if (getDao() == null)
            throw new CoreException(CoreExceptionCode.NO_DAO_AVAILABLE, "unavailable resource");

        T bean = getDao().get(id);
        // bean.expand(DetailLevelEnum.ATTRIBUTE);
        return bean;
    }

    /**
     * merge source collection in target one : <br/>
     * add source objects if not already in target
     * 
     * @param <U>
     *           type of source and target entries
     * @param target
     *           collection to fill
     * @param source
     *           objects to add
     */
    protected static <U> void mergeCollection(Collection<U> target, Collection<U> source) {
        if (source == null || source.isEmpty())
            return;
        for (U object : source) {
            if (!target.contains(object)) {
                target.add(object);
            }
        }
    }

    /**
     * add source in target collection if not null, not already in database and
     * not already in target
     * 
     * @param <U>
     *           type of source and collection entries
     * @param target
     *           collection
     * @param source
     *           object to add
     */
    protected static <U extends NeptuneIdentifiedObject> void addIfMissingInCollection(Collection<U> target,
            U source) {
        if (source == null)
            return;
        if (source.getId() != null) {
            localLogger.debug(source.getObjectId() + " not added , already saved as " + source.getId());
            return;
        }
        if (!target.contains(source))
            target.add(source);

    }

    /**
     * build a list of ids from object collection
     * 
     * @param <U>
     *           type of collection entries
     * @param beans
     *           collection
     * @return
     */
    protected static <U extends NeptuneIdentifiedObject> List<Long> getIds(Collection<U> beans) {
        List<Long> ids = new ArrayList<Long>();
        for (U bean : beans) {
            if (bean.getId() != null) {
                if (!ids.contains(bean.getId())) {
                    ids.add(bean.getId());
                }
            }
        }
        return ids;
    }

}