UIExtensionManagerImpl.java
/*
* Copyright (C) 2003-2009 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.webui.ext.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.core.UIContainer;
import org.exoplatform.webui.ext.UIExtension;
import org.exoplatform.webui.ext.UIExtensionManager;
import org.exoplatform.webui.ext.UIExtensionPlugin;
import org.exoplatform.webui.ext.filter.UIExtensionFilter;
import org.exoplatform.webui.ext.filter.UIExtensionFilterType;
/**
* The default implementation of an extension manager
*
* Created by The eXo Platform SAS
* Author : eXoPlatform
* nicolas.filotto@exoplatform.com
* May 04, 2009
*/
public class UIExtensionManagerImpl implements UIExtensionManager {
/**
* Logger.
*/
private static final Log LOG = ExoLogger.getLogger(UIExtensionManagerImpl.class);
/**
* All the registered extensions
*/
private final ConcurrentMap<String, Map<String, UIExtension>> extensions =
new ConcurrentHashMap<String, Map<String, UIExtension>>();
/**
* {@inheritDoc}
*/
public boolean accept(String extensionType, String extensionName, Map<String, Object> context) {
UIExtension extension = getUIExtension(extensionType, extensionName);
if (extension == null) {
LOG.warn("The extension type = " + extensionType + ", name = " + extensionName + " cannot be found");
} else {
return accept(extension, context, false);
}
return false;
}
/**
* {@inheritDoc}
*/
public UIComponent addUIExtension(String extensionType,
String extensionName,
Map<String, Object> context,
UIContainer parent) throws Exception {
UIExtension extension = getUIExtension(extensionType, extensionName);
if (extension == null) {
LOG.warn("The extension type = " + extensionType + ", name = " + extensionName + " cannot be found");
} else {
String id = createComponentId(parent, extensionName);
// If the component has already been added, first remove it
parent.removeChildById(id);
if (accept(extension, context, true)) {
// The filters passed successfully
UIComponent component = parent.createUIComponent(extension.getComponent(), null, id);
parent.addChild(component);
return component;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public UIComponent addUIExtension(UIExtension extension, Map<String, Object> context, UIContainer parent) throws Exception {
return addUIExtension(extension.getType(), extension.getName(), context, parent);
}
/**
* {@inheritDoc}
*/
public void registerUIExtensionPlugin(UIExtensionPlugin extensionPlugin) {
List<UIExtension> extensions = extensionPlugin.getExtensions();
if (extensions != null) {
for (UIExtension extension : extensions) {
registerUIExtension(extension);
}
}
}
/**
* {@inheritDoc}
*/
public void registerUIExtension(UIExtension extension) {
Map<String, UIExtension> extensions = getUIExtensions(extension.getType(), true);
extensions.put(extension.getName(), extension);
}
/**
* {@inheritDoc}
*/
public List<UIExtension> getUIExtensions(String type) {
Map<String, UIExtension> extensions = getUIExtensions(type, false);
if (extensions != null) {
List<UIExtension> lExtensions = new ArrayList<UIExtension>(extensions.values());
Collections.sort(lExtensions);
return lExtensions;
}
return null;
}
/**
* {@inheritDoc}
*/
public UIExtension getUIExtension(String type, String name) {
Map<String, UIExtension> extensions = getUIExtensions(type, false);
if (extensions != null) {
return extensions.get(name);
}
return null;
}
private Map<String, UIExtension> getUIExtensions(String extensionType, boolean create) {
Map<String, UIExtension> mExtensions = extensions.get(extensionType);
if (mExtensions == null && create) {
extensions.putIfAbsent(extensionType, new ConcurrentHashMap<String, UIExtension>());
mExtensions = extensions.get(extensionType);
}
return mExtensions;
}
protected boolean accept(UIExtension extension, Map<String, Object> context, boolean checkOnly) {
return accept(extension.getExtendedFilters(), context, checkOnly) &&
accept(extension.getComponentFilters(), context, checkOnly) &&
extension.isEnable();
}
protected String createComponentId(UIContainer parent, String extensionName) {
StringBuilder sb = new StringBuilder(128);
sb.append(parent.getId());
sb.append('_');
sb.append(extensionName);
sb.append('_');
return sb.toString();
}
/**
* Checks if the given filters accept the given context
* @param checkOnly if <code>true</code> only the mandatory filters will be tested, otherwise
* all the filters will be tested
* @return <code>true</code> if all filters could pass otherwise it returns <code>false</code>
*/
private boolean accept(List<UIExtensionFilter> filters, Map<String, Object> context, boolean checkOnly) {
boolean result = true;
if (filters != null) {
for (int i = 0, length = filters.size(); i < length; i++) {
UIExtensionFilter filter = filters.get(i);
UIExtensionFilterType type = filter.getType();
if (checkOnly && (type == null || !type.showExtensionOnlyIfOK())) {
// only test the filter that are mandatory
continue;
}
try {
if (!filter.accept(context)) {
onDeny(checkOnly, filter, context);
if (type != null) {
if (type.checkOtherFiltersOnlyIfOK()) {
return false;
} else if (type.acceptOnlyIfOK()) {
result = false;
}
}
}
} catch (Exception e) { //filter.accept() throws Exception()
LOG.error("An exeception occurs while applying the filter", e);
onDeny(checkOnly, filter, context);
if (type != null) {
if (type.checkOtherFiltersOnlyIfOK()) {
return false;
} else if (type.acceptOnlyIfOK()) {
result = false;
}
}
}
}
}
return result;
}
private void onDeny(boolean checkOnly, UIExtensionFilter filter, Map<String, Object> context) {
if (!checkOnly) {
try {
filter.onDeny(context);
} catch (Exception e) { //we want to catch all exceptions here
LOG.error("An execption occurs while calling the method onDeny of the filter", e);
}
}
}
}