Statistics
| Revision:

root / trunk / extensions / extExpressionField / src / com / iver / cit / gvsig / project / documents / table / gui / EvalExpression.java @ 36458

History | View | Annotate | Download (13.5 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.ProjectExtension;
25
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
26
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileWriteException;
27
import com.iver.cit.gvsig.exceptions.validate.ValidateRowException;
28
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException;
29
import com.iver.cit.gvsig.fmap.core.IRow;
30
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
31
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
32
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
33
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
34
import com.iver.cit.gvsig.fmap.edition.EditableAdapter;
35
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
36
import com.iver.cit.gvsig.fmap.edition.IEditableSource;
37
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
38
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
39
import com.iver.cit.gvsig.fmap.edition.IWriteable;
40
import com.iver.cit.gvsig.fmap.edition.IWriter;
41
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
42
import com.iver.cit.gvsig.fmap.layers.FBitSet;
43
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
44
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
45
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
46
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
47
import com.iver.cit.gvsig.project.ProjectFactory;
48
import com.iver.cit.gvsig.project.documents.table.IOperator;
49
import com.iver.cit.gvsig.project.documents.table.Index;
50
import com.iver.cit.gvsig.project.documents.table.ProjectTable;
51
import com.iver.cit.gvsig.project.documents.table.ProjectTableFactory;
52

    
53
/**
54
 * This class implements the logic of a expression and fill a field of the table
55
 * 
56
 * @author Vicente Caballero Navarro
57
 */
58
public class EvalExpression {
59
        private FieldDescription[] fieldDescriptors;
60
        private FieldDescription fieldDescriptor;
61
    private FLyrVect layer;
62
        private  IEditableSource ies =null;
63
        private static Preferences prefs = Preferences.userRoot().node( "fieldExpressionOptions" );
64
        private int limit;
65
        private SelectableDataSource sds;
66
        private BSFManager interpreter;
67
        private Index indexRow;
68
    private int selectedIndex;
69
    private Table table;
70
    private ArrayList<IOperator> operators = new ArrayList<IOperator>();
71

    
72
        /**
73
         * @deprecated
74
         */
75
        public EvalExpression() {
76
        limit=prefs.getInt("limit_rows_in_memory",-1);
77
    }
78

    
79

    
80
    public EvalExpression(BSFManager interpreter, ArrayList<IOperator> operators) {
81
                limit=prefs.getInt("limit_rows_in_memory",-1);
82
                //fpuga: I think interpreter should be instantiated here and not passed
83
                this.interpreter = interpreter;  
84
        this.operators = operators;
85
        }
86
        
87
        public void setLayer(FLyrVect layer, int selectedIndex) {
88
        this.layer = layer;
89
        ies = (VectorialEditableAdapter) layer.getSource();
90
                this.selectedIndex = selectedIndex;
91
                init();
92
                
93
        }
94
        
95
    public void setTable(Table table) {
96
        // TODO: table is only needed to make table.refresh on the dialog.
97
        // Probably a fireevent can be done to avoid this
98
        this.table = table;
99
        layer = (FLyrVect) table.getModel().getAssociatedTable();
100
        if (layer == null)
101
                        ies=table.getModel().getModelo();
102
                else
103
            ies = (VectorialEditableAdapter) layer.getSource();
104
                BitSet columnSelected = table.getSelectedFieldIndices();
105
                selectedIndex = columnSelected.nextSetBit(0);
106
                init();
107
    }
108
        
109
        private void init() {
110
                try {
111
                        sds = ies.getRecordset();
112
                        fieldDescriptors = sds.getFieldsDescription();
113
                        fieldDescriptor = fieldDescriptors[selectedIndex];
114
                        interpreter.declareBean("sds", sds,SelectableDataSource.class);
115
                        indexRow=new Index();
116
                        interpreter.declareBean("indexRow", indexRow,Index.class);
117
                } catch (BSFException e) {
118
                        e.printStackTrace();
119
                } catch (ReadDriverException e) {
120
                        e.printStackTrace();
121
                }
122
        }
123
         public void setValue(Object obj,int i) {
124
                    //VectorialEditableAdapter vea = (VectorialEditableAdapter) lv.getSource();
125
                     Value value = getValue(obj);
126
                     IRow feat=null;
127
                        try {
128
                                feat = ies.getRow(i).getLinkedRow().cloneRow();
129
                        } catch (ExpansionFileReadException e) {
130
                                NotificationManager.addError(e);
131
                        } catch (ReadDriverException e) {
132
                                NotificationManager.addError(e);
133
                        }
134
                     Value[] values = feat.getAttributes();
135
                     values[selectedIndex] = value;
136
                     feat.setAttributes(values);
137

    
138
                     IRowEdited edRow = new DefaultRowEdited(feat,
139
                                     IRowEdited.STATUS_MODIFIED, i);
140
                     try {
141
                                ies.modifyRow(edRow.getIndex(), edRow.getLinkedRow(), "",
142
                                                 EditionEvent.ALPHANUMERIC);
143
                        } catch (ExpansionFileWriteException e) {
144
                                NotificationManager.addError(e);
145
                        } catch (ExpansionFileReadException e) {
146
                                NotificationManager.addError(e);
147
                        } catch (ValidateRowException e) {
148
                                NotificationManager.addError(e);
149
                        } catch (ReadDriverException e) {
150
                                NotificationManager.addError(e);
151
                        }
152

    
153
            }
154

    
155
         public void isCorrectValue(Object obj) throws BSFException {
156
                if (obj instanceof Number || obj instanceof Date || obj instanceof Boolean || obj instanceof String) {
157

    
158
                }else{
159
                        throw new BSFException("incorrect");
160
                }
161
         }
162

    
163

    
164
         /**
165
             * Returns the value created from object.
166
             *
167
             * @param obj value.
168
             *
169
             * @return Value.
170
             */
171
            private Value getValue(Object obj) {
172
                int typeField = fieldDescriptor.getFieldType();
173
                Value value = null;//ValueFactory.createNullValue();
174

    
175
                if (obj instanceof Number) {
176
                    if (typeField == Types.DOUBLE || typeField == Types.NUMERIC) {
177
                        double dv = ((Number) obj).doubleValue();
178
                        value = ValueFactory.createValue(dv);
179
                    } else if (typeField == Types.FLOAT) {
180
                        float df = ((Number) obj).floatValue();
181
                        value = ValueFactory.createValue(df);
182
                    } else if (typeField == Types.INTEGER) {
183
                        int di = ((Number) obj).intValue();
184
                        value = ValueFactory.createValue(di);
185
                    } else if (typeField == Types.BIGINT) {
186
                        long di = ((Number) obj).longValue();
187
                        value = ValueFactory.createValue(di);
188
                    } else if (typeField == Types.VARCHAR) {
189
                        String s = ((Number) obj).toString();
190
                        value = ValueFactory.createValue(s);
191
                    } else if (typeField == Types.BOOLEAN) {
192
                        if (((Number) obj).intValue()==0){
193
                                value=ValueFactory.createValue(false);
194
                        }else{
195
                                value=ValueFactory.createValue(true);
196
                        }
197
                    }
198
                } else if (obj instanceof Date) {
199
                    if (typeField == Types.DATE) {
200
                        Date date = (Date) obj;
201
                        value = ValueFactory.createValue(date);
202
                    } else if (typeField == Types.VARCHAR) {
203
                        String s = ((Date) obj).toString();
204
                        value = ValueFactory.createValue(s);
205
                    }
206
                } else if (obj instanceof Boolean) {
207
                    if (typeField == Types.BOOLEAN) {
208
                        boolean b = ((Boolean) obj).booleanValue();
209
                        value = ValueFactory.createValue(b);
210
                    } else if (typeField == Types.VARCHAR) {
211
                        String s = ((Boolean) obj).toString();
212
                        value = ValueFactory.createValue(s);
213
                    }
214
                } else if (obj instanceof String) {
215
                    if (typeField == Types.VARCHAR) {
216
                        String s = obj.toString();
217
                        value = ValueFactory.createValue(s);
218
                    }
219
                }else{
220
                        value=ValueFactory.createNullValue();
221
                }
222

    
223
                return value;
224
            }
225
        public FieldDescription getFieldDescriptorSelected() {
226
                return fieldDescriptor;
227
        }
228
        public FieldDescription[] getFieldDescriptors() {
229
                return fieldDescriptors;
230
        }
231
//        public void setFieldValue(Object obj,int i) {
232
//            try {
233
//                        ((DBFDriver)table.getModel().getModelo().getOriginalDriver()).setFieldValue(i,selectedIndex,obj);
234
//                } catch (DriverLoadException e) {
235
//                        e.printStackTrace();
236
//                } catch (IOException e) {
237
//                        e.printStackTrace();
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
}