blob: 408dabef31da705576e2350e950de330a77e7a1f [file] [log] [blame]
/*
* 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.cocoon.source;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.Iterator;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.excalibur.source.ModifiableSource;
import org.apache.excalibur.source.ModifiableTraversableSource;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.repository.RepositoryException;
import org.apache.lenya.xml.DocumentHelper;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
* @version $Id$
*/
public final class SourceUtil {
/**
* <p>
* Copies one Source to another using a source buffer i.e. the source Source
* is buffered before it is copied to its final destination.
* </p>
* <p>
* The optional buffering is sometimes useful, if the source Source somehow
* depends on the destination Source. This situation may occur e.g. if
* source Source is a Cocoon pipeline.
* </p>
* <p>
* <em>NOTE:</em> o.a.e..s.SourceUtil.copy does not close streams on an
* exception!!
* </p>
* @param source
* @param destination
* @param useBuffer If true, the source data will be read into a buffer
* before it is written to the final destination.
* @throws IOException If an error occures.
*/
public static void copy(Source source, ModifiableSource destination, boolean useBuffer)
throws IOException {
InputStream sourceInputStream = null;
OutputStream destOutputStream = null;
try {
sourceInputStream = source.getInputStream();
destOutputStream = destination.getOutputStream();
if (useBuffer) {
final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
IOUtils.copy(sourceInputStream, sourceBos);
IOUtils.write(sourceBos.toByteArray(), destOutputStream);
} else {
IOUtils.copy(sourceInputStream, destOutputStream);
}
} finally {
if (destOutputStream != null) {
destOutputStream.flush();
destOutputStream.close();
}
if (sourceInputStream != null) {
sourceInputStream.close();
}
}
}
/**
* Copies one Source to another. The source Source is optionally buffered.
* @param resolver The SourceResolver to use for lookin up Sources.
* @param sourceUri The source to be copied.
* @param destUri The URI to copy to.
* @param useBuffer If true, the source Source is buffered before copied to
* the final destination.
* @throws IOException If an error occures.
* @throws SourceException If the destination is not modifiable.
* @see #copy(Source, ModifiableSource, boolean)
*/
public static void copy(SourceResolver resolver, String sourceUri, String destUri,
boolean useBuffer) throws IOException, SourceException {
Source source = null;
Source dest = null;
try {
source = resolver.resolveURI(sourceUri);
dest = resolver.resolveURI(destUri);
if (!(dest instanceof ModifiableSource))
throw new SourceException("Destination '" + dest.getURI() + "' is not modifiable.");
copy(source, (ModifiableSource) dest, useBuffer);
} finally {
if (source != null)
resolver.release(source);
if (dest != null)
resolver.release(dest);
}
}
/**
* Copies a Source without buffering.
* @param resolver A SourceResolver instance.
* @param sourceUri The source URI to copy from.
* @param destUri The destination URI to copy to.
* @throws IOException If an error occures.
* @see #copy(SourceResolver, String, String, boolean)
*/
public static void copy(SourceResolver resolver, String sourceUri, String destUri)
throws IOException {
copy(resolver, sourceUri, destUri, false);
}
/**
* Copies a Source without buffering.
* @param manager A service manager.
* @param sourceUri The source URI to copy from.
* @param destUri The destination URI to copy to.
* @throws IOException If an error occures.
* @throws ServiceException
* @see #copy(SourceResolver, String, String, boolean)
*/
public static void copy(ServiceManager manager, String sourceUri, String destUri)
throws IOException, ServiceException {
SourceResolver resolver = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
copy(resolver, sourceUri, destUri, false);
} finally {
if (resolver != null) {
manager.release(resolver);
}
}
}
/**
* Reads a DOM from a source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @return A document or <code>null</code> if the source does not exist.
* @throws ServiceException if an error occurs.
* @throws SourceNotFoundException if an error occurs.
* @throws ParserConfigurationException if an error occurs.
* @throws SAXException if an error occurs.
* @throws IOException if an error occurs.
*/
public static Document readDOM(String sourceUri, ServiceManager manager)
throws ServiceException, SourceNotFoundException, ParserConfigurationException,
SAXException, IOException {
SourceResolver resolver = null;
Source source = null;
Document document = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(sourceUri);
if (source.exists()) {
document = DocumentHelper.readDocument(source.getInputStream());
}
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
return document;
}
/**
* Writes a DOM to a source.
* @param document The document.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws TransformerConfigurationException if an error occurs.
* @throws TransformerException if an error occurs.
* @throws ServiceException if the source resolver could not be obtained.
* @throws MalformedURLException if the source URI is not valid.
* @throws IOException if an error occurs.
*/
public static void writeDOM(Document document, String sourceUri, ServiceManager manager)
throws TransformerConfigurationException, TransformerException, ServiceException,
MalformedURLException, IOException {
SourceResolver resolver = null;
ModifiableSource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (ModifiableSource) resolver.resolveURI(sourceUri);
OutputStream oStream = source.getOutputStream();
writeDOM(document, oStream);
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* @param document The XML document.
* @param oStream The output stream.
* @throws TransformerConfigurationException if an error occurs.
* @throws TransformerException if an error occurs.
* @throws IOException if an error occurs.
*/
public static void writeDOM(Document document, OutputStream oStream)
throws TransformerConfigurationException, TransformerException, IOException {
DocumentHelper.writeDocument(document, oStream);
if (oStream != null) {
oStream.flush();
try {
oStream.close();
} catch (Throwable t) {
throw new RuntimeException("Could not write document: ", t);
}
}
}
/**
* Deletes a source if it exists.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws ServiceException if an error occurs.
* @throws MalformedURLException if an error occurs.
* @throws IOException if an error occurs.
*/
public static void delete(String sourceUri, ServiceManager manager) throws ServiceException,
MalformedURLException, IOException {
SourceResolver resolver = null;
ModifiableTraversableSource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (ModifiableTraversableSource) resolver.resolveURI(sourceUri);
if (source.exists()) {
source.delete();
}
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Deletes all empty collections in a subtree.
* @param sourceUri The root source URI.
* @param manager The service manager.
* @throws ServiceException
* @throws MalformedURLException
* @throws IOException
*/
public static void deleteEmptyCollections(String sourceUri, ServiceManager manager)
throws ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
ModifiableTraversableSource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (ModifiableTraversableSource) resolver.resolveURI(sourceUri);
if (source.isCollection()) {
for (Iterator i = source.getChildren().iterator(); i.hasNext();) {
ModifiableTraversableSource child = (ModifiableTraversableSource) i.next();
deleteEmptyCollections(child.getURI(), manager);
}
if (source.getChildren().size() == 0) {
source.delete();
}
}
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Checks if a source exists.
* @param sourceUri The source URI.
* @param manager The service manager.
* @return A boolean value.
* @throws ServiceException if an error occurs.
* @throws MalformedURLException if an error occurs.
* @throws IOException if an error occurs.
*/
public static boolean exists(String sourceUri, ServiceManager manager) throws ServiceException,
MalformedURLException, IOException {
SourceResolver resolver = null;
Source source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(sourceUri);
return source.exists();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Returns the last modification date of a source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @return A long value.
* @throws ServiceException if an error occurs.
* @throws MalformedURLException if an error occurs.
* @throws IOException if an error occurs.
*/
public static long getLastModified(String sourceUri, ServiceManager manager)
throws ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
Source source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(sourceUri);
return source.getLastModified();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Checks out a repository source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws RepositoryException If an error occurs.
* @throws ServiceException If an error occurs.
* @throws MalformedURLException If an error occurs.
* @throws IOException If an error occurs.
*/
public static void checkout(String sourceUri, ServiceManager manager)
throws RepositoryException, ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
RepositorySource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (RepositorySource) resolver.resolveURI(sourceUri);
source.getNode().checkout();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Checks in a transactionable source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws RepositoryException If an error occurs.
* @throws ServiceException If an error occurs.
* @throws MalformedURLException If an error occurs.
* @throws IOException If an error occurs.
*/
public static void checkin(String sourceUri, ServiceManager manager)
throws RepositoryException, ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
RepositorySource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (RepositorySource) resolver.resolveURI(sourceUri);
source.getNode().checkin();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Locks a transactionable source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws RepositoryException If an error occurs.
*/
public static void lock(String sourceUri, ServiceManager manager) throws RepositoryException {
SourceResolver resolver = null;
RepositorySource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (RepositorySource) resolver.resolveURI(sourceUri);
source.getNode().lock();
} catch (RepositoryException e) {
throw e;
} catch (Exception e) {
throw new RepositoryException(e);
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Unlocks a transactionable source.
* @param sourceUri The source URI.
* @param manager The service manager.
* @throws RepositoryException If an error occurs.
*/
public static void unlock(String sourceUri, ServiceManager manager) throws RepositoryException {
SourceResolver resolver = null;
RepositorySource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (RepositorySource) resolver.resolveURI(sourceUri);
source.getNode().unlock();
} catch (RepositoryException e) {
throw e;
} catch (Exception e) {
throw new RepositoryException(e);
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* Registers a source as dirty.
* @param sourceUri The source URI.
* @param manager The service manager.
*/
public static void registerDirty(String sourceUri, ServiceManager manager) {
SourceResolver resolver = null;
RepositorySource source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = (RepositorySource) resolver.resolveURI(sourceUri);
source.getNode().registerDirty();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* @param sourceUri The source URI.
* @param manager The service manager.
* @return A content length.
* @throws ServiceException
* @throws MalformedURLException
* @throws IOException
*/
public static long getContentLength(String sourceUri, ServiceManager manager)
throws ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
Source source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(sourceUri);
return source.getContentLength();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* @param sourceUri The source URI.
* @param manager The service manager.
* @return A mime type.
* @throws ServiceException
* @throws IOException
* @throws MalformedURLException
*/
public static String getMimeType(String sourceUri, ServiceManager manager)
throws ServiceException, MalformedURLException, IOException {
SourceResolver resolver = null;
Source source = null;
try {
resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
source = resolver.resolveURI(sourceUri);
return source.getMimeType();
} finally {
if (resolver != null) {
if (source != null) {
resolver.release(source);
}
manager.release(resolver);
}
}
}
/**
* @param resolver
* @param sourceUri
* @param destOutputStream
* @throws MalformedURLException
* @throws IOException
*/
public static void copy(SourceResolver resolver, String sourceUri, OutputStream destOutputStream) throws MalformedURLException, IOException {
boolean useBuffer = true;
InputStream sourceInputStream = null;
Source source = null;
try {
source = resolver.resolveURI(sourceUri);
sourceInputStream = source.getInputStream();
if (useBuffer) {
final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
IOUtils.copy(sourceInputStream, sourceBos);
IOUtils.write(sourceBos.toByteArray(), destOutputStream);
} else {
IOUtils.copy(sourceInputStream, destOutputStream);
}
} finally {
if (destOutputStream != null) {
destOutputStream.flush();
destOutputStream.close();
}
if (sourceInputStream != null) {
sourceInputStream.close();
}
if (source != null) {
resolver.release(source);
}
}
}
}