KickJava   Java API By Example, From Geeks To Geeks.

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


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.vfs.WriteStream;
33
34 import com.caucho.quercus.UnimplementedException;
35 import com.caucho.quercus.expr.Expr;
36 import com.caucho.quercus.function.Marshal;
37 import com.caucho.quercus.function.MarshalFactory;
38 import com.caucho.quercus.program.AbstractFunction;
39 import com.caucho.quercus.program.JavaClassDef;
40
41 import java.util.*;
42 import java.util.logging.*;
43
44 import java.lang.reflect.Array JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.ObjectInputStream JavaDoc;
47 import java.io.ObjectOutputStream JavaDoc;
48 import java.io.Serializable JavaDoc;
49
50 /**
51  * Interface for marshalled Java data structures.
52  */

53 abstract public class JavaAdapter extends ArrayValue
54   implements Serializable JavaDoc
55 {
56   private static final Logger log
57     = Logger.getLogger(JavaAdapter.class.getName());
58   
59   private Object JavaDoc _object;
60   
61   private JavaClassDef _classDef;
62   private Env _env;
63   
64   // Vars to update when matching array item is modified
65
private HashMap<Value,Value> _refs;
66   
67   protected JavaAdapter(Env env, Object JavaDoc object, JavaClassDef def)
68   {
69     _env = env;
70     _object = object;
71     _classDef = def;
72
73   }
74   
75   public Env getEnv()
76   {
77     return _env;
78   }
79   
80   public JavaClassDef getClassDef()
81   {
82     return _classDef;
83   }
84   
85   public Value wrapJava(Object JavaDoc obj)
86   {
87     return _env.wrapJava(obj);
88   }
89   
90   /**
91    * Converts to an object.
92    */

93   public Object JavaDoc toObject()
94   {
95     return null;
96   }
97
98   /**
99    * Converts to a Java object.
100    */

101   @Override JavaDoc
102   public Object JavaDoc toJavaObject()
103   {
104     return _object;
105   }
106   
107   /**
108    * Converts to a java object.
109    */

110   @Override JavaDoc
111   public Object JavaDoc toJavaObjectNotNull(Env env, Class JavaDoc type)
112   {
113     if (type.isAssignableFrom(_object.getClass())) {
114       return _object;
115     }
116     else {
117       env.warning(L.l("Can't assign {0} to {1}",
118               _object.getClass().getName(), type.getName()));
119     
120       return null;
121     }
122   }
123   
124   //
125
// Conversions
126
//
127

128   /**
129    * Converts to an object.
130    */

131   public Value toObject(Env env)
132   {
133     Value obj = env.createObject();
134
135     for (Map.Entry<Value,Value> entry : entrySet()) {
136       Value key = entry.getKey();
137
138       if (key instanceof StringValue) {
139         // XXX: intern?
140
obj.putField(env, key.toString(), entry.getValue());
141       }
142     }
143
144     return obj;
145   }
146
147   /**
148    * Converts to a java List object.
149    */

150   @Override JavaDoc
151   public Collection toJavaCollection(Env env, Class JavaDoc type)
152   {
153     Collection coll = null;
154     
155     if (type.isAssignableFrom(HashSet.class)) {
156       coll = new HashSet();
157     }
158     else if (type.isAssignableFrom(TreeSet.class)) {
159       coll = new TreeSet();
160     }
161     else {
162       try {
163         coll = (Collection) type.newInstance();
164       }
165       catch (Throwable JavaDoc e) {
166         log.log(Level.FINE, e.toString(), e);
167         env.warning(L.l("Can't assign array to {0}", type.getName()));
168
169         return null;
170       }
171     }
172     
173    for (Map.Entry entry : objectEntrySet()) {
174       coll.add(entry.getValue());
175     }
176
177     return coll;
178   }
179   
180   /**
181    * Converts to a java List object.
182    */

183   @Override JavaDoc
184   public List toJavaList(Env env, Class JavaDoc type)
185   {
186     List list = null;
187     
188     if (type.isAssignableFrom(ArrayList.class)) {
189       list = new ArrayList();
190     }
191     else if (type.isAssignableFrom(LinkedList.class)) {
192       list = new LinkedList();
193     }
194     else if (type.isAssignableFrom(Vector.class)) {
195       list = new Vector();
196     }
197     else {
198       try {
199         list = (List) type.newInstance();
200       }
201       catch (Throwable JavaDoc e) {
202         log.log(Level.FINE, e.toString(), e);
203         env.warning(L.l("Can't assign array to {0}", type.getName()));
204
205         return null;
206       }
207     }
208     
209    for (Map.Entry entry : objectEntrySet()) {
210       list.add(entry.getValue());
211     }
212
213     return list;
214   }
215   
216   /**
217    * Converts to a java object.
218    */

219   @Override JavaDoc
220   public Map toJavaMap(Env env, Class JavaDoc type)
221   {
222     Map map = null;
223
224     if (type.isAssignableFrom(TreeMap.class)) {
225       map = new TreeMap();
226     }
227     else if (type.isAssignableFrom(LinkedHashMap.class)) {
228       map = new LinkedHashMap();
229     }
230     else {
231       try {
232         map = (Map) type.newInstance();
233       }
234       catch (Throwable JavaDoc e) {
235         log.log(Level.FINE, e.toString(), e);
236
237         env.warning(L.l("Can't assign array to {0}", type.getName()));
238
239         return null;
240       }
241     }
242
243     for (Map.Entry entry : objectEntrySet()) {
244       map.put(entry.getKey(), entry.getValue());
245     }
246
247     return map;
248   }
249
250   /**
251    * Copy for assignment.
252    */

253   abstract public Value copy();
254
255   /**
256    * Copy for serialization
257    */

258   public Value copy(Env env, IdentityHashMap<Value,Value> map)
259   {
260     throw new UnsupportedOperationException JavaDoc();
261   }
262
263   /**
264    * Returns the size.
265    */

266   abstract public int getSize();
267
268   /**
269    * Clears the array
270    */

271   abstract public void clear();
272
273   /**
274    * Adds a new value.
275    */

276   public final Value put(Value value)
277   {
278     return put(createTailKey(), value);
279   }
280   
281   /**
282    * Adds a new value.
283    */

284   public final Value put(Value key, Value value)
285   {
286     Value retValue = putImpl(key, value);
287     
288     if (_refs == null)
289       _refs = new HashMap<Value,Value>();
290     
291     if (value instanceof Var) {
292       Var var = (Var) value;
293       
294       var.setReference();
295       
296       _refs.put(key, var);
297     }
298     else {
299       Value ref = _refs.get(key);
300       
301       if (ref != null)
302         ref.set(value);
303     }
304
305     return retValue;
306   }
307   
308   /**
309    * Adds a new value.
310    */

311   abstract public Value putImpl(Value key, Value value);
312
313   /**
314    * Add to front.
315    */

316   public ArrayValue unshift(Value value)
317   {
318     throw new UnsupportedOperationException JavaDoc();
319   }
320
321   /**
322    * Splices.
323    */

324   public ArrayValue splice(int begin, int end, ArrayValue replace)
325   {
326     throw new UnsupportedOperationException JavaDoc();
327   }
328
329   /**
330    * Returns the value as an argument which may be a reference.
331    */

332   public Value getArg(Value index)
333   {
334     throw new UnsupportedOperationException JavaDoc();
335   }
336
337   /**
338    * Sets the array ref.
339    */

340   public Value putRef()
341   {
342     throw new UnsupportedOperationException JavaDoc();
343   }
344
345   /**
346    * Creatse a tail index.
347    */

348   abstract public Value createTailKey();
349
350   /**
351    * Returns a union of this array and the rValue as array.
352    * If the rValue is not an array, the returned union contains the elements
353    * of this array only.
354    *
355    * To append a value to this ArrayValue use the {@link #put(Value)} method.
356    */

357   public Value add(Value rValue)
358   {
359     rValue = rValue.toValue();
360
361     if (! (rValue instanceof ArrayValue))
362       return copy();
363
364     ArrayValue rArray = (ArrayValue) rValue;
365
366     ArrayValue result = new ArrayValueImpl(rArray);
367
368     for (Map.Entry<Value,Value> entry : entrySet()) {
369       result.put(entry.getKey(), entry.getValue());
370     }
371
372     return result;
373   }
374
375   /**
376    * Returns the field values.
377    */

378   public Collection<Value> getIndices()
379   {
380     throw new UnsupportedOperationException JavaDoc();
381   }
382
383   /**
384    * Returns the field keys.
385    */

386   public Value []getKeyArray()
387   {
388     int size = getSize();
389
390     if (size == 0)
391       return NULL_VALUE_ARRAY;
392
393     Value []keys = new Value[size];
394
395     int i = 0;
396     for (Map.Entry<Value,Value> entry : entrySet()) {
397       keys[i++] = entry.getKey();
398     }
399
400     return keys;
401   }
402
403   /**
404    * Returns the field values.
405    */

406   public Value []getValueArray(Env env)
407   {
408     //XXX: alias?
409
return valuesToArray();
410   }
411
412   /**
413    * Gets a new value.
414    */

415   abstract public Value get(Value key);
416
417   /**
418    * Removes a value.
419    */

420   abstract public Value remove(Value key);
421
422   /**
423    * Returns the array ref.
424    */

425   public Var getRef(Value index)
426   {
427     Var var = new JavaAdapterVar(this, index);
428     
429     if (_refs == null)
430       _refs = new HashMap<Value,Value>();
431
432     _refs.put(index, var);
433     
434     return var;
435   }
436
437   /**
438    * Returns an iterator of the entries.
439    */

440   public Set<Value> keySet()
441   {
442     throw new UnsupportedOperationException JavaDoc();
443   }
444
445   /**
446    * Returns a set of all the entries.
447    */

448   abstract public Set<Map.Entry<Value,Value>> entrySet();
449   
450   /**
451    * Returns a java object set of all the entries.
452    */

453   abstract public Set<Map.Entry> objectEntrySet();
454   
455   /**
456    * Returns a collection of the values.
457    */

458   public Collection<Value> values()
459   {
460     throw new UnimplementedException();
461   }
462
463   /**
464    * Appends as an argument - only called from compiled code
465    *
466    * XXX: change name to appendArg
467    */

468   public ArrayValue append(Value key, Value value)
469   {
470     put(key, value);
471
472     return this;
473   }
474
475
476   /**
477    * Pops the top value.
478    */

479   public Value pop()
480   {
481     throw new UnsupportedOperationException JavaDoc();
482   }
483
484   /**
485    * Shuffles the array
486    */

487   public void shuffle()
488   {
489     throw new UnsupportedOperationException JavaDoc();
490   }
491
492   /**
493    * Returns the head.
494    */

495   public Entry getHead()
496   {
497     throw new UnsupportedOperationException JavaDoc();
498   }
499
500   /**
501    * Returns the tail.
502    */

503   protected Entry getTail()
504   {
505     throw new UnsupportedOperationException JavaDoc();
506   }
507
508   /**
509    * Returns the current value.
510    */

511   public Value current()
512   {
513     throw new UnsupportedOperationException JavaDoc();
514   }
515
516   /**
517    * Returns the current key
518    */

519   public Value key()
520   {
521     throw new UnsupportedOperationException JavaDoc();
522   }
523
524   /**
525    * Returns true if there are more elements.
526    */

527   public boolean hasCurrent()
528   {
529     throw new UnsupportedOperationException JavaDoc();
530   }
531
532   /**
533    * Returns the next value.
534    */

535   public Value next()
536   {
537     throw new UnsupportedOperationException JavaDoc();
538   }
539
540   /**
541    * Returns the previous value.
542    */

543   public Value prev()
544   {
545     throw new UnsupportedOperationException JavaDoc();
546   }
547
548   /**
549    * The each iterator
550    */

551   public Value each()
552   {
553     throw new UnsupportedOperationException JavaDoc();
554   }
555
556   /**
557    * Returns the first value.
558    */

559   public Value reset()
560   {
561     throw new UnsupportedOperationException JavaDoc();
562   }
563
564   /**
565    * Returns the last value.
566    */

567   public Value end()
568   {
569     throw new UnsupportedOperationException JavaDoc();
570   }
571
572   /**
573    * Returns the corresponding key if this array contains the given value
574    *
575    * @param value the value to search for in the array
576    *
577    * @return the key if it is found in the array, NULL otherwise
578    *
579    * @throws NullPointerException
580    */

581   public Value contains(Value value)
582   {
583     for (Map.Entry<Value,Value> entry : entrySet()) {
584       if (entry.getValue().equals(value))
585         return entry.getKey();
586     }
587
588     return NullValue.NULL;
589   }
590
591   /**
592    * Returns the corresponding key if this array contains the given value
593    *
594    * @param value the value to search for in the array
595    *
596    * @return the key if it is found in the array, NULL otherwise
597    *
598    * @throws NullPointerException
599    */

600   public Value containsStrict(Value value)
601   {
602     throw new UnsupportedOperationException JavaDoc();
603   }
604
605   /**
606    * Returns the corresponding valeu if this array contains the given key
607    *
608    * @param key the key to search for in the array
609    *
610    * @return the value if it is found in the array, NULL otherwise
611    *
612    * @throws NullPointerException
613    */

614   public Value containsKey(Value key)
615   {
616     throw new UnsupportedOperationException JavaDoc();
617   }
618
619   /**
620    * Returns an object array of this array. This is a copy of this object's
621    * backing structure. Null elements are not included.
622    *
623    * @return an object array of this array
624    */

625   public Map.Entry<Value, Value>[] toEntryArray()
626   {
627     throw new UnsupportedOperationException JavaDoc();
628   }
629
630   /**
631    * Sorts this array based using the passed Comparator
632    *
633    * @param comparator the comparator for sorting the array
634    * @param resetKeys true if the keys should not be preserved
635    * @param strict true if alphabetic keys should not be preserved
636    */

637   public void sort(Comparator<Map.Entry<Value, Value>> comparator,
638                    boolean resetKeys, boolean strict)
639   {
640     Map.Entry<Value,Value>[] entries = new Map.Entry[getSize()];
641
642     int i = 0;
643     for (Map.Entry<Value,Value> entry : entrySet()) {
644       entries[i++] = entry;
645     }
646
647     Arrays.sort(entries, comparator);
648
649     clear();
650
651     long base = 0;
652
653     if (! resetKeys)
654       strict = false;
655
656     for (int j = 0; j < entries.length; j++) {
657       Value key = entries[j].getKey();
658
659       if (resetKeys && (! (key instanceof StringValue) || strict))
660         put(LongValue.create(base++), entries[j].getValue());
661       else
662         put(entries[j].getKey(), entries[j].getValue());
663     }
664   }
665
666   /**
667    * Serializes the value.
668    */

669   public void serialize(StringBuilder JavaDoc sb)
670   {
671     throw new UnsupportedOperationException JavaDoc();
672   }
673
674   /**
675    * Exports the value.
676    */

677   public void varExport(StringBuilder JavaDoc sb)
678   {
679     throw new UnsupportedOperationException JavaDoc();
680   }
681
682   /**
683    * Resets all numerical keys with the first index as base
684    *
685    * @param base the initial index
686    * @param strict if true, string keys are also reset
687    */

688   public boolean keyReset(long base, boolean strict)
689   {
690     throw new UnsupportedOperationException JavaDoc();
691   }
692
693   /**
694    * Takes the values of this array and puts them in a java array
695    */

696   public Value[] valuesToArray()
697   {
698     Value[] values = new Value[getSize()];
699     
700     int i = 0;
701     
702     for (Map.Entry<Value,Value> entry : entrySet()) {
703       values[i++] = entry.getValue();
704     }
705     
706     return values;
707   }
708
709   /**
710    * Takes the values of this array, unmarshalls them to objects of type
711    * <i>elementType</i>, and puts them in a java array.
712    */

713   @Override JavaDoc
714   public Object JavaDoc valuesToArray(Env env, Class JavaDoc elementType)
715   {
716     int size = getSize();
717
718     Object JavaDoc array = Array.newInstance(elementType, size);
719
720     MarshalFactory factory = env.getModuleContext().getMarshalFactory();
721     Marshal elementMarshal = factory.create(elementType);
722
723     int i = 0;
724
725     for (Map.Entry<Value, Value> entry : entrySet()) {
726       Array.set(array, i++, elementMarshal.marshal(env,
727                                                    entry.getValue(),
728                                                    elementType));
729     }
730
731     return array;
732   }
733   
734   @Override JavaDoc
735   public Value getField(Env env, String JavaDoc name)
736   {
737     return _classDef.getField(env, _object, name);
738   }
739
740   @Override JavaDoc
741   public Value putField(Env env,
742                         String JavaDoc name,
743                         Value value)
744   {
745     return _classDef.putField(env, _object, name, value);
746   }
747
748   /**
749    * Returns the class name.
750    */

751   public String JavaDoc getName()
752   {
753     return _classDef.getName();
754   }
755   
756   public boolean isA(String JavaDoc name)
757   {
758     return _classDef.isA(name);
759   }
760
761   /**
762    * Returns the method.
763    */

764   public AbstractFunction findFunction(String JavaDoc methodName)
765   {
766     return _classDef.findFunction(methodName);
767   }
768
769   /**
770    * Evaluates a method.
771    */

772   public Value callMethod(Env env, String JavaDoc methodName, Expr []args)
773   {
774     return _classDef.callMethod(env, _object, methodName, args);
775   }
776
777   /**
778    * Evaluates a method.
779    */

780   public Value callMethod(Env env, String JavaDoc methodName, Value []args)
781   {
782     return _classDef.callMethod(env, _object, methodName, args);
783   }
784
785   /**
786    * Evaluates a method.
787    */

788   public Value callMethod(Env env, String JavaDoc methodName)
789   {
790     return _classDef.callMethod(env, _object, methodName);
791   }
792
793   /**
794    * Evaluates a method.
795    */

796   public Value callMethod(Env env, String JavaDoc methodName, Value a1)
797   {
798     return _classDef.callMethod(env, _object, methodName, a1);
799   }
800
801   /**
802    * Evaluates a method.
803    */

804   public Value callMethod(Env env, String JavaDoc methodName, Value a1, Value a2)
805   {
806     return _classDef.callMethod(env, _object, methodName, a1, a2);
807   }
808
809   /**
810    * Evaluates a method.
811    */

812   public Value callMethod(Env env, String JavaDoc methodName,
813                           Value a1, Value a2, Value a3)
814   {
815     return _classDef.callMethod(env, _object, methodName, a1, a2, a3);
816   }
817
818   /**
819    * Evaluates a method.
820    */

821   public Value callMethod(Env env, String JavaDoc methodName,
822                           Value a1, Value a2, Value a3, Value a4)
823   {
824     return _classDef.callMethod(env, _object, methodName, a1, a2, a3, a4);
825   }
826
827   /**
828    * Evaluates a method.
829    */

830   public Value callMethod(Env env, String JavaDoc methodName,
831                           Value a1, Value a2, Value a3, Value a4, Value a5)
832   {
833     return _classDef.callMethod(env, _object, methodName, a1, a2, a3, a4, a5);
834   }
835
836   /**
837    * Evaluates a method.
838    */

839   public Value callMethodRef(Env env, String JavaDoc methodName, Expr []args)
840   {
841     return _classDef.callMethod(env, _object, methodName, args);
842   }
843
844   /**
845    * Evaluates a method.
846    */

847   public Value callMethodRef(Env env, String JavaDoc methodName, Value []args)
848   {
849     return _classDef.callMethod(env, _object, methodName, args);
850   }
851
852   /**
853    * Evaluates a method.
854    */

855   public Value callMethodRef(Env env, String JavaDoc methodName)
856   {
857     return _classDef.callMethod(env, _object, methodName);
858   }
859
860   /**
861    * Evaluates a method.
862    */

863   public Value callMethodRef(Env env, String JavaDoc methodName, Value a1)
864   {
865     return _classDef.callMethod(env, _object, methodName, a1);
866   }
867
868   /**
869    * Evaluates a method.
870    */

871   public Value callMethodRef(Env env, String JavaDoc methodName, Value a1, Value a2)
872   {
873     return _classDef.callMethod(env, _object, methodName, a1, a2);
874   }
875
876   /**
877    * Evaluates a method.
878    */

879   public Value callMethodRef(Env env, String JavaDoc methodName,
880                           Value a1, Value a2, Value a3)
881   {
882     return _classDef.callMethod(env, _object, methodName, a1, a2, a3);
883   }
884
885   /**
886    * Evaluates a method.
887    */

888   public Value callMethodRef(Env env, String JavaDoc methodName,
889                           Value a1, Value a2, Value a3, Value a4)
890   {
891     return _classDef.callMethod(env, _object, methodName, a1, a2, a3, a4);
892   }
893
894   /**
895    * Evaluates a method.
896    */

897   public Value callMethodRef(Env env, String JavaDoc methodName,
898                           Value a1, Value a2, Value a3, Value a4, Value a5)
899   {
900     return _classDef.callMethod(env, _object, methodName, a1, a2, a3, a4, a5);
901   }
902   
903   @Override JavaDoc
904   public void varDumpImpl(Env env,
905                           WriteStream out,
906                           int depth,
907                           IdentityHashMap<Value, String JavaDoc> valueSet)
908     throws IOException JavaDoc
909   {
910     out.println("array(" + getSize() + ") {");
911
912     int nestedDepth = depth + 1;
913
914     for (Map.Entry<Value,Value> mapEntry : entrySet()) {
915       printDepth(out, nestedDepth * 2);
916       out.print("[");
917
918       Value key = mapEntry.getKey();
919       
920       if (key.isString())
921         out.print("\"" + key + "\"");
922       else
923         out.print(key);
924
925       out.println("]=>");
926
927       printDepth(out, nestedDepth * 2);
928       
929       if (_refs != null && _refs.get(key) != null)
930         out.print('&');
931       
932       mapEntry.getValue().varDump(env, out, nestedDepth, valueSet);
933
934       out.println();
935     }
936
937     printDepth(out, 2 * depth);
938
939     out.print("}");
940   }
941
942   @Override JavaDoc
943   protected void printRImpl(Env env,
944                             WriteStream out,
945                             int depth,
946                             IdentityHashMap<Value, String JavaDoc> valueSet)
947     throws IOException JavaDoc
948   {
949     out.println("Array");
950     printDepth(out, 8 * depth);
951     out.println("(");
952     
953     for (Map.Entry<Value,Value> mapEntry : entrySet()) {
954       printDepth(out, 8 * depth);
955
956       out.print(" [");
957       out.print(mapEntry.getKey());
958       out.print("] => ");
959
960       Value value = mapEntry.getValue();
961
962       if (value != null)
963         value.printR(env, out, depth + 1, valueSet);
964       out.println();
965     }
966
967     printDepth(out, 8 * depth);
968     out.println(")");
969   }
970   
971   //
972
// Java Serialization
973
//
974

975   private void writeObject(ObjectOutputStream JavaDoc out)
976     throws IOException JavaDoc
977   {
978     out.writeObject(_object);
979     out.writeObject(_classDef.getName());
980   }
981   
982   private void readObject(ObjectInputStream JavaDoc in)
983     throws ClassNotFoundException JavaDoc, IOException JavaDoc
984   {
985     _env = Env.getInstance();
986     
987     _object = in.readObject();
988     _classDef = _env.getJavaClassDefinition((String JavaDoc) in.readObject());
989   }
990   
991   /**
992    * Converts to a string.
993    */

994   public String JavaDoc toString()
995   {
996     return String.valueOf(_object);
997   }
998 }
999
1000
Popular Tags