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 @ 46737

History | View | Annotate | Download (14.7 KB)

1 40558 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40558 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 41258 jjdelcerro
 * 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 40558 jjdelcerro
 *
11 41258 jjdelcerro
 * 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 40558 jjdelcerro
 *
16 41258 jjdelcerro
 * 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 40558 jjdelcerro
 *
20 41258 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40435 jjdelcerro
 */
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 {}  {{Task}}
26
 */
27
package org.gvsig.app.extension.dispose;
28
29 41258 jjdelcerro
import java.awt.Dimension;
30 41043 jjdelcerro
import java.awt.event.ActionEvent;
31 45707 jjdelcerro
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 40435 jjdelcerro
import java.util.Set;
37 41043 jjdelcerro
import javax.swing.JScrollPane;
38 45707 jjdelcerro
import javax.swing.JTable;
39 41043 jjdelcerro
import javax.swing.JTextPane;
40 45707 jjdelcerro
import javax.swing.ListSelectionModel;
41 41043 jjdelcerro
import javax.swing.SwingUtilities;
42
import javax.swing.event.ListSelectionEvent;
43 45707 jjdelcerro
import javax.swing.table.AbstractTableModel;
44
import javax.swing.table.DefaultTableColumnModel;
45
import javax.swing.table.TableColumn;
46 40435 jjdelcerro
import org.gvsig.andami.plugins.Extension;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.dispose.Disposable;
49
import org.gvsig.tools.dispose.DisposableInfo;
50
import org.gvsig.tools.dispose.DisposableManager;
51
import org.gvsig.tools.exception.BaseException;
52 41043 jjdelcerro
import org.gvsig.tools.swing.api.ToolsSwingLocator;
53 45729 jjdelcerro
import org.gvsig.tools.swing.api.ToolsSwingManager;
54 45707 jjdelcerro
import org.gvsig.tools.swing.api.ToolsSwingUtils;
55 41043 jjdelcerro
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
56 45716 fdiaz
import org.gvsig.tools.util.LabeledValue;
57 40435 jjdelcerro
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59
60
/**
61
 * An extension to view and manage {@link Disposable} objects which are still
62
 * bound.
63 41258 jjdelcerro
 *
64 40435 jjdelcerro
 * TODO: remove this extension and replace with a better one, maybe based on
65
 * scripting.
66 41258 jjdelcerro
 *
67 40435 jjdelcerro
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
68
 */
69
public class DisposableManagementExtension extends Extension {
70
71 41258 jjdelcerro
    public static String SHOW_COMMAND = "tools-devel-disposables-show-pendings";
72
    public static String DISPOSE_ALL_COMMAND = "tools-devel-disposables-free-all";
73 40435 jjdelcerro
74 41258 jjdelcerro
    private static final Logger LOG
75
            = LoggerFactory.getLogger(DisposableManagementExtension.class);
76 40435 jjdelcerro
77 45707 jjdelcerro
    @Override
78 41258 jjdelcerro
    public void initialize() {
79
        // Nothing to do
80
    }
81 40435 jjdelcerro
82 41258 jjdelcerro
    @Override
83
    public void postInitialize() {
84
        super.postInitialize();
85
    }
86 40435 jjdelcerro
87 45707 jjdelcerro
    @Override
88 41258 jjdelcerro
    public void execute(String actionCommand) {
89 40435 jjdelcerro
90 41258 jjdelcerro
        if (DISPOSE_ALL_COMMAND.equals(actionCommand)) {
91
            disposeAll();
92
        } else {
93
            if (SHOW_COMMAND.equals(actionCommand)) {
94
                DisposablesDoList panel = new DisposablesDoList();
95
                panel.showPanel();
96
            }
97
        }
98
    }
99 40435 jjdelcerro
100 41258 jjdelcerro
    private void disposeAll() {
101
        DisposableManager manager;
102
        manager = ToolsLocator.getDisposableManager();
103
        try {
104
            manager.releaseAll();
105
        } catch (BaseException ex) {
106
            LOG.error("Error disposing all bound disposable objects", ex);
107
        }
108
    }
109 40435 jjdelcerro
110 45707 jjdelcerro
    @Override
111 41258 jjdelcerro
    public boolean isEnabled() {
112
        return true;
113
    }
114 40435 jjdelcerro
115 45707 jjdelcerro
    @Override
116 41258 jjdelcerro
    public boolean isVisible() {
117
        return true;
118
    }
119 41043 jjdelcerro
120 41258 jjdelcerro
    class DisposablesDoList extends DisposablesDoListLayout {
121 41043 jjdelcerro
122 41258 jjdelcerro
        private DisposableManager manager;
123 45707 jjdelcerro
        private JTable disposablesTable = null;
124 41258 jjdelcerro
        private JTextPane infoTextArea = null;
125
126
        public DisposablesDoList() {
127
            manager = ToolsLocator.getDisposableManager();
128
            initComponents();
129 45707 jjdelcerro
            SwingUtilities.invokeLater(() -> {
130
                refreshList();
131
                updateMemoryUsage();
132 41258 jjdelcerro
            });
133
        }
134
135
        private void initComponents() {
136 45729 jjdelcerro
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
137
138 41258 jjdelcerro
            this.setPreferredSize(new Dimension(600, 550));
139 45707 jjdelcerro
140
            this.disposablesTable = new JTable(new DisposablesTableModel());
141 45714 fdiaz
            this.disposablesTable.setAutoCreateColumnsFromModel(false);
142 45707 jjdelcerro
143 45714 fdiaz
            DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
144
            columnModel.addColumn(createTableColumn(0, ToolsSwingUtils.cols2px(5), "refs"));
145
            columnModel.addColumn(createTableColumn(1, ToolsSwingUtils.cols2px(12), "class"));
146
            columnModel.addColumn(createTableColumn(2, ToolsSwingUtils.cols2px(10), "code"));
147
            columnModel.addColumn(createTableColumn(3, ToolsSwingUtils.cols2px(12), "fullClass"));
148
            columnModel.addColumn(createTableColumn(4, ToolsSwingUtils.cols2px(25), "toString"));
149
            this.disposablesTable.setColumnModel(columnModel);
150 45707 jjdelcerro
151 45714 fdiaz
            this.disposablesTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
152 46503 fdiaz
//            ToolsSwingUtils.ensureRows(this.disposablesTable, 10);
153 45729 jjdelcerro
154 41258 jjdelcerro
            this.infoTextArea = new JTextPane();
155
            this.infoTextArea.setContentType("text/html");
156 45729 jjdelcerro
            toolsSwingManager.setDefaultPopupMenu(
157
                    this.infoTextArea,
158
                    "Disposable information"
159
            );
160 45716 fdiaz
161 45707 jjdelcerro
            JScrollPane listScroller = new JScrollPane(this.disposablesTable);
162 41258 jjdelcerro
            JScrollPane infoScroller = new JScrollPane(this.infoTextArea);
163
            this.splitPanel.setLeftComponent(listScroller);
164
            this.splitPanel.setRightComponent(infoScroller);
165 45729 jjdelcerro
            this.splitPanel.setDividerLocation(0.3);
166 41258 jjdelcerro
167 45707 jjdelcerro
            this.closeButton.addActionListener((ActionEvent arg0) -> {
168
                closeWindow();
169 41258 jjdelcerro
            });
170
            this.closeButton.setEnabled(true);
171 45707 jjdelcerro
            this.disposeAllButton.addActionListener((ActionEvent e) -> {
172
                disposeAll();
173
                refreshList();
174
                updateMemoryUsage();
175 41258 jjdelcerro
            });
176
            this.disposeAllButton.setEnabled(true);
177 45707 jjdelcerro
            this.disposeButton.addActionListener((ActionEvent e) -> {
178
                disposeSelecteds();
179
                refreshList();
180
                updateMemoryUsage();
181 41258 jjdelcerro
            });
182
            this.disposeButton.setEnabled(true);
183 45707 jjdelcerro
            this.disposablesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent arg0) -> {
184
                ListItemSelected();
185
                updateMemoryUsage();
186 41258 jjdelcerro
            });
187 45707 jjdelcerro
            this.disposablesTable.setEnabled(true);
188
            this.refreshButton.addActionListener((ActionEvent arg0) -> {
189
                refreshList();
190
                updateMemoryUsage();
191 41258 jjdelcerro
            });
192
            this.refreshButton.setEnabled(true);
193
        }
194 45716 fdiaz
195 45714 fdiaz
        private TableColumn createTableColumn(int col, int size, String name) {
196
            TableColumn tableColumn = new TableColumn(col, size);
197
            tableColumn.setHeaderValue(name);
198
            return tableColumn;
199
        }
200 41258 jjdelcerro
201
        private void refreshList() {
202 45707 jjdelcerro
            fillTable();
203 41258 jjdelcerro
        }
204
205
        private void ListItemSelected() {
206 45707 jjdelcerro
            DisposablesTableModel model = (DisposablesTableModel) this.disposablesTable.getModel();
207
            DisposableInfo info = model.get(this.disposablesTable.getSelectedRow());
208 45716 fdiaz
            if (info == null) {
209 41258 jjdelcerro
                this.infoTextArea.setText("");
210
            } else {
211 45707 jjdelcerro
                this.infoTextArea.setText(toHTML(info));
212 41258 jjdelcerro
                this.infoTextArea.setCaretPosition(0);
213
            }
214
        }
215
216 45707 jjdelcerro
        private void fillTable() {
217
            Set<DisposableInfo> disposables = (Set<DisposableInfo>) manager.getBoundDisposables();
218
            this.messageLabel.setText("Disposables " + disposables.size());
219 41258 jjdelcerro
220 45714 fdiaz
            this.disposablesTable.setModel(new DisposablesTableModel(new ArrayList<>(disposables)));
221
            this.messageLabel.setText("Pending " + disposables.size());
222 41258 jjdelcerro
            this.infoTextArea.setText("");
223
        }
224 45716 fdiaz
225 45707 jjdelcerro
        private void updateMemoryUsage() {
226
            Runtime rt = Runtime.getRuntime();
227 45716 fdiaz
            this.lblTotalMemory.setText(String.valueOf(rt.totalMemory() / 1024));
228
            this.lblMaxMemory.setText(String.valueOf(rt.maxMemory() / 1024));
229
            this.lblFreeMemory.setText(String.valueOf(rt.freeMemory() / 1024));
230 45707 jjdelcerro
            this.lblActiveThreads.setText(String.valueOf(Thread.activeCount()));
231 45716 fdiaz
232 45707 jjdelcerro
            int objectPendingFinalizationCount = -1;
233
            try {
234 45716 fdiaz
                MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
235 45707 jjdelcerro
                objectPendingFinalizationCount = memBean.getObjectPendingFinalizationCount();
236 45716 fdiaz
            } catch (ThreadDeath th) {
237
238 45707 jjdelcerro
            }
239
            this.lblObjectPendingFinalization.setText(String.valueOf(objectPendingFinalizationCount));
240
        }
241 41258 jjdelcerro
242 45707 jjdelcerro
        private class DisposablesTableModel extends AbstractTableModel {
243 41258 jjdelcerro
244 45716 fdiaz
            private List<DisposableInfo> disposables;
245 45707 jjdelcerro
            private final String[] columnNames;
246
            private final Class[] columnClass;
247 45716 fdiaz
248 45707 jjdelcerro
            public DisposablesTableModel() {
249
                this(Collections.EMPTY_LIST);
250
            }
251 45716 fdiaz
252 45707 jjdelcerro
            public DisposablesTableModel(List<DisposableInfo> disposables) {
253
                this.disposables = disposables;
254 45716 fdiaz
                this.columnNames = new String[]{"Refs.", "Class", "Code", "Full class", "To str."};
255 45729 jjdelcerro
                this.columnClass = new Class[]{Integer.class, String.class, String.class, String.class, String.class};
256 45707 jjdelcerro
            }
257 45716 fdiaz
258 45707 jjdelcerro
            public DisposableInfo get(int rowIndex) {
259
                try {
260
                    return this.disposables.get(rowIndex);
261 45716 fdiaz
                } catch (Throwable th) {
262 45707 jjdelcerro
                    return null;
263
                }
264
            }
265 45716 fdiaz
266 45707 jjdelcerro
            @Override
267
            public int getRowCount() {
268
                return this.disposables.size();
269
            }
270 41258 jjdelcerro
271 45707 jjdelcerro
            @Override
272
            public int getColumnCount() {
273
                return this.columnNames.length;
274 41258 jjdelcerro
            }
275
276 45707 jjdelcerro
            @Override
277
            public String getColumnName(int columnIndex) {
278
                return this.columnNames[columnIndex];
279 41258 jjdelcerro
            }
280
281 45707 jjdelcerro
            @Override
282
            public Class<?> getColumnClass(int columnIndex) {
283
                return this.columnClass[columnIndex];
284 41258 jjdelcerro
            }
285
286 45707 jjdelcerro
            @Override
287
            public Object getValueAt(int rowIndex, int columnIndex) {
288
                DisposableInfo info = this.disposables.get(rowIndex);
289 45716 fdiaz
                switch (columnIndex) {
290 45707 jjdelcerro
                    case 0:
291
                        return info.getReferencesCount();
292
                    case 1:
293
                        try {
294 45729 jjdelcerro
                            return info.getDisposable().getClass().getSimpleName();
295
                        } catch (Throwable th) {
296
                            return "(unknown)";
297
                        }
298 45707 jjdelcerro
                    case 2:
299
                        try {
300 45729 jjdelcerro
                            return String.format("%x",info.getDisposable().hashCode());
301
                        } catch (Throwable th) {
302
                            return -1;
303
                        }
304 45714 fdiaz
                    case 3:
305
                        try {
306 45729 jjdelcerro
                            return info.getDisposable().getClass().getName();
307
                        } catch (Throwable th) {
308
                            return "(unknown)";
309
                        }
310 45714 fdiaz
                    case 4:
311 45707 jjdelcerro
                        try {
312 45729 jjdelcerro
                            return info.getDisposable().toString();
313
                        } catch (Throwable th) {
314
                            return "(unknown)";
315
                        }
316 41258 jjdelcerro
                }
317 45707 jjdelcerro
                return null;
318 41258 jjdelcerro
            }
319 45707 jjdelcerro
        }
320 41258 jjdelcerro
321 45716 fdiaz
        public String toHTML(DisposableInfo disposableInfo) {
322 45707 jjdelcerro
            StringBuilder buffer = new StringBuilder();
323
            Disposable disposable = disposableInfo.getDisposable();
324 45729 jjdelcerro
            int code = disposable.hashCode();
325 41258 jjdelcerro
326 45707 jjdelcerro
            buffer.append("<b>Class</b>: ").append(disposable.getClass().getSimpleName()).append("<br>\n");
327
            buffer.append("<b>Full class</b>: ").append(disposable.getClass().getName()).append("<br>\n");
328
            buffer.append("<b>References</b>: ").append(disposableInfo.getReferencesCount()).append("<br>\n");
329 45729 jjdelcerro
            buffer.append(String.format("<b>Code</b>: %x (%d)<br>\n", code,code));
330 45707 jjdelcerro
            buffer.append("<b>toString</b>: ").append(disposable.toString()).append("<br>\n");
331 41258 jjdelcerro
332 45707 jjdelcerro
            try {
333 45716 fdiaz
                List<LabeledValue<StackTraceElement[]>> allStackTraces = disposableInfo.getAllStackTrace();
334
                for (int i = 0; i < allStackTraces.size(); i++) {
335
                    LabeledValue<StackTraceElement[]> trace = allStackTraces.get(i);
336
                    buffer.append("<b>#");
337
                    buffer.append(i + 1);
338
                    buffer.append(" ");
339
                    buffer.append(trace.getLabel());
340
                    buffer.append(" from (stack)</b>:<br>\n");
341
                    for (StackTraceElement stackTrace1 : trace.getValue()) {
342 45714 fdiaz
                        buffer.append("&nbsp;&nbsp;").append(stackTrace1.toString().replaceAll("[<]", "&lt;").replace("[>]", "&gt;")).append("<br>\n");
343
                    }
344
                }
345 45716 fdiaz
346 45707 jjdelcerro
            } catch (Exception ex) {
347
                buffer.append("<br>\n<br>\nError showing stack.<br>\n").append(ex.getMessage());
348 41258 jjdelcerro
            }
349 45707 jjdelcerro
            return buffer.toString();
350 41258 jjdelcerro
        }
351
352
        public void closeWindow() {
353
            this.setVisible(false);
354
        }
355
356
        public void disposeAll() {
357
            try {
358
                manager.releaseAll();
359
            } catch (BaseException ex) {
360
                LOG.error("Error disposing all bound disposable objects", ex);
361
            }
362
        }
363
364
        public void disposeSelecteds() {
365 45707 jjdelcerro
            DisposablesTableModel model = (DisposablesTableModel) this.disposablesTable.getModel();
366
            for (int row : this.disposablesTable.getSelectedRows()) {
367
                DisposableInfo info = model.get(row);
368
                this.manager.release(info.getDisposable());
369 41258 jjdelcerro
            }
370
            refreshList();
371
        }
372
373
        public void showPanel() {
374
            WindowManager wm = ToolsSwingLocator.getWindowManager();
375
            wm.showWindow(this, "Disposable do list", WindowManager.MODE.WINDOW);
376
        }
377 45707 jjdelcerro
378
//        private class ActionListenerImpl implements ActionListener {
379
//
380
//            public ActionListenerImpl() {
381
//            }
382
//
383
//            @Override
384
//            public void actionPerformed(ActionEvent e) {
385
//                disposeSelecteds();
386
//                refreshList();
387
//                updateMemoryUsage();
388
//            }
389
//        }
390 41258 jjdelcerro
    }
391
392
}