You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2007/02/27 10:16:19 UTC

svn commit: r512186 - in /jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons: AbstractSession.java AbstractWorkspace.java DefaultContentHandler.java

Author: jukka
Date: Tue Feb 27 01:16:18 2007
New Revision: 512186

URL: http://svn.apache.org/viewvc?view=rev&rev=512186
Log:
JCR-742: Added abstract base classes for sessions and workspaces

Added:
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java   (with props)
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java   (with props)
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java   (with props)

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java?view=auto&rev=512186
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java Tue Feb 27 01:16:18 2007
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      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.jackrabbit.commons;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.jcr.Credentials;
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Abstract base class for implementing the JCR {@link Session} interface.
+ */
+public abstract class AbstractSession implements Session {
+
+    /**
+     * Calls {@link Session#exportDocumentView(String, ContentHandler, boolean, boolean)}
+     * with the given arguments and a {@link ContentHandler} that serializes
+     * SAX events to the given output stream.
+     *
+     * @param absPath passed through
+     * @param out output stream to which the SAX events are serialized
+     * @param skipBinary passed through
+     * @param noRecurse passed through
+     * @throws IOException if the SAX serialization failed
+     * @throws RepositoryException if another error occurs
+     */
+    public void exportDocumentView(
+            String absPath, OutputStream out,
+            boolean skipBinary, boolean noRecurse)
+            throws IOException, RepositoryException {
+        try {
+            ContentHandler handler = getExportContentHandler(out);
+            exportDocumentView(absPath, handler, skipBinary, noRecurse);
+        } catch (SAXException e) {
+            Exception exception = e.getException();
+            if (exception instanceof RepositoryException) {
+                throw (RepositoryException) exception;
+            } else if (exception instanceof IOException) {
+                throw (IOException) exception;
+            } else {
+                throw new RepositoryException(
+                        "Error serializing document view XML", e);
+            }
+        }
+    }
+
+    /**
+     * Calls {@link Session#exportSystemView(String, ContentHandler, boolean, boolean)}
+     * with the given arguments and a {@link ContentHandler} that serializes
+     * SAX events to the given output stream.
+     *
+     * @param absPath passed through
+     * @param out output stream to which the SAX events are serialized
+     * @param skipBinary passed through
+     * @param noRecurse passed through
+     * @throws IOException if the SAX serialization failed
+     * @throws RepositoryException if another error occurs
+     */
+    public void exportSystemView(
+            String absPath, OutputStream out,
+            boolean skipBinary, boolean noRecurse)
+            throws IOException, RepositoryException {
+        try {
+            ContentHandler handler = getExportContentHandler(out);
+            exportSystemView(absPath, handler, skipBinary, noRecurse);
+        } catch (SAXException e) {
+            Exception exception = e.getException();
+            if (exception instanceof RepositoryException) {
+                throw (RepositoryException) exception;
+            } else if (exception instanceof IOException) {
+                throw (IOException) exception;
+            } else {
+                throw new RepositoryException(
+                        "Error serializing system view XML", e);
+            }
+        }
+    }
+
+    /**
+     * Parses the given input stream as an XML document and processes the
+     * SAX events using the {@link ContentHandler} returned by
+     * {@link Session#getImportContentHandler(String, int)}.
+     *
+     * @param parentAbsPath passed through
+     * @param in input stream to be parsed as XML and imported
+     * @param uuidBehavior passed through
+     * @throws IOException if an I/O error occurs
+     * @throws RepositoryException if another error occurs
+     */
+    public void importXML(
+            String parentAbsPath, InputStream in, int uuidBehavior)
+            throws IOException, RepositoryException {
+        ContentHandler handler =
+            getImportContentHandler(parentAbsPath, uuidBehavior);
+        new DefaultContentHandler(handler).parse(in);
+    }
+
+    /**
+     * Returns the node or property at the given path.
+     * <p>
+     * The default implementation:
+     * <ul>
+     * <li>Throws a {@link PathNotFoundException} if the given path
+     *     does not start with a slash.
+     * <li>Returns the root node if the given path is "/"
+     * <li>Calls {@link Node#getNode(String)} on the root node with the
+     *     part of the given path after the first slash
+     * <li>Calls {@link Node#getProperty(String)} similarly in case the
+     *     above call fails with a {@link PathNotFoundException}
+     * </ul>
+     *
+     * @param absPath absolute path
+     * @return the node or property with the given path
+     * @throws PathNotFoundException if the given path is invalid or not found
+     * @throws RepositoryException if another error occurs
+     */
+    public Item getItem(String absPath)
+            throws PathNotFoundException, RepositoryException {
+        if (!absPath.startsWith("/")) {
+            throw new PathNotFoundException("Not an absolute path: " + absPath);
+        }
+
+        Node root = getRootNode();
+        String relPath = absPath.substring(1);
+        if (relPath.length() == 0) {
+            return root;
+        }
+
+        try {
+            return root.getNode(relPath);
+        } catch (PathNotFoundException e) {
+            return root.getProperty(relPath);
+        }
+    }
+
+    /**
+     * Calls {@link #getItem(String)} with the given path and returns
+     * <code>true</code> if the call succeeds. Returns <code>false</code>
+     * if a {@link PathNotFoundException} was thrown. Other exceptions are
+     * passed through.
+     *
+     * @param absPath absolute path
+     * @return <code>true</code> if an item exists at the given path,
+     *         <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    public boolean itemExists(String absPath) throws RepositoryException {
+        try {
+            getItem(absPath);
+            return true;
+        } catch (PathNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Logs in the same workspace with the given credentials.
+     * <p>
+     * The default implementation:
+     * <ul>
+     * <li>Retrieves the {@link Repository} instance using
+     *     {@link Session#getRepository()}
+     * <li>Retrieves the current workspace using {@link Session#getWorkspace()}
+     * <li>Retrieves the name of the current workspace using
+     *     {@link Workspace#getName()}
+     * <li>Calls {@link Repository#login(Credentials, String)} on the
+     *     retrieved repository with the given credentials and the retrieved
+     *     workspace name.
+     * </ul>
+     *
+     * @param credentials login credentials
+     * @return logged in session
+     * @throws RepositoryException if an error occurs
+     */
+    public Session impersonate(Credentials credentials)
+            throws RepositoryException {
+        return getRepository().login(credentials, getWorkspace().getName());
+    }
+
+    //-------------------------------------------------------------< private >
+
+    /**
+     * Creates a {@link ContentHandler} instance that serializes the
+     * received SAX events to the given output stream.
+     *
+     * @param stream output stream to which the SAX events are serialized
+     * @return SAX content handler
+     * @throws RepositoryException if an error occurs
+     */
+    private ContentHandler getExportContentHandler(OutputStream stream)
+            throws RepositoryException {
+        try {
+            SAXTransformerFactory stf = (SAXTransformerFactory)
+                SAXTransformerFactory.newInstance();
+            TransformerHandler handler = stf.newTransformerHandler();
+
+            Transformer transformer = handler.getTransformer();
+            transformer.setParameter(OutputKeys.METHOD, "xml");
+            transformer.setParameter(OutputKeys.ENCODING, "UTF-8");
+            transformer.setParameter(OutputKeys.INDENT, "no");
+
+            handler.setResult(new StreamResult(stream));
+            return handler;
+        } catch (TransformerFactoryConfigurationError e) {
+            throw new RepositoryException(
+                    "SAX transformer implementation not available", e);
+        } catch (TransformerException e) {
+            throw new RepositoryException(
+                    "Error creating an XML export content handler", e);
+        }
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java?view=auto&rev=512186
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java Tue Feb 27 01:16:18 2007
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      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.jackrabbit.commons;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Workspace;
+
+import org.xml.sax.ContentHandler;
+
+/**
+ * Abstract base class for implementing the JCR {@link Workspace} interface.
+ */
+public abstract class AbstractWorkspace implements Workspace {
+
+    /**
+     * Parses the given input stream as an XML document and processes the
+     * SAX events using the {@link ContentHandler} returned by
+     * {@link Workspace#getImportContentHandler(String, int)}.
+     *
+     * @param parentAbsPath passed through
+     * @param in input stream to be parsed as XML and imported
+     * @param uuidBehavior passed through
+     * @throws IOException if an I/O error occurs
+     * @throws RepositoryException if another error occurs
+     */
+    public void importXML(
+            String parentAbsPath, InputStream in, int uuidBehavior)
+            throws IOException, RepositoryException {
+        ContentHandler handler =
+            getImportContentHandler(parentAbsPath, uuidBehavior);
+        new DefaultContentHandler(handler).parse(in);
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractWorkspace.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java?view=auto&rev=512186
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java Tue Feb 27 01:16:18 2007
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      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.jackrabbit.commons;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.RepositoryException;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Adapter class for exposing a {@link ContentHandler} instance as
+ * {@link DefaultHandler} object.
+ */
+class DefaultContentHandler extends DefaultHandler {
+
+    /**
+     * The adapted content handler instance.
+     */
+    private final ContentHandler handler;
+
+    /**
+     * Creates a {@link DefaultHandler} adapter for the given content
+     * handler.
+     *
+     * @param handler content handler
+     */
+    public DefaultContentHandler(ContentHandler handler) {
+        this.handler = handler;
+    }
+
+    /**
+     * Utility method that parses the given input stream using this handler.
+     *
+     * @param in XML input stream
+     * @throws IOException if an I/O error occurs
+     * @throws RepositoryException if another error occurs
+     */
+    public void parse(InputStream in) throws IOException, RepositoryException {
+        try {
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            factory.setNamespaceAware(true);
+            factory.setFeature(
+                    "http://xml.org/sax/features/namespace-prefixes", false);
+
+            SAXParser parser = factory.newSAXParser();
+            parser.parse(new InputSource(in), this);
+        } catch (FactoryConfigurationError e) {
+            throw new RepositoryException(
+                    "SAX parser implementation not available", e);
+        } catch (ParserConfigurationException e) {
+            throw new RepositoryException("SAX parser configuration error", e);
+        } catch (SAXException e) {
+            Exception exception = e.getException();
+            if (exception instanceof RepositoryException) {
+                throw (RepositoryException) exception;
+            } else if (exception instanceof IOException) {
+                throw (IOException) exception;
+            } else {
+                throw new InvalidSerializedDataException(
+                        "Error parsing XML import", e);
+            }
+        }
+    }
+
+    //------------------------------------------------------< ContentHandler >
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param ch passed through
+     * @param start passed through
+     * @param length passed through
+     * @throws SAXException if an error occurs
+     */
+    public void characters(char[] ch, int start, int length)
+            throws SAXException {
+        handler.characters(ch, start, length);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @throws SAXException if an error occurs
+     */
+    public void endDocument() throws SAXException {
+        handler.endDocument();
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param namespaceURI passed through
+     * @param localName passed through
+     * @param qName passed through
+     * @throws SAXException if an error occurs
+     */
+    public void endElement(
+            String namespaceURI, String localName, String qName)
+            throws SAXException {
+        handler.endElement(namespaceURI, localName, qName);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param prefix passed through
+     * @throws SAXException if an error occurs
+     */
+    public void endPrefixMapping(String prefix) throws SAXException {
+        handler.endPrefixMapping(prefix);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param ch passed through
+     * @param start passed through
+     * @param length passed through
+     * @throws SAXException if an error occurs
+     */
+    public void ignorableWhitespace(char[] ch, int start, int length)
+            throws SAXException {
+        handler.ignorableWhitespace(ch, start, length);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param target passed through
+     * @param data passed through
+     * @throws SAXException if an error occurs
+     */
+    public void processingInstruction(String target, String data)
+            throws SAXException {
+        handler.processingInstruction(target, data);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param locator passed through
+     */
+    public void setDocumentLocator(Locator locator) {
+        handler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param name passed through
+     * @throws SAXException if an error occurs
+     */
+    public void skippedEntity(String name) throws SAXException {
+        handler.skippedEntity(name);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @throws SAXException if an error occurs
+     */
+    public void startDocument() throws SAXException {
+        handler.startDocument();
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param namespaceURI passed through
+     * @param localName passed through
+     * @param qName passed through
+     * @param atts passed through
+     * @throws SAXException if an error occurs
+     */
+    public void startElement(
+            String namespaceURI, String localName, String qName,
+            Attributes atts) throws SAXException {
+        handler.startElement(namespaceURI, localName, qName, atts);
+    }
+
+    /**
+     * Delegated to {@link #handler}.
+     *
+     * @param prefix passed through
+     * @param uri passed through
+     * @throws SAXException if an error occurs
+     */
+    public void startPrefixMapping(String prefix, String uri)
+            throws SAXException {
+        handler.startPrefixMapping(prefix, uri);
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/DefaultContentHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native