001: /*
002: * @(#)ListAction.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.beans.BeanUtil;
012: import pnuts.xml.DigestAction;
013: import java.util.Iterator;
014: import java.util.Stack;
015: import java.util.Map;
016: import java.util.Map.Entry;
017: import java.util.HashMap;
018: import java.util.List;
019: import java.util.ArrayList;
020:
021: /**
022: * This action creates a List object and adds it to the object on the stack top, in a way that
023: * depends on the type of the object.
024: * <ul>
025: * <li>If a List object is on the stack top, the created object is added to the List object.
026: * <li>If a Map object is on the stack top, a map entry of {<em>keyword</em> => the created object}
027: * is added to the Map object.
028: * <li>Otherwise, this action assigns the created object to the Bean
029: * property whose name is the <em>keyword</em>. In this case, the Bean property must be of java.util.List type.
030: * </ul>
031: *
032: * <div>Some elements may be added to the created List object, according to the following rules. </div>
033: * <ul>
034: * <li>If the content of the element is not empty, the content is added to the List object.
035: * <li>If the element has one or more child-elements, the values produced by those elements are added to the List object.
036: * <li>If the element has one or more attributes, a Map object of {attribute's name => the value} is created and added to the List object.
037: * </ul>
038: */
039: public class ListAction extends DigestAction {
040:
041: Stack attributeStack = new Stack();
042:
043: protected Object create(String path, String key, Map attributeMap,
044: Object top) throws Exception {
045: Object v = new ArrayList();
046: if (top instanceof Map) {
047: ((Map) top).put(key, v);
048: } else if (top instanceof List) {
049: ((List) top).add(v);
050: } else {
051: BeanUtil.setProperty(top, key, v);
052: }
053: return v;
054: }
055:
056: public void start(String path, String key, Map attributeMap,
057: Object top) throws Exception {
058: if (!listAlive(path)) {
059: Object v = create(path, key, attributeMap, top);
060: push(path, v);
061: registerListPath(path, v);
062: }
063: attributeStack.push(new HashMap(attributeMap));
064: }
065:
066: public void end(String path, String key, String text, Object top)
067: throws Exception {
068: Map attr = (Map) attributeStack.pop();
069:
070: if (text.length() > 0) {
071: if (top == currentListValue()) {
072: ((List) top).add(text);
073: push(getStackTopPath(), top);
074: }
075: } else {
076: Object value = currentListValue();
077: if (top == value) {
078: if (attr != null) {
079: ((List) top).add(attr);
080: push(getStackTopPath(), top);
081: }
082: } else {
083: while (!getStackTopPath().equals(path)) {
084: pop();
085: }
086: top = getStackTopValue();
087: if (attr != null && top instanceof Map) {
088: Map m = (Map) top;
089: for (Iterator it = attr.entrySet().iterator(); it
090: .hasNext();) {
091: Map.Entry entry = (Map.Entry) it.next();
092: m.put(entry.getKey(), entry.getValue());
093: }
094: }
095: while (getStackTopValue() != value) {
096: pop();
097: }
098: }
099: }
100: }
101: }
|