Revision 44098 trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.swing/org.gvsig.expressionevaluator.swing.impl/src/main/java/org/gvsig/expressionevaluator/swing/impl/DefaultJExpressionBuilder.java
DefaultJExpressionBuilder.java | ||
---|---|---|
1 | 1 |
package org.gvsig.expressionevaluator.swing.impl; |
2 | 2 |
|
3 | 3 |
import java.awt.BorderLayout; |
4 |
import java.awt.Color; |
|
4 | 5 |
import java.awt.Dimension; |
5 | 6 |
import java.awt.event.ActionEvent; |
6 | 7 |
import java.awt.event.ActionListener; |
... | ... | |
11 | 12 |
import java.net.URL; |
12 | 13 |
import java.util.ArrayList; |
13 | 14 |
import java.util.Collection; |
14 |
import java.util.Date; |
|
15 | 15 |
import java.util.HashSet; |
16 | 16 |
import java.util.List; |
17 | 17 |
import java.util.Objects; |
... | ... | |
25 | 25 |
import javax.swing.JScrollPane; |
26 | 26 |
import javax.swing.JTree; |
27 | 27 |
import javax.swing.SwingUtilities; |
28 |
import javax.swing.Timer; |
|
29 |
import javax.swing.event.CaretEvent; |
|
30 |
import javax.swing.event.CaretListener; |
|
31 |
import javax.swing.event.DocumentEvent; |
|
32 |
import javax.swing.event.DocumentListener; |
|
28 | 33 |
import javax.swing.event.ListSelectionEvent; |
29 | 34 |
import javax.swing.event.ListSelectionListener; |
30 | 35 |
import javax.swing.event.TreeModelEvent; |
... | ... | |
36 | 41 |
import javax.swing.tree.TreePath; |
37 | 42 |
import org.apache.commons.io.FilenameUtils; |
38 | 43 |
import org.apache.commons.lang3.StringUtils; |
39 |
import org.apache.commons.lang.StringEscapeUtils; |
|
40 | 44 |
import org.gvsig.expressionevaluator.Expression; |
41 |
import org.gvsig.expressionevaluator.ExpressionBuilder; |
|
42 | 45 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
46 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
|
47 |
import org.gvsig.expressionevaluator.ExpressionRuntimeException; |
|
48 |
import org.gvsig.expressionevaluator.ExpressionSyntaxException; |
|
43 | 49 |
import org.gvsig.expressionevaluator.Function; |
50 |
import org.gvsig.expressionevaluator.MutableSymbolTable; |
|
44 | 51 |
import org.gvsig.expressionevaluator.SymbolTable; |
45 | 52 |
import org.gvsig.expressionevaluator.swing.Element; |
46 | 53 |
import org.gvsig.expressionevaluator.swing.Element.CalculatedElement; |
... | ... | |
49 | 56 |
import org.gvsig.expressionevaluator.swing.Element.GroupElement; |
50 | 57 |
import org.gvsig.expressionevaluator.swing.Element.SimpleElement; |
51 | 58 |
import org.gvsig.expressionevaluator.swing.Element.VariableElement; |
52 |
import org.gvsig.expressionevaluator.swing.ElementFactory; |
|
53 | 59 |
import org.gvsig.expressionevaluator.swing.ExpressionBuilderConfig; |
54 | 60 |
import org.gvsig.expressionevaluator.swing.ExpressionEvaluatorSwingManager; |
55 | 61 |
import org.gvsig.expressionevaluator.swing.JExpressionBuilder; |
56 |
import org.gvsig.fmap.geom.Geometry; |
|
57 |
import org.gvsig.fmap.geom.primitive.Envelope; |
|
58 | 62 |
import org.gvsig.tools.ToolsLocator; |
59 | 63 |
import org.gvsig.tools.i18n.I18nManager; |
60 | 64 |
import org.gvsig.tools.script.Script; |
... | ... | |
76 | 80 |
extends DefaultJExpressionBuilderView |
77 | 81 |
implements JExpressionBuilder { |
78 | 82 |
|
83 |
private static final Color COLOR_ERROR = new Color(255,225,232); |
|
84 |
|
|
79 | 85 |
private final ExpressionEvaluatorSwingManager manager; |
80 | 86 |
private GroupElement currentGroup; |
81 | 87 |
private PickerController<List<Script>> scriptPicker; |
... | ... | |
85 | 91 |
private ElementsTreeModel treeModel; |
86 | 92 |
private java.awt.Component infoPanel = null; |
87 | 93 |
private JEditorPane txtDescription; |
94 |
private Timer timerExpression; |
|
88 | 95 |
private ImageIcon defaultIconGroup; |
89 | 96 |
private ImageIcon defaultIconElement; |
90 | 97 |
private JScrollPane scrDescription; |
91 |
|
|
98 |
private Color color_ok; |
|
99 |
|
|
92 | 100 |
private class ElementsTreeModel implements TreeModel { |
93 | 101 |
|
94 | 102 |
private final GroupElement root; |
... | ... | |
207 | 215 |
ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager(); |
208 | 216 |
final IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent(); |
209 | 217 |
|
218 |
this.btnTip.setVisible(false); |
|
219 |
this.btnTip.addActionListener(new ActionListener() { |
|
220 |
@Override |
|
221 |
public void actionPerformed(ActionEvent e) { |
|
222 |
ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager(); |
|
223 |
dialogs.messageDialog( |
|
224 |
btnTip.getToolTipText(), |
|
225 |
"Tip", |
|
226 |
JOptionPane.INFORMATION_MESSAGE |
|
227 |
); |
|
228 |
} |
|
229 |
}); |
|
230 |
|
|
210 | 231 |
this.defaultIconGroup = theme.get("expressionbuilder-element-group"); |
211 | 232 |
this.defaultIconElement = theme.get("expressionbuilder-element"); |
212 | 233 |
|
234 |
this.timerExpression = new Timer(3000, new ActionListener() { |
|
235 |
@Override |
|
236 |
public void actionPerformed(ActionEvent e) { |
|
237 |
doCheckExpression(); |
|
238 |
} |
|
239 |
}); |
|
240 |
this.timerExpression.setRepeats(false); |
|
213 | 241 |
this.txtDescription = new JEditorPane(); |
214 | 242 |
this.scrDescription = new JScrollPane(this.txtDescription); |
215 | 243 |
|
... | ... | |
228 | 256 |
}); |
229 | 257 |
this.pnlDescription.setLayout(new BorderLayout()); |
230 | 258 |
this.pnlDescription.setBackground(this.txtDescription.getBackground()); |
231 |
|
|
259 |
this.color_ok = this.txtExpression.getBackground(); |
|
260 |
this.txtExpression.addCaretListener(new CaretListener() { |
|
261 |
@Override |
|
262 |
public void caretUpdate(CaretEvent e) { |
|
263 |
lblColumn.setText(Integer.toString(e.getDot())); |
|
264 |
} |
|
265 |
}); |
|
266 |
this.txtExpression.getDocument().addDocumentListener(new DocumentListener() { |
|
267 |
@Override |
|
268 |
public void insertUpdate(DocumentEvent e) { |
|
269 |
timerExpression.restart(); |
|
270 |
} |
|
271 |
|
|
272 |
@Override |
|
273 |
public void removeUpdate(DocumentEvent e) { |
|
274 |
timerExpression.restart(); |
|
275 |
} |
|
276 |
|
|
277 |
@Override |
|
278 |
public void changedUpdate(DocumentEvent e) { |
|
279 |
timerExpression.restart(); |
|
280 |
} |
|
281 |
}); |
|
282 |
this.txtExpression.addKeyListener(new KeyAdapter() { |
|
283 |
@Override |
|
284 |
public void keyPressed(KeyEvent e) { |
|
285 |
if( e.getKeyCode()==KeyEvent.VK_C && e.isControlDown() ) { |
|
286 |
doCheckExpression(); |
|
287 |
} |
|
288 |
} |
|
289 |
}); |
|
232 | 290 |
this.treeElements.setCellRenderer(new DefaultTreeCellRenderer() { |
233 | 291 |
@Override |
234 | 292 |
public java.awt.Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { |
... | ... | |
263 | 321 |
} |
264 | 322 |
} |
265 | 323 |
}); |
324 |
this.treeElements.addMouseListener(new MouseAdapter() { |
|
325 |
@Override |
|
326 |
public void mouseClicked(MouseEvent e) { |
|
327 |
if( e.getButton()==MouseEvent.BUTTON1 && e.getClickCount()==2 ) { |
|
328 |
TreePath path = treeElements.getSelectionPath(); |
|
329 |
Element element = (Element) path.getLastPathComponent(); |
|
330 |
if( element instanceof SimpleElement ) { |
|
331 |
doInsert((SimpleElement) element); |
|
332 |
} |
|
333 |
} |
|
334 |
} |
|
335 |
}); |
|
266 | 336 |
this.btnGroupElementInsert.addActionListener(new ActionListener() { |
267 | 337 |
@Override |
268 | 338 |
public void actionPerformed(ActionEvent e) { |
... | ... | |
307 | 377 |
label.setIcon(element.getIcon()); |
308 | 378 |
} |
309 | 379 |
label.setText(element.getName()); |
380 |
label.setEnabled(element.isEnabled()); |
|
310 | 381 |
} else { |
311 | 382 |
label.setIcon(null); |
312 | 383 |
label.setText(Objects.toString(value, "")); |
... | ... | |
439 | 510 |
this.txtDescription.setPreferredSize(new Dimension(200,200)); |
440 | 511 |
} |
441 | 512 |
|
513 |
private void doCheckExpression() { |
|
514 |
Expression expression = this.getExpression(); |
|
515 |
this.btnTip.setVisible(false); |
|
516 |
if( expression == null ) { |
|
517 |
this.lblMsg.setText(""); |
|
518 |
this.txtExpression.setBackground(this.color_ok); |
|
519 |
return; |
|
520 |
} |
|
521 |
try { |
|
522 |
expression.getCode(); |
|
523 |
this.lblMsg.setText(""); |
|
524 |
this.txtExpression.setBackground(this.color_ok); |
|
525 |
} catch(ExpressionSyntaxException ex) { |
|
526 |
this.lblMsg.setText("<html>"+ex.getDescription()+"</html>"); |
|
527 |
this.txtExpression.setBackground(COLOR_ERROR); |
|
528 |
return; |
|
529 |
} catch(Exception ex) { |
|
530 |
this.lblMsg.setText("Syntax error in expression"); |
|
531 |
this.txtExpression.setBackground(COLOR_ERROR); |
|
532 |
return; |
|
533 |
} |
|
534 |
if( this.config.getPreviewSymbolTable()==null ) { |
|
535 |
try { |
|
536 |
ExpressionEvaluatorManager theManager = ExpressionEvaluatorLocator.getManager(); |
|
537 |
MutableSymbolTable symbolTable = theManager.createSymbolTable(); |
|
538 |
Object value = expression.execute(symbolTable); |
|
539 |
this.lblMsg.setText("<html>"+StringUtils.abbreviate(Utils.toString(value),100)+"</html>"); |
|
540 |
this.txtExpression.setBackground(this.color_ok); |
|
541 |
} catch(Exception ex) { |
|
542 |
this.lblMsg.setText(""); |
|
543 |
} |
|
544 |
} else { |
|
545 |
try { |
|
546 |
Object value = expression.execute(this.config.getPreviewSymbolTable()); |
|
547 |
this.lblMsg.setText("<html>"+StringUtils.abbreviate(Utils.toString(value),100)+"</html>"); |
|
548 |
this.txtExpression.setBackground(this.color_ok); |
|
549 |
} catch(ExpressionRuntimeException ex) { |
|
550 |
if( !StringUtils.isBlank(ex.getTip()) ) { |
|
551 |
this.btnTip.setToolTipText(ex.getTip()); |
|
552 |
this.btnTip.setVisible(true); |
|
553 |
} |
|
554 |
this.lblMsg.setText("<html>Runtime error. "+ex.getMessage()+"</html>"); |
|
555 |
this.txtExpression.setBackground(COLOR_ERROR); |
|
556 |
} catch(Exception ex) { |
|
557 |
this.lblMsg.setText("<html>Runtime error. "+ex.getMessage()+"</html>"); |
|
558 |
this.txtExpression.setBackground(COLOR_ERROR); |
|
559 |
} |
|
560 |
} |
|
561 |
} |
|
562 |
|
|
442 | 563 |
private String removeCursorMark(String s) { |
443 | 564 |
s = s.replace("{{", ""); |
444 | 565 |
s = s.replace("}}", ""); |
... | ... | |
474 | 595 |
} |
475 | 596 |
} else if( element instanceof ConstantElement) { |
476 | 597 |
Object value = ((ConstantElement) element).getValue(); |
477 |
doInsert(" "+repr(value)+" "); |
|
598 |
doInsert(" "+Utils.repr(value)+" ");
|
|
478 | 599 |
} else { |
479 | 600 |
doInsert(" "+element.getName()+" "); |
480 | 601 |
} |
... | ... | |
486 | 607 |
} |
487 | 608 |
|
488 | 609 |
private void doSelectElement(SimpleElement element) { |
610 |
if( !element.isEnabled() ) { |
|
611 |
this.cleanDescription(); |
|
612 |
return; |
|
613 |
} |
|
489 | 614 |
I18nManager i18n = ToolsLocator.getI18nManager(); |
490 | 615 |
|
491 | 616 |
Component aditionalPanel = element.getAditionalPanel(); |
... | ... | |
500 | 625 |
html.append("<b>").append(i18n.getTranslation("_Value")).append("</b> NULL<br>\n"); |
501 | 626 |
} else { |
502 | 627 |
html.append("<b>").append(i18n.getTranslation("_Constant")).append("</b><br>\n<br>\n"); |
503 |
html.append("<b>").append(i18n.getTranslation("_Value")).append("</b> ").append(repr(value)).append("<br>\n"); |
|
628 |
html.append("<b>").append(i18n.getTranslation("_Value")).append("</b> ").append(Utils.repr(value)).append("<br>\n");
|
|
504 | 629 |
html.append("<b>").append(i18n.getTranslation("_Type")).append("</b> ").append(value.getClass().getSimpleName()).append("<br>\n"); |
505 | 630 |
} |
506 | 631 |
|
... | ... | |
565 | 690 |
|
566 | 691 |
} |
567 | 692 |
|
568 |
private void updateSimpleElementsList(GroupElement group) { |
|
569 |
FilteredListModel model = new FilteredListModel(); |
|
570 |
model.addElement("Loading..."); |
|
571 |
this.currentGroup = group; |
|
572 |
this.txtGroupElement.setText(group.getName()); |
|
573 |
this.txtSimpleElementFilter.setText(""); |
|
693 |
private void cleanDescription() { |
|
574 | 694 |
this.txtDescription.setText(""); |
575 | 695 |
if( this.infoPanel != this.scrDescription ) { |
576 | 696 |
this.pnlDescription.removeAll(); |
... | ... | |
579 | 699 |
this.pnlDescription.repaint(); |
580 | 700 |
this.infoPanel = this.scrDescription; |
581 | 701 |
} |
702 |
} |
|
703 |
|
|
704 |
private void updateSimpleElementsList(GroupElement group) { |
|
705 |
FilteredListModel model = new FilteredListModel(); |
|
706 |
model.addElement("Loading..."); |
|
707 |
this.currentGroup = group; |
|
708 |
this.txtGroupElement.setText(group.getName()); |
|
709 |
this.txtSimpleElementFilter.setText(""); |
|
710 |
this.cleanDescription(); |
|
582 | 711 |
if (group instanceof SimpleElement) { |
583 | 712 |
this.btnGroupElementInsert.setEnabled(true); |
584 | 713 |
} else { |
... | ... | |
705 | 834 |
} |
706 | 835 |
|
707 | 836 |
@Override |
837 |
public SymbolTable getPreviewSymbolTable() { |
|
838 |
return this.config.getPreviewSymbolTable(); |
|
839 |
} |
|
840 |
|
|
841 |
@Override |
|
842 |
public void setPreviewSymbolTable(SymbolTable symbolTable) { |
|
843 |
this.config.setPreviewSymbolTable(symbolTable); |
|
844 |
} |
|
845 |
|
|
846 |
@Override |
|
708 | 847 |
public void setScriptsEnabled(boolean enabled) { |
709 | 848 |
this.config.setScriptsEnabled(enabled); |
710 | 849 |
this.tabExpressionBuilder.setEnabledAt(0, this.config.getScriptsEnabled()); |
... | ... | |
729 | 868 |
} |
730 | 869 |
return this; |
731 | 870 |
} |
732 |
|
|
733 |
private String repr(Object value) { |
|
734 |
if (value == null) { |
|
735 |
return "NULL"; |
|
736 |
} else if (value instanceof Date) { |
|
737 |
return "DATE('" + value + "')"; |
|
738 |
} else if (value instanceof Boolean) { |
|
739 |
return value.toString(); |
|
740 |
} else if (value instanceof String) { |
|
741 |
return "'" + StringEscapeUtils.escapeSql((String) value) + "'"; |
|
742 |
} else if (value instanceof Geometry) { |
|
743 |
ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder(); |
|
744 |
return builder.geometry((Geometry)value).toString(); |
|
745 |
} else if (value instanceof Envelope) { |
|
746 |
ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder(); |
|
747 |
return builder.envelope((Envelope)value).toString(); |
|
748 |
} else if (value instanceof Number) { |
|
749 |
return ((Number)value).toString(); |
|
750 |
} else { |
|
751 |
return StringEscapeUtils.escapeSql(value.toString()); |
|
752 |
} |
|
753 |
|
|
754 |
} |
|
755 | 871 |
|
756 | 872 |
private void doSetTimeLimit() { |
757 | 873 |
ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager(); |
Also available in: Unified diff