/*
* � Copyright IBM Corp. 2010
*
* Licensed 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.
*/
package com.ibm.xsp.extlib.relational.jdbc.model;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.model.DataModel;
import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.FacesExceptionEx;
import com.ibm.xsp.context.FacesContextEx;
import com.ibm.xsp.extlib.model.DataAccessorSource;
import com.ibm.xsp.extlib.relational.util.JdbcUtil;
import com.ibm.xsp.model.DataContainer;
import com.ibm.xsp.model.TabularDataSource;
import com.ibm.xsp.util.StateHolderUtil;
import com.sun.rowset.CachedRowSetImpl;
/**
* Data source used to access JDBC enabled databases using a cached row set.
* @author Philippe Riand
*/
public class JdbcRowSetSource extends DataAccessorSource implements TabularDataSource {
// Service access
private String connectionManager;
private String connectionName;
private String connectionUrl;
private String sqlFile;
private String sqlQuery;
private String sqlTable;
private List<SqlParameter> sqlParameters;
private Integer maxRows;
private Boolean showDeleted;
private String rowSetJavaClass;
public JdbcRowSetSource() {
}
@Override
public boolean isReadonly() {
return false;
}
@Override
protected JdbcRowSetAccessor createAccessor() {
return new JdbcRowSetAccessor(this);
}
@Override
public DataModel getDataModel() {
return new JdbcRowSetAccessorModel(this,(Container)getDataContainer());
}
// PHIL: we assume the default id -> if the SQL change, the user must refresh the
// data source explicitly
// @Override
// protected String composeUniqueId() {
// String sq = getSqlQuery();
// if(StringUtil.isNotEmpty(sq)) {
// return sq;
// }
// String sf = getSqlFile();
// if(StringUtil.isNotEmpty(sf)) {
// return sf;
// }
// return super.composeUniqueId();
// }
public String getConnectionManager() {
if (null != connectionManager) {
return connectionManager;
}
ValueBinding valueBinding = getValueBinding("connectionManager"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setConnectionManager(String connectionManager) {
this.connectionManager = connectionManager;
}
public String getConnectionName() {
if (null != connectionName) {
return connectionName;
}
ValueBinding valueBinding = getValueBinding("connectionName"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setConnectionName(String connectionName) {
this.connectionName = connectionName;
}
public String getConnectionUrl() {
if (null != connectionUrl) {
return connectionUrl;
}
ValueBinding valueBinding = getValueBinding("connectionUrl"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setConnectionUrl(String connectionUrl) {
this.connectionUrl = connectionUrl;
}
public String getSqlFile() {
if (null != sqlFile) {
return sqlFile;
}
ValueBinding valueBinding = getValueBinding("sqlFile"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setSqlFile(String sqlFile) {
this.sqlFile = sqlFile;
}
public String getSqlQuery() {
if (null != sqlQuery) {
return sqlQuery;
}
ValueBinding valueBinding = getValueBinding("sqlQuery"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setSqlQuery(String sqlQuery) {
this.sqlQuery = sqlQuery;
}
public String getRowSetJavaClass() {
if (null != rowSetJavaClass) {
return rowSetJavaClass;
}
ValueBinding valueBinding = getValueBinding("rowSetJavaClass"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setRowSetJavaClass(String rowSetClass) {
this.rowSetJavaClass = rowSetClass;
}
public String getSqlTable() {
if (null != sqlTable) {
return sqlTable;
}
ValueBinding valueBinding = getValueBinding("sqlTable"); // $NON-NLS-1$
if (valueBinding != null) {
String value = (String)valueBinding.getValue(getFacesContext());
return value;
}
return null;
}
public void setSqlTable(String sqlTable) {
this.sqlTable = sqlTable;
}
public List<SqlParameter> getSqlParameters() {
return this.sqlParameters;
}
public void addSqlParameter(SqlParameter attribute) {
if(sqlParameters==null) {
sqlParameters = new ArrayList<SqlParameter>();
}
sqlParameters.add(attribute);
}
public void setSqlParameters(List<SqlParameter> parameters) {
this.sqlParameters = parameters;
}
public int getMaxRows() {
if (null != this.maxRows) {
return this.maxRows;
}
ValueBinding _vb = getValueBinding("maxRows"); //$NON-NLS-1$
if (_vb != null) {
Number val = (Number) _vb.getValue(FacesContext.getCurrentInstance());
if(val!=null) {
return val.intValue();
}
}
return 0;
}
public void setMaxRows(int maxRows) {
this.maxRows = maxRows;
}
public boolean isShowDeleted() {
if (null != this.showDeleted) {
return this.showDeleted;
}
ValueBinding _vb = getValueBinding("showDeleted"); //$NON-NLS-1$
if (_vb != null) {
Boolean val = (Boolean) _vb.getValue(FacesContext.getCurrentInstance());
if(val!=null) {
return val;
}
}
return false;
}
public void setShowDeleted(boolean showDeleted) {
this.showDeleted = showDeleted;
}
@Override
public Object saveState(FacesContext context) {
if (isTransient()) {
return null;
}
Object[] state = new Object[11];
state[0] = super.saveState(context);
state[1] = connectionManager;
state[2] = connectionName;
state[3] = connectionUrl;
state[4] = sqlFile;
state[5] = sqlQuery;
state[6] = sqlTable;
state[7] = rowSetJavaClass;
state[8] = StateHolderUtil.saveList(context, sqlParameters);
state[9] = maxRows;
state[10] = showDeleted;
return state;
}
@Override
public void restoreState(FacesContext context, Object state) {
Object[] values = (Object[])state;
super.restoreState(context, values[0]);
this.connectionManager = (String)values[1];
this.connectionName = (String)values[2];
this.connectionUrl = (String)values[3];
this.sqlFile = (String)values[4];
this.sqlQuery = (String)values[5];
this.sqlTable = (String)values[6];
this.rowSetJavaClass = (String)values[7];
this.sqlParameters = StateHolderUtil.restoreList(context, getComponent(), values[8]);
this.maxRows = (Integer)values[9];
this.showDeleted = (Boolean)values[10];
}
// ===================================================================
// JDBC related methods
// ===================================================================
public RowSet createRowSet() {
try {
RowSet rowSet = newRowSet();
initRowSet(rowSet);
return rowSet;
} catch(SQLException ex) {
throw new FacesExceptionEx(ex);
}
}
protected RowSet newRowSet() throws SQLException {
try {
String rsClass = getRowSetJavaClass();
if(StringUtil.isNotEmpty(rsClass)) {
try {
Class<?> c = FacesContextEx.getCurrentInstance().getContextClassLoader().loadClass(rsClass);
return (RowSet)c.newInstance();
} catch(Exception ex) {
throw new FacesExceptionEx(ex,StringUtil.format("Error while creating a RowSet object with class {0}", rsClass)); // $NLX-JdbcRowSetSource.Errorwhileinstanciating0ofclass1-1$ $NON-NLS-2$
}
} else {
CachedRowSet rs = new CachedRowSetImpl();
rs.setReadOnly(false);
return rs;
}
} catch(SQLException ex) {
throw new FacesExceptionEx(ex);
}
}
protected void initRowSet(RowSet rowSet) throws SQLException {
if(rowSet instanceof CachedRowSet) {
CachedRowSet r = (CachedRowSet)rowSet;
if(isShowDeleted()) {
r.setShowDeleted(true);
}
}
}
// ===================================================================
// JDBC related methods
// ===================================================================
public String findSqlQuery() {
// Look for a table name first
String tableName = getSqlTable();
if(StringUtil.isNotEmpty(tableName)) {
return StringUtil.format("SELECT * FROM {0}", tableName); // $NON-NLS-1$
}
// Look for the sql query property
String sql = getSqlQuery();
if(StringUtil.isNotEmpty(sql)) {
return sql;
}
// Then look for a resource
return JdbcUtil.readSqlFile(getSqlFile());
}
@Override
public boolean save(FacesContext context, DataContainer data)
throws FacesExceptionEx {
JdbcRowSetAccessor ac = ((JdbcRowSetAccessorModel)getDataModel()).getDataAccessor();
try {
ac.acceptChanges();
} catch (SQLException ex) {
throw new FacesExceptionEx(ex);
}
return true;
}
}