[jsword-svn] r1693 - in trunk: bibledesktop/src/main/java/org/crosswire/bibledesktop/book common common/src/main/java/org/crosswire/common/util common/src/test/java/org/crosswire/common/icu jsword/src/main/java/org/crosswire/jsword/book/install/sword jsword/src/main/java/org/crosswire/jsword/book/sword jsword/src/main/java/org/crosswire/jsword/index/lucene jsword/src/main/java/org/crosswire/jsword/util jsword-limbo/src/main/java/org/crosswire/jsword/book/search/ser
dmsmith at www.crosswire.org
dmsmith at www.crosswire.org
Sun Aug 26 18:00:37 MST 2007
Author: dmsmith
Date: 2007-08-26 18:00:36 -0700 (Sun, 26 Aug 2007)
New Revision: 1693
Modified:
trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/book/BibleViewPane.java
trunk/common/JSwordDictionary.txt
trunk/common/src/main/java/org/crosswire/common/util/CWClassLoader.java
trunk/common/src/main/java/org/crosswire/common/util/NetUtil.java
trunk/common/src/test/java/org/crosswire/common/icu/AllTests.java
trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/search/ser/SerIndexManager.java
trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java
trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/SwordBookPath.java
trunk/jsword/src/main/java/org/crosswire/jsword/index/lucene/LuceneIndexManager.java
trunk/jsword/src/main/java/org/crosswire/jsword/util/Project.java
Log:
Made CD installations use a read-only jsword.home
Modified: trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/book/BibleViewPane.java
===================================================================
--- trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/book/BibleViewPane.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/bibledesktop/src/main/java/org/crosswire/bibledesktop/book/BibleViewPane.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -89,11 +89,11 @@
{
try
{
- chooser = new JFileChooser(Project.instance().getUserSubProjectDir(BOOKMARK_DIR, true).getPath());
+ chooser = new JFileChooser(Project.instance().getWriteableProjectSubdir(BOOKMARK_DIR, true).getPath());
}
catch (IOException ex)
{
- chooser = new JFileChooser(Project.instance().getUserProjectDir().getPath());
+ chooser = new JFileChooser(Project.instance().getWritableProjectDir().getPath());
}
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
Modified: trunk/common/JSwordDictionary.txt
===================================================================
--- trunk/common/JSwordDictionary.txt 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/common/JSwordDictionary.txt 2007-08-27 01:00:36 UTC (rev 1693)
@@ -24,3 +24,5 @@
eireneh
subdirectory
deprecated
+primordial
+filesystem
Modified: trunk/common/src/main/java/org/crosswire/common/util/CWClassLoader.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/util/CWClassLoader.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/common/src/main/java/org/crosswire/common/util/CWClassLoader.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -21,7 +21,6 @@
*/
package org.crosswire.common.util;
-import java.io.File;
import java.net.URI;
import java.net.URL;
import java.security.AccessController;
@@ -31,6 +30,8 @@
* CWClassLoader extends the regular class loader by using looking
* in more places. This is needed so that ResourceBundle can find
* resources that are not held in the same package as the class.
+ * This is expressed as a list of locations, called homes, that
+ * the program will look in.
*
* @see gnu.lgpl.License for license details.<br>
* The copyright to this program is held by it's authors.
@@ -125,7 +126,7 @@
}
}
- // See if it can be found in the home directory
+ // See if it can be found in a home directory
if (resource == null)
{
URI homeResource = CWClassLoader.findHomeResource(search);
@@ -261,50 +262,58 @@
}
/**
- * If the application has set the home, it will return
- * the application's home directory, otherwise it returns null.
+ * If the application has set the homes, it will return
+ * the application's requested home directory, otherwise it returns null.
* @return Returns the home.
*/
- public static synchronized URI getHome()
+ public static synchronized URI getHome(int i)
{
- return home;
+ if (i > 0 && i < homes.length)
+ {
+ return homes[i];
+ }
+ return null;
}
/**
* Establish the applications home directory from where
* additional resources can be found. URL is expected to
* end with the directory name, not '/'.
- * @param newhome The home to set.
+ * @param newHomes The home to set.
*/
- public static synchronized void setHome(URI newhome)
+ public static synchronized void setHome(URI[] newHomes)
{
- home = newhome;
+ homes = new URI[newHomes.length];
+ System.arraycopy(newHomes, 0, homes, 0, newHomes.length);
}
/**
- * Look for the resource in the home directory
+ * Look for the resource in the home directories, returning the first
+ * readable file.
+ *
* @param search must be non-null, non-empty
*/
public static URI findHomeResource(String search)
{
- URI reply = null;
+ if (homes == null)
+ {
+ return null;
+ }
- URI homeURI = getHome();
+ for (int i = 0; i < homes.length; i++)
+ {
+ URI homeURI = homes[i];
- // Look at the application's home first to allow overrides
- if (homeURI != null)
- {
URI override = NetUtil.lengthenURI(homeURI, search);
// Make sure the file exists and can be read
- File file = new File(override.getPath());
- if (file.canRead())
+ if (NetUtil.canRead(override))
{
- reply = override;
+ return override;
}
}
- return reply;
+ return null;
}
/**
@@ -355,5 +364,5 @@
/**
* Notion of a project's home from where additional resources can be found.
*/
- private static URI home;
+ private static URI[] homes;
}
Modified: trunk/common/src/main/java/org/crosswire/common/util/NetUtil.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/util/NetUtil.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/common/src/main/java/org/crosswire/common/util/NetUtil.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -227,7 +227,7 @@
* If there is a writable directory or file at the other end of this URI return true.
* Note non file: type URIs will always return false
* @param orig The URI to check
- * @return true if the URI points at a file: directory
+ * @return true if the URI points at a writable file or directory
*/
public static boolean canWrite(URI orig)
{
@@ -240,6 +240,22 @@
}
/**
+ * If there is a readable directory or file at the other end of this URI return true.
+ * Note non file: type URIs will always return false
+ * @param orig The URI to check
+ * @return true if the URI points at a readable file or directory
+ */
+ public static boolean canRead(URI orig)
+ {
+ if (!orig.getScheme().equals(PROTOCOL_FILE))
+ {
+ return false;
+ }
+
+ return new File(orig.getPath()).canRead();
+ }
+
+ /**
* Move a URI from one place to another. Currently this only works for
* file: URIs, however the interface should not need to change to
* handle more complex URIs
Modified: trunk/common/src/test/java/org/crosswire/common/icu/AllTests.java
===================================================================
--- trunk/common/src/test/java/org/crosswire/common/icu/AllTests.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/common/src/test/java/org/crosswire/common/icu/AllTests.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -37,7 +37,7 @@
{
TestSuite suite = new TestSuite("Test for org.crosswire.common.icu"); //$NON-NLS-1$
//$JUnit-BEGIN$
- suite.addTest(new TestSuite(NumberShaper.class));
+ suite.addTest(new TestSuite(NumberShaperTest.class));
//$JUnit-END$
return suite;
}
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -489,7 +489,7 @@
{
try
{
- URI scratchdir = Project.instance().getUserSubProjectDir(getTempFileExtension(host, catalogDirectory), true);
+ URI scratchdir = Project.instance().getWriteableProjectSubdir(getTempFileExtension(host, catalogDirectory), true);
return NetUtil.lengthenURI(scratchdir, FILE_LIST_GZ);
}
catch (IOException ex)
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/SwordBookPath.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/SwordBookPath.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/SwordBookPath.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -32,6 +32,7 @@
import java.util.Properties;
import org.crosswire.common.util.Logger;
+import org.crosswire.common.util.OSType;
import org.crosswire.common.util.StringUtil;
import org.crosswire.jsword.book.BookException;
import org.crosswire.jsword.book.Books;
@@ -181,13 +182,13 @@
readSwordConf(bookDirs, sysconfigPaths[i]);
}
- URI userDataArea = Project.instance().getUserProjectDir(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
+ URI userDataArea = OSType.getOSType().getUserAreaFolder(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
// Check look for mods.d in the sword user data area
testDefaultPath(bookDirs, new File(userDataArea.getPath()));
// If the migration did not work then use the old area
- testDefaultPath(bookDirs, new File(Project.instance().getUserProjectDir().getPath()));
+ testDefaultPath(bookDirs, new File(Project.instance().getWritableProjectDir().getPath()));
return (File[]) bookDirs.toArray(new File[bookDirs.size()]);
}
@@ -291,7 +292,7 @@
// If it is not found on the path then it doesn't exist yet and needs to be established
if (path == null)
{
- URI userDataArea = Project.instance().getUserProjectDir(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
+ URI userDataArea = OSType.getOSType().getUserAreaFolder(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
path = new File(userDataArea.getPath());
}
@@ -301,13 +302,13 @@
private static void migrateBookDir()
{
// Books should be on this path
- URI userDataArea = Project.instance().getUserProjectDir(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
+ URI userDataArea = OSType.getOSType().getUserAreaFolder(DIR_SWORD_CONF, DIR_SWORD_CONF_ALT);
File swordBookPath = new File(userDataArea.getPath());
// The "old" Book location might be in one of two locations
// It might be ~/.jsword or the new project dir
- File oldPath = new File(Project.instance().getDeprecatedUserProjectDir().getPath());
+ File oldPath = new File(Project.instance().getDeprecatedWritableProjectDir().getPath());
if (oldPath.isDirectory())
{
@@ -315,7 +316,7 @@
return;
}
- oldPath = new File(Project.instance().getUserProjectDir().getPath());
+ oldPath = new File(Project.instance().getWritableProjectDir().getPath());
if (oldPath.isDirectory())
{
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/index/lucene/LuceneIndexManager.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/index/lucene/LuceneIndexManager.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/index/lucene/LuceneIndexManager.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -190,7 +190,7 @@
assert driverName != null;
assert bookName != null;
- URI base = Project.instance().getUserSubProjectDir(DIR_LUCENE, false);
+ URI base = Project.instance().getWriteableProjectSubdir(DIR_LUCENE, false);
URI driver = NetUtil.lengthenURI(base, driverName);
return NetUtil.lengthenURI(driver, bookName);
Modified: trunk/jsword/src/main/java/org/crosswire/jsword/util/Project.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/util/Project.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/util/Project.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -93,11 +93,11 @@
*/
private Project()
{
- CWClassLoader.setHome(getUserProjectDir());
+ CWClassLoader.setHome(getProjectResourceDirs());
try
{
- URI uricache = getUserSubProjectDir(DIR_NETCACHE, true);
+ URI uricache = getWriteableProjectSubdir(DIR_NETCACHE, true);
File filecache = new File(uricache.getPath());
NetUtil.setURICacheDir(filecache);
}
@@ -110,48 +110,33 @@
}
/**
- * Establishes the user's project directory.
+ * Get the writable user project directory.
+ *
+ * @return the writable user project directory.
*/
- public URI getUserProjectDir(String hiddenFolderName, String visibleFolderName)
+ public URI getWritableProjectDir()
{
- return OSType.getOSType().getUserAreaFolder(hiddenFolderName, visibleFolderName);
+ establishProjectHome();
+ return writeHome;
}
/**
- * Establishes the user's project directory.
+ * Get the locations where project resources can be found.
+ *
+ * @return an array of URIs which can be used to look up resources.
*/
- public URI getUserProjectDir()
+ public URI[] getProjectResourceDirs()
{
- if (home == null)
- {
- // if there is a property set for the jsword home directory
- String jswordhome = System.getProperty(PROPERTY_JSWORD_HOME);
- if (jswordhome != null)
- {
- home = NetUtil.getURI(new File(jswordhome));
- if (!NetUtil.canWrite(home))
- {
- home = null;
- }
- }
- }
-
- if (home == null)
- {
- URI path = getUserProjectDir(DIR_PROJECT, DIR_PROJECT_ALT);
- URI oldPath = getDeprecatedUserProjectDir();
- home = migrateUserProjectDir(oldPath, path);
- }
-
- return home;
+ establishProjectHome();
+ return homes;
}
/**
- * Get the location where the project dir used to be.
+ * Get the location where the project directory used to be.
*
* @return ~/.jsword
*/
- public URI getDeprecatedUserProjectDir()
+ public URI getDeprecatedWritableProjectDir()
{
return OSType.DEFAULT.getUserAreaFolder(DIR_PROJECT, DIR_PROJECT_ALT);
}
@@ -199,18 +184,18 @@
*/
public URI getWritablePropertiesURI(String subject)
{
- return NetUtil.lengthenURI(getUserProjectDir(), subject + FileUtil.EXTENSION_PROPERTIES);
+ return NetUtil.lengthenURI(getWritableProjectDir(), subject + FileUtil.EXTENSION_PROPERTIES);
}
/**
- * A directory within the project dir.
+ * A directory within the project directory.
*
* @param subject A name for the subdirectory of the Project directory.
* @return A file: URI pointing at a local writable directory.
*/
- public URI getUserSubProjectDir(String subject, boolean create) throws IOException
+ public URI getWriteableProjectSubdir(String subject, boolean create) throws IOException
{
- URI temp = NetUtil.lengthenURI(getUserProjectDir(), subject);
+ URI temp = NetUtil.lengthenURI(getWritableProjectDir(), subject);
if (create && !NetUtil.isDirectory(temp))
{
@@ -219,18 +204,84 @@
return temp;
}
+ /**
+ * 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.
+ * <p>Here is the lookup order:
+ * <ol>
+ * <li>Check first to see if the jsword.home property is set.</li>
+ * <li>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.</li>
+ * </ol>
+ * 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.
+ */
+ private void establishProjectHome()
+ {
+ if (writeHome == null && readHome == null)
+ {
+ // if there is a property set for the jsword home directory
+ String jswordhome = System.getProperty(PROPERTY_JSWORD_HOME);
+ if (jswordhome != null)
+ {
+ URI home = NetUtil.getURI(new File(jswordhome));
+ if (NetUtil.canWrite(home))
+ {
+ writeHome = home;
+ }
+ else if (NetUtil.canRead(home))
+ {
+ readHome = home;
+ }
+ // otherwise jsword.home is not usable.
+ }
+ }
+ if (writeHome == null)
+ {
+ URI path = OSType.getOSType().getUserAreaFolder(DIR_PROJECT, DIR_PROJECT_ALT);
+ URI oldPath = getDeprecatedWritableProjectDir();
+ writeHome = migrateUserProjectDir(oldPath, path);
+ }
+
+ if (homes == null)
+ {
+ if (readHome == null)
+ {
+ homes = new URI[] { writeHome };
+ }
+ else
+ {
+ homes = new URI[] { writeHome, readHome };
+ }
+ }
+ }
+
/**
* System property for jsword home directory
*/
private static final String PROPERTY_JSWORD_HOME = "jsword.home"; //$NON-NLS-1$
/**
- * The home for this application
+ * The homes for this application: first is writable, second (if present) is read-only and specified by the system property jsword.home.
*/
- private URI home;
+ private URI[] homes;
/**
+ * The writable home for this application.
+ */
+ private URI writeHome;
+
+ /**
+ * The readable home for this application, specified by the system property jsword.home. Null, if jsword.home is also writable.
+ */
+ private URI readHome;
+
+ /**
* The log stream
*/
private static final Logger log = Logger.getLogger(Project.class);
Modified: trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/search/ser/SerIndexManager.java
===================================================================
--- trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/search/ser/SerIndexManager.java 2007-08-26 22:56:26 UTC (rev 1692)
+++ trunk/jsword-limbo/src/main/java/org/crosswire/jsword/book/search/ser/SerIndexManager.java 2007-08-27 01:00:36 UTC (rev 1693)
@@ -161,7 +161,7 @@
assert driverName != null;
assert bookName != null;
- URI base = Project.instance().getUserSubProjectDir(DIR_SER, false);
+ URI base = Project.instance().getWriteableProjectSubdir(DIR_SER, false);
URI driver = NetUtil.lengthenURI(base, driverName);
return NetUtil.lengthenURI(driver, bookName);
More information about the jsword-svn
mailing list