blob: 5f789f7b3938fa13998b2d8a04a17c146b333b14 [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.scheduling.impl;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
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.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.components.CocoonComponentManager;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.components.cron.ConfigurableCronJob;
import org.apache.cocoon.components.cron.ServiceableCronJob;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.commandline.CommandLineRequest;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.AccessController;
import org.apache.lenya.ac.AccessControllerResolver;
import org.apache.lenya.ac.Identifiable;
import org.apache.lenya.ac.Identity;
import org.apache.lenya.ac.Machine;
import org.apache.lenya.ac.User;
import org.apache.lenya.ac.UserManager;
import org.apache.lenya.cms.usecase.Usecase;
import org.apache.lenya.cms.usecase.UsecaseInvoker;
/**
* Job to schedule usecase execution.
*
* @version $Id$
*/
public class UsecaseCronJob extends ServiceableCronJob implements ConfigurableCronJob,
Contextualizable {
/**
* Initializes the job.
* @param usecase The usecase.
*/
public void setup(Usecase usecase) {
this.usecaseName = usecase.getName();
String[] keys = usecase.getParameterNames();
for (int i = 0; i < keys.length; i++) {
this.parameters.put(keys[i], usecase.getParameter(keys[i]));
}
}
private String usecaseName;
private String sourceUrl;
private String userId;
private String machineIp;
private Map parameters = new HashMap();
protected static final String USECASE_NAME = "usecaseName";
protected static final String SOURCE_URL = "sourceUrl";
protected static final String USER_ID = "userId";
protected static final String MACHINE_IP = "machineIp";
/**
* @return The name of the usecase to execute.
*/
public String getUsecaseName() {
return this.usecaseName;
}
/**
* @return The ID of the user who scheduled the job.
*/
public String getUserId() {
return this.userId;
}
protected String getSourceURL() {
return this.sourceUrl;
}
protected Map getParameters() {
return Collections.unmodifiableMap(this.parameters);
}
/**
* @see org.apache.cocoon.components.cron.CronJob#execute(java.lang.String)
*/
public void execute(String jobname) {
UsecaseInvoker invoker = null;
try {
setupOriginalRequest();
authorizeRequest();
invoker = (UsecaseInvoker) this.manager.lookup(UsecaseInvoker.ROLE);
invoker.invoke(getSourceURL(), getUsecaseName(), getParameters());
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (invoker != null) {
this.manager.release(invoker);
}
}
}
/**
* Creates a new request object based on the information from the original request which
* triggered the usecase.
*/
protected void setupOriginalRequest() {
Environment env = CocoonComponentManager.getCurrentEnvironment();
Request request = ContextHelper.getRequest(this.context);
Map attributes = new HashMap();
for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();) {
String key = (String) e.nextElement();
attributes.put(key, request.getAttribute(key));
}
Map requestParameters = new HashMap();
for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
String key = (String) e.nextElement();
requestParameters.put(key, request.getParameter(key));
}
Map objectModel = ContextHelper.getObjectModel(this.context);
objectModel.put(ObjectModelHelper.REQUEST_OBJECT, new CommandLineRequest(env,
request.getContextPath(),
request.getServletPath(),
getSourceURL(),
attributes,
requestParameters));
}
/**
* Initializes the session with the access control information.
* @throws AccessControlException if an error occurs.
* @throws ServiceException if the access controller resolver could not be created.
*/
protected void authorizeRequest() throws AccessControlException, ServiceException {
ServiceSelector selector = null;
AccessControllerResolver acResolver = null;
AccessController controller = null;
try {
selector = (ServiceSelector) this.manager.lookup(AccessControllerResolver.ROLE
+ "Selector");
acResolver = (AccessControllerResolver) selector.select(AccessControllerResolver.DEFAULT_RESOLVER);
controller = acResolver.resolveAccessController(getSourceURL());
getLogger().debug("Add identity to session");
getLogger().debug("User ID: [" + this.userId + "]");
getLogger().debug("Machine: [" + this.machineIp + "]");
Request request = ContextHelper.getRequest(this.context);
controller.setupIdentity(request);
Session session = request.getSession(false);
Identity identity = (Identity) session.getAttribute(Identity.class.getName());
Identifiable[] identifiables = identity.getIdentifiables();
for (int i = 0; i < identifiables.length; i++) {
identity.removeIdentifiable(identifiables[i]);
}
UserManager userManager = controller.getAccreditableManager().getUserManager();
if (this.userId != null) {
User user = userManager.getUser(this.userId);
if (user == null) {
throw new RuntimeException("User [" + this.userId + "] does not exist!");
}
identity.addIdentifiable(user);
}
if (this.machineIp != null) {
Machine machine = new Machine(this.machineIp);
identity.addIdentifiable(machine);
}
controller.authorize(request);
} finally {
if (selector != null) {
if (acResolver != null) {
if (controller != null) {
acResolver.release(controller);
}
selector.release(acResolver);
}
this.manager.release(selector);
}
}
}
/**
* @see org.apache.cocoon.components.cron.ConfigurableCronJob#setup(org.apache.avalon.framework.parameters.Parameters,
* java.util.Map)
*/
public void setup(Parameters parameters, Map objects) {
this.parameters.putAll(Parameters.toProperties(parameters));
this.usecaseName = (String) objects.get(USECASE_NAME);
this.sourceUrl = (String) objects.get(SOURCE_URL);
this.userId = (String) objects.get(USER_ID);
this.machineIp = (String) objects.get(MACHINE_IP);
}
private Context context;
/**
* @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
*/
public void contextualize(Context context) throws ContextException {
this.context = context;
}
}