root / trunk / extensions / extExpressionField / src / com / iver / cit / gvsig / project / documents / table / gui / EvalExpression.java @ 36459
History | View | Annotate | Download (13.4 KB)
1 |
package com.iver.cit.gvsig.project.documents.table.gui; |
---|---|
2 |
|
3 |
import java.awt.Component; |
4 |
import java.io.UnsupportedEncodingException; |
5 |
import java.sql.Types; |
6 |
import java.util.ArrayList; |
7 |
import java.util.BitSet; |
8 |
import java.util.Date; |
9 |
import java.util.prefs.Preferences; |
10 |
|
11 |
import javax.swing.JOptionPane; |
12 |
|
13 |
import org.apache.bsf.BSFException; |
14 |
import org.apache.bsf.BSFManager; |
15 |
|
16 |
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException; |
17 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
18 |
import com.hardcode.gdbms.engine.values.Value; |
19 |
import com.hardcode.gdbms.engine.values.ValueFactory; |
20 |
import com.iver.andami.PluginServices; |
21 |
import com.iver.andami.messages.NotificationManager; |
22 |
import com.iver.cit.gvsig.EditionUtilities; |
23 |
import com.iver.cit.gvsig.ExpressionFieldExtension; |
24 |
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
25 |
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileWriteException; |
26 |
import com.iver.cit.gvsig.exceptions.validate.ValidateRowException; |
27 |
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException; |
28 |
import com.iver.cit.gvsig.fmap.core.IRow; |
29 |
import com.iver.cit.gvsig.fmap.drivers.FieldDescription; |
30 |
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition; |
31 |
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition; |
32 |
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited; |
33 |
import com.iver.cit.gvsig.fmap.edition.EditionEvent; |
34 |
import com.iver.cit.gvsig.fmap.edition.IEditableSource; |
35 |
import com.iver.cit.gvsig.fmap.edition.IRowEdited; |
36 |
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter; |
37 |
import com.iver.cit.gvsig.fmap.edition.IWriteable; |
38 |
import com.iver.cit.gvsig.fmap.edition.IWriter; |
39 |
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter; |
40 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
41 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
42 |
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource; |
43 |
import com.iver.cit.gvsig.project.documents.table.IOperator; |
44 |
import com.iver.cit.gvsig.project.documents.table.Index; |
45 |
|
46 |
/**
|
47 |
* This class implements the logic of a expression and fill a field of the table
|
48 |
*
|
49 |
* To use this class to evaluate and execute an expression something like this
|
50 |
* can be done:
|
51 |
*
|
52 |
* ExpressionFieldExtension efe = (ExpressionFieldExtension)
|
53 |
* PluginServices.getExtension(ExpressionFieldExtension.class);
|
54 |
*
|
55 |
* EvalExpression ee = new EvalExpression(efe.getInterpreter(), efe.getOperators());
|
56 |
* ToggleEditing te = new ToggleEditing();
|
57 |
* // put the layer in edition mode
|
58 |
* te.startEditing(layer);
|
59 |
* ee.setLayer(layer, 7);
|
60 |
* ee.evalExpression("toUpperCase([NOME_MAPA])");
|
61 |
* // close edition mode and save the layer
|
62 |
* te.stopEditing(layer, false);
|
63 |
*
|
64 |
* @author Vicente Caballero Navarro
|
65 |
*/
|
66 |
public class EvalExpression { |
67 |
private FieldDescription[] fieldDescriptors; |
68 |
private FieldDescription fieldDescriptor;
|
69 |
private FLyrVect layer;
|
70 |
private IEditableSource ies =null; |
71 |
private static Preferences prefs = Preferences.userRoot().node( "fieldExpressionOptions" ); |
72 |
private int limit; |
73 |
private SelectableDataSource sds;
|
74 |
private BSFManager interpreter;
|
75 |
private Index indexRow;
|
76 |
private int selectedIndex; |
77 |
private Table table;
|
78 |
private ArrayList<IOperator> operators = new ArrayList<IOperator>(); |
79 |
|
80 |
/**
|
81 |
* @deprecated
|
82 |
*/
|
83 |
public EvalExpression() {
|
84 |
limit=prefs.getInt("limit_rows_in_memory",-1); |
85 |
} |
86 |
|
87 |
|
88 |
public EvalExpression(BSFManager interpreter, ArrayList<IOperator> operators) { |
89 |
limit=prefs.getInt("limit_rows_in_memory",-1); |
90 |
this.interpreter = interpreter;
|
91 |
this.operators = operators;
|
92 |
} |
93 |
|
94 |
/**
|
95 |
*
|
96 |
* @param layer
|
97 |
* Must be in edition or a ClassCastException will be thrown
|
98 |
* @param selectedIndex
|
99 |
* The index of the field in the FieldDescription which will be
|
100 |
* filled by the expression
|
101 |
*/
|
102 |
public void setLayer(FLyrVect layer, int selectedIndex) { |
103 |
this.layer = layer;
|
104 |
ies = (VectorialEditableAdapter) layer.getSource(); |
105 |
this.selectedIndex = selectedIndex;
|
106 |
init(); |
107 |
|
108 |
} |
109 |
|
110 |
public void setTable(Table table) { |
111 |
// TODO: table is only needed to make table.refresh on the dialog.
|
112 |
// Probably a fireevent can be done to avoid this
|
113 |
this.table = table;
|
114 |
layer = (FLyrVect) table.getModel().getAssociatedTable(); |
115 |
if (layer == null) |
116 |
ies=table.getModel().getModelo(); |
117 |
else
|
118 |
ies = (VectorialEditableAdapter) layer.getSource(); |
119 |
BitSet columnSelected = table.getSelectedFieldIndices();
|
120 |
selectedIndex = columnSelected.nextSetBit(0);
|
121 |
init(); |
122 |
} |
123 |
|
124 |
private void init() { |
125 |
try {
|
126 |
sds = ies.getRecordset(); |
127 |
fieldDescriptors = sds.getFieldsDescription(); |
128 |
fieldDescriptor = fieldDescriptors[selectedIndex]; |
129 |
interpreter.declareBean("sds", sds,SelectableDataSource.class);
|
130 |
indexRow=new Index();
|
131 |
interpreter.declareBean("indexRow", indexRow,Index.class);
|
132 |
} catch (BSFException e) {
|
133 |
e.printStackTrace(); |
134 |
} catch (ReadDriverException e) {
|
135 |
e.printStackTrace(); |
136 |
} |
137 |
} |
138 |
public void setValue(Object obj,int i) { |
139 |
//VectorialEditableAdapter vea = (VectorialEditableAdapter) lv.getSource();
|
140 |
Value value = getValue(obj); |
141 |
IRow feat=null;
|
142 |
try {
|
143 |
feat = ies.getRow(i).getLinkedRow().cloneRow(); |
144 |
} catch (ExpansionFileReadException e) {
|
145 |
NotificationManager.addError(e); |
146 |
} catch (ReadDriverException e) {
|
147 |
NotificationManager.addError(e); |
148 |
} |
149 |
Value[] values = feat.getAttributes();
|
150 |
values[selectedIndex] = value; |
151 |
feat.setAttributes(values); |
152 |
|
153 |
IRowEdited edRow = new DefaultRowEdited(feat,
|
154 |
IRowEdited.STATUS_MODIFIED, i); |
155 |
try {
|
156 |
ies.modifyRow(edRow.getIndex(), edRow.getLinkedRow(), "",
|
157 |
EditionEvent.ALPHANUMERIC); |
158 |
} catch (ExpansionFileWriteException e) {
|
159 |
NotificationManager.addError(e); |
160 |
} catch (ExpansionFileReadException e) {
|
161 |
NotificationManager.addError(e); |
162 |
} catch (ValidateRowException e) {
|
163 |
NotificationManager.addError(e); |
164 |
} catch (ReadDriverException e) {
|
165 |
NotificationManager.addError(e); |
166 |
} |
167 |
|
168 |
} |
169 |
|
170 |
public void isCorrectValue(Object obj) throws BSFException { |
171 |
if (obj instanceof Number || obj instanceof Date || obj instanceof Boolean || obj instanceof String) { |
172 |
|
173 |
}else{
|
174 |
throw new BSFException("incorrect"); |
175 |
} |
176 |
} |
177 |
|
178 |
|
179 |
private Value getValue(Object obj) { |
180 |
int typeField = fieldDescriptor.getFieldType();
|
181 |
Value value = null;//ValueFactory.createNullValue(); |
182 |
|
183 |
if (obj instanceof Number) { |
184 |
if (typeField == Types.DOUBLE || typeField == Types.NUMERIC) { |
185 |
double dv = ((Number) obj).doubleValue(); |
186 |
value = ValueFactory.createValue(dv); |
187 |
} else if (typeField == Types.FLOAT) { |
188 |
float df = ((Number) obj).floatValue(); |
189 |
value = ValueFactory.createValue(df); |
190 |
} else if (typeField == Types.INTEGER) { |
191 |
int di = ((Number) obj).intValue(); |
192 |
value = ValueFactory.createValue(di); |
193 |
} else if (typeField == Types.BIGINT) { |
194 |
long di = ((Number) obj).longValue(); |
195 |
value = ValueFactory.createValue(di); |
196 |
} else if (typeField == Types.VARCHAR) { |
197 |
String s = ((Number) obj).toString(); |
198 |
value = ValueFactory.createValue(s); |
199 |
} else if (typeField == Types.BOOLEAN) { |
200 |
if (((Number) obj).intValue()==0){ |
201 |
value=ValueFactory.createValue(false);
|
202 |
}else{
|
203 |
value=ValueFactory.createValue(true);
|
204 |
} |
205 |
} |
206 |
} else if (obj instanceof Date) { |
207 |
if (typeField == Types.DATE) { |
208 |
Date date = (Date) obj; |
209 |
value = ValueFactory.createValue(date); |
210 |
} else if (typeField == Types.VARCHAR) { |
211 |
String s = ((Date) obj).toString(); |
212 |
value = ValueFactory.createValue(s); |
213 |
} |
214 |
} else if (obj instanceof Boolean) { |
215 |
if (typeField == Types.BOOLEAN) { |
216 |
boolean b = ((Boolean) obj).booleanValue(); |
217 |
value = ValueFactory.createValue(b); |
218 |
} else if (typeField == Types.VARCHAR) { |
219 |
String s = ((Boolean) obj).toString(); |
220 |
value = ValueFactory.createValue(s); |
221 |
} |
222 |
} else if (obj instanceof String) { |
223 |
if (typeField == Types.VARCHAR) { |
224 |
String s = obj.toString();
|
225 |
value = ValueFactory.createValue(s); |
226 |
} |
227 |
}else{
|
228 |
value=ValueFactory.createNullValue(); |
229 |
} |
230 |
|
231 |
return value;
|
232 |
} |
233 |
public FieldDescription getFieldDescriptorSelected() {
|
234 |
return fieldDescriptor;
|
235 |
} |
236 |
public FieldDescription[] getFieldDescriptors() { |
237 |
return fieldDescriptors;
|
238 |
} |
239 |
|
240 |
public void saveEdits(int numRows) throws ReadDriverException, InitializeWriterException, StopWriterVisitorException { |
241 |
if (limit==-1 || numRows == 0 || (numRows % limit)!=0) { |
242 |
return;
|
243 |
} |
244 |
ies.endComplexRow(PluginServices.getText(this, "expression")); |
245 |
if ((layer != null) |
246 |
&& layer.getSource() instanceof VectorialEditableAdapter) {
|
247 |
VectorialEditableAdapter vea = (VectorialEditableAdapter) layer |
248 |
.getSource(); |
249 |
ISpatialWriter spatialWriter = (ISpatialWriter) vea.getDriver(); |
250 |
vea.cleanSelectableDatasource(); |
251 |
// We want that the recordset of the layer shows the changes of the fields
|
252 |
layer.setRecordset(vea.getRecordset()); |
253 |
ILayerDefinition lyrDef = EditionUtilities |
254 |
.createLayerDefinition(layer); |
255 |
spatialWriter.initialize(lyrDef); |
256 |
vea.saveEdits(spatialWriter,EditionEvent.ALPHANUMERIC); |
257 |
vea.getCommandRecord().clearAll(); |
258 |
} else {
|
259 |
if (ies instanceof IWriteable){ |
260 |
IWriteable w = (IWriteable) ies; |
261 |
IWriter writer = w.getWriter(); |
262 |
if (writer == null){ |
263 |
}else{
|
264 |
ITableDefinition tableDef = ies.getTableDefinition(); |
265 |
writer.initialize(tableDef); |
266 |
|
267 |
ies.saveEdits(writer,EditionEvent.ALPHANUMERIC); |
268 |
ies.getSelection().clear(); |
269 |
} |
270 |
} |
271 |
ies.getCommandRecord().clearAll(); |
272 |
} |
273 |
ies.startComplexRow(); |
274 |
} |
275 |
|
276 |
|
277 |
|
278 |
/**
|
279 |
* Evaluate the expression.
|
280 |
* @throws ReadDriverException
|
281 |
* @throws BSFException
|
282 |
*/
|
283 |
public boolean evalExpression(String expression) throws ReadDriverException, BSFException{ |
284 |
long rowCount = sds.getRowCount();
|
285 |
byte[] expressionBytes; |
286 |
String encoding = System.getProperty("file.encoding"); |
287 |
try {
|
288 |
expressionBytes = expression.getBytes(encoding); |
289 |
expression = new String(expressionBytes, "ISO-8859-1"); |
290 |
} catch (UnsupportedEncodingException e) { |
291 |
e.printStackTrace(); |
292 |
} |
293 |
expression=expression.replaceAll("\\[","field(\"").replaceAll("\\]","\")"); |
294 |
|
295 |
interpreter.declareBean("ee",this,EvalExpression.class); |
296 |
interpreter.exec(ExpressionFieldExtension.JYTHON,null,-1,-1,"def expression():\n" + |
297 |
" return " +expression+ ""); |
298 |
if (rowCount > 0) { |
299 |
try {
|
300 |
interpreter.exec(ExpressionFieldExtension.JYTHON,null,-1,-1,"def isCorrect():\n" + |
301 |
" ee.isCorrectValue(expression())\n");
|
302 |
interpreter.exec(ExpressionFieldExtension.JYTHON,null,-1,-1,"isCorrect()"); |
303 |
} catch (BSFException ee) {
|
304 |
String message=ee.getMessage();
|
305 |
if (message.length()>200){ |
306 |
message=message.substring(0,200); |
307 |
} |
308 |
int option=JOptionPane.showConfirmDialog((Component) PluginServices.getMainFrame(), |
309 |
PluginServices.getText(this,
|
310 |
"error_expression")+"\n"+message+"\n"+PluginServices.getText(this,"continue?")); |
311 |
if (option!=JOptionPane.OK_OPTION) { |
312 |
return false; |
313 |
} |
314 |
} |
315 |
} |
316 |
ies.startComplexRow(); |
317 |
|
318 |
ArrayList exceptions=new ArrayList(); |
319 |
interpreter.declareBean("exceptions",exceptions,ArrayList.class); |
320 |
FBitSet selection=sds.getSelection(); |
321 |
if (selection.cardinality() > 0) { |
322 |
interpreter.declareBean("selection", selection, FBitSet.class);
|
323 |
interpreter.exec(ExpressionFieldExtension.JYTHON,null,-1,-1,"def p():\n" + |
324 |
" i=selection.nextSetBit(0)\n" +
|
325 |
" while i >=0:\n" +
|
326 |
" indexRow.set(i)\n" +
|
327 |
" obj=expression()\n" +
|
328 |
" ee.setValue(obj,i)\n" +
|
329 |
" ee.saveEdits(i)\n" +
|
330 |
" i=selection.nextSetBit(i+1)\n");
|
331 |
} else {
|
332 |
interpreter.exec(ExpressionFieldExtension.JYTHON,null,-1,-1,"def p():\n" + |
333 |
" for i in xrange("+rowCount +"):\n" + |
334 |
" indexRow.set(i)\n" +
|
335 |
// " print i , expression() , repr (expression())\n" +
|
336 |
" ee.setValue(expression(),i)\n" +
|
337 |
" ee.saveEdits(i)\n");
|
338 |
} |
339 |
try {
|
340 |
interpreter.eval(ExpressionFieldExtension.JYTHON,null,-1,-1,"p()"); |
341 |
} catch (BSFException ee) {
|
342 |
|
343 |
JOptionPane.showMessageDialog((Component) PluginServices.getMainFrame(), |
344 |
PluginServices.getText(this, "evaluate_expression_with_errors")+" "+(rowCount-indexRow.get())+"\n"+ee.getMessage()); |
345 |
} |
346 |
|
347 |
ies.endComplexRow(PluginServices.getText(this, "expression")); |
348 |
|
349 |
return true; |
350 |
} |
351 |
|
352 |
public Table getTable() {
|
353 |
return this.table; |
354 |
} |
355 |
|
356 |
public ArrayList<IOperator> getOperators() { |
357 |
return this.operators; |
358 |
} |
359 |
|
360 |
public FLyrVect getLayer() {
|
361 |
return this.layer; |
362 |
} |
363 |
|
364 |
public BSFManager getInterpreter() {
|
365 |
return this.interpreter; |
366 |
} |
367 |
} |