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 org.omg.CORBA.LocalObject; 44: import org.omg.CORBA.MARSHAL; 45: 46: import java.io.Serializable; 47: import java.util.Comparator; 48: import java.util.HashMap; 49: import java.util.IdentityHashMap; 50: import java.util.Iterator; 51: import java.util.Map; 52: import java.util.TreeMap; 53: import java.util.TreeSet; 54: 55: /** 56: * Our implementation of the sending context runtime. 57: * 58: * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 59: */ 60: public class gnuRuntime 61: extends LocalObject 62: implements org.omg.SendingContext.RunTime 63: { 64: /** 65: * The data entry about the object that was written. 66: */ 67: static class Entry 68: { 69: /** 70: * The stream position, where the object was written. 71: */ 72: int at; 73: 74: /** 75: * The object that was written. 76: */ 77: Object object; 78: 79: public String toString() 80: { 81: return object + "[" + at + "] "+object.getClass().getName(); 82: } 83: } 84: 85: /** 86: * The instruction that the actual object is stored at different location. 87: * Used when processing chunked data where positions shifts due removing the 88: * chunking tags. 89: */ 90: static class Redirection 91: extends Entry 92: { 93: public String toString() 94: { 95: return "->" + at; 96: } 97: } 98: 99: /** 100: * Use serialVersionUID for interoperability. 101: */ 102: private static final long serialVersionUID = 1; 103: 104: /** 105: * The history of the written objects, maps object to records. The different 106: * objects must be treated as different regardless that .equals returns. 107: */ 108: private Map sh_objects = new IdentityHashMap(); 109: 110: /** 111: * The written repository Ids that can be shared. 112: */ 113: private Map sh_ids = new TreeMap(new Comparator() 114: { 115: public int compare(Object a, Object b) 116: { 117: if (a instanceof String && b instanceof String) 118: // Comparing string with string. 119: return ((String) a).compareTo((String) b); 120: else if (a instanceof String[] && b instanceof String[]) 121: { 122: // Comparing array with array. 123: String[] sa = (String[]) a; 124: String[] sb = (String[]) b; 125: 126: if (sa.length != sb.length) 127: return sa.length - sb.length; 128: else 129: { 130: int c; 131: for (int i = 0; i < sa.length; i++) 132: { 133: c = sa[i].compareTo(sb[i]); 134: if (c != 0) 135: return c; 136: } 137: return 0; 138: } 139: } 140: else 141: // Comparing string with array. 142: return a instanceof String ? 1 : -1; 143: } 144: }); 145: 146: /** 147: * The history of the written objects, maps positions to records. The 148: * different objects must be treated as different regardless that .equals 149: * returns. 150: */ 151: private Map positions = new HashMap(); 152: 153: /** 154: * The Codebase. 155: */ 156: private String codebase; 157: 158: /** 159: * The pre-created instance of the object being written (avoid 160: * re-instantiation). 161: */ 162: public Serializable target; 163: 164: /** 165: * Create Runtime. 166: * 167: * @param a_id a repository Id, if only one Id was specified in the stream. 168: * @param a_ids a repository Ids, if the multiple Ids were specified in te 169: * stream. 170: * @param a_codabase a codebase, if it was specified in the stream. 171: */ 172: public gnuRuntime(String a_codebase, Object a_target) 173: { 174: if (a_target instanceof Serializable) 175: target = (Serializable) a_target; 176: 177: codebase = a_codebase; 178: } 179: 180: /** 181: * Mark the given object as written at the given position. 182: */ 183: public void objectWritten(Object object, int at) 184: { 185: if (object == null || at < 0) 186: return; // No positional information provided. 187: if (sh_objects.containsKey(object)) 188: throw new AssertionError("Repetetive writing of the same object " 189: + object + " at " + at + dump()); 190: 191: Entry e = new Entry(); 192: e.at = at; 193: e.object = object; 194: 195: sh_objects.put(object, e); 196: positions.put(new Integer(at), e); 197: } 198: 199: /** 200: * Check if the object is already written. 201: * 202: * @return the position, at that the object is allready written or -1 if it is 203: * not yet written. 204: */ 205: public int isWrittenAt(Object x) 206: { 207: Entry e = (Entry) sh_objects.get(x); 208: return e == null ? -1 : e.at; 209: } 210: 211: /** 212: * Set redirection, indicating that the object, searched at the p_searched 213: * position can be actually found at the p_present position. 214: */ 215: public void redirect(int p_searched, int p_present) 216: { 217: Redirection redirection = new Redirection(); 218: redirection.at = p_present; 219: positions.put(new Integer(p_searched), redirection); 220: } 221: 222: /** 223: * Get the object, written at the given position. This returs both shared 224: * objects and repository Ids. 225: * 226: * @return the position, at that the object is allready written. 227: * 228: * @throws MARSHAL if there is no object written at that position. 229: */ 230: public Object isObjectWrittenAt(int x, int offset) 231: { 232: Entry e = (Entry) positions.get(new Integer(x)); 233: if (e instanceof Redirection) 234: return isObjectWrittenAt(e.at, offset); 235: else if (e != null) 236: return e.object; 237: else 238: { 239: MARSHAL m = new MARSHAL("No object was written at " + x + 240: " (offset " + offset + ") r " + this + dump()); 241: m.minor = Minor.Graph; 242: throw m; 243: } 244: } 245: 246: /** 247: * Mark the given object as written at the given position. 248: */ 249: public void singleIdWritten(String id, int at) 250: { 251: if (sh_ids.containsKey(id)) 252: throw new InternalError("Repetetive writing of the same string " + 253: id + dump()); 254: 255: Entry e = new Entry(); 256: e.at = at; 257: e.object = id; 258: 259: sh_ids.put(id, e); 260: positions.put(new Integer(at), e); 261: } 262: 263: /** 264: * Mark the given object as written at the given position. 265: */ 266: public void multipleIdsWritten(String[] ids, int at) 267: { 268: if (sh_ids.containsKey(ids)) 269: throw new InternalError("Repetetive writing of the same string " + 270: ids + dump()); 271: 272: Entry e = new Entry(); 273: e.at = at; 274: e.object = ids; 275: 276: sh_ids.put(ids, e); 277: positions.put(new Integer(at), e); 278: } 279: 280: /** 281: * Check if the object is already written. 282: * 283: * @return the position, at that the object is allready written or -1 if it is 284: * not yet written. 285: */ 286: public int idWrittenAt(Object x) 287: { 288: Entry e = (Entry) sh_ids.get(x); 289: return e == null ? -1 : e.at; 290: } 291: 292: /** 293: * Get the codebase. 294: */ 295: public String getCodeBase() 296: { 297: return codebase; 298: } 299: 300: /** 301: * Set the codebase, preserving the old value if the passed parameter is null 302: * and forming the space delimited list if both new and old values are not 303: * null. 304: */ 305: public void addCodeBase(String base) 306: { 307: if (base != null) 308: { 309: if (codebase == null) 310: codebase = base; 311: else 312: codebase = codebase + " " + base; 313: } 314: } 315: 316: /** 317: * Dump all objects that are currently stored. 318: */ 319: public String dump() 320: { 321: StringBuffer b = new StringBuffer(" Stream content: \n"); 322: 323: // Sort by position. 324: TreeSet t = new TreeSet(positions.keySet()); 325: Iterator p = t.iterator(); 326: 327: while (p.hasNext()) 328: { 329: Object k = p.next(); 330: b.append(" " + k + ": " + ((Entry) positions.get(k)).toString() 331: + "\n"); 332: } 333: return b.toString(); 334: } 335: 336: }