001: package org.apache.dvsl;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.util.List;
023: import java.util.ArrayList;
024: import java.util.Map;
025: import java.util.HashMap;
026: import java.util.Stack;
027:
028: import org.apache.velocity.context.Context;
029: import org.apache.velocity.VelocityContext;
030:
031: /**
032: * <p>
033: * Context implementation that is the outer context
034: * during the transformation. Holds the node stack
035: * and also protects the 'special' context elements
036: * like 'node'
037: * </p>
038: * <p>
039: * There are special elements like 'node', which is
040: * readonly and corresponds to the current node, and
041: * 'attrib', which corresponds to a map of attributes
042: * for the current node.
043: * </p>
044: *
045: * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
046: */
047: class DVSLNodeContext extends VelocityContext {
048:
049: /**
050: * Magic context entity that corresponds
051: * to the current node
052: */
053: private final static String NODE = "node";
054:
055: /**
056: * Magic context entity that corresponds to
057: * a Map of attributes for the current node
058: */
059: private final static String ATTRIB = "attrib";
060:
061: /**
062: * Used to hold the nodes as we get invoked from
063: * within the document for applyTemplates() duties
064: */
065: private Stack nodeStack = new Stack();
066:
067: protected Map ctx = new HashMap();
068:
069: public DVSLNodeContext(Context context) {
070: super (context);
071: }
072:
073: private DVSLNodeContext() {
074: }
075:
076: /**
077: * retrieves value for key from internal
078: * storage
079: *
080: * @param key name of value to get
081: * @return value as object
082: */
083: public Object internalGet(String key) {
084: Object o = null;
085:
086: /*
087: * special token : NODE
088: *
089: * returns current node
090: */
091:
092: if (key.equals(NODE)) {
093: return peekNode();
094: }
095:
096: /*
097: * ATTRIB - returns attribute map
098: */
099:
100: if (key.equals(ATTRIB)) {
101: DVSLNode n = peekNode();
102:
103: return n.getAttribMap();
104: }
105:
106: /*
107: * start with local storage
108: */
109:
110: return ctx.get(key);
111: }
112:
113: /**
114: * stores the value for key to internal
115: * storage
116: *
117: * @param key name of value to store
118: * @param value value to store
119: * @return previous value of key as Object
120: */
121: public Object internalPut(String key, Object value) {
122: /*
123: * protect both NODE and ATTRIB for now. We
124: * might want to let people set ATTRIB, but
125: * I suspect not
126: */
127:
128: if (key.equals(NODE))
129: return null;
130:
131: if (key.equals(ATTRIB))
132: return null;
133:
134: return ctx.put(key, value);
135: }
136:
137: /**
138: * determines if there is a value for the
139: * given key
140: *
141: * @param key name of value to check
142: * @return true if non-null value in store
143: */
144: public boolean internalContainsKey(Object key) {
145: return ctx.containsKey(key);
146: }
147:
148: /**
149: * returns array of keys
150: *
151: * $$$ GMJ todo
152: *
153: * @return keys as []
154: */
155: public Object[] internalGetKeys() {
156: return null;
157: }
158:
159: /**
160: * remove a key/value pair from the
161: * internal storage
162: *
163: * @param key name of value to remove
164: * @return value removed
165: */
166: public Object internalRemove(Object key) {
167: return ctx.remove(key);
168: }
169:
170: /* === routines to manage current node stack === */
171:
172: DVSLNode pushNode(DVSLNode n) {
173: nodeStack.push(n);
174: return n;
175: }
176:
177: DVSLNode peekNode() {
178: return (DVSLNode) nodeStack.peek();
179: }
180:
181: DVSLNode popNode() {
182: return (DVSLNode) nodeStack.pop();
183: }
184:
185: void clearNode() {
186: nodeStack.clear();
187: return;
188: }
189:
190: }
|