You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2006/11/27 15:02:17 UTC

svn commit: r479620 [2/2] - in /lenya/trunk/src: impl/java/org/apache/lenya/cms/publication/ java/org/apache/lenya/ac/ java/org/apache/lenya/cms/cocoon/flow/ java/org/apache/lenya/cms/cocoon/source/ java/org/apache/lenya/cms/cocoon/transformation/ java...

Modified: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java?view=diff&rev=479620&r1=479619&r2=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java (original)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java Mon Nov 27 06:02:13 2006
@@ -17,36 +17,22 @@
  */
 package org.apache.lenya.cms.repository;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.net.MalformedURLException;
 import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
 
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.excalibur.source.ModifiableSource;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceNotFoundException;
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.excalibur.source.TraversableSource;
 import org.apache.lenya.ac.Identity;
 import org.apache.lenya.ac.User;
-import org.apache.lenya.cms.cocoon.source.SourceUtil;
 import org.apache.lenya.cms.metadata.MetaData;
 import org.apache.lenya.cms.metadata.MetaDataException;
-import org.apache.lenya.cms.publication.DocumentFactory;
-import org.apache.lenya.cms.publication.DocumentUtil;
-import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.observation.RepositoryEvent;
+import org.apache.lenya.cms.observation.RepositoryEventFactory;
 import org.apache.lenya.cms.rc.RCML;
 import org.apache.lenya.cms.rc.RCMLEntry;
 import org.apache.lenya.cms.rc.RevisionController;
@@ -61,25 +47,42 @@
  */
 public class SourceNode extends AbstractLogEnabled implements Node, Transactionable {
 
-    private String sourceURI;
     protected ServiceManager manager;
-    protected static final String FILE_PREFIX = "file:/";
-    protected static final String CONTEXT_PREFIX = "context://";
-    protected static final String LENYA_META_SUFFIX = "meta";
+    
+    private ContentSourceWrapper contentSource;
+    private MetaSourceWrapper metaSource;
 
     /**
      * Ctor.
      * 
      * @param session
-     * @param sourceURI
+     * @param sourceUri
      * @param manager
      * @param logger
      */
-    public SourceNode(Session session, String sourceURI, ServiceManager manager, Logger logger) {
-        this.sourceURI = sourceURI;
+    public SourceNode(Session session, String sourceUri, ServiceManager manager, Logger logger) {
         this.manager = manager;
         enableLogging(logger);
         this.session = session;
+        
+        this.contentSource = new ContentSourceWrapper(this, sourceUri, manager, logger);
+        this.metaSource = new MetaSourceWrapper(this, sourceUri, manager, logger);
+    }
+    
+    protected ContentSourceWrapper getContentSource() {
+        return this.contentSource;
+    }
+    
+    protected MetaSourceWrapper getMetaSource() {
+        return this.metaSource;
+    }
+
+    /**
+     * @see org.apache.lenya.transaction.Transactionable#deleteTransactionable()
+     */
+    public void deleteTransactionable() throws RepositoryException {
+        this.contentSource.deleteTransactionable();
+        this.metaSource.deleteTransactionable();
     }
 
     protected String getUserId() {
@@ -95,73 +98,11 @@
     }
 
     /**
-     * Returns the URI of the actual source which is used.
-     * 
-     * @return A string.
-     */
-    protected String getRealSourceURI() {
-        String contentDir = null;
-        String publicationId = null;
-        try {
-            String pubBase = Node.LENYA_PROTOCOL + Publication.PUBLICATION_PREFIX_URI + "/";
-            String publicationsPath = this.sourceURI.substring(pubBase.length());
-            publicationId = publicationsPath.split("/")[0];
-            DocumentFactory factory = DocumentUtil
-                    .createDocumentFactory(this.manager, getSession());
-            Publication pub = factory.getPublication(publicationId);
-            contentDir = pub.getContentDir();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        String contentBaseUri = null;
-        String urlID = this.sourceURI.substring(Node.LENYA_PROTOCOL.length());
-
-        // Substitute e.g. "lenya://lenya/pubs/PUB_ID/content" by "contentDir"
-        String filePrefix = urlID.substring(0, urlID.indexOf(publicationId)) + publicationId;
-        String tempString = urlID.substring(filePrefix.length() + 1);
-        String fileMiddle = tempString.substring(0, tempString.indexOf("/"));
-        String fileSuffix = tempString.substring(fileMiddle.length() + 1, tempString.length());
-        String uriSuffix;
-        if (new File(contentDir).isAbsolute()) {
-            // Absolute
-            contentBaseUri = FILE_PREFIX + contentDir;
-            uriSuffix = File.separator + fileSuffix;
-        } else {
-            // Relative
-            contentBaseUri = CONTEXT_PREFIX + contentDir;
-            uriSuffix = "/" + fileSuffix;
-        }
-
-        try {
-            if (!SourceUtil.exists(contentBaseUri, this.manager)) {
-                getLogger().info(
-                        "The content directory [" + contentBaseUri + "] does not exist. "
-                                + "It will be created as soon as documents are added.");
-            }
-        } catch (ServiceException e) {
-            throw new RuntimeException(e);
-        } catch (MalformedURLException e) {
-            throw new RuntimeException(e);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-
-        String realSourceUri = contentBaseUri + uriSuffix;
-
-        if (getLogger().isDebugEnabled()) {
-            getLogger().debug("Real Source URI: " + realSourceUri);
-        }
-
-        return realSourceUri;
-    }
-
-    /**
      * @see org.apache.lenya.transaction.Transactionable#checkin()
      */
     public void checkin() throws RepositoryException {
         if (!isCheckedOut()) {
-            throw new RepositoryException("Cannot check in node [" + this.sourceURI
+            throw new RepositoryException("Cannot check in node [" + getSourceURI()
                     + "]: not checked out!");
         }
 
@@ -208,7 +149,7 @@
     public void checkout() throws RepositoryException {
 
         if (getLogger().isDebugEnabled())
-            getLogger().debug("SourceNode::checkout() called, sourceURI [" + sourceURI + "]");
+            getLogger().debug("SourceNode::checkout() called, sourceURI [" + getSourceURI() + "]");
 
         if (!isCheckedOut()) {
             try {
@@ -219,36 +160,6 @@
         }
     }
 
-    /**
-     * @see org.apache.lenya.transaction.Transactionable#deleteTransactionable()
-     */
-    public void deleteTransactionable() throws RepositoryException {
-        try {
-            if (!isCheckedOut()) {
-                throw new RuntimeException("Cannot delete source [" + this.sourceURI
-                        + "]: not checked out!");
-            } else {
-                this.data = null;
-                SourceUtil.delete(getRealSourceURI(), this.manager);
-            }
-        } catch (Exception e) {
-            throw new RepositoryException(e);
-        }
-    }
-
-    public void removed() {
-        Node node;
-        try {
-            node = getDocumentNode();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        for (Iterator i = this.listeners.iterator(); i.hasNext();) {
-            NodeListener listener = (NodeListener) i.next();
-            listener.nodeRemoved(node, getSession().getIdentity());
-        }
-    }
-
     private RevisionController revisionController;
 
     protected RevisionController getRevisionController() throws RepositoryException {
@@ -274,77 +185,6 @@
     }
 
     /**
-     * @see org.apache.lenya.transaction.Transactionable#saveTransactionable()
-     */
-    public synchronized void saveTransactionable() throws RepositoryException {
-        if (!isCheckedOut()) {
-            throw new RepositoryException("Cannot save node [" + this.sourceURI
-                    + "]: not checked out!");
-        }
-        if (getLogger().isDebugEnabled()) {
-            getLogger().debug("Saving [" + this + "] to source [" + getRealSourceURI() + "]");
-        }
-
-        if (this.data != null) {
-            SourceResolver resolver = null;
-            ModifiableSource source = null;
-            InputStream in = null;
-            OutputStream out = null;
-            try {
-
-                resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
-                source = (ModifiableSource) resolver.resolveURI(getRealSourceURI());
-
-                out = source.getOutputStream();
-
-                byte[] buf = new byte[4096];
-                in = new ByteArrayInputStream(this.data);
-                int read = in.read(buf);
-
-                while (read > 0) {
-                    out.write(buf, 0, read);
-                    read = in.read(buf);
-                }
-            } catch (Exception e) {
-                throw new RepositoryException(e);
-            } finally {
-
-                try {
-                    if (in != null) {
-                        in.close();
-                    }
-                    if (out != null) {
-                        out.flush();
-                        out.close();
-                    }
-                } catch (Throwable t) {
-                    throw new RuntimeException("Could not close streams: ", t);
-                }
-
-                if (resolver != null) {
-                    if (source != null) {
-                        resolver.release(source);
-                    }
-                    manager.release(resolver);
-                }
-            }
-        }
-    }
-
-    public void changed() {
-        Node node;
-        try {
-            node = getDocumentNode();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        for (Iterator i = this.listeners.iterator(); i.hasNext();) {
-            NodeListener listener = (NodeListener) i.next();
-            listener.nodeChanged(node, getSession().getIdentity());
-        }
-    }
-
-    /**
      * @return The document node, if this is a meta data node, or the node
      *         itself otherwise.
      * @throws ServiceException
@@ -399,13 +239,6 @@
             throw new RepositoryException(e);
         }
 
-        if (!getSourceURI().endsWith("." + LENYA_META_SUFFIX)) {
-            lockMetaData();
-        }
-    }
-
-    protected void lockMetaData() throws RepositoryException {
-        SourceUtil.lock(getMetaSourceUri(), this.manager);
     }
 
     /**
@@ -435,30 +268,10 @@
     }
 
     /**
-     * @see org.apache.lenya.cms.repository.Node#exists()
-     */
-    public boolean exists() throws RepositoryException {
-        loadData();
-        return this.data != null;
-    }
-
-    /**
      * @see java.lang.Object#toString()
      */
     public String toString() {
-        return "node " + this.sourceURI;
-    }
-
-    byte[] data = null;
-
-    /**
-     * @see org.apache.lenya.cms.repository.Node#getInputStream()
-     */
-    public synchronized InputStream getInputStream() throws RepositoryException {
-        if (!exists()) {
-            throw new RuntimeException(this + " does not exist!");
-        }
-        return new ByteArrayInputStream(this.data);
+        return "node " + getSourceURI();
     }
 
     /**
@@ -469,13 +282,13 @@
         TraversableSource source = null;
         try {
             resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
-            source = (TraversableSource) resolver.resolveURI(getRealSourceURI());
+            source = (TraversableSource) resolver.resolveURI(this.contentSource.getRealSourceUri());
             Collection children = source.getChildren();
             java.util.Iterator iterator = children.iterator();
             java.util.Vector newChildren = new java.util.Vector();
             while (iterator.hasNext()) {
                 TraversableSource child = (TraversableSource) iterator.next();
-                newChildren.add(new SourceNode(getSession(), sourceURI + "/" + child.getName(),
+                newChildren.add(new SourceNode(getSession(), getSourceURI() + "/" + child.getName(),
                         this.manager, getLogger()));
             }
             return newChildren;
@@ -492,7 +305,7 @@
         TraversableSource source = null;
         try {
             resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
-            source = (TraversableSource) resolver.resolveURI(getRealSourceURI());
+            source = (TraversableSource) resolver.resolveURI(this.contentSource.getRealSourceUri());
             return source.isCollection();
         } catch (Exception e) {
             throw new RepositoryException(e);
@@ -500,173 +313,10 @@
     }
 
     /**
-     * Loads the data from the real source.
-     * 
-     * @throws RepositoryException if an error occurs.
-     */
-    protected synchronized void loadData() throws RepositoryException {
-
-        if (this.data != null) {
-            return;
-        }
-
-        ByteArrayOutputStream out = null;
-        InputStream in = null;
-        SourceResolver resolver = null;
-        TraversableSource source = null;
-        try {
-            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
-            source = (TraversableSource) resolver.resolveURI(getRealSourceURI());
-
-            if (source.exists() && !source.isCollection()) {
-                byte[] buf = new byte[4096];
-                out = new ByteArrayOutputStream();
-                in = source.getInputStream();
-                int read = in.read(buf);
-
-                while (read > 0) {
-                    out.write(buf, 0, read);
-                    read = in.read(buf);
-                }
-
-                this.data = out.toByteArray();
-            }
-        } catch (Exception e) {
-            throw new RepositoryException(e);
-        } finally {
-            try {
-                if (in != null)
-                    in.close();
-                if (out != null)
-                    out.close();
-            } catch (Exception e) {
-                throw new RepositoryException(e);
-            }
-
-            if (resolver != null) {
-                if (source != null) {
-                    resolver.release(source);
-                }
-                this.manager.release(resolver);
-            }
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.repository.Node#getOutputStream()
-     */
-    public synchronized OutputStream getOutputStream() throws RepositoryException {
-        if (getLogger().isDebugEnabled())
-            getLogger().debug("Get OutputStream for " + getSourceURI());
-        try {
-            registerDirty();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        return new NodeOutputStream();
-    }
-
-    /**
-     * Output stream.
-     */
-    private class NodeOutputStream extends ByteArrayOutputStream {
-        /**
-         * @see java.io.OutputStream#close()
-         */
-        public synchronized void close() throws IOException {
-            SourceNode.this.data = super.toByteArray();
-            SourceNode.this.lastModified = new Date().getTime();
-            super.close();
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.repository.Node#getContentLength()
-     */
-    public long getContentLength() throws RepositoryException {
-        loadData();
-        return this.data.length;
-    }
-
-    private long lastModified = -1;
-
-    /**
-     * @see org.apache.lenya.cms.repository.Node#getLastModified()
-     */
-    public long getLastModified() throws RepositoryException {
-        SourceResolver resolver = null;
-        Source source = null;
-        try {
-            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
-            source = resolver.resolveURI(getRealSourceURI());
-
-            long sourceLastModified;
-
-            if (source.exists()) {
-                sourceLastModified = source.getLastModified();
-                if (sourceLastModified > this.lastModified) {
-                    this.lastModified = sourceLastModified;
-                }
-            } else if (this.lastModified == -1) {
-                throw new RepositoryException("The source [" + getRealSourceURI()
-                        + "] does not exist!");
-            }
-
-            return this.lastModified;
-
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (resolver != null) {
-                if (source != null) {
-                    resolver.release(source);
-                }
-                this.manager.release(resolver);
-            }
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.repository.Node#getMimeType()
-     */
-    public String getMimeType() throws RepositoryException {
-        SourceResolver resolver = null;
-        Source source = null;
-        try {
-            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
-            source = resolver.resolveURI(getRealSourceURI());
-            if (source.exists()) {
-                return source.getMimeType();
-            } else {
-                throw new SourceNotFoundException("The source [" + getRealSourceURI()
-                        + "] does not exist!");
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (resolver != null) {
-                if (source != null) {
-                    resolver.release(source);
-                }
-                this.manager.release(resolver);
-            }
-        }
-    }
-
-    /**
      * @see org.apache.lenya.cms.repository.Node#getSourceURI()
      */
     public String getSourceURI() {
-        return sourceURI;
-    }
-
-    /**
-     * @return The source URI of the meta data node. TODO: This is a hack and
-     *         can be removed when UUIDs are used.
-     */
-    protected String getMetaSourceUri() {
-        String sourceUri = getSourceURI();
-        return sourceUri + "." + LENYA_META_SUFFIX;
+        return this.contentSource.getSourceUri();
     }
 
     private Session session;
@@ -689,28 +339,14 @@
     public void registerRemoved() throws RepositoryException {
         try {
             getSession().registerRemoved(this);
-            SourceUtil.delete(getMetaSourceUri(), this.manager);
+            //SourceUtil.delete(getMetaSourceUri(), this.manager);
         } catch (Exception e) {
             throw new RepositoryException(e);
         }
     }
 
-    private Set listeners = new HashSet();
-
-    public void addListener(NodeListener listener) throws RepositoryException {
-        if (this.listeners.contains(listener)) {
-            throw new RepositoryException("The listener [" + listener
-                    + "] is already registered for node [" + this + "]!");
-        }
-        this.listeners.add(listener);
-    }
-
-    public boolean isListenerRegistered(NodeListener listener) {
-        return this.listeners.contains(listener);
-    }
-
     private RCML rcml;
-    
+
     public RCML getRcml() {
         if (this.rcml == null) {
             try {
@@ -723,24 +359,67 @@
     }
 
     public History getHistory() {
-        return new SourceNodeHistory(this, this.manager);
+        return new SourceNodeHistory(this, this.manager, getLogger());
     }
 
     public MetaData getMetaData(String namespaceUri) throws MetaDataException {
-        return getMetaDataHandler().getMetaData(namespaceUri);
+        return this.metaSource.getMetaDataHandler().getMetaData(namespaceUri);
     }
 
-    private SourceNodeMetaDataHandler metaDataHandler = null;
-    
-    protected SourceNodeMetaDataHandler getMetaDataHandler() {
-        if (this.metaDataHandler == null) {
-            this.metaDataHandler = new SourceNodeMetaDataHandler(this.manager, getMetaSourceUri());
+    private RepositoryEvent event;
+
+    public RepositoryEvent getEvent() {
+        if (this.event == null) {
+            this.event = RepositoryEventFactory.createEvent(this.manager, this, getLogger());
         }
-        return this.metaDataHandler;
+        return this.event;
+    }
+
+    public boolean exists() throws RepositoryException {
+        return this.contentSource.exists() || this.metaSource.exists();
+    }
+
+    public OutputStream getOutputStream() throws RepositoryException {
+        return this.contentSource.getOutputStream();
+    }
+
+    public long getContentLength() throws RepositoryException {
+        return this.contentSource.getContentLength();
+    }
+
+    public InputStream getInputStream() throws RepositoryException {
+        return this.contentSource.getInputStream();
+    }
+
+    public long getLastModified() throws RepositoryException {
+        
+        if (!exists()) {
+            throw new RepositoryException("The node [" + this + "] does not exist!");
+        }
+        
+        long contentLastModified = 0;
+        if (this.contentSource.exists()) {
+            contentLastModified = this.contentSource.getLastModified();
+        }
+        long metaLastModified = 0;
+        if (this.metaSource.exists()) {
+            metaLastModified = this.metaSource.getLastModified();
+        }
+        
+        return Math.max(contentLastModified, metaLastModified);
+    }
+
+    public String getMimeType() throws RepositoryException {
+        return this.contentSource.getMimeType();
     }
 
     public String[] getMetaDataNamespaceUris() throws MetaDataException {
-        return getMetaDataHandler().getMetaDataNamespaceUris();
+        return this.metaSource.getMetaDataNamespaceUris();
+    }
+
+    public void saveTransactionable() throws TransactionException {
+        this.contentSource.saveTransactionable();
+        this.metaSource.saveTransactionable();
     }
 
 }

Modified: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeFactory.java?view=diff&rev=479620&r1=479619&r2=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeFactory.java (original)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeFactory.java Mon Nov 27 06:02:13 2006
@@ -22,7 +22,6 @@
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
 import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.lenya.cms.observation.ObservationRegistry;
 
 /**
  * Factory to create source nodes.
@@ -53,18 +52,6 @@
             throw new RepositoryException("The session has not been set!");
         }
         Node node = new SourceNode(this.session, key, this.manager, getLogger());
-        ObservationRegistry registry = null;
-        try {
-            registry = (ObservationRegistry) this.manager.lookup(ObservationRegistry.ROLE);
-            node.addListener(registry);
-        } catch (ServiceException e) {
-            throw new RepositoryException(e);
-        }
-        finally {
-            if (registry != null) {
-                this.manager.release(registry);
-            }
-        }
         return node;
     }
 

Modified: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeHistory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeHistory.java?view=diff&rev=479620&r1=479619&r2=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeHistory.java (original)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeHistory.java Mon Nov 27 06:02:13 2006
@@ -17,12 +17,15 @@
  */
 package org.apache.lenya.cms.repository;
 
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.service.ServiceManager;
 
 /**
  * Revision history implementation.
  */
-public class SourceNodeHistory implements History {
+public class SourceNodeHistory extends AbstractLogEnabled implements History {
 
     private SourceNode node;
     private ServiceManager manager;
@@ -31,10 +34,12 @@
      * Ctor.
      * @param node The node which the history belongs to.
      * @param manager The service manager.
+     * @param logger The logger.
      */
-    public SourceNodeHistory(SourceNode node, ServiceManager manager) {
+    public SourceNodeHistory(SourceNode node, ServiceManager manager, Logger logger) {
         this.node = node;
         this.manager = manager;
+        ContainerUtil.enableLogging(this, logger);
     }
 
     public Revision getLatestRevision() {
@@ -47,7 +52,7 @@
     }
 
     public Revision getRevision(int number) throws RepositoryException {
-        return new SourceNodeRevision(this.node, number, this.manager);
+        return new SourceNodeRevision(this.node, number, this.manager, getLogger());
     }
 
 }

Modified: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java?view=diff&rev=479620&r1=479619&r2=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java (original)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java Mon Nov 27 06:02:13 2006
@@ -21,6 +21,7 @@
 package org.apache.lenya.cms.repository;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -28,6 +29,7 @@
 
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.lenya.cms.cocoon.source.SourceUtil;
 import org.apache.lenya.cms.rc.CheckInEntry;
@@ -48,12 +50,11 @@
  */
 public class SourceNodeRCML implements RCML {
 
-
     private SourceNode node;
     private Document document = null;
     private boolean dirty = false;
     private int maximalNumberOfEntries = 5;
-    
+
     private ServiceManager manager;
 
     private static Map ELEMENTS = new HashMap();
@@ -101,16 +102,16 @@
             try {
                 this.document = SourceUtil.readDOM(getRcmlSourceUri(), this.manager);
             } catch (Exception e) {
-                throw new RevisionControlException("Could not read RC file ["
-                        + getRcmlSourceUri() + "]");
+                throw new RevisionControlException("Could not read RC file [" + getRcmlSourceUri()
+                        + "]");
             }
         }
     }
-    
+
     protected static final String RCML_EXTENSION = ".rcml";
-    
+
     protected String getRcmlSourceUri() {
-        return this.node.getRealSourceURI() + RCML_EXTENSION;
+        return this.node.getContentSource().getRealSourceUri() + RCML_EXTENSION;
     }
 
     /**
@@ -140,15 +141,16 @@
      */
     public void write() throws Exception {
         if (this.document == null) {
-            throw new IllegalStateException("The XML for RC source [" + getRcmlSourceUri() + "] is null!");
+            throw new IllegalStateException("The XML for RC source [" + getRcmlSourceUri()
+                    + "] is null!");
         }
         SourceUtil.writeDOM(this.document, getRcmlSourceUri(), this.manager);
         clearDirty();
     }
 
     /**
-     * Write a new entry for a check out or a check in the RCML-File made by the user with identity
-     * at time
+     * Write a new entry for a check out or a check in the RCML-File made by the
+     * user with identity at time
      * @param type co for a check out, ci for a check in
      * @param identity The identity of the user
      * @param time Time at which the check in/out is made
@@ -158,7 +160,7 @@
      */
     public void checkOutIn(short type, String identity, long time, boolean backup)
             throws IOException, Exception {
-        
+
         if (identity == null) {
             throw new IllegalArgumentException("The identity must not be null!");
         }
@@ -168,7 +170,6 @@
                     + ".checkOutIn(): No such type");
         }
 
-
         Element identityElement = this.document.createElement("Identity");
         identityElement.appendChild(this.document.createTextNode(identity));
         Element timeElement = this.document.createElement("Time");
@@ -311,9 +312,7 @@
         for (int i = 0; i < entries.getLength(); i++) {
             Element elem = (Element) entries.item(i);
             String time = elem.getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
-            String identity = elem.getElementsByTagName("Identity")
-                    .item(0)
-                    .getFirstChild()
+            String identity = elem.getElementsByTagName("Identity").item(0).getFirstChild()
                     .getNodeValue();
 
             if (elem.getTagName().equals("CheckOut")) {
@@ -347,9 +346,7 @@
         for (int i = 0; i < entries.getLength(); i++) {
             Element elem = (Element) entries.item(i);
             String time = elem.getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
-            String identity = elem.getElementsByTagName("Identity")
-                    .item(0)
-                    .getFirstChild()
+            String identity = elem.getElementsByTagName("Identity").item(0).getFirstChild()
                     .getNodeValue();
 
             NodeList versionElements = elem.getElementsByTagName("Version");
@@ -364,34 +361,51 @@
 
         return RCMLEntries;
     }
-    
+
     public void makeBackup(long time) throws RevisionControlException {
-        String backupSourceUri = getBackupSourceUri(time);
+        makeBackup(this.node.getContentSource(), time);
+        makeBackup(this.node.getMetaSource(), time);
+    }
+
+    protected void makeBackup(SourceWrapper wrapper, long time) throws RevisionControlException {
+        String backupSourceUri = getBackupSourceUri(wrapper, time);
         try {
-            SourceUtil.copy(this.manager, this.node.getRealSourceURI(), backupSourceUri);
+            String uri = wrapper.getRealSourceUri();
+            if (SourceUtil.exists(uri, manager)) {
+                SourceUtil.copy(this.manager, uri, backupSourceUri);
+            }
         } catch (Exception e) {
             throw new RevisionControlException(e);
         }
     }
 
     public void restoreBackup(long time) throws RevisionControlException {
-        String backupSourceUri = getBackupSourceUri(time);
+        restoreBackup(this.node.getContentSource(), time);
+        restoreBackup(this.node.getMetaSource(), time);
+    }
+
+    protected void restoreBackup(SourceWrapper wrapper, long time) throws RevisionControlException {
+        String backupSourceUri = getBackupSourceUri(wrapper, time);
         try {
-            SourceUtil.copy(this.manager, backupSourceUri, this.node.getRealSourceURI());
+            SourceUtil.copy(this.manager, backupSourceUri, wrapper.getRealSourceUri());
         } catch (Exception e) {
             throw new RevisionControlException(e);
         }
     }
 
-    protected String getBackupSourceUri(long time) {
-        String backupSourceUri = this.node.getRealSourceURI() + "." + time + ".bak";
-        return backupSourceUri;
+    protected String getBackupSourceUri(SourceWrapper wrapper, long time) {
+        String uri = wrapper.getRealSourceUri();
+        return getBackupSourceUri(uri, time);
+    }
+
+    protected String getBackupSourceUri(String uri, long time) {
+        return uri + "." + time + ".bak";
     }
 
     /**
-     * Prune the list of entries and delete the corresponding backups. Limit the number of entries
-     * to the value maximalNumberOfEntries (2maxNumberOfRollbacks(configured)+1)
-     * @param backupDir The backup directory
+     * Prune the list of entries and delete the corresponding backups. Limit the
+     * number of entries to the value maximalNumberOfEntries
+     * (2maxNumberOfRollbacks(configured)+1)
      * @throws Exception if an error occurs
      */
     public void pruneEntries() throws Exception {
@@ -403,16 +417,23 @@
             Element current = (Element) entries.item(i);
 
             // remove the backup file associated with this entry
-            String time = current.getElementsByTagName("Time")
-                    .item(0)
-                    .getFirstChild()
+            String time = current.getElementsByTagName("Time").item(0).getFirstChild()
                     .getNodeValue();
-            SourceUtil.delete(getBackupSourceUri(Long.valueOf(time).longValue()), this.manager);
+            long timeLong = Long.valueOf(time).longValue();
+            deleteBackup(this.node.getContentSource(), timeLong);
+            deleteBackup(this.node.getMetaSource(), timeLong);
             // remove the entry from the list
             current.getParentNode().removeChild(current);
         }
     }
 
+    protected void deleteBackup(SourceWrapper wrapper, long time) throws ServiceException,
+            MalformedURLException, IOException {
+        String uri = getBackupSourceUri(wrapper, time);
+        SourceUtil.delete(uri, this.manager);
+        SourceUtil.deleteEmptyCollections(uri, this.manager);
+    }
+
     /**
      * Get a clone document
      * @return org.w3c.dom.Document The clone document
@@ -421,7 +442,8 @@
     public org.w3c.dom.Document getDOMDocumentClone() throws Exception {
         Document documentClone = DocumentHelper.createDocument(null, "dummy", null);
         documentClone.removeChild(documentClone.getDocumentElement());
-        documentClone.appendChild(documentClone.importNode(this.document.getDocumentElement(), true));
+        documentClone.appendChild(documentClone
+                .importNode(this.document.getDocumentElement(), true));
 
         return documentClone;
     }
@@ -503,8 +525,7 @@
         try {
             SourceUtil.delete(getRcmlSourceUri(), this.manager);
             SourceUtil.deleteEmptyCollections(getRcmlSourceUri(), this.manager);
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             throw new RuntimeException(e);
         }
         return true;
@@ -512,7 +533,6 @@
 
     /**
      * delete the revisions
-     * @param node of the document
      * @throws RevisionControlException when somthing went wrong
      */
     public void deleteRevisions() throws RevisionControlException {
@@ -520,9 +540,8 @@
             String[] times = getBackupsTime();
             for (int i = 0; i < times.length; i++) {
                 long time = new Long(times[i]).longValue();
-                String backupSourceUri = getBackupSourceUri(time);
-                SourceUtil.delete(backupSourceUri, this.manager);
-                SourceUtil.deleteEmptyCollections(backupSourceUri, this.manager);
+                deleteBackup(this.node.getContentSource(), time);
+                deleteBackup(this.node.getMetaSource(), time);
             }
         } catch (Exception e) {
             throw new RevisionControlException(e);

Modified: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRevision.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRevision.java?view=diff&rev=479620&r1=479619&r2=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRevision.java (original)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRevision.java Mon Nov 27 06:02:13 2006
@@ -21,6 +21,9 @@
 import java.util.Iterator;
 import java.util.Vector;
 
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
@@ -34,7 +37,7 @@
 /**
  * Revision implementation.
  */
-public class SourceNodeRevision implements Revision {
+public class SourceNodeRevision extends AbstractLogEnabled implements Revision {
 
     private SourceNode node;
     private int number;
@@ -44,11 +47,13 @@
      * @param node The node.
      * @param number The revision number.
      * @param manager The service manager.
+     * @param logger The logger.
      */
-    public SourceNodeRevision(SourceNode node, int number, ServiceManager manager) {
+    public SourceNodeRevision(SourceNode node, int number, ServiceManager manager, Logger logger) {
         this.node = node;
         this.number = number;
         this.manager = manager;
+        ContainerUtil.enableLogging(this, logger);
     }
 
     private long time = -1;
@@ -105,7 +110,7 @@
 
     public String getSourceURI() {
         SourceNodeRCML rcml = (SourceNodeRCML) this.node.getRcml();
-        String sourceUri = rcml.getBackupSourceUri(getTime());
+        String sourceUri = rcml.getBackupSourceUri(this.node.getContentSource(), getTime());
         return sourceUri;
     }
 
@@ -127,7 +132,9 @@
     }
 
     protected String getMetaSourceUri() {
-        return this.node.getMetaSourceUri() + "." + getTime() + ".bak";
+        String realSourceUri = SourceWrapper.computeRealSourceUri(this.manager, this.node.getSession(), 
+                this.node.getSourceURI(), getLogger());
+        return realSourceUri + ".meta." + getTime() + ".bak";
     }
 
     public String[] getMetaDataNamespaceUris() throws MetaDataException {

Added: lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceWrapper.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceWrapper.java?view=auto&rev=479620
==============================================================================
--- lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceWrapper.java (added)
+++ lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceWrapper.java Mon Nov 27 06:02:13 2006
@@ -0,0 +1,422 @@
+/*
+ * 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.lenya.cms.repository;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.Date;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.lenya.cms.cocoon.source.SourceUtil;
+import org.apache.lenya.cms.publication.DocumentFactory;
+import org.apache.lenya.cms.publication.DocumentUtil;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.util.Assert;
+
+/**
+ * Provide access to a source.
+ */
+public class SourceWrapper extends AbstractLogEnabled {
+
+    private SourceNode node;
+    private String sourceUri;
+    protected ServiceManager manager;
+
+    /**
+     * Ctor.
+     * @param node
+     * @param sourceUri
+     * @param manager
+     * @param logger
+     */
+    public SourceWrapper(SourceNode node, String sourceUri, ServiceManager manager, Logger logger) {
+        
+        Assert.notNull("node", node);
+        this.node = node;
+        
+        Assert.notNull("source URI", sourceUri);
+        this.sourceUri = sourceUri;
+        
+        Assert.notNull("service manager", manager);
+        this.manager = manager;
+        
+        enableLogging(logger);
+    }
+
+    protected static final String FILE_PREFIX = "file:/";
+    protected static final String CONTEXT_PREFIX = "context://";
+
+    protected SourceNode getNode() {
+        return this.node;
+    }
+
+    private String realSourceUri;
+
+    /**
+     * Returns the URI of the actual source which is used.
+     * 
+     * @return A string.
+     */
+    protected String getRealSourceUri() {
+        if (this.realSourceUri == null) {
+            this.realSourceUri = computeRealSourceUri(this.manager, getNode().getSession(),
+                    this.sourceUri, getLogger());
+        }
+        return this.realSourceUri;
+    }
+
+    protected static final String computeRealSourceUri(ServiceManager manager, Session session,
+            String sourceUri, Logger logger) {
+        String contentDir = null;
+        String publicationId = null;
+        try {
+            String pubBase = Node.LENYA_PROTOCOL + Publication.PUBLICATION_PREFIX_URI + "/";
+            String publicationsPath = sourceUri.substring(pubBase.length());
+            publicationId = publicationsPath.split("/")[0];
+            DocumentFactory factory = DocumentUtil.createDocumentFactory(manager, session);
+            Publication pub = factory.getPublication(publicationId);
+            contentDir = pub.getContentDir();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        String contentBaseUri = null;
+        String urlID = sourceUri.substring(Node.LENYA_PROTOCOL.length());
+
+        // Substitute e.g. "lenya://lenya/pubs/PUB_ID/content" by "contentDir"
+        String filePrefix = urlID.substring(0, urlID.indexOf(publicationId)) + publicationId;
+        String tempString = urlID.substring(filePrefix.length() + 1);
+        String fileMiddle = tempString.substring(0, tempString.indexOf("/"));
+        String fileSuffix = tempString.substring(fileMiddle.length() + 1, tempString.length());
+        String uriSuffix;
+        if (new File(contentDir).isAbsolute()) {
+            // Absolute
+            contentBaseUri = FILE_PREFIX + contentDir;
+            uriSuffix = File.separator + fileSuffix;
+        } else {
+            // Relative
+            contentBaseUri = CONTEXT_PREFIX + contentDir;
+            uriSuffix = "/" + fileSuffix;
+        }
+
+        try {
+            if (!SourceUtil.exists(contentBaseUri, manager)) {
+                logger.info("The content directory [" + contentBaseUri + "] does not exist. "
+                        + "It will be created as soon as documents are added.");
+            }
+        } catch (ServiceException e) {
+            throw new RuntimeException(e);
+        } catch (MalformedURLException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        String realSourceUri = contentBaseUri + uriSuffix;
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Real Source URI: " + realSourceUri);
+        }
+
+        return realSourceUri;
+    }
+
+    /**
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.transaction.Transactionable#deleteTransactionable()
+     */
+    public void deleteTransactionable() throws RepositoryException {
+        try {
+            if (!getNode().isCheckedOut()) {
+                throw new RuntimeException("Cannot delete source [" + getSourceUri()
+                        + "]: not checked out!");
+            } else {
+                this.data = null;
+                SourceUtil.delete(getRealSourceUri(), this.manager);
+            }
+        } catch (Exception e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    byte[] data = null;
+
+    /**
+     * @return An input stream.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#getInputStream()
+     */
+    public synchronized InputStream getInputStream() throws RepositoryException {
+        if (!exists()) {
+            throw new RuntimeException(this + " does not exist!");
+        }
+        return new ByteArrayInputStream(this.data);
+    }
+
+    /**
+     * @return A boolean value.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#exists()
+     */
+    public boolean exists() throws RepositoryException {
+        loadData();
+        return this.data != null;
+    }
+
+    /**
+     * Loads the data from the real source.
+     * 
+     * @throws RepositoryException if an error occurs.
+     */
+    protected synchronized void loadData() throws RepositoryException {
+
+        if (this.data != null) {
+            return;
+        }
+
+        ByteArrayOutputStream out = null;
+        InputStream in = null;
+        SourceResolver resolver = null;
+        TraversableSource source = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            source = (TraversableSource) resolver.resolveURI(getRealSourceUri());
+
+            if (source.exists() && !source.isCollection()) {
+                byte[] buf = new byte[4096];
+                out = new ByteArrayOutputStream();
+                in = source.getInputStream();
+                int read = in.read(buf);
+
+                while (read > 0) {
+                    out.write(buf, 0, read);
+                    read = in.read(buf);
+                }
+
+                this.data = out.toByteArray();
+            }
+        } catch (Exception e) {
+            throw new RepositoryException(e);
+        } finally {
+            try {
+                if (in != null)
+                    in.close();
+                if (out != null)
+                    out.close();
+            } catch (Exception e) {
+                throw new RepositoryException(e);
+            }
+
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                this.manager.release(resolver);
+            }
+        }
+    }
+
+    /**
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.transaction.Transactionable#saveTransactionable()
+     */
+    public synchronized void saveTransactionable() throws RepositoryException {
+        if (!getNode().isCheckedOut()) {
+            throw new RepositoryException("Cannot save node [" + getSourceUri()
+                    + "]: not checked out!");
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Saving [" + this + "] to source [" + getRealSourceUri() + "]");
+        }
+
+        if (this.data != null) {
+            SourceResolver resolver = null;
+            ModifiableSource source = null;
+            InputStream in = null;
+            OutputStream out = null;
+            try {
+
+                resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+                source = (ModifiableSource) resolver.resolveURI(getRealSourceUri());
+
+                out = source.getOutputStream();
+
+                byte[] buf = new byte[4096];
+                in = new ByteArrayInputStream(this.data);
+                int read = in.read(buf);
+
+                while (read > 0) {
+                    out.write(buf, 0, read);
+                    read = in.read(buf);
+                }
+            } catch (Exception e) {
+                throw new RepositoryException(e);
+            } finally {
+
+                try {
+                    if (in != null) {
+                        in.close();
+                    }
+                    if (out != null) {
+                        out.flush();
+                        out.close();
+                    }
+                } catch (Throwable t) {
+                    throw new RuntimeException("Could not close streams: ", t);
+                }
+
+                if (resolver != null) {
+                    if (source != null) {
+                        resolver.release(source);
+                    }
+                    manager.release(resolver);
+                }
+            }
+        }
+    }
+
+    /**
+     * Output stream.
+     */
+    private class NodeOutputStream extends ByteArrayOutputStream {
+        /**
+         * @see java.io.OutputStream#close()
+         */
+        public synchronized void close() throws IOException {
+            SourceWrapper.this.data = super.toByteArray();
+            SourceWrapper.this.lastModified = new Date().getTime();
+            super.close();
+        }
+    }
+
+    /**
+     * @return The content length.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#getContentLength()
+     */
+    public long getContentLength() throws RepositoryException {
+        loadData();
+        return this.data.length;
+    }
+
+    private long lastModified = -1;
+
+    /**
+     * @return The last modification date.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#getLastModified()
+     */
+    public long getLastModified() throws RepositoryException {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(getRealSourceUri());
+
+            long sourceLastModified;
+
+            if (source.exists()) {
+                sourceLastModified = source.getLastModified();
+                if (sourceLastModified > this.lastModified) {
+                    this.lastModified = sourceLastModified;
+                }
+            } else if (this.lastModified == -1) {
+                throw new RepositoryException("The source [" + getRealSourceUri()
+                        + "] does not exist!");
+            }
+
+            return this.lastModified;
+
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                this.manager.release(resolver);
+            }
+        }
+    }
+
+    /**
+     * @return A string.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#getMimeType()
+     */
+    public String getMimeType() throws RepositoryException {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(getRealSourceUri());
+            if (source.exists()) {
+                return source.getMimeType();
+            } else {
+                throw new SourceNotFoundException("The source [" + getRealSourceUri()
+                        + "] does not exist!");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                this.manager.release(resolver);
+            }
+        }
+    }
+
+    /**
+     * @return The source URI.
+     */
+    public String getSourceUri() {
+        return this.sourceUri;
+    }
+
+    /**
+     * @return An output stream.
+     * @throws RepositoryException if an error occurs.
+     * @see org.apache.lenya.cms.repository.Node#getOutputStream()
+     */
+    public synchronized OutputStream getOutputStream() throws RepositoryException {
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("Get OutputStream for " + getSourceUri());
+        try {
+            getNode().registerDirty();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return new NodeOutputStream();
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org