OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 13 | Rev 132 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13 ilm 1
package interpreterDJava;
2
 
3
import java.awt.Color;
4
import java.awt.Dimension;
5
import java.awt.GridBagConstraints;
6
import java.awt.GridBagLayout;
7
import java.awt.Insets;
8
import java.awt.Rectangle;
9
import java.io.BufferedReader;
10
import java.io.BufferedWriter;
11
import java.io.File;
12
import java.io.FileReader;
13
import java.io.FileWriter;
14
import java.io.IOException;
61 ilm 15
import java.util.HashMap;
16
import java.util.Map;
13 ilm 17
 
18
import javax.swing.JLabel;
19
import javax.swing.JPanel;
20
import javax.swing.JScrollBar;
21
import javax.swing.JTextField;
22
import javax.swing.JViewport;
23
import javax.swing.Scrollable;
24
import javax.swing.SwingConstants;
25
 
26
import koala.dynamicjava.interpreter.Interpreter;
27
import koala.dynamicjava.interpreter.InterpreterException;
28
import koala.dynamicjava.interpreter.TreeInterpreter;
29
import koala.dynamicjava.parser.wrapper.JavaCCParserFactory;
30
 
31
import org.jedit.JEditTextArea;
32
import org.jedit.JavaTokenMarker;
33
import org.jedit.Token;
34
 
35
// FIXME afficher les infos sur les variables via uen popup
36
 
37
public class JavaEditor extends JPanel implements Scrollable {
38
    private static final String CODE_CORRECT = "Code correct";
39
    protected JEditTextArea textFormule;
40
    protected JLabel status = new JLabel(CODE_CORRECT);
41
    private final JavaTokenMarker javaTokenMarker;
42
 
43
    protected String varAssign;
44
 
45
    private final JLabel labelPopup = new JLabel();
46
    private boolean codeValid = true;
47
 
61 ilm 48
    Map<String, Object> variable = new HashMap<String, Object>();
49
 
13 ilm 50
    public JavaEditor() {
51
 
52
        setOpaque(false);
53
        setLayout(new GridBagLayout());
54
        final GridBagConstraints c = new GridBagConstraints();
55
        c.gridx = 0;
56
        c.gridy = 0;
57
        c.gridwidth = 1;
58
        c.insets = new Insets(2, 2, 2, 1);
59
        this.textFormule = new JEditTextArea();
60
        c.weighty = 1;
61
        c.weightx = 1;
62
        c.fill = GridBagConstraints.BOTH;
63
        this.add(this.textFormule, c);
64
 
65
        this.javaTokenMarker = new JavaTokenMarker();
66
 
67
        this.textFormule.setTokenMarker(this.javaTokenMarker);
68
        this.textFormule.setFont(new JTextField().getFont());
69
 
70
        c.fill = GridBagConstraints.HORIZONTAL;
71
        c.gridy++;
72
        c.weighty = 0;
73
 
74
        this.add(this.status, c);
75
 
76
        // //ADD VAR ASSIGN
77
        this.varAssign = "$$$$$$";
78
        this.javaTokenMarker.addKeyword(this.varAssign, Token.LITERAL2);
79
 
80
    }
81
 
61 ilm 82
    public void putVariable(String var, Object value) {
83
        this.variable.put(var, value);
84
    }
85
 
86
    public JEditTextArea getTextArea() {
87
        return this.textFormule;
88
    }
89
 
13 ilm 90
    protected void setCodeValid(final boolean codeValid) {
91
        this.codeValid = codeValid;
92
    }
93
 
94
    protected final boolean isCodeValid() {
95
        return this.codeValid;
96
    }
97
 
98
    public void setVarAssign(final String s) {
99
 
100
        synchronized (this.varAssign) {
101
            this.javaTokenMarker.removeKeyword(this.varAssign);
102
 
103
            if (this.varAssign.trim().length() != 0) {
104
                this.varAssign = s;
105
                this.javaTokenMarker.addKeyword(this.varAssign, Token.LITERAL2);
106
            }
107
        }
108
    }
109
 
110
    public void addNewLitteral(final String s) {
111
        this.javaTokenMarker.addKeyword(s, Token.LITERAL2);
112
    }
113
 
114
    /**
115
     * Vérifie que la formule est correcte et renvoie sa valeur.
116
     *
117
     * @param formule formule à tester
118
     * @param varCallName variable qui recoit la formule
119
     * @return la valeur de retour de la formule
120
     */
121
    public Object checkFormule(final String formule, final String varCallName) {
122
 
123
        BufferedReader bR = null;
124
        File f = null;
125
        try {
126
 
127
            // Si la formule est vide --> OK
128
            if (formule.trim().length() == 0) {
129
                this.status.setText("Code correct");
130
                return null;
131
            }
132
            // Fichier temporaire qui contiendra la formule à interpreter
133
            final File dParent = new File(System.getProperty("user.home"), ".java/ilm/Interpreter/");
134
            dParent.mkdir();
135
            f = new File(dParent, "CalculVariable" + varCallName + ".txt");
136
 
137
            final Interpreter interpreter = new TreeInterpreter(new JavaCCParserFactory());
138
 
139
            final BufferedWriter bW = new BufferedWriter(new FileWriter(f));
140
 
61 ilm 141
            for (String var : this.variable.keySet()) {
142
                defineVariable(interpreter, bW, var, this.variable.get(var));
143
            }
13 ilm 144
            bW.write(formule);
145
            bW.flush();
146
            bW.close();
147
 
148
            // Interpret the script
149
            bR = new BufferedReader(new FileReader(f));
150
            final Object interpreterResult = interpreter.interpret(bR, f.getAbsolutePath());
151
            bR.close();
152
            try {
153
                // this.status.setText(interpreter.getVariableNames().toString());
154
                this.status.setText("Code correct, valeur de retour = " + interpreter.getVariable(varCallName).toString());
155
                setCodeValid(true);
156
                return interpreter.getVariable(varCallName);
157
            } catch (final IllegalStateException iSE) {
158
                if (interpreterResult != null) {
159
                    // this.status.setText(interpreter.getVariableNames().toString());
160
                    this.status.setText("Code correct, valeur de retour = " + interpreterResult.toString());
161
                    setCodeValid(true);
162
                    bR.close();
163
                    return interpreterResult;
164
                } else {
165
                    // this.status.setText(interpreter.getVariableNames().toString());
166
                    this.status.setText("Aucune valeur de retour");
167
                    setCodeValid(false);
168
                    return null;
169
                }
170
            }
171
        } catch (final Exception e) {
172
            if (e instanceof InterpreterException) {
173
                String m = "";
174
 
175
                final InterpreterException ex = (InterpreterException) e;
176
                System.out.println(ex.getMessage());
177
                if (ex.getSourceInformation() != null) {
178
                    m += " ligne:" + ex.getSourceInformation().getLine();
179
                }
180
                m += ex.getMessage();
181
                final int in = m.indexOf('\n');
182
                if (in > 0) {
183
                    m = m.substring(0, in);
184
                }
185
                setCodeValid(false);
186
                this.status.setText(m);
187
 
188
            } else {
189
                setCodeValid(false);
190
                System.err.println("err-----");
191
                e.printStackTrace();
192
            }
193
        }
194
        // Highlight the occurrences of the word "public"
195
        // highlight(textFormule, "int");
196
 
197
        // Creates highlights around all occurrences of pattern in textComp
198
        setCodeValid(false);
199
        return null;
200
    }
201
 
202
    /**
203
     * Permet de définir une variable dans la formule ou directement dans le fichier interpréter.
204
     *
205
     * @param interpret
206
     * @param b
207
     * @param varName
208
     * @param value
209
     */
210
    protected void defineVariable(final Interpreter interpret, final BufferedWriter b, final String varName, final Object value) {
211
 
212
        if (value == null) {
213
            try {
214
                b.write("float " + varName + " = 1.0F;\n");
215
            } catch (final IOException e) {
216
                // TODO Auto-generated catch block
217
                e.printStackTrace();
218
            }
219
        } else {
220
            if (value instanceof Integer) {
221
                try {
222
                    b.write("int " + varName + " = " + value + ";\n");
223
                } catch (final IOException e) {
224
                    // TODO Auto-generated catch block
225
                    e.printStackTrace();
226
                }
227
            } else {
228
                if (value instanceof Float) {
229
                    try {
230
                        b.write("float " + varName + " = " + value + "F;\n");
231
                    } catch (final IOException e) {
232
                        // TODO Auto-generated catch block
233
                        e.printStackTrace();
234
                    }
235
                } else {
236
                    if (value instanceof Double) {
237
                        try {
238
                            b.write("double " + varName + " = " + value + ";\n");
239
                        } catch (final IOException e) {
240
                            // TODO Auto-generated catch block
241
                            e.printStackTrace();
242
                        }
243
                    } else {
244
                        interpret.defineVariable(varName, value);
245
                    }
246
                }
247
            }
248
        }
249
    }
250
 
251
    public int getSelectionStart() {
252
 
253
        return this.textFormule.getSelectionStart();
254
    }
255
 
256
    public String getText() {
257
 
258
        return this.textFormule.getText();
259
    }
260
 
261
    public void setText(final String string) {
262
 
263
        this.textFormule.setText(string);
264
        this.textFormule.setCaretPosition(0);
265
    }
266
 
267
    public void setEditable(final boolean b) {
268
        this.textFormule.setEditable(b);
269
        this.textFormule.setBackground(Color.RED); // TODO a implementer
270
        this.textFormule.setCaretVisible(b);
271
        this.textFormule.setCaretBlinkEnabled(b);
272
    }
273
 
274
    /**
275
     * Returns the preferred size of the viewport for a view component. This is implemented to do
276
     * the default behavior of returning the preferred size of the component.
277
     *
278
     * @return the <code>preferredSize</code> of a <code>JViewport</code> whose view is this
279
     *         <code>Scrollable</code>
280
     */
281
    public Dimension getPreferredScrollableViewportSize() {
282
        return getPreferredSize();
283
    }
284
 
285
    /**
286
     * Components that display logical rows or columns should compute the scroll increment that will
287
     * completely expose one new row or column, depending on the value of orientation. Ideally,
288
     * components should handle a partially exposed row or column by returning the distance required
289
     * to completely expose the item.
290
     * <p>
291
     * The default implementation of this is to simply return 10% of the visible area. Subclasses
292
     * are likely to be able to provide a much more reasonable value.
293
     *
294
     * @param visibleRect the view area visible within the viewport
295
     * @param orientation either <code>SwingConstants.VERTICAL</code> or
296
     *        <code>SwingConstants.HORIZONTAL</code>
297
     * @param direction less than zero to scroll up/left, greater than zero for down/right
298
     * @return the "unit" increment for scrolling in the specified direction
299
     * @exception IllegalArgumentException for an invalid orientation
300
     * @see JScrollBar#setUnitIncrement
301
     */
302
    public int getScrollableUnitIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
303
        switch (orientation) {
304
        case SwingConstants.VERTICAL:
305
            return visibleRect.height / 10;
306
        case SwingConstants.HORIZONTAL:
307
            return visibleRect.width / 10;
308
        default:
309
            throw new IllegalArgumentException("Invalid orientation: " + orientation);
310
        }
311
    }
312
 
313
    /**
314
     * Components that display logical rows or columns should compute the scroll increment that will
315
     * completely expose one block of rows or columns, depending on the value of orientation.
316
     * <p>
317
     * The default implementation of this is to simply return the visible area. Subclasses will
318
     * likely be able to provide a much more reasonable value.
319
     *
320
     * @param visibleRect the view area visible within the viewport
321
     * @param orientation either <code>SwingConstants.VERTICAL</code> or
322
     *        <code>SwingConstants.HORIZONTAL</code>
323
     * @param direction less than zero to scroll up/left, greater than zero for down/right
324
     * @return the "block" increment for scrolling in the specified direction
325
     * @exception IllegalArgumentException for an invalid orientation
326
     * @see JScrollBar#setBlockIncrement
327
     */
328
    public int getScrollableBlockIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
329
        switch (orientation) {
330
        case SwingConstants.VERTICAL:
331
            return visibleRect.height;
332
        case SwingConstants.HORIZONTAL:
333
            return visibleRect.width;
334
        default:
335
            throw new IllegalArgumentException("Invalid orientation: " + orientation);
336
        }
337
    }
338
 
339
    /**
340
     * Returns true if a viewport should always force the width of this <code>Scrollable</code> to
341
     * match the width of the viewport. For example a normal text view that supported line wrapping
342
     * would return true here, since it would be undesirable for wrapped lines to disappear beyond
343
     * the right edge of the viewport. Note that returning true for a <code>Scrollable</code> whose
344
     * ancestor is a <code>JScrollPane</code> effectively disables horizontal scrolling.
345
     * <p>
346
     * Scrolling containers, like <code>JViewport</code>, will use this method each time they are
347
     * validated.
348
     *
349
     * @return true if a viewport should force the <code>Scrollable</code>s width to match its own
350
     */
351
    public boolean getScrollableTracksViewportWidth() {
352
        if (getParent() instanceof JViewport) {
353
            return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
354
        }
355
        return false;
356
    }
357
 
358
    /**
359
     * Returns true if a viewport should always force the height of this <code>Scrollable</code> to
360
     * match the height of the viewport. For example a columnar text view that flowed text in left
361
     * to right columns could effectively disable vertical scrolling by returning true here.
362
     * <p>
363
     * Scrolling containers, like <code>JViewport</code>, will use this method each time they are
364
     * validated.
365
     *
366
     * @return true if a viewport should force the Scrollables height to match its own
367
     */
368
    public boolean getScrollableTracksViewportHeight() {
369
        if (getParent() instanceof JViewport) {
370
            return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
371
        }
372
        return false;
373
    }
374
 
375
}