001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010:
011: package org.mmbase.bridge.implementation;
012:
013: import java.util.*;
014: import java.lang.reflect.*;
015: import javax.servlet.*;
016: import javax.servlet.http.*;
017:
018: import org.mmbase.bridge.*;
019: import org.mmbase.module.ProcessorInterface;
020: import org.mmbase.module.core.MMObjectNode;
021: import org.mmbase.util.LocalizedString;
022: import org.mmbase.util.PageInfo;
023: import org.mmbase.util.functions.*;
024: import org.mmbase.util.logging.*;
025:
026: /**
027: * ModuleHandler
028: * Creates a framework for calling modules.
029: * Supports calls to the methods supported by the MMBase ProcessorModules.
030: *
031: * @author Pierre van Rooden
032: * @author Rob Vermeulen
033: * @version $Id: ModuleHandler.java,v 1.37 2007/08/02 10:06:12 michiel Exp $
034: */
035: public class ModuleHandler implements Module, InvocationHandler {
036: private static final Logger log = Logging
037: .getLoggerInstance(ModuleHandler.class);
038:
039: // link to cloud context
040: private CloudContext cloudContext = null;
041: private org.mmbase.module.Module mmbaseModule;
042:
043: private ModuleHandler(org.mmbase.module.Module mod,
044: CloudContext cloudContext) {
045: mmbaseModule = mod;
046: this .cloudContext = cloudContext;
047: }
048:
049: public synchronized static Module getModule(
050: org.mmbase.module.Module mod, CloudContext cloudcontext) {
051: Class[] objClasses = mod.getClass().getInterfaces();
052: // check for allowable interface class
053: // Package bridge = Package.getPackage("org.mmbase.bridge");
054: Class otherintf = null;
055: for (Class element : objClasses) {
056: if (element.getName().startsWith("org.mmbase.bridge")) {
057: otherintf = element;
058: }
059: }
060: Class[] useintf;
061: if (otherintf != null) {
062: log.debug("alternateintf =" + otherintf.getName());
063: useintf = new Class[] { Module.class, otherintf };
064: } else {
065: useintf = new Class[] { Module.class };
066: }
067: log.debug("creating proxy for : " + mod.getName() + " = "
068: + useintf);
069:
070: return (Module) Proxy.newProxyInstance(Module.class
071: .getClassLoader(), useintf, new ModuleHandler(mod,
072: cloudcontext));
073: //return new ModuleHandler(mod,cloudcontext);
074: }
075:
076: public Object invoke(Object proxy, Method method, Object[] args)
077: throws Throwable {
078: if (method.getDeclaringClass().equals(Module.class)) {
079: return method.invoke(this , args);
080: } else {
081: return method.invoke(mmbaseModule, args);
082: }
083: }
084:
085: public CloudContext getCloudContext() {
086: return cloudContext;
087: }
088:
089: protected Cloud getCloud(Map parameters) {
090: Cloud cloud = null;
091: if (parameters != null) {
092: cloud = (Cloud) parameters.get("CLOUD");
093: }
094: if (cloud == null) {
095: // anonymous access on the cloud....
096: cloud = cloudContext.getCloud("mmbase"); // get cloud object so you can create a node list. doh.
097: }
098: return cloud;
099: }
100:
101: public String getName() {
102: return mmbaseModule.getName();
103: }
104:
105: public String getProperty(String name) {
106: return mmbaseModule.getInitParameter(name);
107: }
108:
109: public Map getProperties() {
110: return new HashMap<String, String>(mmbaseModule
111: .getInitParameters());
112: }
113:
114: public String getDescription() {
115: return mmbaseModule.getDescription();
116: }
117:
118: public String getDescription(Locale locale) {
119: return mmbaseModule.getDescription(locale);
120: }
121:
122: public LocalizedString getLocalizedDescription() {
123: return mmbaseModule.getLocalizedDescription();
124: }
125:
126: protected void setLocalizedDescription(LocalizedString description) {
127: throw new SecurityException("Operation not allowed");
128: }
129:
130: public void setDescription(String desc, Locale locale) {
131: throw new SecurityException("Operation not allowed");
132: }
133:
134: public void setDescription(String desc) {
135: throw new SecurityException("Operation not allowed");
136: }
137:
138: public String getGUIName(Locale locale) {
139: return mmbaseModule.getGUIName(locale);
140: }
141:
142: public String getGUIName() {
143: return mmbaseModule.getGUIName();
144: }
145:
146: public void setGUIName(String g, Locale locale) {
147: throw new SecurityException("Operation not allowed");
148: }
149:
150: public void setGUIName(String g) {
151: throw new SecurityException("Operation not allowed");
152: }
153:
154: public LocalizedString getLocalizedGUIName() {
155: return mmbaseModule.getLocalizedGUIName();
156: }
157:
158: protected void setLocalizedGUIName(LocalizedString value) {
159: throw new SecurityException("Operation not allowed");
160: }
161:
162: public String getInfo(String command) {
163: return getInfo(command, null, null);
164: }
165:
166: public String getInfo(String command, ServletRequest req,
167: ServletResponse resp) {
168: if (mmbaseModule instanceof ProcessorInterface) {
169: return ((ProcessorInterface) mmbaseModule)
170: .replace(
171: new PageInfo((HttpServletRequest) req,
172: (HttpServletResponse) resp,
173: getCloud(null)), command);
174: } else {
175: throw new BridgeException(
176: "getInfo() is not supported by this module.");
177: }
178: }
179:
180: public void process(String command, Object parameter) {
181: process(command, parameter, null, null, null);
182: }
183:
184: public void process(String command, Object parameter,
185: Map auxparameters) {
186: process(command, parameter, auxparameters, null, null);
187: }
188:
189: public void process(String command, Object parameter,
190: Map auxparameters, ServletRequest req, ServletResponse resp) {
191: if (mmbaseModule instanceof ProcessorInterface) {
192: Hashtable<String, Object> cmds = new Hashtable<String, Object>();
193: if (parameter == null) {
194: parameter = "-1";
195: }
196: cmds.put(command, parameter);
197: // weird change. should be fixed soon in Module.process
198: Hashtable<String, Object> partab = null;
199: if (auxparameters != null) {
200: partab = new Hashtable<String, Object>(auxparameters);
201: } else {
202: partab = new Hashtable<String, Object>();
203: }
204: ((ProcessorInterface) mmbaseModule).process(
205: new PageInfo((HttpServletRequest) req,
206: (HttpServletResponse) resp,
207: getCloud(auxparameters)), cmds, partab);
208: if (auxparameters != null)
209: auxparameters.putAll(partab);
210: } else {
211: throw new BridgeException(
212: "process() is not supported by this module.");
213: }
214: }
215:
216: public NodeList getList(String command, Map parameters) {
217: return getList(command, parameters, null, null);
218: }
219:
220: public NodeList getList(String command, Map parameters,
221: ServletRequest req, ServletResponse resp) {
222: if (mmbaseModule instanceof ProcessorInterface) {
223: Cloud cloud = getCloud(parameters);
224: log.info("Found " + cloud + " "
225: + (cloud != null ? "" + cloud.getUser() : ""));
226: try {
227: List<org.mmbase.module.core.MMObjectNode> v = ((ProcessorInterface) mmbaseModule)
228: .getNodeList(new PageInfo(
229: (HttpServletRequest) req,
230: (HttpServletResponse) resp, cloud),
231: command, parameters);
232: log.info("Got list " + v);
233: if (v.size() == 0) {
234: return cloud.createNodeList();
235: } else {
236: MMObjectNode node = v.get(0);
237: if (node instanceof org.mmbase.module.core.VirtualNode) {
238: VirtualNodeManager tempNodeManager = new VirtualNodeManager(
239: (org.mmbase.module.core.VirtualNode) node,
240: cloud);
241: return new BasicNodeList(v, tempNodeManager);
242: } else {
243: return new BasicNodeList(v, cloud
244: .getNodeManager(node.getBuilder()
245: .getTableName()));
246: }
247: }
248: } catch (Exception e) {
249: throw new BridgeException(e.getMessage(), e);
250: }
251: } else {
252: throw new BridgeException(
253: "getList() is not supported by this module.");
254: }
255: }
256:
257: /**
258: * Compares this module to the passed object.
259: * Returns 0 if they are equal, -1 if the object passed is a NodeManager and larger than this manager,
260: * and +1 if the object passed is a NodeManager and smaller than this manager.
261: * A module is 'larger' than another module if its name is larger (alphabetically, case sensitive)
262: * than that of the other module. If names are the same, the modules are compared on cloud context.
263: *
264: * @param o the object to compare it with
265: */
266: public int compareTo(Module m) {
267: int res = getName().compareTo(m.getName());
268: if (res != 0) {
269: return res;
270: } else {
271: int h1 = m.getCloudContext().hashCode();
272: int h2 = cloudContext.hashCode();
273: if (h1 > h2) {
274: return -1;
275: } else if (h1 < h2) {
276: return 1;
277: } else {
278: return 0;
279: }
280: }
281: }
282:
283: /**
284: * Compares two modules, and returns true if they are equal.
285: * @param o the object to compare it with
286: */
287: @Override
288: public boolean equals(Object o) {
289: return (o instanceof Module)
290: && getName().equals(((Module) o).getName())
291: && cloudContext.equals(((Module) o).getCloudContext());
292: };
293:
294: public Collection getFunctions() {
295: return mmbaseModule.getFunctions();
296: }
297:
298: public Function getFunction(String functionName) {
299: Function function = mmbaseModule.getFunction(functionName);
300: if (function == null) {
301: throw new NotFoundException("Function with name "
302: + functionName + " does not exist.");
303: }
304: return function;
305: }
306:
307: public Parameters createParameters(String functionName) {
308: return getFunction(functionName).createParameters();
309: }
310:
311: public FieldValue getFunctionValue(String functionName,
312: List parameters) {
313: return (FieldValue) getFunction(functionName)
314: .getFunctionValueWithList(parameters);
315: }
316:
317: }
|