001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.jaxer.impl;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.directwebremoting.extend.Creator;
024: import org.directwebremoting.impl.DefaultCreatorManager;
025: import org.directwebremoting.util.LocalUtil;
026:
027: /**
028: * This is a modification of {@link DefaultCreatorManager} that attempts to do
029: * a second round of configuration to allow direct access to any classes in the
030: * system using a script name something like: creator/com/example/ClassName
031: * <p><strong>WARNING:</strong> This class fundamentally breaks the DWR promise
032: * of "we won't touch any of your code without your express permission". You
033: * should only configure this class if you fully understand the implications of
034: * doing so.
035: * <p>This class was created to allow remoting between Jaxer and DWR for scripts
036: * marked <code>runat="server"</code>. This should ensure that the exported
037: * classes are not available to the outside world.
038: * @author Joe Walker [joe at getahead dot ltd dot uk]
039: */
040: public class WideOpenCreatorManager extends DefaultCreatorManager {
041: /* (non-Javadoc)
042: * @see org.directwebremoting.CreatorManager#getCreator(java.lang.String)
043: */
044: @Override
045: public Creator getCreator(String scriptName)
046: throws SecurityException {
047: Creator creator = creators.get(scriptName);
048:
049: if (creator == null) {
050: creator = shortNames.get(scriptName);
051: }
052:
053: if (creator == null) {
054: // So there is no creator by the given name. Next we try the more
055: // verbose version where the script name is something like:
056: // creator/com/example/ClassName
057: String[] parts = scriptName.split("/", 2);
058: if (parts.length == 1) {
059: log.warn("Malformed scriptName: " + scriptName);
060: throw new SecurityException("Malformed scriptName");
061: }
062:
063: String className = parts[1];
064: String creatorName = parts[0];
065: try {
066: // This is roughly equivalent to:
067: // addCreator(className, creatorName, { });
068:
069: Class<? extends Creator> clazz = creatorTypes
070: .get(creatorName);
071: if (clazz == null) {
072: log.error("Missing creator: " + creatorName
073: + " (while initializing creator for: "
074: + className + ".js)");
075: throw new SecurityException("Missing creator");
076: }
077:
078: creator = clazz.newInstance();
079:
080: // Nasty! Each creator has a different set of init params. The
081: // 'new' creator needs a class param, but the spring creator
082: // needs a 'bean' param. We only have enough for a single param
083: // in the URL and we don't know what it should be called. So
084: // this code is tied to the new creator. Yeulch
085: Map<String, String> params = new HashMap<String, String>();
086: params.put("class", className);
087:
088: LocalUtil.setParams(creator, params, ignore);
089: creator.setProperties(params);
090: addCreator(scriptName, creator);
091: shortNames.put(creator.getJavascript(), creator);
092:
093: creator = creators.get(scriptName);
094: } catch (Exception ex) {
095: log.warn("Error adding creator: " + scriptName, ex);
096: throw new SecurityException("Error adding creator");
097: }
098: }
099:
100: return creator;
101: }
102:
103: /**
104: * We index creators by short name as well as full name
105: */
106: private Map<String, Creator> shortNames = new HashMap<String, Creator>();
107:
108: /**
109: * The log stream
110: */
111: private static final Log log = LogFactory
112: .getLog(WideOpenCreatorManager.class);
113: }
|