com.apatar.http.HttpNode.java Source code

Java tutorial

Introduction

Here is the source code for com.apatar.http.HttpNode.java

Source

/*
_______________________
Apatar Open Source Data Integration
Copyright (C) 2005-2007, Apatar, Inc.
info@apatar.com
195 Meadow St., 2nd Floor
Chicopee, MA 01013
    
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
    
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.
    
 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
________________________
    
 */

package com.apatar.http;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JDialog;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.jdom.Element;

import propertysheet.JPropertySheetPage;

import com.apatar.core.AbstractApatarActions;
import com.apatar.core.AbstractDataBaseNode;
import com.apatar.core.AbstractNonJdbcDataBaseNode;
import com.apatar.core.ApplicationData;
import com.apatar.core.DBTypeRecord;
import com.apatar.core.DataBaseInfo;
import com.apatar.core.DataBaseTools;
import com.apatar.core.DataConversionAlgorithm;
import com.apatar.core.DataProcessingInfo;
import com.apatar.core.ERecordType;
import com.apatar.core.ETableMode;
import com.apatar.core.JdbcObject;
import com.apatar.core.KeyInsensitiveMap;
import com.apatar.core.RDBTable;
import com.apatar.core.Record;
import com.apatar.core.SchemaTable;
import com.apatar.core.TableInfo;
import com.apatar.core.DataBaseTools.SQLCreationData;
import com.apatar.core.DataBaseTools.SQLQueryString;
import com.apatar.http.ui.TableSchemaDescriptor;
import com.apatar.ui.schematable.JTableSchemaPanel;
import com.apatar.ui.wizard.DBConnectionDescriptor;
import com.apatar.ui.wizard.Wizard;
import com.apatar.ui.wizard.WizardPanelDescriptor;

public class HttpNode extends AbstractNonJdbcDataBaseNode {

    static final DataBaseInfo dataBaseInfo = new DataBaseInfo("", "", "\"", "\"", true, true, false, true, false);

    static {
        List<DBTypeRecord> rcList = dataBaseInfo.getAvailableTypes();
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "BIGINT", 8, 8, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "INT", 4, 4, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "INTEGER", 4, 4, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "SMALLINT", 2, 2, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "TINYINT", 1, 1, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Decimal, "FLOAT", 8, 8, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Decimal, "DOUBLE", 8, 8, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Decimal, "REAL", 8, 8, false, true));

        rcList.add(new DBTypeRecord(ERecordType.Boolean, "BIT", 1, 1, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Boolean, "BOOLEAN", 1, 1, false, false));

        rcList.add(new DBTypeRecord(ERecordType.Decimal, "DECIMAL", 16, 16, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Decimal, "NUMERIC", 16, 16, false, true));
        rcList.add(new DBTypeRecord(ERecordType.Text, "CHAR", 1, 255, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Text, "CHARACTER", 1, 255, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Text, "VARCHAR", 1, 255, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Text, "VARCHAR_IGNORECASE", 1, 255, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Text, "LONGVARCHAR", 1, 255, false, false));

        rcList.add(new DBTypeRecord(ERecordType.Date, "DATE", 4, 4, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Time, "TIME", 3, 3, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Date, "DATETIME", 8, 8, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Numeric, "TIMESTAMP", 8, 8, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Binary, "BINARY", 0, 65535, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Binary, "VARBINARY", 0, 65535, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Binary, "LONGVARBINARY", 0, 65535, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Object, "OBJECT", 0, 65535, false, false));
        rcList.add(new DBTypeRecord(ERecordType.Object, "OTHER", 0, 65535, false, false));

    }

    // data to be inserted before the transformation
    Object data[][] = new Object[0][0];

    public Object[][] getData() {
        return data;
    }

    public void setData(Object[][] data) {
        this.data = data;
    }

    public HttpNode() {
        super();
        title = "HTTP";

        // table name is the name of the output table
        table = new RDBTable(getTiForConnection(OUT_CONN_POINT_NAME).getTableName(), ETableMode.ReadWrite);

        SchemaTable sch = getTiForConnection(AbstractDataBaseNode.OUT_CONN_POINT_NAME).getSchemaTable();
        DBTypeRecord dbtRec = DataConversionAlgorithm.bestRecordLookup(getDataBaseInfo().getAvailableTypes(),
                ERecordType.Text, 255);
        sch.getRecords().add(0, new Record(dbtRec, "Response", 255, false, false, false));
        ;
    }

    @Override
    public void createDatabaseParam(Wizard wizard) {
        JDialog wd = wizard.getDialog();

        wd.setTitle(title + " Property");
        try {
            WizardPanelDescriptor descriptor1;

            descriptor1 = new DBConnectionDescriptor(this, new JPropertySheetPage(wd),
                    TableSchemaDescriptor.IDENTIFIER,
                    ApplicationData.classForName("com.apatar.http.HttpConnection"), "db_connector", "http");
            wizard.registerWizardPanel(DBConnectionDescriptor.IDENTIFIER, descriptor1);

            SchemaTable schema = getTiForConnection(AbstractDataBaseNode.OUT_CONN_POINT_NAME).getSchemaTable();
            TableSchemaDescriptor descriptor2 = new TableSchemaDescriptor(
                    new JTableSchemaPanel(ApplicationData.getTempDataBase().getDataBaseInfo().getAvailableTypes(),
                            schema.getRecords()),
                    this);
            wizard.registerWizardPanel(TableSchemaDescriptor.IDENTIFIER, descriptor2);

            wizard.setKeyForReferringToDescription("help.connector.http");
            wizard.setCurrentPanel(DBConnectionDescriptor.IDENTIFIER, Wizard.NEXT_BUTTON_ACTION_COMMAND);

            wizard.showModalDialog();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public ImageIcon getIcon() {
        return HttpUtils.READ_CUSTOM_TABLE_NODE_ICON;
    }

    @Override
    public Element saveToElement() {
        Element node = super.saveToElement();

        Element datas = new Element("datas");
        for (Object[] element : data) {
            Element dataElement = new Element("data");
            for (int j = 0; j < element.length; j++) {
                Element column = new Element("column");
                if (element[j] != null) {
                    column.addContent(element[j].toString());
                    column.setAttribute("index", "" + j);
                    dataElement.addContent(column);
                }
            }
            datas.addContent(dataElement);
        }
        node.addContent(datas);
        return node;
    }

    @Override
    public void initFromElement(Element node) {
        super.initFromElement(node);
    }

    @Override
    public List<RDBTable> getTableList() throws Exception {
        ArrayList<RDBTable> rv = new ArrayList<RDBTable>();
        rv.add(table);
        return rv;
    }

    // this method is called before any transformation to make sure that
    // all the required internal tables exist
    @Override
    public void BeforeExecute() {
        super.BeforeExecute();

        // fill the resulting database after creation with the data that has to
        // be filled in
        try {
            KeyInsensitiveMap datas = new KeyInsensitiveMap();
            TableInfo ti = getTiForConnection(OUT_CONN_POINT_NAME);

            List<Record> records = ti.getSchemaTable().getRecords();

            for (Object[] element : data) {
                datas.clear();
                for (int j = 0; j < element.length; j++) {
                    datas.put(records.get(j).getFieldName(), element[j].toString());
                }

                DataBaseTools.insertData(new DataProcessingInfo(dataBaseInfo, ti.getTableName(), ti.getRecords(),
                        ApplicationData.getTempJDBC()), datas);

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void TransformRDBtoTDB() {
        DataBaseTools.completeTransfer();
        // This method logically is not required for HttpNode
        // all the data is already stored in the output table
    }

    @Override
    protected void TransformTDBtoRDB(int mode) {
        DataBaseTools.completeTransfer();
        HttpConnection conn = (HttpConnection) ApplicationData.getProject().getProjectData(getConnectionDataID())
                .getData();
        String url = conn.getUrl();
        HttpRequestMethod httpRequestMethod = (HttpRequestMethod) conn.getMethod();

        TableInfo ti = getTiForConnection(IN_CONN_POINT_NAME);

        TableInfo tiOut = getTiForConnection(OUT_CONN_POINT_NAME);

        List<Record> selectionList = DataBaseTools.intersectionRecords(tiOut.getRecords(), ti.getRecords(), true);

        // read values from result set and put it in request
        SQLQueryString sqs = DataBaseTools.CreateSelectString(ApplicationData.getTempDataBase().getDataBaseInfo(),
                new SQLCreationData(selectionList, ti.getTableName()), null);

        if (sqs == null) {
            return;
        }

        ResultSet rs;
        try {
            rs = DataBaseTools.executeSelect(sqs, ApplicationData.getTempJDBC());

            while (rs.next()) {
                KeyInsensitiveMap rsData = DataBaseTools.GetDataFromRS(rs);

                HttpMethod hm;

                if (httpRequestMethod == HttpRequestMethod.post) {
                    hm = sendPost(url, rsData);
                } else {
                    hm = sendGet(url, rsData);
                }

                HttpClient client = new HttpClient();
                if (ApplicationData.httpClient.isUseProxy()) {
                    HostConfiguration hostConfig = client.getHostConfiguration();
                    hostConfig.setProxy(ApplicationData.httpClient.getHost(), ApplicationData.httpClient.getPort());
                    String proxyUser = ApplicationData.httpClient.getUserName();
                    if (proxyUser != null) {
                        client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
                                proxyUser, ApplicationData.httpClient.getPassword()));
                    }
                }

                client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
                int status = client.executeMethod(hm);

                KeyInsensitiveMap datas = new KeyInsensitiveMap();

                if (status != HttpStatus.SC_OK) {
                    datas.put("Response", "Upload failed, response=" + HttpStatus.getStatusText(status));
                } else {
                    datas.put("Response", hm.getResponseBodyAsString());
                }

                ti = getTiForConnection(OUT_CONN_POINT_NAME);

                List<Record> recs = getTiForConnection(AbstractDataBaseNode.OUT_CONN_POINT_NAME).getSchemaTable()
                        .getRecords();

                for (int j = 1; j < recs.size(); j++) {
                    Record rec = recs.get(j);
                    datas.put(rec.getFieldName(), rs.getObject(rec.getFieldName()));
                }

                DataBaseTools.insertData(new DataProcessingInfo(ApplicationData.getTempDataBase().getDataBaseInfo(),
                        ti.getTableName(), ti.getRecords(), ApplicationData.getTempJDBC()), datas);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        DataBaseTools.completeTransfer();
    }

    private HttpMethod sendPost(String url, KeyInsensitiveMap data) {

        try {

            PostMethod post = new PostMethod(url);
            List<Record> recs = getTiForConnection(AbstractDataBaseNode.OUT_CONN_POINT_NAME).getSchemaTable()
                    .getRecords();
            Part[] parts = new Part[recs.size() - 1];
            for (int i = 1; i < recs.size(); i++) {
                Record rec = recs.get(i);
                String fieldName = rec.getFieldName();
                Object obj = data.get(fieldName, true);
                if (obj instanceof JdbcObject) {
                    obj = ((JdbcObject) obj).getValue();
                }
                if (rec.getType() == ERecordType.Binary) {
                    parts[i - 1] = new FilePart(fieldName, ApplicationData.createFile("temp.temp", (byte[]) obj));
                } else {
                    parts[i - 1] = new StringPart(fieldName, obj.toString());
                }
            }
            post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));

            return post;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private HttpMethod sendGet(String url, KeyInsensitiveMap data) {
        try {
            GetMethod get = new GetMethod(url);
            List<Record> recs = getTiForConnection(AbstractDataBaseNode.OUT_CONN_POINT_NAME).getSchemaTable()
                    .getRecords();
            for (int i = 1; i < recs.size(); i++) {
                Record rec = recs.get(i);
                String fieldName = rec.getFieldName();
                Object obj = data.get(fieldName, true);
                if (obj instanceof JdbcObject) {
                    obj = ((JdbcObject) obj).getValue();
                }
                if (rec.getType() == ERecordType.Binary) {
                    continue;
                } else {
                    get.addRequestHeader(fieldName, obj.toString());
                }
            }

            return get;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // table is internal it is already created
    @Override
    public void createSchemaTable(AbstractApatarActions actions) throws Exception {
    }

    @Override
    public void deleteAllRecordsInRDB() throws Exception {
    }

    @Override
    public List<Record> getFieldList(AbstractApatarActions actions) throws Exception {
        TableInfo ti = getTiForConnection(OUT_CONN_POINT_NAME);

        List<Record> res = new ArrayList<Record>();
        for (Record rec : ti.getSchemaTable().getRecords()) {
            DBTypeRecord dbirec = DBTypeRecord.getRecordByOriginalType(getDataBaseInfo().getAvailableTypes(),
                    rec.getOriginalType());
            res.add(new Record(dbirec, rec.getFieldName(), rec.getLength(), rec.isNullable(), false,
                    rec.isPrimaryKey()));
        }

        return ti.getSchemaTable().getRecords();
    }

    @Override
    public DataBaseInfo getDataBaseInfo() {
        return dataBaseInfo;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.apatar.core.AbstractDataBaseNode#validateConnectionData()
     */
    @Override
    public boolean validateConnectionData() {
        HttpConnection conn = (HttpConnection) ApplicationData.getProject().getProjectData(connectionDataId)
                .getData();
        if (conn.getUrl() == null || "".equals(conn.getUrl())) {
            lastErrorMessage = "URL should not be empty";
            return false;
        }
        return true;
    }

}