diff options
| author | Benjamin Culkin <scorpress@gmail.com> | 2024-05-20 17:58:16 -0400 |
|---|---|---|
| committer | Benjamin Culkin <scorpress@gmail.com> | 2024-05-20 17:58:16 -0400 |
| commit | 40a9d99496e098562f090fb7ffce9e749011b131 (patch) | |
| tree | 437df24d65470582e943e494a52db8ed65a881ae /projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java | |
| parent | ff072dfe782f6f22123cd4ba050828d35c0d0fbd (diff) | |
Formatting pass
Diffstat (limited to 'projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java')
| -rw-r--r-- | projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java | 1140 |
1 files changed, 484 insertions, 656 deletions
diff --git a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java index 1aa2147..d052fcf 100644 --- a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java +++ b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/KeyValueCodingUtilities.java @@ -38,227 +38,169 @@ import net.wotonomy.foundation.internal.Duplicator; import net.wotonomy.foundation.internal.WotonomyException; /** -* KeyValueCodingUtilities implements what -* EOKeyValueCodingSupport leaves out. Importantly, -* this class implements the deep clone and deep copy -* operations that are essential to the functioning of -* nested editing contexts. -* -* @author michael@mpowers.net -* @author $Author: cgruber $ -* @version $Revision: 900 $ -*/ -public class KeyValueCodingUtilities -{ - /** - * Returns a Map of the specified keys to their values, - * each of which is obtained by calling valueForKey - * on the specified object if it implements EOKeyValueCoding, - * and otherwise falling back on EOKeyValueCodingSupport. - * Null values must be represented by NSNull.nullValue(). - */ - static public NSDictionary valuesForKeys( - Object anObject, List aKeyList ) - { - return valuesForKeys( anObject, aKeyList, false ); - } - - /** - * Returns a Map of the specified keys to their values, - * each of which is obtained by calling storedValueForKey - * on the specified object if it implements EOKeyValueCoding, - * and otherwise falling back on EOKeyValueCodingSupport. - * Null values must be represented by NSNull.nullValue(). - */ - static public NSDictionary storedValuesForKeys( - Object anObject, List aKeyList ) - { - return valuesForKeys( anObject, aKeyList, true ); - } - - /** - * Called by valuesForKeys and storedValuesForKeys. - * This uses storedValueForKey if isStored is true, - * otherwise uses valueForKey. - */ - static private NSDictionary valuesForKeys( - Object anObject, List aKeyList, boolean isStored ) - { - EOKeyValueCoding coding; - if ( anObject instanceof EOKeyValueCoding ) - { - coding = (EOKeyValueCoding) anObject; - } - else - { - coding = null; - } - - String key; - Object value; - NSMutableDictionary result = new NSMutableDictionary(); - Iterator it = aKeyList.iterator(); - while ( it.hasNext() ) - { - //TODO: get rid of this try/catch - exceptions should be fatal (?) - try - { - key = it.next().toString(); - if ( coding != null ) - { - if ( isStored ) - value = coding.storedValueForKey( key ); - else - value = coding.valueForKey( key ); - } - else - { - if ( isStored ) - value = EOKeyValueCodingSupport.storedValueForKey( anObject, key ); - else - value = EOKeyValueCodingSupport.valueForKey( anObject, key ); - } - if ( value == null ) - { - value = EONullValue.nullValue(); - } - result.setObjectForKey( value, key ); - } - catch ( RuntimeException exc ) - { - System.out.println( - "KeyValueCodingUtilities.valuesForKeys: " - + isStored + " : " + exc ); - } - } - return result; - } - - /** - * Takes the keys from the specified Map as properties - * and applies the corresponding values, each of which - * might be set by calling takeValueForKey on the - * specified object if it implements EOKeyValueCoding, - * and otherwise falling back on EOKeyValueCodingSupport. - * Null values must be represented by NSNull.nullValue(). - */ - static public void takeValuesFromDictionary( - Object anObject, Map aMap ) - { - takeStoredValuesFromDictionary( anObject, aMap, false ); - } - - /** - * Takes the keys from the specified Map as properties - * and applies the corresponding values, each of which - * might be set by calling takeStoredValueForKey on the - * specified object if it implements EOKeyValueCoding, - * and otherwise falling back on EOKeyValueCodingSupport. - * Null values must be represented by NSNull.nullValue(). - */ - static public void takeStoredValuesFromDictionary( - Object anObject, Map aMap ) - { - takeStoredValuesFromDictionary( anObject, aMap, true ); - } - - /** - * Called by takeValuesFromDictionary and takeStoredValuesFromDictionary. - * This uses takeStoredValueForKey if isStored is true, - * otherwise uses takeValueForKey. - */ - static private void takeStoredValuesFromDictionary( - Object anObject, Map aMap, boolean isStored ) - { - EOKeyValueCoding coding; - if ( anObject instanceof EOKeyValueCoding ) - { - coding = (EOKeyValueCoding) anObject; - } - else - { - coding = null; - } - - String key; - Object value; - NSMutableDictionary result = new NSMutableDictionary(); - Iterator it = aMap.keySet().iterator(); - while ( it.hasNext() ) - { - //TODO: get rid of this try/catch - exceptions should be fatal (?) - try - { - key = it.next().toString(); - value = aMap.get( key ); - if ( value instanceof EONullValue ) - // can't use == nullValue() because of cloning/serialization - { - value = null; - } - if ( coding != null ) - { - if ( isStored ) - coding.takeStoredValueForKey( value, key ); - else - coding.takeValueForKey( value, key ); - } - else - { - if ( isStored ) - EOKeyValueCodingSupport.takeStoredValueForKey( - anObject, value, key ); - else - EOKeyValueCodingSupport.takeValueForKey( - anObject, value, key ); - } - } - catch ( WotonomyException exc ) - { - System.out.println( - "KeyValueCodingUtilities.takeStoredValuesFromDictionary: " - + isStored + " : " + exc ); - } - } - } - - /** - * Creates a deep clone of the specified object. - * (Object.clone() only creates a shallow clone.) - * Returns null if operation fails. - */ - static public Object clone( Object aSource ) - { - return Duplicator.deepClone( aSource ); - } - - /** - * Creates a deep clone of the specified object, - * registered in the specified source editing context, - * transposing it into the specified destination - * editing context. - * Returns null if operation fails. - */ - static public Object clone( - EOEditingContext aSourceContext, Object aSource, - EOEditingContext aDestinationContext ) - { - return clone( aSourceContext, aSource, aDestinationContext, aSource ); - } - - /** - * Called by clone and copy. - * The specified root object will not be replaced - * by an object in the destination editing context: - * this should be the same as the source object for - * cloning, but should be null for copying. - * Returns null if operation fails. - */ - static private Object clone( - EOEditingContext aSourceContext, Object aSource, - EOEditingContext aDestinationContext, - Object aRootObject ) - { + * KeyValueCodingUtilities implements what EOKeyValueCodingSupport leaves out. + * Importantly, this class implements the deep clone and deep copy operations + * that are essential to the functioning of nested editing contexts. + * + * @author michael@mpowers.net + * @author $Author: cgruber $ + * @version $Revision: 900 $ + */ +public class KeyValueCodingUtilities { + /** + * Returns a Map of the specified keys to their values, each of which is + * obtained by calling valueForKey on the specified object if it implements + * EOKeyValueCoding, and otherwise falling back on EOKeyValueCodingSupport. Null + * values must be represented by NSNull.nullValue(). + */ + static public NSDictionary valuesForKeys(Object anObject, List aKeyList) { + return valuesForKeys(anObject, aKeyList, false); + } + + /** + * Returns a Map of the specified keys to their values, each of which is + * obtained by calling storedValueForKey on the specified object if it + * implements EOKeyValueCoding, and otherwise falling back on + * EOKeyValueCodingSupport. Null values must be represented by + * NSNull.nullValue(). + */ + static public NSDictionary storedValuesForKeys(Object anObject, List aKeyList) { + return valuesForKeys(anObject, aKeyList, true); + } + + /** + * Called by valuesForKeys and storedValuesForKeys. This uses storedValueForKey + * if isStored is true, otherwise uses valueForKey. + */ + static private NSDictionary valuesForKeys(Object anObject, List aKeyList, boolean isStored) { + EOKeyValueCoding coding; + if (anObject instanceof EOKeyValueCoding) { + coding = (EOKeyValueCoding) anObject; + } else { + coding = null; + } + + String key; + Object value; + NSMutableDictionary result = new NSMutableDictionary(); + Iterator it = aKeyList.iterator(); + while (it.hasNext()) { + // TODO: get rid of this try/catch - exceptions should be fatal (?) + try { + key = it.next().toString(); + if (coding != null) { + if (isStored) + value = coding.storedValueForKey(key); + else + value = coding.valueForKey(key); + } else { + if (isStored) + value = EOKeyValueCodingSupport.storedValueForKey(anObject, key); + else + value = EOKeyValueCodingSupport.valueForKey(anObject, key); + } + if (value == null) { + value = EONullValue.nullValue(); + } + result.setObjectForKey(value, key); + } catch (RuntimeException exc) { + System.out.println("KeyValueCodingUtilities.valuesForKeys: " + isStored + " : " + exc); + } + } + return result; + } + + /** + * Takes the keys from the specified Map as properties and applies the + * corresponding values, each of which might be set by calling takeValueForKey + * on the specified object if it implements EOKeyValueCoding, and otherwise + * falling back on EOKeyValueCodingSupport. Null values must be represented by + * NSNull.nullValue(). + */ + static public void takeValuesFromDictionary(Object anObject, Map aMap) { + takeStoredValuesFromDictionary(anObject, aMap, false); + } + + /** + * Takes the keys from the specified Map as properties and applies the + * corresponding values, each of which might be set by calling + * takeStoredValueForKey on the specified object if it implements + * EOKeyValueCoding, and otherwise falling back on EOKeyValueCodingSupport. Null + * values must be represented by NSNull.nullValue(). + */ + static public void takeStoredValuesFromDictionary(Object anObject, Map aMap) { + takeStoredValuesFromDictionary(anObject, aMap, true); + } + + /** + * Called by takeValuesFromDictionary and takeStoredValuesFromDictionary. This + * uses takeStoredValueForKey if isStored is true, otherwise uses + * takeValueForKey. + */ + static private void takeStoredValuesFromDictionary(Object anObject, Map aMap, boolean isStored) { + EOKeyValueCoding coding; + if (anObject instanceof EOKeyValueCoding) { + coding = (EOKeyValueCoding) anObject; + } else { + coding = null; + } + + String key; + Object value; + NSMutableDictionary result = new NSMutableDictionary(); + Iterator it = aMap.keySet().iterator(); + while (it.hasNext()) { + // TODO: get rid of this try/catch - exceptions should be fatal (?) + try { + key = it.next().toString(); + value = aMap.get(key); + if (value instanceof EONullValue) + // can't use == nullValue() because of cloning/serialization + { + value = null; + } + if (coding != null) { + if (isStored) + coding.takeStoredValueForKey(value, key); + else + coding.takeValueForKey(value, key); + } else { + if (isStored) + EOKeyValueCodingSupport.takeStoredValueForKey(anObject, value, key); + else + EOKeyValueCodingSupport.takeValueForKey(anObject, value, key); + } + } catch (WotonomyException exc) { + System.out.println("KeyValueCodingUtilities.takeStoredValuesFromDictionary: " + isStored + " : " + exc); + } + } + } + + /** + * Creates a deep clone of the specified object. (Object.clone() only creates a + * shallow clone.) Returns null if operation fails. + */ + static public Object clone(Object aSource) { + return Duplicator.deepClone(aSource); + } + + /** + * Creates a deep clone of the specified object, registered in the specified + * source editing context, transposing it into the specified destination editing + * context. Returns null if operation fails. + */ + static public Object clone(EOEditingContext aSourceContext, Object aSource, EOEditingContext aDestinationContext) { + return clone(aSourceContext, aSource, aDestinationContext, aSource); + } + + /** + * Called by clone and copy. The specified root object will not be replaced by + * an object in the destination editing context: this should be the same as the + * source object for cloning, but should be null for copying. Returns null if + * operation fails. + */ + static private Object clone(EOEditingContext aSourceContext, Object aSource, EOEditingContext aDestinationContext, + Object aRootObject) { //System.out.println(); //System.out.println( "clone: " + aSourceContext ); @@ -266,475 +208,361 @@ public class KeyValueCodingUtilities //System.out.println( " : " + aDestinationContext ); //System.out.println(); - // the only known way to deep copy in - // java without native code is serialization - - return thaw( - freeze( aSource, aSourceContext, aRootObject, true ), - aDestinationContext, true ); - } - - /** - * Serializes an object to a byte array containing - * GlobalIDMarkers in place of references to other objects - * registered in the specified context. - * The specified root object will be serialized, - * even if it is registered in the specified context: - * this is typically the root object you're trying to - * serialize. - * Package access, as this method is used by editing - * context for snapshots. - */ - static public byte[] freeze( - Object anObject, EOEditingContext aContext, Object aRootObject, boolean transpose ) - { - try - { + // the only known way to deep copy in + // java without native code is serialization + + return thaw(freeze(aSource, aSourceContext, aRootObject, true), aDestinationContext, true); + } + + /** + * Serializes an object to a byte array containing GlobalIDMarkers in place of + * references to other objects registered in the specified context. The + * specified root object will be serialized, even if it is registered in the + * specified context: this is typically the root object you're trying to + * serialize. Package access, as this method is used by editing context for + * snapshots. + */ + static public byte[] freeze(Object anObject, EOEditingContext aContext, Object aRootObject, boolean transpose) { + try { //long t = System.currentTimeMillis(); - ByteArrayOutputStream byteOutput = - new ByteArrayOutputStream();// CloneBufferSize ); - ObjectOutputStream objectOutput; - if ( transpose ) - { - objectOutput = - new TransposingContextObjectOutputStream( - byteOutput, aContext, aRootObject ); - } - else - { - objectOutput = - new ContextObjectOutputStream( - byteOutput, aContext ); - } - - objectOutput.writeObject( anObject ); - objectOutput.flush(); - objectOutput.close(); - - return byteOutput.toByteArray(); + ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();// CloneBufferSize ); + ObjectOutputStream objectOutput; + if (transpose) { + objectOutput = new TransposingContextObjectOutputStream(byteOutput, aContext, aRootObject); + } else { + objectOutput = new ContextObjectOutputStream(byteOutput, aContext); + } + + objectOutput.writeObject(anObject); + objectOutput.flush(); + objectOutput.close(); + + return byteOutput.toByteArray(); // profiling -/* -byte[] result = byteOutput.toByteArray(); -long size = result.length; -long time = ( System.currentTimeMillis() - t ); -maxSize = Math.max( size, maxSize ); -minSize = Math.min( size, minSize ); -totSize += size; -maxTime = Math.max( time, maxTime ); -minTime = Math.min( time, minTime ); -totTime += time; -nTime++; -System.out.println( "freeze: size = [ " + size + " : " + minSize + " : " + ( (float)totSize / (float)nTime ) + " : " + maxSize -+ " ] time = [ " + time + " : " + minTime + " : " + ( (float)totTime / (float)nTime ) + " : " + maxTime + " ]" ); -return result; -*/ + /* + * byte[] result = byteOutput.toByteArray(); long size = result.length; long + * time = ( System.currentTimeMillis() - t ); maxSize = Math.max( size, maxSize + * ); minSize = Math.min( size, minSize ); totSize += size; maxTime = Math.max( + * time, maxTime ); minTime = Math.min( time, minTime ); totTime += time; + * nTime++; System.out.println( "freeze: size = [ " + size + " : " + minSize + + * " : " + ( (float)totSize / (float)nTime ) + " : " + maxSize + " ] time = [ " + * + time + " : " + minTime + " : " + ( (float)totTime / (float)nTime ) + " : " + * + maxTime + " ]" ); return result; + */ // end profiling - } - catch ( Exception exc ) - { - throw new WotonomyException( exc ); - } - } - + } catch (Exception exc) { + throw new WotonomyException(exc); + } + } + //static long maxTime, minTime, totTime, nTime, maxSize, minSize, totSize; //static long maxTimeThaw, minTimeThaw, totTimeThaw, nTimeThaw; - /** - * De-serializes an object from the specified byte - * array, replacing GlobalIDMarkers with reference - * to objects registered in the specified editing - * context. - * Package access, as this method is used by editing - * context for snapshots. - */ - static public Object thaw( - byte[] aByteArray, EOEditingContext aContext, boolean transpose ) - { - return thaw( aByteArray, aContext, null, transpose ); - } - - /** - * De-serializes an object from the specified byte - * array, replacing GlobalIDMarkers with reference - * to objects registered in the specified editing - * context. - * Package access, as this method is used by editing - * context for snapshots. - */ - static public Object thaw( - byte[] aByteArray, EOEditingContext aContext, ClassLoader aLoader, boolean transpose ) - { - try - { + /** + * De-serializes an object from the specified byte array, replacing + * GlobalIDMarkers with reference to objects registered in the specified editing + * context. Package access, as this method is used by editing context for + * snapshots. + */ + static public Object thaw(byte[] aByteArray, EOEditingContext aContext, boolean transpose) { + return thaw(aByteArray, aContext, null, transpose); + } + + /** + * De-serializes an object from the specified byte array, replacing + * GlobalIDMarkers with reference to objects registered in the specified editing + * context. Package access, as this method is used by editing context for + * snapshots. + */ + static public Object thaw(byte[] aByteArray, EOEditingContext aContext, ClassLoader aLoader, boolean transpose) { + try { //long t = System.currentTimeMillis(); - ByteArrayInputStream byteInput = - new ByteArrayInputStream( aByteArray ); - ObjectInputStream objectInput; - if ( transpose ) - { - objectInput = - new TransposingContextObjectInputStream( - byteInput, aContext, aLoader ); - } - else - { - objectInput = - new ContextObjectInputStream( - byteInput, aContext, aLoader ); - } - - return objectInput.readObject(); + ByteArrayInputStream byteInput = new ByteArrayInputStream(aByteArray); + ObjectInputStream objectInput; + if (transpose) { + objectInput = new TransposingContextObjectInputStream(byteInput, aContext, aLoader); + } else { + objectInput = new ContextObjectInputStream(byteInput, aContext, aLoader); + } + + return objectInput.readObject(); // profiling -/* -Object result = objectInput.readObject(); -long timeThaw = ( System.currentTimeMillis() - t ); -maxTimeThaw = Math.max( timeThaw, maxTimeThaw ); -minTimeThaw = Math.min( timeThaw, minTimeThaw ); -totTimeThaw += timeThaw; -nTimeThaw++; -System.out.println( "thaw: size = " + aByteArray.length + ", time = [ " + timeThaw + " : " + minTimeThaw + " : " + ( (float)totTimeThaw / (float)nTimeThaw ) + " : " + maxTimeThaw + " ]" ); -return result; -*/ + /* + * Object result = objectInput.readObject(); long timeThaw = ( + * System.currentTimeMillis() - t ); maxTimeThaw = Math.max( timeThaw, + * maxTimeThaw ); minTimeThaw = Math.min( timeThaw, minTimeThaw ); totTimeThaw + * += timeThaw; nTimeThaw++; System.out.println( "thaw: size = " + + * aByteArray.length + ", time = [ " + timeThaw + " : " + minTimeThaw + " : " + + * ( (float)totTimeThaw / (float)nTimeThaw ) + " : " + maxTimeThaw + " ]" ); + * return result; + */ // end profiling - } - catch ( Exception exc ) - { - throw new WotonomyException( exc ); - } - } - - /** - * Copies values from one object registered in the - * specified origin context to the specified destination - * object - * The values themselves are cloned, so this is a deep copy. - * Returns the destination object, or throws exception - * if operation fails. - */ - static public Object copy( Object aSource, Object aDestination ) - { - NSDictionary values = (NSDictionary) - clone( valuesForKeys( aSource, - EOClassDescription.classDescriptionForClass( - aSource.getClass() ).attributeKeys() ) ); - - takeStoredValuesFromDictionary( aDestination, values ); - return aDestination; - } - - /** - * Copies values from one object registered in the - * specified origin context to the specified destination - * object - * The values themselves are cloned, so this is a deep copy. - * Returns the destination object, or throws exception - * if operation fails. - */ - static public Object copy( - EOEditingContext aSourceContext, Object aSource, - EOEditingContext aDestinationContext, Object aDestination ) - { - // get all keys for this object - EOClassDescription classDesc = - EOClassDescription.classDescriptionForClass( aSource.getClass() ); - List keys = new LinkedList(); - keys.addAll( classDesc.attributeKeys() ); - keys.addAll( classDesc.toOneRelationshipKeys() ); - keys.addAll( classDesc.toManyRelationshipKeys() ); - - // transpose all objects registered in source context - NSDictionary values = storedValuesForKeys( aSource, keys ); - values = (NSDictionary) - clone( aSourceContext, values, aDestinationContext, null ); - - // apply to destination object - takeStoredValuesFromDictionary( aDestination, values ); - return aDestination; - } - - // inner classes - - /** - * An ObjectOutputStream that serializes objects with references - * to an editing context. The specified context will not be - * serialized but referenced, so that a ContextObjectInputStream - * can replace the reference with another editing context. - */ - static private class ContextObjectOutputStream extends ObjectOutputStream - { - private EditingContextMarker marker = new EditingContextMarker(); - protected EOEditingContext editingContext; - - /** - * Specifies the output stream to wrap, - * and the source context that should be - * referenced but not serialized. - */ - public ContextObjectOutputStream( - OutputStream anOutputStream, - EOEditingContext aContext ) - throws IOException - { - super( anOutputStream ); - editingContext = aContext; - try - { - enableReplaceObject(true); - } - catch ( Exception exc ) - { - exc.printStackTrace(); - } - } - - protected Object replaceObject(Object anObject) throws IOException - { + } catch (Exception exc) { + throw new WotonomyException(exc); + } + } + + /** + * Copies values from one object registered in the specified origin context to + * the specified destination object The values themselves are cloned, so this is + * a deep copy. Returns the destination object, or throws exception if operation + * fails. + */ + static public Object copy(Object aSource, Object aDestination) { + NSDictionary values = (NSDictionary) clone(valuesForKeys(aSource, + EOClassDescription.classDescriptionForClass(aSource.getClass()).attributeKeys())); + + takeStoredValuesFromDictionary(aDestination, values); + return aDestination; + } + + /** + * Copies values from one object registered in the specified origin context to + * the specified destination object The values themselves are cloned, so this is + * a deep copy. Returns the destination object, or throws exception if operation + * fails. + */ + static public Object copy(EOEditingContext aSourceContext, Object aSource, EOEditingContext aDestinationContext, + Object aDestination) { + // get all keys for this object + EOClassDescription classDesc = EOClassDescription.classDescriptionForClass(aSource.getClass()); + List keys = new LinkedList(); + keys.addAll(classDesc.attributeKeys()); + keys.addAll(classDesc.toOneRelationshipKeys()); + keys.addAll(classDesc.toManyRelationshipKeys()); + + // transpose all objects registered in source context + NSDictionary values = storedValuesForKeys(aSource, keys); + values = (NSDictionary) clone(aSourceContext, values, aDestinationContext, null); + + // apply to destination object + takeStoredValuesFromDictionary(aDestination, values); + return aDestination; + } + + // inner classes + + /** + * An ObjectOutputStream that serializes objects with references to an editing + * context. The specified context will not be serialized but referenced, so that + * a ContextObjectInputStream can replace the reference with another editing + * context. + */ + static private class ContextObjectOutputStream extends ObjectOutputStream { + private EditingContextMarker marker = new EditingContextMarker(); + protected EOEditingContext editingContext; + + /** + * Specifies the output stream to wrap, and the source context that should be + * referenced but not serialized. + */ + public ContextObjectOutputStream(OutputStream anOutputStream, EOEditingContext aContext) throws IOException { + super(anOutputStream); + editingContext = aContext; + try { + enableReplaceObject(true); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + + protected Object replaceObject(Object anObject) throws IOException { // if ( anObject == editingContext ) return marker; //FIXME: this should be more strict as above - if ( anObject instanceof EOEditingContext ) return marker; - return anObject; - } - - } - - /** - * A ContextObjectOutputStream that replaces any objects registered - * in the source editing context with markers to be used in - * ContextObjectInputStream. - */ - static private class TransposingContextObjectOutputStream - extends ContextObjectOutputStream - { - protected Object rootObject; - - /** - * Specifies the output stream to wrap, - * the source context containing objects that - * should be replaced if found, - * and the object which should not be re-registered, - * which is typically the object being cloned, but - * may be null. - */ - public TransposingContextObjectOutputStream( - OutputStream anOutputStream, - EOEditingContext aContext, - Object anObject ) - throws IOException - { - super( anOutputStream, aContext ); - rootObject = anObject; - } - - protected Object replaceObject(Object anObject) throws IOException - { - if ( anObject == rootObject ) return anObject; - if ( editingContext != null ) - { - EOGlobalID id = editingContext.globalIDForObject( anObject ); - if ( id != null ) - { - Object result = new GlobalIDMarker( id ); - //System.out.println( "KeyValueCodingUtilities.replaceObject: returning: " + result ); - return result; - } - } - return super.replaceObject( anObject ); - } - - } - - /** - * A marker class so references to objects registered in editing - * contexts get transposed rather than cloned. - */ - static private class GlobalIDMarker implements Serializable - { - private EOGlobalID id; - - public GlobalIDMarker( EOGlobalID anID ) - { - id = anID; - } - - public EOGlobalID getID() - { - return id; - } - - public String toString() - { - return "[GlobalIDMarker:"+id+"]"; - } - } - - /** - * A marker class so references an object's editing context - * gets transposed rather than cloned. - */ - static private class EditingContextMarker implements Serializable - { - // just a marker class - no implementation necessary - } - - /** - * An ObjectInputStream that replaces any markers from - * ContextObjectOutputStream with objects registered - * in the destination editing context. - */ - static private class ContextObjectInputStream extends ObjectInputStream - { - protected EOEditingContext editingContext; - protected ClassLoader classLoader; - - /** - * Specifies the output stream to wrap, - * the source context containing objects that - * should be to replace any markers. - * The class loader may be null. - */ - public ContextObjectInputStream( - InputStream anInputStream, - EOEditingContext aContext, - ClassLoader aClassLoader ) - throws IOException - { - super( anInputStream ); - editingContext = aContext; - classLoader = aClassLoader; - if ( classLoader == null ) - { - classLoader = - KeyValueCodingUtilities.class.getClassLoader(); - } - try - { - enableResolveObject(true); - } - catch ( Exception exc ) - { - exc.printStackTrace(); - } - } - - protected Object resolveObject(Object anObject) throws IOException - { - if ( anObject instanceof EditingContextMarker ) - { - return editingContext; - } - return anObject; - } - - protected Class resolveClass(ObjectStreamClass v) - throws IOException, ClassNotFoundException - { - return classLoader.loadClass( v.getName() ); - } - } - - /** - * A ContextObjectInputStream that replaces any markers from - * TransposingContextObjectOutputStream with objects registered - * in the destination editing context. - */ - static private class TransposingContextObjectInputStream - extends ContextObjectInputStream - { - /** - * Specifies the output stream to wrap, - * the source context containing objects that - * should be to replace any markers. - */ - public TransposingContextObjectInputStream( - InputStream anInputStream, - EOEditingContext aContext, - ClassLoader aClassLoader ) - throws IOException - { - super( anInputStream, aContext, aClassLoader ); - } - - protected Object resolveObject(Object anObject) throws IOException - { - if ( anObject instanceof GlobalIDMarker ) - { - return editingContext.faultForGlobalID( - ((GlobalIDMarker)anObject).getID(), editingContext ); - } - return super.resolveObject( anObject ); - } - } - + if (anObject instanceof EOEditingContext) + return marker; + return anObject; + } + + } + + /** + * A ContextObjectOutputStream that replaces any objects registered in the + * source editing context with markers to be used in ContextObjectInputStream. + */ + static private class TransposingContextObjectOutputStream extends ContextObjectOutputStream { + protected Object rootObject; + + /** + * Specifies the output stream to wrap, the source context containing objects + * that should be replaced if found, and the object which should not be + * re-registered, which is typically the object being cloned, but may be null. + */ + public TransposingContextObjectOutputStream(OutputStream anOutputStream, EOEditingContext aContext, + Object anObject) throws IOException { + super(anOutputStream, aContext); + rootObject = anObject; + } + + protected Object replaceObject(Object anObject) throws IOException { + if (anObject == rootObject) + return anObject; + if (editingContext != null) { + EOGlobalID id = editingContext.globalIDForObject(anObject); + if (id != null) { + Object result = new GlobalIDMarker(id); + // System.out.println( "KeyValueCodingUtilities.replaceObject: returning: " + + // result ); + return result; + } + } + return super.replaceObject(anObject); + } + + } + + /** + * A marker class so references to objects registered in editing contexts get + * transposed rather than cloned. + */ + static private class GlobalIDMarker implements Serializable { + private EOGlobalID id; + + public GlobalIDMarker(EOGlobalID anID) { + id = anID; + } + + public EOGlobalID getID() { + return id; + } + + public String toString() { + return "[GlobalIDMarker:" + id + "]"; + } + } + + /** + * A marker class so references an object's editing context gets transposed + * rather than cloned. + */ + static private class EditingContextMarker implements Serializable { + // just a marker class - no implementation necessary + } + + /** + * An ObjectInputStream that replaces any markers from ContextObjectOutputStream + * with objects registered in the destination editing context. + */ + static private class ContextObjectInputStream extends ObjectInputStream { + protected EOEditingContext editingContext; + protected ClassLoader classLoader; + + /** + * Specifies the output stream to wrap, the source context containing objects + * that should be to replace any markers. The class loader may be null. + */ + public ContextObjectInputStream(InputStream anInputStream, EOEditingContext aContext, ClassLoader aClassLoader) + throws IOException { + super(anInputStream); + editingContext = aContext; + classLoader = aClassLoader; + if (classLoader == null) { + classLoader = KeyValueCodingUtilities.class.getClassLoader(); + } + try { + enableResolveObject(true); + } catch (Exception exc) { + exc.printStackTrace(); + } + } + + protected Object resolveObject(Object anObject) throws IOException { + if (anObject instanceof EditingContextMarker) { + return editingContext; + } + return anObject; + } + + protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException { + return classLoader.loadClass(v.getName()); + } + } + + /** + * A ContextObjectInputStream that replaces any markers from + * TransposingContextObjectOutputStream with objects registered in the + * destination editing context. + */ + static private class TransposingContextObjectInputStream extends ContextObjectInputStream { + /** + * Specifies the output stream to wrap, the source context containing objects + * that should be to replace any markers. + */ + public TransposingContextObjectInputStream(InputStream anInputStream, EOEditingContext aContext, + ClassLoader aClassLoader) throws IOException { + super(anInputStream, aContext, aClassLoader); + } + + protected Object resolveObject(Object anObject) throws IOException { + if (anObject instanceof GlobalIDMarker) { + return editingContext.faultForGlobalID(((GlobalIDMarker) anObject).getID(), editingContext); + } + return super.resolveObject(anObject); + } + } + } /* - * $Log$ - * Revision 1.3 2006/02/18 22:46:44 cgruber - * Add Surrogate map from .util into control's internal package, and fix imports. + * $Log$ Revision 1.3 2006/02/18 22:46:44 cgruber Add Surrogate map from .util + * into control's internal package, and fix imports. * - * Revision 1.2 2006/02/16 16:47:14 cgruber - * Move some classes in to "internal" packages and re-work imports, etc. + * Revision 1.2 2006/02/16 16:47:14 cgruber Move some classes in to "internal" + * packages and re-work imports, etc. * - * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions. + * Also use UnsupportedOperationExceptions where appropriate, instead of + * WotonomyExceptions. * - * Revision 1.1 2006/02/16 13:19:57 cgruber - * Check in all sources in eclipse-friendly maven-enabled packages. + * Revision 1.1 2006/02/16 13:19:57 cgruber Check in all sources in + * eclipse-friendly maven-enabled packages. * - * Revision 1.15 2003/01/21 22:30:10 mpowers - * thaw() now allows you to pass in a class loader. + * Revision 1.15 2003/01/21 22:30:10 mpowers thaw() now allows you to pass in a + * class loader. * - * Revision 1.14 2002/05/15 13:46:35 mpowers - * Exposed freeze and thaw as public. + * Revision 1.14 2002/05/15 13:46:35 mpowers Exposed freeze and thaw as public. * - * Revision 1.13 2001/08/22 19:25:13 mpowers - * Added (and commented out) profiling code for freeze. + * Revision 1.13 2001/08/22 19:25:13 mpowers Added (and commented out) profiling + * code for freeze. * - * Revision 1.12 2001/05/06 18:27:10 mpowers - * More broadly catching editing contexts for now. + * Revision 1.12 2001/05/06 18:27:10 mpowers More broadly catching editing + * contexts for now. * - * Revision 1.11 2001/05/05 13:18:49 mpowers - * Fixed: transposing output stream was not returning the object to replace. + * Revision 1.11 2001/05/05 13:18:49 mpowers Fixed: transposing output stream + * was not returning the object to replace. * - * Revision 1.10 2001/05/04 16:57:56 mpowers - * Now correctly transposing references to editing contexts when - * cloning/copying between editing contexts. + * Revision 1.10 2001/05/04 16:57:56 mpowers Now correctly transposing + * references to editing contexts when cloning/copying between editing contexts. * - * Revision 1.9 2001/05/04 14:42:58 mpowers - * Now getting stored values in KeyValueCoding. - * MasterDetail now marks dirty based on whether it's an attribute - * or relation. - * Implemented editing context marker. + * Revision 1.9 2001/05/04 14:42:58 mpowers Now getting stored values in + * KeyValueCoding. MasterDetail now marks dirty based on whether it's an + * attribute or relation. Implemented editing context marker. * - * Revision 1.8 2001/05/02 15:47:40 mpowers - * Fixed the pernicious problem with reverts: recordObject was recording - * a snapshot of the clone before the transposition-copy happened, - * so the revert object would lose all of its transposed relationships. + * Revision 1.8 2001/05/02 15:47:40 mpowers Fixed the pernicious problem with + * reverts: recordObject was recording a snapshot of the clone before the + * transposition-copy happened, so the revert object would lose all of its + * transposed relationships. * - * Revision 1.7 2001/04/30 12:33:17 mpowers - * Fixed problem with use of EONullValue.nullValue(), which can't be used - * when we're serializably duplicating objects. + * Revision 1.7 2001/04/30 12:33:17 mpowers Fixed problem with use of + * EONullValue.nullValue(), which can't be used when we're serializably + * duplicating objects. * - * Revision 1.6 2001/04/30 02:14:25 mpowers - * Copying should call takeStoredValueForKeys. + * Revision 1.6 2001/04/30 02:14:25 mpowers Copying should call + * takeStoredValueForKeys. * - * Revision 1.5 2001/04/29 22:02:45 mpowers - * Work on id transposing between editing contexts. + * Revision 1.5 2001/04/29 22:02:45 mpowers Work on id transposing between + * editing contexts. * - * Revision 1.4 2001/04/29 02:29:31 mpowers - * Debugging relationship faulting. + * Revision 1.4 2001/04/29 02:29:31 mpowers Debugging relationship faulting. * - * Revision 1.3 2001/04/28 16:18:44 mpowers - * Implementing relationships. + * Revision 1.3 2001/04/28 16:18:44 mpowers Implementing relationships. * - * Revision 1.2 2001/04/28 14:12:23 mpowers - * Refactored cloning/copying into KeyValueCodingUtilities. + * Revision 1.2 2001/04/28 14:12:23 mpowers Refactored cloning/copying into + * KeyValueCodingUtilities. * - * Revision 1.1 2001/04/27 23:41:12 mpowers - * Contributing file for KeyValueCodingUtilities. + * Revision 1.1 2001/04/27 23:41:12 mpowers Contributing file for + * KeyValueCodingUtilities. * * */ - - |
