You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by st...@apache.org on 2004/08/02 16:47:10 UTC

cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core DocViewSAXEventGenerator.java AbstractSAXEventGenerator.java SysViewSAXEventGenerator.java WorkspaceImpl.java

stefan      2004/08/02 07:47:09

  Modified:    proposals/jcrri/src/org/apache/slide/jcr/core
                        AbstractSAXEventGenerator.java
                        SysViewSAXEventGenerator.java WorkspaceImpl.java
  Added:       proposals/jcrri/src/org/apache/slide/jcr/core
                        DocViewSAXEventGenerator.java
  Log:
  jcrri: first take at document & system view export from workspace
  
  Revision  Changes    Path
  1.2       +20 -13    jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/AbstractSAXEventGenerator.java
  
  Index: AbstractSAXEventGenerator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/AbstractSAXEventGenerator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractSAXEventGenerator.java	30 Jul 2004 15:00:32 -0000	1.1
  +++ AbstractSAXEventGenerator.java	2 Aug 2004 14:47:09 -0000	1.2
  @@ -46,8 +46,8 @@
    * <li><code>{@link #enteringProperties(NodeState, QName, int)}</code></li>
    * <li><code>{@link #leavingProperties(NodeState, QName, int)}</code></li>
    * <li><code>{@link #leaving(NodeState, QName, int)}</code></li>
  - * <li><code>{@link #entering(PropertyState, String, int)}</code></li>
  - * <li><code>{@link #leaving(PropertyState, String, int)}</code></li>
  + * <li><code>{@link #entering(PropertyState, int)}</code></li>
  + * <li><code>{@link #leaving(PropertyState, int)}</code></li>
    * </ul>
    * for every item state that is granted read access.
    *
  @@ -113,17 +113,26 @@
       public void serialize() throws RepositoryException, SAXException {
   	contentHandler.startDocument();
   	// namespace declarations
  +	documentPrefixMappings();
  +	// start serializing node state(s)
  +	process(startNodeState, startNodeName, 0);
  +
  +	contentHandler.endDocument();
  +    }
  +
  +    /**
  +     *
  +     * @throws RepositoryException
  +     * @throws SAXException
  +     */
  +    protected void documentPrefixMappings() throws RepositoryException, SAXException {
  +	// 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();
       }
   
       /**
  @@ -219,8 +228,8 @@
   	try {
   	    PropertyState propState = (PropertyState) stateProvider.getItemState(propId);
   	    // serialize property
  -	    entering(propState, parentUUID, level);
  -	    leaving(propState, parentUUID, level);
  +	    entering(propState, level);
  +	    leaving(propState, level);
   	} catch (ItemStateException ise) {
   	    String msg = "internal error: failed to retrieve state of property " + propId;
   	    log.error(msg, ise);
  @@ -275,22 +284,20 @@
       /**
        *
        * @param state
  -     * @param parentUUID
        * @param level
        * @throws RepositoryException
        * @throws SAXException
        */
  -    abstract protected void entering(PropertyState state, String parentUUID, int level)
  +    abstract protected void entering(PropertyState state, 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)
  +    abstract protected void leaving(PropertyState state, int level)
   	    throws RepositoryException, SAXException;
   }
  
  
  
  1.2       +5 -5      jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/SysViewSAXEventGenerator.java
  
  Index: SysViewSAXEventGenerator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/SysViewSAXEventGenerator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SysViewSAXEventGenerator.java	30 Jul 2004 15:00:32 -0000	1.1
  +++ SysViewSAXEventGenerator.java	2 Aug 2004 14:47:09 -0000	1.2
  @@ -132,9 +132,9 @@
       }
   
       /**
  -     * @see AbstractSAXEventGenerator#entering(PropertyState, String, int)
  +     * @see AbstractSAXEventGenerator#entering(PropertyState, int)
        */
  -    protected void entering(PropertyState state, String parentUUID, int level)
  +    protected void entering(PropertyState state, int level)
   	    throws RepositoryException, SAXException {
   	String name = state.getName().toJCRName(nsReg);
   	AttributesImpl attrs = new AttributesImpl();
  @@ -168,7 +168,7 @@
   		    // characters
   		    if (type == PropertyType.BINARY) {
   			if (binaryAsLink) {
  -			    String path = hierMgr.getPath(new PropertyId(parentUUID, state.getName())).toJCRPath(nsReg);
  +			    String path = hierMgr.getPath(new PropertyId(state.getParentUUID(), state.getName())).toJCRPath(nsReg);
   			    char[] chars = path.toCharArray();
   			    contentHandler.characters(chars, 0, chars.length);
   			} else {
  @@ -217,9 +217,9 @@
       }
   
       /**
  -     * @see AbstractSAXEventGenerator#leaving(PropertyState, String, int)
  +     * @see AbstractSAXEventGenerator#leaving(PropertyState, int)
        */
  -    protected void leaving(PropertyState state, String parentUUID, int level)
  +    protected void leaving(PropertyState state, int level)
   	    throws RepositoryException, SAXException {
   	contentHandler.endElement(NS_SV_URI, PROPERTY_ELEMENT, NS_SV_PREFIX + ":" + PROPERTY_ELEMENT);
       }
  
  
  
  1.13      +1 -4      jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java
  
  Index: WorkspaceImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/WorkspaceImpl.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- WorkspaceImpl.java	30 Jul 2004 15:01:11 -0000	1.12
  +++ WorkspaceImpl.java	2 Aug 2004 14:47:09 -0000	1.13
  @@ -951,13 +951,10 @@
   	if (!ticket.getAccessManager().isGranted(state.getId(), Permission.READ_ITEM)) {
   	    throw new PathNotFoundException(absPath);
   	}
  -	// @todo implement export of document xml view
  -/*
  +
   	new DocViewSAXEventGenerator(state, name.getName(), noRecurse, binaryAsLink,
   		persistentStateMgr, (NamespaceRegistryImpl) rep.getNamespaceRegistry(),
   		ticket.getAccessManager(), hierMgr, contentHandler).serialize();
  -*/
  -	throw new RepositoryException("not yet implemented");
       }
   
       /**
  
  
  
  1.1                  jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/DocViewSAXEventGenerator.java
  
  Index: DocViewSAXEventGenerator.java
  ===================================================================
  /*
   * $Id: DocViewSAXEventGenerator.java,v 1.1 2004/08/02 14:47:09 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.apache.xml.utils.XMLChar;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  
  import javax.jcr.InvalidSerializedDataException;
  import javax.jcr.PropertyType;
  import javax.jcr.RepositoryException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.StringWriter;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  /**
   * A <code>DocViewSAXEventGenerator</code> instance can be used to generate
   * SAX events representing the serialized form of an item in Document View XML.
   *
   * @author Stefan Guggisberg
   * @version $Revision: 1.1 $, $Date: 2004/08/02 14:47:09 $
   */
  class DocViewSAXEventGenerator extends AbstractSAXEventGenerator {
  
      private static Logger log = Logger.getLogger(DocViewSAXEventGenerator.class);
  
      protected final HierarchyManager hierMgr;
  
      public static final String CDATA_TYPE = "CDATA";
      // jcr:root
      public static final QName NODENAME_ROOT =
  	    new QName(NamespaceRegistryImpl.NS_JCR_URI, "root");
      // jcr:xmltext
      public static final QName NODENAME_XMLTEXT =
  	    new QName(NamespaceRegistryImpl.NS_JCR_URI, "xmltext");
      // jcr:xmltext
      public static final QName PROPNAME_XMLCHARACTERS =
  	    new QName(NamespaceRegistryImpl.NS_JCR_URI, "xmlcharacters");
  
      // used to temporarily store properties of a node
      private final List props;
  
      /**
       * 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
       */
      DocViewSAXEventGenerator(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;
  
  	props = new ArrayList();
      }
  
      /**
       * @see AbstractSAXEventGenerator#entering(NodeState, QName, int)
       */
      protected void entering(NodeState state, QName name, int level)
  	    throws RepositoryException, SAXException {
  	// nop
      }
  
      /**
       * @see AbstractSAXEventGenerator#enteringProperties(NodeState, QName, int)
       */
      protected void enteringProperties(NodeState state, QName name, int level)
  	    throws RepositoryException, SAXException {
  	// reset list of properties
  	props.clear();
      }
  
      /**
       * @see AbstractSAXEventGenerator#leavingProperties(NodeState, QName, int)
       */
      protected void leavingProperties(NodeState state, QName name, int level)
  	    throws RepositoryException, SAXException {
  	if (name.equals(NODENAME_XMLTEXT)) {
  	    // the node represents xml character data
  	    Iterator iter = props.iterator();
  	    while (iter.hasNext()) {
  		PropertyState propState = (PropertyState) iter.next();
  		QName propName = propState.getName();
  		if (propName.equals(PROPNAME_XMLCHARACTERS)) {
  		    InternalValue val = propState.getValues()[0];
  		    char[] chars = val.toJCRValue(nsReg).getString().toCharArray();
  		    contentHandler.characters(chars, 0, chars.length);
  		}
  	    }
  	} else {
  	    // regalur node
  
  	    // element name
  	    String elemName;
  	    if (state.getParentUUIDs().size() == 0) {
  		// root node needs a name
  		elemName = NODENAME_ROOT.toJCRName(nsReg);
  	    } else {
  		elemName = name.toJCRName(nsReg);
  	    }
  	    if (!XMLChar.isValidName(elemName)) {
  		throw new InvalidSerializedDataException("the node name is not a valid xml element name: " + elemName);
  	    }
  
  	    // attributes (properties)
  	    AttributesImpl attrs = new AttributesImpl();
  	    Iterator iter = props.iterator();
  	    while (iter.hasNext()) {
  		PropertyState propState = (PropertyState) iter.next();
  		QName propName = propState.getName();
  		// attribute name
  		String attrName = propState.getName().toJCRName(nsReg);
  		if (!XMLChar.isValidName(attrName)) {
  		    throw new InvalidSerializedDataException("the property name is not a valid xml attribute name: " + attrName);
  		}
  		// attribute value
  		String attrValue;
  		int type = propState.getType();
  		// process property value (guaranteed to be single-valued and non-null)
  		InternalValue val = propState.getValues()[0];
  		if (type == PropertyType.BINARY) {
  		    if (binaryAsLink) {
  			attrValue = hierMgr.getPath(new PropertyId(propState.getParentUUID(), propState.getName())).toJCRPath(nsReg);
  		    } else {
  			// binary data, base64 encoding required
  			BLOBFileValue blob = (BLOBFileValue) val.internalValue();
  			InputStream in = blob.getStream();
  			StringWriter writer = new StringWriter();
  			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);
  			    }
  			}
  			attrValue = writer.toString();
  		    }
  		} else {
  		    attrValue = val.toJCRValue(nsReg).getString();
  		}
  		attrs.addAttribute(propName.getNamespaceURI(), propName.getLocalName(), propName.toJCRName(nsReg), CDATA_TYPE, attrValue);
  	    }
  	    // start element (node)
  	    contentHandler.startElement(name.getNamespaceURI(), name.getLocalName(), elemName, attrs);
  	}
      }
  
      /**
       * @see AbstractSAXEventGenerator#leaving(NodeState, QName, int)
       */
      protected void leaving(NodeState state, QName name, int level)
  	    throws RepositoryException, SAXException {
  	if (name.equals(NODENAME_XMLTEXT)) {
  	    // the node represents xml character data
  	    // (already processed in leavingProperties(NodeState, QName, int)
  	    return;
  	}
  	// element name
  	String elemName;
  	if (state.getParentUUIDs().size() == 0) {
  	    // root node needs a name
  	    elemName = NODENAME_ROOT.toJCRName(nsReg);
  	} else {
  	    elemName = name.toJCRName(nsReg);
  	}
  
  	// end element (node)
  	contentHandler.endElement(name.getNamespaceURI(), name.getLocalName(), elemName);
      }
  
      /**
       * @see AbstractSAXEventGenerator#entering(PropertyState, int)
       */
      protected void entering(PropertyState state, int level)
  	    throws RepositoryException, SAXException {
  	// collect property state in temporary list (will be processed in leavingProperties(NodeState, QName, int)
  	InternalValue[] values = state.getValues();
  	if (values != null && values.length > 0) {
  	    if (values.length != 1) {
  		throw new InvalidSerializedDataException("unable to serialize multi-valued property in document view: " + state.getName().toJCRName(nsReg));
  	    }
  	    if (values[0] != null) {
  		props.add(state);
  	    }
  	}
      }
  
      /**
       * @see AbstractSAXEventGenerator#leaving(PropertyState, int)
       */
      protected void leaving(PropertyState state, int level)
  	    throws RepositoryException, SAXException {
  	// nop
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org