stefan 2004/07/30 08:00:32
Added: proposals/jcrri/src/org/apache/slide/jcr/core
AbstractSAXEventGenerator.java
MalformedPathException.java
SysViewSAXEventGenerator.java
Log:
jcrri
Revision Changes Path
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/AbstractSAXEventGenerator.java
Index: AbstractSAXEventGenerator.java
===================================================================
/*
* $Id: AbstractSAXEventGenerator.java,v 1.1 2004/07/30 15:00:32 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core;
import org.apache.slide.jcr.core.state.NodeState;
import org.apache.slide.jcr.core.state.PropertyState;
import org.apache.slide.jcr.core.state.ItemStateProvider;
import org.apache.slide.jcr.core.state.ItemStateException;
import org.apache.log4j.Logger;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import javax.jcr.RepositoryException;
import javax.jcr.access.Permission;
import java.util.Iterator;
/**
* <code>AbstractSAXEventGenerator</code> serves as the base class for
* <code>SysViewSAXEventGenerator</code> and <code>DocViewSAXEventGenerator</code>
* <p/>
* It traverses a tree of <code>NodeState</code> & <code>PropertyState</code>
* instances, and calls the abstract methods
* <ul>
* <li><code>[EMAIL PROTECTED] #entering(NodeState, QName, int)}</code></li>
* <li><code>[EMAIL PROTECTED] #enteringProperties(NodeState, QName,
int)}</code></li>
* <li><code>[EMAIL PROTECTED] #leavingProperties(NodeState, QName, int)}</code></li>
* <li><code>[EMAIL PROTECTED] #leaving(NodeState, QName, int)}</code></li>
* <li><code>[EMAIL PROTECTED] #entering(PropertyState, String, int)}</code></li>
* <li><code>[EMAIL PROTECTED] #leaving(PropertyState, String, int)}</code></li>
* </ul>
* for every item state that is granted read access.
*
* @author Stefan Guggisberg
* @version $Revision: 1.1 $, $Date: 2004/07/30 15:00:32 $
*/
abstract class AbstractSAXEventGenerator {
private static Logger log = Logger.getLogger(AbstractSAXEventGenerator.class);
protected final ItemStateProvider stateProvider;
protected final NamespaceRegistryImpl nsReg;
protected final AccessManagerImpl accessMgr;
protected final ContentHandler contentHandler;
protected final NodeState startNodeState;
protected final QName startNodeName;
protected final boolean binaryAsLink;
protected final boolean noRecurse;
// jcr:uuid
protected static final QName PROPNAME_UUID = ItemImpl.PROPNAME_UUID;
// jcr:primaryType
protected static final QName PROPNAME_PRIMARYTYPE =
ItemImpl.PROPNAME_PRIMARYTYPE;
// jcr:mixinTypes
protected static final QName PROPNAME_MIXINTYPES = ItemImpl.PROPNAME_MIXINTYPES;
/**
* Constructor
*
* @param nodeState the node state which should be serialized
* @param noRecurse if true, only <code>nodeState</code> and its properties
will
* be serialized; otherwise the entire hierarchy starting
with
* <code>nodeState</code> will be serialized.
* @param binaryAsLink specifies if binary properties are turned into links
* @param nodeName name of the node to be serialized
* @param stateProvider item state provider for retrieving child item state
* @param nsReg the namespace registry to be used for namespace
declarations
* @param accessMgr the access manager
* @param contentHandler the content handler to feed the SAX events to
*/
protected AbstractSAXEventGenerator(NodeState nodeState, QName nodeName,
boolean noRecurse, boolean binaryAsLink,
ItemStateProvider stateProvider,
NamespaceRegistryImpl nsReg,
AccessManagerImpl accessMgr,
ContentHandler contentHandler) {
this.stateProvider = stateProvider;
this.nsReg = nsReg;
this.accessMgr = accessMgr;
startNodeState = nodeState;
startNodeName = nodeName;
this.contentHandler = contentHandler;
this.binaryAsLink = binaryAsLink;
this.noRecurse = noRecurse;
}
/**
* Serializes the hierarchy of nodes and properties.
*
* @throws javax.jcr.RepositoryException if an error occurs while traversing the
hierarchy
* @throws org.xml.sax.SAXException if an error occured while feeding the
events to the content handler
*/
public void serialize() throws RepositoryException, SAXException {
contentHandler.startDocument();
// namespace declarations
String[] prefixes = nsReg.getPrefixes();
for (int i = 0; i < prefixes.length; i++) {
String prefix = prefixes[i];
String uri = nsReg.getURI(prefix);
contentHandler.startPrefixMapping(prefix, uri);
}
// start serializing node state(s)
process(startNodeState, startNodeName, 0);
contentHandler.endDocument();
}
/**
* @param nodeState
* @param level
* @throws RepositoryException
* @throws SAXException
*/
protected void process(NodeState nodeState, QName nodeName, int level)
throws RepositoryException, SAXException {
// enter node
entering(nodeState, nodeName, level);
// enter properties
enteringProperties(nodeState, nodeName, level);
// serialize jcr:primaryType, jcr:mixinTypes & jcr:uuid first:
// jcr:primaryType
if (nodeState.hasPropertyEntry(PROPNAME_PRIMARYTYPE)) {
process(nodeState.getPropertyEntry(PROPNAME_PRIMARYTYPE),
nodeState.getUUID(), level + 1);
} else {
String msg = "internal error: missing jcr:primaryType property on node " +
nodeState.getUUID();
log.error(msg);
throw new RepositoryException(msg);
}
// jcr:mixinTypes
if (nodeState.hasPropertyEntry(PROPNAME_MIXINTYPES)) {
process(nodeState.getPropertyEntry(PROPNAME_MIXINTYPES),
nodeState.getUUID(), level + 1);
}
// jcr:uuid
if (nodeState.hasPropertyEntry(PROPNAME_UUID)) {
process(nodeState.getPropertyEntry(PROPNAME_UUID), nodeState.getUUID(),
level + 1);
}
// serialize remaining properties
Iterator iter = nodeState.getPropertyEntries().iterator();
while (iter.hasNext()) {
NodeState.PropertyEntry pe = (NodeState.PropertyEntry) iter.next();
if (PROPNAME_PRIMARYTYPE.equals(pe.getName()) ||
PROPNAME_MIXINTYPES.equals(pe.getName()) ||
PROPNAME_UUID.equals(pe.getName())) {
continue;
}
PropertyId propId = new PropertyId(nodeState.getUUID(), pe.getName());
// check read access
if (accessMgr.isGranted(propId, Permission.READ_ITEM)) {
// serialize property
process(pe, nodeState.getUUID(), level + 1);
}
}
// leaving properties
leavingProperties(nodeState, nodeName, level);
if (!noRecurse) {
// child nodes
iter = nodeState.getChildNodeEntries().iterator();
while (iter.hasNext()) {
NodeState.ChildNodeEntry cne = (NodeState.ChildNodeEntry) iter.next();
NodeId childId = new NodeId(cne.getUUID());
// check read access
if (accessMgr.isGranted(childId, Permission.READ_ITEM)) {
NodeState childState;
try {
childState = (NodeState) stateProvider.getItemState(childId);
} catch (ItemStateException ise) {
String msg = "internal error: failed to retrieve state of node
" + childId;
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
// recurse
process(childState, cne.getName(), level + 1);
}
}
}
// leaving node
leaving(nodeState, nodeName, level);
}
/**
*
* @param propEntry
* @param parentUUID
* @param level
* @throws RepositoryException
* @throws SAXException
*/
protected void process(NodeState.PropertyEntry propEntry, String parentUUID, int
level)
throws RepositoryException, SAXException {
PropertyId propId = new PropertyId(parentUUID, propEntry.getName());
try {
PropertyState propState = (PropertyState)
stateProvider.getItemState(propId);
// serialize property
entering(propState, parentUUID, level);
leaving(propState, parentUUID, level);
} catch (ItemStateException ise) {
String msg = "internal error: failed to retrieve state of property " +
propId;
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
/**
*
* @param state
* @param name
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void entering(NodeState state, QName name, int level)
throws RepositoryException, SAXException;
/**
*
* @param state
* @param name
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void enteringProperties(NodeState state, QName name, int
level)
throws RepositoryException, SAXException;
/**
*
* @param state
* @param name
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void leavingProperties(NodeState state, QName name, int level)
throws RepositoryException, SAXException;
/**
*
* @param state
* @param name
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void leaving(NodeState state, QName name, int level)
throws RepositoryException, SAXException;
/**
*
* @param state
* @param parentUUID
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void entering(PropertyState state, String parentUUID, int
level)
throws RepositoryException, SAXException;
/**
*
* @param state
* @param parentUUID
* @param level
* @throws RepositoryException
* @throws SAXException
*/
abstract protected void leaving(PropertyState state, String parentUUID, int
level)
throws RepositoryException, SAXException;
}
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/MalformedPathException.java
Index: MalformedPathException.java
===================================================================
/*
* $Id: MalformedPathException.java,v 1.1 2004/07/30 15:00:32 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core;
import org.apache.slide.jcr.core.BaseException;
/**
* <code>MalformedPathException</code> ...
*
* @author Stefan Guggisberg
* @version $Revision: 1.1 $, $Date: 2004/07/30 15:00:32 $
*/
public class MalformedPathException extends BaseException {
/**
* Constructs a new instance of this class.
*/
public MalformedPathException() {
super();
}
/**
* Constructs a new instance of this class given a message describing the
* failure cause.
*
* @param s description
*/
public MalformedPathException(String s) {
super(s);
}
/**
* Constructs a new instance of this class given a message describing the
* failure and a root exception.
*
* @param s description
* @param e root failure cause
*/
public MalformedPathException(String s, Exception e) {
super(s);
/* don't create a proxy to a proxy */
if (e instanceof MalformedPathException) {
MalformedPathException e2 = (MalformedPathException) e;
rootException = e2.rootException;
} else {
rootException = e;
}
}
}
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/SysViewSAXEventGenerator.java
Index: SysViewSAXEventGenerator.java
===================================================================
/*
* $Id: SysViewSAXEventGenerator.java,v 1.1 2004/07/30 15:00:32 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core;
import org.apache.log4j.Logger;
import org.apache.slide.jcr.core.state.ItemStateProvider;
import org.apache.slide.jcr.core.state.NodeState;
import org.apache.slide.jcr.core.state.PropertyState;
import org.apache.slide.jcr.util.Base64;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
/**
* A <code>SysViewSAXEventGenerator</code> instance can be used to generate SAX
events
* representing the serialized form of an item in System View XML.
*
* @author Stefan Guggisberg
* @version $Revision: 1.1 $, $Date: 2004/07/30 15:00:32 $
*/
class SysViewSAXEventGenerator extends AbstractSAXEventGenerator {
private static Logger log = Logger.getLogger(SysViewSAXEventGenerator.class);
protected final HierarchyManager hierMgr;
/**
* The XML elements and attributes used in serialization
*/
public static final String NODE_ELEMENT = "node";
public static final String PROPERTY_ELEMENT = "property";
public static final String VALUE_ELEMENT = "value";
public static final String NAME_ATTRIBUTE = "name";
public static final String TYPE_ATTRIBUTE = "type";
public static final String CDATA_TYPE = "CDATA";
public static final String ENUMERATION_TYPE = "ENUMERATION";
public static final String NS_SV_PREFIX = NamespaceRegistryImpl.NS_SV_PREFIX;
public static final String NS_SV_URI = NamespaceRegistryImpl.NS_SV_URI;
/**
* Constructor
*
* @param nodeState the node state which should be serialized
* @param nodeName name of the node to be serialized
* @param noRecurse if true, only <code>nodeState</code> and its properties
will
* be serialized; otherwise the entire hierarchy starting
with
* <code>nodeState</code> will be serialized.
* @param binaryAsLink specifies if binary properties are turned into links
* @param stateProvider item state provider for retrieving child item state
* @param nsReg the namespace registry to be used for namespace
declarations
* @param accessMgr the access manager
* @param hierMgr the hierarchy manager used to resolve paths
* @param contentHandler the content handler to feed the SAX events to
*/
SysViewSAXEventGenerator(NodeState nodeState, QName nodeName,
boolean noRecurse, boolean binaryAsLink,
ItemStateProvider stateProvider,
NamespaceRegistryImpl nsReg,
AccessManagerImpl accessMgr,
HierarchyManager hierMgr,
ContentHandler contentHandler) {
super(nodeState, nodeName, noRecurse, binaryAsLink,
stateProvider, nsReg, accessMgr, contentHandler);
this.hierMgr = hierMgr;
}
/**
* @see AbstractSAXEventGenerator#entering(NodeState, QName, int)
*/
protected void entering(NodeState state, QName name, int level)
throws RepositoryException, SAXException {
AttributesImpl attrs = new AttributesImpl();
// name attribute
String nodeName = name.toJCRName(nsReg);
attrs.addAttribute(NS_SV_URI, NAME_ATTRIBUTE, NS_SV_PREFIX + ":" +
NAME_ATTRIBUTE, CDATA_TYPE, nodeName);
// start node element
contentHandler.startElement(NS_SV_URI, NODE_ELEMENT, NS_SV_PREFIX + ":" +
NODE_ELEMENT, attrs);
}
/**
* @see AbstractSAXEventGenerator#enteringProperties(NodeState, QName, int)
*/
protected void enteringProperties(NodeState state, QName name, int level)
throws RepositoryException, SAXException {
// nop
}
/**
* @see AbstractSAXEventGenerator#leavingProperties(NodeState, QName, int)
*/
protected void leavingProperties(NodeState state, QName name, int level)
throws RepositoryException, SAXException {
// nop
}
/**
* @see AbstractSAXEventGenerator#leaving(NodeState, QName, int)
*/
protected void leaving(NodeState state, QName name, int level)
throws RepositoryException, SAXException {
// end node element
contentHandler.endElement(NS_SV_URI, NODE_ELEMENT, NS_SV_PREFIX + ":" +
NODE_ELEMENT);
}
/**
* @see AbstractSAXEventGenerator#entering(PropertyState, String, int)
*/
protected void entering(PropertyState state, String parentUUID, int level)
throws RepositoryException, SAXException {
String name = state.getName().toJCRName(nsReg);
AttributesImpl attrs = new AttributesImpl();
// name attribute
attrs.addAttribute(NS_SV_URI, NAME_ATTRIBUTE, NS_SV_PREFIX + ":" +
NAME_ATTRIBUTE, CDATA_TYPE, name);
// type attribute
int type = state.getType();
String typeName;
try {
typeName = PropertyType.nameFromValue(type);
} catch (IllegalArgumentException iae) {
// should never be getting here
throw new RepositoryException("unexpected property-type ordinal: " + type,
iae);
}
if (type == PropertyType.BINARY && binaryAsLink) {
typeName = PropertyType.TYPENAME_SOFTLINK;
}
attrs.addAttribute(NS_SV_URI, TYPE_ATTRIBUTE, NS_SV_PREFIX + ":" +
TYPE_ATTRIBUTE, ENUMERATION_TYPE, typeName);
// start property element
contentHandler.startElement(NS_SV_URI, PROPERTY_ELEMENT, NS_SV_PREFIX + ":" +
PROPERTY_ELEMENT, attrs);
// values
InternalValue[] values = state.getValues();
if (values != null && values.length > 0) {
for (int i = 0; i < values.length; i++) {
if (values[i] != null) {
// start value element
contentHandler.startElement(NS_SV_URI, VALUE_ELEMENT, NS_SV_PREFIX
+ ":" + VALUE_ELEMENT, new AttributesImpl());
// characters
if (type == PropertyType.BINARY) {
if (binaryAsLink) {
String path = hierMgr.getPath(new PropertyId(parentUUID,
state.getName())).toJCRPath(nsReg);
char[] chars = path.toCharArray();
contentHandler.characters(chars, 0, chars.length);
} else {
// binary data, base64 encoding required
BLOBFileValue blob = (BLOBFileValue)
values[i].internalValue();
InputStream in = blob.getStream();
Writer writer = new Writer() {
public void close() /*throws IOException*/ {
}
public void flush() /*throws IOException*/ {
}
public void write(char cbuf[], int off, int len)
throws IOException {
try {
contentHandler.characters(cbuf, off, len);
} catch (SAXException se) {
throw new IOException(se.toString());
}
}
};
try {
Base64.encode(in, writer);
in.close();
writer.close();
} catch (IOException ioe) {
// check if the exception wraps a SAXException
Throwable t = ioe.getCause();
if (t != null && t instanceof SAXException) {
throw (SAXException) t;
} else {
throw new SAXException(ioe);
}
}
}
} else {
char chars[] =
values[i].toJCRValue(nsReg).getString().toCharArray();
contentHandler.characters(chars, 0, chars.length);
}
// end value element
contentHandler.endElement(NS_SV_URI, VALUE_ELEMENT, NS_SV_PREFIX +
":" + VALUE_ELEMENT);
}
}
}
}
/**
* @see AbstractSAXEventGenerator#leaving(PropertyState, String, int)
*/
protected void leaving(PropertyState state, String parentUUID, int level)
throws RepositoryException, SAXException {
contentHandler.endElement(NS_SV_URI, PROPERTY_ELEMENT, NS_SV_PREFIX + ":" +
PROPERTY_ELEMENT);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]