org.electrocodeogram.cpc.core.api.data
Class CloneDiff

java.lang.Object
  extended by org.electrocodeogram.cpc.core.api.data.CloneDiff
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<CloneDiff>, ICloneDataElement, ICloneObjectSupport, IStatefulObject
Direct Known Subclasses:
CompositCloneDiff

public class CloneDiff
extends java.lang.Object
implements ICloneObjectSupport, IStatefulObject, java.lang.Comparable<CloneDiff>

Clone diff objects represent modifications which were made to the content of a clone.
Their semantics are the same as those of DocumentEvents but all positions are relative to the offset of the affected clone.

Due to performance considerations and its inherent simplicity this class is not hidden behind any interface and its implementation is provided directly by the CPC Core and not the ICloneFactoryProvider.

NOTE: a CloneDiff instance only describes the part of a DocumentEvent which affected the corresponding clone. I.e. if a modification started before the start offset of the clone than only the part of the modification which was attributed to the clone, should be part of the CloneDiff event. This may require some translation of offsets. A relative CloneDiff offset must never be negative.
The goal is that CloneDiff events can be applied to a standalone copy of the corresponding clone, without having to take any modifications outside of the clone into account.

Author:
vw
See Also:
IPositionUpdateStrategyProvider, CoreHistoryUtils, Serialized Form

Field Summary
protected  boolean automaticChange
           
protected  java.util.Date creationDate
           
protected  java.lang.String creator
           
protected  int length
           
protected  int offset
           
static java.lang.String PERSISTENCE_CLASS_IDENTIFIER
          IStatefulObject persistence class identifier, value: "clone_diff"
static java.lang.String PERSISTENCE_OBJECT_IDENTIFIER
          IStatefulObject persistence object identifier, value: "creationDate"
getCreationDate() is guaranteed to be a unique value per clone.
protected  java.lang.String text
           
 
Constructor Summary
CloneDiff()
          This constructor may only be used while restoring CloneDiff objects.
CloneDiff(java.lang.String creator, java.util.Date creationDate, boolean automaticChange, int offset, int length, java.lang.String text)
          Creates a new, immutable CloneDiff instance.
 
Method Summary
 java.lang.Object clone()
          CloneDiff objects are immutable.
 int compareTo(CloneDiff o)
           
 boolean equals(java.lang.Object obj)
           
 java.util.Date getCreationDate()
          Retrieves the creation time of this diff.
 java.lang.String getCreator()
          Retrieves the creator (username) of this diff.
 int getLength()
          Retrieves the number of characters replaced by this modification.
 int getOffset()
          Retrieves the offset of this modification.
 java.lang.String getPersistenceClassIdentifier()
          Returns a string which uniquely identifies the object type.
 java.lang.String getPersistenceObjectIdentifier()
          Returns a key which corresponds to an entry in the state Map returned by getState() which uniquely identifies an object instance.
 java.util.Map<java.lang.String,java.lang.Comparable<? extends java.lang.Object>> getState()
          Returns a map which fully describes the internal state of this object.
 java.util.Map<java.lang.String,java.lang.Class<? extends java.lang.Object>> getStateTypes()
          Returns a list of all keys which are needed to persist this objects internal state.
 java.lang.String getText()
          Retrieves the text which was inserted by this modification.
 int getTextLength()
          Retrieves the length of the text which was inserted by this modification.
 int hashCode()
           
 boolean isAutomaticChange()
          Checks whether this CloneDiff was created by some automated action, i.e.
 boolean isSealed()
          Checks whether this ICloneDataElement instance has been sealed.
 void seal()
          Seals this ICloneDataElement instance.
 void setState(java.util.Map<java.lang.String,java.lang.Comparable<? extends java.lang.Object>> state)
          Restores the internal state of this object to the state which was extracted by means of getState() earlier.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

PERSISTENCE_CLASS_IDENTIFIER

public static final java.lang.String PERSISTENCE_CLASS_IDENTIFIER
IStatefulObject persistence class identifier, value: "clone_diff"

See Also:
Constant Field Values

PERSISTENCE_OBJECT_IDENTIFIER

public static final java.lang.String PERSISTENCE_OBJECT_IDENTIFIER
IStatefulObject persistence object identifier, value: "creationDate"
getCreationDate() is guaranteed to be a unique value per clone.

See Also:
Constant Field Values

creator

protected java.lang.String creator

creationDate

protected java.util.Date creationDate

automaticChange

protected boolean automaticChange

offset

protected int offset

length

protected int length

text

protected java.lang.String text
Constructor Detail

CloneDiff

public CloneDiff()
This constructor may only be used while restoring CloneDiff objects.
The values for this diff can then only be set via setState(Map).


CloneDiff

public CloneDiff(java.lang.String creator,
                 java.util.Date creationDate,
                 boolean automaticChange,
                 int offset,
                 int length,
                 java.lang.String text)
Creates a new, immutable CloneDiff instance.

NOTE: The creationDate needs to be a unique value for the corresponding clone. As java Dates offer only millisecond precision and many system clocks much less than that, it would be possible for multiple CloneDiff instances to be created with the same date value.
This needs to be prevented. Any code which creates multiple CloneDiff instances in quick succession has to ensure that no two diffs are created with the same creationDate value.
One possible approach to this requirement would be to remember the time of the last CloneDiff instance and to artificially increase the creationDate by one millisecond if it is equal to the creationDate of the last event.

Parameters:
creator - the creator (username) of this diff, NULL if unknown.
creationDate - the creation time of this diff, never null. This value needs to be unique within one clone instance. See above.
automaticChange - true if it can be guaranteed that this change was not done directly by a human. I.e. refactorings or source code reformats.
offset - the start offset of this diff, relative to the start offset of the clone, always >= 0.
length - the number of characters replaced by this modification. 0 if this modification only added text. Always >=0.
text - the text which was inserted by this modification, may be NULL.
Method Detail

getOffset

public int getOffset()
Retrieves the offset of this modification.

Returns:
the 0-based offset at which this modification begins. Offsets are relative to the start offset of the corresponding clone. Always >=0.

getLength

public int getLength()
Retrieves the number of characters replaced by this modification.

Returns:
the number of characters replaced by this modification. 0 if this modification only added text. Always >=0.

getText

public java.lang.String getText()
Retrieves the text which was inserted by this modification.

Returns:
the text which was inserted by this modification, may be NULL.

getTextLength

public int getTextLength()
Retrieves the length of the text which was inserted by this modification.
Convenience Method.

Returns:
length of getText() or 0 if it is null. Always >=0.

getCreator

public java.lang.String getCreator()
Retrieves the creator (username) of this diff.
The value may be NULL if the creator could not be identified.

Returns:
creator of this diff, may be NULL.

getCreationDate

public java.util.Date getCreationDate()
Retrieves the creation time of this diff.
It is up to the creator of the CloneDiff object to ensure uniqueness of creation times within the diff events of one clone object.
See: CloneDiff(String, Date, boolean, int, int, String)

Returns:
creation time of this diff, never null.

isAutomaticChange

public boolean isAutomaticChange()
Checks whether this CloneDiff was created by some automated action, i.e. a refactoring or a source code reformat.
This is a best effort value. It is guaranteed that the change was not made directly by a human if this value is true. However, if the value is false nothing can be guaranteed.

Returns:
true if this change was definitely not done by a human. False if a human made the change or if unsure.

getPersistenceClassIdentifier

public java.lang.String getPersistenceClassIdentifier()
Description copied from interface: IStatefulObject
Returns a string which uniquely identifies the object type.

For the default ICloneObject sub interfaces the return values must equal the PERSISTENCE_CLASS_IDENTIFIER constant defined in the interface.

3rd party clone objects can define their own persistence identifiers.
Allowed are only letters, numbers and the underscore. Furthermore an identifier needs to contain at least one letter, may not begin with an underscore and may not contain multiple consecutive underscores.

A typical store provider will use this method to derive directory/file or table names.

Specified by:
getPersistenceClassIdentifier in interface IStatefulObject
Returns:
unique identifier for the object type, never null.

getPersistenceObjectIdentifier

public java.lang.String getPersistenceObjectIdentifier()
Description copied from interface: IStatefulObject
Returns a key which corresponds to an entry in the state Map returned by getState() which uniquely identifies an object instance.

For the default ICloneObject sub interfaces the return values must equal the PERSISTENCE_OBJECT_IDENTIFIER constant defined in the ICloneObject interface.

By default this is uuid.

3rd party clone objects can define their own persistence identifiers.
Allowed are only letters, numbers and the underscore. Furthermore an identifier needs to contain at least one letter, may not begin with an underscore and may not contain multiple consecutive underscores.

A typical store provider will use this method to derive file names, internal id structure names or table primary keys.

IMPORTANT: the corresponding value in IStatefulObject.getState() must not be changed at any point.
The unique identifiers of all stateful objects must remain unchanged during their entire lifetime.

Specified by:
getPersistenceObjectIdentifier in interface IStatefulObject
Returns:
key for state Map which yields a unique identifier for an object instance, never null. Will usually return "uuid".
See Also:
IStatefulObject.getState()

getState

public java.util.Map<java.lang.String,java.lang.Comparable<? extends java.lang.Object>> getState()
Description copied from interface: IStatefulObject
Returns a map which fully describes the internal state of this object. The map is persisted by the IStoreProvider and the setState() method is used to restore a persisted state.

In case of an ICloneObject, the map does not include any data for ICloneObjectExtension which are stored under the object.

The values in the map are restricted to the following object types:

The keys in the map should correspond to the following schema: IMPORTANT NOTEs:

Specified by:
getState in interface IStatefulObject
Returns:
a map describing the internal state of this object, never null.
See Also:
IStatefulObject.setState(Map)

getStateTypes

public java.util.Map<java.lang.String,java.lang.Class<? extends java.lang.Object>> getStateTypes()
Description copied from interface: IStatefulObject
Returns a list of all keys which are needed to persist this objects internal state. The values in the returned Map correspond to the classes of the values which will be used in the Map returned by getState().

I.e. if getState() will return a Map which contains the key "uuid" with the value "jda83ds-..." then this Map contains the key "uuid" with the value String.class.

Specified by:
getStateTypes in interface IStatefulObject
Returns:
map which contains all keys and their data types, never null
See Also:
IStatefulObject.getState()

setState

public void setState(java.util.Map<java.lang.String,java.lang.Comparable<? extends java.lang.Object>> state)
Description copied from interface: IStatefulObject
Restores the internal state of this object to the state which was extracted by means of getState() earlier.

For a description of the internal structure of the map, see getState().

Specified by:
setState in interface IStatefulObject
Parameters:
state - a map describing the internal state of this object, never null
See Also:
IStatefulObject.getState()

isSealed

public boolean isSealed()
Description copied from interface: ICloneDataElement
Checks whether this ICloneDataElement instance has been sealed.

Specified by:
isSealed in interface ICloneDataElement
Returns:
true if this instance has been sealed.

seal

public void seal()
Description copied from interface: ICloneDataElement
Seals this ICloneDataElement instance.
A sealed object may not be modified in any way. Otherwise an IllegalStateException is thrown.
Sealing an already sealed object has no effect.

In order to "unseal" an ICloneDataElement, it needs to be cloned. The seal state will not be propagated to the cloned instance.

Specified by:
seal in interface ICloneDataElement

clone

public java.lang.Object clone()
                       throws java.lang.CloneNotSupportedException
CloneDiff objects are immutable.
WARNING: For performance reasons this method does not create a clone of the object, but instead it simply returns the object itself.
For normal use inside of CPC this does not make a difference due to the immutable state of this object.
However, in violation of the Object.clone() contract, cloneDiff.clone() == cloneDiff will be true.

Overrides:
clone in class java.lang.Object
Throws:
java.lang.CloneNotSupportedException

hashCode

public int hashCode()
Overrides:
hashCode in class java.lang.Object

equals

public boolean equals(java.lang.Object obj)
Overrides:
equals in class java.lang.Object

compareTo

public int compareTo(CloneDiff o)
Specified by:
compareTo in interface java.lang.Comparable<CloneDiff>

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object