memoryimpl cleanup (it now passes all the JMI TCK tests) BLD200210240100
authormmatula@netbeans.org
Mon, 21 Oct 2002 17:44:29 +0000
changeset 1100781fd90b97b2
parent 1099 409feb9fba6f
child 1101 35064f1d54ea
memoryimpl cleanup (it now passes all the JMI TCK tests)
mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedIndexImpl.java
mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedOrderedIndexImpl.java
mdr/src/org/netbeans/mdr/persistence/memoryimpl/PrimaryIndexImpl.java
mdr/src/org/netbeans/mdr/persistence/memoryimpl/SinglevaluedIndexImpl.java
mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageFactoryImpl.java
mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageImpl.java
mdr/src/org/netbeans/mdr/util/TransactionMutex.java
     1.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedIndexImpl.java	Mon Oct 21 10:56:35 2002 +0000
     1.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedIndexImpl.java	Mon Oct 21 17:44:29 2002 +0000
     1.3 @@ -17,13 +17,14 @@
     1.4  import java.io.*;
     1.5  
     1.6  import org.netbeans.mdr.util.*;
     1.7 +import org.netbeans.mdr.util.IOUtils;
     1.8  
     1.9  /** Default memory implementation of {@link
    1.10   *  org.netbeans.mdr.persistence.MultivaluedIndex} using 
    1.11   *  {@link java.util.Hashtable}.
    1.12   *
    1.13   * <p>[PENDING]: {@link #isUnique()} is ignored when adding new values.
    1.14 - * @author  Pavel Buzek
    1.15 + * @author  Pavel Buzek, Martin Matula
    1.16   * @version 
    1.17   */
    1.18  public class MultivaluedIndexImpl implements MultivaluedIndex, Streamable {
    1.19 @@ -36,7 +37,7 @@
    1.20      protected Storage.EntryType keyType;
    1.21      protected Storage.EntryType valueType;
    1.22      protected boolean unique;
    1.23 -    protected Hashtable entries = new Hashtable (11);
    1.24 +    protected Map entries;
    1.25      
    1.26      protected MultivalueLog transLog = new MultivalueLog (this);
    1.27      
    1.28 @@ -50,6 +51,7 @@
    1.29          this.keyType = keyType;
    1.30          this.valueType = valueType;
    1.31          this.unique = unique;
    1.32 +        entries = new HashMap();
    1.33      }
    1.34  
    1.35      /** Constructor used when restoring the streamable index from a stream. */
    1.36 @@ -72,7 +74,7 @@
    1.37          return this.keyType;
    1.38      }
    1.39      
    1.40 -    public boolean remove(Object key) throws StorageException {
    1.41 +    public synchronized boolean remove(Object key) throws StorageException {
    1.42          Object value = entries.remove(key);
    1.43          if (value != null) {
    1.44              transLog.logRemoveKey(key, value);
    1.45 @@ -81,14 +83,14 @@
    1.46              return false;
    1.47      }
    1.48  
    1.49 -    public java.util.Set keySet() throws StorageException {
    1.50 +    public synchronized java.util.Set keySet() throws StorageException {
    1.51          return entries.keySet();
    1.52      }
    1.53      
    1.54      /** Appends the specified element to the end of the list of values
    1.55       * associated with the specified key.
    1.56       */
    1.57 -    public void add(Object key,Object value) throws StorageException {
    1.58 +    public synchronized void add(Object key,Object value) throws StorageException {
    1.59          Collection vals = (Collection) entries.get (key);
    1.60          if (vals == null) {
    1.61              vals = new ArrayList ();
    1.62 @@ -106,28 +108,27 @@
    1.63          return unique;
    1.64      }
    1.65  
    1.66 -    public java.util.Collection getItems(Object key) throws StorageException {
    1.67 -        Collection vals = (Collection) entries.get (key);
    1.68 -        return vals == null ? new ArrayList () : vals;
    1.69 +    public synchronized java.util.Collection getItems(Object key) throws StorageException {
    1.70 +        Collection vals = (Collection) entries.get(key);
    1.71 +        if (vals == null) {
    1.72 +            vals = new ArrayList();
    1.73 +            entries.put(key, vals);
    1.74 +        }
    1.75 +        return new MIWrapper((List) vals, key);
    1.76      }
    1.77  
    1.78 -    public java.util.Collection getObjects(Object key, SinglevaluedIndex s) throws StorageException {
    1.79 -       Collection vals = getItems(key);
    1.80 -       ArrayList objs = new ArrayList(vals.size());
    1.81 -       for (Iterator it = vals.iterator(); it.hasNext();) {
    1.82 -           objs.add(s.get(it.next()));
    1.83 -       }
    1.84 -       return objs;
    1.85 +    public synchronized java.util.Collection getObjects(Object key, SinglevaluedIndex s) throws StorageException {
    1.86 +        return new MOWrapper((List) getItems(key), s);
    1.87      }
    1.88      
    1.89      /** Removes the first occurrence of the specified element in the list
    1.90       * of values associated with the specified key.
    1.91       */
    1.92 -    public boolean remove(Object key,Object value) throws StorageException {
    1.93 +    public synchronized boolean remove(Object key,Object value) throws StorageException {
    1.94          Collection vals = (Collection) entries.get (key);
    1.95 -        if (vals != null) {
    1.96 +        if (vals != null && vals.remove(value)) {
    1.97              transLog.logRemove(key, value);
    1.98 -            return vals.remove(value);
    1.99 +            return true;
   1.100          } else {
   1.101              return false;
   1.102          }
   1.103 @@ -143,99 +144,28 @@
   1.104       * in textual representation.
   1.105       * @param outputStream OutputStream that holds value of a Streamable object
   1.106       */
   1.107 -    public void write(java.io.OutputStream outputStream) throws StorageException {
   1.108 +    public void write(java.io.OutputStream out) throws StorageException {
   1.109          try {
   1.110 -            String str = "<name>" + getName() + "</name>"
   1.111 -                         + "<keyType>" + getKeyType().toString() + "</keyType>"
   1.112 -                         + "<valueType>" + getValueType().toString() + "</valueType>"
   1.113 -                         + "<entries>";
   1.114 -            outputStream.write(str.getBytes());
   1.115 -            for (Iterator it = new TreeSet (keySet()).iterator(); it.hasNext();){
   1.116 -                Object o = it.next();
   1.117 -                str = "<entry><key>"+o.toString()+"</key>";
   1.118 -                outputStream.write(str.getBytes());
   1.119 -                for (Iterator iter = getItems(o).iterator(); iter.hasNext();){
   1.120 -                    Object val = iter.next();
   1.121 -                    str = "<value>";
   1.122 -                    outputStream.write(str.getBytes());
   1.123 -                    if (Streamable.class.isAssignableFrom(val.getClass())) {
   1.124 -                        str = "<class>"+val.getClass().getName()+"</class>";
   1.125 -                        outputStream.write(str.getBytes());
   1.126 -                        ((Streamable) val).write (outputStream);
   1.127 -                    } else {
   1.128 -                        outputStream.write(val.toString().getBytes());
   1.129 -                    }
   1.130 -                    str = "</value>";
   1.131 -                    outputStream.write(str.getBytes());
   1.132 -                }
   1.133 -                str = "</entry>";
   1.134 -                outputStream.write(str.getBytes());
   1.135 -            }
   1.136 -            str = "</entries>";
   1.137 -            outputStream.write(str.getBytes());
   1.138 +            IOUtils.writeString(out, name);
   1.139 +            out.write(keyType.encode());
   1.140 +            out.write(valueType.encode());
   1.141 +            IOUtils.write(out, entries);
   1.142          } catch (java.io.IOException e) {
   1.143 -            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   1.144 +            throw new StorageIOException(e);
   1.145          }
   1.146      }
   1.147      /** Restore state of the Storable object from the stream.
   1.148       * @param inputStream InputStream that represents an internal representation of fields of a Streamable object
   1.149       * in which it was written by {@link write } method
   1.150       */
   1.151 -    public void read(java.io.InputStream inputStream) throws StorageException {
   1.152 +    public void read(java.io.InputStream is) throws StorageException {
   1.153          try {
   1.154 -            name = XmlUtils.readTextTag(inputStream); // "<name>"
   1.155 -            Logger.getDefault().log("name:"+name);
   1.156 -            String keyTypeName = XmlUtils.readTextTag(inputStream);// "<keyType>"
   1.157 -            String valueTypeName = XmlUtils.readTextTag(inputStream);// "<valueType>"
   1.158 -            keyType = Storage.EntryType.decodeEntryType(keyTypeName);
   1.159 -            valueType = Storage.EntryType.decodeEntryType(valueTypeName);
   1.160 -            //Log.out.println("keyType:"+keyType);
   1.161 -            //Log.out.println("valueType:"+valueType);
   1.162 -
   1.163 -            XmlUtils.readTagStart(inputStream); // "<entries>";
   1.164 -
   1.165 -            for (;;) {
   1.166 -                inputStream.mark(128);
   1.167 -                String str = XmlUtils.readTagStart(inputStream); // <entry>
   1.168 -                if (str.equals("entry")) { //there are some more entries
   1.169 -                    //Log.out.println("reading entry");
   1.170 -                    //Log.out.indent();
   1.171 -                    String key = XmlUtils.readTextTag(inputStream); //<key>
   1.172 -                    //Log.out.println("key:"+key);
   1.173 -                    for (;;) {
   1.174 -                        str = XmlUtils.readTagStart(inputStream); //<value>
   1.175 -                        if (str.equals("/entry")) break; // no more values
   1.176 -                        Object val = null;
   1.177 -                        if (getValueType().equals(Storage.EntryType.STREAMABLE)) {
   1.178 -                            String className = XmlUtils.readTextTag(inputStream); // "<Class>"
   1.179 -                            //Log.out.println("class:"+className);
   1.180 -                            try {
   1.181 -                                Class cls = Class.forName(className);
   1.182 -                                val = cls.newInstance();
   1.183 -                                ((Streamable) val).read(inputStream);
   1.184 -                            } catch (ClassNotFoundException e) {
   1.185 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   1.186 -                            } catch (InstantiationException e) {
   1.187 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   1.188 -                            } catch (IllegalAccessException e) {
   1.189 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   1.190 -                            }
   1.191 -                        } else {
   1.192 -                            val = XmlUtils.readValue(inputStream);
   1.193 -                        }
   1.194 -                        add (key, val);
   1.195 -                        XmlUtils.skipTagEnd(inputStream); // </value>
   1.196 -                    }
   1.197 -                    //Log.out.unindent();
   1.198 -                } else {
   1.199 -                    inputStream.reset();
   1.200 -                    //Log.out.println("...end");
   1.201 -                    break;
   1.202 -                }
   1.203 -            }
   1.204 -            XmlUtils.skipTagEnd(inputStream); // </entries>
   1.205 +            name = IOUtils.readString(is);
   1.206 +            keyType = Storage.EntryType.decodeEntryType((byte) is.read());
   1.207 +            valueType = Storage.EntryType.decodeEntryType((byte) is.read());
   1.208 +            entries = (Map) IOUtils.read(is);
   1.209          } catch (java.io.IOException e) {
   1.210 -            throw (StoragePersistentDataException) Logger.getDefault().annotate(new StoragePersistentDataException(e.getMessage()), e);
   1.211 +            throw new StorageIOException(e);
   1.212          }
   1.213      }
   1.214          
   1.215 @@ -243,12 +173,12 @@
   1.216      /* -- Transaction support --------------------------------------------- */
   1.217      /* -------------------------------------------------------------------- */
   1.218      
   1.219 -    protected void rollBackChanges () throws StorageException {
   1.220 +    protected synchronized void rollBackChanges () throws StorageException {
   1.221          transLog.rollBack ();
   1.222          transLog.clear ();
   1.223      }
   1.224      
   1.225 -    protected void commitChanges () throws StorageException {        
   1.226 +    protected synchronized void commitChanges () throws StorageException {        
   1.227          transLog.clear ();
   1.228      }
   1.229      
   1.230 @@ -256,11 +186,105 @@
   1.231      /* -- Methods not specified by any interface -------------------------- */
   1.232      /* -------------------------------------------------------------------- */
   1.233  
   1.234 -    public void changed (Object key) {
   1.235 +    public void changed(Object key) {
   1.236      }        
   1.237  
   1.238 -    void setKey (Object key, Object vals) {
   1.239 +    void setKey(Object key, Object vals) {
   1.240          entries.put(key, vals);        
   1.241      }
   1.242      
   1.243 +    private class MIWrapper extends AbstractList {
   1.244 +        private final List inner;
   1.245 +        private final Object key;
   1.246 +        
   1.247 +        public MIWrapper(List inner, Object key) {
   1.248 +            this.inner = inner;
   1.249 +            this.key = key;
   1.250 +        }
   1.251 +        
   1.252 +        public Object get(int param) {
   1.253 +            synchronized (MultivaluedIndexImpl.this) {
   1.254 +                return inner.get(param);
   1.255 +            }
   1.256 +        }
   1.257 +        
   1.258 +        public int size() {
   1.259 +            synchronized (MultivaluedIndexImpl.this) {
   1.260 +                return inner.size();
   1.261 +            }
   1.262 +        }
   1.263 +        
   1.264 +        public Object set(int index, Object element) {
   1.265 +            synchronized (MultivaluedIndexImpl.this) {
   1.266 +                Object orig;
   1.267 +                if ((orig = inner.set(index, element)) != null) {
   1.268 +                    transLog.logReplace(key, orig, index);
   1.269 +                }
   1.270 +                return orig;
   1.271 +            }
   1.272 +        }
   1.273 +        
   1.274 +        public void add(int index, Object element) {
   1.275 +            synchronized (MultivaluedIndexImpl.this) {
   1.276 +                inner.add(index, element);
   1.277 +                transLog.logAdd(key, element, index);
   1.278 +            }
   1.279 +        }
   1.280 +        
   1.281 +        public Object remove(int index) {
   1.282 +            synchronized (MultivaluedIndexImpl.this) {
   1.283 +                Object orig;
   1.284 +                if ((orig = inner.remove(index)) != null) {
   1.285 +                    transLog.logRemove(key, orig, index);
   1.286 +                    return orig;
   1.287 +                } else {
   1.288 +                    return null;
   1.289 +                }
   1.290 +            }
   1.291 +        }
   1.292 +    }
   1.293 +
   1.294 +    private class MOWrapper extends AbstractList {
   1.295 +        private final List inner;
   1.296 +        private final SinglevaluedIndex pi;
   1.297 +        
   1.298 +        public MOWrapper(List inner, SinglevaluedIndex pi) {
   1.299 +            this.inner = inner;
   1.300 +            this.pi = pi;
   1.301 +        }
   1.302 +        
   1.303 +        public Object get(int param) {
   1.304 +            try {
   1.305 +                return pi.get(inner.get(param));
   1.306 +            } catch (StorageException e) {
   1.307 +                throw (RuntimeException) Logger.getDefault().annotate(new RuntimeException(), e);
   1.308 +            }
   1.309 +        }
   1.310 +        
   1.311 +        public int size() {
   1.312 +            synchronized (MultivaluedIndexImpl.this) {
   1.313 +                return inner.size();
   1.314 +            }
   1.315 +        }
   1.316 +        
   1.317 +        public Object set(int index, Object element) {
   1.318 +            if (element instanceof MOFID) {
   1.319 +                return inner.set(index, element);
   1.320 +            } else {
   1.321 +                throw new IllegalArgumentException();
   1.322 +            }
   1.323 +        }
   1.324 +        
   1.325 +        public void add(int index, Object element) {
   1.326 +            if (element instanceof MOFID) {
   1.327 +                inner.add(index, element);
   1.328 +            } else {
   1.329 +                throw new IllegalArgumentException();
   1.330 +            }
   1.331 +        }
   1.332 +        
   1.333 +        public Object remove(int index) {
   1.334 +            return inner.remove(index);
   1.335 +        }
   1.336 +    }
   1.337  }
     2.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedOrderedIndexImpl.java	Mon Oct 21 10:56:35 2002 +0000
     2.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/MultivaluedOrderedIndexImpl.java	Mon Oct 21 17:44:29 2002 +0000
     2.3 @@ -19,7 +19,7 @@
     2.4  import org.netbeans.mdr.util.*;
     2.5  
     2.6  /** Default memory implementation of the MultivaluedOrderedIndex using Hashtable.
     2.7 - * @author  Pavel Buzek
     2.8 + * @author  Pavel Buzek, Martin Matula
     2.9   * @version
    2.10   */
    2.11  public class MultivaluedOrderedIndexImpl extends MultivaluedIndexImpl implements MultivaluedOrderedIndex, Streamable {
    2.12 @@ -32,7 +32,7 @@
    2.13      public MultivaluedOrderedIndexImpl() {
    2.14      }
    2.15  
    2.16 -    public java.util.List getItemsOrdered(Object key) throws StorageException {
    2.17 +    public synchronized java.util.List getItemsOrdered(Object key) throws StorageException {
    2.18          return (List) getItems (key);
    2.19      }
    2.20  
    2.21 @@ -42,129 +42,19 @@
    2.22       * @param key
    2.23       * @throws StorageException
    2.24       */
    2.25 -    public java.util.Collection getObjectsOrdered (Object key, SinglevaluedIndex repos) throws StorageException {
    2.26 +    public synchronized java.util.Collection getObjectsOrdered (Object key, SinglevaluedIndex repos) throws StorageException {
    2.27      	return (List) getObjects(key, repos);
    2.28      }
    2.29  
    2.30 -    /** This method will be used to move changed object from storage cache
    2.31 -    * to the persistent part of storage. It writes the object`s state
    2.32 -     * (set of attributes) in the stream as an array of bytes, for example
    2.33 -     * in textual representation.
    2.34 -     * @param outputStream OutputStream that holds value of a Streamable object
    2.35 -     */
    2.36 -    public void write(java.io.OutputStream outputStream) throws StorageException {
    2.37 -        try {
    2.38 -            String str = "<name>" + getName() + "</name>"
    2.39 -                         + "<keyType>" + getKeyType().toString() + "</keyType>"
    2.40 -                         + "<valueType>" + getValueType().toString() + "</valueType>"
    2.41 -                         + "<entries>";
    2.42 -            outputStream.write(str.getBytes());
    2.43 -            for (Iterator it = new TreeSet (keySet()).iterator(); it.hasNext();){
    2.44 -                Object o = it.next();
    2.45 -                str = "<entry><key>"+o.toString()+"</key>";
    2.46 -                outputStream.write(str.getBytes());
    2.47 -                int i = 0;
    2.48 -                for (Iterator iter = getItems(o).iterator(); iter.hasNext();i++){
    2.49 -                    Object val = iter.next();
    2.50 -                    str = "<value><order>"+i+"</order>";
    2.51 -                    outputStream.write(str.getBytes());
    2.52 -                    if (Streamable.class.isAssignableFrom(val.getClass())) {
    2.53 -                        str = "<class>"+val.getClass().getName()+"</class>";
    2.54 -                        outputStream.write(str.getBytes());
    2.55 -                        ((Streamable) val).write (outputStream);
    2.56 -                    } else {
    2.57 -                        outputStream.write(val.toString().getBytes());
    2.58 -                    }
    2.59 -                    str = "</value>";
    2.60 -                    outputStream.write(str.getBytes());
    2.61 -                }
    2.62 -                str = "</entry>";
    2.63 -                outputStream.write(str.getBytes());
    2.64 -            }
    2.65 -            str = "</entries>";
    2.66 -            outputStream.write(str.getBytes());
    2.67 -        } catch (java.io.IOException e) {
    2.68 -            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
    2.69 -        }
    2.70 -    }
    2.71 -    /** Restore state of the Storable object from the stream.
    2.72 -     * @param inputStream InputStream that represents an internal representation of fields of a Streamable object
    2.73 -     * in which it was written by {@link write } method
    2.74 -     */
    2.75 -    public void read(java.io.InputStream inputStream) throws StorageException {
    2.76 -        try {
    2.77 -            name = XmlUtils.readTextTag(inputStream); // "<name>"
    2.78 -            Logger.getDefault().log("name:"+name);
    2.79 -            String keyTypeName = XmlUtils.readTextTag(inputStream);// "<keyType>"
    2.80 -            String valueTypeName = XmlUtils.readTextTag(inputStream);// "<valueType>"
    2.81 -            keyType = Storage.EntryType.decodeEntryType(keyTypeName);
    2.82 -            valueType = Storage.EntryType.decodeEntryType(valueTypeName);
    2.83 -            //Log.out.println("keyType:"+keyType);
    2.84 -            //Log.out.println("valueType:"+valueType);
    2.85 -
    2.86 -            XmlUtils.readTagStart(inputStream); // "<entries>";
    2.87 -
    2.88 -            for (;;) {
    2.89 -                inputStream.mark(128);
    2.90 -                String str = XmlUtils.readTagStart(inputStream); // <entry>
    2.91 -                if (str.equals("entry")) { //there are some more entries
    2.92 -                    //Log.out.println("reading entry");
    2.93 -                    //Log.out.indent();
    2.94 -                    String key = XmlUtils.readTextTag(inputStream); //<key>
    2.95 -                    //Log.out.println("key:"+key);
    2.96 -                    //Log.out.indent();
    2.97 -                    for (;;) {
    2.98 -                        str = XmlUtils.readTagStart(inputStream); //<value>
    2.99 -                        if (str.equals("/entry")) break; // no more values
   2.100 -                        XmlUtils.readTextTag(inputStream); // order
   2.101 -                        Object val = null;
   2.102 -                        if (getValueType().equals(Storage.EntryType.STREAMABLE)) {
   2.103 -                            String className = XmlUtils.readTextTag(inputStream); // "<Class>"
   2.104 -                            //Log.out.println("class:"+className);
   2.105 -                            try {
   2.106 -                                Class cls = Class.forName(className);
   2.107 -                                val = cls.newInstance();
   2.108 -                                ((Streamable) val).read(inputStream);
   2.109 -                            } catch (ClassNotFoundException e) {
   2.110 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   2.111 -                            } catch (InstantiationException e) {
   2.112 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   2.113 -                            } catch (IllegalAccessException e) {
   2.114 -                                Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   2.115 -                            }
   2.116 -                        } else {
   2.117 -                            val = XmlUtils.readValue(inputStream);
   2.118 -                            //Log.out.println("val:"+key);
   2.119 -                        }
   2.120 -                        //Log.out.unindent();
   2.121 -                        add (key, val);
   2.122 -                        XmlUtils.skipTagEnd(inputStream); // </value>
   2.123 -                    }
   2.124 -                    //Log.out.unindent();
   2.125 -                } else {
   2.126 -                    inputStream.reset();
   2.127 -                    //Log.out.println("...end");
   2.128 -                    break;
   2.129 -                }
   2.130 -            }
   2.131 -            XmlUtils.skipTagEnd(inputStream); // </entries>
   2.132 -        } catch (java.io.IOException e) {
   2.133 -            throw (StoragePersistentDataException) Logger.getDefault().annotate(new StoragePersistentDataException(), e);
   2.134 -        }
   2.135 -    }
   2.136 -    
   2.137      /** Removes the element at the specified position in the list of values
   2.138       * associated with the specified key.
   2.139       */
   2.140 -    public boolean remove(Object key,int index) throws StorageException {
   2.141 +    public synchronized boolean remove(Object key,int index) throws StorageException {
   2.142          List vals = (List) entries.get (key);
   2.143 -        if (vals != null) {
   2.144 -            Object orig = vals.remove(index);
   2.145 -            if (orig != null) {
   2.146 -                transLog.logRemove(key, orig, index);
   2.147 -                return true;
   2.148 -            } else
   2.149 -                return false;            
   2.150 +        Object orig;
   2.151 +        if (vals != null && (orig = vals.remove(index)) != null) {
   2.152 +            transLog.logRemove(key, orig, index);
   2.153 +            return true;
   2.154          } else {
   2.155              return false;
   2.156          }
   2.157 @@ -173,7 +63,7 @@
   2.158      /** Inserts the specified element at the specified position in the list of values
   2.159       * associated with the specified key.
   2.160       */
   2.161 -    public void add(Object key,int index,Object value) throws StorageException {
   2.162 +    public synchronized void add(Object key,int index,Object value) throws StorageException {
   2.163          List vals = (List) entries.get (key);
   2.164          if (vals == null) {
   2.165              vals = new ArrayList ();
   2.166 @@ -191,13 +81,16 @@
   2.167       * @param element
   2.168       * @throws StorageException
   2.169       */
   2.170 -    public void replace(Object key,int index,Object element) throws StorageException {
   2.171 +    public synchronized void replace(Object key,int index,Object element) throws StorageException {
   2.172          List vals = (List) entries.get (key);
   2.173 -        if (vals != null) {
   2.174 -            Object orig = vals.set(index, element);
   2.175 -            transLog.logReplace(key, orig, index);
   2.176 -        } else {
   2.177 -            throw new StorageBadRequestException ("Index out of range");
   2.178 +        try {
   2.179 +            Object orig;
   2.180 +            if (vals != null && (orig = vals.set(index, element)) != null) {
   2.181 +                transLog.logReplace(key, orig, index);
   2.182 +                return;
   2.183 +            }
   2.184 +        } catch (IndexOutOfBoundsException e) {
   2.185          }
   2.186 +        throw new StorageBadRequestException ("Index out of range: " + index + " for key: " + key);
   2.187      }
   2.188  }
     3.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/PrimaryIndexImpl.java	Mon Oct 21 10:56:35 2002 +0000
     3.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/PrimaryIndexImpl.java	Mon Oct 21 17:44:29 2002 +0000
     3.3 @@ -25,43 +25,20 @@
     3.4      private DataOutputStream daoStrm = new DataOutputStream (baoStrm);
     3.5      private StorageImpl storage;
     3.6      
     3.7 -    /** Constructor used when restoring the streamable index from a stream. */
     3.8 -    public PrimaryIndexImpl() {
     3.9 -    }
    3.10 -    
    3.11 -    /** Creates a new single-valued index. */
    3.12 -    public PrimaryIndexImpl(StorageImpl storage, String name, Storage.EntryType keyType, Storage.EntryType valueType) {
    3.13 -        super (name, keyType, valueType);    
    3.14 +    public PrimaryIndexImpl(StorageImpl storage) {
    3.15 +        super(StorageImpl.PRIMARY_INDEX_NAME, Storage.EntryType.MOFID, Storage.EntryType.STREAMABLE);
    3.16          this.storage = storage;
    3.17      }
    3.18 -
    3.19 -    /** Adds the specified value to values associated in this index with the
    3.20 -     * specified key. If the index puts limit on number of values associated
    3.21 -     * with one key and adding value would break this limit, it throws
    3.22 -     * StorageBadRequestException.
    3.23 -     * @param key
    3.24 -     * @param value
    3.25 -     * @throws StorageException
    3.26 -     */
    3.27 -    public void add(Object key,Object value) throws StorageException {
    3.28 -        Object original = table.put (key, value);
    3.29 -        if (original != null) {
    3.30 -            table.remove(key);
    3.31 -            throw new StorageBadRequestException (
    3.32 -                "Cannot add more than one item to key in single-valued index.");
    3.33 -        }        
    3.34 -        transLog.logAdd(key);
    3.35 -    }
    3.36      
    3.37      /** Removes all values assosiated in the index with specified key.
    3.38       * @return true if this index changed as a result of this call
    3.39       * @param key
    3.40       * @throws StorageException
    3.41       */
    3.42 -    public boolean remove(Object key) throws StorageException {
    3.43 +    public synchronized boolean remove(Object key) throws StorageException {
    3.44          Object original = table.remove(key);
    3.45          if (original != null) {
    3.46 -            Object valueLog = transLog.isLogged(key) ? null : createValueLog(original);
    3.47 +            Object valueLog = transLog.isLogged(key) ? null : createValueLog((Streamable) original);
    3.48              transLog.logRemove(key, valueLog);
    3.49              return true;
    3.50          } else
    3.51 @@ -75,12 +52,12 @@
    3.52       * @param value
    3.53       * @throws StorageException
    3.54       */
    3.55 -    public boolean put(Object key,Object value) throws StorageException {
    3.56 +    public synchronized boolean put(Object key,Object value) throws StorageException {
    3.57          Object original = table.put(key, value);
    3.58          if (original == null) {
    3.59              transLog.logAdd(key);
    3.60          } else {
    3.61 -            Object valueLog = transLog.isLogged(key) ? null : createValueLog(original);
    3.62 +            Object valueLog = transLog.isLogged(key) ? null : createValueLog((Streamable) original);
    3.63              transLog.logReplace(key, valueLog);
    3.64          }
    3.65          return original != null;
    3.66 @@ -95,46 +72,20 @@
    3.67       * @throws StorageBadRequestException if the index has no entry with the given
    3.68       *           key 
    3.69       */
    3.70 -    public void replace(Object key,Object value) throws StorageException, StorageBadRequestException {
    3.71 +    public synchronized void replace(Object key,Object value) throws StorageException, StorageBadRequestException {
    3.72          Object original = table.put (key, value);
    3.73          if (original == null) {
    3.74              table.remove(key);
    3.75              throw new StorageBadRequestException ("Cannot replace item that does not exist in the index.");
    3.76          }
    3.77 -        Object valueLog = transLog.isLogged(key) ? null : createValueLog(original);
    3.78 +        Object valueLog = transLog.isLogged(key) ? null : createValueLog((Streamable) original);
    3.79          transLog.logReplace(key, valueLog);
    3.80      }
    3.81      
    3.82 -    /** Returns the value to which this index maps the specified key.
    3.83 -     * StorageBadRequestException is thrown if there is no value for the key.
    3.84 -     * @return value associated with specified key
    3.85 -     * @param key
    3.86 -     * @throws StorageException
    3.87 -     * @throws StorageBadRequestException
    3.88 -     */
    3.89 -    public Object get(Object key) throws StorageException, StorageBadRequestException {
    3.90 -        Object value = table.get(key);
    3.91 -        if (value == null) {
    3.92 -            throw new StorageBadRequestException ("Item not found: " + key);
    3.93 -        } else {
    3.94 -            return value;
    3.95 -        }
    3.96 -    }
    3.97 -
    3.98 -    /** Returns the value to which this index maps the specified key
    3.99 -     * or null if there is no value for this key.
   3.100 -     * @return value associated with specified key or null
   3.101 -     * @param key
   3.102 -     * @throws StorageException
   3.103 -     */
   3.104 -    public Object getIfExists(Object key) throws StorageException {
   3.105 -        return table.get (key);        
   3.106 -    }
   3.107 -     
   3.108 -    public void willChange (Object key) throws StorageException {
   3.109 +    public synchronized void willChange (Object key) throws StorageException {
   3.110          if (!transLog.isLogged(key)) {
   3.111              Object value = table.get (key);
   3.112 -            transLog.logValue (key, createValueLog (value));
   3.113 +            transLog.logValue(key, createValueLog ((Streamable) value));
   3.114          }
   3.115          transLog.setDirty(key);
   3.116      }
   3.117 @@ -143,10 +94,62 @@
   3.118          // do nothing
   3.119      }
   3.120      
   3.121 -    private PrimaryValueLog createValueLog (Object value) throws StorageException {
   3.122 +    private PrimaryValueLog createValueLog (Streamable value) throws StorageException {
   3.123          baoStrm.reset();
   3.124 -        ((Streamable) value).write(daoStrm);
   3.125 -        return new PrimaryValueLog (baoStrm.toByteArray(), (Streamable) value);
   3.126 +        try {
   3.127 +            ((Streamable) value).write(daoStrm);
   3.128 +        } catch (RuntimeException e) {
   3.129 +            // ignore
   3.130 +        }
   3.131 +        return new PrimaryValueLog (baoStrm.toByteArray(), value);
   3.132 +    }
   3.133 +
   3.134 +    /* -------------------------------------------------------------------- */
   3.135 +    /* -- Implementation of org.netbeans.mdr.persistence.Streamable ------- */
   3.136 +    /* -------------------------------------------------------------------- */
   3.137 +
   3.138 +    /** This method will be used to move changed object from storage cache
   3.139 +     * to the persistent part of storage. It writes the object`s state
   3.140 +     * (set of attributes) in the stream as an array of bytes, for example
   3.141 +     * in textual representation.
   3.142 +     * @param outputStream OutputStream that holds value of a Streamable object
   3.143 +     */
   3.144 +    public void write(java.io.OutputStream out) throws StorageException {
   3.145 +        try {
   3.146 +            IOUtils.writeInt(out, table.size());
   3.147 +            for (Iterator it = table.entrySet().iterator(); it.hasNext();) {
   3.148 +                Map.Entry entry = (Map.Entry) it.next();
   3.149 +                storage.writeMOFID(out, (MOFID) entry.getKey());
   3.150 +                Streamable value = (Streamable) entry.getValue();
   3.151 +                IOUtils.writeString(out, value.getClass().getName());
   3.152 +                value.write(out);
   3.153 +            }
   3.154 +        } catch (java.io.IOException e) {
   3.155 +            throw new StorageIOException(e);
   3.156 +        }
   3.157 +    }
   3.158 +    /** Restore state of the Storable object from the stream.
   3.159 +     * @param inputStream InputStream that represents an internal representation of fields of a Streamable object
   3.160 +     * in which it was written by {@link write } method
   3.161 +     */
   3.162 +    public void read(java.io.InputStream is) throws StorageException {
   3.163 +        try {
   3.164 +            int size = IOUtils.readInt(is);
   3.165 +            table = new HashMap(size * 4 / 3);
   3.166 +            for (int i = 0; i < size; i++) {
   3.167 +                MOFID key = storage.readMOFID(is);
   3.168 +                Streamable value = (Streamable) Class.forName(IOUtils.readString(is)).newInstance();
   3.169 +                if (value instanceof StorageClient) {
   3.170 +                    ((StorageClient) value).setStorage(storage);
   3.171 +                }
   3.172 +                value.read(is);
   3.173 +                table.put(key, value);
   3.174 +            }
   3.175 +        } catch (java.io.IOException e) {
   3.176 +            throw new StorageIOException(e);
   3.177 +        } catch (Exception e) {
   3.178 +            throw (StorageException) Logger.getDefault().annotate(new StoragePersistentDataException(), e);
   3.179 +        }
   3.180      }
   3.181  
   3.182      // inner class ..............................................................
   3.183 @@ -170,7 +173,5 @@
   3.184              obj.read(daiStrm);
   3.185              return obj;
   3.186          }
   3.187 -
   3.188      }
   3.189 -
   3.190  }
     4.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/SinglevaluedIndexImpl.java	Mon Oct 21 10:56:35 2002 +0000
     4.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/SinglevaluedIndexImpl.java	Mon Oct 21 17:44:29 2002 +0000
     4.3 @@ -33,7 +33,7 @@
     4.4      private String name;
     4.5      private Storage.EntryType keyType;
     4.6      private Storage.EntryType valueType;
     4.7 -    protected Hashtable table = new Hashtable();
     4.8 +    protected Map table;
     4.9      
    4.10      protected TransactionLog transLog = new TransactionLog (this);
    4.11  
    4.12 @@ -50,6 +50,7 @@
    4.13          this.name = name;
    4.14          this.keyType = keyType;
    4.15          this.valueType = valueType;
    4.16 +        table = new HashMap();
    4.17      }
    4.18  
    4.19      /* -------------------------------------------------------------------- */
    4.20 @@ -73,7 +74,7 @@
    4.21       * @return keys contained in this index
    4.22       * @throws StorageException
    4.23       */
    4.24 -    public java.util.Set keySet() throws StorageException {
    4.25 +    public synchronized java.util.Set keySet() throws StorageException {
    4.26          return table.keySet();
    4.27      }
    4.28      
    4.29 @@ -85,10 +86,10 @@
    4.30       * @param value
    4.31       * @throws StorageException
    4.32       */
    4.33 -    public void add(Object key,Object value) throws StorageException {        
    4.34 +    public synchronized void add(Object key,Object value) throws StorageException {        
    4.35          Object original = table.put (key, value);
    4.36          if (original != null) {
    4.37 -            table.remove(key);
    4.38 +            table.put(key, original);
    4.39              throw new StorageBadRequestException (
    4.40                  "Cannot add more than one item to key in single-valued index.");
    4.41          }
    4.42 @@ -100,11 +101,14 @@
    4.43       * @param key
    4.44       * @throws StorageException
    4.45       */
    4.46 -    public boolean remove(Object key) throws StorageException {
    4.47 +    public synchronized boolean remove(Object key) throws StorageException {
    4.48          Object value = table.remove(key);
    4.49 -        if (value != null)
    4.50 +        if (value != null) {
    4.51              transLog.logRemove (key, value);
    4.52 -        return value != null;
    4.53 +            return true;
    4.54 +        } else {
    4.55 +            return false;
    4.56 +        }
    4.57      }
    4.58  
    4.59      /* -------------------------------------------------------------------- */
    4.60 @@ -118,13 +122,15 @@
    4.61       * @param value
    4.62       * @throws StorageException
    4.63       */
    4.64 -    public boolean put(Object key,Object value) throws StorageException {                
    4.65 +    public synchronized boolean put(Object key,Object value) throws StorageException {                
    4.66          Object old = table.put(key, value);
    4.67 -        if (old == null)
    4.68 +        if (old == null) {
    4.69              transLog.logAdd (key);
    4.70 -        else
    4.71 +            return false;
    4.72 +        } else {
    4.73              transLog.logReplace (key, old);
    4.74 -        return old != null;
    4.75 +            return true;
    4.76 +        }
    4.77      }
    4.78      
    4.79      /** Replaces the original value associated with the specified key in this index
    4.80 @@ -136,8 +142,8 @@
    4.81       * @throws StorageBadRequestException if the index has no entry with the given
    4.82       *           key 
    4.83       */
    4.84 -    public void replace(Object key,Object value) throws StorageException, StorageBadRequestException {
    4.85 -        Object original = table.put (key, value);
    4.86 +    public synchronized void replace(Object key, Object value) throws StorageException {
    4.87 +        Object original = table.put(key, value);
    4.88          if (original == null) {
    4.89              table.remove(key);
    4.90              throw new StorageBadRequestException ("Cannot replace item that does not exist in the index.");
    4.91 @@ -152,7 +158,7 @@
    4.92       * @throws StorageException
    4.93       * @throws StorageBadRequestException
    4.94       */
    4.95 -    public Object get(Object key) throws StorageException, StorageBadRequestException {
    4.96 +    public synchronized Object get(Object key) throws StorageException {
    4.97          Object value = table.get(key);
    4.98          if (value == null) {            
    4.99              throw new StorageBadRequestException ("Item not found: " + key);
   4.100 @@ -166,8 +172,10 @@
   4.101       * @param key
   4.102       * @throws StorageException
   4.103       */
   4.104 -    public Object getObject (Object key, SinglevaluedIndex repos) throws StorageException {
   4.105 -    	return repos.get(get(key));
   4.106 +    public synchronized Object getObject (Object key, SinglevaluedIndex repos) throws StorageException {
   4.107 +        synchronized (repos) {
   4.108 +            return repos.get(get(key));
   4.109 +        }
   4.110      }
   4.111  
   4.112      /** Returns the value to which this index maps the specified key
   4.113 @@ -176,7 +184,7 @@
   4.114       * @param key
   4.115       * @throws StorageException
   4.116       */
   4.117 -    public Object getIfExists(Object key) throws StorageException {
   4.118 +    public synchronized Object getIfExists(Object key) throws StorageException {
   4.119          return table.get (key);
   4.120      }
   4.121  
   4.122 @@ -186,9 +194,15 @@
   4.123       * @param key
   4.124       * @throws StorageException
   4.125       */
   4.126 -    public Object getObjectIfExists (Object key, SinglevaluedIndex repos) throws StorageException {
   4.127 +    public synchronized Object getObjectIfExists (Object key, SinglevaluedIndex repos) throws StorageException {
   4.128      	Object val = getIfExists(key);
   4.129 -	return (val == null) ? null : repos.get(val);
   4.130 +        if (val == null) {
   4.131 +            return null;
   4.132 +        } else {
   4.133 +            synchronized (repos) {
   4.134 +                return repos.get(val);
   4.135 +            }
   4.136 +        }
   4.137      }
   4.138      
   4.139      /** Returns a collection view of the values contained in this index.
   4.140 @@ -197,7 +211,7 @@
   4.141       * @return
   4.142       * @throws StorageException
   4.143       */
   4.144 -    public java.util.Collection values() throws StorageException {
   4.145 +    public synchronized java.util.Collection values() throws StorageException {
   4.146          return table.values();
   4.147      }
   4.148  
   4.149 @@ -211,92 +225,28 @@
   4.150       * in textual representation.
   4.151       * @param outputStream OutputStream that holds value of a Streamable object
   4.152       */
   4.153 -    public void write(java.io.OutputStream outputStream) throws StorageException {
   4.154 +    public void write(java.io.OutputStream out) throws StorageException {
   4.155          try {
   4.156 -            String str = "<name>" + getName() + "</name>"
   4.157 -                         + "<keyType>" + getKeyType().toString() + "</keyType>"
   4.158 -                         + "<valueType>" + getValueType().toString() + "</valueType>"
   4.159 -                         + "<entries>";
   4.160 -            outputStream.write(str.getBytes());
   4.161 -            for (Iterator it = new TreeSet (keySet()).iterator(); it.hasNext();){
   4.162 -                Object o = it.next();
   4.163 -                str = "<entry><key>"+o.toString()+"</key><value>";
   4.164 -                outputStream.write(str.getBytes());
   4.165 -                Object val = get(o);
   4.166 -                if (getValueType().equals(Storage.EntryType.STREAMABLE)) {
   4.167 -                    str = "<class>"+val.getClass().getName()+"</class>";
   4.168 -                    outputStream.write(str.getBytes());
   4.169 -                    ((Streamable) val).write (outputStream);
   4.170 -                } else {
   4.171 -                    outputStream.write(val.toString().getBytes());
   4.172 -                }
   4.173 -                str = "</value></entry>";
   4.174 -                outputStream.write(str.getBytes());
   4.175 -            }
   4.176 -            str = "</entries>";
   4.177 -            outputStream.write(str.getBytes());
   4.178 +            IOUtils.writeString(out, name);
   4.179 +            out.write(keyType.encode());
   4.180 +            out.write(valueType.encode());
   4.181 +            IOUtils.write(out, table);
   4.182          } catch (java.io.IOException e) {
   4.183 -            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   4.184 +            throw new StorageIOException(e);
   4.185          }
   4.186      }
   4.187      /** Restore state of the Storable object from the stream.
   4.188       * @param inputStream InputStream that represents an internal representation of fields of a Streamable object
   4.189       * in which it was written by {@link write } method
   4.190       */
   4.191 -    public void read(java.io.InputStream inputStream) throws StorageException {
   4.192 +    public void read(java.io.InputStream is) throws StorageException {
   4.193          try {
   4.194 -            name = XmlUtils.readTextTag(inputStream); // "<name>"
   4.195 -            Logger.getDefault().log("name:"+name);
   4.196 -            String keyTypeName = XmlUtils.readTextTag(inputStream);// "<keyType>"
   4.197 -            String valueTypeName = XmlUtils.readTextTag(inputStream);// "<valueType>"
   4.198 -            keyType = Storage.EntryType.decodeEntryType(keyTypeName);
   4.199 -            valueType = Storage.EntryType.decodeEntryType(valueTypeName);
   4.200 -            //Log.out.println("keyType:"+keyType);
   4.201 -            //Log.out.println("valueType:"+valueType);
   4.202 -
   4.203 -            XmlUtils.readTagStart(inputStream); // "<entries>";
   4.204 -
   4.205 -            for (;;) {
   4.206 -                inputStream.mark(128);
   4.207 -                String str = XmlUtils.readTagStart(inputStream); // <entry>
   4.208 -                if (str.equals("entry")) { //there are some more entries
   4.209 -                    //Log.out.println("reading entry");
   4.210 -                    //Log.out.indent();
   4.211 -                    String key = XmlUtils.readTextTag(inputStream); //<key>
   4.212 -                    //Log.out.println("key:"+key);
   4.213 -                    XmlUtils.readTagStart(inputStream); //<value>
   4.214 -                    Object val = null;
   4.215 -                    if (getValueType().equals(Storage.EntryType.STREAMABLE)) {
   4.216 -                        String className = XmlUtils.readTextTag(inputStream); // "<Class>"
   4.217 -                        //Log.out.println("class:"+className);
   4.218 -                        try {
   4.219 -                            Class cls = Class.forName(className);
   4.220 -                            val = cls.newInstance();
   4.221 -                            ((Streamable) val).read(inputStream);
   4.222 -                        } catch (ClassNotFoundException e) {
   4.223 -                            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   4.224 -                        } catch (InstantiationException e) {
   4.225 -                            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   4.226 -                        } catch (IllegalAccessException e) {
   4.227 -                            Logger.getDefault().notify(Logger.INFORMATIONAL, e);
   4.228 -                        }
   4.229 -                    } else {
   4.230 -                        val = XmlUtils.readValue(inputStream);
   4.231 -                    }
   4.232 -                    put(key, val);
   4.233 -                    //Log.out.println( key + " : " + val );
   4.234 -                    XmlUtils.skipTagEnd(inputStream); // </value>
   4.235 -                    XmlUtils.skipTagEnd(inputStream); // </entry>
   4.236 -                    //Log.out.unindent();
   4.237 -                } else {
   4.238 -                    inputStream.reset();
   4.239 -                    //Log.out.println("...end");
   4.240 -                    break;
   4.241 -                }
   4.242 -            }
   4.243 -            XmlUtils.skipTagEnd(inputStream); // </entries>
   4.244 +            name = IOUtils.readString(is);
   4.245 +            keyType = Storage.EntryType.decodeEntryType((byte) is.read());
   4.246 +            valueType = Storage.EntryType.decodeEntryType((byte) is.read());
   4.247 +            table = (Map) IOUtils.read(is);
   4.248          } catch (java.io.IOException e) {
   4.249 -            throw (StoragePersistentDataException) Logger.getDefault().annotate(new StoragePersistentDataException(), e);
   4.250 +            throw new StorageIOException(e);
   4.251          }
   4.252      }
   4.253  
   4.254 @@ -304,12 +254,12 @@
   4.255      /* -- Transaction support --------------------------------------------- */
   4.256      /* -------------------------------------------------------------------- */        
   4.257      
   4.258 -    protected void rollBackChanges () throws StorageException {        
   4.259 +    protected synchronized void rollBackChanges () throws StorageException {        
   4.260          transLog.rollBack ();
   4.261          transLog.clear ();        
   4.262      }
   4.263      
   4.264 -    protected void commitChanges () throws StorageException {        
   4.265 +    protected synchronized void commitChanges () throws StorageException {        
   4.266          transLog.clear ();
   4.267      }
   4.268      
   4.269 @@ -320,5 +270,4 @@
   4.270      /** Does nothing. */
   4.271      public void changed (Object key) {
   4.272      }
   4.273 -    
   4.274  }
     5.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageFactoryImpl.java	Mon Oct 21 10:56:35 2002 +0000
     5.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageFactoryImpl.java	Mon Oct 21 17:44:29 2002 +0000
     5.3 @@ -12,6 +12,7 @@
     5.4   */
     5.5  package org.netbeans.mdr.persistence.memoryimpl;
     5.6  
     5.7 +import java.util.HashMap;
     5.8  import java.util.Map;
     5.9  import org.netbeans.mdr.persistence.*;
    5.10  
    5.11 @@ -21,16 +22,12 @@
    5.12   * @version 
    5.13   */
    5.14  public class StorageFactoryImpl extends Object implements StorageFactory {
    5.15 -    
    5.16      public static final String STORAGE_NAME = "org.netbeans.mdr.persistence.memoryimpl.name";
    5.17 -    public static final String PERSISTENT_NAME = "org.netbeans.mdr.persistence.memoryimpl.persistent";
    5.18 -    
    5.19 -    public static final String MEMORY_STORAGE_PREFIX = "MEM";
    5.20 -    public static final int NULL_STORAGE = 0;
    5.21 -    
    5.22 -    private static Sequencer sequencer = null;
    5.23 -    
    5.24 -    private MOFID nullMOFID;
    5.25 +    static final String NULL_STORAGE_ID = ".";
    5.26 +    private static final MOFID NULL_MOFID = new MOFID(0, NULL_STORAGE_ID);
    5.27 +
    5.28 +    private StorageImpl nullStorage; 
    5.29 +    private final HashMap storages = new HashMap();
    5.30  
    5.31      /** Creates new StorageFactoryImpl */
    5.32      public StorageFactoryImpl() {
    5.33 @@ -39,44 +36,24 @@
    5.34      /** Creates instance of class that implements Storage interface.
    5.35       * throws StorageException if the name is not valid name of a Storage
    5.36       */
    5.37 -    public Storage createStorage(Map properties) throws StorageException {
    5.38 -        String name = (String) properties.get (STORAGE_NAME);  // Not mandatory
    5.39 -        boolean persistent = false;
    5.40 -        Boolean persistFlag = (Boolean) properties.get (PERSISTENT_NAME);
    5.41 -        if (persistFlag != null)
    5.42 -            persistent = persistFlag.booleanValue ();
    5.43 -        return new StorageImpl (getSequencer ().nextValue (), name, persistent);
    5.44 +    public synchronized Storage createStorage(Map properties) throws StorageException {
    5.45 +        String name = (String) properties.get(NULL_STORAGE_ID);  // Not mandatory
    5.46 +        if (name == null || name.equals(NULL_STORAGE_ID)) {
    5.47 +            if (nullStorage == null) {
    5.48 +                nullStorage = new StorageImpl(NULL_STORAGE_ID, false);
    5.49 +            }
    5.50 +            return nullStorage;
    5.51 +        } else {
    5.52 +            Storage result = (Storage) storages.get(name);
    5.53 +            if (result == null) {
    5.54 +                result = new StorageImpl(NULL_STORAGE_ID, true);
    5.55 +                storages.put(name, result);
    5.56 +            }
    5.57 +            return result;
    5.58 +        }
    5.59      }
    5.60      
    5.61      public org.netbeans.mdr.persistence.MOFID createNullMOFID() throws StorageException {
    5.62 -        if (this.nullMOFID == null) {
    5.63 -            this.nullMOFID = new MOFID (0, MEMORY_STORAGE_PREFIX + Integer.toString (NULL_STORAGE));
    5.64 -        }
    5.65 -        return this.nullMOFID;
    5.66 +        return NULL_MOFID;
    5.67      }
    5.68 -    
    5.69 -    protected static Sequencer getSequencer () {
    5.70 -        if (sequencer == null) {
    5.71 -            sequencer = new Sequencer (NULL_STORAGE + 1);
    5.72 -        }
    5.73 -        return sequencer;
    5.74 -    }
    5.75 -    
    5.76 -    private static class Sequencer {
    5.77 -        
    5.78 -        private int current;
    5.79 -        
    5.80 -        public Sequencer () {
    5.81 -            this.current = 0;
    5.82 -        }
    5.83 -        
    5.84 -        public Sequencer (int initialValue) {
    5.85 -            this.current = initialValue;
    5.86 -        }
    5.87 -        
    5.88 -        public synchronized int nextValue () {
    5.89 -            return this.current++;
    5.90 -        }
    5.91 -    }
    5.92 -    
    5.93  }
     6.1 --- a/mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageImpl.java	Mon Oct 21 10:56:35 2002 +0000
     6.2 +++ b/mdr/src/org/netbeans/mdr/persistence/memoryimpl/StorageImpl.java	Mon Oct 21 17:44:29 2002 +0000
     6.3 @@ -17,101 +17,101 @@
     6.4  
     6.5  import org.netbeans.mdr.persistence.*;
     6.6  import org.netbeans.mdr.util.*;
     6.7 +import org.netbeans.mdr.util.IOUtils;
     6.8  
     6.9  //import org.w3c.dom.*;
    6.10  
    6.11  /** Default memory implementation of the Storage.
    6.12   * This implementation supports only one index with STORABLE values.
    6.13 - * @author  Pavel Buzek
    6.14 + * @author  Pavel Buzek, Martin Matula
    6.15   * @version
    6.16   */
    6.17 -public class StorageImpl extends Object implements Storage {
    6.18 +public class StorageImpl implements Storage {
    6.19 +    static final String PRIMARY_INDEX_NAME = "PI";
    6.20 +    private static final int INDEX_SINGLEVALUED = 1;
    6.21 +    private static final int INDEX_MULTIVALUED = 2;
    6.22 +    private static final int INDEX_ORDERED = 3;
    6.23 +
    6.24 +    private final HashMap maps = new HashMap();
    6.25 +    private final String storageId;
    6.26 +    private final boolean persistent;
    6.27      
    6.28 -    private static final String PRIMARY_INDEX_NAME = "_primaryIndex";
    6.29 -    private static final String INDENT = "  ";
    6.30 -    private static final String XMI_HEADER = "<?xml version = '1.0' ?><MDRStorage>";
    6.31 -    private static final String DEFAULT_NAME = "storage.xml";
    6.32 -    private static final String MEMORY_STORAGE_PREFIX = "MEM";
    6.33 -    private static final String MOFID_TAG = "MOFID";
    6.34 -    
    6.35 -    private static int lastMofId = 0;
    6.36 -    
    6.37 -    private TreeMap maps = new TreeMap();
    6.38 -    private String name;
    6.39 -    private String storageId;
    6.40 -    private SinglevaluedIndexImpl primaryIndex;
    6.41 -    private boolean persistent;
    6.42 +    private PrimaryIndexImpl primaryIndex;
    6.43 +    private boolean saveOnClose = false;
    6.44 +    private int lastMofId = 0;
    6.45      
    6.46      // variables related to transaction support
    6.47      private Set newIndexes = new HashSet (); // stores names of all new, still existing, indexes created during current transaction
    6.48      private HashMap removedIndexes = new HashMap (); // maps names to indexes created before the current transaction and dropped during the transaction
    6.49      
    6.50      /** Creates new StorageImpl */
    6.51 -    public StorageImpl(int memStorageNumber, String name, boolean persistent) {
    6.52 -        if (name == null) {
    6.53 -            this.name = DEFAULT_NAME;
    6.54 -        } else {
    6.55 -            this.name = name;
    6.56 -        }
    6.57 -        this.storageId = MEMORY_STORAGE_PREFIX + Integer.toString (memStorageNumber);
    6.58 +    public StorageImpl(String name, boolean persistent) {
    6.59 +        this.storageId = name;
    6.60          this.persistent = persistent;
    6.61      }
    6.62      
    6.63 -    public org.netbeans.mdr.persistence.MOFID resolveMOFID (String sMofId) {
    6.64 -        if (sMofId.startsWith (MEMORY_STORAGE_PREFIX)) {
    6.65 -            int index = sMofId.indexOf (':');   // NOI18N
    6.66 -            if (index == -1)
    6.67 +    public MOFID resolveMOFID (String sMofId) {
    6.68 +        if (sMofId.startsWith(storageId + ':')) {
    6.69 +            try {
    6.70 +                long serialNumber = Long.parseLong(sMofId.substring(storageId.length() + 1));
    6.71 +                return new MOFID(serialNumber, storageId);
    6.72 +            } catch (NumberFormatException e) {
    6.73                  return null;
    6.74 -            if (!sMofId.substring (0,index).equals (this.storageId))
    6.75 -                return null;
    6.76 -            long serialNumber = Long.parseLong (sMofId.substring (index+1));
    6.77 -            return new MOFID (serialNumber, this.storageId);
    6.78 +            }
    6.79          }
    6.80          return null;
    6.81      }
    6.82      
    6.83 -    public void writeMOFID (java.io.OutputStream outputStream, MOFID mofid) throws StorageException {
    6.84 +    public void writeMOFID (OutputStream outputStream, MOFID mofid) throws StorageException {
    6.85          try {
    6.86 -            outputStream.write (("<"+MOFID_TAG+">").getBytes ());
    6.87 -            outputStream.write (mofid.toString ().getBytes());
    6.88 -            outputStream.write (("</"+MOFID_TAG+">").getBytes ());
    6.89 -        }catch (java.io.IOException ioException) {
    6.90 +            if (storageId.equals(mofid.getStorageID())) {
    6.91 +                IOUtils.writeString(outputStream, null);
    6.92 +            } else {
    6.93 +                IOUtils.writeString(outputStream, mofid.getStorageID());
    6.94 +            }
    6.95 +            IOUtils.writeLong(outputStream, mofid.getSerialNumber());
    6.96 +        } catch (IOException ioException) {
    6.97              throw new StorageIOException (ioException);
    6.98          }
    6.99      }
   6.100      
   6.101      public MOFID readMOFID (java.io.InputStream inputStream) throws StorageException {
   6.102          try {
   6.103 -            String tagName = XmlUtils.readTagStart(inputStream);
   6.104 -            if (!tagName.equals (MOFID_TAG))
   6.105 -                throw new IllegalStateException ();
   6.106 -            String sMofId = XmlUtils.readTextTag(inputStream);
   6.107 -            MOFID result = this.resolveMOFID(sMofId);
   6.108 -            tagName = XmlUtils.readTagStart (inputStream);
   6.109 -            return result;
   6.110 +            String storageId = IOUtils.readString(inputStream);
   6.111 +            if (storageId == null) storageId = this.storageId;
   6.112 +            long serial = IOUtils.readLong(inputStream);
   6.113 +            return new MOFID(serial, storageId);
   6.114          } catch (java.io.IOException ioException) {
   6.115              throw new StorageIOException (ioException);
   6.116          }
   6.117      }
   6.118 -    
   6.119 -    // does nothing in this implementation
   6.120 -    public void create(boolean replace, ObjectResolver resolver) throws StorageException {
   6.121 -        if (!replace && exists()) {
   6.122 -            throw new StorageBadRequestException("Storage already exists");
   6.123 +
   6.124 +    // used to pre-boot the storage
   6.125 +    public synchronized void create(boolean replace, ObjectResolver resolver) throws StorageException {
   6.126 +        if (persistent) {
   6.127 +            if (!replace && exists()) {
   6.128 +                throw new StorageBadRequestException("Storage already exists");
   6.129 +            }
   6.130 +            try {
   6.131 +                new File(getName()).createNewFile();
   6.132 +            } catch (IOException e) {
   6.133 +                throw new StorageIOException(e);
   6.134 +            }
   6.135 +            saveOnClose = true;
   6.136          }
   6.137          createPrimaryIndex();
   6.138      }
   6.139      
   6.140 -    // does nothing in this implementation
   6.141 -    public void close() throws StorageException {
   6.142 +    public synchronized void close() throws StorageException {
   6.143 +        shutDown();
   6.144      }
   6.145      
   6.146 -    public boolean delete() throws StorageException {
   6.147 +    public synchronized boolean delete() throws StorageException {
   6.148          return new File(getName()).delete();
   6.149      }
   6.150      
   6.151      public String getName() {
   6.152 -        return this.name;
   6.153 +        return this.storageId;
   6.154      }
   6.155      
   6.156      public String getStorageId() {
   6.157 @@ -122,63 +122,68 @@
   6.158          return this.lastMofId++;
   6.159      }
   6.160      
   6.161 -    public boolean exists() throws StorageException {
   6.162 +    public synchronized boolean exists() throws StorageException {
   6.163          return new File(getName()).exists();
   6.164      }
   6.165      
   6.166 -    public void open(boolean createOnNoExist, ObjectResolver resolver) throws StorageException {
   6.167 -        Logger.getDefault().log("Reading storage from XML document ...");
   6.168 -        String className = null;
   6.169 +    public synchronized void open(boolean createOnNoExist, ObjectResolver resolver) throws StorageException {
   6.170 +//        Logger.getDefault().log("Reading storage from XML document ...");
   6.171 +        createPrimaryIndex();
   6.172          if (this.persistent) {
   6.173              try {
   6.174 -                InputStream is = new BufferedInputStream(new FileInputStream( name ));
   6.175 -                is.skip(XMI_HEADER.length());
   6.176 -                while (true) { // ends with EOFException
   6.177 -                    // read name of class
   6.178 -                    // create instance and call read on it
   6.179 -                    String str = XmlUtils.readTagStart(is); // <Index>
   6.180 -                    if (str.equals("/MDRStorage")) break;
   6.181 -                    className = XmlUtils.readTextTag(is); // <class>
   6.182 -                    Logger.getDefault().log("Index:"+className);
   6.183 -                    
   6.184 -                    Streamable object = null;
   6.185 -                    try {
   6.186 -                        Class cls = Class.forName(className);
   6.187 -                        object = (Streamable) cls.newInstance();
   6.188 -                        object.read(is);
   6.189 -                        maps.put(((Index)object).getName(),object);
   6.190 -                        if (((Index)object).getName().equals(PRIMARY_INDEX_NAME)) {
   6.191 -                            primaryIndex = (SinglevaluedIndexImpl) object;
   6.192 -                        }
   6.193 -                    } catch (ClassNotFoundException e) {
   6.194 -                        throw (StoragePersistentDataException) Logger.getDefault().annotate(new StoragePersistentDataException(e.getMessage()), e);
   6.195 -                    } catch (InstantiationException e) {
   6.196 -                        throw (StorageException) Logger.getDefault().annotate(new StoragePersistentDataException(e.getMessage()), e);
   6.197 -                    } catch (IllegalAccessException e) {
   6.198 -                        throw (StorageException) Logger.getDefault().annotate(new StoragePersistentDataException(e.getMessage()), e);
   6.199 +                if (!exists()) {
   6.200 +                    if (createOnNoExist) {
   6.201 +                        new File(getName()).createNewFile();
   6.202 +                        saveOnClose = true;
   6.203 +                        return;
   6.204 +                    } else {
   6.205 +                        throw new StorageBadRequestException("Storage " + getName() + " does not exist.");
   6.206                      }
   6.207 -                    XmlUtils.skipTagEnd(is); // </Index>
   6.208 +                }
   6.209 +
   6.210 +                InputStream is = new BufferedInputStream(new FileInputStream(getName()));
   6.211 +                lastMofId = IOUtils.readInt(is);
   6.212 +                primaryIndex = new PrimaryIndexImpl(this);
   6.213 +                primaryIndex.read(is);
   6.214 +                int size = IOUtils.readInt(is);
   6.215 +                for (int i = 0; i < size; i++) {
   6.216 +                    Streamable index;
   6.217 +                    switch (IOUtils.readInt(is)) {
   6.218 +                        case INDEX_SINGLEVALUED:
   6.219 +                            index = new SinglevaluedIndexImpl();
   6.220 +                            break;
   6.221 +                        case INDEX_MULTIVALUED:
   6.222 +                            index = new MultivaluedIndexImpl();
   6.223 +                            break;
   6.224 +                        case INDEX_ORDERED:
   6.225 +                            index = new MultivaluedOrderedIndexImpl();
   6.226 +                            break;
   6.227 +                        default:
   6.228 +                            throw new StoragePersistentDataException("Unknown type of index.");
   6.229 +                    }
   6.230 +                    index.read(is);
   6.231 +                    maps.put(((Index) index).getName(), index);
   6.232                  }
   6.233              } catch ( java.io.IOException e ) {
   6.234 -                throw (StoragePersistentDataException) Logger.getDefault().annotate(new StoragePersistentDataException(e.getMessage()), e);
   6.235 +                throw (StorageIOException) Logger.getDefault().annotate(new StorageIOException(e), e);
   6.236              }
   6.237          }
   6.238 -        Logger.getDefault().log("Finished reading document.");
   6.239 +//        Logger.getDefault().log("Finished reading document.");
   6.240      }
   6.241      
   6.242 -    public void objectStateWillChange(Object key) throws StorageException {
   6.243 -        ((PrimaryIndexImpl) primaryIndex).willChange (key);
   6.244 +    public synchronized void objectStateWillChange(Object key) throws StorageException {
   6.245 +        primaryIndex.willChange (key);
   6.246      }
   6.247      
   6.248 -    public void objectStateChanged(Object key) throws StorageException {
   6.249 +    public synchronized void objectStateChanged(Object key) throws StorageException {
   6.250          primaryIndex.changed (key);
   6.251      }
   6.252      
   6.253 -    public void rollBackChanges() throws StorageException {
   6.254 +    public synchronized void rollBackChanges() throws StorageException {
   6.255          // drop all indexes created during the transaction
   6.256          Iterator iter = newIndexes.iterator();
   6.257          while (iter.hasNext()) {
   6.258 -            maps.remove (iter.next ());
   6.259 +            maps.remove(iter.next());
   6.260          }
   6.261          // restore all indexes existing before the transaction that have been removed by the transaction
   6.262          iter = removedIndexes.keySet().iterator();
   6.263 @@ -198,11 +203,36 @@
   6.264          }
   6.265      }
   6.266      
   6.267 -    public void shutDown() throws StorageException {
   6.268 -        commitChanges ();
   6.269 +    public synchronized void shutDown() throws StorageException {
   6.270 +        commitChanges();
   6.271 +        if (this.saveOnClose) {
   6.272 +            try {
   6.273 +                OutputStream out = new BufferedOutputStream(new FileOutputStream(getName()));
   6.274 +                IOUtils.writeInt(out, lastMofId);
   6.275 +                primaryIndex.write(out);
   6.276 +                IOUtils.writeInt(out, maps.size());
   6.277 +                for (Iterator it = maps.values().iterator(); it.hasNext();){
   6.278 +                    Index index = (Index) it.next();
   6.279 +                    if (index instanceof SinglevaluedIndexImpl) {
   6.280 +                        out.write(INDEX_SINGLEVALUED);
   6.281 +                    } else if (index instanceof MultivaluedOrderedIndexImpl) {
   6.282 +                        out.write(INDEX_ORDERED);
   6.283 +                    } else if (index instanceof MultivaluedIndexImpl) {
   6.284 +                        out.write(INDEX_MULTIVALUED);
   6.285 +                    } else {
   6.286 +                        throw new DebugException("Invalid index class: " + index.getClass().getName());
   6.287 +                    }
   6.288 +//                    Logger.getDefault().log("Save index:" + index.getName());
   6.289 +                    ((Streamable) index).write(out);
   6.290 +                }
   6.291 +                out.close();
   6.292 +            } catch (IOException e) {
   6.293 +                throw (StorageIOException) Logger.getDefault().annotate(new StorageIOException(e), e);
   6.294 +            }
   6.295 +        }
   6.296      }
   6.297      
   6.298 -    public void commitChanges() throws StorageException {
   6.299 +    public synchronized void commitChanges() throws StorageException {
   6.300          newIndexes.clear();
   6.301          removedIndexes.clear();
   6.302          
   6.303 @@ -215,65 +245,41 @@
   6.304              else if (index instanceof MultivaluedIndexImpl)
   6.305                  ((MultivaluedIndexImpl) index).commitChanges();
   6.306          }
   6.307 -        
   6.308 -        if (this.persistent) {
   6.309 -            try {
   6.310 -                OutputStream outputStream = new BufferedOutputStream(new FileOutputStream( getName()));
   6.311 -                String str = XMI_HEADER;
   6.312 -                outputStream.write(str.getBytes());
   6.313 -                for (Iterator it = maps.values().iterator(); it.hasNext();){
   6.314 -                    Object index = it.next();
   6.315 -                    String className = index.getClass().getName();
   6.316 -                    str = "<Index><class>"+className+"</class>";
   6.317 -                    outputStream.write(str.getBytes());
   6.318 -                    Logger.getDefault().log("Save index:" + ((Index)index).getName() );
   6.319 -                    ((Streamable) index).write(outputStream);
   6.320 -                    //Log.out.println("...saved");
   6.321 -                    str = "</Index>";
   6.322 -                    outputStream.write(str.getBytes());
   6.323 -                }
   6.324 -                str = "</MDRStorage>";
   6.325 -                outputStream.write(str.getBytes());
   6.326 -                outputStream.close();
   6.327 -            } catch (java.io.IOException e) {
   6.328 -                Logger.getDefault().notify(e);
   6.329 -            }
   6.330 -        }
   6.331      }
   6.332      
   6.333 -    public SinglevaluedIndex getSinglevaluedIndex(String name) throws StorageException {
   6.334 +    public synchronized SinglevaluedIndex getSinglevaluedIndex(String name) throws StorageException {
   6.335          return (SinglevaluedIndex) getIndex(name);
   6.336      }
   6.337      
   6.338 -    public MultivaluedIndex getMultivaluedIndex(String name) throws StorageException {
   6.339 +    public synchronized MultivaluedIndex getMultivaluedIndex(String name) throws StorageException {
   6.340          return (MultivaluedIndex) getIndex(name);
   6.341      }
   6.342      
   6.343 -    public MultivaluedOrderedIndex getMultivaluedOrderedIndex(String name) throws StorageException {
   6.344 +    public synchronized MultivaluedOrderedIndex getMultivaluedOrderedIndex(String name) throws StorageException {
   6.345          return (MultivaluedOrderedIndex) getIndex(name);
   6.346      }
   6.347      
   6.348 -    public void dropIndex(String name) throws StorageException {
   6.349 +    public synchronized void dropIndex(String name) throws StorageException {
   6.350          Object index = maps.remove(name);
   6.351          if ((index != null) && !newIndexes.remove(name))
   6.352              removedIndexes.put (name, index);            
   6.353      }
   6.354      
   6.355 -    private void addIndex(String name, Index index) throws StorageException {
   6.356 +    private synchronized void addIndex(String name, Index index) throws StorageException {
   6.357          maps.put(name, index);        
   6.358          newIndexes.add (name);
   6.359      }
   6.360      
   6.361 -    public boolean supportsMultipleStorableIndexes() throws StorageException {
   6.362 -        return true;
   6.363 -    }
   6.364 +//    public boolean supportsMultipleStorableIndexes() throws StorageException {
   6.365 +//        return true;
   6.366 +//    }
   6.367      
   6.368      /** Creates SinglevaluedIndex.
   6.369       * @param name Singlevalued name of the index
   6.370       * @param type type of indexes values
   6.371       * @return created index
   6.372       */
   6.373 -    public SinglevaluedIndex createSinglevaluedIndex(String name,EntryType keyType,EntryType valueType) throws StorageException {
   6.374 +    public synchronized SinglevaluedIndex createSinglevaluedIndex(String name,EntryType keyType,EntryType valueType) throws StorageException {
   6.375          if (valueType.equals(EntryType.STREAMABLE)) {
   6.376              throw new StorageBadRequestException("Cannot create another primary index with STREAMABLE value type.");
   6.377          }
   6.378 @@ -287,7 +293,7 @@
   6.379       * @param type
   6.380       * @return
   6.381       */
   6.382 -    public MultivaluedOrderedIndex createMultivaluedOrderedIndex(String name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
   6.383 +    public synchronized MultivaluedOrderedIndex createMultivaluedOrderedIndex(String name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
   6.384          MultivaluedOrderedIndex sm = new MultivaluedOrderedIndexImpl(name, keyType, valueType, unique);
   6.385          addIndex(name, sm);
   6.386          return sm;
   6.387 @@ -298,7 +304,7 @@
   6.388       * @param type type of indexes values
   6.389       * @return created index
   6.390       */
   6.391 -    public MultivaluedIndex createMultivaluedIndex(String name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
   6.392 +    public synchronized MultivaluedIndex createMultivaluedIndex(String name,EntryType keyType,EntryType valueType,boolean unique) throws StorageException {
   6.393          MultivaluedIndex sm = new MultivaluedIndexImpl(name, keyType, valueType, unique);
   6.394          addIndex(name, sm);
   6.395          return sm;
   6.396 @@ -307,14 +313,14 @@
   6.397      /** Returns the primary index in this Storage. There is exactly one primary
   6.398       * index in every storage.
   6.399       */
   6.400 -    public SinglevaluedIndex getPrimaryIndex() throws StorageException {
   6.401 +    public synchronized SinglevaluedIndex getPrimaryIndex() throws StorageException {
   6.402          return this.primaryIndex;
   6.403      }
   6.404      
   6.405      /** Creates primary index. Primary index is SinglevaluedIndex with STREAMABLE valueType.
   6.406       */
   6.407      private void createPrimaryIndex() throws StorageException {
   6.408 -        this.primaryIndex = new PrimaryIndexImpl(this, PRIMARY_INDEX_NAME, EntryType.MOFID, EntryType.STREAMABLE);
   6.409 +        this.primaryIndex = new PrimaryIndexImpl(this);
   6.410          addIndex(PRIMARY_INDEX_NAME, this.primaryIndex);
   6.411      }
   6.412      
   6.413 @@ -322,7 +328,7 @@
   6.414       * @param name name of the index
   6.415       * @return index of the specified name
   6.416       */
   6.417 -    public Index getIndex(String name) throws StorageException {
   6.418 +    public synchronized Index getIndex(String name) throws StorageException {
   6.419          return (Index) maps.get(name);
   6.420      }
   6.421      
     7.1 --- a/mdr/src/org/netbeans/mdr/util/TransactionMutex.java	Mon Oct 21 10:56:35 2002 +0000
     7.2 +++ b/mdr/src/org/netbeans/mdr/util/TransactionMutex.java	Mon Oct 21 17:44:29 2002 +0000
     7.3 @@ -177,7 +177,7 @@
     7.4                              notifier.fireChanged();
     7.5                              storage.commit();
     7.6                              //Logger.getDefault().log("commited");
     7.7 -                            Logger.getDefault().notify(Logger.INFORMATIONAL, new DebugException("commit"));
     7.8 +//                            Logger.getDefault().notify(Logger.INFORMATIONAL, new DebugException("commit"));
     7.9                          }
    7.10                      } catch (StorageException e) {
    7.11                          try {