OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / CORBA / CDR / gnuRuntime.java
1 /* gnuRuntime.java --
2    Copyright (C) 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package gnu.CORBA.CDR;
40
41 import gnu.CORBA.Minor;
42
43 import gnu.java.lang.CPStringBuilder;
44
45 import org.omg.CORBA.LocalObject;
46 import org.omg.CORBA.MARSHAL;
47
48 import java.io.Serializable;
49 import java.util.Comparator;
50 import java.util.HashMap;
51 import java.util.IdentityHashMap;
52 import java.util.Iterator;
53 import java.util.Map;
54 import java.util.TreeMap;
55 import java.util.TreeSet;
56
57 /**
58  * Our implementation of the sending context runtime.
59  * 
60  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
61  */
62 public class gnuRuntime
63   extends LocalObject
64   implements org.omg.SendingContext.RunTime
65 {
66   /**
67    * The data entry about the object that was written.
68    */
69   static class Entry
70   {
71     /**
72      * The stream position, where the object was written.
73      */
74     int at;
75
76     /**
77      * The object that was written.
78      */
79     Object object;
80
81     public String toString()
82     {
83       return object + "[" + at + "] "+object.getClass().getName();
84     }
85   }
86
87   /**
88    * The instruction that the actual object is stored at different location.
89    * Used when processing chunked data where positions shifts due removing the
90    * chunking tags.
91    */
92   static class Redirection
93     extends Entry
94   {
95     public String toString()
96     {
97       return "->" + at;
98     }
99   }
100
101   /**
102    * Use serialVersionUID for interoperability.
103    */
104   private static final long serialVersionUID = 1;
105
106   /**
107    * The history of the written objects, maps object to records. The different
108    * objects must be treated as different regardless that .equals returns.
109    */
110   private Map sh_objects = new IdentityHashMap();
111
112   /**
113    * The written repository Ids that can be shared.
114    */
115   private Map sh_ids = new TreeMap(new Comparator()
116   {
117     public int compare(Object a, Object b)
118     {
119       if (a instanceof String && b instanceof String)
120         // Comparing string with string.
121         return ((String) a).compareTo((String) b);
122       else if (a instanceof String[] && b instanceof String[])
123         {
124           // Comparing array with array.
125           String[] sa = (String[]) a;
126           String[] sb = (String[]) b;
127
128           if (sa.length != sb.length)
129             return sa.length - sb.length;
130           else
131             {
132               int c;
133               for (int i = 0; i < sa.length; i++)
134                 {
135                   c = sa[i].compareTo(sb[i]);
136                   if (c != 0)
137                     return c;
138                 }
139               return 0;
140             }
141         }
142       else
143         // Comparing string with array.
144         return a instanceof String ? 1 : -1;
145     }
146   });
147
148   /**
149    * The history of the written objects, maps positions to records. The
150    * different objects must be treated as different regardless that .equals
151    * returns.
152    */
153   private Map positions = new HashMap();
154
155   /**
156    * The Codebase.
157    */
158   private String codebase;
159
160   /**
161    * The pre-created instance of the object being written (avoid
162    * re-instantiation).
163    */
164   public Serializable target;
165
166   /**
167    * Create Runtime.
168    * 
169    * @param a_id a repository Id, if only one Id was specified in the stream.
170    * @param a_ids a repository Ids, if the multiple Ids were specified in te
171    * stream.
172    * @param a_codebase a codebase, if it was specified in the stream.
173    */
174   public gnuRuntime(String a_codebase, Object a_target)
175   {
176     if (a_target instanceof Serializable)
177       target = (Serializable) a_target;
178
179     codebase = a_codebase;
180   }
181
182   /**
183    * Mark the given object as written at the given position.
184    */
185   public void objectWritten(Object object, int at)
186   {
187     if (object == null || at < 0)
188       return; // No positional information provided.
189     if (sh_objects.containsKey(object))
190       throw new AssertionError("Repetetive writing of the same object "
191         + object + " at " + at + dump());
192
193     Entry e = new Entry();
194     e.at = at;
195     e.object = object;
196
197     sh_objects.put(object, e);
198     positions.put(new Integer(at), e);
199   }
200
201   /**
202    * Check if the object is already written.
203    * 
204    * @return the position, at that the object is allready written or -1 if it is
205    * not yet written.
206    */
207   public int isWrittenAt(Object x)
208   {
209     Entry e = (Entry) sh_objects.get(x);
210     return e == null ? -1 : e.at;
211   }
212
213   /**
214    * Set redirection, indicating that the object, searched at the p_searched
215    * position can be actually found at the p_present position.
216    */
217   public void redirect(int p_searched, int p_present)
218   {
219     Redirection redirection = new Redirection();
220     redirection.at = p_present;
221     positions.put(new Integer(p_searched), redirection);
222   }
223
224   /**
225    * Get the object, written at the given position. This returs both shared
226    * objects and repository Ids.
227    * 
228    * @return the position, at that the object is allready written.
229    * 
230    * @throws MARSHAL if there is no object written at that position.
231    */
232   public Object isObjectWrittenAt(int x, int offset)
233   {
234     Entry e = (Entry) positions.get(new Integer(x));
235     if (e instanceof Redirection)
236       return isObjectWrittenAt(e.at, offset);
237     else if (e != null)
238       return e.object;
239     else
240       {
241         MARSHAL m = new MARSHAL("No object was written at " + x + 
242           " (offset " + offset + ") r " + this + dump());
243         m.minor = Minor.Graph;
244         throw m;
245       }
246   }
247
248   /**
249    * Mark the given object as written at the given position.
250    */
251   public void singleIdWritten(String id, int at)
252   {
253     if (sh_ids.containsKey(id))
254       throw new InternalError("Repetetive writing of the same string " +
255         id + dump());
256
257     Entry e = new Entry();
258     e.at = at;
259     e.object = id;
260
261     sh_ids.put(id, e);
262     positions.put(new Integer(at), e);
263   }
264
265   /**
266    * Mark the given object as written at the given position.
267    */
268   public void multipleIdsWritten(String[] ids, int at)
269   {
270     if (sh_ids.containsKey(ids))
271       throw new InternalError("Repetetive writing of the same string " + 
272         ids + dump());
273
274     Entry e = new Entry();
275     e.at = at;
276     e.object = ids;
277
278     sh_ids.put(ids, e);
279     positions.put(new Integer(at), e);
280   }
281
282   /**
283    * Check if the object is already written.
284    * 
285    * @return the position, at that the object is allready written or -1 if it is
286    * not yet written.
287    */
288   public int idWrittenAt(Object x)
289   {
290     Entry e = (Entry) sh_ids.get(x);
291     return e == null ? -1 : e.at;
292   }
293
294   /**
295    * Get the codebase.
296    */
297   public String getCodeBase()
298   {
299     return codebase;
300   }
301
302   /**
303    * Set the codebase, preserving the old value if the passed parameter is null
304    * and forming the space delimited list if both new and old values are not
305    * null.
306    */
307   public void addCodeBase(String base)
308   {
309     if (base != null)
310       {
311         if (codebase == null)
312           codebase = base;
313         else
314           codebase = codebase + " " + base;
315       }
316   }
317
318   /**
319    * Dump all objects that are currently stored.
320    */
321   public String dump()
322   {
323     CPStringBuilder b = new CPStringBuilder(" Stream content: \n");
324
325     // Sort by position.
326     TreeSet t = new TreeSet(positions.keySet());
327     Iterator p = t.iterator();
328
329     while (p.hasNext())
330       {
331         Object k = p.next();
332         b.append("     " + k + ": " + ((Entry) positions.get(k)).toString()
333           + "\n");
334       }
335     return b.toString();
336   }
337
338 }