From abaa492d2a54f99d800a9a8cee2122edaad49b73 Mon Sep 17 00:00:00 2001 From: hns Date: Fri, 18 Mar 2005 03:13:12 +0000 Subject: [PATCH] Move XmlDatabase to helma.objectmodel.dom package. Move the IDGenerator into XmlIDGenerator in the same package. Make helma.objectmodel.db.IDGenerator an interface that can be used to plug id generators into NodeManager. --- src/helma/objectmodel/db/IDGenerator.java | 80 +++-------- src/helma/objectmodel/db/NodeManager.java | 33 ++++- .../objectmodel/db/WrappedNodeManager.java | 14 +- .../objectmodel/{db => dom}/XmlDatabase.java | 28 ++-- src/helma/objectmodel/dom/XmlIDGenerator.java | 126 ++++++++++++++++++ 5 files changed, 196 insertions(+), 85 deletions(-) rename src/helma/objectmodel/{db => dom}/XmlDatabase.java (96%) create mode 100644 src/helma/objectmodel/dom/XmlIDGenerator.java diff --git a/src/helma/objectmodel/db/IDGenerator.java b/src/helma/objectmodel/db/IDGenerator.java index 68fd7006..e7264401 100644 --- a/src/helma/objectmodel/db/IDGenerator.java +++ b/src/helma/objectmodel/db/IDGenerator.java @@ -16,69 +16,33 @@ package helma.objectmodel.db; -import java.io.Serializable; +import helma.framework.core.Application; + /** - * An object that generates IDs (Strings) that are unique across the whole system. - * It does this keeping a simple long value which is incremented for each new ID. - * This is the key generation for nodes stored in the internal database, but it can - * also be used for relational nodes if no other mechanism is available. (Sequences - * in Oracle are supported, while auto-IDs are not, since the HOP has to know - * the keys of new objects.) + * An interface for objects that generate IDs (Strings) that are + * unique for a specific type. */ -public final class IDGenerator implements Serializable { - static final long serialVersionUID = 753408631669789263L; - private long counter; - transient volatile boolean dirty; - - /** - * Builds a new IDGenerator starting with 0. - */ - public IDGenerator() { - this.counter = 0L; - dirty = false; - } - - /** - * Builds a new IDGenerator starting with value. - */ - public IDGenerator(long value) { - this.counter = value; - dirty = false; - } - - /** - * Delivers a unique id and increases counter by 1. - */ - public synchronized String newID() { - counter += 1L; - dirty = true; - - return Long.toString(counter); - } - - /** - * Set the counter to a new value - */ - protected synchronized void setValue(long value) { - counter = value; - dirty = true; - } - - /** - * Get the current counter value - */ - public long getValue() { - return counter; - } +public interface IDGenerator { /** + * Init the ID generator for the given application. * - * - * @return ... + * @param app */ - public String toString() { - return "helma.objectmodel.db.IDGenerator[counter=" + counter + ",dirty=" + dirty + - "]"; - } + public void init(Application app); + + /** + * Shut down the ID generator. + */ + public void shutdown(); + + /** + * Generate a new ID for a specific type. + * + * @param dbmap + * @return + */ + public String generateID(DbMapping dbmap); + } diff --git a/src/helma/objectmodel/db/NodeManager.java b/src/helma/objectmodel/db/NodeManager.java index 0962737f..e5c655c5 100644 --- a/src/helma/objectmodel/db/NodeManager.java +++ b/src/helma/objectmodel/db/NodeManager.java @@ -18,6 +18,7 @@ package helma.objectmodel.db; import helma.framework.core.Application; import helma.objectmodel.*; +import helma.objectmodel.dom.XmlDatabase; import java.io.IOException; import java.io.Reader; @@ -40,6 +41,7 @@ public final class NodeManager { protected Application app; private ObjectCache cache; protected IDatabase db; + protected IDGenerator idgen; private boolean logSql; private Log sqlLog = null; protected boolean logReplication; @@ -69,6 +71,13 @@ public final class NodeManager { cache = (ObjectCache) Class.forName(cacheImpl).newInstance(); cache.init(app); + String idgenImpl = props.getProperty("idGeneratorImpl"); + + if (idgenImpl != null) { + idgen = (IDGenerator) Class.forName(idgenImpl).newInstance(); + idgen.init(app); + } + logSql = "true".equalsIgnoreCase(props.getProperty("logsql")); logReplication = "true".equalsIgnoreCase(props.getProperty("logReplication")); @@ -115,6 +124,10 @@ public final class NodeManager { cache.shutdown(); cache = null; } + + if (idgen != null) { + idgen.shutdown(); + } } /** @@ -750,9 +763,27 @@ public final class NodeManager { } /** - * Generate a new ID from an Oracle sequence. + * Generate a new ID for a given type. */ public String generateID(DbMapping map) throws Exception { + if (idgen != null) { + // use our custom IDGenerator + return idgen.generateID(map); + } else if ((map == null) || !map.isRelational() || + "[hop]".equalsIgnoreCase(map.getIDgen())) { + // use embedded db id generator + return db.nextID(); + } else if ((map.getIDgen() == null) || + "[max]".equalsIgnoreCase(map.getIDgen())) { + // use select max as id generator + return generateMaxID(map); + } else { + // use db sequence as id generator + return generateSequenceID(map); + } + } + + public String generateSequenceID(DbMapping map) throws Exception { // Transactor tx = (Transactor) Thread.currentThread (); // tx.timer.beginEvent ("generateID "+map); Statement stmt = null; diff --git a/src/helma/objectmodel/db/WrappedNodeManager.java b/src/helma/objectmodel/db/WrappedNodeManager.java index 2b0a1ad9..a710fb85 100644 --- a/src/helma/objectmodel/db/WrappedNodeManager.java +++ b/src/helma/objectmodel/db/WrappedNodeManager.java @@ -246,19 +246,7 @@ public final class WrappedNodeManager { */ public String generateID(DbMapping map) { try { - if ((map == null) || !map.isRelational() || - "[hop]".equalsIgnoreCase(map.getIDgen())) { - // use embedded db id generator - return nmgr.db.nextID(); - } else if ((map.getIDgen() == null) || - "[max]".equalsIgnoreCase(map.getIDgen())) { - // use select max as id generator - return nmgr.generateMaxID(map); - } else { - // use db sequence as id generator - return nmgr.generateID(map); - } - + return nmgr.generateID(map); } catch (Exception x) { if (nmgr.app.debug()) { x.printStackTrace(); diff --git a/src/helma/objectmodel/db/XmlDatabase.java b/src/helma/objectmodel/dom/XmlDatabase.java similarity index 96% rename from src/helma/objectmodel/db/XmlDatabase.java rename to src/helma/objectmodel/dom/XmlDatabase.java index 26d8375d..34c43dd3 100644 --- a/src/helma/objectmodel/db/XmlDatabase.java +++ b/src/helma/objectmodel/dom/XmlDatabase.java @@ -14,18 +14,17 @@ * $Date$ */ -package helma.objectmodel.db; +package helma.objectmodel.dom; import helma.objectmodel.*; -import helma.objectmodel.dom.IDGenParser; +import helma.objectmodel.db.NodeManager; +import helma.objectmodel.db.Node; +import helma.objectmodel.dom.XmlIDGenerator; import helma.objectmodel.dom.XmlDatabaseReader; import helma.objectmodel.dom.XmlWriter; import helma.framework.core.Application; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; /** @@ -36,7 +35,7 @@ public final class XmlDatabase implements IDatabase { protected File dbHomeDir; protected Application app; protected NodeManager nmgr; - protected IDGenerator idgen; + protected XmlIDGenerator idgen; // character encoding to use when writing files. // use standard encoding by default. @@ -91,7 +90,7 @@ public final class XmlDatabase implements IDatabase { } } catch (ObjectNotFoundException notfound) { // will start with idBaseValue+1 - idgen = new IDGenerator(idBaseValue); + idgen = new XmlIDGenerator(idBaseValue); } // check if we need to set the id generator to a base value @@ -99,7 +98,6 @@ public final class XmlDatabase implements IDatabase { try { node = (Node) getNode(txn, "0"); - node.nmgr = nmgr.safe; } catch (ObjectNotFoundException notfound) { node = new Node("root", "0", "Root", nmgr.safe); node.setDbMapping(app.getDbMapping("root")); @@ -110,7 +108,6 @@ public final class XmlDatabase implements IDatabase { try { node = (Node) getNode(txn, "1"); - node.nmgr = nmgr.safe; } catch (ObjectNotFoundException notfound) { node = new Node("users", "1", null, nmgr.safe); node.setDbMapping(app.getDbMapping("__userroot__")); @@ -226,11 +223,11 @@ public final class XmlDatabase implements IDatabase { * @return the id-generator for this database * @throws ObjectNotFoundException */ - public IDGenerator getIDGenerator(ITransaction txn) + public XmlIDGenerator getIDGenerator(ITransaction txn) throws ObjectNotFoundException { File file = new File(dbHomeDir, "idgen.xml"); - this.idgen = IDGenParser.getIDGenerator(file); + this.idgen = XmlIDGenerator.getIDGenerator(file); return idgen; } @@ -245,7 +242,7 @@ public final class XmlDatabase implements IDatabase { throws IOException { File tmp = File.createTempFile("idgen.xml.", ".tmp", dbHomeDir); - IDGenParser.saveIDGenerator(idgen, tmp); + XmlIDGenerator.saveIDGenerator(idgen, tmp); File file = new File(dbHomeDir, "idgen.xml"); if (file.exists() && !file.canWrite()) { @@ -444,5 +441,10 @@ public final class XmlDatabase implements IDatabase { } } + + class IDGenerator { + + } + } diff --git a/src/helma/objectmodel/dom/XmlIDGenerator.java b/src/helma/objectmodel/dom/XmlIDGenerator.java new file mode 100644 index 00000000..6acfd357 --- /dev/null +++ b/src/helma/objectmodel/dom/XmlIDGenerator.java @@ -0,0 +1,126 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + +package helma.objectmodel.dom; + +import helma.objectmodel.ObjectNotFoundException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.*; +import java.util.Date; + +/** + * + */ +public class XmlIDGenerator { + + private long counter; + transient volatile boolean dirty; + + /** + * Builds a new IDGenerator starting with 0. + */ + public XmlIDGenerator() { + this.counter = 0L; + dirty = false; + } + + /** + * Builds a new IDGenerator starting with value. + */ + public XmlIDGenerator(long value) { + this.counter = value; + dirty = false; + } + + /** + * Delivers a unique id and increases counter by 1. + */ + public synchronized String newID() { + counter += 1L; + dirty = true; + + return Long.toString(counter); + } + + /** + * Set the counter to a new value + */ + protected synchronized void setValue(long value) { + counter = value; + dirty = true; + } + + /** + * Get the current counter value + */ + public long getValue() { + return counter; + } + + /** + * Returns a string representation of this IDGenerator + */ + public String toString() { + return "IDGenerator[counter=" + counter + ",dirty=" + dirty + "]"; + } + + /** + * Read an IDGenerator from file + * + * @param file + * @return + * @throws ObjectNotFoundException + */ + public static XmlIDGenerator getIDGenerator(File file) + throws ObjectNotFoundException { + if (!file.exists()) { + throw new ObjectNotFoundException("IDGenerator not found in idgen.xml"); + } + + try { + Document document = XmlUtil.parse(new FileInputStream(file)); + org.w3c.dom.Element tmp = (Element) document.getDocumentElement() + .getElementsByTagName("counter") + .item(0); + + return new XmlIDGenerator(Long.parseLong(XmlUtil.getTextContent(tmp))); + } catch (Exception e) { + throw new ObjectNotFoundException(e.toString()); + } + } + + /** + * Save an id generator to a file. + * + * @param idgen + * @param file + * @throws IOException + */ + public static void saveIDGenerator(XmlIDGenerator idgen, File file) + throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file)); + + out.write("\n"); + out.write("\n"); + out.write("\n"); + out.write("\n"); + out.write(" " + idgen.getValue() + "\n"); + out.write("\n"); + out.close(); + } +}