You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by un...@apache.org on 2003/10/30 15:41:40 UTC
cvs commit: cocoon-2.1/src/blocks/repository/conf SourceRepository.xroles SourceRepository.xconf
unico 2003/10/30 06:41:40
Added: src/blocks/repository/java/org/apache/cocoon/components/repository
SourceRepositoryImpl.java SourceRepository.java
src/blocks/repository/conf SourceRepository.xroles
SourceRepository.xconf
Log:
SourceRepository component adapted from SourceRepository in linotype, currently used by davmap but should fit onto other editing environments as well
Revision Changes Path
1.1 cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepositoryImpl.java
Index: SourceRepositoryImpl.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <st...@apache.org>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.components.repository;
import java.io.IOException;
import java.util.Iterator;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
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.SourceResolver;
import org.apache.excalibur.source.SourceUtil;
import org.apache.excalibur.source.TraversableSource;
/**
* SourceRepository implementation.
*
* @author <a href="mailto:unico@apache.org">Unico Hommes</a>
*
* @avalon.component
* @avalon.service type="SourceRepository"
* @x-avalon.lifestyle type="singleton"
* @x-avalon.info name="source-repository"
*/
public class SourceRepositoryImpl extends AbstractLogEnabled
implements Serviceable, ThreadSafe, SourceRepository {
private SourceResolver m_resolver;
// ---------------------------------------------------- lifecycle
public SourceRepositoryImpl() {
}
/**
* @avalon.dependency type="SourceResolver"
*/
public void service(ServiceManager manager) throws ServiceException {
m_resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
}
// ---------------------------------------------------- repository operations
public int save(String in, String out) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("save: " + in + "/" + out);
}
Source source = null;
ModifiableTraversableSource destination = null;
try {
destination = (ModifiableTraversableSource) m_resolver.resolveURI(out);
final boolean exists = destination.exists();
if (!exists) {
Source parent = ((TraversableSource) destination).getParent();
if (!parent.exists()) {
getLogger().warn("Conflict during save(): " +
"parent does not exist." );
return STATUS_CONFLICT;
}
}
if (destination.isCollection()) {
getLogger().warn("Conflict during save(): " +
"destination is an existing collection.");
return STATUS_CONFLICT;
}
int status;
if (destination.exists()) {
status = STATUS_OK;
}
else {
status = STATUS_CREATED;
}
source = m_resolver.resolveURI(in);
SourceUtil.copy(source,destination);
return status;
}
catch (IOException e) {
getLogger().error("Unexpected exception during save().",e);
throw e;
}
finally {
if (source != null) {
m_resolver.release(source);
}
if (destination != null) {
m_resolver.release(destination);
}
}
}
public int makeCollection(String location) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("makeCollection: " + location);
}
ModifiableTraversableSource source = null;
Source parent = null;
try {
source = (ModifiableTraversableSource) m_resolver.resolveURI(location);
if (source.exists()) {
getLogger().warn("makeCollection() is not allowed: " +
"the resource already exists.");
return STATUS_NOT_ALLOWED;
}
parent = source.getParent();
if (!parent.exists()) {
getLogger().warn("Conflict during makeCollection(): " +
"parent does not exist.");
return STATUS_CONFLICT;
}
source.makeCollection();
return STATUS_CREATED;
}
catch (IOException e) {
getLogger().error("Unexpected exception during MKCOL.",e);
throw e;
}
finally {
if (source != null) {
m_resolver.release(source);
}
if (parent != null) {
m_resolver.release(parent);
}
}
}
/**
* Deletes a Source and all of its descendants.
*
* @param location the location of the source to delete.
* @return a http status code describing the exit status.
* @throws IOException
*/
public int remove(String location) throws SourceException, IOException {
final Source source = m_resolver.resolveURI(location);
if (!source.exists()) {
getLogger().warn("Trying to delete a non-existing source.");
return STATUS_NOT_FOUND;
}
if (!(source instanceof ModifiableSource)) {
getLogger().warn("Trying to delete a non-modifiable source.");
return STATUS_CONFLICT;
}
try {
return remove((ModifiableSource) source);
}
catch (IOException e) {
getLogger().error("Unexpected exception during DELETE.",e);
throw e;
}
finally {
m_resolver.release(source);
}
}
private int remove(ModifiableSource source) throws SourceException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("remove: " + source.getURI());
}
if (source instanceof ModifiableTraversableSource) {
ModifiableTraversableSource parent = (ModifiableTraversableSource) source;
if (parent.isCollection()) {
int status = STATUS_OK;
final Iterator iter = parent.getChildren().iterator();
while (iter.hasNext()) {
Source child = null;
try {
child = (Source) iter.next();
if (!(child instanceof ModifiableSource)) {
return STATUS_CONFLICT;
}
else {
status = remove((ModifiableSource) child);
if (status != STATUS_OK) {
return status;
}
}
}
finally {
if (child != null) {
m_resolver.release(child);
}
}
}
}
}
source.delete();
return STATUS_OK;
}
public int move(String from, String to) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("move: " + from + " -> " + to);
}
if (from != null && from.equals(to)) {
final String message = "move() is not allowed: " +
"The source and destination URIs are the same";
getLogger().warn(message);
return STATUS_NOT_ALLOWED;
}
Source source = null;
Source destination = null;
try {
source = m_resolver.resolveURI(from);
destination = m_resolver.resolveURI(to);
return move(source, destination);
}
catch (IOException e) {
getLogger().error("Unexpected exception during move().",e);
throw e;
}
finally {
if (source != null) {
m_resolver.release(source);
}
if (destination != null) {
m_resolver.release(destination);
}
}
}
private int move(Source source, Source destination) throws IOException {
if (!source.exists()) {
return STATUS_NOT_FOUND;
}
if (destination.exists()) {
remove((ModifiableSource) destination);
}
SourceUtil.move(source, destination);
return STATUS_CREATED;
}
public int copy(String from, String to) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("copy: " + from + " -> " + to);
}
if (from != null && from.equals(to)) {
final String message = "copy() is not allowed: " +
"The source and destination URIs are the same";
getLogger().warn(message);
return STATUS_NOT_ALLOWED;
}
Source source = null;
Source destination = null;
try {
source = m_resolver.resolveURI(from);
destination = m_resolver.resolveURI(to);
return copy(source, destination);
}
catch (IOException e) {
getLogger().error("Unexpected exception during copy().",e);
throw e;
}
finally {
if (source != null) {
m_resolver.release(source);
}
if (destination != null) {
m_resolver.release(destination);
}
}
}
private int copy(Source source, Source destination) throws IOException {
if (!source.exists()) {
return STATUS_NOT_FOUND;
}
if (destination.exists()) {
remove((ModifiableSource) destination);
}
SourceUtil.copy(source, destination);
return STATUS_CREATED;
}
}
1.1 cocoon-2.1/src/blocks/repository/java/org/apache/cocoon/components/repository/SourceRepository.java
Index: SourceRepository.java
===================================================================
/* Created on Oct 18, 2003 7:00:43 PM by unico */
package org.apache.cocoon.components.repository;
import java.io.IOException;
import org.apache.excalibur.source.SourceException;
/**
* A stateless utitlity service intended to be use by flowscripts to help
* them with persistent operations on sources.
*
* <p>
* Each operation return a status code that is based on RFC 2518 (WebDAV).
* This does not mean to it cannot be used outside of a WebDAV context.
* It is reusing a standard to enable richer communication between
* the flow layer and the service layer.
* </p>
*
* @author <a href="mailto:unico@apache.org">Unico Hommes</a>
*/
public interface SourceRepository {
public static final String ROLE = SourceRepository.class.getName();
/**
* Status OK (<code>200</code>).
*/
public static final int STATUS_OK = 200;
/**
* Status CREATED (<code>201</code>).
*/
public static final int STATUS_CREATED = 201;
/**
* Status NOT_FOUND (<code>404</code>).
*/
public static final int STATUS_NOT_FOUND = 404;
/**
* Status NOT_ALLOWED (<code>495</code>).
*/
public static final int STATUS_NOT_ALLOWED = 405;
/**
* Status CONFLICT (<code>409</code>).
*/
public static final int STATUS_CONFLICT = 409;
/**
* Saves a Source by either creating a new one or overwriting the previous one.
*
* @param in the Source location to read from.
* @param out the Source location to write to.
* @return a status code describing the exit status.
* @throws IOException
*/
public abstract int save(String in, String out) throws IOException;
/**
* Create a Source collection.
*
* @param location the location of the source collection to create.
* @return a status code describing the exit status.
* @throws IOException
*/
public abstract int makeCollection(String location) throws IOException;
/**
* Deletes a Source and all of its descendants.
*
* @param location the location of the source to delete.
* @return a status code describing the exit status.
* @throws IOException
*/
public abstract int remove(String location) throws SourceException, IOException;
/**
* Move a Source from one location to the other.
*
* @param from the source location.
* @param to the destination location.
* @return a status code describing the exit status.
* @throws IOException
*/
public abstract int move(String from, String to) throws IOException;
/**
* Copy a Souce from one location to the other.
*
* @param from the source location.
* @param to the destination location.
* @return a status code describing the exit status.
* @throws IOException
*/
public abstract int copy(String from, String to) throws IOException;
}
1.1 cocoon-2.1/src/blocks/repository/conf/SourceRepository.xroles
Index: SourceRepository.xroles
===================================================================
<?xml version="1.0"?>
<xroles xpath="/role-list" unless="role[@shorthand='source-repository']">
<role name="org.apache.cocoon.components.repository.SourceRepository"
shorthand="source-repository"
default-class="org.apache.cocoon.components.repository.SourceRepositoryImpl"
/>
</xroles>
1.1 cocoon-2.1/src/blocks/repository/conf/SourceRepository.xconf
Index: SourceRepository.xconf
===================================================================
<?xml version="1.0"?>
<xconf xpath="/cocoon" unless="source-repository">
<source-repository logger="core.source-repository" />
</xconf>