Package org.openquark.gems.client.valueentry

Source Code of org.openquark.gems.client.valueentry.JDBCResultSetEditor$JDBCResultSetValueNodeAdapter

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * 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.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
*/


/*
* JDBCResultSetEditor.java
* Created: Apr. 8 / 2003
* By: David Mosimann
*/
package org.openquark.gems.client.valueentry;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.dnd.DragGestureEvent;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;

import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;
import javax.swing.table.TableColumnModel;

import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.foreignsupport.module.DataGems.DatabaseException;
import org.openquark.cal.foreignsupport.module.DataGems.QueryResult;
import org.openquark.cal.foreignsupport.module.DataGems.RecordPlaceholder;
import org.openquark.cal.module.Cal.Data.CAL_DataGems;
import org.openquark.cal.services.CALWorkspace;
import org.openquark.cal.valuenode.ForeignValueNode;
import org.openquark.cal.valuenode.ValueNode;
import org.openquark.cal.valuenode.ValueNodeBuilderHelper;


/**
* A ValueEditor customized for a data inspector.  It will display lists and lists of tuples.
*/
public class JDBCResultSetEditor extends ValueEditor implements LazyLoadingTableRowProvider {
   
    private static final long serialVersionUID = 8182700672556039687L;

    /**
     * This interface defines what drag operations are supported by the
     * <code>JDBCResultSetEditor</code>.  Implementors of this interface will be
     * called when a certain drag operation is initiated by the user.
     */
    public interface JDBCResultSetDragPointHandler extends ValueEditorDragPointHandler {

    /**
     * This method will be called when the user attempts to drag a list of columns
     * from the JDBC ResultSet set table.  By default, this method does nothing
     * and returns <code>false</code>.  Subclasses are encouraged to override
     * this method to define their own dragging behaviour.
     * @param dge
     * @param parentEditor
     * @param columnModel
     * @return boolean
     */
    boolean dragColumns(
        DragGestureEvent dge,
        JDBCResultSetEditor parentEditor,
        TableColumnModel columnModel);
    }

    /**
     * A custom value editor provider for the JDBCResultSetEditor.
     */
    public static class JDBCResultSetEditorProvider extends ValueEditorProvider<JDBCResultSetEditor> {

        public JDBCResultSetEditorProvider(ValueEditorManager valueEditorManager) {
            super(valueEditorManager);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean canHandleValue(ValueNode valueNode, SupportInfo providerSupportInfo) {
            return JDBCResultSetValueNodeAdapter.canHandleValue(valueNode)
//                    || JDBCRecordListValueNodeAdapter.canHandleValue(valueNode)
                    ;
        }
       
        /**
         * @see org.openquark.gems.client.valueentry.ValueEditorProvider#getEditorInstance(ValueEditorHierarchyManager, ValueNode)
         */
        @Override
        public JDBCResultSetEditor getEditorInstance(ValueEditorHierarchyManager valueEditorHierarchyManager, ValueNode valueNode) {
            JDBCResultSetEditor editor = new JDBCResultSetEditor(valueEditorHierarchyManager, null, getPerspective().getWorkspace());
            editor.setOwnerValueNode(valueNode);
            return editor;
        }

        /* (non-Javadoc)
         * @see org.openquark.gems.client.valueentry.ValueEditorProvider#getEditorInstance(org.openquark.gems.client.valueentry.ValueEditorHierarchyManager, org.openquark.cal.valuenode.ValueNodeBuilderHelper, org.openquark.gems.client.valueentry.ValueEditorDragManager, org.openquark.cal.valuenode.ValueNode)
         */
        @Override
        public JDBCResultSetEditor getEditorInstance(
                ValueEditorHierarchyManager valueEditorHierarchyManager,
                ValueNodeBuilderHelper valueNodeBuilderHelper,
                ValueEditorDragManager dragManager,
                ValueNode valueNode) {
            JDBCResultSetEditor editor =
                new JDBCResultSetEditor(
                    valueEditorHierarchyManager,
                    getJDBCResultSetDragPointHandler(dragManager),
                    getPerspective().getWorkspace());
            editor.setOwnerValueNode(valueNode);
            return editor;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean usableForOutput() {
            return true;
        }

        /**
         * A convenient method for casting the drag point handler to the type that is
         * suitable for the <code>JDBCResultSetEditor</code> to use.  If such conversion is not
         * possible, then this method should return <code>null</code>.
         * @param dragManager
         * @return JDBCResultSetDragPointHandler
         */
        private JDBCResultSetDragPointHandler getJDBCResultSetDragPointHandler(ValueEditorDragManager dragManager) {
            ValueEditorDragPointHandler handler = getDragPointHandler(dragManager);
            if (handler instanceof JDBCResultSetDragPointHandler) {
                return (JDBCResultSetDragPointHandler) handler;
            }
            return null;
        }
    }

    /**
     * A simple implementation of the JDBCQueryResultAdapter interface that is
     * able to adapt to a CAL value of type "DataGems.ResultSet".
     */   
    public static class JDBCResultSetValueNodeAdapter implements JDBCQueryResultAdapter {
       
        /**
         * CAL type used for this adapter.
         */
        private static final QualifiedName JDBC_RESULT_SET_NAME = CAL_DataGems.TypeConstructors.ResultSet;
       
        private final QueryResult resultSet;
       
        public JDBCResultSetValueNodeAdapter(ValueNode valueNode) {
            resultSet = (QueryResult) valueNode.getValue();
        }

        /**
         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#getResultSet()
         */
        public QueryResult getResultSet() {
            return resultSet;
        }

        /**
         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#getRow(int)
         */
        public RecordPlaceholder getRow(int index) throws DatabaseException {
            return resultSet.resultGetRecord(index+1);
        }

        /**
         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#hasRow(int)
         */
        public boolean hasRow(int index) {
            return resultSet.recordAt(index+1);
        }

        /**
         * Convenient method for testing if the given expression is of type
         * "DataGems.ResultSet".
         * @param valueNode
         * @return boolean
         */
        public static boolean canHandleValue(ValueNode valueNode) {
            if (valueNode instanceof ForeignValueNode) {
                return valueNode.getTypeExpr().hasRootTypeConstructor(JDBC_RESULT_SET_NAME);
            }
            return false;
        }

    }
   
//    /**
//     * A slighly more complex implementation of the JDBCQueryResultAdapter interface
//     * that is able to adapt to a CAL value of type "[DataGems.DatabaseRecord]".
//     */   
//    public static class JDBCRecordListValueNodeAdapter implements JDBCQueryResultAdapter {
//
//        /**
//         * CAL type used for this adapter.
//         */
//        private static final QualifiedName JDBC_RECORD_NAME = QualifiedName.make("DataGems", "DatabaseRecord");
//       
//        private QueryResult resultSet;
//        private ListValueNode listValueNode;
//       
//        public JDBCRecordListValueNodeAdapter(ValueNode valueNode) {
//            listValueNode = (ListValueNode) valueNode;
//            if (hasRow(0)) {
//                resultSet = getRow(0).getRecordSet();
//            }
//        }
//
//        /* (non-Javadoc)
//         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#getResultSet()
//         */
//        public QueryResult getResultSet() {
//            return resultSet;
//        }
//
//        /* (non-Javadoc)
//         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#getRow(int)
//         */
//        public RecordPlaceholder getRow(int index) {
//            ValueNode node = listValueNode.getValueAt(index);
//            return (RecordPlaceholder) node.getValue();
//        }
//
//        /* (non-Javadoc)
//         * @see org.openquark.gems.client.valueentry.JDBCQueryResultAdapter#hasRow(int)
//         */
//        public boolean hasRow(int index) {
//            return index >= 0 && index < listValueNode.getNElements();
//        }
//
//        /**
//         * Convenient method for testing if the given expression is of type "[DataGems.DatabaseRecord]".
//         * @param valueNode
//         * @return boolean
//         */
//        public static boolean canHandleValue(ValueNode valueNode) {
//            if (valueNode instanceof ListValueNode) {
//                TypeConsApp typeConsApp = valueNode.getTypeExpr().rootTypeConsApp();
//                if (typeConsApp.getNArgs() == 1) {
//                    return typeConsApp.getArg(0).isNonParametricType(JDBC_RECORD_NAME);                   
//                }
//            }
//            return false;
//        }
//    }

    /**
     * A simple variation of the lazy loading table that uses the string representation
     * of a cell's value as its tooltip text.
     */   
    private static class JDBCResultSetTable extends LazyLoadingTable {

        private static final long serialVersionUID = 6785306966736775696L;

        public JDBCResultSetTable(LazyLoadingTableRowProvider provider) {
            super(provider);
        }

        /* (non-Javadoc)
         * @see javax.swing.JComponent#getToolTipText(java.awt.event.MouseEvent)
         */
        @Override
        public String getToolTipText(MouseEvent event) {
            Point p = event.getPoint();
            int row = rowAtPoint(p);
            int column = columnAtPoint(p);
            if (row >= 0 && column >= 0) {
                Object value = getValueAt(row, column);
                return value == null ? "(no value)" : value.toString(); // TODO internationalization
            } else {
                return super.getToolTipText(event);
            }
        }
    }
   
    protected final LazyLoadingTable table;
    protected final JDBCResultSetDragPointHandler dragPointHandler;
    protected CALWorkspace workspace;

    private JScrollPane scrollPane;
   
    /**
     * Query result adapter used for this editor.  This adapter will be refreshed
     * whenever the owner value node is changed.
     */
    protected JDBCQueryResultAdapter adapter;

    /**
     * JDBCResultSetEditor constructor.  Intended to be used by the value editor
     * provider only.
     *
     * @param valueEditorHierarchyManager
     * @param dragPointHandler
     * @param workspace
     */
    protected JDBCResultSetEditor(
            ValueEditorHierarchyManager valueEditorHierarchyManager,
            JDBCResultSetDragPointHandler dragPointHandler,
            CALWorkspace workspace) {

        super(valueEditorHierarchyManager);
        this.dragPointHandler = dragPointHandler;
        this.workspace = workspace;

        // Create the JTable to show the records
        table = new JDBCResultSetTable(this);

        // Initialize the components
        initialize();
    }
   
    /**
     * Do some initialization work
     */
    private void initialize() {
        try {
            setName("JDBCResultSetEditor");
            setBorder(new EtchedBorder());
            setLayout(new BorderLayout());
            add(getScrollPane(), BorderLayout.CENTER);
            validate();
            setSize(getPreferredSize());
        } catch (Throwable ivjExc) {
            handleException(ivjExc);
        }
    }
   
    /**
     * Returns the query result adapter used for this editor.  Please note that this
     * value can never be null.
     * @return JDBCQueryResultAdapter
     */
    public JDBCQueryResultAdapter getResultAdapter() {
        return adapter;
    }
   
    /**
     * Converts the width, in terms of the number of character(s), to points
     * based on the default font.
     * @param width
     * @return double
     */
    public double convertWidthInCharToPoint(int width) {
        // TODO this method for estimating the average width of the characters
        // supported by the font might not be accurate, but it should be okay
        // for now
        Rectangle2D rec = getFont().getStringBounds(
            String.valueOf("m"),
            new FontRenderContext(null, true, false));
        return rec.getMaxX() * width;
    }

    /**
     * Returns the component that should be assigned focus when the control first appears
     */
    @Override
    public Component getDefaultFocusComponent() {
        return getScrollPane();
    }

    /**
     * Return the JScrollPane1 property value.
     * @return JScrollPane
     */
    private JScrollPane getScrollPane() {
        if (scrollPane == null) {
            try {
                scrollPane = new JScrollPane(table);
                scrollPane.setName("JScrollPane1");
                scrollPane.setOpaque(true);
                scrollPane.setBorder(new EtchedBorder());
                scrollPane.setBackground(new Color(204, 204, 204));

            } catch (Throwable ivjExc) {
                handleException(ivjExc);
            }
        }
        return scrollPane;
    }

    /**
     * Called whenever the part throws an exception.
     * @param exception Throwable
     */
    private void handleException(Throwable exception) {

        /* Uncomment the following lines to print uncaught exceptions to stdout */
        System.out.println("--------- UNCAUGHT EXCEPTION ---------");
        exception.printStackTrace(System.out);
    }

    /**
     * Sets the initial value.  This is used to update the UI to reflect the current value
     */
    @Override
    public void setInitialValue() {
        getScrollPane().getViewport().add(table);

        // If there is a row, set edit mode on the first cell and select first row.
        ListSelectionModel lsm = table.getSelectionModel();
        if (table.getRowCount() > 0 && lsm.isSelectionEmpty()) {
            lsm.setSelectionInterval(0, 0);
        }

        // Ensure that the containers update correctly to reflect the newly added table component
        doLayout();
    }

    /**
     * Sets the ValueNode for this editor.  The editor will be reinitialized with the new value
     * @param newValueNode
     */
    @Override
    public void setOwnerValueNode(ValueNode newValueNode) {
        // Set the new value node
        super.setOwnerValueNode(newValueNode);
       
        // pick the appropriate adapter for the value node and fill the table with
        // new information
        if (JDBCResultSetValueNodeAdapter.canHandleValue(newValueNode)) {
            adapter = new JDBCResultSetValueNodeAdapter(newValueNode);
            initializeTable();
        }
//        else if (JDBCRecordListValueNodeAdapter.canHandleValue(newValueNode)) {
//            adapter = new JDBCRecordListValueNodeAdapter(newValueNode);
//            initializeTable();
//        }
    }

    /* (non-Javadoc)
     * @see org.openquark.gems.client.valueentry.LazyLoadingTableRowProvider#hasRow(int)
     */
    public boolean hasRow(int row) {
        return adapter.hasRow(row);
    }

    /* (non-Javadoc)
     * @see org.openquark.gems.client.valueentry.LazyLoadingTableRowProvider#loadRow(int)
     */
    public Object[] loadRow(int row) {
        if (adapter.hasRow(row)) {
            try {
                RecordPlaceholder record = adapter.getRow(row);
                int size = adapter.getResultSet().getColumnCount();
                Object data[] = new Object[size];
                for (int i = 0; i < size; ++i) {
                    data[i] = record.extractObject(i+1);
                }
                return data;
            } catch (DatabaseException sqle) {
                // FIXME Log error
            }
        }
        return null;
    }

    private void initializeTable() {

        // Some variables we want to set and use inside the try/catch blocks
        LazyLoadingTableModel model = new LazyLoadingTableModel();
        TableColumnModel columnModel = table.getColumnModel();
        table.setTableHeader(new JDBCResultSetTableHeader(columnModel, this, dragPointHandler));
        QueryResult recordSet;
        int nColumns = 0;

        boolean failed = false;       
        try {
            // Get some information from the Record Set
            recordSet = adapter.getResultSet();
            if (recordSet != null) {
                // Set the appropriate columns into the table (note that this is 1-based not 0-based)
                nColumns = recordSet.getColumnCount();
                for (int i = 1; i <= nColumns; ++i) {
                    model.addColumn(recordSet.getColumnName(i));
                }
            } else {
                // cannot get the result set object: no column list
                failed = true;
            }
        } catch (DatabaseException e) {
            // FIXME Log this error
            failed = true;
        } finally {
            // If we fail to setup the headers then we're hooped.  Set an error message and return.
            if (failed) {
                model = new LazyLoadingTableModel();
                // TODO: localize the string
                model.addColumn("Failed to Browse Data");
                table.setModel(model);
                return;
            }
        }

        // We have finished building up the model so we need to set it into the table
        model.setGloballyEditable(false);
        table.setModel(model);

        // Resize the columns to make the UI look nicer.
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.doLayout();
    }

    /**
     * The JDBCResultSetEditor can only be used for output.  The values can not be edited
     * @return boolean
     */
    @Override
    public boolean isEditable() {
        return false;
    }

}
TOP

Related Classes of org.openquark.gems.client.valueentry.JDBCResultSetEditor$JDBCResultSetValueNodeAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.