org.hd.d.pg2k.svrCore
Class ExhibitPropsLoadable

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.ExhibitPropsLoadable
All Implemented Interfaces:
java.io.ObjectInputValidation, java.io.Serializable, MemoryTools.Compactable, MemoryTools.Internable

public final class ExhibitPropsLoadable
extends java.lang.Object
implements java.io.Serializable, java.io.ObjectInputValidation, MemoryTools.Internable, MemoryTools.Compactable

Immutable (and serialisable) store of all loadable auxiliary properties of a single exhibit. These are properties (such as descriptive comment) that must be fetched from the exhibit database and that cannot be computed.

This is designed to be efficient on the wire and in memory, since these details will be held for each and every exhibit.

Note that a factory method is used to generate instances of this class and where there is no loadable data for an exhibit (which will be rare) null is returned.

Equals is implemented so that duplicates (particularly of EMPTY) can easily be discarded. hashCode() is implemented to support the semantics of equals() and as a hash over all the contents of the object.

By default this looks for data in a new-style properties file first (fileBase + '/' + exhibitName + ".props"), and then, iff READ_OLD_FILES == true, in the old-style individual files.

See Also:
Serialized Form

Field Summary
private  int _hash
          Private to hashCode() lock-free cache of computed hash value; initially 0 indicating not computed.
private  AccessionData accession
          Accession data; null if none.
private static boolean DEFER_COMPACTION
          If true then defer compaction of metadata.
private  java.lang.Object description
          The description.
static ExhibitPropsLoadable EMPTY
          Shared EMPTY instance (no auxiliary data on exhibit).
static java.lang.String EXHIBIT_PROPS_FILENAME_SUFFIX
          Suffix for new-format exhibit-properties file, if extant.
private  Location.Base location
          Location information; null if none.
static java.lang.String PNAME_DESCRIPTION
          Name of property for (default English text/HTML) description in new properties file.
static java.lang.String PNAME_LOCATION_PREFIX
          Prefix of property names for location information in new properties file.
static boolean READ_OLD_FILES
          Allow backwards compatibility if true, ie look for old-style files for info not found in new props file.
static Compact7BitString.StaticDictionary sDict
          Shared static dictionary for use with in-memory Compact7BitString metadata.
private static long serialVersionUID
          My serial ID.
 
Constructor Summary
private ExhibitPropsLoadable(java.lang.Object _description, Location.Base _location, AccessionData _accession, boolean doNotCompact)
          Private constructor so creation is by factory method.
 
Method Summary
private static java.lang.String _decompressASCII7Text(byte[] compressed)
          Attempt to decompress some deflated bytes to an ASCII 7-bit String.
 void compact()
          Compact the internal representation of this instance (and its sub-objects) if possible.
 boolean equals(java.lang.Object o)
          Based on entire content of object; if equivalent content then they are equal.
 AccessionData getAccessionMetadata()
          Get exhibit accession metadata; null if none available.
 java.lang.String getCompactableInstanceName()
          Get name of this Compactable instance for tracking purposes, or null if none.
 java.lang.String getDescription()
          Get the description; returns null if none, else non-empty String.
static ExhibitPropsLoadable getLoadableProperties(Name.ExhibitFull exhibitName, java.io.File exhibitBaseDir)
          Make a new instance with data loaded from the filesystem, given the exhibit name and some filesystem base directories.
 Location.Base getLocation()
          Return location information; null if none.
 boolean hasDescription()
          Reports if there is a description; returns true if so.
 int hashCode()
          Based on entire content of object; if equivalent content then they have same hash.
static java.util.Set<java.lang.String> listPropsFiles(Name.ExhibitFull exhibitName, java.io.File exhibitBaseDir)
          Method that lists exhibit-specific files containing loadable properties of the given exhibit.
protected  java.lang.Object readResolve()
          Deserialise: use constructor for validation, defensive copying, etc.
static java.lang.String relPathToNewAccession(Name.ExhibitFull exhibitName)
          Make relative path to new accession-date file; never null.
private static java.lang.String relPathToNewProperties(Name.ExhibitFull exhibitName)
          Make relative path to new-style properties file.
static java.lang.String relPathToOldAccession(Name.ExhibitFull exhibitName)
          Make relative path to old accession-date file; never null.
private static java.lang.String relPathToOldDescription(Name.ExhibitFull exhibitName)
          Make relative path to old-style en-GB HTML generic description file.
private static java.lang.String relPathToOldLocation(Name.ExhibitFull exhibitName)
          Make relative path to old-style accession-date YYYY[/MM[/DD]] file.
 java.lang.String toString()
          Human-readable summary.
 void validateObject()
          Validate fields/state.
protected  java.lang.Object writeReplace()
          Serialise: write in the best format for the wire.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

EMPTY

public static final ExhibitPropsLoadable EMPTY
Shared EMPTY instance (no auxiliary data on exhibit).


_hash

private transient int _hash
Private to hashCode() lock-free cache of computed hash value; initially 0 indicating not computed.


serialVersionUID

private static final long serialVersionUID
My serial ID.

See Also:
Constant Field Values

EXHIBIT_PROPS_FILENAME_SUFFIX

public static final java.lang.String EXHIBIT_PROPS_FILENAME_SUFFIX
Suffix for new-format exhibit-properties file, if extant.

See Also:
Constant Field Values

READ_OLD_FILES

public static final boolean READ_OLD_FILES
Allow backwards compatibility if true, ie look for old-style files for info not found in new props file.

See Also:
Constant Field Values

PNAME_DESCRIPTION

public static final java.lang.String PNAME_DESCRIPTION
Name of property for (default English text/HTML) description in new properties file.

See Also:
Constant Field Values

PNAME_LOCATION_PREFIX

public static final java.lang.String PNAME_LOCATION_PREFIX
Prefix of property names for location information in new properties file.

See Also:
Constant Field Values

sDict

public static final Compact7BitString.StaticDictionary sDict
Shared static dictionary for use with in-memory Compact7BitString metadata. We expose this to help generate tuned dictionary values; this is safe to do since this dictionary is immutable.


description

private volatile java.lang.Object description
The description. This can be:
  • null, meaning no description,
  • a non-empty String for the literal description
  • a non-empty byte[] containing a maximally deflated copy of the string without zlib or gzip headers and trailers
  • a ROByteArray created with compressFromString()
  • a Name (the preferred on-the-wire form)
  • a Compact7BitString (the preferred in-memory form).
  • Support for the byte[] and ROByteArray formats exists mainly for backwards compatibility, ie deserialising old values. All bytes in the source string are of value 0--127 (ie ASCII 7-bit).

    Marked volatile to allow safe lockless update by compact().


    location

    private final Location.Base location
    Location information; null if none. Information here must always be marked "specific".


    accession

    private final AccessionData accession
    Accession data; null if none.


    DEFER_COMPACTION

    private static final boolean DEFER_COMPACTION
    If true then defer compaction of metadata. If true then (any) compaction is NOT done during construction or deserialisation since it may place memory under more stress with old and new versions in memory simultaneously, but until some later point such as a call to compact().

    Conversely, this could save a lot of time constructing/deserialising data before the first operations can be performed on it and where memory space is not the primary constraint.

    See Also:
    Constant Field Values
    Constructor Detail

    ExhibitPropsLoadable

    private ExhibitPropsLoadable(java.lang.Object _description,
                                 Location.Base _location,
                                 AccessionData _accession,
                                 boolean doNotCompact)
    Private constructor so creation is by factory method. Parameters should already have been checked before we are called.

    We may intern() components that are likely to be duplicated and that may consume significant memory.

    Parameters:
    _description - no more than MAX_DESCRIPTION_CHARS or null or "" if none
    doNotCompact - if true then do not attempt to compact the description; store as passed in
    Method Detail

    relPathToNewProperties

    private static java.lang.String relPathToNewProperties(Name.ExhibitFull exhibitName)
    Make relative path to new-style properties file.


    relPathToOldDescription

    private static java.lang.String relPathToOldDescription(Name.ExhibitFull exhibitName)
    Make relative path to old-style en-GB HTML generic description file.


    relPathToNewAccession

    public static java.lang.String relPathToNewAccession(Name.ExhibitFull exhibitName)
    Make relative path to new accession-date file; never null. This is an XML-format file.

    Public so that other routines can find and read this file directly.

    Parameters:
    exhibitName - non-null relative path to exhibit

    relPathToOldAccession

    public static java.lang.String relPathToOldAccession(Name.ExhibitFull exhibitName)
    Make relative path to old accession-date file; never null. Historically the format of this file is a single line of the format:
         YYYY[/MM[/DD]]
     
    where YYYY is the year and MM is the month 01--12 and DD is the 01-31, all relative to UTC/GMT, and represent the approximate date that the exhibits where incorporated in the library.

    Public so that other routines can find and read this file directly.

    Parameters:
    exhibitName - non-null relative path to exhibit

    relPathToOldLocation

    private static java.lang.String relPathToOldLocation(Name.ExhibitFull exhibitName)
    Make relative path to old-style accession-date YYYY[/MM[/DD]] file.


    getLoadableProperties

    public static ExhibitPropsLoadable getLoadableProperties(Name.ExhibitFull exhibitName,
                                                             java.io.File exhibitBaseDir)
                                                      throws java.io.IOException
    Make a new instance with data loaded from the filesystem, given the exhibit name and some filesystem base directories. In case of severe unexpected problems with retrieving information an IOException is thrown, but minor problems are resolved quietly and a message is reported on System.err.

    Returns:
    null, or non-null non-EMPTY result
    Throws:
    java.io.IOException - in case of severe, unrecoverable difficulty with this exhibit

    equals

    public boolean equals(java.lang.Object o)
    Based on entire content of object; if equivalent content then they are equal. Can be used to eliminate duplicates, eg after deserialising.

    Overrides:
    equals in class java.lang.Object

    toString

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

    Overrides:
    toString in class java.lang.Object

    hashCode

    public int hashCode()
    Based on entire content of object; if equivalent content then they have same hash. Can be used for tracking if content has changed from one scan to another, ie is optimised for spotting changes rather than key distribution for use in a Hashtable, for example, though it should be serviceable for that purpose too as it is computed once and cached (transiently).

    The cache relies on atomic assignment of int and is lock-free.

    This may be slow to compute.

    The hash value is never zero.

    Overrides:
    hashCode in class java.lang.Object

    readResolve

    protected java.lang.Object readResolve()
    Deserialise: use constructor for validation, defensive copying, etc. Also resolve all empty instances to a singleton as a minor optimisation, and immediately intern() new values so as to immediately discard duplicates (eg of exhibits already known) ASAP to minimise heap churn.


    writeReplace

    protected java.lang.Object writeReplace()
    Serialise: write in the best format for the wire. To get best aggregate compressed size on the wire, eg where the compressed stream contains many similar non-identical instances, we always write out (non-null) description in Name format (minus the outer tags) regardless of how it is actually held in memory. This also makes us immune to changes in the the internals of the other formats and allows use of a static dictionary with Compact7BitString for better in-memory compression (ie effectively cross-instance compression).

    This allows a stream compressor to effectively remove the redundancy between instances of this class on the wire as well as internal redundancies.

    We assume that there will almost never be entirely identical instances on one stream so we don't mind writing new copies each time where it does happen.


    validateObject

    public void validateObject()
                        throws java.io.InvalidObjectException
    Validate fields/state. Called in the constructor and possibly after de-serialising.

    Barf if something bad is found. (Maybe allow some extra info in debug version.)

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

    getDescription

    public java.lang.String getDescription()
    Get the description; returns null if none, else non-empty String. This text may contain non-XML-safe and non-ASCII 7-bit characters.


    hasDescription

    public boolean hasDescription()
    Reports if there is a description; returns true if so. This is relatively inexpensive as it does not require inspecting or decompressing (etc) any message text.


    _decompressASCII7Text

    private static java.lang.String _decompressASCII7Text(byte[] compressed)
                                                   throws java.io.IOException
    Attempt to decompress some deflated bytes to an ASCII 7-bit String. (Actually, we won't mind if it happens to be 8-bit.)

    Throws:
    java.io.IOException

    getLocation

    public Location.Base getLocation()
    Return location information; null if none. Always marked as "specific".


    getAccessionMetadata

    public AccessionData getAccessionMetadata()
    Get exhibit accession metadata; null if none available. This data includes such items as:


    compact

    public void compact()
    Compact the internal representation of this instance (and its sub-objects) if possible. This has no effect on the logical content of this instance in-memory or serialised, is guaranteed to be safe to run concurrently with other uses of this instance (and will take any locks as needed to work incrementally), and may do nothing but consume some CPU cycles.

    This may be able to convert some state to a more memory-efficient representation after construction or deserialisation, and is suitable to call in a background thread.

    We don't prevent multiple concurrent calls to this routine, since they are at worst wasteful of CPU but not unsafe.

    Specified by:
    compact in interface MemoryTools.Compactable

    getCompactableInstanceName

    public java.lang.String getCompactableInstanceName()
    Get name of this Compactable instance for tracking purposes, or null if none.

    Specified by:
    getCompactableInstanceName in interface MemoryTools.Compactable

    listPropsFiles

    public static java.util.Set<java.lang.String> listPropsFiles(Name.ExhibitFull exhibitName,
                                                                 java.io.File exhibitBaseDir)
    Method that lists exhibit-specific files containing loadable properties of the given exhibit. This takes the same arguments as getLoadableProperties() and returns a Set of the String names of all files (relative to exhibitBaseDir) that contain loadable-properties for this exhibit.

    This may name more files than are currently used by the system, eg including legacy files.

    This never returns null, though may return an empty set.

    When backing up exhibit data these files should be backed up with the relevant exhibit.


    DHD Multimedia Gallery V1.57.21

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