001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.flow.javascript;
018:
019: import java.util.LinkedList;
020: import java.util.List;
021:
022: import org.apache.commons.jxpath.DynamicPropertyHandler;
023: import org.apache.commons.jxpath.ri.model.NodePointer;
024: import org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer;
025: import org.mozilla.javascript.NativeArray;
026: import org.mozilla.javascript.Scriptable;
027: import org.mozilla.javascript.ScriptableObject;
028: import org.mozilla.javascript.Undefined;
029: import org.mozilla.javascript.Wrapper;
030:
031: /**
032: *
033: * @version CVS $Id: ScriptablePropertyPointer.java 433543 2006-08-22 06:22:54Z crossley $
034: */
035: public class ScriptablePropertyPointer extends DynamicPropertyPointer {
036:
037: DynamicPropertyHandler handler;
038:
039: public ScriptablePropertyPointer(NodePointer parent,
040: DynamicPropertyHandler handler) {
041: super (parent, handler);
042: this .handler = handler;
043: }
044:
045: public int getLength() {
046: Object obj = getBaseValue();
047: if (obj instanceof Scriptable) {
048: Scriptable node = (Scriptable) obj;
049: if (node instanceof NativeArray) {
050: return (int) ((NativeArray) node).jsGet_length();
051: }
052: if (ScriptableObject.hasProperty(node, "length")) {
053: Object val = ScriptableObject.getProperty(node,
054: "length");
055: if (val instanceof Number) {
056: return ((Number) val).intValue();
057: }
058: }
059: }
060: return super .getLength();
061: }
062:
063: public Object getImmediateNode() {
064: Object value;
065: if (index == WHOLE_COLLECTION) {
066: value = getBaseValue();
067: } else {
068: value = getBaseValue();
069: if (value instanceof Scriptable) {
070: Object property = ScriptableObject.getProperty(
071: (Scriptable) value, index);
072: if (property != Scriptable.NOT_FOUND) {
073: value = property; // hack?
074: }
075: } else {
076: return super .getImmediateNode();
077: }
078: }
079: if (value instanceof Wrapper) {
080: value = ((Wrapper) value).unwrap();
081: }
082: return value;
083: }
084:
085: public Object getValue() {
086: Object val = getNode();
087: if (val instanceof NativeArray) {
088: NativeArray arr = (NativeArray) val;
089: List list = new LinkedList();
090: int len = (int) arr.jsGet_length();
091: for (int i = 0; i < len; i++) {
092: Object obj = arr.get(i, arr);
093: if (obj == Undefined.instance) {
094: obj = null;
095: }
096: list.add(obj);
097: }
098: return list;
099: }
100: return super .getValue();
101: }
102:
103: public void setValue(Object value) {
104: if (index == WHOLE_COLLECTION) {
105: handler.setProperty(getBean(), getPropertyName(), value);
106: } else {
107: Object val = handler.getProperty(getBean(),
108: getPropertyName());
109: if (val instanceof Scriptable) {
110: ScriptableObject.putProperty((Scriptable) val, index,
111: value);
112: } else {
113: super .setValue(value);
114: }
115: }
116: }
117:
118: public void remove() {
119: if (index == WHOLE_COLLECTION) {
120: handler.setProperty(getBean(), "length", new Integer(0));
121: } else {
122: Object val = handler.getProperty(getBean(),
123: getPropertyName());
124: if (val instanceof Scriptable) {
125: try {
126: ScriptableObject.deleteProperty((Scriptable) val,
127: index);
128: } catch (Exception e) {
129: e.printStackTrace();
130: }
131: } else {
132: super .remove();
133: }
134: }
135: }
136:
137: public boolean isCollection() {
138: Object obj = getBaseValue();
139: if (obj instanceof NativeArray) {
140: return true;
141: }
142: return super .isCollection();
143: }
144:
145: public String asPath() {
146: Object obj = getBaseValue();
147: if (!(obj instanceof Scriptable)) {
148: return super .asPath();
149: }
150: StringBuffer buffer = new StringBuffer();
151: buffer.append(getParent().asPath());
152: if (buffer.length() == 0) {
153: buffer.append("/.");
154: } else if (buffer.charAt(buffer.length() - 1) == '/') {
155: buffer.append('.');
156: }
157: buffer.append("[@name = '");
158: buffer.append(escape(getPropertyName()));
159: buffer.append("']");
160: if (index != WHOLE_COLLECTION && (obj instanceof NativeArray)) {
161: buffer.append('[').append(index + 1).append(']');
162: }
163: return buffer.toString();
164: }
165:
166: private String escape(String string) {
167: int index = string.indexOf('\'');
168: while (index != -1) {
169: string = string.substring(0, index) + "'"
170: + string.substring(index + 1);
171: index = string.indexOf('\'');
172: }
173: index = string.indexOf('\"');
174: while (index != -1) {
175: string = string.substring(0, index) + """
176: + string.substring(index + 1);
177: index = string.indexOf('\"');
178: }
179: return string;
180: }
181:
182: }
|