blob: 2006c1f9efc2083cd16ebe009925e22ebfd8b336 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
*/
package org.apache.lenya.cms.usecase.gui.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.AccessController;
import org.apache.lenya.ac.AccessControllerResolver;
import org.apache.lenya.ac.Authorizer;
import org.apache.lenya.ac.Role;
import org.apache.lenya.cms.ac.PolicyUtil;
import org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer;
import org.apache.lenya.cms.cocoon.components.context.ContextUtility;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentUtil;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationUtil;
import org.apache.lenya.cms.usecase.Usecase;
import org.apache.lenya.cms.usecase.UsecaseMessage;
import org.apache.lenya.cms.usecase.UsecaseResolver;
import org.apache.lenya.cms.usecase.gui.GUIManager;
import org.apache.lenya.cms.usecase.gui.Tab;
import org.apache.lenya.util.ServletHelper;
/**
* GUI manager implementation.
*/
public class GUIManagerImpl extends AbstractLogEnabled implements GUIManager, Configurable,
Serviceable, Contextualizable {
protected static final String ELEMENT_PARAMETER = "parameter";
protected static final String ELEMENT_TAB_GROUP = "tab-group";
protected static final String ELEMENT_TAB = "tab";
protected static final String ATTRIBUTE_NAME = "name";
protected static final String ATTRIBUTE_VALUE = "value";
protected static final String ATTRIBUTE_LABEL = "label";
protected static final String ATTRIBUTE_USECASE = "usecase";
private Map name2group = new HashMap();
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
public void configure(Configuration config) throws ConfigurationException {
Configuration[] tabGroupConfigs = config.getChildren(ELEMENT_TAB_GROUP);
for (int i = 0; i < tabGroupConfigs.length; i++) {
String groupName = tabGroupConfigs[i].getAttribute(ATTRIBUTE_NAME);
List group = new ArrayList();
Configuration[] tabConfigs = tabGroupConfigs[i].getChildren(ELEMENT_TAB);
for (int j = 0; j < tabConfigs.length; j++) {
String name = tabConfigs[j].getAttribute(ATTRIBUTE_NAME);
String label = tabConfigs[j].getAttribute(ATTRIBUTE_LABEL);
String usecase = tabConfigs[j].getAttribute(ATTRIBUTE_USECASE);
TabImpl tab = new TabImpl(groupName, name, usecase, label);
group.add(tab);
Configuration[] paramConfigs = tabConfigs[j].getChildren(ELEMENT_PARAMETER);
for (int p = 0; p < paramConfigs.length; p++) {
String paramName = paramConfigs[p].getAttribute(ATTRIBUTE_NAME);
String paramValue = paramConfigs[p].getAttribute(ATTRIBUTE_VALUE);
tab.setParameter(paramName, paramValue);
}
}
name2group.put(groupName, group.toArray(new Tab[group.size()]));
}
}
/**
* @see org.apache.lenya.cms.usecase.gui.GUIManager#getActiveTabs(java.lang.String)
*/
public Tab[] getActiveTabs(String group) {
Tab[] tabs = getTabs(group);
List activeTabs = new ArrayList();
for (int i = 0; i < tabs.length; i++) {
if (getErrorMessages(tabs[i]).length == 0) {
activeTabs.add(tabs[i]);
}
}
return (Tab[]) activeTabs.toArray(new Tab[activeTabs.size()]);
}
protected Tab[] getTabs(String group) {
Tab[] tabs = (Tab[]) name2group.get(group);
return tabs;
}
/**
* @see org.apache.lenya.cms.usecase.gui.GUIManager#getTab(java.lang.String, java.lang.String)
*/
public Tab getTab(String group, String name) {
Tab[] tabs = getTabs(group);
for (int i = 0; i < tabs.length; i++) {
if (name.equals(tabs[i].getName())) {
return tabs[i];
}
}
throw new IllegalArgumentException("No tab [" + name + "] in group [" + group + "]");
}
/**
* Checks if a tab's usecase can be executed.
* @param tab The tab.
* @return An array of error messages.
*/
protected UsecaseMessage[] getErrorMessages(Tab tab) {
UsecaseMessage[] messages;
ServiceSelector selector = null;
AccessControllerResolver acResolver = null;
AccessController accessController = null;
UsecaseResolver usecaseResolver = null;
UsecaseAuthorizer authorizer = null;
try {
selector = (ServiceSelector) this.manager.lookup(AccessControllerResolver.ROLE
+ "Selector");
acResolver = (AccessControllerResolver) selector.select(AccessControllerResolver.DEFAULT_RESOLVER);
accessController = acResolver.resolveAccessController(this.webappUrl);
Authorizer[] authorizers = accessController.getAuthorizers();
for (int i = 0; i < authorizers.length; i++) {
if (authorizers[i] instanceof UsecaseAuthorizer) {
authorizer = (UsecaseAuthorizer) authorizers[i];
}
}
usecaseResolver = (UsecaseResolver) this.manager.lookup(UsecaseResolver.ROLE);
// filter item if usecase not allowed
if (tab.getUsecase() != null) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Found usecase [" + tab.getUsecase() + "]");
}
DocumentFactory factory;
ContextUtility util = null;
try {
util = (ContextUtility) this.manager.lookup(ContextUtility.ROLE);
Request request = util.getRequest();
factory = DocumentUtil.getDocumentFactory(this.manager, request);
} finally {
if (util != null) {
this.manager.release(util);
}
}
Publication pub = PublicationUtil.getPublicationFromUrl(this.manager,
factory,
this.webappUrl);
if (!authorizer.authorizeUsecase(tab.getUsecase(), this.roles, pub)) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Usecase not authorized");
}
messages = new UsecaseMessage[1];
messages[0] = new UsecaseMessage("Access denied");
}
}
if (usecaseResolver.isRegistered(this.webappUrl, tab.getUsecase())) {
Usecase usecase = null;
try {
usecase = usecaseResolver.resolve(this.webappUrl, tab.getUsecase());
usecase.setSourceURL(this.webappUrl);
usecase.setName(tab.getUsecase());
String[] keys = tab.getParameterNames();
for (int i = 0; i < keys.length; i++) {
usecase.setParameter(keys[i], tab.getParameter(keys[i]));
}
usecase.checkPreconditions();
if (usecase.hasErrors()) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Usecase preconditions not complied");
}
List msgs = usecase.getErrorMessages();
messages = (UsecaseMessage[]) msgs.toArray(new UsecaseMessage[msgs.size()]);
} else {
messages = new UsecaseMessage[0];
}
} finally {
if (usecase != null) {
usecaseResolver.release(usecase);
}
}
} else {
messages = new UsecaseMessage[1];
messages[0] = new UsecaseMessage("Usecase [" + tab.getUsecase()
+ "] is not registered!", null);
}
} catch (final Exception e) {
throw new RuntimeException(e);
} finally {
if (usecaseResolver != null) {
this.manager.release(usecaseResolver);
}
if (selector != null) {
if (acResolver != null) {
if (accessController != null) {
acResolver.release(accessController);
}
selector.release(acResolver);
}
this.manager.release(selector);
}
}
return messages;
}
private ServiceManager manager;
/**
* @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
*/
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
}
private String webappUrl;
private Role[] roles;
/**
* @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
*/
public void contextualize(Context context) throws ContextException {
Request request = ContextHelper.getRequest(context);
try {
this.roles = PolicyUtil.getRoles(request);
} catch (AccessControlException e) {
throw new ContextException("Obtaining roles failed: ", e);
}
this.webappUrl = ServletHelper.getWebappURI(request);
}
}