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 {