// // MDBParser.java // /* LOCI Bio-Formats package for reading and converting biological file formats. Copyright (C) 2005-@year@ Melissa Linkert, Curtis Rueden, Chris Allan, Eric Kjellman and Brian Loranger. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package loci.formats.in; import java.util.*; import loci.formats.*; /** * Utility class for parsing MDB database files. * * <dl><dt><b>Source code:</b></dt> * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/loci/formats/in/MDBParser.java">Trac</a>, * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/loci/formats/in/MDBParser.java">SVN</a></dd></dl> */ public final class MDBParser { // -- Constants -- private static final String NO_MDB_MSG = "The Java port of MDB tools is required to read MDB files. Please " + "obtain mdbtools-java.jar from http://loci.wisc.edu/ome/formats.html"; // -- Static fields -- private static boolean noMDB = false; private static ReflectedUniverse r = createReflectedUniverse(); private static ReflectedUniverse createReflectedUniverse() { r = null; try { r = new ReflectedUniverse(); r.exec("import java.util.Vector"); r.exec("import mdbtools.jdbc2.File"); r.exec("import mdbtools.libmdb.Catalog"); r.exec("import mdbtools.libmdb.Constants"); r.exec("import mdbtools.libmdb.Data"); r.exec("import mdbtools.libmdb.Holder"); r.exec("import mdbtools.libmdb.MdbCatalogEntry"); r.exec("import mdbtools.libmdb.MdbColumn"); r.exec("import mdbtools.libmdb.MdbHandle"); r.exec("import mdbtools.libmdb.MdbTableDef"); r.exec("import mdbtools.libmdb.Table"); r.exec("import mdbtools.libmdb.file"); r.exec("import mdbtools.libmdb.mem"); } catch (Throwable t) { noMDB = true; if (FormatHandler.debug) LogTools.trace(t); } return r; } // -- Constructor -- private MDBParser() { } // -- Utility methods -- /** Parses table structure for a specified MDB file. */ public static void parseDatabase(String filename, Hashtable h) throws FormatException { if (noMDB) throw new FormatException(NO_MDB_MSG); try { // initialize r.setVar("twoFiveSix", 256); r.exec("boundValues = new Vector()"); r.setVar("delimiter", ","); r.exec("mem.mdb_init()"); // print out all data r.setVar("filename", filename); r.exec("dbfile = new File(filename)"); r.exec("mdb = file.mdb_open(dbfile)"); r.exec("Catalog.mdb_read_catalog(mdb, Constants.MDB_TABLE)"); int num = ((Integer) r.getVar("mdb.num_catalog")).intValue(); for (int i=0; i<num; i++) { r.setVar("c", (List) r.getVar("mdb.catalog")); r.setVar("i", i); r.exec("entry = c.get(i)"); r.setVar("objType", ((Integer) r.getVar("entry.object_type")).intValue()); r.setVar("objName", (String) r.getVar("entry.object_name")); int objType = ((Integer) r.getVar("objType")).intValue(); int tableType = ((Integer) r.getVar("Constants.MDB_TABLE")).intValue(); boolean isTable = objType == tableType; String objName = (String) r.getVar("objName"); if (isTable && !objName.startsWith("MSys")) { r.exec("table = Table.mdb_read_table(entry)"); try { r.exec("Table.mdb_read_columns(table)"); } catch (ReflectException e) { break; } r.exec("Data.mdb_rewind_table(table)"); r.setVar("numCols", ((Integer) r.getVar("table.num_cols")).intValue()); int numCols = ((Integer) r.getVar("numCols")).intValue(); for (int j=0; j<numCols; j++) { r.setVar("j", j); r.exec("blah = new Holder()"); r.setVar("l", j + 1); r.exec("Data.mdb_bind_column(table, l, blah)"); r.exec("boundValues.add(blah)"); } StringBuffer[] sbs = new StringBuffer[numCols]; for (int j=0; j<sbs.length; j++) sbs[j] = new StringBuffer(); boolean moreRows = true; try { r.exec("moreRows = Data.mdb_fetch_row(table)"); moreRows = ((Boolean) r.getVar("moreRows")).booleanValue(); } catch (ReflectException e) { moreRows = false; } while (moreRows) { for (int j=0; j<numCols; j++) { r.setVar("j", j); r.setVar("columns", (List) r.getVar("table.columns")); r.exec("col = columns.get(j)"); if (sbs[j].length() > 0) sbs[j].append(","); r.exec("blah = boundValues.get(j)"); sbs[j].append((String) r.getVar("blah.s")); } try { r.exec("moreRows = Data.mdb_fetch_row(table)"); moreRows = ((Boolean) r.getVar("moreRows")).booleanValue(); } catch (ReflectException e) { moreRows = false; } } // place column of data in the hashtable // key is table name + column name, value is each value in the // column, separated by commas for (int j=0; j<sbs.length; j++) { r.setVar("j", j); r.setVar("columns", (List) r.getVar("table.columns")); r.exec("col = columns.get(j)"); h.put(objName + " - " + (String) r.getVar("col.name"), sbs[j].toString()); } } } } catch (ReflectException exc) { LogTools.trace(exc); } } }