package com.vividsolutions.jump.workbench.ui.plugin.datastore;
import java.util.ArrayList;
import java.util.Collection;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jump.datastore.AdhocQuery;
import com.vividsolutions.jump.datastore.FilterQuery;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.io.FeatureInputStream;
import com.vividsolutions.jump.io.datasource.Connection;
import com.vividsolutions.jump.io.datasource.DataSource;
import com.vividsolutions.jump.task.TaskMonitor;
import com.vividsolutions.jump.util.CollectionUtil;
import com.vividsolutions.jump.util.LangUtil;
import com.vividsolutions.jump.workbench.WorkbenchContext;
import com.vividsolutions.jump.workbench.datastore.ConnectionDescriptor;
import com.vividsolutions.jump.workbench.datastore.ConnectionManager;
import com.vividsolutions.jump.workbench.model.cache.CachingFeatureCollection;
import com.vividsolutions.jump.workbench.model.cache.DynamicFeatureCollection;
import com.vividsolutions.jump.workbench.plugin.PlugInContext;
import com.vividsolutions.jump.workbench.ui.plugin.WorkbenchContextReference;
/**
* Implements the DataSource interface in order to persist a query issued
* from RunDatastoreQueryPlugIn.
*/
public class DataStoreQueryDataSource extends DataSource implements
WorkbenchContextReference {
public static final String DATASET_NAME_KEY = "Dataset Name";
public static final String SQL_QUERY_KEY = "SQL Query";
public static final String CONNECTION_DESCRIPTOR_KEY = "Connection Descriptor";
private WorkbenchContext context;
public DataStoreQueryDataSource() {
// Called by Java2XML [Jon Aquino 2005-03-16]
}
public DataStoreQueryDataSource(String datasetName,
String query,
ConnectionDescriptor connectionDescriptor,
WorkbenchContext context) {
setProperties(CollectionUtil.createMap(new Object[] {
DATASET_NAME_KEY, datasetName,
SQL_QUERY_KEY, query,
CONNECTION_DESCRIPTOR_KEY, connectionDescriptor}));
setWorkbenchContext(context);
}
public boolean isWritable() {
return false;
}
public Connection getConnection() {
return new Connection() {
public FeatureCollection executeQuery(String query,
Collection exceptions, TaskMonitor monitor) {
try {
return createFeatureCollection();
} catch (Exception e) {
exceptions.add(e);
return null;
}
}
public FeatureCollection executeQuery(String query,
TaskMonitor monitor) throws Exception {
Collection exceptions = new ArrayList();
FeatureCollection featureCollection = executeQuery(query,
exceptions, monitor);
if (!exceptions.isEmpty()) {
throw (Exception) exceptions.iterator().next();
}
return featureCollection;
}
public void executeUpdate(String query,
FeatureCollection featureCollection, TaskMonitor monitor)
throws Exception {
throw new UnsupportedOperationException();
}
public void close() {
// Do nothing, because DataStore connections are always
// open (managed by the ConnectionManager). [Jon Aquino
// 2005-03-16]
}
};
}
private FeatureCollection createFeatureCollection() {
FeatureInputStream featureInputStream = null;
FeatureDataset featureDataset = null;
ConnectionDescriptor connectionDescriptor =
(ConnectionDescriptor)getProperties().get(CONNECTION_DESCRIPTOR_KEY);
String query = (String)getProperties().get(SQL_QUERY_KEY);
String driver = connectionDescriptor.getDataStoreDriverClassName();
if (driver.contains("Postgis") && query.matches("(?s).*\\$\\{[^\\{\\}]*\\}.*")) {
query = expandQuery(query, context.createPlugInContext());
}
try {
featureInputStream = ConnectionManager.instance(context)
.getOpenConnection(connectionDescriptor).execute(new AdhocQuery(query));
featureDataset = new FeatureDataset(featureInputStream.getFeatureSchema());
int i = 0;
while (featureInputStream.hasNext()) {
featureDataset.add( featureInputStream.next() );
}
return featureDataset;
}
catch(Exception e) {
context.getWorkbench().getFrame().handleThrowable(e);
}
finally {
if (featureInputStream != null) {
try {featureInputStream.close();}
catch(Exception e){}
}
}
return featureDataset;
}
public void setWorkbenchContext(WorkbenchContext context) {
this.context = context;
try {
// This method is called by OpenProjectPlugIn in the
// GUI thread, so now is a good time to prompt for
// a password if necessary. [Jon Aquino 2005-03-16]
new PasswordPrompter().getOpenConnection(ConnectionManager
.instance(context),
(ConnectionDescriptor) getProperties().get(
CONNECTION_DESCRIPTOR_KEY), context.getWorkbench()
.getFrame());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private String expandQuery(String query, PlugInContext context) {
GeometryFactory gf = new GeometryFactory();
Geometry viewG = gf.toGeometry(context.getLayerViewPanel().getViewport().getEnvelopeInModelCoordinates());
Geometry fenceG = context.getLayerViewPanel().getFence();
if (viewG != null) {
query = query.replaceAll("\\$\\{view\\}", "\\${view:-1}");
query = query.replaceAll("\\$\\{view(?::(-?[0-9]+))\\}", "ST_GeomFromText('" + viewG.toText() + "',$1)");
}
if (fenceG != null) {
query = query.replaceAll("\\$\\{fence\\}", "\\${fence:-1}");
query = query.replaceAll("\\$\\{fence(?::(-?[0-9]+))\\}", "ST_GeomFromText('" + fenceG.toText() + "',$1)");
}
else {
query = query.replaceAll("\\$\\{fence\\}", "\\${fence:-1}");
query = query.replaceAll("\\$\\{fence(?::(-?[0-9]+))\\}", "ST_GeomFromText('POLYGON EMPTY',$1)");
}
return query;
}
}