KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > env > ObjectExtValue


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.env;
31
32 import com.caucho.quercus.QuercusException;
33 import com.caucho.quercus.expr.Expr;
34 import com.caucho.quercus.expr.StringLiteralExpr;
35 import com.caucho.quercus.program.AbstractFunction;
36 import com.caucho.vfs.WriteStream;
37
38 import java.io.IOException JavaDoc;
39 import java.io.ObjectInputStream JavaDoc;
40 import java.io.ObjectOutputStream JavaDoc;
41 import java.io.Serializable JavaDoc;
42 import java.util.*;
43
44 /**
45  * Represents a PHP object value.
46  */

47 public class ObjectExtValue extends ObjectValue
48   implements Serializable JavaDoc
49 {
50   private static final StringValue TO_STRING = new StringValueImpl("__toString");
51
52   private static final int DEFAULT_SIZE = 16;
53
54   private QuercusClass _cl;
55
56   private Entry []_entries;
57   private int _hashMask;
58
59   private int _size;
60
61   public ObjectExtValue(QuercusClass cl)
62   {
63     _cl = cl;
64     
65     init();
66   }
67   
68   private void init()
69   {
70     _entries = new Entry[DEFAULT_SIZE];
71     _hashMask = _entries.length - 1;
72   }
73
74   /*
75   public ObjectExtValue(Env env, IdentityHashMap<Value,Value> map,
76                      QuercusClass cl, ArrayValue oldValue)
77   {
78     super(new ArrayValueImpl(env, map, oldValue));
79
80     _cl = cl;
81
82     // _cl.initFields(_map);
83   }
84   */

85
86   /**
87    * Returns the class name.
88    */

89   public String JavaDoc getName()
90   {
91     return _cl.getName();
92   }
93
94   /**
95    * Returns the parent class
96    */

97   public String JavaDoc getParentName()
98   {
99     return _cl.getParentName();
100   }
101
102   /**
103    * Returns the quercus class.
104    */

105   public QuercusClass getQuercusClass()
106   {
107     return _cl;
108   }
109
110   /**
111    * Returns the type.
112    */

113   public String JavaDoc getType()
114   {
115     return "object";
116   }
117
118   /**
119    * Converts to a boolean.
120    */

121   public boolean toBoolean()
122   {
123     return true;
124   }
125
126   /**
127    * Returns true for an implementation of a class
128    */

129   public boolean isA(String JavaDoc name)
130   {
131     return _cl.isA(name);
132   }
133
134   /**
135    * Returns true for an object.
136    */

137   public boolean isObject()
138   {
139     return true;
140   }
141
142   /**
143    * Converts to a long.
144    */

145   public long toLong()
146   {
147     return 1;
148   }
149
150   /**
151    * Converts to a double.
152    */

153   public double toDouble()
154   {
155     return toLong();
156   }
157
158   /**
159    * Returns the number of entries.
160    */

161   public int getSize()
162   {
163     return _size;
164   }
165
166   /**
167    * Gets a field value.
168    */

169   @Override JavaDoc
170   public Value getField(Env env, String JavaDoc key)
171   {
172     int capacity = _entries.length;
173
174     int hashMask = _hashMask;
175     int hash = key.hashCode() & hashMask;
176
177     int count = capacity;
178     for (; count >= 0; count--) {
179       Entry entry = _entries[hash];
180
181       if (entry == null) {
182         return _cl.getField(env, this, key);
183       }
184       else if (key.equals(entry.getKey())) {
185         return entry.getValue();
186       }
187
188       hash = (hash + 1) & hashMask;
189     }
190
191     return _cl.getField(env, this, key);
192   }
193
194   /**
195    * Returns the array ref.
196    */

197   public Var getFieldRef(Env env, String JavaDoc index)
198   {
199     Entry entry = createEntry(index);
200
201     Value value = entry._value;
202
203     if (value instanceof Var)
204       return (Var) value;
205
206     Var var = new Var(value);
207
208     entry.setValue(var);
209
210     return var;
211   }
212
213   /**
214    * Returns the value as an argument which may be a reference.
215    */

216   public Value getFieldArg(Env env, String JavaDoc index)
217   {
218     Entry entry = getEntry(index);
219
220     if (entry != null)
221       return entry.toArg();
222     else
223       return new ArgGetFieldValue(env, this, index);
224   }
225
226   /**
227    * Returns the value as an argument which may be a reference.
228    */

229   public Value getFieldArgRef(Env env, String JavaDoc index)
230   {
231     Entry entry = getEntry(index);
232
233     if (entry != null)
234       return entry.toArg();
235     else
236       return new ArgGetFieldValue(env, this, index);
237   }
238
239   /**
240    * Gets a new value.
241    */

242   private Entry getEntry(String JavaDoc key)
243   {
244     int capacity = _entries.length;
245
246     int hash = key.hashCode() & _hashMask;
247
248     int count = capacity;
249     for (; count >= 0; count--) {
250       Entry entry = _entries[hash];
251
252       if (entry == null)
253         return null;
254       else if (key.equals(entry.getKey()))
255         return entry;
256
257       hash = (hash + 1) & _hashMask;
258     }
259
260     return null;
261   }
262
263   /**
264    * XXX: to handle foreach
265    */

266   public Value get(Value key)
267   {
268     // php/0d92 - expects exception
269
return getField(null, key.toString());
270   }
271
272   public Value put(Value index, Value value)
273   {
274     throw new QuercusException(L.l("Object of type '{0}' cannot be used as an array",
275                    getClassName()));
276   }
277
278   public Value put(Value value)
279   {
280     throw new QuercusException(L.l("Object of type '{0}' cannot be used as an array",
281                    getClassName()));
282   }
283
284   /**
285    * Adds a new value.
286    */

287   public Value putFieldInit(Env env, String JavaDoc key, Value value)
288   {
289     createEntry(key);
290
291     return putField(env, key, value);
292   }
293
294   /**
295    * Adds a new value.
296    */

297   @Override JavaDoc
298   public Value putField(Env env, String JavaDoc key, Value value)
299   {
300     Entry entry = null;
301
302     AbstractFunction setField = _cl.getSetField();
303     if (setField != null) {
304       entry = getEntry(key);
305
306       if (entry == null)
307     return setField.callMethod(env, this, new StringValueImpl(key), value);
308     }
309     else
310       entry = createEntry(key);
311
312     Value oldValue = entry._value;
313
314     if (value instanceof Var) {
315       Var var = (Var) value;
316       var.setReference();
317
318       entry._value = var;
319     }
320     else if (oldValue instanceof Var) {
321       oldValue.set(value);
322     }
323     else {
324       entry._value = value;
325     }
326
327     return value;
328   }
329
330   /**
331    * Adds a new value.
332    */

333   public Value putField(String JavaDoc key, String JavaDoc value)
334   {
335     return putField(null, key, new StringValueImpl(value));
336   }
337
338   /**
339    * Adds a new value.
340    */

341   public Value putField(String JavaDoc key, long value)
342   {
343     return putField(null, key, LongValue.create(value));
344   }
345
346   /**
347    * Adds a new value.
348    */

349   public Value putField(String JavaDoc key, double value)
350   {
351     return putField(null, key, DoubleValue.create(value));
352   }
353
354   /**
355    * Removes a value.
356    */

357   public void removeField(String JavaDoc key)
358   {
359     int capacity = _entries.length;
360
361     int hash = key.hashCode() & _hashMask;
362
363     int count = capacity;
364     for (; count >= 0; count--) {
365       Entry entry = _entries[hash];
366
367       if (entry == null)
368         return;
369       else if (key.equals(entry.getKey())) {
370         _size--;
371
372         _entries[hash] = null;
373         shiftEntries(hash + 1);
374
375         return;
376       }
377
378       hash = (hash + 1) & _hashMask;
379     }
380   }
381
382   /**
383    * Shift entries after a delete.
384    */

385   private void shiftEntries(int index)
386   {
387     int capacity = _entries.length;
388
389     for (; index < capacity; index++) {
390       Entry entry = _entries[index];
391
392       if (entry == null)
393         return;
394
395       _entries[index] = null;
396
397       addEntry(entry);
398     }
399   }
400
401   /**
402    * Creates the entry for a key.
403    */

404   private Entry createEntry(String JavaDoc key)
405   {
406     int capacity = _entries.length;
407
408     int hashMask = _hashMask;
409
410     int hash = key.hashCode() & hashMask;
411
412     int count = capacity;
413     for (; count >= 0; count--) {
414       Entry entry = _entries[hash];
415
416       if (entry == null)
417         break;
418       else if (key.equals(entry.getKey()))
419         return entry;
420
421       hash = (hash + 1) & hashMask;
422     }
423
424     _size++;
425
426     Entry newEntry = new Entry(key);
427     _entries[hash] = newEntry;
428
429     if (_entries.length <= 2 * _size)
430       expand();
431
432     return newEntry;
433   }
434
435   private void expand()
436   {
437     Entry []entries = _entries;
438
439     _entries = new Entry[2 * entries.length];
440     _hashMask = _entries.length - 1;
441
442     for (int i = entries.length - 1; i >= 0; i--) {
443       Entry entry = entries[i];
444
445       if (entry != null)
446         addEntry(entry);
447     }
448   }
449
450   private void addEntry(Entry entry)
451   {
452     int capacity = _entries.length;
453
454     int hash = entry.getKey().hashCode() & _hashMask;
455
456     for (int i = capacity; i >= 0; i--) {
457       if (_entries[hash] == null) {
458         _entries[hash] = entry;
459         return;
460       }
461
462       hash = (hash + 1) & _hashMask;
463     }
464   }
465
466   /**
467    * Returns the key array
468    */

469   public Value []getKeyArray()
470   {
471     Value []keys = new Value[getSize()];
472
473     int k = 0;
474     for (int i = 0; i < _entries.length; i++) {
475       Entry entry = _entries[i];
476
477       if (entry != null)
478     keys[k++] = new StringValueImpl(entry.getKey());
479     }
480
481     return keys;
482   }
483
484   /**
485    * Returns the value array
486    */

487   public Value []getValueArray(Env env)
488   {
489     Value []values = new Value[getSize()];
490
491     int k = 0;
492     for (int i = 0; i < _entries.length; i++) {
493       Entry entry = _entries[i];
494
495       if (entry != null)
496     values[k++] = entry.getValue().toValue();
497     }
498
499     return values;
500   }
501
502   /**
503    * Returns the field values.
504    */

505   public Collection<Value> getIndices()
506   {
507     ArrayList<Value> indices = new ArrayList<Value>();
508
509     for (int i = 0; i < _entries.length; i++) {
510       Entry entry = _entries[i];
511
512       if (entry != null)
513     indices.add(new StringValueImpl(entry.getKey()));
514     }
515
516     return indices;
517   }
518
519   /**
520    * Finds the method name.
521    */

522   public AbstractFunction findFunction(String JavaDoc methodName)
523   {
524     return _cl.findFunction(methodName);
525   }
526
527   /**
528    * Evaluates a method.
529    */

530   public Value callMethod(Env env, String JavaDoc methodName, Expr []args)
531   {
532     AbstractFunction fun = _cl.findFunction(methodName);
533     
534     if (fun != null)
535       return fun.callMethod(env, this, args);
536     else if (_cl.getCall() != null) {
537       Expr []newArgs = new Expr[args.length + 1];
538       newArgs[0] = new StringLiteralExpr(methodName);
539       System.arraycopy(args, 0, newArgs, 1, args.length);
540       
541       return _cl.getCall().callMethod(env, this, newArgs);
542     }
543     else
544       return env.error(L.l("Call to undefined method {0}::{1}",
545                            _cl.getName(), methodName));
546   }
547
548   /**
549    * Evaluates a method.
550    */

551   public Value callMethod(Env env, String JavaDoc methodName, Value []args)
552   {
553     AbstractFunction fun = _cl.findFunction(methodName);
554
555     if (fun != null)
556       return fun.callMethod(env, this, args);
557     else if (_cl.getCall() != null) {
558       StringValueImpl name = new StringValueImpl(methodName);
559       ArrayValue newArgs = new ArrayValueImpl();
560
561       for (int i = 0; i < args.length; i++)
562     newArgs.append(args[i]);
563       
564       return _cl.getCall().callMethod(env, this, name, newArgs);
565     }
566     else
567       return env.error(L.l("Call to undefined method {0}::{1}()",
568                            _cl.getName(), methodName));
569   }
570
571   /**
572    * Evaluates a method.
573    */

574   public Value callMethod(Env env, String JavaDoc methodName)
575   {
576     AbstractFunction fun = _cl.findFunction(methodName);
577
578     if (fun != null)
579       return fun.callMethod(env, this);
580     else if (_cl.getCall() != null) {
581       return _cl.getCall().callMethod(env,
582                       this,
583                       new StringValueImpl(methodName),
584                       new ArrayValueImpl());
585     }
586     else
587       return env.error(L.l("Call to undefined method {0}::{1}()",
588                            _cl.getName(), methodName));
589   }
590
591   /**
592    * Evaluates a method.
593    */

594   public Value callMethod(Env env, String JavaDoc methodName, Value a0)
595   {
596     AbstractFunction fun = _cl.findFunction(methodName);
597
598     if (fun != null)
599       return fun.callMethod(env, this, a0);
600     else if (_cl.getCall() != null) {
601       return _cl.getCall().callMethod(env,
602                       this,
603                       new StringValueImpl(methodName),
604                       new ArrayValueImpl()
605                       .append(a0));
606     }
607     else
608       return env.error(L.l("Call to undefined method {0}::{1}()",
609                            _cl.getName(), methodName));
610   }
611
612   /**
613    * Evaluates a method.
614    */

615   public Value callMethod(Env env, String JavaDoc methodName,
616                           Value a0, Value a1)
617   {
618     AbstractFunction fun = _cl.findFunction(methodName);
619
620     if (fun != null)
621       return fun.callMethod(env, this, a0, a1);
622     else if (_cl.getCall() != null) {
623       return _cl.getCall().callMethod(env,
624                       this,
625                       new StringValueImpl(methodName),
626                       new ArrayValueImpl()
627                       .append(a0)
628                       .append(a1));
629     }
630     else
631       return env.error(L.l("Call to undefined method {0}::{1}()",
632                            _cl.getName(), methodName));
633   }
634
635   /**
636    * Evaluates a method.
637    */

638   public Value callMethod(Env env, String JavaDoc methodName,
639                           Value a0, Value a1, Value a2)
640   {
641     AbstractFunction fun = _cl.findFunction(methodName);
642
643     if (fun != null)
644       return fun.callMethod(env, this, a0, a1, a2);
645     else if (_cl.getCall() != null) {
646       return _cl.getCall().callMethod(env,
647                       this,
648                       new StringValueImpl(methodName),
649                       new ArrayValueImpl().append(a0)
650                       .append(a1)
651                       .append(a2));
652     }
653     else
654       return env.error(L.l("Call to undefined method {0}::{1}()",
655                            _cl.getName(), methodName));
656   }
657
658   /**
659    * Evaluates a method.
660    */

661   public Value callMethod(Env env, String JavaDoc methodName,
662                           Value a0, Value a1, Value a2, Value a3)
663   {
664     AbstractFunction fun = _cl.findFunction(methodName);
665
666     if (fun != null)
667       return fun.callMethod(env, this, a0, a1, a2, a3);
668     else if (_cl.getCall() != null) {
669       return _cl.getCall().callMethod(env,
670                       this,
671                       new StringValueImpl(methodName),
672                       new ArrayValueImpl()
673                       .append(a0)
674                       .append(a1)
675                       .append(a2)
676                       .append(a3));
677     }
678     else
679       return env.error(L.l("Call to undefined method {0}::{1}()",
680                            _cl.getName(), methodName));
681   }
682
683   /**
684    * Evaluates a method.
685    */

686   public Value callMethod(Env env, String JavaDoc methodName,
687                           Value a0, Value a1, Value a2, Value a3, Value a4)
688   {
689     AbstractFunction fun = _cl.findFunction(methodName);
690
691     if (fun != null)
692       return fun.callMethod(env, this, a0, a1, a2, a3, a4);
693     else if (_cl.getCall() != null) {
694       return _cl.getCall().callMethod(env,
695                       this,
696                       new StringValueImpl(methodName),
697                       new ArrayValueImpl()
698                       .append(a0)
699                       .append(a1)
700                       .append(a2)
701                       .append(a3)
702                       .append(a4));
703     }
704     else
705       return env.error(L.l("Call to undefined method {0}::{1}()",
706                            _cl.getName(), methodName));
707   }
708
709   /**
710    * Evaluates a method.
711    */

712   public Value callMethodRef(Env env, String JavaDoc methodName, Expr []args)
713   {
714     return _cl.getFunction(methodName).callMethodRef(env, this, args);
715   }
716
717   /**
718    * Evaluates a method.
719    */

720   public Value callMethodRef(Env env, String JavaDoc methodName, Value []args)
721   {
722     AbstractFunction fun = _cl.findFunction(methodName);
723
724     if (fun != null)
725       return fun.callMethodRef(env, this, args);
726     else if (_cl.getCall() != null) {
727       StringValueImpl name = new StringValueImpl(methodName);
728       ArrayValue newArgs = new ArrayValueImpl();
729
730       for (int i = 0; i < args.length; i++)
731     newArgs.append(args[i]);
732       
733       return _cl.getCall().callMethodRef(env, this, name, newArgs);
734     }
735     else
736       return env.error(L.l("Call to undefined method {0}::{1}()",
737                            _cl.getName(), methodName));
738   }
739
740   /**
741    * Evaluates a method.
742    */

743   public Value callMethodRef(Env env, String JavaDoc methodName)
744   {
745     AbstractFunction fun = _cl.findFunction(methodName);
746
747     if (fun != null)
748       return fun.callMethodRef(env, this);
749     else if (_cl.getCall() != null) {
750       return _cl.getCall().callMethodRef(env,
751                      this,
752                      new StringValueImpl(methodName),
753                      new ArrayValueImpl());
754     }
755     else
756       return env.error(L.l("Call to undefined method {0}::{1}()",
757                            _cl.getName(), methodName));
758   }
759
760   /**
761    * Evaluates a method.
762    */

763   public Value callMethodRef(Env env, String JavaDoc methodName, Value a0)
764   {
765     AbstractFunction fun = _cl.findFunction(methodName);
766
767     if (fun != null)
768       return fun.callMethodRef(env, this, a0);
769     else if (_cl.getCall() != null) {
770       return _cl.getCall().callMethodRef(env,
771                      this,
772                      new StringValueImpl(methodName),
773                      new ArrayValueImpl()
774                      .append(a0));
775     }
776     else
777       return env.error(L.l("Call to undefined method {0}::{1}()",
778                            _cl.getName(), methodName));
779   }
780
781   /**
782    * Evaluates a method.
783    */

784   public Value callMethodRef(Env env, String JavaDoc methodName,
785                              Value a0, Value a1)
786   {
787     AbstractFunction fun = _cl.findFunction(methodName);
788
789     if (fun != null)
790       return fun.callMethodRef(env, this, a0, a1);
791     else if (_cl.getCall() != null) {
792       return _cl.getCall().callMethodRef(env,
793                      this,
794                      new StringValueImpl(methodName),
795                      new ArrayValueImpl()
796                      .append(a0)
797                      .append(a1));
798     }
799     else
800       return env.error(L.l("Call to undefined method {0}::{1}()",
801                            _cl.getName(), methodName));
802   }
803
804   /**
805    * Evaluates a method.
806    */

807   public Value callMethodRef(Env env, String JavaDoc methodName,
808                              Value a0, Value a1, Value a2)
809   {
810     AbstractFunction fun = _cl.findFunction(methodName);
811
812     if (fun != null)
813       return fun.callMethodRef(env, this, a0, a1, a2);
814     else if (_cl.getCall() != null) {
815       return _cl.getCall().callMethodRef(env,
816                      this,
817                      new StringValueImpl(methodName),
818                      new ArrayValueImpl()
819                      .append(a0)
820                      .append(a1)
821                      .append(a2));
822     }
823     else
824       return env.error(L.l("Call to undefined method {0}::{1}()",
825                            _cl.getName(), methodName));
826   }
827
828   /**
829    * Evaluates a method.
830    */

831   public Value callMethodRef(Env env, String JavaDoc methodName,
832                              Value a0, Value a1, Value a2, Value a3)
833   {
834     AbstractFunction fun = _cl.findFunction(methodName);
835
836     if (fun != null)
837       return fun.callMethodRef(env, this, a0, a1, a2, a3);
838     else if (_cl.getCall() != null) {
839       return _cl.getCall().callMethodRef(env,
840                      this,
841                      new StringValueImpl(methodName),
842                      new ArrayValueImpl()
843                      .append(a0)
844                      .append(a1)
845                      .append(a2)
846                      .append(a3));
847     }
848     else
849       return env.error(L.l("Call to undefined method {0}::{1}()",
850                            _cl.getName(), methodName));
851   }
852
853   /**
854    * Evaluates a method.
855    */

856   public Value callMethodRef(Env env, String JavaDoc methodName,
857                              Value a0, Value a1, Value a2, Value a3, Value a4)
858   {
859     AbstractFunction fun = _cl.findFunction(methodName);
860
861     if (fun != null)
862       return fun.callMethodRef(env, this, a0, a1, a2, a3, a4);
863     else if (_cl.getCall() != null) {
864       return _cl.getCall().callMethodRef(env,
865                      this,
866                      new StringValueImpl(methodName),
867                      new ArrayValueImpl()
868                      .append(a0)
869                      .append(a1)
870                      .append(a2)
871                      .append(a3)
872                      .append(a4));
873     }
874     else
875       return env.error(L.l("Call to undefined method {0}::{1}()",
876                            _cl.getName(), methodName));
877   }
878
879   /**
880    * Evaluates a method.
881    */

882   public Value callClassMethod(Env env, AbstractFunction fun, Value []args)
883   {
884     return fun.callMethod(env, this, args);
885   }
886
887   /**
888    * Returns the value for the variable, creating an object if the var
889    * is unset.
890    */

891   public Value getObject(Env env)
892   {
893     return this;
894   }
895
896   /**
897    * Copy for assignment.
898    */

899   public Value copy()
900   {
901     return this;
902   }
903
904   /**
905    * Copy for serialization
906    */

907   public Value copy(Env env, IdentityHashMap<Value,Value> map)
908   {
909     Value oldValue = map.get(this);
910
911     if (oldValue != null)
912       return oldValue;
913
914     // XXX:
915
// return new ObjectExtValue(env, map, _cl, getArray());
916

917     return this;
918   }
919
920   /**
921    * Clone the object
922    */

923   public Value clone()
924   {
925     ObjectExtValue newObject = new ObjectExtValue(_cl);
926
927     for (Map.Entry<String JavaDoc,Value> entry : entrySet())
928       newObject.putField(null, entry.getKey(), entry.getValue());
929
930     return newObject;
931   }
932
933   // XXX: need to check the other copy, e.g. for sessions
934

935   /**
936    * Serializes the value.
937    */

938   public void serialize(StringBuilder JavaDoc sb)
939   {
940     sb.append("O:");
941     sb.append(_cl.getName().length());
942     sb.append(":\"");
943     sb.append(_cl.getName());
944     sb.append("\":");
945     sb.append(getSize());
946     sb.append(":{");
947
948     for (Map.Entry<String JavaDoc,Value> entry : entrySet()) {
949       String JavaDoc key = entry.getKey();
950
951       sb.append("s:");
952       sb.append(key.length());
953       sb.append(":\"");
954       sb.append(key);
955       sb.append("\";");
956
957       entry.getValue().serialize(sb);
958     }
959
960     sb.append("}");
961   }
962
963   /**
964    * Converts to a string.
965    * @param env
966    */

967   public StringValue toString(Env env)
968   {
969     AbstractFunction fun = _cl.findFunction("__toString");
970
971     if (fun != null)
972       return fun.callMethod(env, this, new Expr[0]).toStringValue();
973     else
974       return new StringValueImpl(_cl.getName() + "[]");
975   }
976
977   /**
978    * Converts to a string.
979    * @param env
980    */

981   public void print(Env env)
982   {
983     env.print(toString(env));
984   }
985
986   /**
987    * Converts to an array.
988    */

989   public Value toArray()
990   {
991     ArrayValue array = new ArrayValueImpl();
992
993     for (Map.Entry<String JavaDoc,Value> entry : entrySet()) {
994       array.put(new StringValueImpl(entry.getKey()), entry.getValue());
995     }
996
997     return array;
998   }
999
1000  /**
1001   * Converts to an object.
1002   */

1003  public Value toObject(Env env)
1004  {
1005    return this;
1006  }
1007
1008  /**
1009   * Converts to an object.
1010   */

1011  public Object JavaDoc toJavaObject()
1012  {
1013    return this;
1014  }
1015
1016  public Set<Map.Entry<String JavaDoc,Value>> entrySet()
1017  {
1018    return new EntrySet();
1019  }
1020
1021  /**
1022   * Returns a Set of entries, sorted by key.
1023   */

1024  public Set<Map.Entry<String JavaDoc,Value>> sortedEntrySet()
1025  {
1026    return new TreeSet<Map.Entry<String JavaDoc, Value>>(entrySet());
1027  }
1028
1029  public String JavaDoc toString()
1030  {
1031    return "ObjectExtValue@" + System.identityHashCode(this) + "[" + _cl.getName() + "]";
1032  }
1033
1034  public void varDumpImpl(Env env,
1035                          WriteStream out,
1036                          int depth,
1037                          IdentityHashMap<Value, String JavaDoc> valueSet)
1038    throws IOException JavaDoc
1039  {
1040    out.println("object(" + getName() + ") (" + getSize() + ") {");
1041
1042    for (Map.Entry<String JavaDoc,Value> mapEntry : sortedEntrySet()) {
1043      ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry;
1044
1045      entry.varDumpImpl(env, out, depth + 1, valueSet);
1046    }
1047
1048    printDepth(out, 2 * depth);
1049
1050    out.print("}");
1051  }
1052
1053  protected void printRImpl(Env env,
1054                            WriteStream out,
1055                            int depth,
1056                            IdentityHashMap<Value, String JavaDoc> valueSet)
1057    throws IOException JavaDoc
1058  {
1059    out.print(_cl.getName());
1060    out.print(' ');
1061    out.println("Object");
1062    printDepth(out, 4 * depth);
1063    out.println("(");
1064
1065    for (Map.Entry<String JavaDoc,Value> mapEntry : sortedEntrySet()) {
1066      ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry;
1067
1068      entry.printRImpl(env, out, depth + 1, valueSet);
1069    }
1070
1071    printDepth(out, 4 * depth);
1072    out.println(")");
1073  }
1074
1075  //
1076
// Java Serialization
1077
//
1078

1079  private void writeObject(ObjectOutputStream JavaDoc out)
1080    throws IOException JavaDoc
1081  {
1082    out.writeObject(_cl.getName());
1083
1084    out.writeInt(_size);
1085    
1086    for (Map.Entry<String JavaDoc,Value> entry : entrySet()) {
1087      out.writeObject(entry.getKey());
1088      out.writeObject(entry.getValue());
1089    }
1090  }
1091  
1092  private void readObject(ObjectInputStream JavaDoc in)
1093    throws ClassNotFoundException JavaDoc, IOException JavaDoc
1094  {
1095    Env env = Env.getInstance();
1096    String JavaDoc name = (String JavaDoc) in.readObject();
1097
1098    _cl = env.findClass(name);
1099
1100    init();
1101
1102    if (_cl != null) {
1103    }
1104    else {
1105      _cl = env.getQuercus().getStdClass();
1106
1107      putField(env,
1108               "__Quercus_Class_Definition_Not_Found",
1109               new StringValueImpl(name));
1110    }
1111
1112    int size = in.readInt();
1113    
1114    for (int i = 0; i < size; i++) {
1115      putField(env, (String JavaDoc) in.readObject(), (Value) in.readObject());
1116    }
1117  }
1118  
1119  public class EntrySet extends AbstractSet<Map.Entry<String JavaDoc,Value>> {
1120    EntrySet()
1121    {
1122    }
1123
1124    public int size()
1125    {
1126      return ObjectExtValue.this.getSize();
1127    }
1128
1129    public Iterator<Map.Entry<String JavaDoc,Value>> iterator()
1130    {
1131      return new EntryIterator(ObjectExtValue.this._entries);
1132    }
1133  }
1134
1135  public static class EntryIterator
1136    implements Iterator<Map.Entry<String JavaDoc,Value>> {
1137    private final Entry []_list;
1138    private int _index;
1139
1140    EntryIterator(Entry []list)
1141    {
1142      _list = list;
1143    }
1144
1145    public boolean hasNext()
1146    {
1147      for (; _index < _list.length && _list[_index] == null; _index++) {
1148      }
1149
1150      return _index < _list.length;
1151    }
1152
1153    public Map.Entry<String JavaDoc,Value> next()
1154    {
1155      for (; _index < _list.length && _list[_index] == null; _index++) {
1156      }
1157
1158      if (_list.length <= _index)
1159        return null;
1160
1161      return _list[_index++];
1162    }
1163
1164    public void remove()
1165    {
1166      throw new UnsupportedOperationException JavaDoc();
1167    }
1168  }
1169
1170  public final static class Entry
1171    implements Map.Entry<String JavaDoc,Value>,
1172               Comparable JavaDoc<Map.Entry<String JavaDoc, Value>>
1173  {
1174    private final String JavaDoc _key;
1175    private Value _value;
1176
1177    public Entry(String JavaDoc key)
1178    {
1179      _key = key;
1180      _value = NullValue.NULL;
1181    }
1182
1183    public Entry(String JavaDoc key, Value value)
1184    {
1185      _key = key;
1186      _value = value;
1187    }
1188
1189    public Value getValue()
1190    {
1191      return _value.toValue();
1192    }
1193
1194    public String JavaDoc getKey()
1195    {
1196      return _key;
1197    }
1198
1199    public Value toValue()
1200    {
1201      // The value may be a var
1202
// XXX: need test
1203
return _value.toValue();
1204    }
1205
1206    /**
1207     * Argument used/declared as a ref.
1208     */

1209    public Var toRefVar()
1210    {
1211      Value val = _value;
1212
1213      if (val instanceof Var)
1214        return (Var) val;
1215      else {
1216        Var var = new Var(val);
1217
1218        _value = var;
1219
1220        return var;
1221      }
1222    }
1223
1224    /**
1225     * Converts to an argument value.
1226     */

1227    public Value toArgValue()
1228    {
1229      return _value.toValue();
1230    }
1231
1232    public Value setValue(Value value)
1233    {
1234      Value oldValue = toValue();
1235
1236      _value = value;
1237
1238      return oldValue;
1239    }
1240
1241    /**
1242     * Converts to a variable reference (for function arguments)
1243     */

1244    public Value toRef()
1245    {
1246      Value value = _value;
1247
1248      if (value instanceof Var)
1249        return new RefVar((Var) value);
1250      else {
1251    Var var = new Var(_value);
1252    
1253    _value = var;
1254    
1255        return new RefVar(var);
1256      }
1257    }
1258
1259    /**
1260     * Converts to a variable reference (for function arguments)
1261     */

1262    public Value toArgRef()
1263    {
1264      Value value = _value;
1265
1266      if (value instanceof Var)
1267        return new RefVar((Var) value);
1268      else {
1269    Var var = new Var(_value);
1270    
1271    _value = var;
1272    
1273        return new RefVar(var);
1274      }
1275    }
1276
1277    public Value toArg()
1278    {
1279      Value value = _value;
1280
1281      if (value instanceof Var)
1282        return value;
1283      else {
1284    Var var = new Var(_value);
1285    
1286    _value = var;
1287    
1288        return var;
1289      }
1290    }
1291
1292    public int compareTo(Map.Entry<String JavaDoc, Value> other)
1293    {
1294      if (other == null)
1295        return 1;
1296
1297      String JavaDoc thisKey = getKey();
1298      String JavaDoc otherKey = other.getKey();
1299
1300      if (thisKey == null)
1301        return otherKey == null ? 0 : -1;
1302
1303      if (otherKey == null)
1304        return 1;
1305
1306      return thisKey.compareTo(otherKey);
1307    }
1308
1309    public void varDumpImpl(Env env,
1310                            WriteStream out,
1311                            int depth,
1312                            IdentityHashMap<Value, String JavaDoc> valueSet)
1313      throws IOException JavaDoc
1314    {
1315      printDepth(out, 2 * depth);
1316      out.println("[\"" + getKey() + "\"]=>");
1317
1318      printDepth(out, 2 * depth);
1319      
1320      _value.varDump(env, out, depth, valueSet);
1321      
1322      out.println();
1323    }
1324
1325    protected void printRImpl(Env env,
1326                              WriteStream out,
1327                              int depth,
1328                              IdentityHashMap<Value, String JavaDoc> valueSet)
1329      throws IOException JavaDoc
1330    {
1331      printDepth(out, 4 * depth);
1332      out.print("[" + getKey() + "] => ");
1333      
1334      _value.printR(env, out, depth + 1, valueSet);
1335
1336      out.println();
1337    }
1338
1339    private void printDepth(WriteStream out, int depth)
1340      throws java.io.IOException JavaDoc
1341    {
1342      for (int i = 0; i < depth; i++)
1343    out.print(' ');
1344    }
1345
1346    public String JavaDoc toString()
1347    {
1348      return "ObjectExtValue.Entry[" + getKey() + "]";
1349    }
1350  }
1351}
1352
1353
Popular Tags