Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.dynform / org.gvsig.tools.dynform.spi / src / main / java / org / gvsig / tools / dynform / spi / dynform / AbstractJDynForm.java @ 1947

History | View | Annotate | Download (16.5 KB)

1
package org.gvsig.tools.dynform.spi.dynform;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Color;
5
import java.awt.Component;
6
import java.awt.Dimension;
7
import java.awt.event.MouseAdapter;
8
import java.awt.event.MouseEvent;
9
import java.io.IOException;
10
import java.util.ArrayList;
11
import java.util.Collection;
12
import java.util.Collections;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.logging.Level;
20
import javax.swing.Action;
21
import javax.swing.BorderFactory;
22
import javax.swing.JComponent;
23
import javax.swing.JLabel;
24
import javax.swing.JOptionPane;
25
import javax.swing.JPanel;
26
import javax.swing.JScrollPane;
27
import javax.swing.JViewport;
28
import org.apache.commons.io.IOUtils;
29
import org.apache.commons.lang3.StringUtils;
30
import org.gvsig.expressionevaluator.Code;
31
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
32
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
33
import org.gvsig.expressionevaluator.Function;
34
import org.gvsig.expressionevaluator.Interpreter;
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dataTypes.CoercionException;
37
import org.gvsig.tools.dataTypes.DataType;
38
import org.gvsig.tools.dataTypes.DataTypes;
39
import org.gvsig.tools.dynform.DynFormDefinition;
40
import org.gvsig.tools.dynform.JDynForm;
41
import org.gvsig.tools.dynform.JDynFormField;
42
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
43
import org.gvsig.tools.dynobject.DynObject;
44
import org.gvsig.tools.dynobject.Tags;
45
import org.gvsig.tools.identitymanagement.SimpleIdentity;
46
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
47
import org.gvsig.tools.util.PropertiesSupportHelper;
48
import org.slf4j.Logger;
49
import org.slf4j.LoggerFactory;
50

    
51
public abstract class AbstractJDynForm implements JDynForm {
52

    
53
    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractJDynForm.class);
54
    
55
    private final DynFormSPIManager manager;
56
    private final DynFormDefinition definition;
57
    private final JDynFormFactory factory;
58

    
59
    private DynFormContext context;
60

    
61
    private int formWidth = -1;
62
    private int formHeight = -1;
63
    private int layoutMode = USE_PLAIN;
64
    private JLabel jlabel_messages = null;
65
    private boolean readOnly = true;
66
    private Set listeners = null;
67
    private boolean useScrollBars = true;
68
    private final Map<String, List<Action>> customActions;
69
    private JComponent contents = null;
70
    protected DynObject values = null;
71
    private boolean border;
72
    private final PropertiesSupportHelper propertiesHelper = new PropertiesSupportHelper();
73
    private Interpreter interpreter;
74
    private boolean intepreter_initialized = false;
75

    
76
    @SuppressWarnings("OverridableMethodCallInConstructor")
77
    public AbstractJDynForm(
78
            DynFormSPIManager manager,
79
            JDynFormFactory factory,
80
            DynFormDefinition definition,
81
            DynFormContext context
82
    ) {
83
        this.manager = manager;
84
        this.factory = factory;
85
        this.definition = definition;
86
        this.context = context;
87
        this.listeners = new HashSet();
88
        this.customActions = new HashMap();
89
        if (definition != null) {
90
            this.loadDefaultValuesFromTags(definition.getTags());
91
            SimpleIdentity user = ToolsLocator.getIdentityManager().getCurrentIdentity();
92
            if( !user.canWrite(this, definition.getName()) ) {
93
                this.readOnly = true;
94
            }
95
        }
96
    }
97

    
98
    private Interpreter getInterpreter() {
99
        if( intepreter_initialized ) {
100
            return interpreter;
101
        }
102
        try {
103
            ResourcesStorage resources = this.context.getResourcesStorage();
104
            if( resources==null ) {
105
                this.interpreter = null;
106
                this.intepreter_initialized = true;
107
                return null;
108
            }
109
            ResourcesStorage.Resource res = resources.getResource("jfrms");
110
            if( res == null || !res.exists() ) {
111
                this.interpreter = null;
112
                this.intepreter_initialized = true;
113
                return null;
114
            }
115
            List<String> lines = IOUtils.readLines(res.asInputStream());
116
            if( lines == null ) {
117
                this.interpreter = null;
118
                this.intepreter_initialized = true;
119
                return null;
120
            }
121
            String source = StringUtils.join(lines, "\n");
122
            ExpressionEvaluatorManager expmanager = ExpressionEvaluatorLocator.getManager();
123
            Code code = expmanager.compile(source);
124
            this.interpreter = expmanager.createInterpreter();
125
            this.interpreter.run(code);
126
            this.intepreter_initialized = true;
127
            return interpreter;
128
        } catch (IOException ex) {
129
            LOGGER.warn("Can't load resource jfrms.", ex);
130
            this.interpreter = null;
131
            this.intepreter_initialized = true;
132
            return null;
133
        }
134
    }
135
    
136
    @Override
137
    public boolean hasUserCode() {
138
        return this.getInterpreter()!=null;
139
    }
140
    
141
    @Override
142
    public boolean hasUserFunction(String name) {
143
        Interpreter theInterpreter = this.getInterpreter();
144
        if( theInterpreter==null ) {
145
            return false;
146
        }
147
        return theInterpreter.hasFunction(name);
148
    }
149
    
150
    protected void callUserEvent(String name, Object...args) {
151
        Interpreter theInterpreter = this.getInterpreter();
152
        if( theInterpreter==null ) {
153
            return;
154
        }
155
        if( theInterpreter.hasFunction(name) ) {
156
            try {
157
                theInterpreter.call(name, args);
158
            } catch(Exception ex) {
159
                LOGGER.warn("Error calling form event '"+name+"'.", ex);
160
            }
161
        }
162
    }
163
    
164
    @Override
165
    public Object callUserFunction(String function, Object...args) throws Exception {
166
        Interpreter theInterpreter = this.getInterpreter();
167
        if( theInterpreter==null ) {
168
            throw new RuntimeException("Can't exists user code associated to this form.");
169
        }
170
        if( !theInterpreter.hasFunction(function) ) {
171
            throw new IllegalArgumentException("Don't exists function '"+function+"' associated to this form.");
172
        }
173
        return theInterpreter.call(function, args);
174
    } 
175
    
176
    protected Collection<Function> getUserFunctions() {
177
        Interpreter theInterpreter = this.getInterpreter();
178
        if( theInterpreter==null ) {
179
            return Collections.EMPTY_LIST;
180
        }
181
        return theInterpreter.getSymbolTable().localfunctions();
182
    }
183
    
184
    public static int getLayoutFromTags(Tags tags) {
185
        String layoutMode = (String) tags.get(
186
                DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE, 
187
                DataTypes.STRING, 
188
                DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE_VALUE_PLAIN
189
        );
190
        if (!StringUtils.isEmpty(layoutMode)) {
191
            if (layoutMode.equalsIgnoreCase("0")
192
                    || layoutMode.equalsIgnoreCase(DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE_VALUE_PLAIN)) {
193
                return JDynForm.USE_PLAIN;
194
            } else if (layoutMode.equalsIgnoreCase("1")
195
                    || layoutMode.equalsIgnoreCase(DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE_VALUE_TABS)) {
196
                return JDynForm.USE_TABS;
197
            } else if (layoutMode.equalsIgnoreCase("2")
198
                    || layoutMode.equalsIgnoreCase(DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE_VALUE_SEPARATORS)) {
199
                return JDynForm.USE_SEPARATORS;
200
            }
201
        }
202
        return JDynForm.USE_PLAIN;
203
    }
204

    
205
    public void loadDefaultValuesFromTags(Tags tags) {
206
        this.setLayoutMode(getLayoutFromTags(tags));
207

    
208
        try {
209
            this.formWidth = tags.getInt(DynFormSPIManager.TAG_DYNFORM_WIDTH);
210
        } catch (CoercionException ex) {
211
        }
212
        try {
213
            this.formHeight = tags.getInt(DynFormSPIManager.TAG_DYNFORM_HEIGHT);
214
        } catch (CoercionException ex) {
215
        }
216
        try {
217
            this.border = tags.getBoolean(DynFormSPIManager.TAG_DYNFORM_BORDER);
218
        } catch (CoercionException ex) {
219
        }
220
        try {
221
            this.useScrollBars = tags.getBoolean(DynFormSPIManager.TAG_DYNFORM_USESCROLLBARS);
222
        } catch (CoercionException ex) {
223
        }
224
        try {
225
            this.readOnly = tags.getBoolean(DynFormSPIManager.TAG_DYNFORM_READONLY);
226
        } catch (CoercionException ex) {
227
        }
228
    }
229

    
230
    public DynFormSPIManager getServiceManager() {
231
        return this.manager;
232
    }
233

    
234
    @Override
235
    public JComponent asJComponent() {
236
        if (this.contents == null) {
237
            this.initComponents();
238
        }
239
        return this.contents;
240
    }
241

    
242
    protected void initComponents() {
243
        if (this.contents == null) {
244
            this.contents = addScrollsAndMessageBar(this.getFieldsContainer());
245
            if (this.values != null) {
246
                this.setValues(values);
247
            }
248
            if (this.border) {
249
                this.contents.setBorder(BorderFactory.createLineBorder(Color.GRAY));
250
            }
251
            message();
252
        }
253
    }
254

    
255
    protected boolean isContentsInitialized() {
256
        return this.contents != null;
257
    }
258

    
259
    @Override
260
    public void addListener(JDynFormListener listener) {
261
        this.listeners.add(listener);
262
    }
263

    
264
    @Override
265
    public void removeListener(JDynFormListener listener) {
266
        this.listeners.remove(listener);
267
    }
268

    
269
    public JLabel getMessagesJLabel() {
270
        if (this.jlabel_messages == null) {
271
            this.jlabel_messages = new JLabel();
272
            this.jlabel_messages.addMouseListener(new MouseAdapter() {
273
                @Override
274
                public void mouseClicked(MouseEvent evt) {
275
                    int count = evt.getClickCount();
276
                    if (count == 2) {
277
                        JOptionPane.showMessageDialog(contents, jlabel_messages.getText(), "Status", JOptionPane.INFORMATION_MESSAGE);
278
                    }
279
                }
280
            });
281
        }
282
        return this.jlabel_messages;
283
    }
284

    
285
    @Override
286
    public void setShowMessageStatus(boolean showMessageStatus) {
287
        this.getMessagesJLabel().setVisible(showMessageStatus);
288
    }
289

    
290
    @Override
291
    public boolean isShowMessageStatus() {
292
        return this.getMessagesJLabel().isVisible();
293
    }
294

    
295
    @Override
296
    public void message() {
297
        this.getMessagesJLabel().setText(" ");
298
    }
299

    
300
    @Override
301
    public void message(String msg) {
302
        this.getMessagesJLabel().setText(msg);
303
        fireMessageEvent(msg);
304
    }
305

    
306
    protected void fireMessageEvent(String message) {
307
        Iterator it = this.listeners.iterator();
308
        while (it.hasNext()) {
309
            JDynFormListener listener = (JDynFormListener) it.next();
310
            try {
311
                listener.message(message);
312
            } catch (Exception ex) {
313
                LOGGER.info("Error calling listener " + listener.toString()
314
                        + "(" + listener.getClass().getName() + ") from "
315
                        + this.toString() + "(" + this.getClass().getName()
316
                        + ").", ex);
317
            }
318
        }
319
    }
320

    
321
    protected void fireFieldChangeEvent(JDynFormField field) {
322
        Iterator it = this.listeners.iterator();
323
        while (it.hasNext()) {
324
            JDynFormListener listener = (JDynFormListener) it.next();
325
            try {
326
                listener.fieldChanged(field);
327
            } catch (Exception ex) {
328
                LOGGER.info("Error calling listener " + listener.toString()
329
                        + "(" + listener.getClass().getName() + ") from "
330
                        + this.toString() + "(" + this.getClass().getName()
331
                        + ").", ex);
332
            }
333
        }
334
    }
335

    
336
    protected JPanel addScrollsAndMessageBar(JComponent formPanel) {
337
        formPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
338
        JScrollPane scroll = new JScrollPane(formPanel);
339
        Dimension size = formPanel.getPreferredSize();
340
        if( this.formWidth<100 ) {
341
            if( size.width>800 ) {
342
                this.formWidth = 800;
343
            } else {
344
                this.formWidth = size.width;
345
            }
346
        }
347
        if( this.formHeight<100 ) {
348
            if( size.height>450 ) {
349
                this.formHeight = 450;
350
            } else {
351
                this.formHeight = size.height;
352
            }
353
        }
354
        
355
        if (useScrollBars) {
356
            int scrollBarWidth = scroll.getVerticalScrollBar().getPreferredSize().width;
357
            scroll.setPreferredSize(new Dimension(formWidth+4, formHeight+4));
358
            formPanel.setPreferredSize(new Dimension(formWidth-scrollBarWidth, size.height));
359
        } else {
360
            scroll.setPreferredSize(size);
361
        }
362
        scroll.setBorder(BorderFactory.createEmptyBorder());
363
        JPanel jpanel = new JPanel();
364
        jpanel.setLayout(new BorderLayout());
365
        jpanel.add(scroll, BorderLayout.CENTER);
366
        jpanel.add(getMessagesJLabel(), BorderLayout.PAGE_END);
367
        return jpanel;
368
    }
369

    
370
    @Override
371
    public int getLayoutMode() {
372
        return this.layoutMode;
373
    }
374

    
375
    @Override
376
    public void setLayoutMode(int layoutMode) {
377
        if (layoutMode < 0 || layoutMode > USE_SEPARATORS) {
378
            throw new IllegalArgumentException("layoutMode (" + layoutMode + ") out of range. Valid values are 0 .. " + USE_SEPARATORS + ".");
379
        }
380
        this.layoutMode = layoutMode;
381
    }
382

    
383
    @Override
384
    public boolean isReadOnly() {
385
        return readOnly;
386
    }
387

    
388
    @Override
389
    public void setReadOnly(boolean readOnly) {
390
        this.readOnly = readOnly;
391
    }
392

    
393
    @Override
394
    public int getFormWidth() {
395
        if (this.contents == null) {
396
            return this.formWidth;
397
        } else {
398
            JViewport port = ((JScrollPane) this.asJComponent()).getViewport();
399
            Component comp = (Component) port.getView();
400
            return comp.getWidth();
401
        }
402
    }
403

    
404
    @Override
405
    public int getFormHeight() {
406
        if (this.contents == null) {
407
            return this.formHeight;
408
        } else {
409
            JViewport port = ((JScrollPane) this.asJComponent()).getViewport();
410
            Component comp = (Component) port.getView();
411
            return comp.getHeight();
412
        }
413
    }
414

    
415
    @Override
416
    public void setFormSize(int width, int height) {
417
        this.formHeight = height;
418
        this.formWidth = width;
419
        if (this.contents != null) {
420
            this.asJComponent().setPreferredSize(new Dimension(width, height));
421
        }
422
    }
423

    
424
    protected List<Action> getCustomFields(DataType dataType) {
425
        return (List<Action>) customActions.get(dataType.getName());
426
    }
427

    
428
    @Override
429
    public void addActionToPopupMenu(DataType tipo, String name, Action action) {
430
        List<Action> acts = this.getCustomFields(tipo);
431
        action.putValue(Action.NAME, name);
432
        if (acts == null) {
433
            List<Action> aux = new ArrayList<>();
434
            aux.add(action);
435
            customActions.put(tipo.getName(), aux);
436
        } else {
437
            acts.add(action);
438
        }
439
    }
440

    
441
    @Override
442
    public void addSeparatorToPopupMenu(DataType tipo) {
443
        List<Action> acts = this.getCustomFields(tipo);
444
        if (acts == null) {
445
            List<Action> aux = new ArrayList<>();
446
            aux.add(null);
447
            customActions.put(tipo.getName(), aux);
448
        } else {
449
            acts.add(null);
450
        }
451
    }
452

    
453
    @Override
454
    public DynFormDefinition getDefinition() {
455
        return this.definition;
456
    }
457

    
458
    @Override
459
    public boolean getUseScrollBars() {
460
        return useScrollBars;
461
    }
462

    
463
    @Override
464
    public void setUseScrollBars(boolean usesScrolls) {
465
        this.useScrollBars = usesScrolls;
466
    }
467

    
468
    public void setBorder(boolean border) {
469
        this.border = border;
470
        if (this.isContentsInitialized() && border) {
471
            this.asJComponent().setBorder(BorderFactory.createLineBorder(Color.GRAY));
472
        }
473
    }
474

    
475
    @Override
476
    public JDynFormField getField(String fieldName) {
477
        return null;
478
    }
479

    
480
    @Override
481
    public Object getProperty(String key) {
482
        return this.propertiesHelper.getProperty(key);
483
    }
484

    
485
    @Override
486
    public void setProperty(String key, Object obj) {
487
        this.propertiesHelper.setProperty(key, obj);
488
    }
489

    
490
    @Override
491
    public Map<String, Object> getProperties() {
492
        return this.propertiesHelper.getProperties();
493
    }
494

    
495
    @Override
496
    public DynFormContext getContext() {
497
        return this.context;
498
    }
499

    
500
    @Override
501
    public void setContext(DynFormContext context) {
502
        this.context = context;
503
    }
504

    
505
    protected abstract JComponent getFieldsContainer();
506
}