/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id: Query.java 464373 2006-10-16 04:21:54Z rahul $
*/
package org.apache.shale.examples.sqlbrowser;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.model.ResultSetDataModel;
import javax.sql.DataSource;
import org.apache.shale.tiger.managed.Bean;
import org.apache.shale.tiger.managed.Scope;
import org.apache.shale.tiger.view.Destroy;
import org.apache.shale.tiger.view.Prerender;
import org.apache.shale.tiger.view.View;
/**
* <p>Backing bean for the SQL query demo page.</p>
*/
@Bean(name="query", scope=Scope.REQUEST)
@View
public class Query {
// ------------------------------------------------------ Instance Variables
/**
* <p>The JDBC connection we will be using.</p>
*/
private Connection conn = null;
/**
* <p>The JDBC result set we will be using.</p>
*/
private ResultSet rs = null;
/**
* <p>The JDBC statement we will be using.</p>
*/
private PreparedStatement stmt = null;
// ---------------------------------------------------------- JSF Properties
/**
* <p>Flag indicating whether the dynamically constructed table has been
* completed, and should therefore be displayed.</p>
*/
private boolean completed = false;
public boolean isCompleted() {
return this.completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
/**
* <p>The name of the JNDI data source we should use for querying.</p>
*/
private String dataSource = null;
public String getDataSource() {
return this.dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource;
}
/**
* <p>The SQL query we should execute.</p>
*/
private String query = null;
public String getQuery() {
return this.query;
}
public void setQuery(String query) {
this.query = query;
}
/**
* <p>The results table we will dynamically construct.</p>
*/
private HtmlDataTable results = new HtmlDataTable();
public HtmlDataTable getResults() {
return this.results;
}
public void setResults(HtmlDataTable results) {
this.results = results;
}
/**
* <p>The <code>ResultSetDataModel</code> to which we will bind
* our data table component.</p>
*/
private ResultSetDataModel resultSetDataModel = null;
public ResultSetDataModel getResultSetDataModel() {
return this.resultSetDataModel;
}
// ------------------------------------------------------ JSF Event Handlers
/**
* <p>Process the submit of the query form.</p>
*/
public String execute() {
return null;
}
// ------------------------------------------------- View Controller Methods
/**
* <p>Perform the dynamic query, and set up the corresponding columns.</p>
*/
@Prerender
public void prerender() {
// If there is no query string at all, do nothing
if ((query == null) || (query.length() < 1)) {
return;
}
// Perform the query and dynamically set up the results
FacesContext context = FacesContext.getCurrentInstance();
try {
// Look up the appropriate data source
// FIXME - add JNDI lookup support for non-internal
DataSource ds = (DataSource)
context.getExternalContext().getApplicationMap().get(Listener.INTERNAL_DATA_SOURCE);
conn = ds.getConnection();
// Execute the requested query
stmt = conn.prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery();
// Set up the data model for our result set
ResultSetMetaData rsmd = rs.getMetaData();
resultSetDataModel = new ResultSetDataModel(rs);
results.setFirst(0);
// Dynamically create columns as needed
List children = results.getChildren();
children.clear();
for (int i = 1; i <= rsmd.getColumnCount(); i++) { // SQL stuff is one-relative
UIColumn column = new UIColumn();
column.setId("column" + i);
children.add(column);
HtmlOutputText header = new HtmlOutputText();
String label = rsmd.getColumnLabel(i);
if ((label == null) || (label.length() < 1)) {
label = rsmd.getColumnName(i);
}
header.setValue(label);
column.setHeader(header);
HtmlOutputText data = new HtmlOutputText();
data.setId("data" + i);
data.setValueBinding("value",
context.getApplication().createValueBinding("#{current['" + rsmd.getColumnName(i) + "']}"));
column.getChildren().add(data);
}
/*
// Position to first few rows to ensure that we can
for (int i = 0; i < 10; i++) {
resultSetDataModel.setRowIndex(i);
System.err.println("prerender(): Row " + i + " exists? " + resultSetDataModel.isRowAvailable());
if (!resultSetDataModel.isRowAvailable()) {
break;
}
System.err.println("prerender(): Row " + i + " data: " + resultSetDataModel.getRowData());
}
*/
// Set the completed flag to indicate that we should display the results
completed = true;
} catch (Exception e) {
context.addMessage
(null, new FacesMessage("Exception executing this query: " + e));
while (e != null) {
context.getExternalContext().
log("Exception executing this query", e);
if (e instanceof SQLException) {
e = ((SQLException) e).getNextException();
} else {
e = null;
}
}
setCompleted(false);
}
}
/**
* <p>Clean up after rendering is complete, and close the connection
* (which returns it to the connection pool).</p>
*/
@Destroy
public void destroy() {
// Close the result set (if any) that we opened
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
// Close the statement (if any) that we opened
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
}
}
// Close the connection (if any) that we opened
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
}
}