001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Benoit Delbosc
018 */
019package org.nuxeo.ecm.platform.query.core;
020
021import java.util.HashMap;
022import java.util.Map;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.ecm.platform.query.api.PageProvider;
027import org.nuxeo.ecm.platform.query.api.PageProviderClassReplacerDefinition;
028import org.nuxeo.runtime.model.ContributionFragmentRegistry;
029
030/**
031 * Registry for page provider class replacements.
032 *
033 * @since 6.0
034 */
035public class PageProviderClassReplacerRegistry extends
036        ContributionFragmentRegistry<PageProviderClassReplacerDefinition> {
037
038    private static final Log log = LogFactory.getLog(PageProviderClassReplacerRegistry.class);
039
040    protected Map<String, Class<? extends PageProvider<?>>> replacerMap = new HashMap<>();
041
042    @Override
043    public String getContributionId(PageProviderClassReplacerDefinition contrib) {
044        return contrib.getPageProviderClassName();
045    }
046
047    @Override
048    public void contributionUpdated(String id, PageProviderClassReplacerDefinition desc,
049            PageProviderClassReplacerDefinition newOrigContrib) {
050        String name = desc.getPageProviderClassName();
051        if (name == null) {
052            log.error("Cannot register page provider class replacer without class name");
053            return;
054        }
055        if (!desc.isEnabled()) {
056            return;
057        }
058        log.debug("Registering page provider class replacer using " + name);
059        Class<? extends PageProvider<?>> klass = getPageProviderClass(desc.getPageProviderClassName());
060        for (String providerName : desc.getPageProviderNames()) {
061            replacerMap.put(providerName, klass);
062        }
063
064    }
065
066    @Override
067    public void contributionRemoved(String id, PageProviderClassReplacerDefinition origContrib) {
068        log.debug("Unregistering page provider replacer for class " + id);
069        for (String providerName : origContrib.getPageProviderNames()) {
070            replacerMap.remove(providerName);
071        }
072    }
073
074    @Override
075    public boolean isSupportingMerge() {
076        return false;
077    }
078
079    @Override
080    public PageProviderClassReplacerDefinition clone(PageProviderClassReplacerDefinition orig) {
081        throw new UnsupportedOperationException();
082    }
083
084    @Override
085    public void merge(PageProviderClassReplacerDefinition src, PageProviderClassReplacerDefinition dst) {
086        throw new UnsupportedOperationException();
087    }
088
089    @SuppressWarnings("unchecked")
090    protected Class<? extends PageProvider<?>> getPageProviderClass(final String className) {
091        Class<? extends PageProvider<?>> ret;
092        try {
093            ret = (Class<? extends PageProvider<?>>) Class.forName(className);
094        } catch (ClassNotFoundException e) {
095            throw new IllegalStateException(String.format("Class %s not found", className));
096        }
097        if (!PageProvider.class.isAssignableFrom(ret)) {
098            throw new IllegalStateException(String.format("Class %s does not implement PageProvider interface",
099                    className));
100        }
101        return ret;
102    }
103
104    // API
105    public Class<? extends PageProvider<?>> getClassForPageProvider(String name) {
106        return replacerMap.get(name);
107    }
108
109    public void dumpReplacerMap() {
110        if (replacerMap.isEmpty()) {
111            log.info("No page provider has been superseded");
112            return;
113        }
114        StringBuilder out = new StringBuilder();
115        out.append("List of page provider names that are superseded: \n");
116        for (String name : replacerMap.keySet()) {
117            out.append(String.format("  - %s: %s\n", name, replacerMap.get(name).getName()));
118        }
119        log.info(out.toString());
120    }
121}