Frames | No Frames |
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: }