org.hd.d.pg2k.svrCore.props
Class PropertiesBundleDiff

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.props.PropertiesBundleDiff
All Implemented Interfaces:
java.io.ObjectInputValidation, java.io.Serializable

public class PropertiesBundleDiff
extends java.lang.Object
implements java.io.Serializable, java.io.ObjectInputValidation

A diff/patch mechanism for a bundle of well-behaved simple String-->String Properties. These diffs can be used to send just changes/deltas over the wire for well-behaved bundles of closely-related pure-String Properties, eg of the form of i18n ResourceBundle inputs.

This class itself is immutable and Serialisable, and designed to be efficient on the wire.

This uses PropertiesDiff to hold each Properties instance immutably/efficiently.

Author:
DHD
See Also:
Serialized Form

Field Summary
private  int _hash
          Cached hash value; initially zero.
private  java.util.SortedSet<java.lang.String> deletedNames
          The immutable in-order set of Properties sets entirely removed; never null.
private static java.util.Map<java.lang.String,java.util.Properties> EMPTY_BUNDLE
          Private empty Properties map; never changed, never null.
static PropertiesBundleDiff EMPTY_DIFF
          Immutable empty diff.
private static java.util.Properties EMPTY_PROPERTIES
          Private empty Properties map; never changed, never null.
private  java.util.SortedMap<java.lang.String,PropertiesDiff> newValues
          The immutable in-order map from items/names to the new/changed Properties sets; never null.
private static long serialVersionUID
          Serial UID.
 int sizeAfter
          The output bundle count as a sanity-check; guaranteed non-negative.
 int sizeBefore
          The input bundle count as a sanity-check; guaranteed non-negative.
 
Constructor Summary
PropertiesBundleDiff()
          Make new empty diff instance.
PropertiesBundleDiff(int sizeBefore, int sizeAfter, java.util.Set<java.lang.String> deleted, java.util.Map<java.lang.String,PropertiesDiff> added)
          Create diff instance.
 
Method Summary
private static java.util.Set<Tuple.Pair<java.lang.String,java.util.Properties>> _computeChangeValues(java.util.Map<java.lang.String,java.util.Properties> pb)
          Create "change" values from a Properties bundle; never null.
static java.util.Map<java.lang.String,java.util.Properties> applyDiff(java.util.Map<java.lang.String,java.util.Properties> bp1, PropertiesBundleDiff diff)
          Applies diff to an extant Properties instance to generate a new AEP instance; never null.
static PropertiesBundleDiff createAsStandAloneDiff(java.util.Map<java.lang.String,java.util.Properties> p1)
          Create diff against empty Properties.
static PropertiesBundleDiff createDiff(java.util.Map<java.lang.String,java.util.Properties> p1, java.util.Map<java.lang.String,java.util.Properties> p2, boolean force, boolean intern)
          Create diff between two Properties instances.
static java.util.Map<java.lang.String,java.util.Properties> createFromStandAloneDiff(PropertiesBundleDiff pd)
          Create from diff against empty Properties.
 boolean equals(java.lang.Object obj)
          Equal iff all fields are identical.
 java.util.SortedMap<java.lang.String,PropertiesDiff> getNewValues()
          Get newValues; never null.
 int hashCode()
          Hash code depends on all deleted/changed elements; guaranteed zero for an empty diff, non-zero otherwise.
 boolean isEmpty()
          Returns true iff the diff is "empty", ie no deletions nor additions/changes.
static Tuple.Pair<java.util.Map<java.lang.String,java.util.Properties>,java.lang.Long> loadBundle(java.io.File dir, java.lang.String basename)
          Load a complete bundle of properties files with timestamp in one go; never null.
private  void readObject(java.io.ObjectInputStream ois)
          Deserialise.
protected  java.lang.Object readResolve()
          Deserialise: discard duplicate empty values.
 java.lang.String toString()
          Human-readable summary of state.
 void validateObject()
          Checks that the object is internally consistent.
private  void writeObject(java.io.ObjectOutputStream oos)
          Write out a less-redundant form of our internal information.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

deletedNames

private transient java.util.SortedSet<java.lang.String> deletedNames
The immutable in-order set of Properties sets entirely removed; never null. This field is NOT serialised directly.


newValues

private transient java.util.SortedMap<java.lang.String,PropertiesDiff> newValues
The immutable in-order map from items/names to the new/changed Properties sets; never null. Note that we store the differences in each underlying Properties set to efficiently represent small changes within each set.

This field is NOT serialised directly.


sizeBefore

public final int sizeBefore
The input bundle count as a sanity-check; guaranteed non-negative.


sizeAfter

public final int sizeAfter
The output bundle count as a sanity-check; guaranteed non-negative.


EMPTY_DIFF

public static final PropertiesBundleDiff EMPTY_DIFF
Immutable empty diff.


EMPTY_BUNDLE

private static final java.util.Map<java.lang.String,java.util.Properties> EMPTY_BUNDLE
Private empty Properties map; never changed, never null.


EMPTY_PROPERTIES

private static final java.util.Properties EMPTY_PROPERTIES
Private empty Properties map; never changed, never null.


_hash

private transient int _hash
Cached hash value; initially zero. We cache this to ensure that hashCode() always remains quick.

Since access is atomic, this need not be marked volatile.

Never set to zero once non-zero.


serialVersionUID

private static final long serialVersionUID
Serial UID.

See Also:
Constant Field Values
Constructor Detail

PropertiesBundleDiff

public PropertiesBundleDiff()
Make new empty diff instance.


PropertiesBundleDiff

public PropertiesBundleDiff(int sizeBefore,
                            int sizeAfter,
                            java.util.Set<java.lang.String> deleted,
                            java.util.Map<java.lang.String,PropertiesDiff> added)
Create diff instance. We defensively copy the potentially-mutable Collection argument.

Parameters:
sizeBefore - size of input Properties; non-negative
sizeAfter - size of output Properties; non-negative
deleted - named Properties sets present in input and not present in output; non-null
added - new/changed named Properties sets in output; non-null
Method Detail

getNewValues

public java.util.SortedMap<java.lang.String,PropertiesDiff> getNewValues()
Get newValues; never null.


_computeChangeValues

private static java.util.Set<Tuple.Pair<java.lang.String,java.util.Properties>> _computeChangeValues(java.util.Map<java.lang.String,java.util.Properties> pb)
Create "change" values from a Properties bundle; never null. This is the set of values to be added to an empty Properties value to regenerate this one.

The first element in each Pair is the (non-null) Properties set name; the second element is the (non-null) Properties set.

Parameters:
pb - non-null pure String-->String properties set

createAsStandAloneDiff

public static PropertiesBundleDiff createAsStandAloneDiff(java.util.Map<java.lang.String,java.util.Properties> p1)
Create diff against empty Properties. This is a safe, efficient, immutable, Serializable representation for a single Properties instance, where a raw Properties instance may not be safe/robust enough.

Forces intern()ing of the keys and values.


createFromStandAloneDiff

public static java.util.Map<java.lang.String,java.util.Properties> createFromStandAloneDiff(PropertiesBundleDiff pd)
                                                                                     throws AllExhibitPropertiesDelta.DiffException
Create from diff against empty Properties. Recovers Properties instance created by createAsDiff.

Throws:
AllExhibitPropertiesDelta.DiffException

createDiff

public static PropertiesBundleDiff createDiff(java.util.Map<java.lang.String,java.util.Properties> p1,
                                              java.util.Map<java.lang.String,java.util.Properties> p2,
                                              boolean force,
                                              boolean intern)
                                       throws AllExhibitPropertiesDelta.DiffException
Create diff between two Properties instances. This creates a diff to be applied to an instance of the first argument to recreate the second argument.

This will refuse to create a diff if it seems that the diff is unlikely to be useful, for example:

Parameters:
force - if true then force a diff to be produced even if this routine would normally refuse to do so on efficiency grounds
intern - if true than force intern()ing of all String values
Throws:
AllExhibitPropertiesDelta.DiffException - if no diff can be generated or is unlikely to be worthwhile to use (eg would be more than a fraction of the size of the second AEP)

applyDiff

public static java.util.Map<java.lang.String,java.util.Properties> applyDiff(java.util.Map<java.lang.String,java.util.Properties> bp1,
                                                                             PropertiesBundleDiff diff)
                                                                      throws AllExhibitPropertiesDelta.DiffException
Applies diff to an extant Properties instance to generate a new AEP instance; never null. The diff must only be applied to the same Properties instance value that the diff was generated from (ie an equal one).

We do very basic/quick sanity checks on the before/after sizes to catch misapplication of a diff to a clearly-inappropriate Properties set.

Throws:
AllExhibitPropertiesDelta.DiffException - if the diff cannot be applied

isEmpty

public boolean isEmpty()
Returns true iff the diff is "empty", ie no deletions nor additions/changes.


equals

public boolean equals(java.lang.Object obj)
Equal iff all fields are identical.

Overrides:
equals in class java.lang.Object

hashCode

public int hashCode()
Hash code depends on all deleted/changed elements; guaranteed zero for an empty diff, non-zero otherwise.

Overrides:
hashCode in class java.lang.Object

toString

public java.lang.String toString()
Human-readable summary of state.

Overrides:
toString in class java.lang.Object

writeObject

private void writeObject(java.io.ObjectOutputStream oos)
                  throws java.io.IOException
Write out a less-redundant form of our internal information. In particular, since deltas will not usually involve deletion of any values, we make the no-deletions case take no space at all in the serialised form.

Throws:
java.io.IOException

readObject

private void readObject(java.io.ObjectInputStream ois)
                 throws java.io.IOException,
                        java.lang.ClassNotFoundException
Deserialise. This intern()s all the Properties set names.

Throws:
java.io.IOException
java.lang.ClassNotFoundException

readResolve

protected java.lang.Object readResolve()
                                throws java.io.ObjectStreamException
Deserialise: discard duplicate empty values.

Throws:
java.io.ObjectStreamException

validateObject

public void validateObject()
                    throws java.io.InvalidObjectException
Checks that the object is internally consistent.

Specified by:
validateObject in interface java.io.ObjectInputValidation
Throws:
java.io.InvalidObjectException

loadBundle

public static Tuple.Pair<java.util.Map<java.lang.String,java.util.Properties>,java.lang.Long> loadBundle(java.io.File dir,
                                                                                                         java.lang.String basename)
                                                                                                  throws java.io.IOException
Load a complete bundle of properties files with timestamp in one go; never null. The timestamp is that of the newest (most-recently-modified) bundle member.

We load all files of form basename*.properties in the given directory.

Parameters:
dir - directory in which properties files are to be found; non-null
basename - base name of properties files; non-null
Throws:
java.io.FileNotFoundException - if directoiry not found or no bundle files found
java.io.IOException - in case of difficulty loading bundle files

DHD Multimedia Gallery V1.57.21

Copyright (c) 1996-2011, Damon Hart-Davis. All rights reserved.