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 [EMAIL PROTECTED] * * 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:[EMAIL PROTECTED]">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 [EMAIL PROTECTED] * * 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:[EMAIL PROTECTED]">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: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]