001: /*
002: * $Id: AnyMap.java,v 1.19 2002/09/16 08:05:02 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core;
011:
012: import anvil.script.Context;
013: import anvil.java.util.BindingEnumeration;
014: import java.io.IOException;
015: import java.io.OutputStream;
016: import java.io.Writer;
017:
018: /// @class map
019: /// Map represents mapping of key to value.
020:
021: /**
022: * class AnyMap
023: *
024: * @author: Jani Lehtimäki
025: */
026: public class AnyMap extends Any {
027:
028: /// @constructor map
029: /// Creates a mappings.
030: /// @synopsis range(object key, object value)
031: public static final Object[] newInstance = { "key", "value" };
032:
033: public static final Any newInstance(Any a, Any b) {
034: return new AnyMap(a, b);
035: }
036:
037: transient public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
038: "map",
039: AnyMap.class,
040: //DOC{{
041: ""
042: + " @class map\n"
043: + " Map represents mapping of key to value.\n"
044: + " @constructor map\n"
045: + " Creates a mappings.\n"
046: + " @synopsis range(object key, object value)\n"
047: + " @method swap \n"
048: + " Returns new map containing this map with left and right side \n"
049: + " swapped.\n" + " @synopsis map swap()\n"
050: //}}DOC
051: );
052:
053: protected Any _left;
054: protected Any _right;
055:
056: private AnyMap() {
057: }
058:
059: public AnyMap(Any left, Any right) {
060: _left = left;
061: _right = right;
062: }
063:
064: public final anvil.script.ClassType classOf() {
065: return __class__;
066: }
067:
068: public int typeOf() {
069: return IS_MAP;
070: }
071:
072: public int sizeOf() {
073: return 2;
074: }
075:
076: public boolean isMap() {
077: return true;
078: }
079:
080: public boolean toBoolean() {
081: return true;
082: }
083:
084: public Any getLeft() {
085: return _left;
086: }
087:
088: public Any getRight() {
089: return _right;
090: }
091:
092: public Any[] toTuple() {
093: return new Any[] { _left, _right };
094: }
095:
096: public Object toObject() {
097: return new Any[] { _left, _right };
098: }
099:
100: public AnyMap toMap() {
101: return this ;
102: }
103:
104: public int hashCode() {
105: return _left.hashCode() + 3 * _right.hashCode();
106: }
107:
108: public String toString() {
109: return _left.toString() + "=>" + _right.toString();
110: }
111:
112: public Writer toAnvil(Writer writer) throws IOException {
113: _left.toAnvil(writer);
114: writer.write("=>");
115: _right.toAnvil(writer);
116: return writer;
117: }
118:
119: public Writer toJava(Writer writer) throws IOException {
120: writer.write("new anvil.core.AnyMap(");
121: _left.toJava(writer);
122: writer.write(',');
123: writer.write(' ');
124: _right.toJava(writer);
125: writer.write(')');
126: return writer;
127: }
128:
129: public anvil.codec.Code toCode(anvil.codec.Code code) {
130: anvil.codec.ConstantPool pool = code.getPool();
131: int clazz = pool.addClass("anvil/core/AnyMap");
132: code.anew(clazz);
133: code.dup();
134: _left.toCode(code);
135: _right.toCode(code);
136: code.invokespecial(pool.addMethodRef(clazz, "<init>",
137: "(Lanvil/core/Any;Lanvil/core/Any;)V"));
138: return code;
139: }
140:
141: public Object clone() {
142: return this ;
143: }
144:
145: public Any copy() {
146: return new AnyMap(_left.copy(), _right.copy());
147: }
148:
149: public boolean equals(Object obj) {
150: if (this == obj) {
151: return true;
152: }
153: if (obj instanceof AnyMap) {
154: AnyMap map = (AnyMap) obj;
155: return _left.equals(map._left) && _right.equals(map._right);
156: }
157: return false;
158: }
159:
160: protected int compare(Any other) {
161: AnyMap map = other.toMap();
162: int delta = _left.compareTo(map._left);
163: if (delta == 0) {
164: delta = _right.compareTo(map._right);
165: }
166: return delta;
167: }
168:
169: public void serialize(Serializer serializer) throws IOException {
170: if (serializer.register(this )) {
171: return;
172: }
173: serializer.write('m');
174: _left.serialize(serializer);
175: _right.serialize(serializer);
176: }
177:
178: public static final AnyMap unserialize(Unserializer unserializer)
179: throws UnserializationException {
180: AnyMap map = new AnyMap();
181: unserializer.register(map);
182: map._left = unserializer.unserialize();
183: map._right = unserializer.unserialize();
184: return map;
185: }
186:
187: public Any getReference(Context context, Any index) {
188: int i = index.toInt();
189: if (i == 0) {
190: return _left;
191: } else if (i == 1) {
192: return _right;
193: } else {
194: throw context.ReferenceError("map[" + index + "]");
195: }
196: }
197:
198: public Any checkReference(Context context, Any index) {
199: int i = index.toInt();
200: if (i == 0) {
201: return _left;
202: } else if (i == 1) {
203: return _right;
204: } else {
205: return UNDEFINED;
206: }
207: }
208:
209: public boolean contains(Any value) {
210: if (_left.equals(value)) {
211: return true;
212: }
213: if (_right.equals(value)) {
214: return true;
215: }
216: return false;
217: }
218:
219: public Any getAttribute(Context context, String attribute) {
220: if (attribute.equals("left")) {
221: return _left;
222: } else if (attribute.equals("right")) {
223: return _right;
224: } else {
225: throw context.AttributeError("map." + attribute);
226: }
227: }
228:
229: public BindingEnumeration enumeration() {
230: return new MapEnumeration();
231: }
232:
233: /// @method swap
234: /// Returns new map containing this map with left and right side
235: /// swapped.
236: /// @synopsis map swap()
237: public Any m_swap() {
238: return new AnyMap(_right, _left);
239: }
240:
241: public class MapEnumeration implements BindingEnumeration {
242:
243: boolean _more = true;
244:
245: public MapEnumeration() {
246: }
247:
248: public boolean hasMoreElements() {
249: return _more;
250: }
251:
252: public Object nextElement() {
253: _more = false;
254: return _right;
255: }
256:
257: public Object nextKey() {
258: return _left;
259: }
260:
261: }
262:
263: }
|