Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / dispose / DisposableManagementExtension.java @ 45707

History | View | Annotate | Download (13.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 {}  {{Task}}
26
 */
27
package org.gvsig.app.extension.dispose;
28

    
29
import java.awt.Dimension;
30
import java.awt.event.ActionEvent;
31
import java.lang.management.ManagementFactory;
32
import java.lang.management.MemoryMXBean;
33
import java.util.ArrayList;
34
import java.util.Collections;
35
import java.util.List;
36
import java.util.Set;
37

    
38
import javax.swing.JScrollPane;
39
import javax.swing.JTable;
40
import javax.swing.JTextPane;
41
import javax.swing.ListSelectionModel;
42
import javax.swing.SwingUtilities;
43
import javax.swing.event.ListSelectionEvent;
44
import javax.swing.table.AbstractTableModel;
45
import javax.swing.table.DefaultTableColumnModel;
46
import javax.swing.table.TableColumn;
47
import javax.swing.table.TableColumnModel;
48

    
49
import org.gvsig.andami.plugins.Extension;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.dispose.Disposable;
52
import org.gvsig.tools.dispose.DisposableInfo;
53
import org.gvsig.tools.dispose.DisposableManager;
54
import org.gvsig.tools.exception.BaseException;
55
import org.gvsig.tools.swing.api.ToolsSwingLocator;
56
import org.gvsig.tools.swing.api.ToolsSwingUtils;
57
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
/**
62
 * An extension to view and manage {@link Disposable} objects which are still
63
 * bound.
64
 *
65
 * TODO: remove this extension and replace with a better one, maybe based on
66
 * scripting.
67
 *
68
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
69
 */
70
public class DisposableManagementExtension extends Extension {
71

    
72
    public static String SHOW_COMMAND = "tools-devel-disposables-show-pendings";
73
    public static String DISPOSE_ALL_COMMAND = "tools-devel-disposables-free-all";
74

    
75
    private static final Logger LOG
76
            = LoggerFactory.getLogger(DisposableManagementExtension.class);
77

    
78
    @Override
79
    public void initialize() {
80
        // Nothing to do
81
    }
82

    
83
    @Override
84
    public void postInitialize() {
85
        super.postInitialize();
86
    }
87

    
88
    @Override
89
    public void execute(String actionCommand) {
90

    
91
        if (DISPOSE_ALL_COMMAND.equals(actionCommand)) {
92
            disposeAll();
93
        } else {
94
            if (SHOW_COMMAND.equals(actionCommand)) {
95
                DisposablesDoList panel = new DisposablesDoList();
96
                panel.showPanel();
97
            }
98
        }
99
    }
100

    
101
    private void disposeAll() {
102
        DisposableManager manager;
103
        manager = ToolsLocator.getDisposableManager();
104
        try {
105
            manager.releaseAll();
106
        } catch (BaseException ex) {
107
            LOG.error("Error disposing all bound disposable objects", ex);
108
        }
109
    }
110

    
111
    @Override
112
    public boolean isEnabled() {
113
        return true;
114
    }
115

    
116
    @Override
117
    public boolean isVisible() {
118
        return true;
119
    }
120

    
121
    class DisposablesDoList extends DisposablesDoListLayout {
122

    
123
        private DisposableManager manager;
124
        private JTable disposablesTable = null;
125
        private JTextPane infoTextArea = null;
126

    
127
        public DisposablesDoList() {
128
            manager = ToolsLocator.getDisposableManager();
129
            initComponents();
130
            SwingUtilities.invokeLater(() -> {
131
                refreshList();
132
                updateMemoryUsage();
133
            });
134
        }
135

    
136
        private void initComponents() {
137
            this.setPreferredSize(new Dimension(600, 550));
138

    
139
            this.disposablesTable = new JTable(new DisposablesTableModel());
140
            this.disposablesTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
141

    
142
//            DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
143
//            columnModel.addColumn(new TableColumn(0, ToolsSwingUtils.cols2px(5)));
144
//            columnModel.addColumn(new TableColumn(1, ToolsSwingUtils.cols2px(12)));
145
//            columnModel.addColumn(new TableColumn(2, ToolsSwingUtils.cols2px(12)));
146
//            columnModel.addColumn(new TableColumn(3, ToolsSwingUtils.cols2px(25)));
147
//            this.disposablesTable.setColumnModel(columnModel);
148

    
149
            this.infoTextArea = new JTextPane();
150
            this.infoTextArea.setContentType("text/html");
151
            
152
            JScrollPane listScroller = new JScrollPane(this.disposablesTable);
153
            JScrollPane infoScroller = new JScrollPane(this.infoTextArea);
154
            this.splitPanel.setLeftComponent(listScroller);
155
            this.splitPanel.setRightComponent(infoScroller);
156

    
157
//            Dimension dim = this.splitPanel.getPreferredSize();
158
//            dim.height = dim.height / 2;
159
//            this.disposablesTable.setPreferredSize(dim);
160
//            this.splitPanel.invalidate();
161
            
162
            this.closeButton.addActionListener((ActionEvent arg0) -> {
163
                closeWindow();
164
            });
165
            this.closeButton.setEnabled(true);
166
            this.disposeAllButton.addActionListener((ActionEvent e) -> {
167
                disposeAll();
168
                refreshList();
169
                updateMemoryUsage();
170
            });
171
            this.disposeAllButton.setEnabled(true);
172
            this.disposeButton.addActionListener((ActionEvent e) -> {
173
                disposeSelecteds();
174
                refreshList();
175
                updateMemoryUsage();
176
            });
177
            this.disposeButton.setEnabled(true);
178
            this.disposablesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent arg0) -> {
179
                ListItemSelected();
180
                updateMemoryUsage();
181
            });
182
            this.disposablesTable.setEnabled(true);
183
            this.refreshButton.addActionListener((ActionEvent arg0) -> {
184
                refreshList();
185
                updateMemoryUsage();
186
            });
187
            this.refreshButton.setEnabled(true);
188
        }
189

    
190
        private void refreshList() {
191
            fillTable();
192
        }
193

    
194
        private void ListItemSelected() {
195
            DisposablesTableModel model = (DisposablesTableModel) this.disposablesTable.getModel();
196
            DisposableInfo info = model.get(this.disposablesTable.getSelectedRow());
197
            if( info==null ) {
198
                this.infoTextArea.setText("");
199
            } else {
200
                this.infoTextArea.setText(toHTML(info));
201
                this.infoTextArea.setCaretPosition(0);
202
            }
203
        }
204

    
205
        private void fillTable() {
206
            Set<DisposableInfo> disposables = (Set<DisposableInfo>) manager.getBoundDisposables();
207
            this.messageLabel.setText("Disposables " + disposables.size());
208

    
209
            this.disposablesTable.setModel(new DisposablesTableModel(new ArrayList<>(disposables)));            this.messageLabel.setText("Pending " + disposables.size());
210
            this.infoTextArea.setText("");
211
        }
212
        
213
        private void updateMemoryUsage() {
214
            Runtime rt = Runtime.getRuntime();
215
            this.lblTotalMemory.setText(String.valueOf(rt.totalMemory()/1024));
216
            this.lblMaxMemory.setText(String.valueOf(rt.maxMemory()/1024));
217
            this.lblFreeMemory.setText(String.valueOf(rt.freeMemory()/1024));
218
            this.lblActiveThreads.setText(String.valueOf(Thread.activeCount()));
219
            
220
            int objectPendingFinalizationCount = -1;
221
            try {
222
                MemoryMXBean memBean = ManagementFactory.getMemoryMXBean() ;
223
                objectPendingFinalizationCount = memBean.getObjectPendingFinalizationCount();
224
            } catch(ThreadDeath th) {
225
                
226
            }
227
            this.lblObjectPendingFinalization.setText(String.valueOf(objectPendingFinalizationCount));
228
        }
229

    
230
        private class DisposablesTableModel extends AbstractTableModel {
231

    
232
            private List<DisposableInfo> disposables; 
233
            private final String[] columnNames;
234
            private final Class[] columnClass;
235
            
236
            public DisposablesTableModel() {
237
                this(Collections.EMPTY_LIST);
238
            }
239
            
240
            public DisposablesTableModel(List<DisposableInfo> disposables) {
241
                this.disposables = disposables;
242
                this.columnNames = new String[] {"Refs.", "Class", "Full class", "To str."};
243
                this.columnClass = new Class[] {Integer.class, String.class, String.class, String.class};
244
            }
245
            
246
            public DisposableInfo get(int rowIndex) {
247
                try {
248
                    return this.disposables.get(rowIndex);
249
                } catch(Throwable th) {
250
                    return null;
251
                }
252
            }
253
            
254
            @Override
255
            public int getRowCount() {
256
                return this.disposables.size();
257
            }
258

    
259
            @Override
260
            public int getColumnCount() {
261
                return this.columnNames.length;
262
            }
263

    
264
            @Override
265
            public String getColumnName(int columnIndex) {
266
                return this.columnNames[columnIndex];
267
            }
268

    
269
            @Override
270
            public Class<?> getColumnClass(int columnIndex) {
271
                return this.columnClass[columnIndex];
272
            }
273

    
274
            @Override
275
            public Object getValueAt(int rowIndex, int columnIndex) {
276
                DisposableInfo info = this.disposables.get(rowIndex);
277
                switch(columnIndex) {
278
                    case 0:
279
                        return info.getReferencesCount();
280
                    case 1:
281
                        try {
282
                            return info.getDisposable().getClass().getSimpleName();
283
                        } catch(Throwable th) {
284
                            return "(unknown)";
285
                        }
286
                    case 2:
287
                        try {
288
                            return info.getDisposable().getClass().getName();
289
                        } catch(Throwable th) {
290
                            return "(unknown)";
291
                        }
292
                    case 3:
293
                        try {
294
                            return info.getDisposable().toString();
295
                        } catch(Throwable th) {
296
                            return "(unknown)";
297
                        }
298
                }
299
                return null;
300
            }
301
        }
302

    
303
        public String toHTML(DisposableInfo  disposableInfo) {
304
            StringBuilder buffer = new StringBuilder();
305
            Disposable disposable = disposableInfo.getDisposable();
306

    
307
            buffer.append("<b>Class</b>: ").append(disposable.getClass().getSimpleName()).append("<br>\n");
308
            buffer.append("<b>Full class</b>: ").append(disposable.getClass().getName()).append("<br>\n");
309
            buffer.append("<b>References</b>: ").append(disposableInfo.getReferencesCount()).append("<br>\n");
310
            buffer.append("<b>toString</b>: ").append(disposable.toString()).append("<br>\n");
311

    
312
            buffer.append("<b>Binded from (stack)</b>:<br>\n");
313
            try {
314
                StackTraceElement[] stackTrace = disposableInfo
315
                        .getBindDisposableStackTrace();
316
                for (StackTraceElement stackTrace1 : stackTrace) {
317
                    buffer.append("&nbsp;&nbsp;").append(stackTrace1.toString().replaceAll("[<]", "&lt;").replace("[>]", "&gt;")).append("<br>\n");
318
                }
319
            } catch (Exception ex) {
320
                buffer.append("<br>\n<br>\nError showing stack.<br>\n").append(ex.getMessage());
321
            }
322
            return buffer.toString();
323
        }
324

    
325
        public void closeWindow() {
326
            this.setVisible(false);
327
        }
328

    
329
        public void disposeAll() {
330
            try {
331
                manager.releaseAll();
332
            } catch (BaseException ex) {
333
                LOG.error("Error disposing all bound disposable objects", ex);
334
            }
335
        }
336

    
337
        public void disposeSelecteds() {
338
            DisposablesTableModel model = (DisposablesTableModel) this.disposablesTable.getModel();
339
            for (int row : this.disposablesTable.getSelectedRows()) {
340
                DisposableInfo info = model.get(row);
341
                this.manager.release(info.getDisposable());
342
            }
343
            refreshList();
344
        }
345

    
346
        public void showPanel() {
347
            WindowManager wm = ToolsSwingLocator.getWindowManager();
348
            wm.showWindow(this, "Disposable do list", WindowManager.MODE.WINDOW);
349
        }
350

    
351
//        private class ActionListenerImpl implements ActionListener {
352
//
353
//            public ActionListenerImpl() {
354
//            }
355
//
356
//            @Override
357
//            public void actionPerformed(ActionEvent e) {
358
//                disposeSelecteds();
359
//                refreshList();
360
//                updateMemoryUsage();
361
//            }
362
//        }
363
    }
364

    
365
}