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>[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>
  + * <li><code>[EMAIL PROTECTED] #entering(PropertyState, int)}</code></li>
  + * <li><code>[EMAIL PROTECTED] #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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to