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]

Reply via email to