]> source.dussan.org Git - jackcess.git/commitdiff
implement some tweaks which allow jackcess to be used on the android platform, thanks...
authorJames Ahlborn <jtahlborn@yahoo.com>
Wed, 3 Nov 2010 02:58:25 +0000 (02:58 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Wed, 3 Nov 2010 02:58:25 +0000 (02:58 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@496 f203690c-595d-4dc9-a70b-905162fa7fd2

pom.xml
src/changes/changes.xml
src/java/com/healthmarketscience/jackcess/Database.java
src/java/com/healthmarketscience/jackcess/IndexCodes.java
src/java/com/healthmarketscience/jackcess/JetFormat.java
src/site/fml/faq.fml

diff --git a/pom.xml b/pom.xml
index c70d850a3ba3ad0f4b613a22f2fe5a43e3e01923..0913e55eb725bf14a8fb1d6bc46614656b67e38c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       <name>Tim McCune</name>
       <id>javajedi</id>
       <email>javajedi@users.sf.net</email>
-      <organization>Health Market Science, Inc.</organization>
       <timezone>-5</timezone>
     </developer>
     <developer>
       <name>James Ahlborn</name>
       <id>jahlborn</id>
       <email>jahlborn@users.sf.net</email>
-      <organization>Health Market Science, Inc.</organization>
+      <organization>Boomi, Inc.</organization>
       <timezone>-5</timezone>
     </developer>
     <developer>
       <name>Rob Di Marco</name>
       <id>robdimarco</id>
-      <organization>Health Market Science, Inc.</organization>
       <timezone>-5</timezone>
     </developer>
     <developer>
index 3e2c6245cc61debaaa3f84d7adcfa0895d46eac6..4e6b33b724be1febccf17f4dca93d9580d125476 100644 (file)
       </action>
       <action dev="jahlborn" type="update" issue="3065010">
         Add support for plugging implementations of various page
-        encoding/decoding algorithms.
+        encoding/decoding algorithms.  (thanks to Vladimir Berezniker).
+      </action>
+      <action dev="jahlborn" type="update" issue="3101578">
+        Implement some tweaks which allow jackcess to be used on the Android
+        platform. (thanks to Miha Pirnat).
       </action>
     </release>
     <release version="1.2.1" date="2010-08-01">
index f84d79ad7c8b8a27193bdc6c92519b5b2d6c6fff..124fa706d8946cb887be5d6cfa9bcf3cfc4c046c 100644 (file)
@@ -33,10 +33,12 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.Flushable;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.Charset;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -97,8 +99,13 @@ public class Database
       but leaves more chance of a useable database in the face of failures. */
   public static final boolean DEFAULT_AUTO_SYNC = true;
 
-  /** system property which can be used to make big index support the
-      default. */
+  /** the default value for the resource path used to load classpath
+      resources. */
+  public static final String DEFAULT_RESOURCE_PATH = 
+    "com/healthmarketscience/jackcess/";
+
+  /** (boolean) system property which can be used to disable the default big
+      index support. */
   public static final String USE_BIG_INDEX_PROPERTY =
     "com.healthmarketscience.jackcess.bigIndex";
 
@@ -112,6 +119,18 @@ public class Database
   public static final String CHARSET_PROPERTY_PREFIX =
     "com.healthmarketscience.jackcess.charset.";
 
+  /** system property which can be used to set the path from which classpath
+      resources are loaded (must end with a "/" if non-empty).  Default value
+      is {@link #DEFAULT_RESOURCE_PATH} if unspecified. */
+  public static final String RESOURCE_PATH_PROPERTY = 
+    "com.healthmarketscience.jackcess.resourcePath";
+
+  /** (boolean) system property which can be used to indicate that the current
+      vm has a poor nio implementation (specifically for
+      FileChannel.transferFrom) */
+  public static final String BROKEN_NIO_PROPERTY = 
+    "com.healthmarketscience.jackcess.brokenNio";
+
   /** default error handler used if none provided (just rethrows exception) */
   public static final ErrorHandler DEFAULT_ERROR_HANDLER = new ErrorHandler() {
       public Object handleRowError(Column column,
@@ -127,6 +146,14 @@ public class Database
         throw (RuntimeException)error;
       }
     };
+
+  /** the resource path to be used when loading classpath resources */
+  static final String RESOURCE_PATH = 
+    System.getProperty(RESOURCE_PATH_PROPERTY, DEFAULT_RESOURCE_PATH);
+
+  /** whether or not this jvm has "broken" nio support */
+  static final boolean BROKEN_NIO = Boolean.TRUE.toString().equalsIgnoreCase(
+      System.getProperty(BROKEN_NIO_PROPERTY));
   
   /** System catalog always lives on page 2 */
   private static final int PAGE_SYSTEM_CATALOG = 2;
@@ -182,13 +209,16 @@ public class Database
   private static final String CAT_COL_FLAGS = "Flags";
   /** System catalog column name of the properties column */
   private static final String CAT_COL_PROPS = "LvProp";
+
+  /** the maximum size of any of the included "empty db" resources */
+  private static final long MAX_EMPTYDB_SIZE = 320000L;
   
   public static enum FileFormat {
 
     V1997(null, JetFormat.VERSION_3),
-    V2000("com/healthmarketscience/jackcess/empty.mdb", JetFormat.VERSION_4),
-    V2003("com/healthmarketscience/jackcess/empty2003.mdb", JetFormat.VERSION_4),
-    V2007("com/healthmarketscience/jackcess/empty2007.accdb", JetFormat.VERSION_5, ".accdb"),
+    V2000(RESOURCE_PATH + "empty.mdb", JetFormat.VERSION_4),
+    V2003(RESOURCE_PATH + "empty2003.mdb", JetFormat.VERSION_4),
+    V2007(RESOURCE_PATH + "empty2007.accdb", JetFormat.VERSION_5, ".accdb"),
     MSISAM(null, JetFormat.VERSION_MSISAM, ".mny");
 
     private final String _emptyFile;
@@ -558,9 +588,8 @@ public class Database
 
     FileChannel channel = openChannel(mdbFile, false);
     channel.truncate(0);
-    channel.transferFrom(Channels.newChannel(
-        Thread.currentThread().getContextClassLoader().getResourceAsStream(
-            fileFormat._emptyFile)), 0, Integer.MAX_VALUE);
+    transferFrom(channel, Thread.currentThread().getContextClassLoader()
+                 .getResourceAsStream(fileFormat._emptyFile));
     return new Database(channel, autoSync, fileFormat, charset, timeZone,
                         null);
   }
@@ -1532,6 +1561,28 @@ public class Database
     return format.CHARSET;
   }
   
+  /**
+   * Copies the given InputStream to the given channel using the most
+   * efficient means possible.
+   */
+  private static void transferFrom(FileChannel channel, InputStream in)
+    throws IOException
+  {
+    ReadableByteChannel readChannel = Channels.newChannel(in);
+    if(!BROKEN_NIO) {
+      // sane implementation
+      channel.transferFrom(readChannel, 0, MAX_EMPTYDB_SIZE);    
+    } else {
+      // do things the hard way for broken vms
+      ByteBuffer bb = ByteBuffer.allocate(8096);
+      while(readChannel.read(bb) >= 0) {
+        bb.flip();
+        channel.write(bb);
+        bb.clear();
+      }
+    }
+  }
+
   /**
    * Utility class for storing table page number and actual name.
    */
index 15c141d9b248f4564a8f22395658f2b9f2cdd4a3..4197b6e3e06efe149b03c2d655ed8fe1c97c6ca0 100644 (file)
@@ -85,9 +85,9 @@ public class IndexCodes {
 
   // stash the codes in some resource files
   private static final String CODES_FILE = 
-    "com/healthmarketscience/jackcess/index_codes.txt";
+    Database.RESOURCE_PATH + "index_codes.txt";
   private static final String EXT_CODES_FILE = 
-    "com/healthmarketscience/jackcess/index_codes_ext.txt";
+    Database.RESOURCE_PATH + "index_codes_ext.txt";
 
   /**
    * Enum which classifies the types of char encoding strategies used when
index 1453f7dbdd4244236563219945e3e6f5c00dac6e..0922ab0173f031d920d87316d5d11cb82a374174 100644 (file)
@@ -126,6 +126,15 @@ public abstract class JetFormat {
     }
   }
 
+  /** the JetFormat constants for the Jet database version "3" */
+  public static final JetFormat VERSION_3 = new Jet3Format();
+  /** the JetFormat constants for the Jet database version "4" */
+  public static final JetFormat VERSION_4 = new Jet4Format();
+  /** the JetFormat constants for the MSISAM database */
+  public static final JetFormat VERSION_MSISAM = new MSISAMFormat();
+  /** the JetFormat constants for the Jet database version "5" */
+  public static final JetFormat VERSION_5 = new Jet5Format();
+
   //These constants are populated by this class's constructor.  They can't be
   //populated by the subclass's constructor because they are final, and Java
   //doesn't allow this; hence all the abstract defineXXX() methods.
@@ -230,11 +239,6 @@ public abstract class JetFormat {
   
   public final Charset CHARSET;
   
-  public static final JetFormat VERSION_3 = new Jet3Format();
-  public static final JetFormat VERSION_4 = new Jet4Format();
-  public static final JetFormat VERSION_MSISAM = new MSISAMFormat();
-  public static final JetFormat VERSION_5 = new Jet5Format();
-
   /**
    * @param channel the database file.
    * @return The Jet Format represented in the passed-in file
index 1d4cba754e5f830dad130057207b27bcbdc7dcfb..2b4d2d9f4069554244954901f7e0810e3c49435f 100644 (file)
@@ -8,8 +8,8 @@
     <faq id="linux">
       <question>Does this work on Linux/Unix?</question>
       <answer>
-        <p>Yep, Jackcess is pure Java.  It will work on any
-          Java Virtual Machine (1.4+).</p>
+        <p>Yep, Jackcess is pure Java.  It will work on any Java Virtual
+        Machine (1.5+).</p>
       </answer>
     </faq>
 
       </answer>
     </faq>
     
+    <faq id="android">
+      <question>Why do I get an OutOfMemoryError or NullPointerException when
+                creating a new database on the Android platform?</question>
+      <answer>
+        <p>
+          There are 2 issues which need to be dealt with when using Jackcess
+          on the Android platform.  The first is that non-class resources need
+          to be in a special location.  The second is that the nio
+          implementation has some "weaknesses".
+        </p>
+        <p>
+          The following steps will make Jackcess compatible with the Android
+          platform.
+          <ul>
+            <li>Set the system property "com.healthmarketscience.jackcess.brokenNio=true"</li>
+            <li>Set the system property "com.healthmarketscience.jackcess.resourcePath=/res/raw/"</li>
+            <li>Copy the *.txt, *.mdb, and *.accdb files from the
+                "com/healthmarketscience/jackcess/" directory in the Jackcess
+                jar to the "/res/raw" Android application directory.</li>
+            <li>Before executing any Jackcess code, set the current Thread's
+                context classloader,
+                e.g. "Thread.currentThread().setContextClassLoader(Database.class.getClassLoader())".</li>
+          </ul>
+        </p>
+      </answer>
+    </faq>
+    
     <faq id="hms">
       <question>Who is Health Market Science?</question>
       <answer>
           Using proprietary matching and consolidation software,
           HMS scientifically manufactures the most comprehensive
           and accurate healthcare data sets in the market today.
-          <a href="http://www.healthmarketscience.com/company/careers.html">We're hiring!</a>
-          HMS is always looking for talented individuals.
         </p>
       </answer>
     </faq>