Author: vgritsenko
Date: Wed Aug 22 17:40:57 2007
New Revision: 568786
URL: http://svn.apache.org/viewvc?rev=568786&view=rev
Log:
implemented support for read only symbol tables.
refactor collection to take advantage of that.
catch read only exception, propagate as appropriate.
javadoc.
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/Collection.java
xml/xindice/trunk/java/src/org/apache/xindice/core/SystemCollection.java
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/DocumentHandler.java
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/IndexPattern.java
xml/xindice/trunk/java/src/org/apache/xindice/core/query/XPathQueryResolver.java
xml/xindice/trunk/java/src/org/apache/xindice/xml/SymbolTable.java
xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DOMCompressor.java
xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/SymbolTableTest.java
Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/Collection.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/Collection.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/Collection.java
(original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/Collection.java Wed Aug
22 17:40:57 2007
@@ -218,7 +218,6 @@
private String oidTemplate;
private long documentId;
- private boolean internalSymbols;
private SymbolTable symbols;
private File collectionRoot;
@@ -296,6 +295,7 @@
*
* @param config The Indexer's configuration
* @return The newly created Indexer
+ * @throws DBException if operation failed
*/
public final Indexer createIndexer(Configuration config) throws
DBException {
checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
@@ -380,7 +380,7 @@
getCollectionRoot().delete();
// Drop symbols
- if (!internalSymbols) {
+ if (!symbols.isReadOnly()) {
getSystemCollection().dropSymbols(this);
}
@@ -389,7 +389,7 @@
}
/**
- * @see
org.apache.xindice.core.CollectionManager#dropCollection(org.apache.xindice.core.Collection)
+ * @see CollectionManager#dropCollection(Collection)
*/
public final boolean dropCollection(Collection collection) throws
DBException {
boolean success = super.dropCollection(collection);
@@ -403,6 +403,7 @@
*
* @param index The Indexer to drop
* @return Whether or not the Indexer was dropped
+ * @throws DBException if operation failed
*/
public final boolean dropIndexer(Indexer index) throws DBException {
checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
@@ -425,10 +426,10 @@
}
/**
- * @throws DBException
+ * @throws DBException if operation failed
*/
public final void flushSymbolTable() throws DBException {
- if (symbols.isDirty() && !internalSymbols) {
+ if (symbols.isDirty()) {
getSystemCollection().saveSymbols(this, symbols);
}
}
@@ -516,6 +517,7 @@
* returned will be null.
*
* @return MetaData this collection's metadata.
+ * @throws DBException if operation failed
*/
public MetaData getCollectionMeta() throws DBException {
if (!isMetaEnabled()) {
@@ -550,6 +552,7 @@
*
* @param docKey The Document Key
* @return The Container
+ * @throws DBException if operation failed
*/
public final Container getContainer(Object docKey) throws DBException {
Key key = createNewKey(docKey);
@@ -571,6 +574,7 @@
*
* @param key The Document Key
* @return The Document
+ * @throws DBException if operation failed
*/
public final Document getDocument(Object key) throws DBException {
if (log.isDebugEnabled()) {
@@ -596,6 +600,7 @@
* by this Collection.
*
* @return The Document count
+ * @throws DBException if operation failed
*/
public final long getDocumentCount() throws DBException {
// a collection in which you are unable to file documents will have no
filer
@@ -606,9 +611,11 @@
/**
* 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
+ * @return meta data for requested resource
+ * @throws DBException if operation failed
*/
public MetaData getDocumentMeta(String id) throws DBException {
if (!isMetaEnabled()) {
@@ -661,6 +668,7 @@
* by this Collection.
*
* @return The DocumentSet
+ * @throws DBException if operation failed
*/
public final DocumentSet getDocumentSet() throws DBException {
// a collection in which you are unable to file documents will have no
filer
@@ -841,6 +849,7 @@
*
* @param name The Indexer name
* @return The Indexer (or null)
+ * @throws DBException if operation failed
*/
public final Indexer getIndexer(String name) throws DBException {
checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
@@ -851,6 +860,7 @@
* return the IndexManager being used by this Collection.
*
* @return The IndexManager
+ * @throws DBException if operation failed
*/
public final IndexManager getIndexManager() throws DBException {
checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
@@ -878,6 +888,7 @@
*
* @param key The Document Key
* @return an Castable XMLSerializable Instance
+ * @throws DBException if operation failed
*/
public final XMLSerializable getObject(Object key) throws DBException {
if (log.isDebugEnabled()) {
@@ -918,6 +929,7 @@
* Collection.
*
* @return The parent Collection (or null)
+ * @throws DBException if operation failed
*/
public final Collection getParentCollection() throws DBException {
return parent;
@@ -927,6 +939,7 @@
* getQueryEngine returns the Database's Query Engine
*
* @return The Query Engine
+ * @throws DBException if operation failed
*/
public QueryEngine getQueryEngine() throws DBException {
return getDatabase().getQueryEngine();
@@ -972,6 +985,7 @@
*
* @param docKey The document Key
* @param bytes The document to insert
+ * @return key for the inserted binary
* @throws DBException if inline-metadata is not enabled, the key is
* already in the database, or an error occurs while saving.
*/
@@ -998,6 +1012,7 @@
*
* @param document The Document
* @return The new Object Identifier
+ * @throws DBException if operation failed
*/
public final Key insertDocument(Document document) throws DBException {
return insertDocument(null, document);
@@ -1008,6 +1023,8 @@
*
* @param docKey The document Key
* @param document The document to insert
+ * @return key for inserted document
+ * @throws DBException if operation failed
*/
public final Key insertDocument(Object docKey, Document document) throws
DBException {
Key key = createNewKey(docKey);
@@ -1028,6 +1045,7 @@
*
* @param obj The Object to insert
* @return The newly generated Key
+ * @throws DBException if operation failed
*/
public final Key insertObject(XMLSerializable obj) throws DBException {
return insertObject(null, obj);
@@ -1040,6 +1058,8 @@
*
* @param objKey The Key to use
* @param obj The Object to insert
+ * @return key for the inserted object
+ * @throws DBException if operation failed
*/
public final Key insertObject(String objKey, XMLSerializable obj) throws
DBException {
Key key = createNewKey(objKey);
@@ -1076,6 +1096,7 @@
* collection.
*
* @return the list of entry keys
+ * @throws DBException if operation failed
*/
public final String[] listDocuments() throws DBException {
// a collection in which you are unable to file documents will have no
filer
@@ -1104,6 +1125,7 @@
* as an array of String.
*
* @return The Indexer list
+ * @throws DBException if operation failed
*/
public final String[] listIndexers() throws DBException {
checkFiler(FaultCodes.COL_NO_INDEXMANAGER);
@@ -1121,6 +1143,7 @@
* @param key The key to use when caching
* @param xml The string to parse
* @return A parsed DOM document or null if failure
+ * @throws DBException if operation failed
*/
private Document parseDocument(Key key, String xml) throws DBException {
try {
@@ -1350,6 +1373,7 @@
* @param query The query to execute
* @param nsMap The namespace Map (if any)
* @return The resulting NodeSet
+ * @throws DBException if operation failed
*/
public final NodeSet queryCollection(String style, String query,
NamespaceMap nsMap) throws DBException {
if (log.isDebugEnabled()) {
@@ -1371,6 +1395,7 @@
* @param nsMap The namespace Map (if any)
* @param key The Document to query
* @return The resulting NodeSet
+ * @throws DBException if operation failed
*/
public final NodeSet queryDocument(String style, String query,
NamespaceMap nsMap, Object key) throws DBException {
if (log.isInfoEnabled()) {
@@ -1392,6 +1417,7 @@
* regardless of it's type.
*
* @param key The Object's Key
+ * @throws DBException if operation failed
*/
public final void remove(Object key) throws DBException {
if (log.isInfoEnabled()) {
@@ -1445,7 +1471,9 @@
/**
* Reset the metadata object for this collection.
+ *
* @param meta the Metadata to use
+ * @throws DBException if operation failed
*/
public void setCollectionMeta(MetaData meta) throws DBException {
if (!isMetaEnabled()) {
@@ -1525,15 +1553,14 @@
// Symbol Table Setup
Configuration symConfig = config.getChild(SYMBOLS);
- internalSymbols = (symConfig != null);
- if (internalSymbols) {
+ if (symConfig != null) {
if (log.isTraceEnabled()) {
log.trace(localDebugHeader +
"Internal symbols=<" +
TextWriter.toString(symConfig.getElement()) + ">");
}
try {
- symbols = new SymbolTable(symConfig.getElement());
+ symbols = new SymbolTable(symConfig.getElement(), true);
} catch (Exception e) {
if (log.isWarnEnabled()) {
log.warn(localDebugHeader + "Error building symbol
table from internal symbols", e);
@@ -1600,6 +1627,7 @@
*
* @param docKey The Document Key
* @param document The Document
+ * @throws DBException if operation failed
*/
public final boolean setDocument(Object docKey, Document document) throws
DBException {
if (log.isInfoEnabled()) {
@@ -1620,6 +1648,7 @@
*
* @param docKey The document Key
* @param bytes The document to insert
+ * @return true if new binary was created, false otherwise
* @throws DBException if inline-metadata is not enabled, the key is
* already in the database, or an error occurs while saving.
*/
@@ -1648,6 +1677,7 @@
*
* @param id the document name
* @param meta the metadata object to be used.
+ * @throws DBException if operation failed
*/
public void setDocumentMeta(String id, MetaData meta) throws DBException {
if (!isMetaEnabled()) {
@@ -1682,10 +1712,10 @@
}
/**
- * @param string
+ * @param name collection name
*/
- protected void setName(String string) {
- name = string;
+ protected void setName(String name) {
+ this.name = name;
}
/**
@@ -1695,6 +1725,7 @@
*
* @param key The Key to use
* @param obj The Object to set
+ * @throws DBException if operation failed
*/
public final void setObject(Object key, XMLSerializable obj) throws
DBException {
if (log.isInfoEnabled()) {
@@ -1748,6 +1779,9 @@
/**
* update the modified time of this document when appropriate
+ *
+ * @param record database record for which metadata should be updated
+ * @throws DBException if operation failed
*/
protected void updateDocumentMeta(Record record) throws DBException {
// update the meta data if necessary
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/SystemCollection.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/SystemCollection.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/SystemCollection.java
(original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/SystemCollection.java
Wed Aug 22 17:40:57 2007
@@ -126,7 +126,7 @@
if (symbols != null) {
String name = getSymbolTableName(collection);
getCollection(SYMBOLS).setObject(name, symbols);
- symbols.setDirty(false);
+ symbols.resetDirty();
}
}
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/DocumentHandler.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/DocumentHandler.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
---
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/DocumentHandler.java
(original)
+++
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/DocumentHandler.java
Wed Aug 22 17:40:57 2007
@@ -19,18 +19,21 @@
package org.apache.xindice.core.indexer;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.Attributes;
-import org.apache.xindice.xml.sax.CompressionHandler;
-import org.apache.xindice.xml.sax.SAXEventGenerator;
-import org.apache.xindice.xml.SymbolTable;
-import org.apache.xindice.util.ObjectStack;
-import org.apache.xindice.core.data.Key;
-import org.apache.xindice.core.DBException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.data.Key;
+import org.apache.xindice.util.ObjectStack;
+import org.apache.xindice.util.ReadOnlyException;
+import org.apache.xindice.xml.SymbolTable;
+import org.apache.xindice.xml.sax.CompressionHandler;
+import org.apache.xindice.xml.sax.SAXEventGenerator;
+
import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
/**
* DocumentHandler actually performs the work of adding and removing Indexer
@@ -39,6 +42,9 @@
* @version $Revision$, $Date$
*/
class DocumentHandler implements ContentHandler, CompressionHandler {
+
+ private static final Log log = LogFactory.getLog(DocumentHandler.class);
+
static final int ACTION_CREATE = 0;
static final int ACTION_DELETE = 1;
@@ -53,8 +59,6 @@
public StackInfo info; // Current State
- private static final Log log = LogFactory.getLog(DocumentHandler.class);
-
public DocumentHandler(SymbolTable symbols, Key key, Document doc, int
action, Indexer[] list) {
this.symbols = symbols;
this.key = key;
@@ -173,23 +177,27 @@
}
}
- public void startElement(String namespaceURI, String localName, String
qName, Attributes atts) {
- // Modify the stack info to normalize the symbolID
- if (namespaceURI != null && namespaceURI.length() > 0) {
- info.symbolID = symbols.getNormalizedSymbol(localName,
namespaceURI, true);
- }
-
- int size = atts.getLength();
- for (int i = 0; i < size; i++) {
- String nsURI = atts.getURI(i);
- short id;
- if (nsURI != null && nsURI.length() > 0) {
- id = symbols.getNormalizedSymbol(atts.getLocalName(i), nsURI,
true);
- } else {
- id = symbols.getSymbol(atts.getQName(i), true);
+ public void startElement(String namespaceURI, String localName, String
qName, Attributes atts) throws SAXException {
+ try {
+// Modify the stack info to normalize the symbolID
+ if (namespaceURI != null && namespaceURI.length() > 0) {
+ info.symbolID = symbols.getNormalizedSymbol(localName,
namespaceURI, true);
}
- processEntry(new IndexPattern(symbols, info.symbolID, id),
atts.getValue(i), info.pos, info.len);
+ int size = atts.getLength();
+ for (int i = 0; i < size; i++) {
+ String nsURI = atts.getURI(i);
+ short id;
+ if (nsURI != null && nsURI.length() > 0) {
+ id = symbols.getNormalizedSymbol(atts.getLocalName(i),
nsURI, true);
+ } else {
+ id = symbols.getSymbol(atts.getQName(i), true);
+ }
+
+ processEntry(new IndexPattern(symbols, info.symbolID, id),
atts.getValue(i), info.pos, info.len);
+ }
+ } catch (ReadOnlyException e) {
+ throw new SAXException(e);
}
}
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/IndexPattern.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/IndexPattern.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
---
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/IndexPattern.java
(original)
+++
xml/xindice/trunk/java/src/org/apache/xindice/core/indexer/IndexPattern.java
Wed Aug 22 17:40:57 2007
@@ -19,7 +19,9 @@
package org.apache.xindice.core.indexer;
+import org.apache.xindice.core.FaultCodes;
import org.apache.xindice.core.filer.Streamable;
+import org.apache.xindice.util.ReadOnlyException;
import org.apache.xindice.xml.NamespaceMap;
import org.apache.xindice.xml.SymbolTable;
@@ -53,24 +55,30 @@
private short attrID = PATTERN_NONE;
- public IndexPattern(SymbolTable symbols, String pattern, NamespaceMap
nsMap) {
+ public IndexPattern(SymbolTable symbols, String pattern, NamespaceMap
nsMap) throws IndexerException {
this.symbols = symbols;
StringTokenizer st = new StringTokenizer(pattern.trim(), "@");
- elemName = st.nextToken();
- if (elemName.equals("*")) {
- elemID = PATTERN_WILDCARD;
- } else {
- elemID = symbols.getNormalizedSymbol(elemName, nsMap, true);
- }
-
- if (st.hasMoreTokens()) {
- attrName = st.nextToken();
- if (attrName.equals("*")) {
- attrID = PATTERN_WILDCARD;
+
+ try {
+ elemName = st.nextToken();
+ if (elemName.equals("*")) {
+ elemID = PATTERN_WILDCARD;
} else {
- attrID = elemID == PATTERN_WILDCARD ? PATTERN_NAME
- : symbols.getNormalizedSymbol(attrName, nsMap, true);
+ elemID = symbols.getNormalizedSymbol(elemName, nsMap, true);
+ }
+
+ if (st.hasMoreTokens()) {
+ attrName = st.nextToken();
+ if (attrName.equals("*")) {
+ attrID = PATTERN_WILDCARD;
+ } else {
+ attrID = elemID == PATTERN_WILDCARD ? PATTERN_NAME
+ : symbols.getNormalizedSymbol(attrName, nsMap,
true);
+ }
}
+ } catch (ReadOnlyException e) {
+ throw new IndexerException(FaultCodes.IDX_NOT_SUPPORTED,
+ "Pattern '" + pattern + "' is not
allowed in this collection.", e);
}
}
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/core/query/XPathQueryResolver.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/query/XPathQueryResolver.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
---
xml/xindice/trunk/java/src/org/apache/xindice/core/query/XPathQueryResolver.java
(original)
+++
xml/xindice/trunk/java/src/org/apache/xindice/core/query/XPathQueryResolver.java
Wed Aug 22 17:40:57 2007
@@ -919,7 +919,7 @@
return null;
}
- private Object funcStartsWith(String owner, List args) {
+ private Object funcStartsWith(String owner, List args) throws
Exception {
if (args.size() == 2) {
Object o = args.get(0);
Object s = args.get(1);
@@ -1114,7 +1114,7 @@
* @param right The right Operand
* @return The resulting Keys (if any)
*/
- private Object queryComparison(int op, String owner, Object left,
Object right) {
+ private Object queryComparison(int op, String owner, Object left,
Object right) throws Exception {
op = OPMAP[op - OpCodes.OP_NOTEQUALS];
if (left instanceof XObject) {
Modified: xml/xindice/trunk/java/src/org/apache/xindice/xml/SymbolTable.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/SymbolTable.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/SymbolTable.java
(original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/SymbolTable.java Wed Aug
22 17:40:57 2007
@@ -19,6 +19,8 @@
package org.apache.xindice.xml;
+import org.apache.xindice.util.ReadOnlyException;
+
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -45,9 +47,10 @@
private transient boolean dirty;
private transient long lastModified = System.currentTimeMillis();
+ private short maxSymbol = -1;
private final Map symbols = new HashMap(); // String to SymbolInfo
private final Map names = new HashMap(); // Short to SymbolInfo
- private short maxSymbol = -1;
+ private boolean readOnly;
public static final class SymbolInfo implements Serializable {
@@ -55,14 +58,14 @@
private final String qname;
private final short symbol;
- private SymbolInfo(String qname, String namespaceURI, short symbol) {
- this.namespaceURI = namespaceURI;
+ private SymbolInfo(String qname, short symbol) {
+ this.namespaceURI = null;
this.qname = qname;
this.symbol = symbol;
}
- private SymbolInfo(String qname, short symbol) {
- this.namespaceURI = null;
+ private SymbolInfo(String qname, String namespaceURI, short symbol) {
+ this.namespaceURI = namespaceURI;
this.qname = qname;
this.symbol = symbol;
}
@@ -87,23 +90,50 @@
public SymbolTable() {
}
- public SymbolTable(Element elem) {
- streamFromXML(elem);
+ public SymbolTable(Element symbols) {
+ streamFromXML(symbols);
+ }
+
+ public SymbolTable(Element symbols, boolean readOnly) {
+ this(symbols);
+ this.readOnly = readOnly;
}
+ /**
+ * @return true if symbol table has been modified
+ */
public final boolean isDirty() {
return dirty;
}
- public final void setDirty(boolean dirty) {
- this.dirty = dirty;
+ /**
+ * Set dirty flag to true and update last modified
+ * time stamp.
+ */
+ private void markDirty() {
+ this.dirty = true;
this.lastModified = System.currentTimeMillis();
}
+ /**
+ * Reset dirty flag to false. Should be invoked
+ * once symbol table is successfully saved.
+ */
+ public final void resetDirty() {
+ this.dirty = false;
+ }
+
public final long getLastModified() {
return lastModified;
}
+ /**
+ * @return true if symbol table is read only
+ */
+ public final boolean isReadOnly() {
+ return readOnly;
+ }
+
//
// Lookup by symbol id
//
@@ -127,26 +157,40 @@
//
public final short getSymbol(String qname) {
- return getSymbol(qname, false);
+ try {
+ return getSymbol(qname, false);
+ } catch (ReadOnlyException e) {
+ // Won't happen
+ throw new IllegalStateException();
+ }
}
public final short getSymbol(String qname, String namespaceURI) {
- return getSymbol(qname, namespaceURI, false);
+ try {
+ return getSymbol(qname, namespaceURI, false);
+ } catch (ReadOnlyException e) {
+ // Won't happen
+ throw new IllegalStateException();
+ }
}
- public final short getSymbol(String qname, boolean create) {
+ public final short getSymbol(String qname, boolean create) throws
ReadOnlyException {
SymbolInfo info = (SymbolInfo) symbols.get(qname);
if (info != null) {
return info.symbol;
}
if (create) {
+ if (readOnly) {
+ throw new ReadOnlyException();
+ }
+
synchronized (symbols) {
short id = ++maxSymbol;
info = new SymbolInfo(qname, id);
symbols.put(qname, info);
names.put(new Short(id), info);
- setDirty(true);
+ markDirty();
return id;
}
}
@@ -154,7 +198,7 @@
return -1;
}
- public final short getSymbol(String qname, String namespaceURI, boolean
create) {
+ public final short getSymbol(String qname, String namespaceURI, boolean
create) throws ReadOnlyException {
String lookupName = getLookupName(qname, namespaceURI);
SymbolInfo info = (SymbolInfo) symbols.get(lookupName);
@@ -163,12 +207,16 @@
}
if (create) {
+ if (readOnly) {
+ throw new ReadOnlyException();
+ }
+
synchronized (symbols) {
short id = ++maxSymbol;
info = new SymbolInfo(qname, namespaceURI, id);
symbols.put(lookupName, info);
names.put(new Short(id), info);
- setDirty(true);
+ markDirty();
return id;
}
}
@@ -181,7 +229,12 @@
//
public final short getNormalizedSymbol(String localName, String
namespaceURI) {
- return getNormalizedSymbol(localName, namespaceURI, false);
+ try {
+ return getNormalizedSymbol(localName, namespaceURI, false);
+ } catch (ReadOnlyException e) {
+ // Won't happen
+ throw new IllegalStateException();
+ }
}
/**
@@ -191,9 +244,10 @@
* @param namespaceURI element (attribute) namespace URI
* @param create when true, creates symbol if it is missing
* @return symbol id or -1
+ * @throws ReadOnlyException if 'create' option specified and the symbol
is missing
*/
- public final short getNormalizedSymbol(String localName, String
namespaceURI, boolean create) {
- String normalizedQName = SymbolTable.getNormalizedQName(localName,
namespaceURI);
+ public final short getNormalizedSymbol(String localName, String
namespaceURI, boolean create) throws ReadOnlyException {
+ String normalizedQName = getNormalizedQName(localName, namespaceURI);
return getSymbol(normalizedQName, namespaceURI, create);
}
@@ -212,8 +266,9 @@
* @param nsMap namespace map
* @param create when true, creates symbol if it is missing
* @return symbol id or -1
+ * @throws ReadOnlyException if 'create' option specified and the symbol
is missing
*/
- public final short getNormalizedSymbol(String lookup, NamespaceMap nsMap,
boolean create) {
+ public final short getNormalizedSymbol(String lookup, NamespaceMap nsMap,
boolean create) throws ReadOnlyException {
// Parse [<namespaceURI>]<nsPrefix>:<localName> with optional nsPrefix
if (lookup.startsWith("[")) {
int idx = lookup.indexOf(']');
@@ -300,7 +355,7 @@
// Implementation methods
//
- private static String getNormalizedQName(String localName, String
namespaceURI) {
+ private String getNormalizedQName(String localName, String namespaceURI) {
return "ns" + namespaceURI.hashCode() + ':' + localName;
}
Modified:
xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DOMCompressor.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DOMCompressor.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DOMCompressor.java
(original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DOMCompressor.java
Wed Aug 22 17:40:57 2007
@@ -21,11 +21,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.xindice.util.ReadOnlyException;
import org.apache.xindice.xml.Signatures;
import org.apache.xindice.xml.SymbolTable;
import org.apache.xindice.xml.XMLCompressedOutput;
import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@@ -56,6 +58,8 @@
*
* @param node the node to write
* @throws IOException if the write to underlying stream has failed
+ * @throws DOMException if used symbol table is read only and some of
+ * node's content can not be serialized.
*/
public void writeNode(Node node) throws IOException {
// Check if it's node of ours
@@ -85,9 +89,21 @@
String nsURI = node.getNamespaceURI();
short symbolID;
if (nsURI != null) {
- symbolID = st.getSymbol(node.getNodeName(), nsURI,
true);
+ try {
+ symbolID = st.getSymbol(node.getNodeName(), nsURI,
true);
+ } catch (ReadOnlyException e) {
+ throw new
DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Element can not be
serialized (read only symbol table). " +
+ "Name: '" +
node.getNodeName() + "', namespace: " + nsURI);
+ }
} else {
- symbolID = st.getSymbol(node.getNodeName(), true);
+ try {
+ symbolID = st.getSymbol(node.getNodeName(), true);
+ } catch (ReadOnlyException e) {
+ throw new
DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Element can not be
serialized (read only symbol table). " +
+ "Name: '" +
node.getNodeName() + "'");
+ }
}
byte signature = Signatures.NODE_ELEM;
@@ -118,9 +134,21 @@
String nsURI = attr.getNamespaceURI();
short symbolID;
if (nsURI != null) {
- symbolID = st.getSymbol(attr.getName(), nsURI, true);
+ try {
+ symbolID = st.getSymbol(attr.getName(), nsURI,
true);
+ } catch (ReadOnlyException e) {
+ throw new
DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Attribute can not be
serialized (read only symbol table). " +
+ "Name: '" + attr.getName()
+ "', namespace: " + nsURI);
+ }
} else {
- symbolID = st.getSymbol(attr.getName(), true);
+ try {
+ symbolID = st.getSymbol(attr.getName(), true);
+ } catch (ReadOnlyException e) {
+ throw new
DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Attribute can not be
serialized (read only symbol table). " +
+ "Name: '" + attr.getName()
+ "'");
+ }
}
writeShort(symbolID);
@@ -178,7 +206,13 @@
// TODO symbol =
} else {
encoding = 2;
- symbol = st.getSymbol(value, true);
+ try {
+ symbol = st.getSymbol(value, true);
+ } catch (ReadOnlyException e) {
+ throw new
DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Entity reference can not
be serialized (read only symbol table). " +
+ "Value: '" + value + "'");
+ }
signature |= (byte) (Signatures.ENT_DEFINED);
}
writeByte(signature);
Modified:
xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/SymbolTableTest.java
URL:
http://svn.apache.org/viewvc/xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/SymbolTableTest.java?rev=568786&r1=568785&r2=568786&view=diff
==============================================================================
---
xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/SymbolTableTest.java
(original)
+++
xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/SymbolTableTest.java
Wed Aug 22 17:40:57 2007
@@ -19,6 +19,7 @@
package org.apache.xindice.xml;
+import org.apache.xindice.util.ReadOnlyException;
import org.apache.xindice.xml.dom.DOMParser;
import junit.framework.TestCase;
@@ -44,7 +45,7 @@
}
- public void testMissingSymbol() {
+ public void testMissingSymbol() throws Exception {
assertNull(symbols.getSymbolInfo((short) 123));
assertEquals(-1, symbols.getSymbol("missing"));
@@ -95,7 +96,7 @@
assertFalse(symbols.isDirty());
}
- public void testAddSymbol() {
+ public void testAddSymbol() throws Exception {
assertEquals(-1, symbols.getSymbol("missing"));
assertTrue(symbols.getSymbol("missing", true) != -1);
assertTrue(symbols.isDirty());
@@ -109,7 +110,7 @@
assertEquals(s, si.getSymbolID());
}
- public void testAddNamespacedSymbol() {
+ public void testAddNamespacedSymbol() throws Exception {
assertEquals(-1, symbols.getSymbol("missing", "urn:unknown"));
assertTrue(symbols.getSymbol("missing", "urn:unknown", true) != -1);
assertTrue(symbols.isDirty());
@@ -123,7 +124,7 @@
assertEquals(s, si.getSymbolID());
}
- public void testGetNormalizedSymbol() {
+ public void testGetNormalizedSymbol() throws Exception {
assertEquals(1, symbols.getNormalizedSymbol("simple", (NamespaceMap)
null, false));
assertEquals(-1,
symbols.getNormalizedSymbol("[http://www.w3.org/1999/xhtml]spaced",
(NamespaceMap) null, false));
@@ -140,5 +141,16 @@
NamespaceMap m = new NamespaceMap();
m.setNamespace("z", "http://www.w3.org/1999/xhtml");
assertEquals(s, symbols.getNormalizedSymbol("z:spaced", m, false));
+ }
+
+ public void testReadOnly() throws Exception {
+ symbols = new
SymbolTable(DOMParser.toDocument(SYMBOLS).getDocumentElement(), true);
+
+ assertEquals(-1, symbols.getSymbol("foo"));
+
+ try {
+ symbols.getSymbol("foo", true);
+ fail();
+ } catch (ReadOnlyException e) { }
}
}