1 /***
2 * IndexerOperator.java
3 *
4 * $Author: mballesteros $
5 * $Date: 2003/11/28 19:18:04 $
6 * $Revision: 1.1 $
7 */
8 package net.sf.jec;
9
10 import java.util.List;
11 import java.util.Map;
12
13 import net.sf.jec.util.XMLHelper;
14
15 import org.w3c.dom.Element;
16 import org.w3c.dom.Node;
17 import org.w3c.dom.NodeList;
18
19
20 /*** IndexerOperator operates on indexed objects as List, NodeList or Map.
21 * Accepts an operator as the index provider. If the operator's context is a
22 * List, the index operator must be convertible to 'int'. For Map contexts,
23 * the index operator can produce any Object as index.
24 * @author mballesteros
25 */
26 public class IndexerOperator extends InvertibleOperator {
27
28 private Operator indexOperator;
29 private boolean throwExceptions;
30
31 /*** This operator requires object conversion and an operator chain that
32 * resolves the selected index.
33 */
34 public IndexerOperator(Operator indexOperator, Operator nestedOp,
35 boolean throwExceptions) {
36 super(nestedOp);
37 this.indexOperator = indexOperator;
38 this.throwExceptions = throwExceptions;
39 }
40
41 /*** Returns a function representation String for this operator
42 */
43 public String toFunctionString() {
44 return "Indexer(" + indexOperator
45 + (nestedOp == null? "" : ", "+nestedOp) + ")";
46 }
47
48 /*** Returns an expression String representation for this operator
49 */
50 public String toExpressionString() {
51 return (nestedOp == null? "" : nestedOp.toString()) + "[" + indexOperator + "]";
52 }
53
54
55 /*** Returns the associated value to the given context and root context
56 * @param rootCtx The root context, needed for operators that require
57 * expression evaluation from root point. Example: Indexer operators
58 * @param ctx The current context where the operator will work over
59 */
60 protected Object directMap(Object rootCtx, Object ctx) throws EvaluationException {
61 try {
62 if (ctx instanceof List) {
63 int index = 0;
64 try {
65 index = ObjectConverter.toInt(indexOperator.apply(rootCtx, rootCtx));
66 return ((List)ctx).get(index);
67 } catch (IndexOutOfBoundsException ioobe) {
68 if (throwExceptions) throw new EvaluationException("Index out of bounds: "+index);
69 else return null;
70 }
71 } else if (ctx instanceof NodeList) {
72 NodeList nl = (NodeList)ctx;
73 int index = 0;
74 try {
75 index = ObjectConverter.toInt(indexOperator.apply(rootCtx, rootCtx));
76 if (index < nl.getLength()) {
77 return nl.item(index);
78 } else if (index == nl.getLength()) {
79 Element child = (Element)nl.item(0);
80 Node parent = child.getParentNode();
81 child = child.getOwnerDocument().createElement(child.getTagName());
82 parent.appendChild(child);
83 return child;
84 } else {
85 return null;
86 }
87 } catch (IndexOutOfBoundsException ioobe) {
88 if (throwExceptions) throw new EvaluationException("Index out of bounds: "+index);
89 else return null;
90 }
91 } else if (ctx instanceof Map) {
92 return ((Map)ctx).get(indexOperator.apply(rootCtx, rootCtx));
93 } else {
94 return null;
95 }
96 } catch (ConversionException ce) {
97 if (throwExceptions) throw new EvaluationException("Error converting value: "+ce.getMessage());
98 else return null;
99 }
100 }
101
102 /*** Sets the given value if this operator is at the end of the operator chain
103 * or just resolves the context object and passes it to the next operator in
104 * the chain.
105 * @param rootCtx The root context, needed for operators that require
106 * expression evaluation from root point. Example: Indexer operators
107 * @param ctx The current context where the operator will work over
108 * @param value The value to set.
109 */
110 protected void inverseMap(Object rootCtx, Object ctx, Object value) throws EvaluationException {
111 try {
112 if (ctx instanceof List) {
113 int index = ObjectConverter.toInt(indexOperator.apply(rootCtx, rootCtx));
114 ((List)ctx).set(index, value);
115 } else if (ctx instanceof Element) {
116 int index = ObjectConverter.toInt(indexOperator.apply(rootCtx, rootCtx));
117 if (index == 1) XMLHelper.createBrother((Element)ctx, value.toString());
118 } else if (ctx instanceof NodeList) {
119 NodeList nl = (NodeList)ctx;
120 int index = ObjectConverter.toInt(indexOperator.apply(rootCtx, rootCtx));
121 if (index < nl.getLength()) {
122 XMLHelper.setText((Element)nl.item(index), value.toString());
123 } else if (index == nl.getLength()) {
124 XMLHelper.createBrother((Element)nl.item(0), value.toString());
125 }
126 } else if (ctx instanceof Map) {
127 String index = indexOperator.apply(rootCtx, rootCtx).toString();
128 ((Map)ctx).put(index, value);
129 }
130 } catch (ConversionException ce) {
131 if (throwExceptions) throw new EvaluationException("Error converting value: "+ce.getMessage());
132 }
133 }
134 }
This page was automatically generated by Maven