001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Antoine Taillefer <ataillefer@nuxeo.com>
016 */
017package org.nuxeo.drive.service.impl;
018
019import java.io.ByteArrayInputStream;
020import java.io.ByteArrayOutputStream;
021import java.io.IOException;
022import java.io.ObjectInputStream;
023import java.io.ObjectOutputStream;
024import java.util.HashSet;
025import java.util.Set;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.ecm.core.api.NuxeoException;
030import org.nuxeo.runtime.model.ContributionFragmentRegistry;
031
032/**
033 * Registry for the {@code activeFileSystemItemFactories} contributions.
034 *
035 * @author Antoine Taillefer
036 * @see FileSystemItemAdapterServiceImpl
037 */
038public class ActiveFileSystemItemFactoryRegistry extends
039        ContributionFragmentRegistry<ActiveFileSystemItemFactoriesDescriptor> {
040
041    private static final Log log = LogFactory.getLog(ActiveFileSystemItemFactoryRegistry.class);
042
043    protected static final String CONTRIBUTION_ID = "activeFileSystemItemFactoriesContrib";
044
045    protected Set<String> activeFactories = new HashSet<String>();
046
047    @Override
048    public String getContributionId(ActiveFileSystemItemFactoriesDescriptor contrib) {
049        return CONTRIBUTION_ID;
050    }
051
052    @Override
053    public void contributionUpdated(String id, ActiveFileSystemItemFactoriesDescriptor contrib,
054            ActiveFileSystemItemFactoriesDescriptor newOrigContrib) {
055        if (log.isTraceEnabled()) {
056            log.trace(String.format("Updating activeFileSystemItemFactories contribution %s.", contrib));
057        }
058        if (contrib.isMerge()) {
059            // Merge active factories
060            for (ActiveFileSystemItemFactoryDescriptor factory : contrib.getFactories()) {
061                if (activeFactories.contains(factory.getName()) && !factory.isEnabled()) {
062                    if (log.isTraceEnabled()) {
063                        log.trace(String.format("Removing factory %s from active factories.", factory.getName()));
064                    }
065                    activeFactories.remove(factory.getName());
066                }
067                if (!activeFactories.contains(factory.getName()) && factory.isEnabled()) {
068                    if (log.isTraceEnabled()) {
069                        log.trace(String.format("Adding factory %s to active factories.", factory.getName()));
070                    }
071                    activeFactories.add(factory.getName());
072                }
073            }
074        } else {
075            // No merge, reset active factories
076            if (log.isTraceEnabled()) {
077                log.trace(String.format("Clearing active factories as contribution %s doesn't merge.", contrib));
078            }
079            activeFactories.clear();
080            for (ActiveFileSystemItemFactoryDescriptor factory : contrib.getFactories()) {
081                if (factory.isEnabled()) {
082                    if (log.isTraceEnabled()) {
083                        log.trace(String.format("Adding factory %s to active factories.", factory.getName()));
084                    }
085                    activeFactories.add(factory.getName());
086                }
087            }
088        }
089    }
090
091    @Override
092    public void contributionRemoved(String id, ActiveFileSystemItemFactoriesDescriptor origContrib) {
093        log.trace("Clearing active factories.");
094        activeFactories.clear();
095    }
096
097    @Override
098    public ActiveFileSystemItemFactoriesDescriptor clone(ActiveFileSystemItemFactoriesDescriptor orig) {
099        if (log.isTraceEnabled()) {
100            log.trace(String.format("Cloning contribution %s.", orig));
101        }
102        try {
103            ByteArrayOutputStream bos = new ByteArrayOutputStream();
104            ObjectOutputStream oos = new ObjectOutputStream(bos);
105            oos.writeObject(orig);
106            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
107            ObjectInputStream ois = new ObjectInputStream(bis);
108            return (ActiveFileSystemItemFactoriesDescriptor) ois.readObject();
109        } catch (IOException | ClassNotFoundException e) {
110            throw new NuxeoException(String.format("Cannot clone contribution %s.", orig), e);
111        }
112    }
113
114    @Override
115    public void merge(ActiveFileSystemItemFactoriesDescriptor src, ActiveFileSystemItemFactoriesDescriptor dst) {
116        if (log.isTraceEnabled()) {
117            log.trace(String.format("Merging contribution %s to contribution %s.", src, dst));
118        }
119        // Merge
120        if (src.isMerge() != dst.isMerge()) {
121            dst.setMerge(src.isMerge());
122        }
123        // Factories
124        for (ActiveFileSystemItemFactoryDescriptor factory : src.getFactories()) {
125            int indexOfFactory = dst.getFactories().indexOf(factory);
126            if (indexOfFactory > -1) {
127                dst.getFactories().get(indexOfFactory).setEnabled(factory.isEnabled());
128            } else {
129                dst.getFactories().add(factory);
130            }
131        }
132    }
133}