package org.openjump.core.ui.plugin.queries;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
import buoy.event.*;
import buoy.widget.*;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.feature.AttributeType;
import com.vividsolutions.jump.feature.BasicFeature;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;
import com.vividsolutions.jump.util.CollectionMap;
import com.vividsolutions.jump.workbench.model.CategoryEvent;
import com.vividsolutions.jump.workbench.model.FeatureEvent;
import com.vividsolutions.jump.workbench.model.Layer;
import com.vividsolutions.jump.workbench.model.LayerEvent;
import com.vividsolutions.jump.workbench.model.LayerListener;
import com.vividsolutions.jump.workbench.model.LayerManagerProxy;
import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
import com.vividsolutions.jump.workbench.plugin.PlugInContext;
import com.vividsolutions.jump.workbench.ui.FeatureSelection;
import com.vividsolutions.jump.workbench.ui.InfoFrame;
import com.vividsolutions.jump.workbench.ui.TaskFrame;
/**
* QueryDialog
* @author Michael MICHAUD
* version 0.1.0 (4 Dec 2004)
* version 0.1.1 (15 Jan 2005)
* version 0.2 (16 Oct 2005)
* version 0.2.1 (10 aug 2007)
* version 0.3.0 (04 sept 2010) complete rewrite of functionChenged and operatorChanged methods
*/
public class QueryDialog extends BDialog {
public static final int ALL_LAYERS = 0;
public static final int SELECTION = 1;
public static final int SELECTED_LAYERS = 2;
public static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat();
private PlugInContext context;
// List of layers to search
List layers = new ArrayList();
// List of available attributes
Set attributes = new TreeSet();
// Selected attribute name
String attribute;
// Selected attribute type
char attributeType;
// Selected function
Function function;
// Selected operator
Operator operator;
// Selected value
String value;
// Map attributes with lists of available values read in the fc
Map enumerations = new HashMap();
// Flag indicating a query is running
static boolean runningQuery = false;
static boolean cancelQuery = false;
// if mmpatch is used (mmpatch gives more attribute types), mmaptch must
// be set to true
// boolean mmpatch = false;
// selected features initialized in execute query if "select" option is true
Collection selection;
BCheckBox charFilter;
BCheckBox caseSensitive;
BCheckBox numFilter;
BCheckBox geoFilter;
BCheckBox display;
BCheckBox select;
BCheckBox create;
BComboBox layerCB;
BComboBox attributeCB;
BComboBox functionCB;
BComboBox operatorCB;
BComboBox valueCB;
BLabel comments;
BLabel progressBarTitle;
BProgressBar progressBar;
BButton okButton;
BButton refreshButton;
BButton cancelButton;
BButton stopButton;
/**
* Main method : create a Query Dialog.
*/
//public static void main(String[] args) {
//BFrame frame = new BFrame();
//QueryDialog qd = new QueryDialog(null);
//}
/**
* Overloads createComponent in BDialog, in order to link this BDialog
* to a swing Window (instead of a WindowWidget).
*/
//protected JDialog createComponent(Window parent, String title, boolean modal) {
//return super.createComponent(parent, "", modal);
//}
/**
* Constructor of a QueryDialog
* @param context the plugin context
*/
public QueryDialog(PlugInContext context) {
component = super.createComponent(context.getWorkbenchFrame(), "", false);
//component = createComponent(context.getWorkbenchFrame(), "", false);
//initInternal();
//BDialog dialog = new BDialog();
addEventLink(WindowClosingEvent.class, this, "exit");
//if (AttributeType.allTypes().size()>6) {
// mmpatch = true;
//}
this.context = context;
setTitle(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.query-builder"));
initUI(context);
}
/**
* Perform internal initialization.
* Copied from BDialog because it is declared as a private method.
* (the method is called in QueryDialog constructor)
*/
/*private void initInternal() {
component.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ev) {
if (lastSize == null || !lastSize.equals(component.getSize())) {
lastSize = null;
layoutChildren();
QueryDialog.this.dispatchEvent(new WindowResizedEvent(QueryDialog.this));
}
else
lastSize = null;
}
});
((JDialog) component).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}*/
/**
* User Interface Initialization
*/
protected void initUI(PlugInContext context) {
// LAYOUT DEFINITIONS
LayoutInfo centerNone6 =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.NONE,
new java.awt.Insets(6,6,6,6), new java.awt.Dimension());
LayoutInfo centerBoth3 =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.BOTH,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo centerBoth1 =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.BOTH,
new java.awt.Insets(1,1,1,1), new java.awt.Dimension());
LayoutInfo nwBoth1 =
new LayoutInfo(LayoutInfo.NORTHWEST, LayoutInfo.BOTH,
new java.awt.Insets(1,1,1,1), new java.awt.Dimension());
LayoutInfo centerNone3 =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.NONE,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo centerH3 =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.HORIZONTAL,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo centerBoth =
new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.BOTH,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo rightAlign =
new LayoutInfo(LayoutInfo.EAST, LayoutInfo.HORIZONTAL,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo leftAlign =
new LayoutInfo(LayoutInfo.WEST, LayoutInfo.HORIZONTAL,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
LayoutInfo leftAlignShort =
new LayoutInfo(LayoutInfo.WEST, LayoutInfo.NONE,
new java.awt.Insets(3,3,3,3), new java.awt.Dimension());
Border border = BorderFactory.createLineBorder(java.awt.Color.BLACK);
Border border2 = BorderFactory.createLineBorder(java.awt.Color.BLACK, 2);
// MAIN GUI CONTAINERS
BorderContainer dialogContainer = new BorderContainer();
// NORTH
BorderContainer northPanel = new BorderContainer();
BorderContainer titleContainer = new BorderContainer();
titleContainer.setDefaultLayout(centerNone6);
// CENTER
FormContainer centerPanel = new FormContainer(1,3);
//OPTIONS
FormContainer optionPanel = new FormContainer(4,1);
optionPanel.setDefaultLayout(centerBoth1);
BOutline optionPanelB = new BOutline(optionPanel, border);
// MANAGER
FormContainer managerPanel = new FormContainer(3,3);
managerPanel.setDefaultLayout(nwBoth1);
BOutline managerPanelB = new BOutline(managerPanel,
BorderFactory.createTitledBorder(border,
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.query-manager")));
// ATTRIBUTE FILTER
FormContainer attributeFilterPanel = new FormContainer(2,3);
attributeFilterPanel.setDefaultLayout(nwBoth1);
BOutline attributeFilterPanelB = new BOutline(attributeFilterPanel,
BorderFactory.createTitledBorder(border,
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.filter-on-attribute-type")));
// RESULT OPTIONS
FormContainer resultPanel = new FormContainer(1,3);
resultPanel.setDefaultLayout(nwBoth1);
BOutline resultPanelB = new BOutline(resultPanel,
BorderFactory.createTitledBorder(border,
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.results")));
// QUERY CONSTRUCTOR
//FormContainer queryConstructorPanel = new FormContainer(5,3);
FormContainer queryConstructorPanel = new FormContainer(2,7);
queryConstructorPanel.setBackground(Color.decode(
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.color1")
));
queryConstructorPanel.setDefaultLayout(centerNone3);
BOutline queryConstructorPanelB = new BOutline(queryConstructorPanel, border2);
// PROGRESS BAR
FormContainer progressBarPanel = new FormContainer(5,1);
// SOUTH PANEL (OK/CANCEL BUTTONS)
FormContainer southPanel = new FormContainer(7,1);
// SET THE MANAGER BUTTONS
BButton openButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.open"));
openButton.addEventLink(CommandEvent.class, this, "open");
managerPanel.add(openButton, 1, 0, centerH3);
BButton saveasButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.save-as"));
saveasButton.addEventLink(CommandEvent.class, this, "saveas");
managerPanel.add(saveasButton, 1, 2, centerH3);
// SET THE ATTRIBUTE FILTER CHECKBOXES
charFilter = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.string"), true);
charFilter.addEventLink(ValueChangedEvent.class, this, "charFilterChanged");
attributeFilterPanel.add(charFilter, 0, 0);
caseSensitive = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.case-sensitive"), false);
//caseSensitive.addEventLink(ValueChangedEvent.class, this, "caseSensitiveChanged");
attributeFilterPanel.add(caseSensitive, 1, 0, centerNone3);
numFilter = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.numeric"), true);
numFilter.addEventLink(ValueChangedEvent.class, this, "numFilterChanged");
attributeFilterPanel.add(numFilter, 0, 1);
geoFilter = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.geometric"), true);
geoFilter.addEventLink(ValueChangedEvent.class, this, "geoFilterChanged");
attributeFilterPanel.add(geoFilter, 0, 2);
// SET THE RESULT OPTIONS
display = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.display-the-table"), false);
resultPanel.add(display, 0, 0);
select = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.select-the-result"), true);
resultPanel.add(select, 0, 1);
create = new BCheckBox(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.create-a-new-layer"), false);
resultPanel.add(create, 0, 2);
// SET THE COMBO BOXES
BLabel layerLabel = new BLabel(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.layer"), BLabel.EAST);
queryConstructorPanel.add(layerLabel, 0, 0, rightAlign);
BLabel attributeLabel = new BLabel(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.attribute"), BLabel.EAST);
queryConstructorPanel.add(attributeLabel, 0, 1, rightAlign);
BLabel functionLabel = new BLabel(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.function"), BLabel.EAST);
queryConstructorPanel.add(functionLabel, 0, 2, rightAlign);
BLabel operatorLabel = new BLabel(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.operator"), BLabel.EAST);
queryConstructorPanel.add(operatorLabel, 0, 3, rightAlign);
BLabel valueLabel = new BLabel(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.value"), BLabel.EAST);
queryConstructorPanel.add(valueLabel, 0, 4, rightAlign);
layerCB = new BComboBox();
layerCB.addEventLink(ValueChangedEvent.class, this, "layerChanged");
queryConstructorPanel.add(layerCB, 1, 0, leftAlign);
// mmichaud 2008-11-13 limit the width to about 40 chars
((javax.swing.JComboBox)layerCB.getComponent())
.setPrototypeDisplayValue("012345678901234567890123456789O1");
attributeCB = new BComboBox();
attributeCB.addEventLink(ValueChangedEvent.class, this, "attributeChanged");
queryConstructorPanel.add(attributeCB, 1, 1, leftAlign);
// mmichaud 2008-11-13 limit the width to about 40 chars
((javax.swing.JComboBox)attributeCB.getComponent())
.setPrototypeDisplayValue("01234567890123456789012345678901");
functionCB = new BComboBox();
functionCB.addEventLink(ValueChangedEvent.class, this, "functionChanged");
queryConstructorPanel.add(functionCB, 1, 2, leftAlignShort);
operatorCB = new BComboBox();
operatorCB.addEventLink(ValueChangedEvent.class, this, "operatorChanged");
queryConstructorPanel.add(operatorCB, 1, 3, leftAlignShort);
valueCB = new BComboBox();
valueCB.addEventLink(ValueChangedEvent.class, this, "valueChanged");
queryConstructorPanel.add(valueCB, 1, 4, leftAlign);
// mmichaud 2008-11-13 limit the width to about 40 chars
((javax.swing.JComboBox)valueCB.getComponent())
.setPrototypeDisplayValue("012345678901234567890123456789012345678901234567");
comments = new BLabel("<html> <br> </html>");
queryConstructorPanel.add(comments, 0, 5, 2, 2, centerBoth);
// PROGRESS BAR PANEL
progressBarTitle = new BLabel(" ");
progressBarPanel.add(progressBarTitle, 0, 0, 1, 1, centerH3);
progressBar = new BProgressBar();
progressBarPanel.add(progressBar, 1, 0, 4, 1, centerH3);
// CENTER PANEL LAYOUT
optionPanel.add(managerPanelB, 0, 0);
optionPanel.add(attributeFilterPanelB, 1, 0, 2, 1);
optionPanel.add(resultPanelB, 3, 0);
centerPanel.setDefaultLayout(centerBoth3);
centerPanel.add(optionPanel, 0, 0);
centerPanel.add(queryConstructorPanelB, 0, 1);
centerPanel.add(progressBarPanel, 0, 2);
// SET THE OK/CANCEL BUTTONS
okButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.ok"));
okButton.addEventLink(CommandEvent.class, this, "ok");
//cancelButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.cancel"));
// cancelButton.addEventLink(CommandEvent.class, this, "cancel");
stopButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.stop"));
stopButton.addEventLink(CommandEvent.class, this, "stop");
refreshButton = new BButton(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.refresh"));
refreshButton.addEventLink(CommandEvent.class, this, "refresh");
southPanel.add(okButton, 2, 0);
southPanel.add(refreshButton, 3, 0);
//southPanel.add(cancelButton, 4, 0);
southPanel.add(stopButton, 4, 0);
dialogContainer.add(northPanel, dialogContainer.NORTH);
dialogContainer.add(centerPanel, dialogContainer.CENTER);
dialogContainer.add(southPanel, dialogContainer.SOUTH);
// added on 2007-08-22 to synchronize the UI with layerNamePanel changes
context.getLayerManager().addLayerListener(new LayerListener() {
public void categoryChanged(CategoryEvent e) {}
public void featuresChanged(FeatureEvent e) {}
public void layerChanged(LayerEvent e) {if (!runningQuery) refresh();}
});
initComboBoxes();
setContent(dialogContainer);
addEventLink(MouseEnteredEvent.class, this, "toFront");
pack();
setVisible(true);
toFront();
}
// To add an eventLink in the QueryPlugIn
BButton getOkButton() {return okButton;}
BButton getCancelButton() {return cancelButton;}
void initVariables() {
runningQuery = false;
cancelQuery = false;
//comments.setText("");
progressBarTitle.setText("");
progressBar.setIndeterminate(false);
progressBar.setValue(0);
progressBar.setProgressText("");
refreshButton.setEnabled(true);
}
void initComboBoxes() {
// INIT layerCB and attributeCB
layerCB.removeAll();
layerCB.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.all-layers"));
layerCB.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.selection"));
layerCB.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.selected-layers"));
List layers = context.getLayerManager().getLayers();
for (int i = 0 ; i < layers.size() ; i++) {
Layer layer = (Layer)layers.get(i);
layerCB.add(layer.getName());
}
this.layers = layers;
this.attributes = authorizedAttributes(layers);
attributeType = 'G';
attributeCB.setContents(attributes);
// INIT functionCB
functionCB.setContents(Function.GEOMETRIC_FUNCTIONS);
function = (Function)functionCB.getSelectedValue();
// INIT operatorCB
operatorCB.setContents(Operator.GEOMETRIC_OP);
operator = (Operator)operatorCB.getSelectedValue();
// INIT valueCB
valueCB.setContents(availableTargets());
valueChanged();
pack();
initVariables();
}
public void layerChanged() {
layers.clear();
attributes.clear();
// index 0 ==> all the layers
if (layerCB.getSelectedIndex() == ALL_LAYERS) {
layers.addAll(context.getLayerManager().getLayers());
}
// index 1 ==> all the selected features
else if (layerCB.getSelectedIndex() == SELECTION) {
layers.addAll(context.getLayerViewPanel()
.getSelectionManager()
.getLayersWithSelectedItems());
}
// index 2 ==> all the selected layers
else if (layerCB.getSelectedIndex() == SELECTED_LAYERS) {
Layer[] ll = context.getLayerNamePanel().getSelectedLayers();
layers.addAll(Arrays.asList(ll));
}
// selected layer
else {
layers.add(context.getLayerManager().getLayer((String)layerCB.getSelectedValue()));
}
attributes.addAll(authorizedAttributes(layers));
attributeCB.setContents(attributes);
attributeChanged();
}
private boolean isAttributeAuthorized(FeatureSchema fs, String attributeName) {
AttributeType type = fs.getAttributeType(attributeName);
if (type==AttributeType.GEOMETRY && geoFilter.getState()) return true;
else if (type==AttributeType.STRING && charFilter.getState()) return true;
else if (type==AttributeType.INTEGER && numFilter.getState()) return true;
else if (type==AttributeType.DOUBLE && numFilter.getState()) return true;
else if (type==AttributeType.DATE && numFilter.getState()) return true;
/* Special MM attributes, to add if mmpatch is added to the core
else if (mmpatch && type==AttributeType.LONG && numFilter.getState()) return true;
else if (mmpatch && type==AttributeType.BOOLEAN && numFilter.getState()) return true;
else if (mmpatch && type instanceof AttributeType.Char && charFilter.getState()) return true;
else if (mmpatch && type instanceof AttributeType.Decimal && numFilter.getState()) return true;
else if (mmpatch && type instanceof AttributeType.Enumeration) return true;
*/
else return false;
}
private Set authorizedAttributes(List layers) {
// set of authorized Attributes
Set set = new TreeSet();
// map of enumerations
enumerations = new HashMap();
// Geometry is processed separetely in order to always have it first
if (geoFilter.getState()) set.add(" (GEOMETRY)");
attribute = "";
for (int i = 0 ; i < layers.size() ; i++) {
Layer layer = (Layer)layers.get(i);
FeatureSchema fs = layer.getFeatureCollectionWrapper().getFeatureSchema();
for (int j = 0 ; j < fs.getAttributeCount() ; j++) {
String att = fs.getAttributeName(j);
AttributeType type = fs.getAttributeType(j);
if (type!=AttributeType.GEOMETRY && isAttributeAuthorized(fs, att) ) {
/* add this test if mmpatch is added to OpenJUMP core
if(mmpatch && type instanceof AttributeType.Enumeration) {
set.add(att + " (ENUM)");
enumerations.put(att, ((AttributeType.Enumeration)type).getEnumerationArray());
}
*/
//else {
set.add(att + " (" + type.toString().split(" ")[0] + ")");
//}
}
}
}
return set;
}
private void charFilterChanged() {
if (charFilter.getState()) caseSensitive.setVisible(true);
else caseSensitive.setVisible(false);
layerChanged();
}
private void numFilterChanged() {
layerChanged();
}
private void geoFilterChanged() {
layerChanged();
}
public void attributeChanged() {
String att = (String)attributeCB.getSelectedValue();
attribute = att.substring(0, att.lastIndexOf(' '));
String attType = att.substring(att.lastIndexOf('(')+1,
att.lastIndexOf(')'));
char newat = 'S';
//if (mmpatch && attType.equals("BOOLEAN")) newat = 'B';
if (attType.equals("INTEGER")) newat = 'N';
else if (attType.equals("DATE")) newat = 'D';
//else if (mmpatch && attType.equals("LONG")) newat = 'N';
else if (attType.equals("DOUBLE")) newat = 'N';
//else if (mmpatch && attType.equals("DECIMAL")) newat = 'N';
else if (attType.equals("STRING")) newat = 'S';
//else if (mmpatch && attType.equals("CHAR")) newat = 'S';
//else if (mmpatch && attType.equals("ENUM")) newat = 'E';
else if (attType.equals("GEOMETRY")) newat = 'G';
else;
// No type change
if (newat==attributeType) {
if (newat=='S') updateValues();
}
else {
attributeType = newat;
updateFunctions();
functionChanged();
updateValues();
}
}
private void updateFunctions() {
switch (attributeType) {
case 'B' :
functionCB.setContents(Function.BOOLEAN_FUNCTIONS);
break;
case 'N' :
functionCB.setContents(Function.NUMERIC_FUNCTIONS);
break;
case 'D' :
functionCB.setContents(Function.DATE_FUNCTIONS);
break;
case 'S' :
functionCB.setContents(Function.STRING_FUNCTIONS);
break;
case 'E' :
functionCB.setContents(Function.STRING_FUNCTIONS);
break;
case 'G' :
functionCB.setContents(Function.GEOMETRIC_FUNCTIONS);
break;
default :
}
}
public void functionChanged() {
// if function is edited to change the parameter value by hand (buffer),
// functionCB.getSelectedValue() class changes from Function to String
String ft = functionCB.getSelectedValue().toString();
try {
if (functionCB.getSelectedValue() instanceof Function) {
Function newfunction = (Function)functionCB.getSelectedValue();
if (newfunction.type!=function.type) {
updateOperators();
operatorChanged();
updateValues();
}
function = (Function)functionCB.getSelectedValue();
if (function == Function.SUBS || function == Function.BUFF) {
functionCB.setEditable(true);
}
else functionCB.setEditable(false);
}
else if (functionCB.getSelectedValue() instanceof String) {
// SET IF FUNCTION IS EDITABLE OR NOT
if(function==Function.SUBS) {
//functionCB.setEditable(true);
String f = functionCB.getSelectedValue().toString();
String sub = f.substring(f.lastIndexOf('(')+1, f.lastIndexOf(')'));
String[] ss = sub.split(",");
Function.SUBS.args = new int[ss.length];
if (ss.length>0) Function.SUBS.args[0] = Integer.parseInt(ss[0]);
if (ss.length>1) Function.SUBS.args[1] = Integer.parseInt(ss[1]);
functionCB.setSelectedValue(Function.SUBS);
}
else if(function==Function.BUFF) {
//functionCB.setEditable(true);
String f = functionCB.getSelectedValue().toString();
String sub = f.substring(f.lastIndexOf('(')+1, f.lastIndexOf(')'));
Function.BUFF.arg = Double.parseDouble(sub);
functionCB.setSelectedValue(Function.BUFF);
}
else {
functionCB.setEditable(false);
context.getWorkbenchFrame().warnUser("Cannot modify this function name");
}
}
} catch(Exception e) {
context.getWorkbenchFrame().toMessage(e);
}
}
private void updateOperators() {
function = (Function)functionCB.getSelectedValue();
switch(function.type) {
case 'S' :
case 'E' :
operatorCB.setContents(Operator.STRING_OP);
break;
case 'B' :
operatorCB.setContents(Operator.BOOLEAN_OP);
break;
case 'N' :
case 'D' :
operatorCB.setContents(Operator.NUMERIC_OP);
break;
case 'G' :
operatorCB.setContents(Operator.GEOMETRIC_OP);
break;
default :
}
}
public void operatorChanged() {
//Operator newop = (Operator)operatorCB.getSelectedValue();
String newopstring = operatorCB.getSelectedValue().toString();
try {
if (operatorCB.getSelectedValue() instanceof Operator) {
Operator newop = (Operator)operatorCB.getSelectedValue();
if(newop.type!=operator.type) {
updateValues();
}
if (operator!=Operator.MATC && operator!=Operator.FIND &&
(newop==Operator.MATC || newop==Operator.FIND)) {
updateValues();
}
if ((operator==Operator.MATC || operator==Operator.FIND) &&
(newop!=Operator.MATC && newop!=Operator.FIND)) {
updateValues();
}
operator = newop;
if (operator == Operator.WDIST) {
operatorCB.setEditable(true);
}
else {
operatorCB.setEditable(false);
}
}
else if (operatorCB.getSelectedValue() instanceof String) {
if (operator==Operator.WDIST) {
//operatorCB.setEditable(true); // added on 2007-07-02 (bug fix)
String f = operatorCB.getSelectedValue().toString();
String sub = f.substring(f.lastIndexOf('(')+1, f.lastIndexOf(')'));
Operator.WDIST.arg = Double.parseDouble(sub);
operatorCB.setSelectedValue(Operator.WDIST);
}
else {
operatorCB.setEditable(false);
context.getWorkbenchFrame().warnUser("Cannot modify this function name");
}
}
}
catch(Exception e) {
context.getWorkbenchFrame().toMessage(e);
}
}
/**
* Update the possible values list (may be editable or not)
*/
private void updateValues() {
if(function.type == 'B') {
valueCB.setContents(new String[]{
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.true"),
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.false")
});
valueCB.setEditable(false);
}
else if (operator.type=='G') {
valueCB.setContents(availableTargets());
valueCB.setEditable(true);
}
else if (attributeType=='E') {
if (operator.type=='S') {
valueCB.setContents((Object[])enumerations.get(attribute));
}
else if (operator.type=='N') {
valueCB.setContents(new Object[]{"0"});
}
valueCB.setEditable(true);
}
else if (attributeType=='D') {
valueCB.setContents(new Object[]{DATE_FORMATTER.format(new Date())});
}
else if (attributeType=='S') {
valueCB.setContents(availableStrings(attribute, 12));
if (operator==Operator.MATC || operator==Operator.FIND) {
valueCB.setContents(new String[]{
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.regular-expression")
});
}
valueCB.setEditable(true);
}
else {
valueCB.setContents(new String[]{""});
valueCB.setEditable(true);
}
}
private void valueChanged() {
value = (String)valueCB.getSelectedValue();
}
private List availableTargets() {
List list = new ArrayList();
list.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.all-layers"));
list.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.selection"));
list.add(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.selected-layers"));
List layers = context.getLayerManager().getLayers();
for (int i = 0 ; i < layers.size() ; i++) {
list.add(((Layer)layers.get(i)).getName());
}
return list;
}
private Set availableStrings(String attribute, int maxsize) {
Set set = new TreeSet();
set.add("");
for (int i = 0 ; i < layers.size() ; i++) {
FeatureCollection fc = ((Layer)layers.get(i)).getFeatureCollectionWrapper();
if (!fc.getFeatureSchema().hasAttribute(attribute)) continue;
Iterator it = fc.iterator();
while (it.hasNext() && set.size()<maxsize) {
Feature f = (Feature)it.next();
Object val = f.getAttribute(attribute);
if (val != null) set.add(val);
}
}
return set;
}
private void open() {
BFileChooser bfc = new BFileChooser(BFileChooser.OPEN_FILE,
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.open"));
Properties prop = new Properties();
if (bfc.showDialog(this)) {
try {
File f = bfc.getSelectedFile();
prop.load(new FileInputStream(f));
}
catch(IOException e){
context.getWorkbenchFrame().warnUser(e.getMessage());
}
}
else {return;}
charFilter.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.string")).booleanValue());
caseSensitive.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.case-sensitive")).booleanValue());
numFilter.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.numeric")).booleanValue());
geoFilter.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.geometric")).booleanValue());
display.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.display-the-table")).booleanValue());
select.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.select-the-result")).booleanValue());
create.setState(new Boolean(prop.getProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.create-a-new-layer")).booleanValue());
initComboBoxes();
int layerIndex = Integer.parseInt(prop.getProperty("layer_index"));
String layerName = prop.getProperty("layer_name");
if (layerIndex<3) layerCB.setSelectedIndex(layerIndex);
else layerCB.setSelectedValue(layerName);
if(!layerName.equals(layerCB.getSelectedValue().toString())) {
context.getWorkbenchFrame().warnUser(layerName + " " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.does-not-exist"));
return;
}
layerChanged();
int attributeIndex = Integer.parseInt(prop.getProperty("attribute_index"));
String attributeName = prop.getProperty("attribute_name");
attributeCB.setSelectedValue(attributeName);
if(!attributeName.equals(attributeCB.getSelectedValue().toString())) {
context.getWorkbenchFrame().warnUser(attributeName + " " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.does-not-exist"));
return;
}
attributeChanged();
int functionIndex = Integer.parseInt(prop.getProperty("function_index"));
String functionName = prop.getProperty("function_name");
functionCB.setSelectedIndex(functionIndex%functionCB.getItemCount());
if(!functionName.equals(functionCB.getSelectedValue().toString())) {
if (functionCB.getItem(functionIndex)==Function.SUBS) {
functionCB.setEditable(true);
functionCB.setSelectedValue(functionName);
}
else if (functionCB.getItem(functionIndex)==Function.BUFF) {
functionCB.setEditable(true);
functionCB.setSelectedValue(functionName);
}
else {
context.getWorkbenchFrame().warnUser(functionName + " " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.does-not-exist"));
return;
}
}
functionChanged();
int operatorIndex = Integer.parseInt(prop.getProperty("operator_index"));
String operatorName = prop.getProperty("operator_name");
operatorCB.setSelectedIndex(operatorIndex%operatorCB.getItemCount());
if(!operatorName.equals(operatorCB.getSelectedValue().toString())) {
if (operatorCB.getItem(operatorIndex)==Operator.WDIST) {
operatorCB.setEditable(true);
operatorCB.setSelectedValue(operatorName);
}
else {
context.getWorkbenchFrame().warnUser(operatorName + " " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.does-not-exist"));
return;
}
}
operatorChanged();
String value = prop.getProperty("value");
valueCB.setSelectedValue(value);
}
private void saveas() {
Properties prop = new Properties();
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.string", ""+charFilter.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.case-sensitive", ""+caseSensitive.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.numeric", ""+numFilter.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.geometric", ""+geoFilter.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.display-the-table", ""+display.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.select-the-result", ""+select.getState());
prop.setProperty("org.openjump.core.ui.plugin.queries.SimpleQuery.create-a-new-layer", ""+create.getState());
prop.setProperty("layer_index", ""+layerCB.getSelectedIndex());
prop.setProperty("layer_name", ""+layerCB.getSelectedValue());
prop.setProperty("attribute_index", ""+attributeCB.getSelectedIndex());
prop.setProperty("attribute_name", ""+attributeCB.getSelectedValue());
prop.setProperty("function_index", ""+functionCB.getSelectedIndex());
prop.setProperty("function_name", ""+functionCB.getSelectedValue());
prop.setProperty("operator_index", ""+operatorCB.getSelectedIndex());
prop.setProperty("operator_name", ""+operatorCB.getSelectedValue());
prop.setProperty("value", ""+valueCB.getSelectedValue());
BFileChooser bfc = new BFileChooser(BFileChooser.SAVE_FILE,
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.save-as"));
if (bfc.showDialog(this)) {
try {
File f = bfc.getSelectedFile();
prop.store(new FileOutputStream(f), "Query file for Sqi4jump");
}
catch(FileNotFoundException e) {
context.getWorkbenchFrame().warnUser(e.getMessage());
}
catch(IOException e) {
context.getWorkbenchFrame().warnUser(e.getMessage());
}
}
}
void executeQuery() {
final QueryDialog queryDialog = this;
Runnable runnable = new Runnable() {
public void run() {
// runningQuery is set to true while the query is running
runningQuery=true;
cancelQuery=false;
refreshButton.setEnabled(false);
// New condition
Condition condition = new Condition(queryDialog, context);
comments.setText("<html>" +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.select-from") +
" \"" + layerCB.getSelectedValue() + "\" " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.features-where") + " " +
condition + "...</html>"
);
// The FeatureSelection before the query
FeatureSelection selectedFeatures = context.getLayerViewPanel()
.getSelectionManager()
.getFeatureSelection();
// srcFeaturesMap keys are layers to query
// srcFeaturesMap values are collection of features to query
CollectionMap srcFeaturesMap = new CollectionMap();
int total = 0; // total number of objects to scan
int featuresfound = 0;
if (layerCB.getSelectedIndex() == SELECTION) {
for (Iterator it = selectedFeatures.getLayersWithSelectedItems().iterator() ; it.hasNext() ; ) {
Layer layer = (Layer)it.next();
srcFeaturesMap.put(layer, selectedFeatures.getFeaturesWithSelectedItems(layer));
}
total = srcFeaturesMap.size();
}
else {
for (int i = 0 ; i < layers.size() ; i++) {
total += ((Layer)layers.get(i)).getFeatureCollectionWrapper().size();
}
}
// Set the selection used as target for geometric operations
// Bug fixed on 2007-08-10 : selection has index 1 (SELECTION), not 0
if (operator.type=='G' && valueCB.getSelectedIndex() == SELECTION) {
selection = context.getLayerViewPanel().getSelectionManager().getSelectedItems();
}
// initialize the selection if the select option is true
if(select.getState()) {selectedFeatures.unselectItems();}
// initialization for infoframe
InfoFrame info = null;
if(display.getState()) {
info = new InfoFrame(context.getWorkbenchContext(),
(LayerManagerProxy)context,
(TaskFrame)context.getWorkbenchFrame().getActiveInternalFrame());
}
// Loop on the requested layers
int count = 0;
for (int i = 0 ; i < layers.size() ; i++) {
Layer layer = (Layer)layers.get(i);
FeatureCollection fc = layer.getFeatureCollectionWrapper();
// When the user choose all layers, some attributes are not
// available for all attributes
if(attributeType!='G' && !fc.getFeatureSchema().hasAttribute(attribute)) continue;
//monitor.report(layer.getName());
Collection features = null;
// case 1 : query only selected features
if (layerCB.getSelectedIndex()==1) {
features = (Collection)srcFeaturesMap.get(layer);
}
// other cases : query the whole layer
else {
features = fc.getFeatures();
}
// initialize a new dataset
progressBarTitle.setText(layer.getName());
progressBarTitle.getParent().layoutChildren();
progressBar.setMinimum(0);
progressBar.setMaximum(total);
progressBar.setValue(0);
progressBar.setProgressText("0/"+total);
progressBar.setShowProgressText(true);
FeatureCollection dataset = new FeatureDataset(fc.getFeatureSchema());
// initialize a new list for the new selection
List okFeatures = new ArrayList();
int mod = 1;
if (total > 1000) mod = 10;
if (total > 33000) mod = 100;
if (total > 1000000) mod = 1000;
try {
for (Iterator it = features.iterator() ; it.hasNext() ; ) {
count++;
if (count%mod==0) {
progressBar.setProgressText(""+count+"/"+total);
progressBar.setValue(count);
}
Feature f = (BasicFeature)it.next();
if (condition.test(f)) {
okFeatures.add(f);
featuresfound++;
}
Thread.yield();
if (cancelQuery) break;
}
progressBar.setProgressText(""+count+"/"+total);
progressBar.setValue(count);
}
catch(Exception e) {e.printStackTrace();}
if (cancelQuery) break;
if (okFeatures.size()==0) continue;
//
if(select.getState()) {
selectedFeatures.selectItems(layer, okFeatures);
}
if(create.getState() || display.getState()) {
dataset.addAll(okFeatures);
}
if(create.getState()) {
context.getLayerManager().addLayer(
//context.getLayerManager().getCategory(layer).getName(),
StandardCategoryNames.RESULT, // modified on 2007-08-22
layer.getName()+"_"+value, dataset
);
}
if(display.getState()) {
info.getModel().add(layer, okFeatures);
//context.getWorkbenchFrame().addInternalFrame(info);
}
}
if (cancelQuery) {
initVariables();
comments.setText(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.query-interrupted"));
return;
}
progressBarTitle.setText(I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.result-display"));
progressBar.setIndeterminate(true);
comments.setText("<html>" +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.select-from") +
" \"" + layerCB.getSelectedValue() + "\" " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.features-where") + " " +
condition + " : " + featuresfound + " " +
I18N.get("org.openjump.core.ui.plugin.queries.SimpleQuery.features-found") + "</html>"
);
// update the selection attribute
if(select.getState()) {
selection = context.getLayerViewPanel().getSelectionManager().getSelectedItems();
}
if(display.getState()) {
context.getWorkbenchFrame().addInternalFrame(info);
}
// init ComboBoxes to add new layers
if (create.getState()) { initComboBoxes(); }
progressBar.setIndeterminate(false);
progressBar.setValue(progressBar.getMaximum());
//comments.setText("Select from " + layerCB.getSelectedValue() + " where " + condition + " : " + total + " features found");
initVariables();
}
};
Thread t = new Thread(runnable);
// Set a low priority to the thread to keep a responsive interface
// (progresBar progression and interruption command)
t.setPriority(Thread.currentThread().getPriority()-1);
// start the thread
t.start();
}
private void ok() {executeQuery();}
//private void cancel() {setVisible(false);}
private void stop() {if (runningQuery) cancelQuery = true;}
private void refresh() {initComboBoxes();}
private void exit() {
if (runningQuery) cancelQuery = true;
setVisible(false);
}
}