org.crosswire.common.util

## Class CWProject

- java.lang.Object
- - org.crosswire.common.util.CWProject

-     public final class CWProject
      extends Object

  The Project class looks after the source of project files. These are per user files and as such have a different location on different operating systems. These are:

  Mac OS X | ~/Library/Application Support/JSword
  Win NT/2000/XP/ME/9x | ~/Application Data/JSword (~ is all over the place, but Java figures it out)
  Unix and otherwise | ~/.jsword

  Previously the location was ~/.jsword, which is unfriendly in the Windows and Mac world. If this location is found on Mac or Windows, it will be moved to the new location, if different and possible.

  Note: If the Java System property jsword.home is set and it exists and is writable then it will be used instead of the above location. This is useful for USB Drives and other portable implementations of JSword. It is recommended that this name be JSword.

  Author:
    DM Smith
  See Also:
    `The GNU Lesser General Public License for details.`

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `private static String` | `DIR_NETCACHE` The cache of downloaded files inside the project directory
    `private String` | `frontendName` The name of the front-end application.
    `private URI` | `frontendReadHome` Front-end read home, could be null if not present
    `private static String` | `homeAltDirectory` The JSword user settings directory for Mac and Windows
    `private static String` | `homeDirectory` The JSword user settings directory
    `private static String` | `homeProperty` System property for home directory
    `private URI[]` | `homes` The homes for this application: first is writable, second (if present) is read-only and specified by the system property jsword.home.
    `private static CWProject` | `instance` The filesystem resources
    `private static org.slf4j.Logger` | `LOGGER` The log stream
    `private URI` | `readHome` The readable home for this application, specified by the system property jsword.home.
    `private URI` | `writableFrontEndHome` Front-end home, where the app can write information to it.
    `private URI` | `writeHome` The writable home for this application.

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `private` | `CWProject()` Prevent instantiation.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `private void` | `establishProjectHome()` Establishes the user's project directory.
    `URI` | `getDeprecatedWritableProjectDir()` Get the location where the project directory used to be.
    `URI[]` | `getProjectResourceDirs()` Get the locations where project resources can be found.
    `URI` | `getReadableFrontendProjectDir()`
    `URI` | `getWritableFrontendProjectDir()`
    `URI` | `getWritableProjectDir()` Get the writable user project directory.
    `URI` | `getWritableProjectSubdir(String subject, boolean create)` A directory within the project directory.
    `URI` | `getWritableURI(String subject, String extension)` Create a the URI for a (potentially non-existent) file to which we can write.
    `static CWProject` | `instance()` Accessor for the resource singleton.
    `private URI` | `migrateUserProjectDir(URI oldPath, URI newPath)` Migrates the user's project dir, if necessary and possible.
    `private static void` | `reset()` Required for reset of statics during testing
    `void` | `setFrontendName(String frontendName)` Sets the name of the front-end.
    `static void` | `setHome(String homeProperty, String homeDir, String altHomeDir)` Establish how this project finds it's resources.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### DIR_NETCACHE

          private static final String DIR_NETCACHE

      The cache of downloaded files inside the project directory
      See Also:
        Constant Field Values

    - #### homes

          private URI[] homes

      The homes for this application: first is writable, second (if present) is read-only and specified by the system property jsword.home.

    - #### writeHome

          private URI writeHome

      The writable home for this application.

    - #### frontendName

          private String frontendName

      The name of the front-end application. This allows front-ends to store information under the jsword directory, separate from other front-ends

    - #### readHome

          private URI readHome

      The readable home for this application, specified by the system property jsword.home. Null, if jsword.home is also writable.

    - #### writableFrontEndHome

          private URI writableFrontEndHome

      Front-end home, where the app can write information to it. Could be null if failed to create

    - #### frontendReadHome

          private URI frontendReadHome

      Front-end read home, could be null if not present

    - #### homeProperty

          private static String homeProperty

      System property for home directory

    - #### homeDirectory

          private static String homeDirectory

      The JSword user settings directory

    - #### homeAltDirectory

          private static String homeAltDirectory

      The JSword user settings directory for Mac and Windows

    - #### instance

          private static CWProject instance

      The filesystem resources

    - #### LOGGER

          private static final org.slf4j.Logger LOGGER

      The log stream

  - ### Constructor Detail

    - #### CWProject

          private CWProject()

      Prevent instantiation.

  - ### Method Detail

    - #### instance

          public static CWProject instance()

      Accessor for the resource singleton.
      Returns:
        the singleton

    - #### reset

          private static void reset()

      Required for reset of statics during testing

    - #### setHome

          public static void setHome(String homeProperty,
                     String homeDir,
                     String altHomeDir)

      Establish how this project finds it's resources.
      Parameters:
        `homeProperty` - a property that is used as the home directory name. If this property has a value then homeDir and altHomeDir are ignored. Defaults to jsword.home.
        `homeDir` - the name of the directory to be used for Unix. Typically this is a hidden directory, that is, it begins with a '.'. Defaults to .jsword
        `altHomeDir` - the name of the directory to be used for other OSes. This should not be a hidden directory. Defaults to JSword.

    - #### setFrontendName

          public void setFrontendName(String frontendName)

      Sets the name of the front-end. This then informs the read/write directory of the front-end.
      Parameters:
        `frontendName` -

    - #### getWritableFrontendProjectDir

          public URI getWritableFrontendProjectDir()

      Returns:
        the writable home for the front-end settings, that can be kept separate from JSword's configuration, as well from other front-ends.

    - #### getReadableFrontendProjectDir

          public URI getReadableFrontendProjectDir()

      Returns:
        the readable home for the front-end settings, that can be kept separate from JSword's configuration, as well from other front-ends.

    - #### getWritableProjectDir

          public URI getWritableProjectDir()

      Get the writable user project directory.
      Returns:
        the writable user project directory.

    - #### getProjectResourceDirs

          public URI[] getProjectResourceDirs()

      Get the locations where project resources can be found.
      Returns:
        an array of URIs which can be used to look up resources.

    - #### getDeprecatedWritableProjectDir

          public URI getDeprecatedWritableProjectDir()

      Get the location where the project directory used to be.
      Returns:
        ~/.jsword

    - #### getWritableURI

          public URI getWritableURI(String subject,
                           String extension)

      Create a the URI for a (potentially non-existent) file to which we can write. Typically this is used to store user preferences and application overrides. This method of acquiring files is preferred over getResourceProperties() as this is writable and can take into account user preferences. This method makes no promise that the URI returned is valid. It is totally untested, so reading may well cause errors.
      Parameters:
        `subject` - The name (minus the .xxx extension)
        `extension` - The extension, prefixed with a '.' See: `FileUtil` for a list of popular extensions.
      Returns:
        The resource as a URI

    - #### getWritableProjectSubdir

          public URI getWritableProjectSubdir(String subject,
                                     boolean create)
                                       throws IOException

      A directory within the project directory.
      Parameters:
        `subject` - A name for the subdirectory of the Project directory.
        `create` - whether to create the directory if it does not exist
      Returns:
        A file: URI pointing at a local writable directory.
      Throws:
        `IOException`

    - #### establishProjectHome

          private void establishProjectHome()

      Establishes the user's project directory. In a CD installation, the home directory on the CD will be read-only. This is not sufficient. We also need a writable home directory. And in looking up resources, the ones in the writable directory trump those in the readable directory, allowing the read-only resources to be overridden.

      Here is the lookup order:

      1. Check first to see if the jsword.home property is set.
      2. Check for the existence of a platform specific project area and for the existence of a deprecated project area (~/.jsword on Windows and Mac) and if it exists and it is possible "upgrade" to the platform specific project area. Of these "two" only one is the folder to check.
      In checking these areas, if the one is read-only, add it to the list and keep going. However, if it is also writable, then use it alone.

    - #### migrateUserProjectDir

          private URI migrateUserProjectDir(URI oldPath,
                                  URI newPath)

      Migrates the user's project dir, if necessary and possible.
      Parameters:
        `oldPath` - the path to the old, deprecated location
        `newPath` - the path to the new location
      Returns:
        newPath if the migration was possible or not needed.