Statistics
| Revision:

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
}