You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/03/27 18:49:28 UTC

svn commit: r389196 - in /incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax: crypto/spec/SecretKeySpec.java security/auth/kerberos/KerberosKey.java

Author: tellison
Date: Mon Mar 27 08:49:26 2006
New Revision: 389196

URL: http://svn.apache.org/viewcvs?rev=389196&view=rev
Log:
Apply patch HARMONY-233 (private serialVersionID field should be set in javax.security.auth.kerberos.KerberosKey class)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/crypto/spec/SecretKeySpec.java
    incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/security/auth/kerberos/KerberosKey.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/crypto/spec/SecretKeySpec.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/crypto/spec/SecretKeySpec.java?rev=389196&r1=389195&r2=389196&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/crypto/spec/SecretKeySpec.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/crypto/spec/SecretKeySpec.java Mon Mar 27 08:49:26 2006
@@ -1,116 +1,121 @@
-/*
- *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/**
-* @author Alexander Y. Kleymenov
-* @version $Revision$
-*/
-
-package javax.crypto.spec;
-
-import java.io.Serializable;
-import java.security.spec.KeySpec;
-import java.util.Arrays;
-import javax.crypto.SecretKey;
-
-/**
- * @com.intel.drl.spec_ref
- */
-public class SecretKeySpec implements SecretKey, KeySpec, Serializable {
-
-    private final byte[] key;
-    private final String algorithm;
-    private final String format = "RAW";
-
-    private static final IllegalArgumentException BADPARAMS_EXC =
-            new IllegalArgumentException(
-                    "algorithm is null or key is null, empty, or too short.");
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public SecretKeySpec(byte[] key, String algorithm) {
-        if ((key == null) || (key.length == 0) || (algorithm == null)) {
-            throw BADPARAMS_EXC;
-        }
-        this.algorithm = algorithm;
-        this.key = new byte[key.length];
-        System.arraycopy(key, 0, this.key, 0, key.length);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
-        if ((key == null) || (key.length == 0)
-                || (key.length - offset < len) || (algorithm == null)) {
-            throw BADPARAMS_EXC;
-        }
-        this.algorithm = algorithm;
-        this.key = new byte[len];
-        System.arraycopy(key, offset, this.key, 0, len);
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public String getFormat() {
-        return format;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public byte[] getEncoded() {
-        byte[] result = new byte[key.length];
-        System.arraycopy(key, 0, result, 0, key.length);
-        return result;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public int hashCode() {
-        int result = algorithm.length();
-        for (int i=0; i<key.length; i++) {
-            result += key[i];
-        }
-        return result;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof SecretKeySpec)) {
-            return false;
-        }
-        SecretKeySpec ks = (SecretKeySpec) obj;
-        return (algorithm.equalsIgnoreCase(ks.algorithm))
-            && (Arrays.equals(key, ks.key));
-    }
-}
-
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package javax.crypto.spec;
+
+import java.io.Serializable;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import javax.crypto.SecretKey;
+
+/**
+ * @com.intel.drl.spec_ref
+ */
+public class SecretKeySpec implements SecretKey, KeySpec, Serializable {
+
+    // The 5.0 spec. doesn't declare this serialVersionUID field
+    // In order to be compatible it is explicitly declared here
+    // for details see HARMONY-233
+    private static final long serialVersionUID = 6577238317307289933L;
+
+    private final byte[] key;
+    private final String algorithm;
+    private final String format = "RAW";
+
+    private static final IllegalArgumentException BADPARAMS_EXC =
+            new IllegalArgumentException(
+                    "algorithm is null or key is null, empty, or too short.");
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public SecretKeySpec(byte[] key, String algorithm) {
+        if ((key == null) || (key.length == 0) || (algorithm == null)) {
+            throw BADPARAMS_EXC;
+        }
+        this.algorithm = algorithm;
+        this.key = new byte[key.length];
+        System.arraycopy(key, 0, this.key, 0, key.length);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
+        if ((key == null) || (key.length == 0)
+                || (key.length - offset < len) || (algorithm == null)) {
+            throw BADPARAMS_EXC;
+        }
+        this.algorithm = algorithm;
+        this.key = new byte[len];
+        System.arraycopy(key, offset, this.key, 0, len);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String getFormat() {
+        return format;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public byte[] getEncoded() {
+        byte[] result = new byte[key.length];
+        System.arraycopy(key, 0, result, 0, key.length);
+        return result;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int hashCode() {
+        int result = algorithm.length();
+        for (int i=0; i<key.length; i++) {
+            result += key[i];
+        }
+        return result;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof SecretKeySpec)) {
+            return false;
+        }
+        SecretKeySpec ks = (SecretKeySpec) obj;
+        return (algorithm.equalsIgnoreCase(ks.algorithm))
+            && (Arrays.equals(key, ks.key));
+    }
+}
+

Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/security/auth/kerberos/KerberosKey.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/security/auth/kerberos/KerberosKey.java?rev=389196&r1=389195&r2=389196&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/security/auth/kerberos/KerberosKey.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/common/javasrc/javax/security/auth/kerberos/KerberosKey.java Mon Mar 27 08:49:26 2006
@@ -1,303 +1,305 @@
-/*
- *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/**
-* @author Maxim V. Makarov
-* @version $Revision$
-*/
-
-package javax.security.auth.kerberos;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.Arrays;
-
-import javax.crypto.SecretKey;
-import javax.security.auth.DestroyFailedException;
-import javax.security.auth.Destroyable;
-
-import org.apache.harmony.security.utils.Array;
-
-/**
- * @com.intel.drl.spec_ref
- * 
- */
-public class KerberosKey implements SecretKey, Destroyable {
-
-    //principal    
-    private KerberosPrincipal principal;
-
-    //key version number
-    private int versionNum;
-    
-    //raw bytes for the sicret key
-    private KeyImpl key;
-    
-    // indicates the ticket state
-    private transient boolean destroyed;
-    
-    
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public KerberosKey(KerberosPrincipal principal, byte[] keyBytes,
-                       int keyType, int versionNumber) {
-        //TODO: is a principal mutable ? 
-        this.principal = principal;
-        this.versionNum = versionNumber;
-        
-        if (keyBytes == null) {
-            throw new IllegalArgumentException("key is null");
-        }
-        
-        this.key = new KeyImpl(keyBytes, keyType);
-        
-    }
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public KerberosKey(KerberosPrincipal principal, char[] password,
-                       String algorithm) {
-        this.key = new KeyImpl(principal, password, algorithm);
-    }
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final KerberosPrincipal getPrincipal() {
-        checkState();
-        return principal;
-    }
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final String getAlgorithm() {
-        checkState();
-        return key.getAlgorithm();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final String getFormat() {
-        checkState();
-        return key.getFormat();
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final int getKeyType() {
-        checkState();
-        return key.getKeyType();
-    }  
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final byte[] getEncoded() {
-        checkState();
-        return key.getEncoded();
-    }
-    
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public final int getVersionNumber()  {
-        checkState();
-        return versionNum;
-    } 
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public void destroy() throws DestroyFailedException {
-        if (!destroyed) {
-            this.principal = null;
-            key.destroy();
-            this.destroyed = true;
-        }
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public boolean isDestroyed() {
-        return destroyed;
-    }
-
-    /**
-     * @com.intel.drl.spec_ref
-     */
-    public String toString() {
-        checkState();
-        StringBuffer sb = new StringBuffer();
-        sb.append("KerberosPrincipal ").append(principal.getName()).append("\n");
-        sb.append("KeyVersion ").append(versionNum).append("\n");
-        sb.append(key.toString());
-        return sb.toString();
-    } 
-    
-    // if a key is destroyed then IllegalStateException must be thrown 
-    private void checkState() {
-        if (destroyed) {
-            throw new IllegalStateException ("The key is destroyed");
-        }
-    }
-}
-
-/**
- * This class encapsulates a Kerberos encryption key.
- * 
- */
-class KeyImpl implements SecretKey, Destroyable, Serializable {
-
-    private transient byte[] keyBytes;
-
-    private transient int keyType;
-    
-    //  indicates the ticket state
-    private transient boolean destroyed;
-    
-    /**
-     * creates a secret key from a given raw bytes
-     * 
-     * @param keyBytes
-     * @param keyType
-     */
-    public KeyImpl(byte[] keyBytes, int keyType) {
-        this.keyBytes = new byte[keyBytes.length];
-        System.arraycopy(keyBytes , 0, this.keyBytes, 0, this.keyBytes.length); 
-        this.keyType = keyType;
-    }
-    /**
-     * creates a secret key from a given password
-     * 
-     * @param principal
-     * @param password
-     * @param algorithm
-     */
-    public KeyImpl(KerberosPrincipal principal, char[] password, String algorithm) {
-
-        //TODO: need to read a key from a Kerberos "keytab". 
-        throw new UnsupportedOperationException ();
-/*        if (principal == null || password == null || algorithm == null) {
-            throw new NullPointerException();
-        }
-        this.principal = principal;
-        this.password = (char[])password.clone();
-        this.algorithm = algorithm;
-*/        
-    }
-    
-    /**
-     * Method is described in 
-     * <code>getAlgorithm</code> in interface <code>Key</code>
-     */
-    public final String getAlgorithm() {
-        checkState();
-        //TODO: if algoritm is null then return "DES"
-        // else return another algoritm
-        return "DES";
-    }
-    
-    /**
-     * Method is described in
-     * <code>getFormat</code> in interface <code>Key</code>
-     */
-    public final String getFormat() {
-        checkState();
-        return "RAW";
-    }
-   
-    /**
-     * Method is described in
-     * <code>getEncoded</code> in interface <code>Key</code>
-     */
-    public final byte[] getEncoded() {
-        checkState();
-        byte[] tmp = new byte[keyBytes.length];
-        System.arraycopy(keyBytes, 0, tmp, 0, tmp.length);
-        return tmp;
-    }
-
-    /**
-     * Returns the key type for this key
-     */
-    public final int getKeyType() {
-        checkState();
-        return keyType;
-    }
-
-    /**
-     * Destroys this key
-     */
-    public void destroy() throws DestroyFailedException {
-        if (!destroyed) {
-            Arrays.fill(keyBytes, (byte) 0); 
-            destroyed = true;
-        }
-        
-    }
-    /**
-     * Determines if this key has been destroyed 
-     */
-   public boolean isDestroyed() {
-        return destroyed;
-    }
-
-   /**
-    * A string representation of this key
-    */
-   public String toString() {
-       String s_key = null;
-       StringBuffer sb = new StringBuffer();
-       
-       if (keyBytes.length == 0) {
-           s_key = "Empty Key";
-       } else {
-           s_key = Array.toString(keyBytes," ");
-       }
-       sb.append("EncryptionKey: ").append("KeyType = ").append(keyType);
-       sb.append("KeyBytes (Hex dump) = ").append(s_key);
-       return sb.toString();
-   }
-   
-   /**
-    * if a key is destroyed then IllegalStateException should be thrown
-    */  
-   private void checkState() {
-       if (destroyed) {
-           throw new IllegalStateException ("The key is destroyed");
-       }
-   }
-
-   // TODO: read a object from a stream
-   private void readObject(ObjectInputStream s) throws IOException,
-       ClassNotFoundException {
-       s.defaultReadObject();
-   }
-
-   // TODO: write a object to a stream
-   private void writeObject(ObjectOutputStream s) throws IOException {
-       s.defaultWriteObject();
-   }
-
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+* @author Maxim V. Makarov
+* @version $Revision$
+*/
+
+package javax.security.auth.kerberos;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import javax.crypto.SecretKey;
+import javax.security.auth.DestroyFailedException;
+import javax.security.auth.Destroyable;
+
+import org.apache.harmony.security.utils.Array;
+
+/**
+ * @com.intel.drl.spec_ref
+ * 
+ */
+public class KerberosKey implements SecretKey, Destroyable {
+
+    private static final long serialVersionUID = -4625402278148246993L;
+    
+    //principal    
+    private KerberosPrincipal principal;
+
+    //key version number
+    private int versionNum;
+    
+    //raw bytes for the sicret key
+    private KeyImpl key;
+    
+    // indicates the ticket state
+    private transient boolean destroyed;
+    
+    
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public KerberosKey(KerberosPrincipal principal, byte[] keyBytes,
+                       int keyType, int versionNumber) {
+        //TODO: is a principal mutable ? 
+        this.principal = principal;
+        this.versionNum = versionNumber;
+        
+        if (keyBytes == null) {
+            throw new IllegalArgumentException("key is null");
+        }
+        
+        this.key = new KeyImpl(keyBytes, keyType);
+        
+    }
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public KerberosKey(KerberosPrincipal principal, char[] password,
+                       String algorithm) {
+        this.key = new KeyImpl(principal, password, algorithm);
+    }
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final KerberosPrincipal getPrincipal() {
+        checkState();
+        return principal;
+    }
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final String getAlgorithm() {
+        checkState();
+        return key.getAlgorithm();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final String getFormat() {
+        checkState();
+        return key.getFormat();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final int getKeyType() {
+        checkState();
+        return key.getKeyType();
+    }  
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final byte[] getEncoded() {
+        checkState();
+        return key.getEncoded();
+    }
+    
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public final int getVersionNumber()  {
+        checkState();
+        return versionNum;
+    } 
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public void destroy() throws DestroyFailedException {
+        if (!destroyed) {
+            this.principal = null;
+            key.destroy();
+            this.destroyed = true;
+        }
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean isDestroyed() {
+        return destroyed;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String toString() {
+        checkState();
+        StringBuffer sb = new StringBuffer();
+        sb.append("KerberosPrincipal ").append(principal.getName()).append("\n");
+        sb.append("KeyVersion ").append(versionNum).append("\n");
+        sb.append(key.toString());
+        return sb.toString();
+    } 
+    
+    // if a key is destroyed then IllegalStateException must be thrown 
+    private void checkState() {
+        if (destroyed) {
+            throw new IllegalStateException ("The key is destroyed");
+        }
+    }
+}
+
+/**
+ * This class encapsulates a Kerberos encryption key.
+ * 
+ */
+class KeyImpl implements SecretKey, Destroyable, Serializable {
+
+    private transient byte[] keyBytes;
+
+    private transient int keyType;
+    
+    //  indicates the ticket state
+    private transient boolean destroyed;
+    
+    /**
+     * creates a secret key from a given raw bytes
+     * 
+     * @param keyBytes
+     * @param keyType
+     */
+    public KeyImpl(byte[] keyBytes, int keyType) {
+        this.keyBytes = new byte[keyBytes.length];
+        System.arraycopy(keyBytes , 0, this.keyBytes, 0, this.keyBytes.length); 
+        this.keyType = keyType;
+    }
+    /**
+     * creates a secret key from a given password
+     * 
+     * @param principal
+     * @param password
+     * @param algorithm
+     */
+    public KeyImpl(KerberosPrincipal principal, char[] password, String algorithm) {
+
+        //TODO: need to read a key from a Kerberos "keytab". 
+        throw new UnsupportedOperationException ();
+/*        if (principal == null || password == null || algorithm == null) {
+            throw new NullPointerException();
+        }
+        this.principal = principal;
+        this.password = (char[])password.clone();
+        this.algorithm = algorithm;
+*/        
+    }
+    
+    /**
+     * Method is described in 
+     * <code>getAlgorithm</code> in interface <code>Key</code>
+     */
+    public final String getAlgorithm() {
+        checkState();
+        //TODO: if algoritm is null then return "DES"
+        // else return another algoritm
+        return "DES";
+    }
+    
+    /**
+     * Method is described in
+     * <code>getFormat</code> in interface <code>Key</code>
+     */
+    public final String getFormat() {
+        checkState();
+        return "RAW";
+    }
+   
+    /**
+     * Method is described in
+     * <code>getEncoded</code> in interface <code>Key</code>
+     */
+    public final byte[] getEncoded() {
+        checkState();
+        byte[] tmp = new byte[keyBytes.length];
+        System.arraycopy(keyBytes, 0, tmp, 0, tmp.length);
+        return tmp;
+    }
+
+    /**
+     * Returns the key type for this key
+     */
+    public final int getKeyType() {
+        checkState();
+        return keyType;
+    }
+
+    /**
+     * Destroys this key
+     */
+    public void destroy() throws DestroyFailedException {
+        if (!destroyed) {
+            Arrays.fill(keyBytes, (byte) 0); 
+            destroyed = true;
+        }
+        
+    }
+    /**
+     * Determines if this key has been destroyed 
+     */
+   public boolean isDestroyed() {
+        return destroyed;
+    }
+
+   /**
+    * A string representation of this key
+    */
+   public String toString() {
+       String s_key = null;
+       StringBuffer sb = new StringBuffer();
+       
+       if (keyBytes.length == 0) {
+           s_key = "Empty Key";
+       } else {
+           s_key = Array.toString(keyBytes," ");
+       }
+       sb.append("EncryptionKey: ").append("KeyType = ").append(keyType);
+       sb.append("KeyBytes (Hex dump) = ").append(s_key);
+       return sb.toString();
+   }
+   
+   /**
+    * if a key is destroyed then IllegalStateException should be thrown
+    */  
+   private void checkState() {
+       if (destroyed) {
+           throw new IllegalStateException ("The key is destroyed");
+       }
+   }
+
+   // TODO: read a object from a stream
+   private void readObject(ObjectInputStream s) throws IOException,
+       ClassNotFoundException {
+       s.defaultReadObject();
+   }
+
+   // TODO: write a object to a stream
+   private void writeObject(ObjectOutputStream s) throws IOException {
+       s.defaultWriteObject();
+   }
+
 }