001: /*
002: * project.java
003: *
004: * Copyright (c) 2004-2007 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 org.pnuts.lib;
010:
011: import pnuts.lang.*;
012: import pnuts.lang.Runtime;
013: import java.util.*;
014:
015: public class project extends PnutsFunction {
016:
017: public project() {
018: super ("project");
019: }
020:
021: public boolean defined(int narg) {
022: return (narg == 2);
023: }
024:
025: protected Object exec(final Object args[], final Context context) {
026: if (args.length != 2) {
027: undefined(args, context);
028: return null;
029: }
030: final Object f = args[1];
031: Object a1 = args[0];
032:
033: if (a1 instanceof Object[]) {
034: Object[] x = (Object[]) a1;
035: return new ProjectionList(new SimpleArrayList(x)) {
036: protected Object project(Object obj) {
037: return Runtime.call(context, f,
038: new Object[] { obj }, null);
039: }
040: };
041: } else if (a1 instanceof Set) {
042: final Set x = (Set) a1;
043: return new CloneableSet() {
044: public int size() {
045: return x.size();
046: }
047:
048: public Iterator iterator() {
049: return new ProjectionIterator(x.iterator()) {
050: public Object project(Object obj) {
051: return Runtime.call(context, f,
052: new Object[] { obj }, null);
053: }
054: };
055: }
056:
057: public Object clone() {
058: Set s = new HashSet();
059: for (Iterator it = iterator(); it.hasNext();) {
060: s.add(it.next());
061: }
062: return s;
063: }
064: };
065: } else if (a1 instanceof List) {
066: final List x = (List) a1;
067: return new ProjectionList(x) {
068: protected Object project(Object obj) {
069: return Runtime.call(context, f,
070: new Object[] { obj }, null);
071: }
072: };
073: } else if (a1 instanceof Iterator) {
074: return new ProjectionIterator((Iterator) a1) {
075: public Object project(Object obj) {
076: return Runtime.call(context, f,
077: new Object[] { obj }, null);
078: }
079: };
080: } else if (a1 instanceof Enumeration) {
081: return new ProjectionEnumeration((Enumeration) a1) {
082: public Object project(Object obj) {
083: return Runtime.call(context, f,
084: new Object[] { obj }, null);
085: }
086: };
087: } else if (a1 instanceof Generator) {
088: final Generator g = (Generator) a1;
089: return new Generator() {
090: public Object apply(final PnutsFunction closure,
091: final Context context) {
092: return g.apply(new PnutsFunction() {
093: protected Object exec(Object[] args, Context c) {
094: closure.call(new Object[] { Runtime.call(
095: context, f, args, null) }, context);
096: return null;
097: }
098: }, context);
099: }
100: };
101: } else if (a1 instanceof Map) {
102: final Map m = (Map) a1;
103: return new CloneableMap() {
104: public Object get(Object key) {
105: Object obj = m.get(key);
106: return Runtime.call(context, f,
107: new Object[] { obj }, null);
108: }
109:
110: public Set entrySet() {
111: return new CloneableSet() {
112: public Iterator iterator() {
113: return new ProjectionIterator(m.entrySet()
114: .iterator()) {
115: public Object project(Object obj) {
116: Map.Entry entry = (Map.Entry) obj;
117: final Object key = entry.getKey();
118: final Object value = entry
119: .getValue();
120: return new Map.Entry() {
121: public Object getKey() {
122: return key;
123: }
124:
125: public Object getValue() {
126: return Runtime
127: .call(
128: context,
129: f,
130: new Object[] { value },
131: null);
132: }
133:
134: public Object setValue(
135: Object value) {
136: throw new UnsupportedOperationException();
137: }
138: };
139: }
140: };
141: }
142:
143: public Object clone() {
144: Set s = new HashSet();
145: for (Iterator it = iterator(); it.hasNext();) {
146: s.add(it.next());
147: }
148: return s;
149: }
150:
151: public int size() {
152: return m.size();
153: }
154: };
155: }
156:
157: public Object clone() {
158: HashMap m = new HashMap();
159: for (Iterator it = entrySet().iterator(); it
160: .hasNext();) {
161: Map.Entry entry = (Map.Entry) it.next();
162: m.put(entry.getKey(), entry.getValue());
163: }
164: return m;
165: }
166: };
167: } else if (a1 == null) {
168: return null;
169: } else {
170: Enumeration e = context.getConfiguration()
171: .toEnumeration(a1);
172: if (e != null) {
173: return new ProjectionEnumeration(e) {
174: public Object project(Object obj) {
175: return Runtime.call(context, f,
176: new Object[] { obj }, null);
177: }
178: };
179: } else {
180: final Object m = a1;
181: return new pnuts.lang.Property() {
182: public Object get(String key, Context ctx) {
183: Object obj = context.getConfiguration()
184: .getElement(ctx, m, key);
185: return Runtime.call(ctx, f,
186: new Object[] { obj }, null);
187: }
188:
189: public void set(String key, Object value,
190: Context ctx) {
191: throw new UnsupportedOperationException();
192: }
193: };
194: }
195: }
196: }
197:
198: public String toString() {
199: return "function project(elements, funcOrClass)";
200: }
201:
202: static abstract class CloneableSet extends AbstractSet implements
203: Cloneable {
204: }
205:
206: static abstract class CloneableMap extends AbstractMap implements
207: Cloneable {
208: }
209: }
|