| /* |
| * 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.cocoon.components.repository.impl; |
| |
| import java.io.BufferedInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.util.Properties; |
| |
| import javax.xml.transform.OutputKeys; |
| |
| import org.apache.avalon.framework.activity.Disposable; |
| import org.apache.avalon.framework.activity.Initializable; |
| import org.apache.avalon.framework.component.Component; |
| import org.apache.avalon.framework.configuration.Configurable; |
| import org.apache.avalon.framework.configuration.Configuration; |
| import org.apache.avalon.framework.configuration.ConfigurationException; |
| 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.cocoon.ProcessingException; |
| import org.apache.cocoon.components.LifecycleHelper; |
| import org.apache.cocoon.components.repository.Repository; |
| import org.apache.cocoon.components.repository.helpers.CredentialsToken; |
| import org.apache.cocoon.components.repository.helpers.RepositoryTransactionHelper; |
| import org.apache.cocoon.components.repository.helpers.RepositoryPropertyHelper; |
| import org.apache.cocoon.components.repository.helpers.RepositoryVersioningHelper; |
| import org.apache.cocoon.components.webdav.WebDAVUtil; |
| import org.apache.cocoon.xml.XMLUtils; |
| import org.apache.commons.httpclient.HttpException; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.excalibur.source.Source; |
| import org.apache.excalibur.xml.dom.DOMParser; |
| import org.apache.webdav.lib.WebdavResource; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| |
| /** |
| * A repository implementation for WebDAV. |
| */ |
| public class WebDAVRepository extends AbstractLogEnabled |
| implements Repository, Serviceable, Configurable, Initializable, Disposable, Component { |
| |
| /** The name of the repository location configuration element */ |
| public static final String REPO_BASE_CONF = "repo-base"; |
| |
| /* The ServiceManager */ |
| private ServiceManager manager; |
| |
| /* The RepositoryPropertyHelper */ |
| private WebDAVRepositoryPropertyHelper propertyHelper; |
| |
| /* The RepositoryTransactionHelper */ |
| private WebDAVRepositoryTransactionHelper transactionHelper; |
| |
| /* The RepositoryVersioningHelper */ |
| private WebDAVRepositoryVersioningHelper versioningHelper; |
| |
| /* The location of the repository */ |
| private String repoBaseUrl; |
| |
| /* The credentials to be used against the WebDAV repository */ |
| private CredentialsToken credentials; |
| |
| /* (non-Javadoc) |
| * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager) |
| */ |
| public void service(ServiceManager manager) throws ServiceException { |
| this.manager = manager; |
| |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) |
| */ |
| public void configure(Configuration configuration) throws ConfigurationException { |
| this.repoBaseUrl = configuration.getChild(REPO_BASE_CONF).getValue(); |
| if (this.getLogger().isDebugEnabled()) { |
| this.getLogger().debug("configuring repository location " + this.repoBaseUrl); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.avalon.framework.activity.Initializable#initialize() |
| */ |
| public void initialize() throws Exception { |
| this.propertyHelper = new WebDAVRepositoryPropertyHelper(this.credentials, this); |
| this.transactionHelper = new WebDAVRepositoryTransactionHelper(this.credentials, this); |
| this.versioningHelper = new WebDAVRepositoryVersioningHelper(this.credentials, this); |
| LifecycleHelper lh = new LifecycleHelper(this.getLogger(), |
| null, |
| this.manager, |
| null, |
| null); |
| lh.setupComponent(this.propertyHelper, true); |
| lh.setupComponent(this.transactionHelper, true); |
| lh.setupComponent(this.versioningHelper, true); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.avalon.framework.activity.Disposable#dispose() |
| */ |
| public void dispose() { |
| this.manager = null; |
| this.propertyHelper.dispose(); |
| this.transactionHelper.dispose(); |
| this.versioningHelper.dispose(); |
| this.propertyHelper = null; |
| this.transactionHelper = null; |
| this.versioningHelper = null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#getContentString(java.lang.String) |
| */ |
| public String getContentString(String uri) throws ProcessingException { |
| |
| try { |
| return IOUtils.toString(this.getContentStream(uri)); |
| |
| } catch (IOException ioe) { |
| throw new ProcessingException ("Error loading resource: " + this.repoBaseUrl + uri, ioe); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#getContentStream(java.lang.String) |
| */ |
| public InputStream getContentStream(String uri) throws ProcessingException { |
| |
| if (this.getLogger().isDebugEnabled()) { |
| this.getLogger().debug("getting content of: " + uri); |
| } |
| |
| try { |
| |
| WebdavResource resource = WebDAVUtil.getWebdavResource(this.getAbsoluteURI(uri)); |
| if (!resource.exists()) { |
| throw new HttpException(uri + " does not exist"); |
| } |
| return new BufferedInputStream(resource.getMethodData()); |
| |
| } catch (MalformedURLException mue) { |
| throw new ProcessingException ("Bad URL for resource: " + this.repoBaseUrl + uri, mue); |
| } catch (IOException ioe) { |
| throw new ProcessingException ("Error loading resource: " + this.repoBaseUrl + uri, ioe); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#getContentDOM(java.lang.String) |
| */ |
| public Document getContentDOM(String uri) throws ProcessingException { |
| |
| DOMParser parser = null; |
| |
| try { |
| parser = (DOMParser)this.manager.lookup( DOMParser.ROLE); |
| return parser.parseDocument(new InputSource(this.getContentStream(uri))); |
| |
| } catch (SAXException se) { |
| throw new ProcessingException ("Error parsing: " + this.repoBaseUrl + uri, se); |
| } catch (IOException ioe) { |
| throw new ProcessingException ("Error getting: " + this.repoBaseUrl + uri, ioe); |
| } catch (ServiceException se) { |
| throw new ProcessingException ("Error getting DOMParser", se); |
| |
| } finally { |
| this.manager.release(parser); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#saveContent(java.lang.String, java.lang.String) |
| */ |
| public boolean saveContent(String uri, String content) { |
| |
| if (this.getLogger().isDebugEnabled()) { |
| this.getLogger().debug("save content to " + uri); |
| } |
| |
| try { |
| return WebDAVUtil.getWebdavResource(this.getAbsoluteURI(uri)).putMethod(content); |
| |
| } catch (HttpException he) { |
| this.getLogger().error("Error saving: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("Error saving: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#saveContent(java.lang.String, org.w3c.dom.Node) |
| */ |
| public boolean saveContent(String uri, Node node) { |
| |
| try { |
| Properties format = new Properties(); |
| format.put(OutputKeys.METHOD, "xml"); |
| format.put(OutputKeys.OMIT_XML_DECLARATION, "yes"); |
| return this.saveContent(uri, XMLUtils.serializeNode(node, format)); |
| |
| } catch (ProcessingException pe) { |
| this.getLogger().error("Error saving dom to: " + this.repoBaseUrl + uri, pe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#saveContent(java.lang.String, org.apache.excalibur.source.Source) |
| */ |
| public boolean saveContent(String uri, Source source) { |
| |
| try { |
| return this.saveContent(uri, IOUtils.toString(source.getInputStream())); |
| |
| } catch (IOException ioe) { |
| this.getLogger().error("Error saving source: " + source.getURI() + |
| " to "+ this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#createResource(java.lang.String, java.lang.String) |
| */ |
| public boolean createResource(String uri, String content) { |
| |
| if (this.getLogger().isDebugEnabled()) { |
| this.getLogger().debug("creating new resource " + uri); |
| } |
| |
| try { |
| WebDAVUtil.createResource(this.getAbsoluteURI(uri), content); |
| return true; |
| |
| } catch (HttpException he) { |
| this.getLogger().error("Error creating resource: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("Error creating resource: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#exists(java.lang.String) |
| */ |
| public boolean exists(String uri) { |
| |
| if (this.getLogger().isDebugEnabled()) { |
| this.getLogger().debug("checking existance of " + uri); |
| } |
| |
| try { |
| return WebDAVUtil.getWebdavResource(this.getAbsoluteURI(uri)).exists(); |
| |
| } catch (HttpException he) { |
| this.getLogger().error("HTTP Error occurred while checking for existance of: " + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("IO Error occurred while checking for existance of: " + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#copy(java.lang.String, java.lang.String, boolean) |
| */ |
| public boolean copy(String uri, String dest, boolean recurse, boolean overwrite) { |
| |
| try { |
| WebDAVUtil.copyResource(this.getAbsoluteURI(uri), this.getAbsoluteURI(dest), recurse, overwrite); |
| return true; |
| |
| } catch (HttpException he) { |
| this.getLogger().error("HTTP Error copying: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("IO Error copying: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#move(java.lang.String, java.lang.String, boolean) |
| */ |
| public boolean move(String uri, String dest, boolean recurse, boolean overwrite) { |
| |
| try { |
| WebDAVUtil.moveResource(this.getAbsoluteURI(uri), this.getAbsoluteURI(dest), recurse, overwrite); |
| return true; |
| } catch (HttpException he) { |
| this.getLogger().error("HTTP Error moving: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("IO Error moving: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#remove(java.lang.String) |
| */ |
| public boolean remove(String uri) { |
| |
| try { |
| return WebDAVUtil.getWebdavResource(this.getAbsoluteURI(uri)).deleteMethod(); |
| |
| } catch (HttpException he) { |
| this.getLogger().error("HTTP Error removing: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("IO Error removing: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#makeCollection(java.lang.String, boolean) |
| */ |
| public boolean makeCollection(String uri, boolean recursive) { |
| |
| try { |
| if (uri.endsWith("/")) uri = uri.substring(0, uri.length()-1); |
| if (recursive) { |
| WebDAVUtil.makePath(this.getAbsoluteURI(uri)); |
| return true; |
| } else { |
| String parent = uri.substring(0, uri.lastIndexOf("/")); |
| String collection = uri.substring(uri.lastIndexOf("/")+1); |
| WebDAVUtil.makeCollection(this.getAbsoluteURI(parent), collection); |
| return true; |
| } |
| |
| } catch (HttpException he) { |
| this.getLogger().error("HTTP Error making collection: " + this.repoBaseUrl + uri, he); |
| } catch (IOException ioe) { |
| this.getLogger().error("IO Error making collection: " + this.repoBaseUrl + uri, ioe); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * get a WebDAV property helper |
| * |
| * @return a WebDAV property helper. |
| */ |
| public RepositoryPropertyHelper getPropertyHelper() { |
| return this.propertyHelper; |
| } |
| |
| /** |
| * get a WebDAV transaction helper |
| * |
| * @return a WebDAV transaction helper. |
| */ |
| public RepositoryTransactionHelper getTransactionHelper() { |
| return this.transactionHelper; |
| } |
| |
| /** |
| * get a WebDAV versioning helper |
| * |
| * @return a WebDAV versioning helper. |
| */ |
| public RepositoryVersioningHelper getVersioningHelper() { |
| return this.versioningHelper; |
| } |
| |
| /** |
| * get the absolute URI of a given path |
| * |
| * @param uri the uri to get a versioning helper for. |
| * @return the absolute URI. |
| */ |
| public String getAbsoluteURI(String uri) { |
| |
| return "http://"+this.credentials.getPrincipal().getName() |
| +":"+this.credentials.getCredentials() |
| +"@"+this.repoBaseUrl + uri; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#getCredentials() |
| */ |
| public CredentialsToken getCredentials() { |
| return this.credentials; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.components.repository.Repository#setCredentials(org.apache.cocoon.components.repository.helpers.CredentialsToken) |
| */ |
| public void setCredentials(CredentialsToken credentials) { |
| this.credentials = credentials; |
| } |
| |
| } |