001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.forms.data;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.sql.Blob;
021import java.sql.Connection;
022import java.sql.PreparedStatement;
023import java.sql.ResultSet;
024import java.sql.SQLException;
025
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.reading.ServiceableReader;
029import org.apache.commons.lang.StringUtils;
030import org.apache.excalibur.source.SourceUtil;
031import org.apache.tika.io.IOUtils;
032import org.xml.sax.SAXException;
033
034import org.ametys.core.datasource.ConnectionHelper;
035import org.ametys.core.datasource.dbtype.SQLDatabaseTypeExtensionPoint;
036import org.ametys.plugins.forms.table.FormTableManager;
037import org.ametys.runtime.config.Config;
038
039/**
040 * Reads a BLOB value of a form entry.
041 */
042public class FormEntryFileReader extends ServiceableReader
043{
044    private SQLDatabaseTypeExtensionPoint _sqlDatabaseTypeExtensionPoint;
045
046    private SQLDatabaseTypeExtensionPoint getSQLDatabaseTypeExtensionPoint()
047    {
048        if (_sqlDatabaseTypeExtensionPoint == null)
049        {
050            try
051            {
052                _sqlDatabaseTypeExtensionPoint = (SQLDatabaseTypeExtensionPoint) manager.lookup(SQLDatabaseTypeExtensionPoint.ROLE);
053            }
054            catch (ServiceException e)
055            {
056                throw new RuntimeException(e);
057            }
058        }
059        return _sqlDatabaseTypeExtensionPoint;
060    }
061    
062    @Override
063    public void generate() throws IOException, SAXException, ProcessingException
064    {
065        String siteName = parameters.getParameter("site", "");
066        String formId = parameters.getParameter("form-id", "");
067        int entryId = parameters.getParameterAsInteger("entry-id", Integer.MIN_VALUE);
068        String fieldId = parameters.getParameter("field-id", "");
069        
070        if (StringUtils.isEmpty(siteName) || StringUtils.isEmpty(formId)
071            || entryId == Integer.MIN_VALUE || StringUtils.isEmpty(fieldId))
072        {
073            throw new IllegalArgumentException("Site name, form id, entry id and field id must be provided.");
074        }
075        
076        String tableName = FormTableManager.TABLE_PREFIX + formId;
077        
078        Connection connection = null;
079        PreparedStatement stmt = null;
080        ResultSet rs = null;
081        InputStream is = null;
082        
083        
084        try
085        {
086            String dataSourceId = Config.getInstance().getValueAsString(FormTableManager.FORMS_POOL_CONFIG_PARAM);
087            connection = ConnectionHelper.getConnection(dataSourceId);
088            
089            String dbType = ConnectionHelper.getDatabaseType(connection);
090            String sql = "SELECT " + getSQLDatabaseTypeExtensionPoint().languageEscapeTableName(dbType, fieldId) + " FROM " + getSQLDatabaseTypeExtensionPoint().languageEscapeTableName(dbType, tableName) + " WHERE id = ?";
091            
092            stmt = connection.prepareStatement(sql);
093            
094            stmt.setInt(1, entryId);
095            
096            // Execute the query.
097            rs = stmt.executeQuery();
098            
099            // Extract the result.
100            if (rs.next())
101            {
102                if (ConnectionHelper.DATABASE_POSTGRES.equals(dbType))
103                {
104                    is = rs.getBinaryStream(1);
105                }
106                else
107                {
108                    Blob blob = rs.getBlob(1);
109                    if (blob != null)
110                    {
111                        is = blob.getBinaryStream();
112                    }
113                }
114                
115                if (is != null)
116                {
117                    SourceUtil.copy(is, out);
118                }
119            }
120        }
121        catch (SQLException e)
122        {
123            getLogger().error("Error reading a form entry blob." + tableName, e);
124            throw new ProcessingException("Error reading a form entry blob.", e);
125        }
126        finally
127        {
128            IOUtils.closeQuietly(is);
129            
130            ConnectionHelper.cleanup(rs);
131            ConnectionHelper.cleanup(stmt);
132            ConnectionHelper.cleanup(connection);
133        }
134    }
135}