001: /*
002: * @(#)CallAction.java 1.2 04/12/06
003: *
004: * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.xml.action;
010:
011: import pnuts.xml.DigestAction;
012: import java.util.Map;
013: import java.util.HashMap;
014: import java.util.ArrayList;
015:
016: /**
017: * This action does some computation using values popped out of the stack.
018: * A subclass defines a concrete implementation.
019: */
020: public abstract class CallAction extends DigestAction {
021:
022: private String[] parameterNames;
023: private int numberOfParameters;
024:
025: /**
026: * Subclass should override this method.
027: *
028: * @param args the arguments.
029: */
030: protected abstract void call(Object[] args);
031:
032: /**
033: * Constructor
034: */
035: protected CallAction() {
036: this (-1);
037: }
038:
039: /**
040: * Constructor
041: *
042: * @param nargs the number of parameters.
043: */
044: public CallAction(int nargs) {
045: this .numberOfParameters = nargs;
046: }
047:
048: /**
049: * Constructor
050: *
051: * @param parameterNames the names of the parameters.
052: * This parameter defines both the number of parameter and the order of the parameters.
053: */
054: public CallAction(String[] parameterNames) {
055: this .parameterNames = parameterNames;
056: }
057:
058: /**
059: * Sets the parameter names
060: *
061: * @param parameterNames the parameter names
062: */
063: public void setParameterNames(String[] parameterNames) {
064: this .parameterNames = parameterNames;
065: }
066:
067: /**
068: * Gets the parameter names
069: *
070: */
071: public String[] getParameterNames() {
072: return this .parameterNames;
073: }
074:
075: /**
076: * Calls call(Object[]) method with the specified parameter names.
077: * Arguments are poped from the stack and the result is pushed onto the stack.
078: *
079: * @param parameterNames the parameter names
080: */
081: protected void callWithNamedParameters(String[] parameterNames) {
082: Object obj;
083: HashMap map = new HashMap();
084: ArrayList args = new ArrayList();
085: for (int i = 0; i < parameterNames.length; i++) {
086: obj = getStackTopValue();
087: if (obj instanceof Parameter) {
088: Parameter param = (Parameter) obj;
089: map.put(param.name, param.value);
090: pop();
091: } else {
092: throw new IllegalStateException();
093: }
094: }
095: for (int i = 0; i < parameterNames.length; i++) {
096: args.add(map.get(parameterNames[i]));
097: }
098: call(args.toArray());
099: }
100:
101: /**
102: * Calls call(Object[]) method with the fixed number of arguments.
103: * Arguments are poped from the stack and the result is pushed onto the stack.
104: *
105: * @param nargs the number of arguments
106: */
107: protected void callWithFixedNumberOfParameters(int nargs) {
108: Object obj;
109: ArrayList args = new ArrayList();
110: for (int i = 0; i < nargs; i++) {
111: obj = getStackTopValue();
112: if (obj instanceof Parameter) {
113: Parameter param = (Parameter) obj;
114: args.add(param.value);
115: pop();
116: } else {
117: throw new IllegalStateException();
118: }
119: }
120: call(args.toArray());
121: }
122:
123: public void end(String path, String key, String text, Object top)
124: throws Exception {
125: if (parameterNames != null) {
126: callWithNamedParameters(parameterNames);
127: } else if (numberOfParameters >= 0) {
128: callWithFixedNumberOfParameters(numberOfParameters);
129: } else {
130: throw new IllegalStateException(
131: "either paramterNames or numberOfParameters must be set.");
132: }
133: }
134: }
|