001/*
002 * (C) Copyright 2012 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 *     Benoit Delbosc
016 */
017package org.nuxeo.ecm.platform.query.core;
018
019import java.util.HashMap;
020import java.util.Map;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024import org.nuxeo.ecm.platform.query.api.PageProvider;
025import org.nuxeo.ecm.platform.query.api.PageProviderClassReplacerDefinition;
026import org.nuxeo.runtime.model.ContributionFragmentRegistry;
027
028/**
029 * Registry for page provider class replacements.
030 *
031 * @since 6.0
032 */
033public class PageProviderClassReplacerRegistry extends
034        ContributionFragmentRegistry<PageProviderClassReplacerDefinition> {
035
036    private static final Log log = LogFactory.getLog(PageProviderClassReplacerRegistry.class);
037
038    protected Map<String, Class<? extends PageProvider<?>>> replacerMap = new HashMap<>();
039
040    @Override
041    public String getContributionId(PageProviderClassReplacerDefinition contrib) {
042        return contrib.getPageProviderClassName();
043    }
044
045    @Override
046    public void contributionUpdated(String id, PageProviderClassReplacerDefinition desc,
047            PageProviderClassReplacerDefinition newOrigContrib) {
048        String name = desc.getPageProviderClassName();
049        if (name == null) {
050            log.error("Cannot register page provider class replacer without class name");
051            return;
052        }
053        if (!desc.isEnabled()) {
054            return;
055        }
056        log.debug("Registering page provider class replacer using " + name);
057        Class<? extends PageProvider<?>> klass = getPageProviderClass(desc.getPageProviderClassName());
058        for (String providerName : desc.getPageProviderNames()) {
059            replacerMap.put(providerName, klass);
060        }
061
062    }
063
064    @Override
065    public void contributionRemoved(String id, PageProviderClassReplacerDefinition origContrib) {
066        log.debug("Unregistering page provider replacer for class " + id);
067        for (String providerName : origContrib.getPageProviderNames()) {
068            replacerMap.remove(providerName);
069        }
070    }
071
072    @Override
073    public boolean isSupportingMerge() {
074        return false;
075    }
076
077    @Override
078    public PageProviderClassReplacerDefinition clone(PageProviderClassReplacerDefinition orig) {
079        throw new UnsupportedOperationException();
080    }
081
082    @Override
083    public void merge(PageProviderClassReplacerDefinition src, PageProviderClassReplacerDefinition dst) {
084        throw new UnsupportedOperationException();
085    }
086
087    @SuppressWarnings("unchecked")
088    protected Class<? extends PageProvider<?>> getPageProviderClass(final String className) {
089        Class<? extends PageProvider<?>> ret;
090        try {
091            ret = (Class<? extends PageProvider<?>>) Class.forName(className);
092        } catch (ClassNotFoundException e) {
093            throw new IllegalStateException(String.format("Class %s not found", className));
094        }
095        if (!PageProvider.class.isAssignableFrom(ret)) {
096            throw new IllegalStateException(String.format("Class %s does not implement PageProvider interface",
097                    className));
098        }
099        return ret;
100    }
101
102    // API
103    public Class<? extends PageProvider<?>> getClassForPageProvider(String name) {
104        return replacerMap.get(name);
105    }
106
107    public void dumpReplacerMap() {
108        if (replacerMap.isEmpty()) {
109            log.info("No page provider has been superseded");
110            return;
111        }
112        StringBuilder out = new StringBuilder();
113        out.append("List of page provider names that are superseded: \n");
114        for (String name : replacerMap.keySet()) {
115            out.append(String.format("  - %s: %s\n", name, replacerMap.get(name).getName()));
116        }
117        log.info(out.toString());
118    }
119}