/* * Copyright 2005 Joe Walker * * 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. */ package org.directwebremoting.jaxer.impl; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.directwebremoting.extend.Creator; import org.directwebremoting.impl.DefaultCreatorManager; import org.directwebremoting.util.LocalUtil; /** * This is a modification of {@link DefaultCreatorManager} that attempts to do * a second round of configuration to allow direct access to any classes in the * system using a script name something like: creator/com/example/ClassName * <p><strong>WARNING:</strong> This class fundamentally breaks the DWR promise * of "we won't touch any of your code without your express permission". You * should only configure this class if you fully understand the implications of * doing so. * <p>This class was created to allow remoting between Jaxer and DWR for scripts * marked <code>runat="server"</code>. This should ensure that the exported * classes are not available to the outside world. * @author Joe Walker [joe at getahead dot ltd dot uk] */ public class WideOpenCreatorManager extends DefaultCreatorManager { /* (non-Javadoc) * @see org.directwebremoting.CreatorManager#getCreator(java.lang.String) */ @Override public Creator getCreator(String scriptName, boolean includeHidden) throws SecurityException { Creator creator = creators.get(scriptName); if (creator == null) { creator = shortNames.get(scriptName); } if (creator == null) { // So there is no creator by the given name. Next we try the more // verbose version where the script name is something like: // creator/com/example/ClassName String[] parts = scriptName.split("/", 2); if (parts.length == 1) { log.warn("Malformed scriptName: " + scriptName); throw new SecurityException("Malformed scriptName"); } String className = parts[1]; String creatorName = parts[0]; try { // This is roughly equivalent to: // addCreator(className, creatorName, { }); Class<? extends Creator> clazz = creatorTypes.get(creatorName); if (clazz == null) { log.error("Missing creator: " + creatorName + " (while initializing creator for: " + className + ".js)"); throw new SecurityException("Missing creator"); } creator = clazz.newInstance(); // Nasty! Each creator has a different set of init params. The // 'new' creator needs a class param, but the spring creator // needs a 'bean' param. We only have enough for a single param // in the URL and we don't know what it should be called. So // this code is tied to the new creator. Yeulch Map<String, String> params = new HashMap<String, String>(); params.put("class", className); params.put("scope", "script"); LocalUtil.setParams(creator, params, ignore); creator.setProperties(params); addCreator(scriptName, creator); shortNames.put(creator.getJavascript(), creator); creator = creators.get(scriptName); } catch (Exception ex) { log.warn("Error adding creator: " + scriptName, ex); throw new SecurityException("Error adding creator"); } } if (creator.isHidden() && !includeHidden) { log.warn("Attempt made to get hidden class with name: " + scriptName + " while includeHidden=false"); throw new SecurityException("Missing script name"); } return creator; } /** * We index creators by short name as well as full name */ private Map<String, Creator> shortNames = new HashMap<String, Creator>(); /** * The log stream */ private static final Log log = LogFactory.getLog(WideOpenCreatorManager.class); }