/*
* (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id$
*/
package org.nuxeo.ecm.webapp.tree;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.Filter;
import org.nuxeo.ecm.core.api.Sorter;
import org.nuxeo.ecm.core.api.tree.DefaultDocumentTreeFilter;
import org.nuxeo.ecm.core.api.tree.DefaultDocumentTreeSorter;
import org.nuxeo.ecm.core.api.tree.DocumentTreeFilter;
import org.nuxeo.ecm.core.api.tree.DocumentTreeSorter;
import org.nuxeo.runtime.model.ComponentContext;
import org.nuxeo.runtime.model.ComponentInstance;
import org.nuxeo.runtime.model.DefaultComponent;
/**
* Component for tree service, handing registries for trees managing {@link DocumentModel} object.
*
* @author Anahide Tchertchian
*/
// TODO: refactor to use only one registry
public class TreeManagerImpl extends DefaultComponent implements TreeManager {
private static final long serialVersionUID = 1L;
public static final String NAME = TreeManager.class.getName();
public static final String PLUGIN_EXTENSION_POINT = "plugin";
private static final Log log = LogFactory.getLog(TreeManager.class);
protected Map<String, Filter> filters;
protected Map<String, Filter> leafFilters;
protected Map<String, Sorter> sorters;
protected Map<String, String> pageProviderNames;
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isAssignableFrom(TreeManager.class)) {
return (T) this;
}
return null;
}
@Override
public void activate(ComponentContext context) {
super.activate(context);
filters = new HashMap<String, Filter>();
leafFilters = new HashMap<String, Filter>();
sorters = new HashMap<String, Sorter>();
pageProviderNames = new HashMap<String, String>();
}
@Override
public void deactivate(ComponentContext context) {
filters = null;
leafFilters = null;
sorters = null;
pageProviderNames = null;
super.deactivate(context);
}
@Override
public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
if (PLUGIN_EXTENSION_POINT.equals(extensionPoint)) {
TreeManagerPluginDescriptor plugin = (TreeManagerPluginDescriptor) contribution;
String name = plugin.getName();
// filter
if (filters.containsKey(name)) {
// FIXME handle merge?
log.info("Overriding filter for plugin " + name);
filters.remove(name);
}
log.info("Registering filter for plugin " + name);
filters.put(name, buildFilter(plugin));
// leaf filter
if (leafFilters.containsKey(name)) {
// FIXME handle merge?
log.info("Overriding leaf filter for plugin " + name);
leafFilters.remove(name);
}
log.info("Registering leaf filter for plugin " + name);
leafFilters.put(name, buildLeafFilter(plugin));
// sorter
if (sorters.containsKey(name)) {
// FIXME handle merge?
log.info("Overriding sorter for plugin " + name);
sorters.remove(name);
}
log.info("Registering sorter for plugin " + name);
sorters.put(name, buildSorter(plugin));
// page provider
if (pageProviderNames.containsKey(name)) {
// FIXME handle merge?
log.info("Overriding page provider for plugin " + name);
pageProviderNames.remove(name);
}
log.info("Registering page provider for plugin " + name);
pageProviderNames.put(name, plugin.getPageProvider());
}
}
@Override
public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
if (PLUGIN_EXTENSION_POINT.equals(extensionPoint)) {
TreeManagerPluginDescriptor plugin = (TreeManagerPluginDescriptor) contribution;
String name = plugin.getName();
// filter
if (filters.containsKey(name)) {
log.info("Unregistering filter for plugin " + name);
filters.remove(name);
}
// leaf filter
if (leafFilters.containsKey(name)) {
log.info("Unregistering leaf filter for plugin " + name);
leafFilters.remove(name);
}
// sorter
if (sorters.containsKey(name)) {
log.info("Unregistering sorter for plugin " + name);
sorters.remove(name);
}
// page provider
if (pageProviderNames.containsKey(name)) {
log.info("Unregistering page provider for plugin " + name);
pageProviderNames.remove(name);
}
}
}
protected Filter buildFilter(TreeManagerPluginDescriptor plugin) {
Filter filter = null;
List<String> includedFacets = plugin.getIncludedFacets();
List<String> excludedFacets = plugin.getExcludedFacets();
List<String> excludedTypes = plugin.getExcludedTypes();
String filterClass = plugin.getFilterClassName();
if (filterClass == null || "".equals(filterClass)) {
if ((includedFacets == null || includedFacets.isEmpty())
&& (excludedFacets == null || excludedFacets.isEmpty())
&& (excludedTypes == null || excludedTypes.isEmpty())) {
return null;
}
// built-in filter
filter = new DefaultDocumentTreeFilter();
} else {
// custom filter
try {
Object instance = TreeManagerImpl.class.getClassLoader().loadClass(filterClass).newInstance();
if (instance instanceof Filter) {
filter = (Filter) instance;
} else {
log.error(String.format("Class %s should follow %s interface", filterClass, Filter.class.getName()));
}
} catch (ReflectiveOperationException e) {
log.error(e, e);
}
}
// setup config when possible
if (filter instanceof DocumentTreeFilter) {
DocumentTreeFilter treeFilter = (DocumentTreeFilter) filter;
treeFilter.setIncludedFacets(includedFacets);
treeFilter.setExcludedFacets(excludedFacets);
treeFilter.setExcludedTypes(excludedTypes);
}
return filter;
}
protected Filter buildLeafFilter(TreeManagerPluginDescriptor plugin) {
String leafFilterClass = plugin.getLeafFilterClassName();
if (leafFilterClass == null || "".equals(leafFilterClass)) {
return null;
}
try {
Object instance = TreeManagerImpl.class.getClassLoader().loadClass(leafFilterClass).newInstance();
if (instance instanceof Filter) {
return (Filter) instance;
} else {
log.error(String.format("Class %s should follow %s interface", leafFilterClass, Filter.class.getName()));
}
} catch (ReflectiveOperationException e) {
log.error(e, e);
}
return null;
}
protected Sorter buildSorter(TreeManagerPluginDescriptor plugin) {
Sorter sorter = null;
String sortPropertyPath = plugin.getSortPropertyPath();
String sorterClass = plugin.getSorterClassName();
if (sorterClass == null || "".equals(sorterClass)) {
if (sortPropertyPath == null || "".equals(sortPropertyPath)) {
return null;
}
// built-in sorter
sorter = new DefaultDocumentTreeSorter();
} else {
// custom sorter
try {
Object instance = TreeManagerImpl.class.getClassLoader().loadClass(sorterClass).newInstance();
if (instance instanceof Sorter) {
sorter = (Sorter) instance;
} else {
log.error(String.format("Class %s should follow %s interface", sorterClass, Sorter.class.getName()));
}
} catch (ReflectiveOperationException e) {
log.error(e, e);
}
}
// setup config when possible
if (sorter instanceof DocumentTreeSorter) {
DocumentTreeSorter treeSorter = (DocumentTreeSorter) sorter;
treeSorter.setSortPropertyPath(sortPropertyPath);
}
return sorter;
}
public Filter getFilter(String pluginName) {
return filters.get(pluginName);
}
public Filter getLeafFilter(String pluginName) {
return leafFilters.get(pluginName);
}
public Sorter getSorter(String pluginName) {
return sorters.get(pluginName);
}
@Override
public String getPageProviderName(String pluginName) {
return pageProviderNames.get(pluginName);
}
}