You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2002/03/15 19:49:32 UTC
cvs commit: xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/source BlobSource.java BlobSourceFactory.java blob.xconf
sylvain 02/03/15 10:49:32
Added: src/scratchpad/src/org/apache/cocoon/components/source
BlobSource.java BlobSourceFactory.java blob.xconf
Log:
New Blob source
Revision Changes Path
1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/source/BlobSource.java
Index: BlobSource.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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 (INCLUDING, 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. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.components.source;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.log.Logger;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.cocoon.ProcessingException;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.net.MalformedURLException;
import java.sql.*;
/**
* A <code>Source</code> that takes its content in a single JDBC column. Any
* kind of column can be used (clob, blob, varchar, etc), but "Blob" means
* that the whole content is contained in a single column.
* <p>The URL syntax is "blob:/datasource/table/column[cond]", where :
* <ul>
* <li>"datasource" is the jdbc datasource to use (defined in cocoon.xonf)
* <li>"table" is the database table,
* <li>"column" is (you can guess, now :) the column in "table",
* <li>"cond" is the boolean condition used to select a particular record in
* the table.
* </ul>
* <p>For example, "<code>blob:/personel/people/photo[userid='foo']</code>"
* will fetch the first column returned by the statement "<code>SELECT photo
* from people where userid='foo'</code>" in the datasource "<code>personel</code>"
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version $Id: BlobSource.java,v 1.1 2002/03/15 18:49:32 sylvain Exp $
*/
public class BlobSource extends AbstractStreamSource {
/**
* The system ID for this source
*/
private String systemId;
private String datasourceName;
private String tableName;
private String columnName;
private String condition;
private final static String URL_PREFIX = "blob:/";
private final static int URL_PREFIX_LEN = URL_PREFIX.length();
/**
* Create a file source from a 'blob:' url and a component manager.
* <p>The url is of the form "blob:/datasource/table/column[condition]
*/
public BlobSource(String url, ComponentManager manager) throws MalformedURLException {
super(manager);
if (!url.startsWith("blob:/")) {
throw new MalformedURLException("Malformed url for a blob source : " + url);
}
this.systemId = url;
// Parse the url
int start = URL_PREFIX_LEN;
int end;
// Datasource
end = url.indexOf('/', start);
if (end == -1) {
throw new MalformedURLException("Malformed blob source (cannot find datasource) : " + url);
}
this.datasourceName = url.substring(start, end);
// Table
start = end + 1;
end = url.indexOf('/', start);
if (end == -1) {
throw new MalformedURLException("Malformed blob source (cannot find table name) : " + url);
}
this.tableName = url.substring(start, end);
// Column
start = end + 1;
end = url.indexOf('[', start);
if (end == -1) {
this.columnName = url.substring(start);
} else {
this.columnName = url.substring(start, end);
// Condition
start = end + 1;
end = url.length() - 1;
if (url.charAt(end) != ']') {
throw new MalformedURLException("Malformed url for a blob source (cannot find condition) : " + url);
} else {
this.condition = url.substring(start, end);
}
}
}
/**
* Return the unique identifer for this source
*/
public String getSystemId() {
return this.systemId;
}
/**
* Get the input stream for this source.
*/
public InputStream getInputStream() throws IOException, ProcessingException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Opening stream for datasource " + this.datasourceName +
", table " + this.tableName + ", column " + this.columnName +
(this.condition == null ? ", no condition" : ", condition " + this.condition)
);
}
Connection cnx = null;
Statement stmt = null;
try {
cnx = getConnection();
stmt = cnx.createStatement();
StringBuffer selectBuf = new StringBuffer("SELECT ").append(this.columnName).
append(" FROM ").append(this.tableName);
if (this.condition != null) {
selectBuf.append(" WHERE ").append(this.condition);
}
String select = selectBuf.toString();
if (getLogger().isDebugEnabled()) {
getLogger().debug("Executing statement " + select);
}
ResultSet rs = stmt.executeQuery(select);
rs.next();
int colType = rs.getMetaData().getColumnType(1);
switch(colType) {
case Types.BLOB :
Blob blob = rs.getBlob(1);
return new JDBCInputStream(blob.getBinaryStream(), cnx);
//break;
case Types.CLOB :
Clob clob = rs.getClob(1);
return new JDBCInputStream(clob.getAsciiStream(), cnx);
//break;
default :
String value = rs.getString(1);
stmt.close();
rs.close();
cnx.close();
return new ByteArrayInputStream(value.getBytes());
}
} catch(SQLException sqle) {
String msg = "Cannot retrieve content from " + this.systemId;
getLogger().error(msg, sqle);
try {
if (cnx != null) {
cnx.close();
}
} catch(SQLException sqle2) {
// PITA
throw new ProcessingException("Cannot close connection", sqle2);
}
// IOException would be more adequate, but ProcessingException is cascaded...
throw new ProcessingException(msg, sqle);
}
}
private Connection getConnection() throws ProcessingException {
ComponentSelector selector = null;
DataSourceComponent datasource = null;
try {
try {
selector = (ComponentSelector)this.manager.lookup(DataSourceComponent.ROLE + "Selector");
datasource = (DataSourceComponent)selector.select(this.datasourceName);
} catch(Exception e) {
String msg = "Cannot get datasource '" + this.datasourceName + "'";
getLogger().error(msg);
throw new ProcessingException(msg, e);
}
try {
return datasource.getConnection();
} catch(Exception e) {
String msg = "Cannot get connection for datasource '" + this .datasourceName + "'";
getLogger().error(msg);
throw new ProcessingException(msg, e);
}
} finally {
if (datasource != null) {
selector.release(datasource);
}
}
}
/**
* An OutputStream that will close the connection that created it on
* close.
*/
private class JDBCInputStream extends FilterInputStream {
Connection cnx;
public JDBCInputStream(InputStream stream, Connection cnx) {
super(stream);
this.cnx = cnx;
}
public void close() throws IOException {
super.close();
if (this.cnx != null) {
try {
cnx.close();
cnx = null;
} catch(Exception e) {
String msg = "Error closing the connection for " + BlobSource.this.systemId;
BlobSource.this.getLogger().error(msg, e);
throw new IOException(msg + " : " + e.getMessage());
}
}
}
}
}
1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/source/BlobSourceFactory.java
Index: BlobSourceFactory.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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 (INCLUDING, 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. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.components.source;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.source.SourceFactory;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.ProcessingException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
/**
* A factory for 'blob:' sources.
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @version $Id: BlobSourceFactory.java,v 1.1 2002/03/15 18:49:32 sylvain Exp $
*/
public class BlobSourceFactory extends AbstractLoggable
implements SourceFactory, Composable, ThreadSafe {
private ComponentManager manager;
public void compose(ComponentManager manager) throws ComponentException {
this.manager = manager;
}
public Source getSource(Environment environment, String location)
throws ProcessingException, MalformedURLException, IOException {
Source result = new BlobSource(location, this.manager);
setupLogger(result);
return result;
}
public Source getSource(Environment environment, URL base, String location)
throws ProcessingException, MalformedURLException, IOException {
return getSource(environment, new URL(base, location).toExternalForm());
}
}
1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/source/blob.xconf
Index: blob.xconf
===================================================================
<?xml version="1.0"?>
<xconf xpath="/cocoon/source-handler" unless="protocol[@name='blob']">
<!-- blob pseudo protocol -->
<protocol name="blob" class="org.apache.cocoon.components.source.BlobSource"/>
</xconf>
----------------------------------------------------------------------
In case of troubles, e-mail: webmaster@xml.apache.org
To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org