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: package org.mmbase.module;
011:
012: import java.util.*;
013: import java.util.Map.Entry;
014:
015: import javax.servlet.http.*;
016: import org.mmbase.module.core.*;
017: import org.mmbase.bridge.Cloud;
018: import org.mmbase.bridge.implementation.BasicNodeList;
019: import org.mmbase.util.*;
020: import org.mmbase.util.functions.*;
021: import org.mmbase.util.logging.*;
022:
023: /**
024: * The Processor Module extends the basic module to the Processor
025: * interface so it can perform for servscan (pagelets).
026: *
027: * @author Daniel Ockeloen
028: * @todo Should be abstract, deprecated?
029: */
030: public class ProcessorModule extends Module implements
031: ProcessorInterface {
032:
033: protected static final Parameter[] PARAMS_PAGEINFO = new Parameter[] {
034: Parameter.REQUEST, Parameter.RESPONSE, Parameter.CLOUD };
035: protected static final Parameter.Wrapper PARAM_PAGEINFO = new Parameter.Wrapper(
036: PARAMS_PAGEINFO);
037:
038: private static final Logger log = Logging
039: .getLoggerInstance(ProcessorModule.class);
040:
041: public ProcessorModule() {
042: }
043:
044: public ProcessorModule(String name) {
045: super (name);
046: }
047:
048: /**
049: * {@inheritDoc}
050: **/
051: public MMObjectBuilder getListBuilder(String command,
052: Map<String, Object> params) {
053: return new VirtualBuilder(null);
054: }
055:
056: /**
057: * Used by function wrappers.
058: * @since MMBase-1.8
059: */
060: private static PageInfo getPageInfo(Parameters arguments) {
061: PageInfo pageInfo = null;
062: if (arguments.indexOfParameter(Parameter.REQUEST) > -1) {
063: HttpServletRequest req = arguments.get(Parameter.REQUEST);
064: HttpServletResponse res = arguments.get(Parameter.RESPONSE);
065: Cloud cloud = arguments.get(Parameter.CLOUD);
066: pageInfo = new PageInfo(req, res, cloud);
067: }
068: return pageInfo;
069: }
070:
071: /**
072: * Used by function wrappers.
073: * @since MMBase-1.8
074: */
075: private static String getCommand(String functionName,
076: Parameters arguments) {
077: StringBuilder buf = new StringBuilder(functionName);
078: Iterator<Object> i = arguments.iterator();
079: while (i.hasNext()) {
080: Object argument = i.next();
081: if (argument instanceof String && !"".equals(argument)) {
082: buf.append('-').append(argument);
083: }
084: }
085: return buf.toString();
086: }
087:
088: /**
089: * Function implementation around {@link #getNodeList(Object, String, Map)}. See in MMAdmin for an example on how to use.
090: * @since MMBase-1.8
091: */
092: protected class GetNodeListFunction extends
093: AbstractFunction<org.mmbase.bridge.NodeList> {
094: public GetNodeListFunction(String name, Parameter[] params) {
095: super (name, params, ReturnType.NODELIST);
096: }
097:
098: public org.mmbase.bridge.NodeList getFunctionValue(
099: Parameters arguments) {
100: Cloud cloud = arguments.get(Parameter.CLOUD);
101: return new BasicNodeList(getNodeList(
102: getPageInfo(arguments), getCommand(getName(),
103: arguments), arguments.toMap()), cloud);
104: }
105: }
106:
107: /**
108: * Function implementation around {@link #replace(PageInfo, String)}. See in MMAdmin for an example on how to use.
109: * @since MMBase-1.8
110: */
111: protected class ReplaceFunction extends AbstractFunction<String> {
112: public ReplaceFunction(String name, Parameter[] params) {
113: super (name, params, ReturnType.STRING);
114: }
115:
116: public String getFunctionValue(Parameters arguments) {
117: return replace(getPageInfo(arguments), getCommand(
118: getName(), arguments));
119: }
120: }
121:
122: /**
123: * Function implementation around {@link #process(PageInfo, Hashtable, Hashtable)}. See in
124: * MMAdmin for an example on how to use. It does not support multipible commands, so the first
125: * Hashtable always contains precisely one entry. The value of the entry is the value of the
126: * first string parameter or the empty string. All parameters are added to the second Hashtable
127: * parameter ('vars'), and this is also returned (because sometimes also results are put in it).
128: * @since MMBase-1.8
129: */
130: protected class ProcessFunction extends AbstractFunction<Map<?, ?>> {
131: public ProcessFunction(String name, Parameter<Object>[] params) {
132: super (name, params, ReturnType.MAP);
133: }
134:
135: public Map getFunctionValue(Parameters arguments) {
136: Hashtable<String, Object> cmds = new Hashtable<String, Object>();
137: Hashtable<String, Object> vars = new Hashtable<String, Object>();
138: Parameter[] def = arguments.getDefinition();
139: for (Parameter param : def) {
140: Object value = arguments.get(param);
141: if (String.class.isAssignableFrom(param
142: .getTypeAsClass())
143: && cmds.size() == 0) {
144: cmds.put(getName(), value);
145: }
146: vars.put(param.getName(), value);
147: }
148: if (cmds.size() == 0)
149: cmds.put(getName(), "");
150: boolean ok = process(getPageInfo(arguments), cmds, vars);
151: return vars;
152: }
153: }
154:
155: /**
156: * This method is a wrapper around {@link #getList(PageInfo, StringTagger, String)}
157: * @param context The PageInfo object. It beats me why it is Object and not PageInfo. I think it's silly.
158: * @param command The command to execute
159: * @param params Parameters, they will be added to the StringTagger.
160: **/
161: public Vector<MMObjectNode> getNodeList(Object context,
162: String command, Map<String, Object> params) {
163: StringTagger tagger = null;
164: if (params instanceof StringTagger) {
165: tagger = (StringTagger) params;
166: } else {
167: tagger = new StringTagger("");
168: if (params != null) {
169: for (Entry<String, Object> entry : params.entrySet()) {
170: String key = entry.getKey();
171: Object o = entry.getValue();
172: if (o instanceof Vector) {
173: tagger.setValues(key, (Vector) o);
174: } else {
175: tagger.setValue(key, "" + o);
176: }
177: }
178: }
179: }
180: PageInfo sp = null;
181: if (context instanceof PageInfo) {
182: sp = (PageInfo) context;
183: }
184: Vector<String> v = getList(sp, tagger, command);
185: int items = 1;
186: try {
187: items = Integer.parseInt(tagger.Value("ITEMS"));
188: } catch (NumberFormatException e) {
189: }
190: Vector<String> fieldlist = tagger.Values("FIELDS");
191: Vector<MMObjectNode> res = new Vector<MMObjectNode>(v.size()
192: / items);
193: MMObjectBuilder bul = getListBuilder(command, params);
194: for (int i = 0; i < v.size(); i += items) {
195: VirtualNode node = new VirtualNode(bul);
196: for (int j = 0; (j < items) && (j < v.size()); j++) {
197: if ((fieldlist != null) && (j < fieldlist.size())) {
198: node.setValue(fieldlist.get(j), v.get(i + j));
199: } else {
200: node.setValue("item" + (j + 1), v.get(i + j));
201: }
202: }
203: res.add(node);
204: }
205: return res;
206: }
207:
208: /**
209: * @javadoc
210: **/
211: public Vector<String> getList(PageInfo sp, StringTagger params,
212: String command) {
213: throw new UnsupportedOperationException("Module "
214: + this .getClass().getName()
215: + " does not implement LIST");
216: }
217:
218: /**
219: * {@inheritDoc}
220: */
221: public boolean process(PageInfo sp, Hashtable<String, Object> cmds,
222: Hashtable<String, Object> vars) {
223: return false;
224: }
225:
226: /**
227: * {@inheritDoc}
228: **/
229: public String replace(PageInfo sp, String command) {
230: return "This module doesn't implement this processor call";
231: }
232:
233: /**
234: * {@inheritDoc}
235: * who the hell uses this (daniel)
236: **/
237: public String replace(PageInfo sp, StringTagger command) {
238: return "This module doesn't implement this processor call";
239: }
240:
241: /**
242: * {@inheritDoc}
243: */
244: public boolean cacheCheck(PageInfo sp, String cmd) {
245: return false;
246: }
247:
248: /**
249: * What should this do, when is this called?
250: * @deprecated called by nothing
251: * @javadoc
252: */
253:
254: public void reload() {
255: }
256:
257: /**
258: * What should this do, when is this called?
259: * @deprecated called by nothing
260: * @javadoc
261: */
262: public void unload() {
263: }
264:
265: /**
266: * {@inheritDoc}
267: * @scope abstract
268: */
269: public void init() {
270: }
271:
272: /**
273: * {@inheritDoc}
274: * @scope abstract
275: */
276: public void onload() {
277: }
278:
279: }
|