kevinross 2003/07/14 12:07:16
Modified: java/src/org/apache/xindice/util Configurable.java
XindiceRuntimeException.java XindiceException.java
ConfigurationException.java
java/src/org/apache/xindice/core DBObject.java
MetaSystemCollection.java DBObserver.java
FaultCodes.java DocumentCache.java DBException.java
Container.java Database.java Collection.java
SystemCollection.java CollectionManager.java
java/src/org/apache/xindice/client/xmldb/embed
DatabaseImpl.java
Log:
refactoring for javabeans coding conventions including:
-naming
-accessibility of members.
-javadoc comments
Revision Changes Path
1.3 +15 -17
xml-xindice/java/src/org/apache/xindice/util/Configurable.java
Index: Configurable.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/Configurable.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Configurable.java 31 Oct 2002 07:01:45 -0000 1.2
+++ Configurable.java 14 Jul 2003 19:07:14 -0000 1.3
@@ -59,8 +59,6 @@
* $Id$
*/
-
-
/**
* Configurable is a simple interface used to pass configuration information
* to an object. The implementing object is ultimately responsible for
@@ -77,19 +75,19 @@
*/
public interface Configurable {
- /**
- * setConfig sets the configuration information for the Configurable
- * object instance.
- *
- * @param config The configuration Node
- */
- void setConfig(Configuration config) throws XindiceException;
+ /**
+ * setConfig sets the configuration information for the Configurable
+ * object instance.
+ *
+ * @param config The configuration Node
+ */
+ void setConfig(Configuration config) throws XindiceException;
- /**
- * getConfig retrieves the configuration information for the
- * Configurable object instance.
- *
- * @return The configuration Node
- */
- Configuration getConfig();
+ /**
+ * getConfig retrieves the configuration information for the
+ * Configurable object instance.
+ *
+ * @return The configuration Node
+ */
+ Configuration getConfig();
}
1.2 +6 -1
xml-xindice/java/src/org/apache/xindice/util/XindiceRuntimeException.java
Index: XindiceRuntimeException.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/XindiceRuntimeException.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XindiceRuntimeException.java 14 Jul 2003 18:28:45 -0000 1.1
+++ XindiceRuntimeException.java 14 Jul 2003 19:07:14 -0000 1.2
@@ -74,6 +74,11 @@
super(message);
}
+ public XindiceRuntimeException(Throwable cause) {
+ super();
+ this.cause = cause;
+ }
+
public XindiceRuntimeException(String message, Throwable cause) {
super(message);
this.cause = cause;
1.6 +7 -2
xml-xindice/java/src/org/apache/xindice/util/XindiceException.java
Index: XindiceException.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/XindiceException.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- XindiceException.java 14 Jul 2003 18:28:45 -0000 1.5
+++ XindiceException.java 14 Jul 2003 19:07:14 -0000 1.6
@@ -74,7 +74,12 @@
public XindiceException(String message) {
super(message);
}
-
+
+ public XindiceException(Throwable cause) {
+ super();
+ this.cause = cause;
+ }
+
public XindiceException(String message, Throwable cause) {
super(message);
this.cause = cause;
1.2 +4 -0
xml-xindice/java/src/org/apache/xindice/util/ConfigurationException.java
Index: ConfigurationException.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/util/ConfigurationException.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ConfigurationException.java 14 Jul 2003 18:28:45 -0000 1.1
+++ ConfigurationException.java 14 Jul 2003 19:07:14 -0000 1.2
@@ -26,4 +26,8 @@
public ConfigurationException(String message, Throwable cause) {
super(message, cause);
}
+
+ public ConfigurationException(Throwable cause) {
+ super(cause);
+ }
}
1.3 +48 -50
xml-xindice/java/src/org/apache/xindice/core/DBObject.java
Index: DBObject.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBObject.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DBObject.java 31 Oct 2002 06:59:56 -0000 1.2
+++ DBObject.java 14 Jul 2003 19:07:14 -0000 1.3
@@ -59,8 +59,6 @@
* $Id$
*/
-
-
/**
* DBObject is the interface implemented by all Xindice database objects.
* DBObjects are typically objects that can be managed using XML
@@ -71,51 +69,51 @@
*/
public interface DBObject {
- /**
- * create creates a new DBObject and any associated resources for the new
- * DBObject, such as disk files, etc.
- *
- * @return Whether or not the DBObject was created
- */
- boolean create() throws DBException;
-
- /**
- * open opens the DBObject
- *
- * @return Whether or not the DBObject was opened
- */
- boolean open() throws DBException;
-
- /**
- * isOpened returns whether or not the DBObject is opened for business.
- *
- * @return The open status of the DBObject
- */
- boolean isOpened() throws DBException;
-
- /**
- * exists returns whether or not a physical representation of this
- * DBObject actually exists. In the case of a HashFiler, this would
- * check for the file, and in the case of an FTPFiler, it might
- * perform a connection check.
- *
- * @return Whether or not the physical resource exists
- */
- boolean exists() throws DBException;
-
- /**
- * drop instructs the DBObjectimplementation to remove itself from
- * existence. The DBObject's parent is responsible for removing any
- * references to the DBObject in its own context.
- *
- * @return Whether or not the DBObject was dropped
- */
- boolean drop() throws DBException;
-
- /**
- * close closes the DBObject
- *
- * @return Whether or not the DBObject was closed
- */
- boolean close() throws DBException;
+ /**
+ * create creates a new DBObject and any associated resources for the new
+ * DBObject, such as disk files, etc.
+ *
+ * @return Whether or not the DBObject was created
+ */
+ boolean create() throws DBException;
+
+ /**
+ * open opens the DBObject
+ *
+ * @return Whether or not the DBObject was opened
+ */
+ boolean open() throws DBException;
+
+ /**
+ * isOpened returns whether or not the DBObject is opened for business.
+ *
+ * @return The open status of the DBObject
+ */
+ boolean isOpened() throws DBException;
+
+ /**
+ * exists returns whether or not a physical representation of this
+ * DBObject actually exists. In the case of a HashFiler, this would
+ * check for the file, and in the case of an FTPFiler, it might
+ * perform a connection check.
+ *
+ * @return Whether or not the physical resource exists
+ */
+ boolean exists() throws DBException;
+
+ /**
+ * drop instructs the DBObjectimplementation to remove itself from
+ * existence. The DBObject's parent is responsible for removing any
+ * references to the DBObject in its own context.
+ *
+ * @return Whether or not the DBObject was dropped
+ */
+ boolean drop() throws DBException;
+
+ /**
+ * close closes the DBObject
+ *
+ * @return Whether or not the DBObject was closed
+ */
+ boolean close() throws DBException;
}
1.3 +61 -96
xml-xindice/java/src/org/apache/xindice/core/MetaSystemCollection.java
Index: MetaSystemCollection.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/MetaSystemCollection.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MetaSystemCollection.java 27 Mar 2003 07:05:32 -0000 1.2
+++ MetaSystemCollection.java 14 Jul 2003 19:07:14 -0000 1.3
@@ -59,7 +59,6 @@
* $Id$
*/
-
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
@@ -69,52 +68,48 @@
import org.apache.xindice.xml.dom.DOMParser;
import org.w3c.dom.Document;
-
-
/**
* MetaSystemCollection represents the Meta System Collection. Beyond
* standard Collection operations, this class will provide facilities
* for Meta data management.
*/
-public final class MetaSystemCollection extends Collection
-{
- public static final String METACOL = "meta";
- public static final String METAS = "Metas";
+public final class MetaSystemCollection extends Collection {
+ public static final String METACOL = "meta";
+ public static final String METAS = "Metas";
public static final String COLLECTION_META_DATA = "_META_DATA_";
private String dbCanonicalName;
private String metaCanonicalName;
- private static Log log = LogFactory.getLog("org.apache.xindice.core");
+ private static Log log = LogFactory.getLog("org.apache.xindice.core");
- public MetaSystemCollection(Database db)
- {
+ public MetaSystemCollection(Database db) {
super(db);
}
- public void init() throws DBException
- {
+ public void init() throws DBException {
// Bootstrap the System Collection
- String MetaCol =
- "<collection name=\""+METACOL+"\">"
- // Meta System Collections
- + " <collections>"
- // Meta Collections
- + " <collection name=\""+METAS+"\" compressed=\"true\">"
- + " <filer class=\"org.apache.xindice.core.filer.BTreeFiler\"
/>"
- + " </collection>"
-
- + " </collections>"
- + "</collection>";
+ String MetaCol =
+ "<collection name=\"" + METACOL + "\">"
+ // Meta System Collections
+ +" <collections>"
+ // Meta Collections
+ +" <collection name=\""
+ + METAS
+ + "\" compressed=\"true\">"
+ + " <filer
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
+ + " </collection>"
+ + " </collections>"
+ + "</collection>";
try {
Document metaDoc = DOMParser.toDocument(MetaCol);
Configuration metaCfg = new Configuration(metaDoc, false);
setConfig(metaCfg);
}
- catch ( Exception e ) {
- if (log.isFatalEnabled()) {
- log.fatal("FATAL ERROR: Generating System Collection
'"+METACOL+"'", e);
+ catch (Exception e) {
+ if (log.isFatalEnabled()) {
+ log.fatal("FATAL ERROR: Generating System Collection '" +
METACOL + "'", e);
}
System.exit(1);
}
@@ -127,58 +122,47 @@
/**
* Returns the corresponding Meta Collection for the given
* collection, optionally creating the hierarchy
- *
- * @param collection the collection whose meta you want
- * @param create whether or not to create the meta if its missing
- * @return collection the meta collection for the requested collection
+ *
+ * @param collection the collection whose meta you want
+ * @param create whether or not to create the meta if its missing
+ * @return collection the meta collection for the requested collection
*/
- public Collection getMetaCollection(Collection collection,
- boolean create)
- throws DBException
- {
+ public Collection getMetaCollection(Collection collection, boolean
create) throws DBException {
String path = collection.getCanonicalName();
// different database
- if( !path.startsWith(dbCanonicalName) )
+ if (!path.startsWith(dbCanonicalName))
return null;
// this is a meta collection
- if( path.startsWith(metaCanonicalName) )
+ if (path.startsWith(metaCanonicalName))
return null;
Collection current = getCollection(METAS);
- StringTokenizer st = new StringTokenizer(
- path.substring(dbCanonicalName.length()), "/");
+ StringTokenizer st = new
StringTokenizer(path.substring(dbCanonicalName.length()), "/");
- while( current != null && st.hasMoreTokens() )
- {
+ while (current != null && st.hasMoreTokens()) {
String segment = st.nextToken().trim();
- if ( segment.length() == 0 )
- continue;
+ if (segment.length() == 0)
+ continue;
Collection childcol = current.getCollection(segment);
- if( null == childcol )
- {
- if( !create )
+ if (null == childcol) {
+ if (!create)
return null;
String cfgText =
- "<collection name=\""+segment+"\" compressed=\"true\">" +
- " <filer class=\"org.apache.xindice.core.filer.BTreeFiler\"
/>" +
- "</collection>";
+ "<collection name=\"" + segment + "\"
compressed=\"true\">" + " <filer
class=\"org.apache.xindice.core.filer.BTreeFiler\" />" + "</collection>";
- try
- {
+ try {
Document cfgDoc = DOMParser.toDocument(cfgText);
Configuration cfg = new Configuration(cfgDoc, false);
childcol = current.createCollection(segment, cfg);
}
- catch( DBException de )
- {
+ catch (DBException de) {
throw de;
}
- catch( Exception e )
- {
+ catch (Exception e) {
throw new DBException(FaultCodes.getFaultCode(e));
}
}
@@ -194,16 +178,13 @@
*
* @param collection The Collection whose meta is required
*/
- public void dropCollectionMeta(Collection collection)
- throws DBException
- {
+ public void dropCollectionMeta(Collection collection) throws DBException
{
Collection mcol = getMetaCollection(collection, false);
- if( null != mcol )
- {
+ if (null != mcol) {
try {
mcol.drop();
}
- catch( DBException e ) {
+ catch (DBException e) {
// fail silently
}
}
@@ -217,18 +198,15 @@
* @param collection The Collection whose meta is required
* @return The requested MetaData
*/
- public MetaData getCollectionMeta(Collection collection)
- throws DBException
- {
+ public MetaData getCollectionMeta(Collection collection) throws
DBException {
Collection mcol = getMetaCollection(collection, true);
- if( null != mcol )
- {
- MetaData meta = (MetaData)mcol.getObject(COLLECTION_META_DATA);
- if ( meta == null )
+ if (null != mcol) {
+ MetaData meta = (MetaData) mcol.getObject(COLLECTION_META_DATA);
+ if (meta == null)
meta = new MetaData();
- if( meta.getType() == MetaData.UNKNOWN )
+ if (meta.getType() == MetaData.UNKNOWN)
meta.setType(MetaData.COLLECTION);
meta.setOwner(collection.getCanonicalName());
meta.setDirty(false);
@@ -243,15 +221,12 @@
* @param collection The Collection that owns the MetaData
* @param meta The MetaData
*/
- public void setCollectionMeta(Collection collection, MetaData meta)
- throws DBException
- {
- if( null == meta )
+ public void setCollectionMeta(Collection collection, MetaData meta)
throws DBException {
+ if (null == meta)
return;
Collection mcol = getMetaCollection(collection, true);
- if( null != mcol )
- {
+ if (null != mcol) {
mcol.setObject(COLLECTION_META_DATA, meta);
meta.setDirty(false);
}
@@ -264,16 +239,13 @@
* @param collection The Collection whose meta is required
* @param id the Document id
*/
- public void dropDocumentMeta(Collection collection, String id)
- throws DBException
- {
+ public void dropDocumentMeta(Collection collection, String id) throws
DBException {
Collection mcol = getMetaCollection(collection, false);
- if( null != mcol )
- {
+ if (null != mcol) {
try {
mcol.remove(id);
}
- catch( DBException e ) {
+ catch (DBException e) {
// fail silently
}
}
@@ -287,17 +259,14 @@
* @param id the ID
* @return The requested MetaData
*/
- public MetaData getDocumentMeta(Collection collection, String id)
- throws DBException
- {
+ public MetaData getDocumentMeta(Collection collection, String id) throws
DBException {
Collection mcol = getMetaCollection(collection, true);
- if( null != mcol )
- {
- MetaData meta = (MetaData)mcol.getObject(id);
- if ( meta == null )
+ if (null != mcol) {
+ MetaData meta = (MetaData) mcol.getObject(id);
+ if (meta == null)
meta = new MetaData();
- if( meta.getType() == MetaData.UNKNOWN )
+ if (meta.getType() == MetaData.UNKNOWN)
meta.setType(MetaData.DOCUMENT);
meta.setOwner(collection.getCanonicalName() + "/" + id);
meta.setDirty(false);
@@ -313,18 +282,14 @@
* @param id
* @param meta The MetaData
*/
- public void setDocumentMeta(Collection collection, String id, MetaData
meta)
- throws DBException
- {
- if( null == meta )
+ public void setDocumentMeta(Collection collection, String id, MetaData
meta) throws DBException {
+ if (null == meta)
return;
Collection mcol = getMetaCollection(collection, true);
- if( null != mcol )
- {
+ if (null != mcol) {
mcol.setObject(id, meta);
meta.setDirty(false);
}
}
}
-
1.4 +38 -63
xml-xindice/java/src/org/apache/xindice/core/DBObserver.java
Index: DBObserver.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBObserver.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DBObserver.java 14 Jul 2003 17:23:56 -0000 1.3
+++ DBObserver.java 14 Jul 2003 19:07:14 -0000 1.4
@@ -1,114 +1,89 @@
package org.apache.xindice.core;
+import java.util.Map;
+
import org.apache.xindice.core.data.Key;
import org.apache.xindice.core.data.Record;
import org.apache.xindice.util.Configuration;
-
-import org.w3c.dom.*;
-
-import java.util.Map;
+import org.w3c.dom.Document;
/**
* Observer for Xindice DB activities
*/
-public abstract class DBObserver
-{
- private static final DBObserver NOOP = new DBObserver()
- {
- public void setDatabaseConfig(
- Database db, Map collections, Configuration cfg ) {}
+public abstract class DBObserver {
+
+ private static final DBObserver NOOP = new DBObserver() {
+ public void setDatabaseConfig(Database db, Map collections,
Configuration cfg) {}
- public void setCollectionConfig(
- Collection col, Configuration cfg ) {}
+ public void setCollectionConfig(Collection col, Configuration cfg) {}
- public void flushDatabaseConfig(
- Database db, Configuration cfg ) {}
-
- public void dropCollection( Collection col )
- throws DBException {}
+ public void flushDatabaseConfig(Database db, Configuration cfg) {}
+
+ public void dropCollection(Collection col) throws DBException {}
+
+ public void createCollection(Collection col) throws DBException {}
- public void createCollection( Collection col )
- throws DBException {}
+ public void putDocument(Collection col, Key key, Document document,
boolean create) throws DBException {}
- public void putDocument(
- Collection col, Key key, Document document, boolean create )
- throws DBException {}
-
- public void loadDocument(
- Collection col, Record record, Document document )
- throws DBException {}
-
- public void dropDocument( Collection col, Key key )
- throws DBException {}
+ public void loadDocument(Collection col, Record record, Document
document) throws DBException {}
+
+ public void dropDocument(Collection col, Key key) throws DBException
{}
};
private static DBObserver instance = NOOP;
/**
* Sets the default observer instance
- */
- public static void setInstance( DBObserver obs )
- {
- instance = (null == obs) ? NOOP : obs;
+ */
+ public static void setInstance(DBObserver obs) {
+ instance = (null == obs) ? NOOP : obs;
}
/**
* Returns the observer instance, must be non-null
- */
- public static DBObserver getInstance()
- {
- return instance;
+ */
+ public static DBObserver getInstance() {
+ return instance;
}
-
+
/**
* Called after Database.setConfig()
- */
- public abstract void setDatabaseConfig(
- Database db, Map collections, Configuration cfg );
+ */
+ public abstract void setDatabaseConfig(Database db, Map collections,
Configuration cfg);
/**
* Called after Collection.setConfig()
- */
- public abstract void setCollectionConfig(
- Collection col, Configuration cfg );
+ */
+ public abstract void setCollectionConfig(Collection col, Configuration
cfg);
/**
* Called after Database.flushConfig()
*/
- public abstract void flushDatabaseConfig(
- Database db, Configuration cfg );
-
+ public abstract void flushDatabaseConfig(Database db, Configuration cfg);
+
/**
* Called before Collection.drop()
*/
- public abstract void dropCollection( Collection col )
- throws DBException;
+ public abstract void dropCollection(Collection col) throws DBException;
/**
* Called after Collection.create()
*/
- public abstract void createCollection( Collection col )
- throws DBException;
+ public abstract void createCollection(Collection col) throws DBException;
/**
* Called after Collection.putDocument()
- */
- public abstract void putDocument(
- Collection col, Key key, Document document, boolean create )
- throws DBException;
+ */
+ public abstract void putDocument(Collection col, Key key, Document
document, boolean create) throws DBException;
/**
* Called after Collection.getDocument()
- */
- public abstract void loadDocument(
- Collection col, Record record, Document document )
- throws DBException;
+ */
+ public abstract void loadDocument(Collection col, Record record,
Document document) throws DBException;
/**
* Called before Collection.remove(key)
*/
- public abstract void dropDocument( Collection col, Key key )
- throws DBException;
-
-}
+ public abstract void dropDocument(Collection col, Key key) throws
DBException;
+}
1.11 +253 -253
xml-xindice/java/src/org/apache/xindice/core/FaultCodes.java
Index: FaultCodes.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/FaultCodes.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- FaultCodes.java 11 Jun 2003 03:56:47 -0000 1.10
+++ FaultCodes.java 14 Jul 2003 19:07:14 -0000 1.11
@@ -71,256 +71,256 @@
*/
public abstract class FaultCodes {
- private static final Map faultMessages = new HashMap();
- public static final int GEN = (int) (0l);
- public static final int OBJ = (int) (100l);
- public static final int COL = (int) (200l);
- public static final int IDX = (int) (300l);
- public static final int TRX = (int) (400l);
- public static final int DBE = (int) (500l);
- public static final int QRY = (int) (600l);
- public static final int SEC = (int) (700l);
- public static final int URI = (int) (800l);
- public static final int JAVA = (int) (2000l);
- public static final int GEN_UNKNOWN = (int) (0l);
- public static final int GEN_GENERAL_ERROR = (int) (40l);
- public static final int GEN_CRITICAL_ERROR = (int) (70l);
- public static final int GEN_FATAL_ERROR = (int) (90l);
- public static final int COL_COLLECTION_NOT_FOUND = (int) (200l);
- public static final int COL_DOCUMENT_NOT_FOUND = (int) (201l);
- public static final int COL_DUPLICATE_COLLECTION = (int) (240l);
- public static final int COL_NULL_RESULT = (int) (241l);
- public static final int COL_NO_FILER = (int) (242l);
- public static final int COL_NO_INDEXMANAGER = (int) (242l);
- public static final int COL_DOCUMENT_MALFORMED = (int) (243l);
- public static final int COL_CANNOT_STORE = (int) (244l);
- public static final int COL_CANNOT_RETRIEVE = (int) (245l);
- public static final int COL_COLLECTION_READ_ONLY = (int) (246l);
- public static final int COL_COLLECTION_CLOSED = (int) (247l);
- public static final int COL_CANNOT_CREATE = (int) (270l);
- public static final int COL_CANNOT_DROP = (int) (271l);
- public static final int COL_INVALID_RESULT = (int) (277l);
- public static final int IDX_VALUE_NOT_FOUND = (int) (300l);
- public static final int IDX_INDEX_NOT_FOUND = (int) (301l);
- public static final int IDX_MATCHES_NOT_FOUND = (int) (340l);
- public static final int IDX_DUPLICATE_INDEX = (int) (341l);
- public static final int IDX_NOT_SUPPORTED = (int) (370l);
- public static final int IDX_STYLE_NOT_FOUND = (int) (371l);
- public static final int IDX_CORRUPTED = (int) (372l);
- public static final int IDX_CANNOT_CREATE = (int) (373l);
- public static final int TRX_DOC_LOCKED = (int) (400l);
- public static final int TRX_NO_CONTEXT = (int) (440l);
- public static final int TRX_NOT_ACTIVE = (int) (441l);
- public static final int TRX_NOT_SUPPORTED = (int) (470l);
- public static final int DBE_NO_PARENT = (int) (500l);
- public static final int DBE_CANNOT_DROP = (int) (570l);
- public static final int DBE_CANNOT_CREATE = (int) (571l);
- public static final int QRY_NULL_RESULT = (int) (600l);
- public static final int QRY_COMPILATION_ERROR = (int) (640l);
- public static final int QRY_PROCESSING_ERROR = (int) (641l);
- public static final int QRY_NOT_SUPPORTED = (int) (670l);
- public static final int QRY_STYLE_NOT_FOUND = (int) (671l);
- public static final int SEC_INVALID_USER = (int) (770l);
- public static final int SEC_INVALID_GROUP = (int) (771l);
- public static final int SEC_INVALID_ACCESS = (int) (772l);
- public static final int SEC_INVALID_CREDENTIALS = (int) (773l);
- public static final int URI_EMPTY = (int) (800l);
- public static final int URI_NULL = (int) (801l);
- public static final int URI_PARSE_ERROR = (int) (820l);
- public static final int JAVA_RUNTIME_ERROR = (int) (2070l);
-
- private FaultCodes() {}
-
- static {
- // General errors 0 series
- putCodeMessage(GEN_UNKNOWN, "Unknown");
- putCodeMessage(GEN_GENERAL_ERROR, "General Error");
- putCodeMessage(GEN_CRITICAL_ERROR, "Critical Error");
- putCodeMessage(GEN_FATAL_ERROR, "Fatal Error");
-
- // Collection-related errors 200 series
- putCodeMessage(COL_COLLECTION_NOT_FOUND, "Collection Not
Found");
- putCodeMessage(COL_DOCUMENT_NOT_FOUND, "Collection Document Not
Found");
- putCodeMessage(COL_DUPLICATE_COLLECTION, "Collection
Duplicated");
- putCodeMessage(COL_NULL_RESULT, "Collection Null Result");
- putCodeMessage(COL_NO_FILER, "Collection No Filer");
- putCodeMessage(COL_NO_INDEXMANAGER, "Collection No
IndexManager");
- putCodeMessage(COL_DOCUMENT_MALFORMED, "Collection Document
Malformed");
- putCodeMessage(COL_CANNOT_STORE, "Collection Cannot Store");
- putCodeMessage(COL_CANNOT_RETRIEVE, "Collection Cannot
Retrieve");
- putCodeMessage(COL_COLLECTION_READ_ONLY, "Collection
Read-only");
- putCodeMessage(COL_COLLECTION_CLOSED, "Collection Closed");
- putCodeMessage(COL_CANNOT_CREATE, "Collection Cannot Create");
- putCodeMessage(COL_CANNOT_DROP, "Collection Cannot Drop");
- putCodeMessage(COL_INVALID_RESULT, "Collection Invalid Result");
-
- // Index-related errors 300 series
- putCodeMessage(IDX_VALUE_NOT_FOUND, "Index Value Not Found");
- putCodeMessage(IDX_INDEX_NOT_FOUND, "Index Not Found");
- putCodeMessage(IDX_MATCHES_NOT_FOUND, "Index Matches Not
Found");
- putCodeMessage(IDX_DUPLICATE_INDEX, "Index Duplicate Index");
- putCodeMessage(IDX_NOT_SUPPORTED, "Index Not Supported");
- putCodeMessage(IDX_STYLE_NOT_FOUND, "Index Style Not Found");
- putCodeMessage(IDX_CORRUPTED, "Index Corrupted");
- putCodeMessage(IDX_CANNOT_CREATE, "Index Cannot Create");
-
- // Transaction-related errors 400 series
- putCodeMessage(TRX_DOC_LOCKED, "Transaction Document Locked");
- putCodeMessage(TRX_NO_CONTEXT, "Transaction No Context");
- putCodeMessage(TRX_NOT_ACTIVE, "Transaction Not Active");
- putCodeMessage(TRX_NOT_SUPPORTED, "Transaction Not Supported");
-
- // Database-related errors 500 series
- putCodeMessage(DBE_NO_PARENT, "Database No Parent");
- putCodeMessage(DBE_CANNOT_DROP, "Database Cannot Drop");
- putCodeMessage(DBE_CANNOT_CREATE, "Database Cannot Create");
-
- // Query-related errors 600 series
- putCodeMessage(QRY_NULL_RESULT, "Query Null Result");
- putCodeMessage(QRY_COMPILATION_ERROR, "Query Compilation
Error");
- putCodeMessage(QRY_PROCESSING_ERROR, "Query Processing Error");
- putCodeMessage(QRY_NOT_SUPPORTED, "Query Not Supported");
- putCodeMessage(QRY_STYLE_NOT_FOUND, "Query Style Not Found");
-
- // Security-related errors 700 series
- putCodeMessage(SEC_INVALID_USER, "Security Invalid User");
- putCodeMessage(SEC_INVALID_GROUP, "Security Invalid Group");
- putCodeMessage(SEC_INVALID_ACCESS, "Security Invalid Access");
- putCodeMessage(SEC_INVALID_CREDENTIALS, "Security Invalid
Credentials");
-
- // URI-related errors 800 series
- putCodeMessage(URI_EMPTY, "URI Empty");
- putCodeMessage(URI_NULL, "URI Null");
- putCodeMessage(URI_PARSE_ERROR, "URI Parse Error");
-
- // Java-related errors 2000 series
- putCodeMessage(JAVA_RUNTIME_ERROR, "Java Runtime Error");
- }
-
- private static void putCodeMessage(int code, String message) {
- faultMessages.put(new Integer(code), message);
- }
-
- /**
- * getMessage returns a textual form for the specified fault code.
- *
- * @param code The Fault Code
- * @return It's textual form
- */
- public static String getMessage(int code) {
- String msg = (String) faultMessages.get(new Integer(code));
- return msg != null ? msg : "";
- }
-
- /**
- * createXMLDBException creates an XMLDBException instance based
- * on the specified Exception. If the Exception is a DBException,
- * it will extract any important information from it (like fault
- * codes and messages)
- *
- * @param e The Exception to use
- * @return An XMLDBException instance
- */
- public static XMLDBException createXMLDBException(Exception e) {
- if (e instanceof XMLDBException)
- return (XMLDBException) e;
-
- int faultCode = e instanceof RuntimeException ?
JAVA_RUNTIME_ERROR : GEN_UNKNOWN;
- return createXMLDBException(faultCode, null, e);
- }
-
- /**
- * Creates an XMLDBException instance based
- * on the specified fault code, message, and Exception. If the
Exception is a DBException,
- * it will extract any important information from it (like fault
- * codes and messages). If the exception is an instance of
XindiceException,
- * the exception class name and message of any Throwable(s) available
- * via XindiceException.getCause will also be incorporated
- * into the message. If a chain of wrapped XindiceExceptions is
available,
- * the chain will be followed incorporating the class name and message
- * at each level.
- * TODO: This should only be considered a temporary fix
- * TODO: until such time as the xmldb API can be refined to allow for
wrapped
- * TODO: throwables in XMLDBException.
- *
- * @param faultCode the fault code for the created exception
- * @param e The Exception to use
- * @return An XMLDBException instance
- */
- public static XMLDBException createXMLDBException(int faultCode, String
message, Exception e) {
- if (e instanceof XMLDBException) {
- return (XMLDBException) e;
- }
-
- if (e instanceof DBException) {
- faultCode = ((DBException) e).faultCode;
- }
-
- return new XMLDBException(ErrorCodes.VENDOR_ERROR, faultCode,
message, e);
- }
-
- /**
- * getFaultCodeType examines the provided exception to determine
- * the general fault code that is associated with it. General
- * fault codes are reduced from actual fault codes to be one of
- * the GEN_ prefixed fault code values.
- *
- * @param e The Exception to examine
- * @return The General Fault Code
- */
- public static int getFaultCodeType(Exception e) {
- int code = 0;
- if (e instanceof DBException)
- code = ((DBException) e).faultCode;
-
- // Strip it to the General series
- code = code % 100;
- // Narrow to a General value
- code = code - (code % 10);
- return code;
- }
-
- /**
- * getFaultCodeSeries examines the provided exception to
- * determine the fault code series that is associated with it.
- * Series are reduced from actual fault codes to be one of
- * the fault code prefixes (ex: COL, DB, SEC).
- *
- * @param e The Exception to examine
- * @return The Fault Code Series
- */
- public static int getFaultCodeSeries(Exception e) {
- int code = 0;
- if (e instanceof DBException)
- code = ((DBException) e).faultCode;
-
- // Strip it to the series
- code = code - (code % 100);
- return code;
- }
-
- /**
- * getFaultCode examines the provided exception to determine
- * the fault code that is associated with it.
- *
- * @param e The Exception to examine
- * @return The Fault Code
- */
- public static int getFaultCode(Exception e) {
- if (e instanceof DBException)
- return ((DBException) e).faultCode;
- else
- return 0;
- }
-
- /**
- * getFaultMessage examines the provided exception to determine
- * the fault message that is associated with it.
- *
- * @param e The Exception to examine
- * @return The Fault Message
- */
- public static String getFaultMessage(Exception e) {
- return getMessage(getFaultCode(e));
- }
+ private static final Map faultMessages = new HashMap();
+ public static final int GEN = (int) (0l);
+ public static final int OBJ = (int) (100l);
+ public static final int COL = (int) (200l);
+ public static final int IDX = (int) (300l);
+ public static final int TRX = (int) (400l);
+ public static final int DBE = (int) (500l);
+ public static final int QRY = (int) (600l);
+ public static final int SEC = (int) (700l);
+ public static final int URI = (int) (800l);
+ public static final int JAVA = (int) (2000l);
+ public static final int GEN_UNKNOWN = (int) (0l);
+ public static final int GEN_GENERAL_ERROR = (int) (40l);
+ public static final int GEN_CRITICAL_ERROR = (int) (70l);
+ public static final int GEN_FATAL_ERROR = (int) (90l);
+ public static final int COL_COLLECTION_NOT_FOUND = (int) (200l);
+ public static final int COL_DOCUMENT_NOT_FOUND = (int) (201l);
+ public static final int COL_DUPLICATE_COLLECTION = (int) (240l);
+ public static final int COL_NULL_RESULT = (int) (241l);
+ public static final int COL_NO_FILER = (int) (242l);
+ public static final int COL_NO_INDEXMANAGER = (int) (242l);
+ public static final int COL_DOCUMENT_MALFORMED = (int) (243l);
+ public static final int COL_CANNOT_STORE = (int) (244l);
+ public static final int COL_CANNOT_RETRIEVE = (int) (245l);
+ public static final int COL_COLLECTION_READ_ONLY = (int) (246l);
+ public static final int COL_COLLECTION_CLOSED = (int) (247l);
+ public static final int COL_CANNOT_CREATE = (int) (270l);
+ public static final int COL_CANNOT_DROP = (int) (271l);
+ public static final int COL_INVALID_RESULT = (int) (277l);
+ public static final int IDX_VALUE_NOT_FOUND = (int) (300l);
+ public static final int IDX_INDEX_NOT_FOUND = (int) (301l);
+ public static final int IDX_MATCHES_NOT_FOUND = (int) (340l);
+ public static final int IDX_DUPLICATE_INDEX = (int) (341l);
+ public static final int IDX_NOT_SUPPORTED = (int) (370l);
+ public static final int IDX_STYLE_NOT_FOUND = (int) (371l);
+ public static final int IDX_CORRUPTED = (int) (372l);
+ public static final int IDX_CANNOT_CREATE = (int) (373l);
+ public static final int TRX_DOC_LOCKED = (int) (400l);
+ public static final int TRX_NO_CONTEXT = (int) (440l);
+ public static final int TRX_NOT_ACTIVE = (int) (441l);
+ public static final int TRX_NOT_SUPPORTED = (int) (470l);
+ public static final int DBE_NO_PARENT = (int) (500l);
+ public static final int DBE_CANNOT_DROP = (int) (570l);
+ public static final int DBE_CANNOT_CREATE = (int) (571l);
+ public static final int QRY_NULL_RESULT = (int) (600l);
+ public static final int QRY_COMPILATION_ERROR = (int) (640l);
+ public static final int QRY_PROCESSING_ERROR = (int) (641l);
+ public static final int QRY_NOT_SUPPORTED = (int) (670l);
+ public static final int QRY_STYLE_NOT_FOUND = (int) (671l);
+ public static final int SEC_INVALID_USER = (int) (770l);
+ public static final int SEC_INVALID_GROUP = (int) (771l);
+ public static final int SEC_INVALID_ACCESS = (int) (772l);
+ public static final int SEC_INVALID_CREDENTIALS = (int) (773l);
+ public static final int URI_EMPTY = (int) (800l);
+ public static final int URI_NULL = (int) (801l);
+ public static final int URI_PARSE_ERROR = (int) (820l);
+ public static final int JAVA_RUNTIME_ERROR = (int) (2070l);
+
+ private FaultCodes() {}
+
+ static {
+ // General errors 0 series
+ putCodeMessage(GEN_UNKNOWN, "Unknown");
+ putCodeMessage(GEN_GENERAL_ERROR, "General Error");
+ putCodeMessage(GEN_CRITICAL_ERROR, "Critical Error");
+ putCodeMessage(GEN_FATAL_ERROR, "Fatal Error");
+
+ // Collection-related errors 200 series
+ putCodeMessage(COL_COLLECTION_NOT_FOUND, "Collection Not Found");
+ putCodeMessage(COL_DOCUMENT_NOT_FOUND, "Collection Document Not
Found");
+ putCodeMessage(COL_DUPLICATE_COLLECTION, "Collection Duplicated");
+ putCodeMessage(COL_NULL_RESULT, "Collection Null Result");
+ putCodeMessage(COL_NO_FILER, "Collection No Filer");
+ putCodeMessage(COL_NO_INDEXMANAGER, "Collection No IndexManager");
+ putCodeMessage(COL_DOCUMENT_MALFORMED, "Collection Document
Malformed");
+ putCodeMessage(COL_CANNOT_STORE, "Collection Cannot Store");
+ putCodeMessage(COL_CANNOT_RETRIEVE, "Collection Cannot Retrieve");
+ putCodeMessage(COL_COLLECTION_READ_ONLY, "Collection Read-only");
+ putCodeMessage(COL_COLLECTION_CLOSED, "Collection Closed");
+ putCodeMessage(COL_CANNOT_CREATE, "Collection Cannot Create");
+ putCodeMessage(COL_CANNOT_DROP, "Collection Cannot Drop");
+ putCodeMessage(COL_INVALID_RESULT, "Collection Invalid Result");
+
+ // Index-related errors 300 series
+ putCodeMessage(IDX_VALUE_NOT_FOUND, "Index Value Not Found");
+ putCodeMessage(IDX_INDEX_NOT_FOUND, "Index Not Found");
+ putCodeMessage(IDX_MATCHES_NOT_FOUND, "Index Matches Not Found");
+ putCodeMessage(IDX_DUPLICATE_INDEX, "Index Duplicate Index");
+ putCodeMessage(IDX_NOT_SUPPORTED, "Index Not Supported");
+ putCodeMessage(IDX_STYLE_NOT_FOUND, "Index Style Not Found");
+ putCodeMessage(IDX_CORRUPTED, "Index Corrupted");
+ putCodeMessage(IDX_CANNOT_CREATE, "Index Cannot Create");
+
+ // Transaction-related errors 400 series
+ putCodeMessage(TRX_DOC_LOCKED, "Transaction Document Locked");
+ putCodeMessage(TRX_NO_CONTEXT, "Transaction No Context");
+ putCodeMessage(TRX_NOT_ACTIVE, "Transaction Not Active");
+ putCodeMessage(TRX_NOT_SUPPORTED, "Transaction Not Supported");
+
+ // Database-related errors 500 series
+ putCodeMessage(DBE_NO_PARENT, "Database No Parent");
+ putCodeMessage(DBE_CANNOT_DROP, "Database Cannot Drop");
+ putCodeMessage(DBE_CANNOT_CREATE, "Database Cannot Create");
+
+ // Query-related errors 600 series
+ putCodeMessage(QRY_NULL_RESULT, "Query Null Result");
+ putCodeMessage(QRY_COMPILATION_ERROR, "Query Compilation Error");
+ putCodeMessage(QRY_PROCESSING_ERROR, "Query Processing Error");
+ putCodeMessage(QRY_NOT_SUPPORTED, "Query Not Supported");
+ putCodeMessage(QRY_STYLE_NOT_FOUND, "Query Style Not Found");
+
+ // Security-related errors 700 series
+ putCodeMessage(SEC_INVALID_USER, "Security Invalid User");
+ putCodeMessage(SEC_INVALID_GROUP, "Security Invalid Group");
+ putCodeMessage(SEC_INVALID_ACCESS, "Security Invalid Access");
+ putCodeMessage(SEC_INVALID_CREDENTIALS, "Security Invalid
Credentials");
+
+ // URI-related errors 800 series
+ putCodeMessage(URI_EMPTY, "URI Empty");
+ putCodeMessage(URI_NULL, "URI Null");
+ putCodeMessage(URI_PARSE_ERROR, "URI Parse Error");
+
+ // Java-related errors 2000 series
+ putCodeMessage(JAVA_RUNTIME_ERROR, "Java Runtime Error");
+ }
+
+ private static void putCodeMessage(int code, String message) {
+ faultMessages.put(new Integer(code), message);
+ }
+
+ /**
+ * getMessage returns a textual form for the specified fault code.
+ *
+ * @param code The Fault Code
+ * @return It's textual form
+ */
+ public static String getMessage(int code) {
+ String msg = (String) faultMessages.get(new Integer(code));
+ return msg != null ? msg : "";
+ }
+
+ /**
+ * createXMLDBException creates an XMLDBException instance based
+ * on the specified Exception. If the Exception is a DBException,
+ * it will extract any important information from it (like fault
+ * codes and messages)
+ *
+ * @param e The Exception to use
+ * @return An XMLDBException instance
+ */
+ public static XMLDBException createXMLDBException(Exception e) {
+ if (e instanceof XMLDBException)
+ return (XMLDBException) e;
+
+ int faultCode = e instanceof RuntimeException ? JAVA_RUNTIME_ERROR :
GEN_UNKNOWN;
+ return createXMLDBException(faultCode, null, e);
+ }
+
+ /**
+ * Creates an XMLDBException instance based
+ * on the specified fault code, message, and Exception. If the
Exception is a DBException,
+ * it will extract any important information from it (like fault
+ * codes and messages). If the exception is an instance of
XindiceException,
+ * the exception class name and message of any Throwable(s) available
+ * via XindiceException.getCause will also be incorporated
+ * into the message. If a chain of wrapped XindiceExceptions is
available,
+ * the chain will be followed incorporating the class name and message
+ * at each level.
+ * TODO: This should only be considered a temporary fix
+ * TODO: until such time as the xmldb API can be refined to allow for
wrapped
+ * TODO: throwables in XMLDBException.
+ *
+ * @param faultCode the fault code for the created exception
+ * @param e The Exception to use
+ * @return An XMLDBException instance
+ */
+ public static XMLDBException createXMLDBException(int faultCode, String
message, Exception e) {
+ if (e instanceof XMLDBException) {
+ return (XMLDBException) e;
+ }
+
+ if (e instanceof DBException) {
+ faultCode = ((DBException) e).faultCode;
+ }
+
+ return new XMLDBException(ErrorCodes.VENDOR_ERROR, faultCode,
message, e);
+ }
+
+ /**
+ * getFaultCodeType examines the provided exception to determine
+ * the general fault code that is associated with it. General
+ * fault codes are reduced from actual fault codes to be one of
+ * the GEN_ prefixed fault code values.
+ *
+ * @param e The Exception to examine
+ * @return The General Fault Code
+ */
+ public static int getFaultCodeType(Exception e) {
+ int code = 0;
+ if (e instanceof DBException)
+ code = ((DBException) e).faultCode;
+
+ // Strip it to the General series
+ code = code % 100;
+ // Narrow to a General value
+ code = code - (code % 10);
+ return code;
+ }
+
+ /**
+ * getFaultCodeSeries examines the provided exception to
+ * determine the fault code series that is associated with it.
+ * Series are reduced from actual fault codes to be one of
+ * the fault code prefixes (ex: COL, DB, SEC).
+ *
+ * @param e The Exception to examine
+ * @return The Fault Code Series
+ */
+ public static int getFaultCodeSeries(Exception e) {
+ int code = 0;
+ if (e instanceof DBException)
+ code = ((DBException) e).faultCode;
+
+ // Strip it to the series
+ code = code - (code % 100);
+ return code;
+ }
+
+ /**
+ * getFaultCode examines the provided exception to determine
+ * the fault code that is associated with it.
+ *
+ * @param e The Exception to examine
+ * @return The Fault Code
+ */
+ public static int getFaultCode(Exception e) {
+ if (e instanceof DBException)
+ return ((DBException) e).faultCode;
+ else
+ return 0;
+ }
+
+ /**
+ * getFaultMessage examines the provided exception to determine
+ * the fault message that is associated with it.
+ *
+ * @param e The Exception to examine
+ * @return The Fault Message
+ */
+ public static String getFaultMessage(Exception e) {
+ return getMessage(getFaultCode(e));
+ }
}
1.5 +122 -99
xml-xindice/java/src/org/apache/xindice/core/DocumentCache.java
Index: DocumentCache.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DocumentCache.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DocumentCache.java 3 Jul 2003 19:23:07 -0000 1.4
+++ DocumentCache.java 14 Jul 2003 19:07:14 -0000 1.5
@@ -59,16 +59,17 @@
* $Id$
*/
+import java.util.Map;
+import java.util.WeakHashMap;
+
import org.apache.xindice.core.data.Key;
import org.apache.xindice.xml.NodeSource;
import org.apache.xindice.xml.SymbolTable;
import org.apache.xindice.xml.dom.DBDocument;
import org.apache.xindice.xml.dom.DocumentImpl;
-
-import org.w3c.dom.*;
-
-import java.util.Map;
-import java.util.WeakHashMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
* DocumentCache implements a simple Document caching system for
@@ -76,98 +77,120 @@
*/
public final class DocumentCache {
- private Map table = new WeakHashMap();
+ private Map table = new WeakHashMap();
- public Document getDocument(Collection col, Key key) {
- Object v = table.get(new CacheKey(col, key));
- Document doc = null;
- if (v instanceof Document)
- doc = (Document) v;
- else if (v instanceof byte[]) {
- try {
- SymbolTable s = col.getSymbols();
- NodeSource ns = new NodeSource(col, key);
- doc = new DocumentImpl((byte[]) v, s, ns);
- }
- catch (Exception e) {}
- }
- return doc;
- }
-
- public void putDocument(Collection col, Key key, byte[] bytes) {
- CacheKey ckey = new CacheKey(col, key);
- table.put(ckey, bytes);
- }
-
- public void putDocument(Collection col, Key key, Document doc) {
- CacheKey ckey = new CacheKey(col, key);
- table.put(ckey, doc);
- }
-
- public void removeDocument(Collection col, Key key) {
- table.remove(new CacheKey(col, key));
- }
-
- public static int getCacheControl(Document doc) {
- String cache = DBDocument.CACHE;
- NodeList childNodes = doc.getChildNodes();
- int size = childNodes.getLength();
- for (int i = 0; i < size; i++) {
- Node n = childNodes.item(i);
- if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE
&& n.getNodeName().equals(DBDocument.CACHE_CONTROL)) {
- cache = n.getNodeValue().trim();
- break;
- }
- }
-
- if (cache != null) {
- if (cache.equals(DBDocument.CACHE))
- return -1;
- else if (cache.equals(DBDocument.NOCACHE))
- return 0;
- else
- return Integer.parseInt(cache);
- }
- else
- return -1;
- }
-
- /**
- * CacheKey
- */
-
- private class CacheKey {
- private Collection col;
- private String strVal;
- private Key key;
-
- public CacheKey(Collection col, Key key) {
- this.col = col;
- this.key = key;
- }
-
- public Collection getCollection() {
- return col;
- }
-
- public Key getKey() {
- return key;
- }
-
- public String toString() {
- if (strVal == null)
- strVal = col.getCanonicalDocumentName(key);
- return strVal;
- }
-
- public int hashCode() {
- if (strVal == null)
- strVal = col.getCanonicalDocumentName(key);
- return strVal.hashCode();
- }
-
- public boolean equals(Object o) {
- return o instanceof CacheKey && col == ((CacheKey)
o).col && key.equals(((CacheKey) o).key);
- }
- }
+ /**
+ * @param col
+ * @param key
+ * @return
+ */
+ public Document getDocument(Collection col, Key key) {
+ Object v = table.get(new CacheKey(col, key));
+ Document doc = null;
+ if (v instanceof Document)
+ doc = (Document) v;
+ else if (v instanceof byte[]) {
+ try {
+ SymbolTable s = col.getSymbols();
+ NodeSource ns = new NodeSource(col, key);
+ doc = new DocumentImpl((byte[]) v, s, ns);
+ }
+ catch (Exception e) {}
+ }
+ return doc;
+ }
+
+ /**
+ * @param col
+ * @param key
+ * @param bytes
+ */
+ public void putDocument(Collection col, Key key, byte[] bytes) {
+ CacheKey ckey = new CacheKey(col, key);
+ table.put(ckey, bytes);
+ }
+
+ /**
+ * @param col
+ * @param key
+ * @param doc
+ */
+ public void putDocument(Collection col, Key key, Document doc) {
+ CacheKey ckey = new CacheKey(col, key);
+ table.put(ckey, doc);
+ }
+
+ /**
+ * @param col
+ * @param key
+ */
+ public void removeDocument(Collection col, Key key) {
+ table.remove(new CacheKey(col, key));
+ }
+
+ /**
+ * @param doc
+ * @return
+ */
+ public static int getCacheControl(Document doc) {
+ String cache = DBDocument.CACHE;
+ NodeList childNodes = doc.getChildNodes();
+ int size = childNodes.getLength();
+ for (int i = 0; i < size; i++) {
+ Node n = childNodes.item(i);
+ if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
n.getNodeName().equals(DBDocument.CACHE_CONTROL)) {
+ cache = n.getNodeValue().trim();
+ break;
+ }
+ }
+
+ if (cache != null) {
+ if (cache.equals(DBDocument.CACHE))
+ return -1;
+ else if (cache.equals(DBDocument.NOCACHE))
+ return 0;
+ else
+ return Integer.parseInt(cache);
+ }
+ else
+ return -1;
+ }
+
+ /**
+ * CacheKey
+ */
+ private class CacheKey {
+ private Collection col;
+ private String strVal;
+ private Key key;
+
+ public CacheKey(Collection col, Key key) {
+ this.col = col;
+ this.key = key;
+ }
+
+ public Collection getCollection() {
+ return col;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public String toString() {
+ if (strVal == null)
+ strVal = col.getCanonicalDocumentName(key);
+ return strVal;
+ }
+
+ public int hashCode() {
+ if (strVal == null)
+ strVal = col.getCanonicalDocumentName(key);
+ return strVal.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ return o instanceof CacheKey && col == ((CacheKey) o).col &&
key.equals(((CacheKey) o).key);
+ }
+ }
}
1.5 +18 -19
xml-xindice/java/src/org/apache/xindice/core/DBException.java
Index: DBException.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/DBException.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DBException.java 31 Oct 2002 06:59:56 -0000 1.4
+++ DBException.java 14 Jul 2003 19:07:14 -0000 1.5
@@ -68,23 +68,22 @@
*/
public class DBException extends XindiceException {
- public int faultCode;
+ public int faultCode;
- public DBException() {
- this(FaultCodes.GEN_UNKNOWN, "", null);
- }
+ public DBException() {
+ this(FaultCodes.GEN_UNKNOWN, "", null);
+ }
- public DBException(int faultCode) {
- this(faultCode, "", null);
- }
+ public DBException(int faultCode) {
+ this(faultCode, "", null);
+ }
- public DBException(int faultCode, String message) {
- this(faultCode, message, null);
- }
-
- public DBException(int faultCode, String message, Throwable cause) {
- super(message, cause);
- this.faultCode = faultCode;
- }
+ public DBException(int faultCode, String message) {
+ this(faultCode, message, null);
+ }
+ public DBException(int faultCode, String message, Throwable cause) {
+ super(message, cause);
+ this.faultCode = faultCode;
+ }
}
1.3 +3 -3
xml-xindice/java/src/org/apache/xindice/core/Container.java
Index: Container.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Container.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Container.java 31 Oct 2002 06:59:56 -0000 1.2
+++ Container.java 14 Jul 2003 19:07:14 -0000 1.3
@@ -60,14 +60,14 @@
*/
import org.apache.xindice.core.data.Key;
-
-import org.w3c.dom.*;
+import org.w3c.dom.Document;
/**
* Container is a generic container for Key and Document pairs.
*/
public interface Container {
+
/**
* getCollection returns the Collection that the Document contained
* belongs to.
1.21 +293 -270
xml-xindice/java/src/org/apache/xindice/core/Database.java
Index: Database.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Database.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Database.java 14 Jul 2003 18:31:57 -0000 1.20
+++ Database.java 14 Jul 2003 19:07:14 -0000 1.21
@@ -80,273 +80,296 @@
* Database is the primary container for the Xindice Database Engine.
*/
public final class Database extends Collection implements Named {
- public static final String DBROOT = "dbroot";
- private static final String QUERYENGINE = "queryengine";
- private static final String DATABASE = "database";
- private static final String COLKEY = "database.xml";
- private static final String METADATA = "use-metadata";
- public static final String NAME = "name";
-
- private static Log log = LogFactory.getLog("org.apache.xindice.core");
-
- public static final String PROP_XINDICE_HOME = "xindice.home";
-
- private static final Map databases = new HashMap(); // String to
Database
-
- private DocumentCache docCache = new DocumentCache();
-
- private SystemCollection systemCollection = null;
-
- private MetaSystemCollection metaSystemCollection = null;
-
- private boolean sysInit = false;
- private boolean metaInit = false;
- private boolean metaEnabled = false;
- // key = canonical name, value = timerecord
- private Map timestamps = new HashMap();
-
- private QueryEngine engine = new QueryEngine(this);
-
- /**
- * This will merely return an instance of a Database for the given
- * name if one has already been loaded.
- *
- * @param name
- * @return Database
- */
- public static Database getDatabase(String name) {
-
- Database database = (Database) databases.get(name);
- if (null == database) {
- // in case it's currently being added (only pay the
sync hit on a miss)
- synchronized (databases) {
- database = (Database) databases.get(name);
- }
- }
-
- return database;
- }
-
- /**
- * This will return an instance of a Database for the given
- * name if one has already been loaded, otherwise it will
- * create a new instance.
- *
- * @param config
- * @return Database
- */
- public static Database getDatabase(Configuration config) {
-
- String name = config.getAttribute(Database.NAME);
-
- // no name in the config file ... can't the database
- if (null == name) {
- throw new ConfigurationException("Database
configuration didn't contain a database name");
- }
-
- Database database = (Database) databases.get(name);
- if (null == database) {
- // in case it's currently being added (only pay the
sync hit on a miss)
- synchronized (databases) {
- // was it created while we waited?
- database = (Database) databases.get(name);
- if (null == database) {
- database = new Database();
- database.setConfig(config);
-
- databases.put(database.getName(),
database);
- }
- }
- }
-
- return database;
- }
-
- public static String[] listDatabases() {
- return (String[]) databases.keySet().toArray(new String[0]);
- }
-
- public void setConfig(Configuration config) {
- this.config = config;
-
- this.name = config.getAttribute(NAME);
- setCanonicalName('/' + getName());
-
- String dbroot = config.getAttribute(DBROOT);
- File dbrootDir = new File(dbroot);
- if (!dbrootDir.isAbsolute()) {
- dbrootDir = new
File(System.getProperty(PROP_XINDICE_HOME), dbroot);
- }
- setCollectionRoot(dbrootDir);
- log.info("Database points to " + dbrootDir.getAbsolutePath());
- log.debug("Database dir exists: " + (dbrootDir == null ? false
: dbrootDir.exists()));
-
- try {
- Configuration queryCfg = config.getChild(QUERYENGINE);
- if (queryCfg != null)
- this.engine.setConfig(queryCfg);
- }
- catch (Exception e) {
-
- log.warn(e);
- }
-
- if (!sysInit) {
- this.systemCollection = new SystemCollection(this);
-
- try {
- this.systemCollection.init();
- }
- catch (XindiceException e) {
- log.warn(e);
- }
-
- this.collections.put(systemCollection.getName(),
systemCollection);
- this.sysInit = true;
- }
-
- try {
- // Bootstrap from the database itself... This is
accomplished
- // by intercepting the setConfig call and using a
Configuration
- // retrieved from the database instead of the standard
config
- Document colDoc =
systemCollection.getCollection(SystemCollection.CONFIGS).getDocument(COLKEY);
- if (colDoc == null) {
- DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
- colDoc = db.newDocument();
- Element root = colDoc.createElement(DATABASE);
- root.setAttribute(NAME, name);
- colDoc.appendChild(root);
-
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY,
colDoc);
- }
-
- super.setConfig(new
Configuration(colDoc.getDocumentElement(), false));
- }
- catch (Exception e) {
- log.warn(e);
- }
-
- // Register the Database with the VM
- // databases.put(getName(), this);
-
- // initialize the meta collection
- // but only if it's turned on in the config.
- String metaCfg = config.getAttribute(METADATA);
- if (metaCfg.equalsIgnoreCase("on")) {
- metaEnabled = true;
- if (!metaInit) {
- this.metaSystemCollection = new
MetaSystemCollection(this);
- try {
- this.metaSystemCollection.init();
- }
- catch (XindiceException e) {
- log.warn("Error initializing the meta
collection", e);
- }
- // should this attach the meta collection to
the database?
-
- collections.put(metaSystemCollection.getName(),
metaSystemCollection);
- metaInit = true;
- log.info("Meta information initialized");
- }
- }
-
- // observer
- DBObserver.getInstance().setDatabaseConfig(this, collections,
config);
- }
-
- public SystemCollection getSystemCollection() {
- return systemCollection;
- }
-
- /**
- * Return the MetaSystem collection for this database.
- *
- * It will return null if metadata is not enabled on this database.
- * @return MetaSystemCollection
- */
- public MetaSystemCollection getMetaSystemCollection() {
- return metaSystemCollection;
- }
-
- /**
- * Return whether or not metadata is enabled on this database.
- * @return boolean
- */
- public boolean isMetaEnabled() {
- return metaEnabled;
- }
-
- public Database getDatabase() {
- return this;
- }
-
- /**
- * flushConfig ensures that the Collection configuration has been
- * properly flushed to disk after a modification.
- */
- public void flushConfig() {
-
- try {
- Document d = config.getElement().getOwnerDocument();
-
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, d);
- }
- catch (Exception e) {
- log.error("Error Writing Configuration '" + name + "',
for database " + getName(), e);
- }
-
- // observer
- DBObserver.getInstance().flushDatabaseConfig(this, config);
- }
-
- public boolean close() throws DBException {
- flushConfig();
-
- synchronized (databases) {
- databases.remove(getName());
- }
-
- return true;
- }
-
- /**
- * getDocumentCache returns the Database-level Document Cache.
- *
- * @return The DocumentCache
- */
- public DocumentCache getDocumentCache() {
- return docCache;
- }
-
- /**
- * getQueryEngine returns a reference to the Database's current
- * operating QueryEngine implementation.
- *
- * @return The QueryEngine instance
- */
- public QueryEngine getQueryEngine() {
- return engine;
- }
-
- // methods for recording the times when meta data is enabled.
- public synchronized void recordTime(String path, long created, long
modified) {
- TimeRecord rec = (TimeRecord) timestamps.get(path);
- if (null == rec) {
- rec = new TimeRecord(created, modified);
- timestamps.put(path, rec);
- }
- else {
- if (created > 0)
- rec.setCreatedTime(created);
- if (modified > 0)
- rec.setModifiedTime(modified);
- }
- }
-
- public synchronized void removeTime(String path) {
- timestamps.remove(path);
- }
-
- public synchronized TimeRecord getTime(String path) {
- TimeRecord rec = (TimeRecord) timestamps.get(path);
- return rec;
- }
+
+ public static final String DBROOT = "dbroot";
+ public static final String NAME = "name";
+ public static final String PROP_XINDICE_HOME = "xindice.home";
+ private static final String QUERYENGINE = "queryengine";
+ private static final String COLKEY = "database.xml";
+ private static final String DATABASE = "database";
+ private static final String METADATA = "use-metadata";
+ private static Log log = LogFactory.getLog("org.apache.xindice.core");
+ private static final Map databases = new HashMap(); // String to Database
+
+ /**
+ * This will return an instance of a Database for the given
+ * name if one has already been loaded, otherwise it will
+ * create a new instance.
+ *
+ * @param config
+ * @return Database
+ */
+ public static Database getDatabase(Configuration config) {
+
+ String name = config.getAttribute(Database.NAME);
+
+ // no name in the config file ... can't the database
+ if (null == name) {
+ throw new ConfigurationException("Database configuration didn't
contain a database name");
+ }
+
+ Database database = (Database) databases.get(name);
+ if (null == database) {
+ // in case it's currently being added (only pay the sync hit on
a miss)
+ synchronized (databases) {
+ // was it created while we waited?
+ database = (Database) databases.get(name);
+ if (null == database) {
+ database = new Database();
+
+ try {
+ database.setConfig(config);
+ }
+ catch (XindiceException x) { // TODO: Configurable
interface should use ConfigurationException instead of XindiceException.
+
+ throw new ConfigurationException(x);
+ }
+
+ databases.put(database.getName(), database);
+ }
+ }
+ }
+
+ return database;
+ }
+
+ /**
+ * This will merely return an instance of a Database for the given
+ * name if one has already been loaded.
+ *
+ * @param name
+ * @return Database
+ */
+ public static Database getDatabase(String name) {
+
+ Database database = (Database) databases.get(name);
+ if (null == database) {
+ // in case it's currently being added (only pay the sync hit on
a miss)
+ synchronized (databases) {
+ database = (Database) databases.get(name);
+ }
+ }
+
+ return database;
+ }
+
+ public static String[] listDatabases() {
+ return (String[]) databases.keySet().toArray(new String[0]);
+ }
+
+ //
+ // Instance...
+ //
+ private DocumentCache docCache = new DocumentCache();
+ private QueryEngine engine = new QueryEngine(this);
+ private boolean metaEnabled = false;
+ private boolean metaInit = false;
+ private MetaSystemCollection metaSystemCollection = null;
+ private boolean sysInit = false;
+ private SystemCollection systemCollection = null;
+ /** key = canonical name, value = timerecord */
+ private Map timestamps = new HashMap();
+
+ /**
+ * @see org.apache.xindice.core.DBObject#close()
+ */
+ public boolean close() throws DBException {
+ flushConfig();
+
+ synchronized (databases) {
+ databases.remove(getName());
+ }
+
+ return true;
+ }
+
+ /**
+ * flushConfig ensures that the Collection configuration has been
+ * properly flushed to disk after a modification.
+ */
+ public void flushConfig() {
+
+ try {
+ Document d = getConfig().getElement().getOwnerDocument();
+
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY, d);
+ }
+ catch (Exception e) {
+ log.error("Error Writing Configuration '" + getName() + "', for
database " + getName(), e);
+ }
+
+ // observer
+ DBObserver.getInstance().flushDatabaseConfig(this, getConfig());
+ }
+
+ /**
+ * @see org.apache.xindice.core.Collection#getDatabase()
+ */
+ public Database getDatabase() {
+ return this;
+ }
+
+ /**
+ * getDocumentCache returns the Database-level Document Cache.
+ *
+ * @return The DocumentCache
+ */
+ public DocumentCache getDocumentCache() {
+ return docCache;
+ }
+
+ /**
+ * Return the MetaSystem collection for this database.
+ *
+ * It will return null if metadata is not enabled on this database.
+ * @return MetaSystemCollection
+ */
+ public MetaSystemCollection getMetaSystemCollection() {
+ return metaSystemCollection;
+ }
+
+ /**
+ * getQueryEngine returns a reference to the Database's current
+ * operating QueryEngine implementation.
+ *
+ * @return The QueryEngine instance
+ */
+ public QueryEngine getQueryEngine() {
+ return engine;
+ }
+
+ /**
+ * @see org.apache.xindice.core.Collection#getSystemCollection()
+ */
+ public SystemCollection getSystemCollection() {
+ return systemCollection;
+ }
+
+ /**
+ * @param path
+ * @return
+ */
+ public synchronized TimeRecord getTime(String path) {
+ TimeRecord rec = (TimeRecord) timestamps.get(path);
+ return rec;
+ }
+
+ /**
+ * Return whether or not metadata is enabled on this database.
+ * @return boolean
+ */
+ public boolean isMetaEnabled() {
+ return metaEnabled;
+ }
+
+ // methods for recording the times when meta data is enabled.
+ public synchronized void recordTime(String path, long created, long
modified) {
+ TimeRecord rec = (TimeRecord) timestamps.get(path);
+ if (null == rec) {
+ rec = new TimeRecord(created, modified);
+ timestamps.put(path, rec);
+ }
+ else {
+ if (created > 0)
+ rec.setCreatedTime(created);
+ if (modified > 0)
+ rec.setModifiedTime(modified);
+ }
+ }
+
+ /**
+ * @param path
+ */
+ public synchronized void removeTime(String path) {
+ timestamps.remove(path);
+ }
+
+ /**
+ * @see
org.apache.xindice.util.Configurable#setConfig(org.apache.xindice.util.Configuration)
+ */
+ public void setConfig(Configuration config) throws XindiceException {
+ super.setConfig(config);
+
+ setName(config.getAttribute(NAME));
+ setCanonicalName('/' + getName());
+
+ String dbroot = config.getAttribute(DBROOT);
+ File dbrootDir = new File(dbroot);
+ if (!dbrootDir.isAbsolute()) {
+ dbrootDir = new File(System.getProperty(PROP_XINDICE_HOME),
dbroot);
+ }
+ setCollectionRoot(dbrootDir);
+ log.info("Database points to " + dbrootDir.getAbsolutePath());
+ log.debug("Database dir exists: " + (dbrootDir == null ? false :
dbrootDir.exists()));
+
+ try {
+ Configuration queryCfg = config.getChild(QUERYENGINE);
+ if (queryCfg != null)
+ this.engine.setConfig(queryCfg);
+ }
+ catch (Exception e) {
+
+ log.warn(e);
+ }
+
+ if (!sysInit) {
+ this.systemCollection = new SystemCollection(this);
+
+ try {
+ this.systemCollection.init();
+ }
+ catch (XindiceException e) {
+ log.warn(e);
+ }
+
+ super.addCollection(systemCollection);
+ this.sysInit = true;
+ }
+
+ try {
+ // Bootstrap from the database itself... This is accomplished
+ // by intercepting the setConfig call and using a Configuration
+ // retrieved from the database instead of the standard config
+ Document colDoc =
systemCollection.getCollection(SystemCollection.CONFIGS).getDocument(COLKEY);
+ if (colDoc == null) {
+ DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ colDoc = db.newDocument();
+ Element root = colDoc.createElement(DATABASE);
+ root.setAttribute(NAME, getName());
+ colDoc.appendChild(root);
+
systemCollection.getCollection(SystemCollection.CONFIGS).setDocument(COLKEY,
colDoc);
+ }
+
+ super.setConfig(new Configuration(colDoc.getDocumentElement(),
false));
+ }
+ catch (Exception e) {
+ log.warn(e);
+ }
+
+ // Register the Database with the VM
+ // databases.put(getName(), this);
+
+ // initialize the meta collection
+ // but only if it's turned on in the config.
+ String metaCfg = config.getAttribute(METADATA);
+ if (metaCfg.equalsIgnoreCase("on")) {
+ metaEnabled = true;
+ if (!metaInit) {
+ this.metaSystemCollection = new MetaSystemCollection(this);
+ try {
+ this.metaSystemCollection.init();
+ }
+ catch (XindiceException e) {
+ log.warn("Error initializing the meta collection", e);
+ }
+ // should this attach the meta collection to the database?
+
+ super.addCollection(metaSystemCollection);
+ metaInit = true;
+ log.info("Meta information initialized");
+ }
+ }
+
+ // observer
+ DBObserver.getInstance().setDatabaseConfig(this, getCollections(),
config);
+ }
}
1.21 +1485
-1476xml-xindice/java/src/org/apache/xindice/core/Collection.java
Index: Collection.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/Collection.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Collection.java 14 Jul 2003 17:23:56 -0000 1.20
+++ Collection.java 14 Jul 2003 19:07:15 -0000 1.21
@@ -58,7 +58,13 @@
*
* $Id$
*/
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.xindice.core.data.DocumentSet;
import org.apache.xindice.core.data.EmptyDocumentSet;
import org.apache.xindice.core.data.EmptyNodeSet;
@@ -70,10 +76,10 @@
import org.apache.xindice.core.filer.Filer;
import org.apache.xindice.core.indexer.IndexManager;
import org.apache.xindice.core.indexer.Indexer;
+import org.apache.xindice.core.meta.MetaData;
import org.apache.xindice.core.meta.inline.InlineMetaMap;
import org.apache.xindice.core.meta.inline.InlineMetaService;
import org.apache.xindice.core.meta.inline.ResourceTypeReader;
-import org.apache.xindice.core.meta.MetaData;
import org.apache.xindice.core.query.QueryEngine;
import org.apache.xindice.util.Configurable;
import org.apache.xindice.util.Configuration;
@@ -94,14 +100,6 @@
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.util.ArrayList;
-
/**
* Collection represents a collection of Documents maintains links to
* the Filer storage implementation, and the Indexes associated with
@@ -109,1470 +107,1481 @@
**/
public class Collection extends CollectionManager implements Named,
DBObject, Configurable {
- private static final String NAME = "name";
- private static final String FILER = "filer";
- private static final String CLASS = "class";
- private static final String INDEXES = "indexes";
- private static final String INLINE_METADATA = "inline-metadata";
- private static final String COMPRESSED = "compressed";
- private static final String CACHE = "cache";
- private static final String SYMBOLS = "symbols";
- private static final String CLASSNAME = "xindice-class";
-
- private static final DocumentSet EMPTY_DOCUMENTSET = new
EmptyDocumentSet();
- private static final NodeSet EMPTY_NODESET = new EmptyNodeSet();
- private static final String[] EMPTY_STRING_ARRAY = {};
-
- private static Log log = LogFactory.getLog("org.apache.xindice.core");
-
- private static int host_id;
- static {
- try {
- InetAddress a = InetAddress.getLocalHost();
- byte[] b = a.getAddress();
- host_id = 0;
- host_id += b[0];
- host_id += (b[1] << 8);
- host_id += (b[2] << 16);
- host_id += (b[3] << 24);
- host_id = Math.abs(host_id);
- }
- catch (Exception e) {}
- };
-
- private Collection parent = null;
-
- // Object ID Stuff
- private int collection_id = 0;
- private long document_id = System.currentTimeMillis();
- private Object oidMutex = new Object();
- private String oidTemplate = null;
-
- protected String name;
- private String canonicalName;
- private File collectionRoot;
-
- private Filer filer = null;
-
- private boolean compressed = false;
- private SymbolTable symbols = null;
- private boolean internalSymbols = false;
-
- private IndexManager indexManager;
- private DocumentCache documentCache;
-
- private InlineMetaService inlineMetaService;
-
- protected Collection() {}
-
- public Collection(Collection collection) {
- this();
- parent = collection;
- }
-
- public void setConfig(Configuration config) throws XindiceException {
- this.config = config;
-
- name = config.getAttribute(NAME);
- compressed = config.getBooleanAttribute(COMPRESSED, true);
-
- /*
- * If inline metadata is desired, get an InlineMetaService
object.
- */
- if (config.getBooleanAttribute(INLINE_METADATA, false)) {
- inlineMetaService = new InlineMetaService();
- }
-
- /*
- * Wait to set up the local debug header until everything needed
- * by debugHeader() is complete!
- */
- String localDebugHeader = debugHeader() + "setConfig: ";
-
- if (inlineMetaService == null) {
- log.debug(localDebugHeader + "inline metadata
DISABLED");
- }
- else {
- log.debug(localDebugHeader + "inline metadata ENABLED");
- }
-
- if (parent != null) {
- setCanonicalName(parent.getCanonicalName() + '/' +
name);
- log.debug(localDebugHeader + "canonical name=<" +
getCanonicalName() + ">");
- setCollectionRoot(new File(parent.getCollectionRoot(),
name));
- log.debug(localDebugHeader + "collection root=<" +
getCollectionRoot().toString() + ">");
- }
-
- if (config.getBooleanAttribute(CACHE, true))
- documentCache = getDatabase().getDocumentCache();
-
- // If no Filer is defined, skip Symbols and Indexes
- Configuration filerConfig = config.getChild(FILER);
- if (filerConfig != null) {
- log.debug(localDebugHeader + "have filer config...");
-
- // Symbol Table Setup
- Configuration symConfig = config.getChild(SYMBOLS);
- internalSymbols = (symConfig != null);
- if (internalSymbols) {
- log.debug(localDebugHeader + "have internal
symbols <" + TextWriter.toString(symConfig.getElement()) + ">");
- try {
- symbols = new
SymbolTable(symConfig.getElement());
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Error building
symbol table from internal symbols", e);
- }
- }
- }
- else {
- log.debug(localDebugHeader + "no internal
symbols...");
- try {
- symbols =
getSystemCollection().loadSymbols(this);
- log.debug(
- localDebugHeader
- + "loaded symbols from
system collection <"
- +
TextWriter.toString(symbols.streamToXML(new DocumentImpl()))
- + ">");
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Error building
symbol table from system collection...", e);
- }
- }
- }
-
- String className = filerConfig.getAttribute(CLASS);
- log.debug(localDebugHeader + "file class=<" + className
+ ">");
- try {
- filer = (Filer)
Class.forName(className).newInstance();
- // filer.setCollection(this);
- filer.setLocation(getCollectionRoot(),
getName());
- filer.setConfig(filerConfig);
- if (!filer.exists())
- filer.create();
- filer.open();
- }
- catch (Exception e) {
- if (log.isWarnEnabled()) {
- log.warn("Filer '" + className + "' not
available", e);
- }
- }
-
- // Index Manager
- try {
- indexManager = new IndexManager(this);
- Configuration idxConfig =
config.getChild(INDEXES, true);
- indexManager.setConfig(idxConfig);
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("No message", e);
- }
- }
- }
-
- super.setConfig(config);
-
- // observer
- DBObserver.getInstance().setCollectionConfig(this, config);
- }
-
- public final String getName() {
- return name;
- }
-
- public final File getCollectionRoot() {
- return collectionRoot;
- }
-
- protected final void setCollectionRoot(File collectionRoot) {
- this.collectionRoot = collectionRoot;
- if (!collectionRoot.exists())
- collectionRoot.mkdirs();
- }
-
- /**
- * getParentCollection returns the parent Collection of this
- * Collection.
- *
- * @return The parent Collection (or null)
- */
- public final Collection getParentCollection() throws DBException {
- return parent;
- }
-
- public final boolean dropCollection(Collection collection) throws
DBException {
- boolean success = super.dropCollection(collection);
- getDatabase().flushConfig();
- return success;
- }
-
- public final Collection createCollection(String path, Configuration
config) throws DBException {
- Collection col = super.createCollection(path, config);
- getDatabase().flushConfig();
- return col;
- }
-
- // Convenience Methods
-
- /**
- * getDatabase returns the Database owner for this Collection.
- *
- * @return The Database
- */
- public Database getDatabase() {
- return parent.getDatabase();
- }
-
- /**
- * getSystemCollection returns the System Collection.
- *
- * @return The System Collection
- */
- public SystemCollection getSystemCollection() throws DBException {
- return getDatabase().getSystemCollection();
- }
-
- /**
- * getQueryEngine returns the Database's Query Engine
- *
- * @return The Query Engine
- */
- public QueryEngine getQueryEngine() throws DBException {
- return getDatabase().getQueryEngine();
- }
-
- private void checkFiler(int faultCode) throws DBException {
- if (filer == null)
- throw new DBException(faultCode, "This Collection '" +
name + "' cannot store Documents");
- }
-
- /**
- * getIndexer retrieves an Indexer by name.
- *
- * @param name The Indexer name
- * @return The Indexer (or null)
- */
- public final Indexer getIndexer(String name) throws DBException {
- checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
- return indexManager.get(name);
- }
-
- /**
- * listIndexers returns a list of the currently registered Indexers
- * as an array of String.
- *
- * @return The Indexer list
- */
- public final String[] listIndexers() throws DBException {
- checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
- return indexManager.list();
- }
-
- /**
- * dropIndexer physically removes the specified Indexer and any
- * associated system resources that the Indexer uses.
- *
- * @param index The Indexer to drop
- * @return Whether or not the Indexer was dropped
- */
- public final boolean dropIndexer(Indexer index) throws DBException {
- checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
-
- if (index == null)
- throw new DBException(FaultCodes.IDX_INDEX_NOT_FOUND,
"Index Value Null");
-
- boolean success = indexManager.drop(index.getName());
- getDatabase().flushConfig();
- return success;
- }
-
- /**
- * createIndexer creates a new Indexer object and any associated
- * system resources that the Indexer will need.
- *
- * @param config The Indexer's configuration
- * @return The newly created Indexer
- */
- public final Indexer createIndexer(Configuration config) throws
DBException {
- checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
- Indexer idx = indexManager.create(config);
- getDatabase().flushConfig();
- return idx;
- }
-
- /**
- * getFiler returns the low-level Filer instances underlying the
- * Collection instance.
- *
- * @return The requested Filer
- */
- public final Filer getFiler() {
- return filer;
- }
-
- /**
- * return the IndexManager being used by this Collection.
- *
- * @return The IndexManager
- */
- public final IndexManager getIndexManager() throws DBException {
- checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
- return indexManager;
- }
-
- /**
- * getSymbols returns the SymbolTable in use by this
- * Collection.
- *
- * @return The Symbol Table
- */
- public final SymbolTable getSymbols() throws DBException {
- return symbols;
- }
-
- /**
- * Turns an XML string into a parsed document and caches it.
- *
- * @param key The key to use when caching
- * @param xml The string to parse
- * @return A parsed DOM document or null if failure
- */
- private Document parseDocument(Key key, String xml) throws DBException {
- Document doc = null;
- try {
- doc = DOMParser.toDocument(xml);
-
- // Have to move it to Xindice DOM for XMLObject
AutoLinking
- byte[] b = DOMCompressor.Compress(doc, symbols);
- doc = new DocumentImpl(b, symbols, new NodeSource(this,
key));
-
- if (documentCache != null)
- documentCache.putDocument(this, key, b);
- }
- catch (Exception e) {
- throw new
DBException(FaultCodes.COL_DOCUMENT_MALFORMED, "Unable to parse Document", e);
- }
- return doc;
- }
-
- /**
- * getCanonicalName returns the canonical name for this Object.
- * <br>
- * ex: /local/test/ocs
- *
- * @return The canonical name
- */
- public final String getCanonicalName() {
- return canonicalName;
- }
-
- protected final void setCanonicalName(String canonicalName) {
- this.canonicalName = canonicalName;
-
- // Calculate The OID Template
- collection_id = Math.abs(canonicalName.hashCode());
- StringBuffer sb = new
StringBuffer("00000000000000000000000000000000");
- String host = Integer.toString(host_id, 16);
- String collection = Integer.toString(collection_id, 16);
- sb.insert(8 - host.length(), host);
- sb.insert(16 - collection.length(), collection);
- sb.setLength(32);
- oidTemplate = sb.toString();
- }
-
- /**
- * getCanonicalDocumentName returns the canonical name for the specified
- * Key in relation to this Collection.
- * <br>
- * ex: /local/test/ocs/ytd
- *
- * @param key The Key
- * @return The canonical name
- */
- public final String getCanonicalDocumentName(Key key) {
- return getCanonicalDocumentName(key.toString());
- }
-
- public final String getCanonicalDocumentName(String key) {
- StringBuffer sb = new StringBuffer();
- sb.append(canonicalName);
- sb.append('/');
- sb.append(key);
- return sb.toString();
- }
-
- public final boolean open() throws DBException {
- return true;
- }
-
- public boolean isOpened() throws DBException {
- return true;
- }
-
- public boolean exists() throws DBException {
- return true;
- }
-
- public boolean close() throws DBException {
- return true;
- }
-
- public boolean create() throws DBException {
- // update the meta information if necessary
- updateCollectionMeta();
-
- DBObserver.getInstance().createCollection(this);
- return true;
- }
-
- public boolean drop() throws DBException {
- if (this == getDatabase())
- throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You
Cannot Drop The Database");
-
- DBObserver.getInstance().dropCollection(this);
-
- // drop the meta if necessary
- if (isMetaEnabled()) {
- MetaSystemCollection metacol =
getMetaSystemCollection();
- metacol.dropCollectionMeta(this);
- }
-
- // Drop Child Collections
- String[] cols = listCollections();
- for (int i = 0; i < cols.length; i++)
- dropCollection(getCollection(cols[i]));
-
- if (filer != null) {
- // Drop Indexers
- String[] idx = indexManager.list();
- for (int i = 0; i < idx.length; i++)
- dropIndexer(getIndexer(idx[i]));
-
- // Now Drop The Filer
- filer.drop();
- }
-
- getCollectionRoot().delete();
- getDatabase().flushConfig();
-
- return true;
- }
-
- // All Document Handling Code Follows
-
- /**
- * createNewOID allocates a new Object ID to be used as a Key in the
- * Collection.
- *
- * @return The newly generated Key
- */
- public final Key createNewOID() {
- long ct = System.currentTimeMillis();
-
- synchronized (oidMutex) {
- if (ct <= document_id)
- ct = document_id + 1;
- document_id = ct;
- }
-
- StringBuffer sb = new StringBuffer(oidTemplate);
- String document = Long.toString(document_id, 16);
- sb.insert(32 - document.length(), document);
- sb.setLength(32);
-
- return new Key(sb.toString());
- }
-
- /**
- * createNewKey allocates a new Key to be used as a Key in the
- * Collection.
- *
- * @param key The Key hint
- * @return The newly generated Key
- */
- protected final Key createNewKey(Object key) {
- if (key == null)
- return createNewOID();
- if (key instanceof Key)
- return (Key) key;
- else
- return new Key(key.toString());
- }
-
- public final void flushSymbolTable() throws DBException {
- if (symbols.isDirty() && !internalSymbols)
- getSystemCollection().saveSymbols(this, symbols);
- }
-
- /*
- * Lowest-level method for saving a binary entry into the database.
- * Does not update non-inline metadata.
- */
- private void putBinary(Key key, byte[] bytes, boolean create) throws
DBException {
-
- if (inlineMetaService == null) {
- throw new DBException(
- FaultCodes.COL_CANNOT_STORE,
- "Cannot store a binary resource in collection "
+ name + ": inline-metadata is not enabled");
- }
-
- if (!create) {
- byte[] storedBytes = getBinary(key);
- if (storedBytes == null) {
- /*
- * XXX TODO
- * Do we need a COL_KEY_ALREADY_PRESENT fault
- * so that the caller can interpret this
exception?
- */
- throw new DBException(
- FaultCodes.COL_CANNOT_STORE,
- "Error storing binary object with key
'" + key + "': the 'create' flag is false and" + " the key is not in the
database");
- }
- }
-
- InlineMetaMap map = inlineMetaService.getEmptyMap();
- map.put("type", ResourceTypeReader.BINARY);
- Value value = inlineMetaService.createValue(map, bytes, 0,
bytes.length);
- filer.writeRecord(key, value);
- }
-
- /**
- * This is the lowest-level method for storing a record into the
backing store.
- * It does not update non-inline metadata.
- */
- private void putDocument(Key key, Document document /* TODO used this
variable , boolean create*/
- ) throws DBException {
-
- String localDebugHeader = debugHeader() + "putDocument:
docKey=<" + key.toString() + ">: ";
-
- log.debug(localDebugHeader + "document=<" +
TextWriter.toString(document).toString() + ">");
-
- checkFiler(FaultCodes.COL_NO_FILER);
-
- if (document instanceof DBDocument) {
- // This is a shitty shitty hack... Kill immediately
- DBDocument dbDoc = (DBDocument) document;
- if (dbDoc.getSource() == null)
- dbDoc.setSource(new NodeSource(this, key));
- }
-
- /*
- * The possibilities are restricted because only XML
- * is handled by this method. There are only a few
- * pieces of information that need to be constructed:
- * 1) the xindice DOM document is needed for all XML objects, as
- * it is handed to the IndexManager and the DBObserver.
- * 2) the packed document, if this is a compressed XML object,
- * is needed for the cache and the BTree (via the Value
object).
- * 3) the string-converted-to-utf-8 bytes, if this is a
non-compressed
- * XML object, is needed for the BTree (via the Value
object).
- * 4) A Value object, with a header if headers are enabled, and
- * otherwise without headers, for the BTree.
- */
-
- byte[] packedDocument = null;
- byte[] utf8Document = null;
-
- if (compressed) {
- try {
-
- packedDocument =
DOMCompressor.Compress(document, symbols);
- log.debug(localDebugHeader + "length=" +
packedDocument.length);
-
- // Why must it be re-created?
- document = new DocumentImpl(packedDocument,
symbols, new NodeSource(this, key));
-
- log.debug(localDebugHeader + "packedDocument:
length=" + packedDocument.length + " document=<" +
TextWriter.toString(document) + ">");
- }
- catch (Exception e) {
- throw new
DBException(FaultCodes.COL_CANNOT_STORE, localDebugHeader + "Error compressing
Document '" + key + "'", e);
- }
- }
- else {
- try {
- utf8Document =
TextWriter.toString(document).getBytes("utf-8");
- log.debug(localDebugHeader + "utf8Document:
length=" + utf8Document.length + " document=<" + new String(utf8Document,
"utf-8") + ">");
- }
- catch (UnsupportedEncodingException e) {
- throw new
DBException(FaultCodes.GEN_FATAL_ERROR, "utf-8 encoding not supported", e);
- }
- }
-
- /*
- * XXX TODO
- * Can this be moved into the if(compressed) block?
- */
- flushSymbolTable();
-
- // Temporary until insert and update are separate
- Document oldDoc = getDocument(key);
- if (oldDoc != null) {
- indexManager.removeDocument(key, oldDoc);
- }
- indexManager.addDocument(key, document);
-
- /*
- * Construct the Value object that is stored in the BTree.
- */
- Value value;
- if (inlineMetaService == null) {
- if (compressed) {
- value = new Value(packedDocument);
- }
- else {
- value = new Value(utf8Document);
- }
- }
- else {
- InlineMetaMap map = inlineMetaService.getEmptyMap();
- map.put("type", ResourceTypeReader.XML);
- if (compressed) {
- value = inlineMetaService.createValue(map,
packedDocument, 0, packedDocument.length);
- }
- else {
- value = inlineMetaService.createValue(map,
utf8Document, 0, utf8Document.length);
- }
- }
- filer.writeRecord(key, value);
-
- // Cache Stuff
- if (documentCache != null) {
- if (compressed)
- documentCache.putDocument(this, key,
packedDocument);
- else
- documentCache.putDocument(this, key, document);
- }
-
- DBObserver.getInstance().putDocument(this, key, document,
oldDoc == null);
- }
-
- /**
- * update the modified time of this collection when appropriate
- */
- protected void updateCollectionMeta() {
- // update the meta data if necessary
- if (isMetaEnabled()) {
- MetaSystemCollection metacol =
getMetaSystemCollection();
- MetaData meta = null;
- try {
- meta = metacol.getCollectionMeta(this);
- }
- catch (DBException e) {
- // something strange has happened.. can't get
the
- // meta data for this collection
- if (log.isWarnEnabled())
- log.warn("Error fetching collection
meta. " + e);
- return;
- }
-
- if (log.isInfoEnabled())
- log.info("Updating modified time for this
collection's meta");
- long now = System.currentTimeMillis();
- if (null == meta) {
- meta = new MetaData(MetaData.COLLECTION,
getCanonicalName(), now, now);
- }
- else {
- // this collection already has a meta. so
update its modified time.
- meta.setContext(0, now);
- }
- try {
- metacol.setCollectionMeta(this, meta);
- }
- catch (DBException e) {
- if (log.isWarnEnabled())
- log.warn("Error setting the collection
meta. " + e);
- return;
- }
- }
- }
-
- /**
- * update the modified time of this document when appropriate
- */
- protected void updateDocumentMeta(String id) throws DBException {
- // update the meta data if necessary
- if (!isMetaEnabled())
- return;
-
- Document doc = getDocument(id);
- if (null == doc)
- throw new
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not
exist");
-
- MetaSystemCollection metacol = getMetaSystemCollection();
- MetaData meta = metacol.getDocumentMeta(this, id);
-
- String path = getCanonicalDocumentName(id);
-
- /*
- TimeRecord rec = null;
- if( null == meta || !meta.hasContext() )
- rec = getDatabase().getTime(path);
-
- long created = (null != rec) ? rec.getCreatedTime() :
System.currentTimeMillis();
- long modified = (null != rec) ? rec.getModifiedTime() :
System.currentTimeMillis();
- */
-
- // this is wrong.. but it should work for now...
- long created = System.currentTimeMillis();
- long modified = System.currentTimeMillis();
-
- if (null == meta) {
- meta = new MetaData(MetaData.DOCUMENT, path, created,
modified);
- }
- else if (!meta.hasContext()) {
- meta.setContext(created, modified);
- }
- else {
- meta.setContext(0, modified);
- }
- metacol.setDocumentMeta(this, id, meta);
- }
-
- /**
- * insertBinary inserts a new binary object into a Xindice Collection.
- *
- * @param docKey The document Key
- * @param document The document to insert
- * @throws DBException if inline-metadata is not enabled, the key is
- * already in the database, or an error occurs while saving.
- */
- public void insertBinary(Object docKey, byte[] bytes) throws
DBException {
-
- if (inlineMetaService == null) {
- throw new DBException(
- FaultCodes.COL_CANNOT_STORE,
- "Cannot insert a binary resource in collection
" + name + ": inline-metadata is not enabled.");
- }
-
- putBinary(createNewKey(docKey), bytes, true);
-
- // update the meta information if necessary
- updateCollectionMeta();
- }
-
- /**
- * Insert a binary object into a Xindice Collection. A unique key
- * is automatically generated. by which the binary object can be
- * retrieved in the future. Note: because the key is automatically
- * unique, this insert method will never cause a collision with an
- * object already in the database.
- *
- * @param bytes The bytes making up the binary object to insert
- * @return Key automatically generated for the binary object
- * @throws DBException if inline-metadata is not enabled, or an
- * error occurs while saving.
- */
- public Key insertBinary(byte[] bytes) throws DBException {
-
- if (inlineMetaService == null) {
- throw new DBException(
- FaultCodes.COL_CANNOT_STORE,
- "Cannot insert a binary resource in collection
" + name + ": inline-metadata is not enabled.");
- }
-
- Key key = createNewOID();
- putBinary(key, bytes, true);
-
- // update the meta information if necessary
- updateCollectionMeta();
-
- return key;
- }
-
- /**
- * insertDocument inserts a new Document into a Xindice Collection.
- *
- * @param document The Document
- * @return The new Object Identifier
- */
- public final Key insertDocument(Document document) throws DBException {
- Key key = createNewOID();
- putDocument(key, document /*, true */
- );
- // update the meta information if necessary
- updateCollectionMeta();
- return key;
- }
-
- /**
- * insertDocument inserts a new Document into a Xindice Collection.
- *
- * @param docKey The document Key
- * @param document The document to insert
- */
- public final void insertDocument(Object docKey, Document document)
throws DBException {
- putDocument(createNewKey(docKey), document /*, true */
- );
- // update the meta information if necessary
- updateCollectionMeta();
- }
-
- /**
- * setDocument overwrites/updates an existing Document in a
- * Xindice Collection.
- *
- * @param docKey The Document Key
- * @param document The Document
- */
- public final void setDocument(Object docKey, Document document) throws
DBException {
- putDocument(createNewKey(docKey), document /*, false */
- );
- // update the meta for this document
- updateDocumentMeta(docKey.toString());
- }
-
- /**
- * remove removes an object from the Collection based on its Key,
- * regardless of it's type.
- *
- * @param key The Object's Key
- */
- public final void remove(Object key) throws DBException {
- checkFiler(FaultCodes.COL_NO_FILER);
-
- Key objKey = createNewKey(key);
-
- Document oldDoc = getDocument(objKey);
- if (oldDoc != null)
- indexManager.removeDocument(objKey, oldDoc);
-
- if (documentCache != null)
- documentCache.removeDocument(this, objKey);
-
- if (!filer.deleteRecord(objKey))
- throw new
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document Does Not Exist");
-
- // update the meta for this collection if necessary
- updateCollectionMeta();
- // remove the document meta
- if (isMetaEnabled()) {
- getMetaSystemCollection().dropDocumentMeta(this,
objKey.toString());
- }
- DBObserver.getInstance().dropDocument(this, objKey);
- }
-
- /**
- * Retrieve a binary database entry by key.
- * This low-level method will not update non-inline metadata.
- *
- * @param docKey identifying the desired database entry
- * @return byte[] containing the binary database entry
- * @throws DBException if inline-metadata is not enabled
- * (binary resource cannot be stored in a collection
- * which does not have inline-metadata enabled),
- * in case of backing store error, and in case of
- * header corruption
- */
- public final byte[] getBinary(Object docKey) throws DBException {
-
- log.debug(debugHeader() + "getBinary: docKey=<" +
docKey.toString() + ">");
-
- if (inlineMetaService != null) {
- throw new DBException(
- FaultCodes.COL_DOCUMENT_NOT_FOUND,
- "There are no binary resources in collection" +
name + ": inline-metadata is not enabled.");
- }
-
- Object entry = getEntry(docKey);
- if (entry == null) {
- return null;
- }
-
- if (!(entry instanceof byte[])) {
- throw new DBException(
- FaultCodes.COL_INVALID_RESULT,
- "The resource associated with key '" +
docKey.toString() + "' in collection '" + name + "'is not binary");
- }
-
- return (byte[]) entry;
- }
-
- /**
- * getDocument retrieves a Document by Key.
- *
- * @param docKey The Document Key
- * @return The Document
- */
- public final Document getDocument(Object docKey) throws DBException {
-
- log.debug(debugHeader() + "getDocument: docKey=<" +
docKey.toString() + ">");
-
- Object entry = getEntry(docKey);
- if (entry == null) {
- return null;
- }
-
- if (!(entry instanceof Document)) {
- throw new DBException(
- FaultCodes.COL_INVALID_RESULT,
- "The resource associated with key '" +
docKey.toString() + "' in collection '" + name + "'is not XML");
- }
-
- return (Document) entry;
- }
-
- /**
- * Retrieve a database entry by key.
- * If no matching entry is found, null is returned; if
- * an XML entry is found, a Document is returned; if a
- * binary entryis found, byte[] is returned.
- * This low-level method will not update non-inline metadata.
- *
- * @param docKey identifying the desired database entry
- * @return Object containing the database entry, or null if no
- * matching entry is found
- * @throws DBException in case of backing store error,
- * and in case of header corruption
- */
- public final Object getEntry(Object docKey) throws DBException {
-
- /*
- * I would prefer to throw an exception (NPE) in this case,
- * but we have a test indicating a null return...
- */
- if (docKey == null) {
- return null;
- }
-
- String localDebugHeader = debugHeader() + "getEntry: docKey=<"
+ docKey.toString() + ">: ";
-
- log.debug(localDebugHeader);
-
- checkFiler(FaultCodes.COL_NO_FILER);
-
- Key key = createNewKey(docKey);
-
- /*
- * If the key has a corresponding value in the cache, return it
- * and save a disk access.
- *
- * At some point the current document-centric cache
implementation
- * needs to be converted to an entry cache which can hold both
- * Document and byte[].
- */
- if (documentCache != null) {
- Document document = documentCache.getDocument(this,
key);
- log.debug(localDebugHeader + "cache search returned: "
+ document);
- if (document != null) {
- return document;
- }
- }
-
- Record record = filer.readRecord(key);
- if (record == null) {
- return null;
- }
-
- log.debug(localDebugHeader + "record value: length=" +
record.getValue().getLength());
-
- Value value;
- InlineMetaMap metaMap = null;
- if (inlineMetaService == null) {
- log.debug(localDebugHeader + "type not available");
- value = record.getValue();
- }
- else {
- log.debug(localDebugHeader + "decomposing header...");
- InlineMetaService.DatabaseEntry databaseEntry =
inlineMetaService.readDatabaseEntry(record.getValue());
- metaMap = databaseEntry.map;
- value = databaseEntry.value;
-
- log.debug(localDebugHeader + "type=" +
metaMap.get("type") + " length=" + value.getLength());
- }
-
- if (inlineMetaService == null ||
metaMap.get("type").equals(ResourceTypeReader.XML)) {
-
- log.debug(localDebugHeader + "XML document");
-
- Document document;
- if (compressed) {
-
- document = new DocumentImpl(value.getData(),
symbols, new NodeSource(this, key));
-
- flushSymbolTable();
-
- log.debug(localDebugHeader + "compressed XML
document: document=<" + TextWriter.toString(document) + ">");
-
- if (documentCache != null) {
- documentCache.putDocument(this, key,
value.getData());
- }
- }
- else {
- log.debug(localDebugHeader + "pre
parseDocument(): value=<" + value.toString() + ">");
- document = parseDocument(key, value.toString());
- }
-
- DBObserver.getInstance().loadDocument(this, record,
document);
- return document;
- }
- else {
- return value.getData();
- }
- }
-
- /**
- * getContainer retrieves a Container from the Collection. The
Container
- * encapsulates all information needed in dealing with a Document
outside
- * of the context of a Collection (ex: DocumentContext).
- *
- * @param docKey The Document Key
- * @return The Container
- */
- public final Container getContainer(Object docKey) throws DBException {
- Key key = createNewKey(docKey);
- Document doc = getDocument(key);
- return doc != null ? new ColContainer(key, doc) : null;
- }
-
- /**
- * getObject instantiates and returns an XMLSerializable object based
on the
- * provided Key. Xindice takes care of instantiating the correct
class, but
- * only if a class was registered with the Document in the first place.
- *
- * @param key The Document Key
- * @return an Castable XMLSerializable Instance
- */
- public final XMLSerializable getObject(Object key) throws DBException {
- String className = null;
-
- Document doc = getDocument(key);
-
- if (doc != null) {
- NodeList childNodes = doc.getChildNodes();
- int size = childNodes.getLength();
- for (int i = 0; i < size; i++) {
- Node n = childNodes.item(i);
- if (n.getNodeType() ==
Node.PROCESSING_INSTRUCTION_NODE && n.getNodeName().equals(CLASSNAME)) {
- className = n.getNodeValue().trim();
- break;
- }
- }
-
- if (className != null) {
- try {
- XMLSerializable obj = (XMLSerializable)
Class.forName(className).newInstance();
-
obj.streamFromXML(doc.getDocumentElement());
- return obj;
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("No message", e);
- }
- }
- }
- }
-
- return null;
- }
-
- private void putObject(Key key, XMLSerializable obj /*, boolean create
*/
- ) throws DBException {
-
- String localDebugHeader = debugHeader() + "putObject: key=<" +
key.toString() + ">: ";
-
- Document doc = new DocumentImpl();
- ProcessingInstruction pi =
doc.createProcessingInstruction(CLASSNAME, obj.getClass().getName());
- doc.appendChild(pi);
- Element elem = obj.streamToXML(doc);
- log.debug(localDebugHeader + "elem=<" +
TextWriter.toString(elem) + ">");
- doc.appendChild(elem);
- putDocument(key, doc /*, create */
- );
- }
-
- /**
- * setObject sets an XMLSerializable object in the Collection based on
the
- * provided Key. Xindice takes care of associating the implementation
class
- * with the XMLSerializable object.
- *
- * @param key The Key to use
- * @param obj The Object to set
- */
- public final void setObject(Object key, XMLSerializable obj) throws
DBException {
- putObject(createNewKey(key), obj /*, false */
- );
- }
-
- /**
- * insertObject inserts an XMLSerializable object into the Collection
and
- * returns a newly generated Key. Xindice takes care of associating the
- * implementation class with the XMLSerializable object.
- *
- * @param obj The Object to insert
- * @return The newly generated Key
- */
- public final Key insertObject(XMLSerializable obj) throws DBException {
- Key key = createNewOID();
- putObject(key, obj /*, true */
- );
- return key;
- }
-
- /**
- * insertObject inserts an XMLSerializable object into the Collection
based
- * on the specified Key. Xindice takes care of associating the
- * implementation class with the XMLSerializable object.
- *
- * @param key The Key to use
- * @param obj The Object to insert
- */
- public final void insertObject(String key, XMLSerializable obj) throws
DBException {
- putObject(createNewKey(key), obj /*, true */
- );
- }
-
- /**
- * queryCollection performs a query against the current collection
- * using the specified style and query String.
- *
- * @param style The query style to use (ex: XPath)
- * @param query The query to execute
- * @param nsMap The namespace Map (if any)
- * @return The resulting NodeSet
- */
- public final NodeSet queryCollection(String style, String query,
NamespaceMap nsMap) throws DBException {
- // a collection in which you are unable to file documents will
have no filer
- // (for example the root collection). Rather than throwing an
exception return
- // a constant result (nothing)
- return null == filer ? EMPTY_NODESET :
getQueryEngine().query(this, style, query, nsMap, null);
- }
-
- /**
- * queryDocument performs a query against a single Document using
- * the specified style, query string, and Document ID.
- *
- * @param style The query style to use (ex: XPath)
- * @param query The query to execute
- * @param nsMap The namespace Map (if any)
- * @param key The Document to query
- * @return The resulting NodeSet
- */
- public final NodeSet queryDocument(String style, String query,
NamespaceMap nsMap, Object key) throws DBException {
- checkFiler(FaultCodes.QRY_STYLE_NOT_FOUND);
- Key[] k = null;
- if (key instanceof Key[])
- k = (Key[]) key;
- else
- k = new Key[] { createNewKey(key)};
- return getQueryEngine().query(this, style, query, nsMap, k);
- }
-
- /**
- * getDocumentSet returns the set of Documents being maintained
- * by this Collection.
- *
- * @return The DocumentSet
- */
- public final DocumentSet getDocumentSet() throws DBException {
- // a collection in which you are unable to file documents will
have no filer
- // (for example the root collection). Rather than throwing an
exception return
- // a constant result (nothing)
- return null == filer ? EMPTY_DOCUMENTSET : new
ColDocumentSet(filer.getRecordSet());
- }
-
- /**
- * listDocuments returns a list of all document keys stored by this
- * collection.
- *
- * @return the list of document keys
- */
- public final String[] listDocuments() throws DBException {
- // a collection in which you are unable to file documents will
have no filer
- // (for example the root collection). Rather than throwing an
exception return
- // a constant result (nothing)
- if (null == filer)
- {
- return EMPTY_STRING_ARRAY;
- }
- else
- {
- RecordSet set = filer.getRecordSet();
-
- // todo: what happens if the size if > than the size of
an int.
- // I'm pretty sure some sort of runtime exception will
occur
- // in the ArrayList.add method.
-
- // give a hint to the size of the record set, saves on
arraylist array copies.
- ArrayList temp = new
ArrayList((int)filer.getRecordCount());
-
- while (set.hasMoreRecords()) {
- Key key = set.getNextKey();
- temp.add(key.toString());
- }
-
- return (String[]) temp.toArray(new String[0]);
- }
- }
-
- /**
- * getDocumentCount returns the count of Documents being maintained
- * by this Collection.
- *
- * @return The Document count
- */
- public final long getDocumentCount() throws DBException {
- // a collection in which you are unable to file documents will
have no filer
- // (for example the root collection). Rather than throwing an
exception return
- // a constant result (nothing)
- return null == filer ? 0 : filer.getRecordCount();
- }
-
- public void dispose() {
- try {
- ((Collection) this).close();
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("No message", e);
- }
- }
- }
-
- private String debugHeader() {
- return "["
- + Thread.currentThread().getName()
- + "] Collection:"
- + " name="
- + name
- + " compressed="
- + compressed
- + " inline-metadata="
- + (inlineMetaService != null)
- + " ";
- }
-
- // META DATA RELATED DOCS
- /**
- * Returns whether or not meta data is enabled.
- * @return boolean whether or not meta data is enabled.
- */
- public boolean isMetaEnabled() {
- return getDatabase().isMetaEnabled();
- }
-
- /**
- * Return the MetaData for this collection.
- *
- * If metadata is not enabled in the configuration, the MetaData object
- * returned will be null.
- * @return MetaData this collection's metadata.
- */
- public MetaData getCollectionMeta() throws DBException {
- MetaData meta = null;
- if (!isMetaEnabled()) {
- if (log.isWarnEnabled()) {
- log.warn("Meta information requested but not
enabled in config!");
- }
- return meta;
- }
- MetaSystemCollection metacol = getMetaSystemCollection();
- meta = metacol.getCollectionMeta(this);
- long now = System.currentTimeMillis();
- if (null == meta) {
- meta = new MetaData(MetaData.COLLECTION,
getCanonicalName(), now, now);
- metacol.setCollectionMeta(this, meta);
- }
- return meta;
- }
-
- /**
- * Reset the metadata object for this collection.
- * @param meta the Metadata to use
- */
- public void setCollectionMeta(MetaData meta) throws DBException {
- if (!isMetaEnabled()) {
- if (log.isWarnEnabled()) {
- log.warn("Meta information requested but not
enabled in config!");
- }
- return;
- }
- if (null != meta) {
- if (meta.getType() != MetaData.COLLECTION)
- throw new DBException(FaultCodes.GEN_UNKNOWN,
"Mismatch type of meta data for collection " + getCanonicalName());
-
- MetaSystemCollection metacol =
getMetaSystemCollection();
- metacol.setCollectionMeta(this, meta);
- }
- }
-
- /**
- * Return the MetaData object for a document within this collection.
- *
- * If metadata is not enabled, the MetaData object returned will be
null.
- * @param id the document whose metadata you want
- */
- public MetaData getDocumentMeta(String id) throws DBException {
- MetaData meta = null;
- if (!isMetaEnabled()) {
- if (log.isWarnEnabled()) {
- log.warn("Meta information requested but not
enabled in config!");
- }
- return meta;
- }
- Document doc = getDocument(id);
- if (null == doc)
- throw new
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not
exist");
-
- MetaSystemCollection metacol = getMetaSystemCollection();
- meta = metacol.getDocumentMeta(this, id);
-
- String path = getCanonicalDocumentName(id);
-
- /*
- TimeRecord rec = null;
- if( null == meta || !meta.hasContext() )
- rec = getDatabase().getTime(path);
-
- long created = (null != rec) ? rec.getCreatedTime() :
System.currentTimeMillis();
- long modified = (null != rec) ? rec.getModifiedTime() :
System.currentTimeMillis();
- */
-
- // this is wrong.. but it should work for now...
- long created = System.currentTimeMillis();
- long modified = System.currentTimeMillis();
-
- if (null == meta) {
- meta = new MetaData(MetaData.DOCUMENT, path, created,
modified);
- metacol.setDocumentMeta(this, id, meta);
- }
- else if (!meta.hasContext()) {
- meta.setContext(created, modified);
- }
-
- return meta;
- }
-
- /**
- * Set the metadata associated with a document within this collection.
- *
- * @param id the document name
- * @param meta the metadata object to be used.
- */
- public void setDocumentMeta(String id, MetaData meta) throws
DBException {
- if (!isMetaEnabled()) {
- if (log.isWarnEnabled()) {
- log.warn("Meta information requested but not
enabled in config!");
- }
- return;
- }
- Document doc = getDocument(id);
- if (null == doc)
- throw new
DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "Document " + id + " does not
exist");
-
- if (null != meta) {
- if (meta.getType() == MetaData.UNKNOWN ||
meta.getType() == MetaData.COLLECTION)
- throw new DBException(FaultCodes.GEN_UNKNOWN,
"Mismatch type of meta data for document " + getCanonicalDocumentName(id));
-
- MetaSystemCollection metacol =
getMetaSystemCollection();
- metacol.setDocumentMeta(this, id, meta);
- }
- }
-
- /**
- * Return the MetaSystemCollection for the database containing this
- * collection.
- *
- * @return MetaSystemCollection
- */
- private MetaSystemCollection getMetaSystemCollection() //throws
DBException
- {
- return getDatabase().getMetaSystemCollection();
- }
-
- /**
- * ColDocumentSet
- */
- private class ColDocumentSet implements DocumentSet {
- private RecordSet set;
-
- public ColDocumentSet(RecordSet set) {
- this.set = set;
- }
-
- public boolean hasMoreDocuments() throws DBException {
- return set.hasMoreRecords();
- }
-
- public Container getNextContainer() throws DBException {
- if (set.hasMoreRecords()) {
- Record rec = set.getNextRecord();
- Key key = rec.getKey();
- Value val = rec.getValue();
- if (val.getData() != null) {
- try {
- if (compressed) {
- Document doc = new
DocumentImpl(val.getData(), symbols, new NodeSource(Collection.this, key));
- return new
ColContainer(key, doc);
- }
- else
- return new
ColContainer(key, DOMParser.toDocument(val));
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("No message",
e);
- }
- }
- }
- }
- return null;
- }
-
- public Document getNextDocument() throws DBException {
- Container c = getNextContainer();
- if (c != null)
- return c.getDocument();
- else
- return null;
- }
- }
-
- /**
- * ColContainer
- */
- private class ColContainer implements Container {
- private Key key;
- private Document document;
-
- public ColContainer(Key key, Document document) {
- this.key = key;
- this.document = document;
- }
-
- public Collection getCollection() {
- return Collection.this;
- }
-
- public Key getKey() {
- return key;
- }
-
- public String getCanonicalName() throws DBException {
- return getCanonicalDocumentName(key);
- }
-
- public Document getDocument() {
- return document;
- }
-
- public Document rollback() throws DBException {
- document = Collection.this.getDocument(key);
- return document;
- }
-
- public void commit(Document doc) throws DBException {
- document = doc;
- commit();
- }
-
- public void commit() throws DBException {
- putDocument(key, document /*, false */
- );
- }
-
- public void remove() throws DBException {
- Collection.this.remove(key);
- }
- }
+
+ /**
+ * ColContainer
+ */
+ private class ColContainer implements Container {
+ private Document document;
+ private Key key;
+
+ public ColContainer(Key key, Document document) {
+ this.key = key;
+ this.document = document;
+ }
+
+ public void commit() throws DBException {
+ putDocument(key, document /*, false */
+ );
+ }
+
+ public void commit(Document doc) throws DBException {
+ document = doc;
+ commit();
+ }
+
+ public String getCanonicalName() throws DBException {
+ return getCanonicalDocumentName(key);
+ }
+
+ public Collection getCollection() {
+ return Collection.this;
+ }
+
+ public Document getDocument() {
+ return document;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public void remove() throws DBException {
+ Collection.this.remove(key);
+ }
+
+ public Document rollback() throws DBException {
+ document = Collection.this.getDocument(key);
+ return document;
+ }
+ }
+
+ /**
+ * ColDocumentSet
+ */
+ private class ColDocumentSet implements DocumentSet {
+ private RecordSet set;
+
+ public ColDocumentSet(RecordSet set) {
+ this.set = set;
+ }
+
+ public Container getNextContainer() throws DBException {
+ if (set.hasMoreRecords()) {
+ Record rec = set.getNextRecord();
+ Key key = rec.getKey();
+ Value val = rec.getValue();
+ if (val.getData() != null) {
+ try {
+ if (compressed) {
+ Document doc = new DocumentImpl(val.getData(),
symbols, new NodeSource(Collection.this, key));
+ return new ColContainer(key, doc);
+ }
+ else
+ return new ColContainer(key,
DOMParser.toDocument(val));
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("No message", e);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public Document getNextDocument() throws DBException {
+ Container c = getNextContainer();
+ if (c != null)
+ return c.getDocument();
+ else
+ return null;
+ }
+
+ public boolean hasMoreDocuments() throws DBException {
+ return set.hasMoreRecords();
+ }
+ }
+
+ private static final String CACHE = "cache";
+ private static final String CLASS = "class";
+ private static final String CLASSNAME = "xindice-class";
+ private static final String COMPRESSED = "compressed";
+ private static final DocumentSet EMPTY_DOCUMENTSET = new
EmptyDocumentSet();
+ private static final NodeSet EMPTY_NODESET = new EmptyNodeSet();
+ private static final String[] EMPTY_STRING_ARRAY = {};
+ private static final String FILER = "filer";
+ private static int host_id;
+ private static final String INDEXES = "indexes";
+ private static final String INLINE_METADATA = "inline-metadata";
+ private static Log log = LogFactory.getLog("org.apache.xindice.core");
+ private static final String NAME = "name";
+ private static final String SYMBOLS = "symbols";
+
+ static {
+ try {
+ InetAddress a = InetAddress.getLocalHost();
+ byte[] b = a.getAddress();
+ host_id = 0;
+ host_id += b[0];
+ host_id += (b[1] << 8);
+ host_id += (b[2] << 16);
+ host_id += (b[3] << 24);
+ host_id = Math.abs(host_id);
+ }
+ catch (Exception e) {
+
+ log.warn(e);
+ }
+ }
+
+ private String canonicalName;
+ // Object ID Stuff
+ private int collection_id = 0;
+ private File collectionRoot;
+ private boolean compressed = false;
+ private long document_id = System.currentTimeMillis();
+ private DocumentCache documentCache;
+ private Filer filer = null;
+ private IndexManager indexManager;
+ private InlineMetaService inlineMetaService;
+ private boolean internalSymbols = false;
+ private String name;
+ private Object oidMutex = new Object();
+ private String oidTemplate = null;
+ private Collection parent = null;
+ private SymbolTable symbols = null;
+
+ protected Collection() {}
+
+ /**
+ *
+ * @param parentCollection
+ */
+ public Collection(Collection parentCollection) {
+ this();
+ this.parent = parentCollection;
+ }
+
+ private void checkFiler(int faultCode) throws DBException {
+ if (filer == null)
+ throw new DBException(faultCode, "This Collection '" + name + "'
cannot store Documents");
+ }
+
+ /**
+ * @see org.apache.xindice.core.DBObject#close()
+ */
+ public boolean close() throws DBException {
+ return true;
+ }
+
+ /**
+ * @see org.apache.xindice.core.DBObject#create()
+ */
+ public boolean create() throws DBException {
+ // update the meta information if necessary
+ updateCollectionMeta();
+
+ DBObserver.getInstance().createCollection(this);
+ return true;
+ }
+
+ /**
+ * @see
org.apache.xindice.core.CollectionManager#createCollection(java.lang.String,
org.apache.xindice.util.Configuration)
+ */
+ public final Collection createCollection(String path, Configuration
config) throws DBException {
+ Collection col = super.createCollection(path, config);
+ getDatabase().flushConfig();
+ return col;
+ }
+
+ /**
+ * createIndexer creates a new Indexer object and any associated
+ * system resources that the Indexer will need.
+ *
+ * @param config The Indexer's configuration
+ * @return The newly created Indexer
+ */
+ public final Indexer createIndexer(Configuration config) throws
DBException {
+ checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
+ Indexer idx = indexManager.create(config);
+ getDatabase().flushConfig();
+ return idx;
+ }
+
+ /**
+ * createNewKey allocates a new Key to be used as a Key in the
+ * Collection.
+ *
+ * @param key The Key hint
+ * @return The newly generated Key
+ */
+ protected final Key createNewKey(Object key) {
+ if (key == null)
+ return createNewOID();
+ if (key instanceof Key)
+ return (Key) key;
+ else
+ return new Key(key.toString());
+ }
+
+ /**
+ * createNewOID allocates a new Object ID to be used as a Key in the
+ * Collection.
+ *
+ * @return The newly generated Key
+ */
+ public final Key createNewOID() {
+ long ct = System.currentTimeMillis();
+
+ synchronized (oidMutex) {
+ if (ct <= document_id)
+ ct = document_id + 1;
+ document_id = ct;
+ }
+
+ StringBuffer sb = new StringBuffer(oidTemplate);
+ String document = Long.toString(document_id, 16);
+ sb.insert(32 - document.length(), document);
+ sb.setLength(32);
+
+ return new Key(sb.toString());
+ }
+
+ private String debugHeader() {
+ return "["
+ + Thread.currentThread().getName()
+ + "] Collection:"
+ + " name="
+ + name
+ + " compressed="
+ + compressed
+ + " inline-metadata="
+ + (inlineMetaService != null)
+ + " ";
+ }
+
+ /**
+ * @see org.apache.xindice.util.Disposable#dispose()
+ */
+ public void dispose() {
+ try {
+ ((Collection) this).close();
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("No message", e);
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.xindice.core.DBObject#drop()
+ */
+ public boolean drop() throws DBException {
+ if (this == getDatabase())
+ throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You Cannot
Drop The Database");
+
+ DBObserver.getInstance().dropCollection(this);
+
+ // drop the meta if necessary
+ if (isMetaEnabled()) {
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ metacol.dropCollectionMeta(this);
+ }
+
+ // Drop Child Collections
+ String[] cols = listCollections();
+ for (int i = 0; i < cols.length; i++)
+ dropCollection(getCollection(cols[i]));
+
+ if (filer != null) {
+ // Drop Indexers
+ String[] idx = indexManager.list();
+ for (int i = 0; i < idx.length; i++)
+ dropIndexer(getIndexer(idx[i]));
+
+ // Now Drop The Filer
+ filer.drop();
+ }
+
+ getCollectionRoot().delete();
+ getDatabase().flushConfig();
+
+ return true;
+ }
+
+ /**
+ * @see
org.apache.xindice.core.CollectionManager#dropCollection(org.apache.xindice.core.Collection)
+ */
+ public final boolean dropCollection(Collection collection) throws
DBException {
+ boolean success = super.dropCollection(collection);
+ getDatabase().flushConfig();
+ return success;
+ }
+
+ /**
+ * dropIndexer physically removes the specified Indexer and any
+ * associated system resources that the Indexer uses.
+ *
+ * @param index The Indexer to drop
+ * @return Whether or not the Indexer was dropped
+ */
+ public final boolean dropIndexer(Indexer index) throws DBException {
+ checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
+
+ if (index == null)
+ throw new DBException(FaultCodes.IDX_INDEX_NOT_FOUND, "Index
Value Null");
+
+ boolean success = indexManager.drop(index.getName());
+ getDatabase().flushConfig();
+ return success;
+ }
+
+ /**
+ * @see org.apache.xindice.core.DBObject#exists()
+ */
+ public boolean exists() throws DBException {
+ return true;
+ }
+
+ /**
+ * @throws DBException
+ */
+ public final void flushSymbolTable() throws DBException {
+ if (symbols.isDirty() && !internalSymbols)
+ getSystemCollection().saveSymbols(this, symbols);
+ }
+
+ /**
+ * Retrieve a binary database entry by key.
+ * This low-level method will not update non-inline metadata.
+ *
+ * @param docKey identifying the desired database entry
+ * @return byte[] containing the binary database entry
+ * @throws DBException if inline-metadata is not enabled
+ * (binary resource cannot be stored in a collection
+ * which does not have inline-metadata enabled),
+ * in case of backing store error, and in case of
+ * header corruption
+ */
+ public final byte[] getBinary(Object docKey) throws DBException {
+
+ log.debug(debugHeader() + "getBinary: docKey=<" + docKey.toString()
+ ">");
+
+ if (inlineMetaService != null) {
+ throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND, "There
are no binary resources in collection" + name + ": inline-metadata is not
enabled.");
+ }
+
+ Object entry = getEntry(docKey);
+ if (entry == null) {
+ return null;
+ }
+
+ if (!(entry instanceof byte[])) {
+ throw new DBException(FaultCodes.COL_INVALID_RESULT, "The
resource associated with key '" + docKey.toString() + "' in collection '" +
name + "'is not binary");
+ }
+
+ return (byte[]) entry;
+ }
+
+ /**
+ * getCanonicalDocumentName returns the canonical name for the specified
+ * Key in relation to this Collection.
+ * <br>
+ * ex: /local/test/ocs/ytd
+ *
+ * @param key The Key
+ * @return The canonical name
+ */
+ public final String getCanonicalDocumentName(Key key) {
+ return getCanonicalDocumentName(key.toString());
+ }
+
+ /**
+ * @param key
+ * @return
+ */
+ public final String getCanonicalDocumentName(String key) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(canonicalName);
+ sb.append('/');
+ sb.append(key);
+ return sb.toString();
+ }
+
+ /**
+ * getCanonicalName returns the canonical name for this Object.
+ * <br>
+ * ex: /local/test/ocs
+ *
+ * @return The canonical name
+ */
+ public final String getCanonicalName() {
+ return canonicalName;
+ }
+
+ /**
+ * Return the MetaData for this collection.
+ *
+ * If metadata is not enabled in the configuration, the MetaData object
+ * returned will be null.
+ * @return MetaData this collection's metadata.
+ */
+ public MetaData getCollectionMeta() throws DBException {
+ MetaData meta = null;
+ if (!isMetaEnabled()) {
+ if (log.isWarnEnabled()) {
+ log.warn("Meta information requested but not enabled in
config!");
+ }
+ return meta;
+ }
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ meta = metacol.getCollectionMeta(this);
+ long now = System.currentTimeMillis();
+ if (null == meta) {
+ meta = new MetaData(MetaData.COLLECTION, getCanonicalName(),
now, now);
+ metacol.setCollectionMeta(this, meta);
+ }
+ return meta;
+ }
+
+ /**
+ * @return
+ */
+ public final File getCollectionRoot() {
+ return collectionRoot;
+ }
+
+ /**
+ * getContainer retrieves a Container from the Collection. The Container
+ * encapsulates all information needed in dealing with a Document outside
+ * of the context of a Collection (ex: DocumentContext).
+ *
+ * @param docKey The Document Key
+ * @return The Container
+ */
+ public final Container getContainer(Object docKey) throws DBException {
+ Key key = createNewKey(docKey);
+ Document doc = getDocument(key);
+ return doc != null ? new ColContainer(key, doc) : null;
+ }
+
+ /**
+ * getDatabase returns the Database owner for this Collection.
+ *
+ * @return The Database
+ */
+ public Database getDatabase() {
+ return parent.getDatabase();
+ }
+
+ /**
+ * getDocument retrieves a Document by Key.
+ *
+ * @param docKey The Document Key
+ * @return The Document
+ */
+ public final Document getDocument(Object docKey) throws DBException {
+
+ log.debug(debugHeader() + "getDocument: docKey=<" +
docKey.toString() + ">");
+
+ Object entry = getEntry(docKey);
+ if (entry == null) {
+ return null;
+ }
+
+ if (!(entry instanceof Document)) {
+ throw new DBException(FaultCodes.COL_INVALID_RESULT, "The
resource associated with key '" + docKey.toString() + "' in collection '" +
name + "'is not XML");
+ }
+
+ return (Document) entry;
+ }
+
+ /**
+ * getDocumentCount returns the count of Documents being maintained
+ * by this Collection.
+ *
+ * @return The Document count
+ */
+ public final long getDocumentCount() throws DBException {
+ // a collection in which you are unable to file documents will have
no filer
+ // (for example the root collection). Rather than throwing an
exception return
+ // a constant result (nothing)
+ return null == filer ? 0 : filer.getRecordCount();
+ }
+
+ /**
+ * Return the MetaData object for a document within this collection.
+ *
+ * If metadata is not enabled, the MetaData object returned will be null.
+ * @param id the document whose metadata you want
+ */
+ public MetaData getDocumentMeta(String id) throws DBException {
+ MetaData meta = null;
+ if (!isMetaEnabled()) {
+ if (log.isWarnEnabled()) {
+ log.warn("Meta information requested but not enabled in
config!");
+ }
+ return meta;
+ }
+ Document doc = getDocument(id);
+ if (null == doc)
+ throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND,
"Document " + id + " does not exist");
+
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ meta = metacol.getDocumentMeta(this, id);
+
+ String path = getCanonicalDocumentName(id);
+
+ /*
+ TimeRecord rec = null;
+ if( null == meta || !meta.hasContext() )
+ rec = getDatabase().getTime(path);
+
+ long created = (null != rec) ? rec.getCreatedTime() :
System.currentTimeMillis();
+ long modified = (null != rec) ? rec.getModifiedTime() :
System.currentTimeMillis();
+ */
+
+ // this is wrong.. but it should work for now...
+ long created = System.currentTimeMillis();
+ long modified = System.currentTimeMillis();
+
+ if (null == meta) {
+ meta = new MetaData(MetaData.DOCUMENT, path, created, modified);
+ metacol.setDocumentMeta(this, id, meta);
+ }
+ else if (!meta.hasContext()) {
+ meta.setContext(created, modified);
+ }
+
+ return meta;
+ }
+
+ /**
+ * getDocumentSet returns the set of Documents being maintained
+ * by this Collection.
+ *
+ * @return The DocumentSet
+ */
+ public final DocumentSet getDocumentSet() throws DBException {
+ // a collection in which you are unable to file documents will have
no filer
+ // (for example the root collection). Rather than throwing an
exception return
+ // a constant result (nothing)
+ return null == filer ? EMPTY_DOCUMENTSET : new
ColDocumentSet(filer.getRecordSet());
+ }
+
+ /**
+ * Retrieve a database entry by key.
+ * If no matching entry is found, null is returned; if
+ * an XML entry is found, a Document is returned; if a
+ * binary entryis found, byte[] is returned.
+ * This low-level method will not update non-inline metadata.
+ *
+ * @param docKey identifying the desired database entry
+ * @return Object containing the database entry, or null if no
+ * matching entry is found
+ * @throws DBException in case of backing store error,
+ * and in case of header corruption
+ */
+ public final Object getEntry(Object docKey) throws DBException {
+
+ /*
+ * I would prefer to throw an exception (NPE) in this case,
+ * but we have a test indicating a null return...
+ */
+ if (docKey == null) {
+ return null;
+ }
+
+ String localDebugHeader = debugHeader() + "getEntry: docKey=<" +
docKey.toString() + ">: ";
+
+ log.debug(localDebugHeader);
+
+ checkFiler(FaultCodes.COL_NO_FILER);
+
+ Key key = createNewKey(docKey);
+
+ /*
+ * If the key has a corresponding value in the cache, return it
+ * and save a disk access.
+ *
+ * At some point the current document-centric cache implementation
+ * needs to be converted to an entry cache which can hold both
+ * Document and byte[].
+ */
+ if (documentCache != null) {
+ Document document = documentCache.getDocument(this, key);
+ log.debug(localDebugHeader + "cache search returned: " +
document);
+ if (document != null) {
+ return document;
+ }
+ }
+
+ Record record = filer.readRecord(key);
+ if (record == null) {
+ return null;
+ }
+
+ log.debug(localDebugHeader + "record value: length=" +
record.getValue().getLength());
+
+ Value value;
+ InlineMetaMap metaMap = null;
+ if (inlineMetaService == null) {
+ log.debug(localDebugHeader + "type not available");
+ value = record.getValue();
+ }
+ else {
+ log.debug(localDebugHeader + "decomposing header...");
+ InlineMetaService.DatabaseEntry databaseEntry =
inlineMetaService.readDatabaseEntry(record.getValue());
+ metaMap = databaseEntry.map;
+ value = databaseEntry.value;
+
+ log.debug(localDebugHeader + "type=" + metaMap.get("type") + "
length=" + value.getLength());
+ }
+
+ if (inlineMetaService == null ||
metaMap.get("type").equals(ResourceTypeReader.XML)) {
+
+ log.debug(localDebugHeader + "XML document");
+
+ Document document;
+ if (compressed) {
+
+ document = new DocumentImpl(value.getData(), symbols, new
NodeSource(this, key));
+
+ flushSymbolTable();
+
+ log.debug(localDebugHeader + "compressed XML document:
document=<" + TextWriter.toString(document) + ">");
+
+ if (documentCache != null) {
+ documentCache.putDocument(this, key, value.getData());
+ }
+ }
+ else {
+ log.debug(localDebugHeader + "pre parseDocument(): value=<"
+ value.toString() + ">");
+ document = parseDocument(key, value.toString());
+ }
+
+ DBObserver.getInstance().loadDocument(this, record, document);
+ return document;
+ }
+ else {
+ return value.getData();
+ }
+ }
+
+ /**
+ * getFiler returns the low-level Filer instances underlying the
+ * Collection instance.
+ *
+ * @return The requested Filer
+ */
+ public final Filer getFiler() {
+ return filer;
+ }
+
+ /**
+ * getIndexer retrieves an Indexer by name.
+ *
+ * @param name The Indexer name
+ * @return The Indexer (or null)
+ */
+ public final Indexer getIndexer(String name) throws DBException {
+ checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
+ return indexManager.get(name);
+ }
+
+ /**
+ * return the IndexManager being used by this Collection.
+ *
+ * @return The IndexManager
+ */
+ public final IndexManager getIndexManager() throws DBException {
+ checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
+ return indexManager;
+ }
+
+ /**
+ * Return the MetaSystemCollection for the database containing this
+ * collection.
+ *
+ * @return MetaSystemCollection
+ */
+ private MetaSystemCollection getMetaSystemCollection() //throws
DBException
+ {
+ return getDatabase().getMetaSystemCollection();
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * getObject instantiates and returns an XMLSerializable object based on
the
+ * provided Key. Xindice takes care of instantiating the correct class,
but
+ * only if a class was registered with the Document in the first place.
+ *
+ * @param key The Document Key
+ * @return an Castable XMLSerializable Instance
+ */
+ public final XMLSerializable getObject(Object key) throws DBException {
+ String className = null;
+
+ Document doc = getDocument(key);
+
+ if (doc != null) {
+ NodeList childNodes = doc.getChildNodes();
+ int size = childNodes.getLength();
+ for (int i = 0; i < size; i++) {
+ Node n = childNodes.item(i);
+ if (n.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
n.getNodeName().equals(CLASSNAME)) {
+ className = n.getNodeValue().trim();
+ break;
+ }
+ }
+
+ if (className != null) {
+ try {
+ XMLSerializable obj = (XMLSerializable)
Class.forName(className).newInstance();
+ obj.streamFromXML(doc.getDocumentElement());
+ return obj;
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("No message", e);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * getParentCollection returns the parent Collection of this
+ * Collection.
+ *
+ * @return The parent Collection (or null)
+ */
+ public final Collection getParentCollection() throws DBException {
+ return parent;
+ }
+
+ /**
+ * getQueryEngine returns the Database's Query Engine
+ *
+ * @return The Query Engine
+ */
+ public QueryEngine getQueryEngine() throws DBException {
+ return getDatabase().getQueryEngine();
+ }
+
+ /**
+ * getSymbols returns the SymbolTable in use by this
+ * Collection.
+ *
+ * @return The Symbol Table
+ */
+ public final SymbolTable getSymbols() throws DBException {
+ return symbols;
+ }
+
+ /**
+ * getSystemCollection returns the System Collection.
+ *
+ * @return The System Collection
+ */
+ public SystemCollection getSystemCollection() throws DBException {
+ return getDatabase().getSystemCollection();
+ }
+
+ /**
+ * Insert a binary object into a Xindice Collection. A unique key
+ * is automatically generated. by which the binary object can be
+ * retrieved in the future. Note: because the key is automatically
+ * unique, this insert method will never cause a collision with an
+ * object already in the database.
+ *
+ * @param bytes The bytes making up the binary object to insert
+ * @return Key automatically generated for the binary object
+ * @throws DBException if inline-metadata is not enabled, or an
+ * error occurs while saving.
+ */
+ public Key insertBinary(byte[] bytes) throws DBException {
+
+ if (inlineMetaService == null) {
+ throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot
insert a binary resource in collection " + name + ": inline-metadata is not
enabled.");
+ }
+
+ Key key = createNewOID();
+ putBinary(key, bytes, true);
+
+ // update the meta information if necessary
+ updateCollectionMeta();
+
+ return key;
+ }
+
+ /**
+ * insertBinary inserts a new binary object into a Xindice Collection.
+ *
+ * @param docKey The document Key
+ * @param document The document to insert
+ * @throws DBException if inline-metadata is not enabled, the key is
+ * already in the database, or an error occurs while saving.
+ */
+ public void insertBinary(Object docKey, byte[] bytes) throws DBException
{
+
+ if (inlineMetaService == null) {
+ throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot
insert a binary resource in collection " + name + ": inline-metadata is not
enabled.");
+ }
+
+ putBinary(createNewKey(docKey), bytes, true);
+
+ // update the meta information if necessary
+ updateCollectionMeta();
+ }
+
+ /**
+ * insertDocument inserts a new Document into a Xindice Collection.
+ *
+ * @param document The Document
+ * @return The new Object Identifier
+ */
+ public final Key insertDocument(Document document) throws DBException {
+ Key key = createNewOID();
+ putDocument(key, document /*, true */
+ );
+ // update the meta information if necessary
+ updateCollectionMeta();
+ return key;
+ }
+
+ /**
+ * insertDocument inserts a new Document into a Xindice Collection.
+ *
+ * @param docKey The document Key
+ * @param document The document to insert
+ */
+ public final void insertDocument(Object docKey, Document document)
throws DBException {
+ putDocument(createNewKey(docKey), document /*, true */
+ );
+ // update the meta information if necessary
+ updateCollectionMeta();
+ }
+
+ /**
+ * insertObject inserts an XMLSerializable object into the Collection
based
+ * on the specified Key. Xindice takes care of associating the
+ * implementation class with the XMLSerializable object.
+ *
+ * @param key The Key to use
+ * @param obj The Object to insert
+ */
+ public final void insertObject(String key, XMLSerializable obj) throws
DBException {
+ putObject(createNewKey(key), obj /*, true */
+ );
+ }
+
+ /**
+ * insertObject inserts an XMLSerializable object into the Collection and
+ * returns a newly generated Key. Xindice takes care of associating the
+ * implementation class with the XMLSerializable object.
+ *
+ * @param obj The Object to insert
+ * @return The newly generated Key
+ */
+ public final Key insertObject(XMLSerializable obj) throws DBException {
+ Key key = createNewOID();
+ putObject(key, obj /*, true */
+ );
+ return key;
+ }
+
+ // META DATA RELATED DOCS
+ /**
+ * Returns whether or not meta data is enabled.
+ * @return boolean whether or not meta data is enabled.
+ */
+ public boolean isMetaEnabled() {
+ return getDatabase().isMetaEnabled();
+ }
+
+ public boolean isOpened() throws DBException {
+ return true;
+ }
+
+ /**
+ * listDocuments returns a list of all document keys stored by this
+ * collection.
+ *
+ * @return the list of document keys
+ */
+ public final String[] listDocuments() throws DBException {
+ // a collection in which you are unable to file documents will have
no filer
+ // (for example the root collection). Rather than throwing an
exception return
+ // a constant result (nothing)
+ if (null == filer) {
+ return EMPTY_STRING_ARRAY;
+ }
+ else {
+ RecordSet set = filer.getRecordSet();
+
+ // todo: what happens if the size if > than the size of an int.
+ // I'm pretty sure some sort of runtime exception will occur
+ // in the ArrayList.add method.
+
+ // give a hint to the size of the record set, saves on arraylist
array copies.
+ ArrayList temp = new ArrayList((int) filer.getRecordCount());
+
+ while (set.hasMoreRecords()) {
+ Key key = set.getNextKey();
+ temp.add(key.toString());
+ }
+
+ return (String[]) temp.toArray(new String[0]);
+ }
+ }
+
+ /**
+ * listIndexers returns a list of the currently registered Indexers
+ * as an array of String.
+ *
+ * @return The Indexer list
+ */
+ public final String[] listIndexers() throws DBException {
+ checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
+ return indexManager.list();
+ }
+
+ public final boolean open() throws DBException {
+ return true;
+ }
+
+ /**
+ * Turns an XML string into a parsed document and caches it.
+ *
+ * @param key The key to use when caching
+ * @param xml The string to parse
+ * @return A parsed DOM document or null if failure
+ */
+ private Document parseDocument(Key key, String xml) throws DBException {
+ Document doc = null;
+ try {
+ doc = DOMParser.toDocument(xml);
+
+ // Have to move it to Xindice DOM for XMLObject AutoLinking
+ byte[] b = DOMCompressor.Compress(doc, symbols);
+ doc = new DocumentImpl(b, symbols, new NodeSource(this, key));
+
+ if (documentCache != null)
+ documentCache.putDocument(this, key, b);
+ }
+ catch (Exception e) {
+ throw new DBException(FaultCodes.COL_DOCUMENT_MALFORMED, "Unable
to parse Document", e);
+ }
+ return doc;
+ }
+
+ /*
+ * Lowest-level method for saving a binary entry into the database.
+ * Does not update non-inline metadata.
+ */
+ private void putBinary(Key key, byte[] bytes, boolean create) throws
DBException {
+
+ if (inlineMetaService == null) {
+ throw new DBException(FaultCodes.COL_CANNOT_STORE, "Cannot store
a binary resource in collection " + name + ": inline-metadata is not enabled");
+ }
+
+ if (!create) {
+ byte[] storedBytes = getBinary(key);
+ if (storedBytes == null) {
+ /*
+ * TODO: Do we need a COL_KEY_ALREADY_PRESENT fault so that
the caller can interpret this exception?
+ */
+ throw new DBException(
+ FaultCodes.COL_CANNOT_STORE,
+ "Error storing binary object with key '" + key + "': the
'create' flag is false and" + " the key is not in the database");
+ }
+ }
+
+ InlineMetaMap map = inlineMetaService.getEmptyMap();
+ map.put("type", ResourceTypeReader.BINARY);
+ Value value = inlineMetaService.createValue(map, bytes, 0,
bytes.length);
+ filer.writeRecord(key, value);
+ }
+
+ /**
+ * This is the lowest-level method for storing a record into the backing
store.
+ * It does not update non-inline metadata.
+ */
+ private void putDocument(Key key, Document document) throws DBException {
+
+ String localDebugHeader = debugHeader() + "putDocument: docKey=<" +
key.toString() + ">: ";
+
+ log.debug(localDebugHeader + "document=<" +
TextWriter.toString(document).toString() + ">");
+
+ checkFiler(FaultCodes.COL_NO_FILER);
+
+ if (document instanceof DBDocument) {
+ // This is a shitty shitty hack... Kill immediately
+ DBDocument dbDoc = (DBDocument) document;
+ if (dbDoc.getSource() == null)
+ dbDoc.setSource(new NodeSource(this, key));
+ }
+
+ /*
+ * The possibilities are restricted because only XML
+ * is handled by this method. There are only a few
+ * pieces of information that need to be constructed:
+ * 1) the xindice DOM document is needed for all XML objects, as
+ * it is handed to the IndexManager and the DBObserver.
+ * 2) the packed document, if this is a compressed XML object,
+ * is needed for the cache and the BTree (via the Value
object).
+ * 3) the string-converted-to-utf-8 bytes, if this is a
non-compressed
+ * XML object, is needed for the BTree (via the Value object).
+ * 4) A Value object, with a header if headers are enabled, and
+ * otherwise without headers, for the BTree.
+ */
+
+ byte[] packedDocument = null;
+ byte[] utf8Document = null;
+
+ if (compressed) {
+ try {
+
+ packedDocument = DOMCompressor.Compress(document, symbols);
+ log.debug(localDebugHeader + "length=" +
packedDocument.length);
+
+ // Why must it be re-created?
+ document = new DocumentImpl(packedDocument, symbols, new
NodeSource(this, key));
+
+ log.debug(localDebugHeader + "packedDocument: length=" +
packedDocument.length + " document=<" + TextWriter.toString(document) + ">");
+ }
+ catch (Exception e) {
+ throw new DBException(FaultCodes.COL_CANNOT_STORE,
localDebugHeader + "Error compressing Document '" + key + "'", e);
+ }
+ }
+ else {
+ try {
+ utf8Document =
TextWriter.toString(document).getBytes("utf-8");
+ log.debug(localDebugHeader + "utf8Document: length=" +
utf8Document.length + " document=<" + new String(utf8Document, "utf-8") + ">");
+ }
+ catch (UnsupportedEncodingException e) {
+ throw new DBException(FaultCodes.GEN_FATAL_ERROR, "utf-8
encoding not supported", e);
+ }
+ }
+
+ /*
+ * TODO: Can this be moved into the if(compressed) block?
+ */
+ flushSymbolTable();
+
+ // Temporary until insert and update are separate
+ Document oldDoc = getDocument(key);
+ if (oldDoc != null) {
+ indexManager.removeDocument(key, oldDoc);
+ }
+ indexManager.addDocument(key, document);
+
+ /*
+ * Construct the Value object that is stored in the BTree.
+ */
+ Value value;
+ if (inlineMetaService == null) {
+ if (compressed) {
+ value = new Value(packedDocument);
+ }
+ else {
+ value = new Value(utf8Document);
+ }
+ }
+ else {
+ InlineMetaMap map = inlineMetaService.getEmptyMap();
+ map.put("type", ResourceTypeReader.XML);
+ if (compressed) {
+ value = inlineMetaService.createValue(map, packedDocument,
0, packedDocument.length);
+ }
+ else {
+ value = inlineMetaService.createValue(map, utf8Document, 0,
utf8Document.length);
+ }
+ }
+ filer.writeRecord(key, value);
+
+ // Cache Stuff
+ if (documentCache != null) {
+ if (compressed)
+ documentCache.putDocument(this, key, packedDocument);
+ else
+ documentCache.putDocument(this, key, document);
+ }
+
+ DBObserver.getInstance().putDocument(this, key, document, oldDoc ==
null);
+ }
+
+ private void putObject(Key key, XMLSerializable obj) throws DBException {
+
+ String localDebugHeader = debugHeader() + "putObject: key=<" +
key.toString() + ">: ";
+
+ Document doc = new DocumentImpl();
+ ProcessingInstruction pi =
doc.createProcessingInstruction(CLASSNAME, obj.getClass().getName());
+ doc.appendChild(pi);
+ Element elem = obj.streamToXML(doc);
+ log.debug(localDebugHeader + "elem=<" + TextWriter.toString(elem) +
">");
+ doc.appendChild(elem);
+ putDocument(key, doc /*, create */
+ );
+ }
+
+ /**
+ * queryCollection performs a query against the current collection
+ * using the specified style and query String.
+ *
+ * @param style The query style to use (ex: XPath)
+ * @param query The query to execute
+ * @param nsMap The namespace Map (if any)
+ * @return The resulting NodeSet
+ */
+ public final NodeSet queryCollection(String style, String query,
NamespaceMap nsMap) throws DBException {
+ // a collection in which you are unable to file documents will have
no filer
+ // (for example the root collection). Rather than throwing an
exception return
+ // a constant result (nothing)
+ return null == filer ? EMPTY_NODESET : getQueryEngine().query(this,
style, query, nsMap, null);
+ }
+
+ /**
+ * queryDocument performs a query against a single Document using
+ * the specified style, query string, and Document ID.
+ *
+ * @param style The query style to use (ex: XPath)
+ * @param query The query to execute
+ * @param nsMap The namespace Map (if any)
+ * @param key The Document to query
+ * @return The resulting NodeSet
+ */
+ public final NodeSet queryDocument(String style, String query,
NamespaceMap nsMap, Object key) throws DBException {
+ checkFiler(FaultCodes.QRY_STYLE_NOT_FOUND);
+ Key[] k = null;
+ if (key instanceof Key[])
+ k = (Key[]) key;
+ else
+ k = new Key[] { createNewKey(key)};
+ return getQueryEngine().query(this, style, query, nsMap, k);
+ }
+
+ /**
+ * remove removes an object from the Collection based on its Key,
+ * regardless of it's type.
+ *
+ * @param key The Object's Key
+ */
+ public final void remove(Object key) throws DBException {
+ checkFiler(FaultCodes.COL_NO_FILER);
+
+ Key objKey = createNewKey(key);
+
+ Document oldDoc = getDocument(objKey);
+ if (oldDoc != null)
+ indexManager.removeDocument(objKey, oldDoc);
+
+ if (documentCache != null)
+ documentCache.removeDocument(this, objKey);
+
+ if (!filer.deleteRecord(objKey))
+ throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND,
"Document Does Not Exist");
+
+ // update the meta for this collection if necessary
+ updateCollectionMeta();
+ // remove the document meta
+ if (isMetaEnabled()) {
+ getMetaSystemCollection().dropDocumentMeta(this,
objKey.toString());
+ }
+ DBObserver.getInstance().dropDocument(this, objKey);
+ }
+
+ protected final void setCanonicalName(String canonicalName) {
+ this.canonicalName = canonicalName;
+
+ // Calculate The OID Template
+ collection_id = Math.abs(canonicalName.hashCode());
+ StringBuffer sb = new
StringBuffer("00000000000000000000000000000000");
+ String host = Integer.toString(host_id, 16);
+ String collection = Integer.toString(collection_id, 16);
+ sb.insert(8 - host.length(), host);
+ sb.insert(16 - collection.length(), collection);
+ sb.setLength(32);
+ oidTemplate = sb.toString();
+ }
+
+ /**
+ * Reset the metadata object for this collection.
+ * @param meta the Metadata to use
+ */
+ public void setCollectionMeta(MetaData meta) throws DBException {
+ if (!isMetaEnabled()) {
+ if (log.isWarnEnabled()) {
+ log.warn("Meta information requested but not enabled in
config!");
+ }
+ return;
+ }
+ if (null != meta) {
+ if (meta.getType() != MetaData.COLLECTION)
+ throw new DBException(FaultCodes.GEN_UNKNOWN, "Mismatch type
of meta data for collection " + getCanonicalName());
+
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ metacol.setCollectionMeta(this, meta);
+ }
+ }
+
+ protected final void setCollectionRoot(File collectionRoot) {
+ this.collectionRoot = collectionRoot;
+ if (!collectionRoot.exists())
+ collectionRoot.mkdirs();
+ }
+
+ public void setConfig(Configuration config) throws XindiceException {
+ super.setConfig(config);
+
+ name = config.getAttribute(NAME);
+ compressed = config.getBooleanAttribute(COMPRESSED, true);
+
+ /*
+ * If inline metadata is desired, get an InlineMetaService object.
+ */
+ if (config.getBooleanAttribute(INLINE_METADATA, false)) {
+ inlineMetaService = new InlineMetaService();
+ }
+
+ /*
+ * Wait to set up the local debug header until everything needed
+ * by debugHeader() is complete!
+ */
+ String localDebugHeader = debugHeader() + "setConfig: ";
+
+ if (inlineMetaService == null) {
+ log.debug(localDebugHeader + "inline metadata DISABLED");
+ }
+ else {
+ log.debug(localDebugHeader + "inline metadata ENABLED");
+ }
+
+ if (parent != null) {
+ setCanonicalName(parent.getCanonicalName() + '/' + name);
+ log.debug(localDebugHeader + "canonical name=<" +
getCanonicalName() + ">");
+ setCollectionRoot(new File(parent.getCollectionRoot(), name));
+ log.debug(localDebugHeader + "collection root=<" +
getCollectionRoot().toString() + ">");
+ }
+
+ if (config.getBooleanAttribute(CACHE, true))
+ documentCache = getDatabase().getDocumentCache();
+
+ // If no Filer is defined, skip Symbols and Indexes
+ Configuration filerConfig = config.getChild(FILER);
+ if (filerConfig != null) {
+ log.debug(localDebugHeader + "have filer config...");
+
+ // Symbol Table Setup
+ Configuration symConfig = config.getChild(SYMBOLS);
+ internalSymbols = (symConfig != null);
+ if (internalSymbols) {
+ log.debug(localDebugHeader + "have internal symbols <" +
TextWriter.toString(symConfig.getElement()) + ">");
+ try {
+ symbols = new SymbolTable(symConfig.getElement());
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error building symbol table from internal
symbols", e);
+ }
+ }
+ }
+ else {
+ log.debug(localDebugHeader + "no internal symbols...");
+ try {
+ symbols = getSystemCollection().loadSymbols(this);
+ log.debug(localDebugHeader + "loaded symbols from system
collection <" + TextWriter.toString(symbols.streamToXML(new DocumentImpl())) +
">");
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error building symbol table from system
collection...", e);
+ }
+ }
+ }
+
+ String className = filerConfig.getAttribute(CLASS);
+ log.debug(localDebugHeader + "file class=<" + className + ">");
+ try {
+ filer = (Filer) Class.forName(className).newInstance();
+ // filer.setCollection(this);
+ filer.setLocation(getCollectionRoot(), getName());
+ filer.setConfig(filerConfig);
+ if (!filer.exists())
+ filer.create();
+ filer.open();
+ }
+ catch (Exception e) {
+ if (log.isWarnEnabled()) {
+ log.warn("Filer '" + className + "' not available", e);
+ }
+ }
+
+ // Index Manager
+ try {
+ indexManager = new IndexManager(this);
+ Configuration idxConfig = config.getChild(INDEXES, true);
+ indexManager.setConfig(idxConfig);
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("No message", e);
+ }
+ }
+ }
+
+ super.setConfig(config);
+
+ // observer
+ DBObserver.getInstance().setCollectionConfig(this, config);
+ }
+
+ /**
+ * setDocument overwrites/updates an existing Document in a
+ * Xindice Collection.
+ *
+ * @param docKey The Document Key
+ * @param document The Document
+ */
+ public final void setDocument(Object docKey, Document document) throws
DBException {
+ putDocument(createNewKey(docKey), document /*, false */
+ );
+ // update the meta for this document
+ updateDocumentMeta(docKey.toString());
+ }
+
+ /**
+ * Set the metadata associated with a document within this collection.
+ *
+ * @param id the document name
+ * @param meta the metadata object to be used.
+ */
+ public void setDocumentMeta(String id, MetaData meta) throws DBException
{
+ if (!isMetaEnabled()) {
+ if (log.isWarnEnabled()) {
+ log.warn("Meta information requested but not enabled in
config!");
+ }
+ return;
+ }
+ Document doc = getDocument(id);
+ if (null == doc)
+ throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND,
"Document " + id + " does not exist");
+
+ if (null != meta) {
+ if (meta.getType() == MetaData.UNKNOWN || meta.getType() ==
MetaData.COLLECTION)
+ throw new DBException(FaultCodes.GEN_UNKNOWN, "Mismatch type
of meta data for document " + getCanonicalDocumentName(id));
+
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ metacol.setDocumentMeta(this, id, meta);
+ }
+ }
+
+ /**
+ * @param string
+ */
+ protected void setName(String string) {
+ name = string;
+ }
+
+ /**
+ * setObject sets an XMLSerializable object in the Collection based on
the
+ * provided Key. Xindice takes care of associating the implementation
class
+ * with the XMLSerializable object.
+ *
+ * @param key The Key to use
+ * @param obj The Object to set
+ */
+ public final void setObject(Object key, XMLSerializable obj) throws
DBException {
+ putObject(createNewKey(key), obj /*, false */
+ );
+ }
+
+ /**
+ * update the modified time of this collection when appropriate
+ */
+ protected void updateCollectionMeta() {
+ // update the meta data if necessary
+ if (isMetaEnabled()) {
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ MetaData meta = null;
+ try {
+ meta = metacol.getCollectionMeta(this);
+ }
+ catch (DBException e) {
+ // something strange has happened.. can't get the
+ // meta data for this collection
+ if (log.isWarnEnabled())
+ log.warn("Error fetching collection meta. " + e);
+ return;
+ }
+
+ if (log.isInfoEnabled())
+ log.info("Updating modified time for this collection's
meta");
+ long now = System.currentTimeMillis();
+ if (null == meta) {
+ meta = new MetaData(MetaData.COLLECTION, getCanonicalName(),
now, now);
+ }
+ else {
+ // this collection already has a meta. so update its
modified time.
+ meta.setContext(0, now);
+ }
+ try {
+ metacol.setCollectionMeta(this, meta);
+ }
+ catch (DBException e) {
+ if (log.isWarnEnabled())
+ log.warn("Error setting the collection meta. " + e);
+ return;
+ }
+ }
+ }
+
+ /**
+ * update the modified time of this document when appropriate
+ */
+ protected void updateDocumentMeta(String id) throws DBException {
+ // update the meta data if necessary
+ if (!isMetaEnabled())
+ return;
+
+ Document doc = getDocument(id);
+ if (null == doc)
+ throw new DBException(FaultCodes.COL_DOCUMENT_NOT_FOUND,
"Document " + id + " does not exist");
+
+ MetaSystemCollection metacol = getMetaSystemCollection();
+ MetaData meta = metacol.getDocumentMeta(this, id);
+
+ String path = getCanonicalDocumentName(id);
+
+ /*
+ TimeRecord rec = null;
+ if( null == meta || !meta.hasContext() )
+ rec = getDatabase().getTime(path);
+
+ long created = (null != rec) ? rec.getCreatedTime() :
System.currentTimeMillis();
+ long modified = (null != rec) ? rec.getModifiedTime() :
System.currentTimeMillis();
+ */
+
+ // this is wrong.. but it should work for now...
+ long created = System.currentTimeMillis();
+ long modified = System.currentTimeMillis();
+
+ if (null == meta) {
+ meta = new MetaData(MetaData.DOCUMENT, path, created, modified);
+ }
+ else if (!meta.hasContext()) {
+ meta.setContext(created, modified);
+ }
+ else {
+ meta.setContext(0, modified);
+ }
+ metacol.setDocumentMeta(this, id, meta);
+ }
}
1.13 +94 -100
xml-xindice/java/src/org/apache/xindice/core/SystemCollection.java
Index: SystemCollection.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/SystemCollection.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- SystemCollection.java 11 Dec 2002 00:22:56 -0000 1.12
+++ SystemCollection.java 14 Jul 2003 19:07:15 -0000 1.13
@@ -59,15 +59,13 @@
* $Id$
*/
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.xindice.util.Configuration;
import org.apache.xindice.xml.SymbolTable;
import org.apache.xindice.xml.SymbolTableSymbols;
import org.apache.xindice.xml.dom.DOMParser;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.w3c.dom.*;
+import org.w3c.dom.Document;
/**
* SystemCollection represents the System Collection. Beyond
@@ -77,98 +75,94 @@
public final class SystemCollection extends Collection {
- public static final String SYSCOL = "system";
-
- public static final String SYMBOLS = "SysSymbols";
- public static final String OBJECTS = "SysObjects";
- public static final String CONFIGS = "SysConfig";
- public static final String USERS = "SysUsers";
- public static final String GROUPS = "SysGroups";
- public static final String ACCESS = "SysAccess";
-
- private static Log log = LogFactory.getLog("org.apache.xindice.core");
-
- public SystemCollection(Database db) {
- super(db);
- }
-
- void init() throws DBException {
- // Bootstrap the System Collection
-
- String SysCol =
- "<collection name=\""+SYSCOL+"\">"
-
- // System Collections
- + " <collections>"
-
- // Symbol Tables Collection
- + " <collection name=\""+SYMBOLS+"\" compressed=\"true\">"
- + " <filer class=\"org.apache.xindice.core.filer.BTreeFiler\"
/>"
- // Textual Representation of Hard-coded Symbol Table
- + SymbolTableSymbols.getDefinition()
- + " </collection>"
-
- // System Configuration Collection
- + " <collection name=\""+CONFIGS+"\" compressed=\"false\">"
- + " <filer class=\"org.apache.xindice.core.filer.BTreeFiler\"
/>"
- + " </collection>"
-
- + " </collections>"
- + "</collection>";
-
- try {
- Document sysDoc = DOMParser.toDocument(SysCol);
- Configuration sysCfg = new Configuration(sysDoc, false);
- setConfig(sysCfg);
- }
- catch ( Exception e ) {
- if (log.isFatalEnabled()) {
- log.fatal("FATAL ERROR: Generating System Collection
'"+SYSCOL+"'", e);
- }
- System.exit(1);
- }
- }
-
- private String getSymbolTableName(Collection col) {
- String name = col.getCanonicalName();
- int idx = name.indexOf('/', 1);
- name = name.substring(idx+1);
- return name.replace('/', '_');
- }
-
- /**
- * loadSymbols retrieves the SymbolTable for the specified Collection.
- *
- * @param collection The Collection whose SymbolTable is required
- * @return The requested SymbolTable
- */
- public SymbolTable loadSymbols(Collection collection) throws DBException
{
- String name = getSymbolTableName(collection);
-
- Collection symCol = getCollection(SYMBOLS);
-
- SymbolTable symbols = (SymbolTable)symCol.getObject(name);
- if ( symbols == null ) {
- symbols = new SymbolTable();
- saveSymbols(collection, symbols);
- }
- return symbols;
- }
-
- /**
- * saveSymbols save the SymbolTable for the specified Collection.
- *
- * @param collection The Collection that owns the SymbolTable
- * @param symbols The SymbolTable
- */
- public void saveSymbols(Collection collection, SymbolTable symbols)
throws DBException {
- String name = getSymbolTableName(collection);
-
- Collection symCol = getCollection(SYMBOLS);
-
- if ( symbols != null ) {
- symCol.setObject(name, symbols);
- symbols.setDirty(false);
- }
- }
+ public static final String SYSCOL = "system";
+ public static final String SYMBOLS = "SysSymbols";
+ public static final String OBJECTS = "SysObjects";
+ public static final String CONFIGS = "SysConfig";
+ public static final String USERS = "SysUsers";
+ public static final String GROUPS = "SysGroups";
+ public static final String ACCESS = "SysAccess";
+ private static Log log = LogFactory.getLog("org.apache.xindice.core");
+
+ /**
+ * @param db
+ */
+ public SystemCollection(Database db) {
+ super(db);
+ }
+
+ void init() throws DBException {
+ // Bootstrap the System Collection
+
+ String SysCol = "<collection name=\"" + SYSCOL + "\">"
+ // System Collections
+ +" <collections>"
+ // Symbol Tables Collection
+ +" <collection name=\"" + SYMBOLS + "\"
compressed=\"true\">" + " <filer
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
+ // Textual Representation of Hard-coded Symbol Table
+ +SymbolTableSymbols.getDefinition() + " </collection>"
+ // System Configuration Collection
+ +" <collection name=\""
+ + CONFIGS
+ + "\" compressed=\"false\">"
+ + " <filer
class=\"org.apache.xindice.core.filer.BTreeFiler\" />"
+ + " </collection>"
+ + " </collections>"
+ + "</collection>";
+
+ try {
+ Document sysDoc = DOMParser.toDocument(SysCol);
+ Configuration sysCfg = new Configuration(sysDoc, false);
+ setConfig(sysCfg);
+ }
+ catch (Exception e) {
+ if (log.isFatalEnabled()) {
+ log.fatal("FATAL ERROR: Generating System Collection '" +
SYSCOL + "'", e);
+ }
+ System.exit(1);
+ }
+ }
+
+ private String getSymbolTableName(Collection col) {
+ String name = col.getCanonicalName();
+ int idx = name.indexOf('/', 1);
+ name = name.substring(idx + 1);
+ return name.replace('/', '_');
+ }
+
+ /**
+ * loadSymbols retrieves the SymbolTable for the specified Collection.
+ *
+ * @param collection The Collection whose SymbolTable is required
+ * @return The requested SymbolTable
+ */
+ public SymbolTable loadSymbols(Collection collection) throws DBException
{
+ String name = getSymbolTableName(collection);
+
+ Collection symCol = getCollection(SYMBOLS);
+
+ SymbolTable symbols = (SymbolTable) symCol.getObject(name);
+ if (symbols == null) {
+ symbols = new SymbolTable();
+ saveSymbols(collection, symbols);
+ }
+ return symbols;
+ }
+
+ /**
+ * saveSymbols save the SymbolTable for the specified Collection.
+ *
+ * @param collection The Collection that owns the SymbolTable
+ * @param symbols The SymbolTable
+ */
+ public void saveSymbols(Collection collection, SymbolTable symbols)
throws DBException {
+ String name = getSymbolTableName(collection);
+
+ Collection symCol = getCollection(SYMBOLS);
+
+ if (symbols != null) {
+ symCol.setObject(name, symbols);
+ symbols.setDirty(false);
+ }
+ }
}
1.11 +208 -193
xml-xindice/java/src/org/apache/xindice/core/CollectionManager.java
Index: CollectionManager.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/CollectionManager.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CollectionManager.java 26 Nov 2002 02:17:18 -0000 1.10
+++ CollectionManager.java 14 Jul 2003 19:07:15 -0000 1.11
@@ -77,196 +77,211 @@
*/
public class CollectionManager implements Configurable, Disposable {
- private static final String COLLECTIONS = "collections";
- private static final String COLLECTION = "collection";
- private static final String NAME = "name";
-
- private static Log log = LogFactory.getLog("org.apache.xindice.core");
-
- private static final String[] EmptyStrings = new String[0];
-
- protected Map collections = new HashMap(); // Collection
-
- protected Configuration config = null;
-
- protected CollectionManager() {
- }
-
- public void setConfig(Configuration config) throws XindiceException {
- this.config = config;
-
- Configuration colConfig = config.getChild(COLLECTIONS);
- if ( colConfig != null ) {
- colConfig.processChildren(COLLECTION,
- new ConfigurationCallback() {
- public void process(Configuration cfg) throws
XindiceException {
- // check for an existing Collection by name and, if found,
skip creating a new Collection
- // else, create a new child Collection, configure it an
add it
- // if the Collection already exists in our collections
list,
- // creating a new one will cause the old one to be
discarded
- // while holding open file handles, etc.
- Collection col =
(Collection)collections.get(cfg.getAttribute(NAME));
- if(col == null)
- {
- col = new
Collection((Collection)CollectionManager.this);
- col.setConfig(cfg);
- collections.put(col.getName(), col);
- }
- // else, assume col is configured elsewhere...
- // I'm not sure this should be happening, but it does
- // it is not safe to call col.setConfig again since it
does a bunch
- // of stuff (like creating a new Filer and overwriting the
existing one, etc.)
- }
- });
- }
- }
-
- public Configuration getConfig() {
- return config;
- }
-
- /**
- * getCollection retrieves a Collection by name.
- *
- * @param path The Collection path
- * @return The Collection (or null)
- */
- public Collection getCollection(String path) throws DBException {
- if ( path.indexOf("/") != -1 ) {
- CollectionManager cm = this;
- StringTokenizer st = new StringTokenizer(path, "/");
- while ( cm != null && st.hasMoreTokens()) {
- path = st.nextToken();
- cm = (CollectionManager)cm.collections.get(path);
- }
- return (Collection)cm;
- }
- else
- return (Collection)collections.get(path);
- }
-
- /**
- * listCollections retrieves a list of Collections as an array of
- * Strings.
- *
- * @return The Collection list
- */
- public final String[] listCollections() throws DBException {
- return (String[]) collections.keySet().toArray(EmptyStrings);
- }
-
- /**
- * Returns number of child collections
- *
- * @return number of collections
- */
- public final long countCollections() throws DBException {
- return (long) collections.size();
- }
-
- /**
- * dropCollection physically removes the specified Collection and any
- * associated system resources that the Collection uses.
- *
- * @param collection The Collection to drop
- * @return Whether or not the Collection was dropped
- */
- public boolean dropCollection(Collection collection) throws DBException {
- if ( collection == null )
- throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND,
"Collection Value Null");
-
- Collection cm = collection.getParentCollection();
-
- if ( cm == null )
- throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You Cannot Drop
The Database");
-
- if ( cm != this )
- return cm.dropCollection(collection);
- else {
- final String name = collection.getName();
- boolean dropped = collection.drop();
- if ( dropped ) {
- collections.remove(name);
- Configuration colConfig = config.getChild(COLLECTIONS);
- colConfig.processChildren(COLLECTION,
- new ConfigurationCallback() {
- public void process(Configuration cfg) {
- try {
- if ( cfg.getAttribute(NAME).equals(name) )
- cfg.delete();
- }
- catch ( Exception e ) {
- if (log.isDebugEnabled()) {
- log.debug("No message", e);
- }
- }
- }
- });
- }
- return dropped;
- }
- }
-
- /**
- * createCollection creates a new Collection object and any associated
- * system resources that the Collection will need.
- *
- * @param path The relative path of the Collection
- * @param cfg The Collection's configuration
- * @return The newly created Collection
- */
- public Collection createCollection(String path, Configuration cfg)
- throws DBException {
- if ( path.indexOf("/") != -1 ) {
- CollectionManager cm = this;
- StringTokenizer st = new StringTokenizer(path, "/");
- while ( cm != null && st.hasMoreTokens()) {
- path = st.nextToken().trim();
- if ( path.length() == 0 )
- continue;
- if ( st.hasMoreTokens() )
- cm = (CollectionManager)cm.collections.get(path);
- else
- return cm.createCollection(path, cfg);
- }
- throw new DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Parent
Collection '"+path+"' doesn't exist");
- }
-
- Collection collection = null;
-
- if ( CollectionManager.this instanceof Database )
- collection = new Collection((Database)CollectionManager.this);
- else
- collection = new Collection((Collection)CollectionManager.this);
-
- try {
- // Do a name check to see if all is well
- String n = cfg.getAttribute(NAME);
- if ( n == null || n.trim().equals("") )
- throw new DBException(FaultCodes.COL_CANNOT_CREATE, "No name
specified");
-
- if ( getCollection(n) != null )
- throw new DBException(FaultCodes.COL_DUPLICATE_COLLECTION,
"Duplicate Collection '"+n+"'");
-
- Configuration colConfig = this.config.getChild(COLLECTIONS, true);
- colConfig.add(cfg);
-
- collection.setConfig(cfg);
- collection.create();
- collections.put(n, collection);
- if (log.isInfoEnabled()) {
- log.info("Created a new collection named '"+n+"'");
- }
- }
- catch ( DBException e ) {
- throw e;
- }
- catch ( Exception e ) {
- throw new DBException(FaultCodes.COL_CANNOT_CREATE, "Error Creating
Collection '"+path+"'", e);
- }
- return collection;
- }
-
- public void dispose() {
- }
+ private static final String COLLECTION = "collection";
+ private static final String COLLECTIONS = "collections";
+ private static final String[] EmptyStrings = new String[0];
+ private static Log log = LogFactory.getLog("org.apache.xindice.core");
+ private static final String NAME = "name";
+ private Map collections = new HashMap(); // Collection
+ private Configuration config = null;
+
+ protected CollectionManager() {}
+
+ /**
+ *
+ * @param collection
+ */
+ protected void addCollection(Collection collection){
+
+ this.collections.put(collection.getName(), collection);
+ }
+
+ /**
+ * Returns number of child collections
+ *
+ * @return number of collections
+ */
+ public final long countCollections() throws DBException {
+ return (long) collections.size();
+ }
+
+ /**
+ * createCollection creates a new Collection object and any associated
+ * system resources that the Collection will need.
+ *
+ * @param path The relative path of the Collection
+ * @param cfg The Collection's configuration
+ * @return The newly created Collection
+ */
+ public Collection createCollection(String path, Configuration cfg)
throws DBException {
+ if (path.indexOf("/") != -1) {
+ CollectionManager cm = this;
+ StringTokenizer st = new StringTokenizer(path, "/");
+ while (cm != null && st.hasMoreTokens()) {
+ path = st.nextToken().trim();
+ if (path.length() == 0)
+ continue;
+ if (st.hasMoreTokens())
+ cm = (CollectionManager)
cm.collections.get(path);
+ else
+ return cm.createCollection(path, cfg);
+ }
+ throw new
DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Parent Collection '" + path +
"' doesn't exist");
+ }
+
+ Collection collection = null;
+
+ if (CollectionManager.this instanceof Database)
+ collection = new Collection((Database)
CollectionManager.this);
+ else
+ collection = new Collection((Collection)
CollectionManager.this);
+
+ try {
+ // Do a name check to see if all is well
+ String n = cfg.getAttribute(NAME);
+ if (n == null || n.trim().equals(""))
+ throw new
DBException(FaultCodes.COL_CANNOT_CREATE, "No name specified");
+
+ if (getCollection(n) != null)
+ throw new
DBException(FaultCodes.COL_DUPLICATE_COLLECTION, "Duplicate Collection '" + n +
"'");
+
+ Configuration colConfig =
this.config.getChild(COLLECTIONS, true);
+ colConfig.add(cfg);
+
+ collection.setConfig(cfg);
+ collection.create();
+ collections.put(n, collection);
+ if (log.isInfoEnabled()) {
+ log.info("Created a new collection named '" + n
+ "'");
+ }
+ }
+ catch (DBException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new DBException(FaultCodes.COL_CANNOT_CREATE,
"Error Creating Collection '" + path + "'", e);
+ }
+ return collection;
+ }
+
+ /**
+ * @see org.apache.xindice.util.Disposable#dispose()
+ */
+ public void dispose() {}
+
+ /**
+ * dropCollection physically removes the specified Collection and any
+ * associated system resources that the Collection uses.
+ *
+ * @param collection The Collection to drop
+ * @return Whether or not the Collection was dropped
+ */
+ public boolean dropCollection(Collection collection) throws DBException
{
+ if (collection == null)
+ throw new
DBException(FaultCodes.COL_COLLECTION_NOT_FOUND, "Collection Value Null");
+
+ Collection cm = collection.getParentCollection();
+
+ if (cm == null)
+ throw new DBException(FaultCodes.DBE_CANNOT_DROP, "You
Cannot Drop The Database");
+
+ if (cm != this)
+ return cm.dropCollection(collection);
+ else {
+ final String name = collection.getName();
+ boolean dropped = collection.drop();
+ if (dropped) {
+ collections.remove(name);
+ Configuration colConfig =
config.getChild(COLLECTIONS);
+ colConfig.processChildren(COLLECTION, new
ConfigurationCallback() {
+ public void process(Configuration cfg) {
+ try {
+ if
(cfg.getAttribute(NAME).equals(name))
+ cfg.delete();
+ }
+ catch (Exception e) {
+ if
(log.isDebugEnabled()) {
+ log.debug("No
message", e);
+ }
+ }
+ }
+ });
+ }
+ return dropped;
+ }
+ }
+
+ /**
+ * getCollection retrieves a Collection by name.
+ *
+ * @param path The Collection path
+ * @return The Collection (or null)
+ */
+ public Collection getCollection(String path) throws DBException {
+ if (path.indexOf("/") != -1) {
+ CollectionManager cm = this;
+ StringTokenizer st = new StringTokenizer(path, "/");
+ while (cm != null && st.hasMoreTokens()) {
+ path = st.nextToken();
+ cm = (CollectionManager)
cm.collections.get(path);
+ }
+ return (Collection) cm;
+ }
+ else
+ return (Collection) collections.get(path);
+ }
+
+ /**
+ * @return
+ */
+ protected Map getCollections() {
+ return this.collections;
+ }
+
+ /**
+ * @see org.apache.xindice.util.Configurable#getConfig()
+ */
+ public Configuration getConfig() {
+ return config;
+ }
+
+ /**
+ * listCollections retrieves a list of Collections as an array of
+ * Strings.
+ *
+ * @return The Collection list
+ */
+ public final String[] listCollections() throws DBException {
+ return (String[]) collections.keySet().toArray(EmptyStrings);
+ }
+
+ /**
+ * @see
org.apache.xindice.util.Configurable#setConfig(org.apache.xindice.util.Configuration)
+ */
+ public void setConfig(Configuration config) throws XindiceException {
+ this.config = config;
+
+ Configuration colConfig = config.getChild(COLLECTIONS);
+ if (colConfig != null) {
+ colConfig.processChildren(COLLECTION, new
ConfigurationCallback() {
+ public void process(Configuration cfg) throws
XindiceException {
+ // check for an existing Collection by
name and, if found, skip creating a new Collection
+ // else, create a new child Collection,
configure it an add it
+ // if the Collection already exists in
our collections list,
+ // creating a new one will cause the
old one to be discarded
+ // while holding open file handles, etc.
+ Collection col = (Collection)
collections.get(cfg.getAttribute(NAME));
+ if (col == null) {
+ col = new
Collection((Collection) CollectionManager.this);
+ col.setConfig(cfg);
+ collections.put(col.getName(),
col);
+ }
+ // else, assume col is configured
elsewhere...
+ // I'm not sure this should be
happening, but it does
+ // it is not safe to call col.setConfig
again since it does a bunch
+ // of stuff (like creating a new Filer
and overwriting the existing one, etc.)
+ }
+ });
+ }
+ }
}
1.11 +177 -179
xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java
Index: DatabaseImpl.java
===================================================================
RCS file:
/home/cvs/xml-xindice/java/src/org/apache/xindice/client/xmldb/embed/DatabaseImpl.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DatabaseImpl.java 10 Jul 2003 21:42:48 -0000 1.10
+++ DatabaseImpl.java 14 Jul 2003 19:07:16 -0000 1.11
@@ -56,7 +56,6 @@
*
* $Id$
*/
-
package org.apache.xindice.client.xmldb.embed;
import org.apache.xindice.client.xmldb.CommonConfigurable;
@@ -88,184 +87,183 @@
*/
public class DatabaseImpl extends CommonConfigurable implements
org.xmldb.api.base.Database {
- private static Log log =
LogFactory.getLog("org.apache.xindice.client.embed");
-
- /* prefix used to denote XML:DB URI's that should use this driver */
- static String DRIVER_NAME = "xindice-embed";
+ private static Log log =
LogFactory.getLog("org.apache.xindice.client.embed");
- /* XML:DB conformance level of this driver */
- private String CONFORMANCE_LEVEL = "0";
+ /** prefix used to denote XML:DB URI's that should use this driver */
+ public static final String DRIVER_NAME = "xindice-embed";
- protected Database db;
-
- /**
- * Creates new <code>DatabaseImpl</code> instance. The configuration is
- * loaded from the file defined in the PROP_XINDICE_CONFIGURATION system
- * variable.
- *
- * This is only a temporarly solution since the question of a new init
- * method is raised in the xmldb:api group. Another solution could be to
- * use the Configurable interface and only create the database when the
- * getCollection method is called.
- */
- public DatabaseImpl() throws FileNotFoundException, XindiceException {
-
- Configuration config = loadConfiguration();
- this.db = Database.getDatabase(config);
-
- if (null == this.db) {
- log.fatal("Unable to configure database");
-
- throw new XindiceException("Unable to configure
database");
- }
- else if (log.isInfoEnabled()) {
- log.info("Database name: '" + this.db.getName() + "'");
- }
- }
-
- protected Configuration loadConfiguration() throws
FileNotFoundException, XindiceException, ReadOnlyException {
- Configuration config;
- String configFile =
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
- if (configFile != null && !configFile.equals("")) {
- if (log.isInfoEnabled()) {
- log.info("Specified configuration file: '" +
configFile + "'");
- }
- FileInputStream configXMLFile = new FileInputStream(new
File(configFile));
-
- config = new
Configuration(DOMParser.toDocument(configXMLFile), false);
- }
- else {
- if (log.isInfoEnabled()) {
- log.info("No configuration file specified,
going with the default configuration");
- }
- config = new
Configuration(DOMParser.toDocument(Xindice.DEFAULT_CONFIGURATION), false);
- }
-
- config = config.getChild("root-collection", false);
- return config;
- }
-
- /**
- * Determines whether this <code>Database</code> implementation can
handle
- * the URI. It should return true if the Database instance knows how to
- * handle the URI and false otherwise.
- *
- * @param uri the URI to check for.
- * @return true if the URI can be handled, false otherwise.
- * @exception XMLDBException with expected error codes.<br />
- * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
- * specific errors that occur.<br />
- * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid
format. <br />
- */
- public boolean acceptsURI(String uri) throws XMLDBException {
-
- return ((uri != null) && uri.startsWith(getName() + "://"));
- }
-
- /**
- * Retrieves a <code>Collection</code> instance based on the URI
provided
- * in the <code>uri</code> parameter. The format of the URI is defined
in the
- * documentation for DatabaseManager.getCollection().<p/>
- *
- * Authentication is handled via username and password however it is not
- * required that the database support authentication. Databases that do
not
- * support authentication MUST ignore the
- * <code>username</code> and <code>password</code> if those provided
are not
- * null.
- *
- * @param uri the URI to use to locate the collection.
- * @param password The password to use for authentication to the
database or
- * null if the database does not support authentication.
- * @return A <code>Collection</code> instance for the requested
collection or
- * null if the collection could not be found.
- * @return The <code>Collection</code> instance
- * @exception XMLDBException with expected error codes.<br />
- * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
- * specific errors that occur.<br />
- * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid
format. <br />
- * <code>ErrroCodes.PERMISSION_DENIED</code> If the
<code>username</code>
- * and <code>password</code> were not accepted by the database.
- */
- public Collection getCollection(String uri, String userName, String
password) throws XMLDBException {
- /* TODO: introduce authentication some day */
-
- if (!acceptsURI(uri)) {
- throw new XMLDBException(ErrorCodes.INVALID_URI,
"Invalid URL: " + uri);
- }
-
- /* Chop off driver prefix, and '://' */
- uri = uri.substring(getName().length() + 3);
-
- /* Extract host name & port, if present */
- int firstSlash = uri.indexOf('/');
- if (firstSlash == -1) {
- throw new XMLDBException(ErrorCodes.INVALID_URI);
- }
-
- String collPath = uri.substring(firstSlash);
-
- // The path must start with a /
- if (collPath.startsWith("/")) {
- // find the database name. We just skip the first slash
- int colIndex = collPath.indexOf('/', 1);
-
- // We assume there's no collection specified
- String dbName = collPath.substring(1);
- String colName = "/";
-
- // if colIndex isn't -1 then we need to pick out the db
and collection
- if (colIndex != -1) {
- dbName = collPath.substring(1, colIndex);
-
- // The rest of the name locates the collection
- colName = collPath.substring(colIndex);
- }
-
- if (colName.equals("")) {
- colName = "/";
- }
-
- try {
- return new CollectionImpl(db, colName);
- }
- catch (XMLDBException e) {
- if (e.errorCode ==
ErrorCodes.NO_SUCH_COLLECTION) {
- // per getCollection contract, return
null if not found
- return null;
- }
- throw e;
- }
- }
- else {
- throw new XMLDBException(ErrorCodes.INVALID_URI,
"Collection name must begin with a '/'");
- }
- }
-
- /**
- * Returns the prefix used in XML:DB to denote URI's that this driver
can
- * handle.
- *
- * @return the prefix driver name
- * @exception XMLDBException with expected error codes.<br />
- * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
- * specific errors that occur.<br />
- */
- public String getName() throws XMLDBException {
- return DRIVER_NAME;
- }
-
- /**
- * Returns the XML:DB API Conformance level for the implementation.
This can
- * be used by client programs to determine what functionality is
available to
- * them.
- *
- * @return the XML:DB API conformance level for this implementation.
- * @exception XMLDBException with expected error codes.<br />
- * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
- * specific errors that occur.<br />
- */
- public String getConformanceLevel() throws XMLDBException {
- return CONFORMANCE_LEVEL;
- }
+ /** XML:DB conformance level of this driver */
+ private String CONFORMANCE_LEVEL = "0";
+ private Database database;
+
+ /**
+ * Creates new <code>DatabaseImpl</code> instance. The configuration is
+ * loaded from the file defined in the PROP_XINDICE_CONFIGURATION system
+ * variable.
+ *
+ * This is only a temporarly solution since the question of a new init
+ * method is raised in the xmldb:api group. Another solution could be to
+ * use the Configurable interface and only create the database when the
+ * getCollection method is called.
+ */
+ public DatabaseImpl() throws FileNotFoundException, XindiceException {
+
+ Configuration config = loadConfiguration();
+ this.database = Database.getDatabase(config);
+
+ if (null == this.database) {
+ log.fatal("Unable to configure database");
+
+ throw new XindiceException("Unable to configure database");
+ }
+ else if (log.isInfoEnabled()) {
+ log.info("Database name: '" + this.database.getName() + "'");
+ }
+ }
+
+ protected Configuration loadConfiguration() throws
FileNotFoundException, XindiceException, ReadOnlyException {
+ Configuration config;
+ String configFile =
System.getProperty(Xindice.PROP_XINDICE_CONFIGURATION);
+ if (configFile != null && !configFile.equals("")) {
+ if (log.isInfoEnabled()) {
+ log.info("Specified configuration file: '" + configFile +
"'");
+ }
+ FileInputStream configXMLFile = new FileInputStream(new
File(configFile));
+
+ config = new Configuration(DOMParser.toDocument(configXMLFile),
false);
+ }
+ else {
+ if (log.isInfoEnabled()) {
+ log.info("No configuration file specified, going with the
default configuration");
+ }
+ config = new
Configuration(DOMParser.toDocument(Xindice.DEFAULT_CONFIGURATION), false);
+ }
+
+ config = config.getChild("root-collection", false);
+ return config;
+ }
+
+ /**
+ * Determines whether this <code>Database</code> implementation can
handle
+ * the URI. It should return true if the Database instance knows how to
+ * handle the URI and false otherwise.
+ *
+ * @param uri the URI to check for.
+ * @return true if the URI can be handled, false otherwise.
+ * @exception XMLDBException with expected error codes.<br />
+ * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
+ * specific errors that occur.<br />
+ * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid
format. <br />
+ */
+ public boolean acceptsURI(String uri) throws XMLDBException {
+
+ return ((uri != null) && uri.startsWith(getName() + "://"));
+ }
+
+ /**
+ * Retrieves a <code>Collection</code> instance based on the URI provided
+ * in the <code>uri</code> parameter. The format of the URI is defined
in the
+ * documentation for DatabaseManager.getCollection().<p/>
+ *
+ * Authentication is handled via username and password however it is not
+ * required that the database support authentication. Databases that do
not
+ * support authentication MUST ignore the
+ * <code>username</code> and <code>password</code> if those provided are
not
+ * null.
+ *
+ * @param uri the URI to use to locate the collection.
+ * @param password The password to use for authentication to the
database or
+ * null if the database does not support authentication.
+ * @return A <code>Collection</code> instance for the requested
collection or
+ * null if the collection could not be found.
+ * @return The <code>Collection</code> instance
+ * @exception XMLDBException with expected error codes.<br />
+ * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
+ * specific errors that occur.<br />
+ * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid
format. <br />
+ * <code>ErrroCodes.PERMISSION_DENIED</code> If the
<code>username</code>
+ * and <code>password</code> were not accepted by the database.
+ */
+ public Collection getCollection(String uri, String userName, String
password) throws XMLDBException {
+ /* TODO: introduce authentication some day */
+
+ if (!acceptsURI(uri)) {
+ throw new XMLDBException(ErrorCodes.INVALID_URI, "Invalid URL: "
+ uri);
+ }
+
+ /* Chop off driver prefix, and '://' */
+ uri = uri.substring(getName().length() + 3);
+
+ /* Extract host name & port, if present */
+ int firstSlash = uri.indexOf('/');
+ if (firstSlash == -1) {
+ throw new XMLDBException(ErrorCodes.INVALID_URI);
+ }
+
+ String collPath = uri.substring(firstSlash);
+
+ // The path must start with a /
+ if (collPath.startsWith("/")) {
+ // find the database name. We just skip the first slash
+ int colIndex = collPath.indexOf('/', 1);
+
+ // We assume there's no collection specified
+ String dbName = collPath.substring(1);
+ String colName = "/";
+
+ // if colIndex isn't -1 then we need to pick out the db and
collection
+ if (colIndex != -1) {
+ dbName = collPath.substring(1, colIndex);
+
+ // The rest of the name locates the collection
+ colName = collPath.substring(colIndex);
+ }
+
+ if (colName.equals("")) {
+ colName = "/";
+ }
+
+ try {
+ return new CollectionImpl(database, colName);
+ }
+ catch (XMLDBException e) {
+ if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
+ // per getCollection contract, return null if not found
+ return null;
+ }
+ throw e;
+ }
+ }
+ else {
+ throw new XMLDBException(ErrorCodes.INVALID_URI, "Collection
name must begin with a '/'");
+ }
+ }
+
+ /**
+ * Returns the prefix used in XML:DB to denote URI's that this driver can
+ * handle.
+ *
+ * @return the prefix driver name
+ * @exception XMLDBException with expected error codes.<br />
+ * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
+ * specific errors that occur.<br />
+ */
+ public String getName() throws XMLDBException {
+ return DRIVER_NAME;
+ }
+
+ /**
+ * Returns the XML:DB API Conformance level for the implementation. This
can
+ * be used by client programs to determine what functionality is
available to
+ * them.
+ *
+ * @return the XML:DB API conformance level for this implementation.
+ * @exception XMLDBException with expected error codes.<br />
+ * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor
+ * specific errors that occur.<br />
+ */
+ public String getConformanceLevel() throws XMLDBException {
+ return CONFORMANCE_LEVEL;
+ }
}