001/*****************************************************************************
002 * Copyright by The HDF Group.                                               *
003 * Copyright by the Board of Trustees of the University of Illinois.         *
004 * All rights reserved.                                                      *
005 *                                                                           *
006 * This file is part of the HDF Java Products distribution.                  *
007 * The full copyright notice, including terms governing use, modification,   *
008 * and redistribution, is contained in the files COPYING and Copyright.html. *
009 * COPYING can be found at the root of the source code distribution tree.    *
010 * Or, see https://support.hdfgroup.org/products/licenses.html               *
011 * If you do not have access to either file, you may request a copy from     *
012 * help@hdfgroup.org.                                                        *
013 ****************************************************************************/
014
015package hdf.view.MetaDataView;
016
017import java.lang.reflect.Array;
018
019import org.eclipse.swt.SWT;
020import org.eclipse.swt.events.SelectionAdapter;
021import org.eclipse.swt.events.SelectionEvent;
022import org.eclipse.swt.layout.FillLayout;
023import org.eclipse.swt.layout.GridData;
024import org.eclipse.swt.layout.GridLayout;
025import org.eclipse.swt.widgets.Button;
026import org.eclipse.swt.widgets.Composite;
027import org.eclipse.swt.widgets.Label;
028import org.eclipse.swt.widgets.Table;
029import org.eclipse.swt.widgets.TableColumn;
030import org.eclipse.swt.widgets.TableItem;
031import org.eclipse.swt.widgets.Text;
032
033import hdf.object.CompoundDS;
034import hdf.object.Dataset;
035import hdf.object.Datatype;
036import hdf.object.HObject;
037import hdf.object.ScalarDS;
038import hdf.view.Tools;
039import hdf.view.DataView.DataViewManager;
040
041/**
042 *
043 * The metadata view interface for displaying dataset metadata information
044 */
045public class DefaultDatasetMetaDataView extends DefaultLinkMetaDataView implements MetaDataView {
046
047    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultDatasetMetaDataView.class);
048
049    /**
050     *The metadata view interface for displaying dataset metadata information
051     *
052     * @param parentComposite
053     *        the parent visual object
054     * @param viewer
055     *        the viewer to use
056     * @param theObj
057     *        the object to display the metadata info
058     */
059    public DefaultDatasetMetaDataView(Composite parentComposite, DataViewManager viewer, HObject theObj) {
060        super(parentComposite, viewer, theObj);
061    }
062
063    @Override
064    protected void addObjectSpecificContent() {
065
066        super.addObjectSpecificContent();
067
068        String labelInfo;
069        Label label;
070        Text text;
071
072        Dataset d = (Dataset) dataObject;
073        if (!d.isInited()) {
074            d.init();
075        }
076
077        org.eclipse.swt.widgets.Group datasetInfoGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
078        datasetInfoGroup.setFont(curFont);
079        datasetInfoGroup.setText("Dataset Dataspace and Datatype");
080        datasetInfoGroup.setLayout(new GridLayout(2, false));
081        datasetInfoGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
082
083        /* Dataset Rank section */
084        label = new Label(datasetInfoGroup, SWT.LEFT);
085        label.setFont(curFont);
086        label.setText("No. of Dimension(s): ");
087
088        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
089        text.setEditable(false);
090        text.setFont(curFont);
091        if (d.isScalar()) {
092            labelInfo = "Scalar";
093        }
094        else {
095            labelInfo = "" + d.getRank();
096        }
097        text.setText(labelInfo);
098        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
099
100        if (!d.isScalar()) {
101            /* Dataset dimension size section */
102            label = new Label(datasetInfoGroup, SWT.LEFT);
103            label.setFont(curFont);
104            label.setText("Dimension Size(s): ");
105
106            // Set Dimension Size
107            String dimStr = null;
108            String maxDimStr = null;
109            long dims[] = d.getDims();
110            long maxDims[] = d.getMaxDims();
111            if (dims != null) {
112                String[] dimNames = d.getDimNames();
113                boolean hasDimNames = ((dimNames != null) && (dimNames.length == dims.length));
114                StringBuilder sb = new StringBuilder();
115                StringBuilder sb2 = new StringBuilder();
116
117                sb.append(dims[0]);
118                if (hasDimNames) {
119                    sb.append(" (").append(dimNames[0]).append(")");
120                }
121
122                if (maxDims[0] < 0)
123                    sb2.append("Unlimited");
124                else
125                    sb2.append(maxDims[0]);
126
127                for (int i = 1; i < dims.length; i++) {
128                    sb.append(" x ");
129                    sb.append(dims[i]);
130                    if (hasDimNames) {
131                        sb.append(" (").append(dimNames[i]).append(")");
132                    }
133
134                    sb2.append(" x ");
135                    if (maxDims[i] < 0)
136                        sb2.append("Unlimited");
137                    else
138                        sb2.append(maxDims[i]);
139
140                }
141                dimStr = sb.toString();
142                maxDimStr = sb2.toString();
143            }
144
145            text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
146            text.setEditable(false);
147            text.setFont(curFont);
148            text.setText((dimStr == null) ? "null" : dimStr);
149            text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
150
151            label = new Label(datasetInfoGroup, SWT.LEFT);
152            label.setFont(curFont);
153            label.setText("Max Dimension Size(s): ");
154
155            text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
156            text.setEditable(false);
157            text.setFont(curFont);
158            text.setText((maxDimStr == null) ? "null" : maxDimStr);
159            text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
160        }
161
162        /* Dataset datatype section */
163        label = new Label(datasetInfoGroup, SWT.LEFT);
164        label.setFont(curFont);
165        label.setText("Data Type: ");
166
167        Datatype t = d.getDatatype();
168        String type = (t == null) ? "null" : t.getDescription();
169        if (d instanceof CompoundDS) {
170            if (isH4) {
171                type = "Vdata";
172            }
173            else {
174                /*
175                 * For Compounds, Arrays of Compounds, Vlens of Compounds, etc. we want to show
176                 * the fully-qualified type, minus the compound members, since we already show
177                 * the Compound datatype's members in a table.
178                 */
179                int bracketIndex = type.indexOf('{');
180                int lastBracketIndex = type.lastIndexOf('}');
181                if (bracketIndex >= 0 && lastBracketIndex >= 0) {
182                    type = type.replace(type.substring(bracketIndex, lastBracketIndex + 1), "");
183                }
184            }
185        }
186
187        text = new Text(datasetInfoGroup, SWT.SINGLE | SWT.BORDER);
188        text.setEditable(false);
189        text.setFont(curFont);
190        text.setText(type);
191        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
192
193        /* Add a dummy label to take up some vertical space between sections */
194        label = new Label(generalObjectInfoPane, SWT.LEFT);
195        label.setText("");
196        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
197
198        /*
199         * Dataset storage layout, compression, filters, storage type, fill value, etc.
200         * section
201         */
202        org.eclipse.swt.widgets.Group datasetLayoutGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
203        datasetLayoutGroup.setFont(curFont);
204        datasetLayoutGroup.setText("Miscellaneous Dataset Information");
205        datasetLayoutGroup.setLayout(new GridLayout(2, false));
206        datasetLayoutGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
207
208        /* Dataset Storage Layout section */
209        label = new Label(datasetLayoutGroup, SWT.LEFT);
210        label.setFont(curFont);
211        label.setText("Storage Layout: ");
212
213        label = new Label(datasetLayoutGroup, SWT.RIGHT);
214        label.setFont(curFont);
215        labelInfo = d.getStorageLayout();
216        if (labelInfo == null) labelInfo = "UNKNOWN";
217        label.setText(labelInfo);
218
219        /* Dataset Compression section */
220        label = new Label(datasetLayoutGroup, SWT.LEFT);
221        label.setFont(curFont);
222        label.setText("Compression: ");
223
224        label = new Label(datasetLayoutGroup, SWT.RIGHT);
225        label.setFont(curFont);
226        labelInfo = d.getCompression();
227        if (labelInfo == null) labelInfo = "UNKNOWN";
228        label.setText(labelInfo);
229
230        /* Dataset filters section */
231        label = new Label(datasetLayoutGroup, SWT.LEFT);
232        label.setFont(curFont);
233        label.setText("Filters: ");
234
235        label = new Label(datasetLayoutGroup, SWT.RIGHT);
236        label.setFont(curFont);
237        labelInfo = d.getFilters();
238        if (labelInfo == null) labelInfo = "UNKNOWN";
239        label.setText(labelInfo);
240
241        /* Dataset extra storage information section */
242        label = new Label(datasetLayoutGroup, SWT.LEFT);
243        label.setFont(curFont);
244        label.setText("Storage: ");
245
246        label = new Label(datasetLayoutGroup, SWT.RIGHT);
247        label.setFont(curFont);
248        labelInfo = d.getStorage();
249        if (labelInfo == null) labelInfo = "UNKNOWN";
250        label.setText(labelInfo);
251
252        /* Dataset fill value info section */
253        label = new Label(datasetLayoutGroup, SWT.LEFT);
254        label.setFont(curFont);
255        label.setText("Fill value: ");
256
257        Object fillValue = null;
258        String fillValueInfo = "NONE";
259        if (d instanceof ScalarDS) fillValue = ((ScalarDS) d).getFillValue();
260        if (fillValue != null) {
261            if (fillValue.getClass().isArray()) {
262                int len = Array.getLength(fillValue);
263                fillValueInfo = Array.get(fillValue, 0).toString();
264                for (int i = 1; i < len; i++) {
265                    fillValueInfo += ", ";
266                    fillValueInfo += Array.get(fillValue, i).toString();
267                }
268            }
269            else
270                fillValueInfo = fillValue.toString();
271        }
272
273        label = new Label(datasetLayoutGroup, SWT.RIGHT);
274        label.setFont(curFont);
275        label.setText(fillValueInfo);
276
277        /* Button to open Data Option dialog */
278        Button showDataOptionButton = new Button(datasetInfoGroup, SWT.PUSH);
279        showDataOptionButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false, 2, 1));
280        showDataOptionButton.setText("Show Data with Options");
281        showDataOptionButton.addSelectionListener(new SelectionAdapter() {
282            @Override
283            public void widgetSelected(SelectionEvent e) {
284                try {
285                    viewManager.getTreeView().setDefaultDisplayMode(false);
286                    viewManager.getTreeView().showDataContent(dataObject);
287                }
288                catch (Exception ex) {
289                    display.beep();
290                    Tools.showError(display.getShells()[0], "Select", ex.getMessage());
291                }
292            }
293        });
294
295        /*
296         * If this is a Compound Dataset, add a table which displays all of the members
297         * in the Compound Datatype.
298         */
299        if (d instanceof CompoundDS) {
300            log.trace("addObjectSpecificContent(): add member table for Compound Datatype Dataset");
301
302            CompoundDS compound = (CompoundDS) d;
303
304            int n = compound.getMemberCount();
305            log.trace("addObjectSpecificContent(): number of compound members={}", n);
306
307            // Add a dummy label to take up some vertical space between sections
308            label = new Label(generalObjectInfoPane, SWT.LEFT);
309            label.setText("");
310            label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
311
312            org.eclipse.swt.widgets.Group compoundMembersGroup = new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
313            compoundMembersGroup.setFont(curFont);
314            compoundMembersGroup.setText("Compound Dataset Members");
315            compoundMembersGroup.setLayout(new FillLayout(SWT.VERTICAL));
316            compoundMembersGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
317
318            Table memberTable = new Table(compoundMembersGroup, SWT.BORDER);
319            memberTable.setLinesVisible(true);
320            memberTable.setHeaderVisible(true);
321            memberTable.setFont(curFont);
322
323            String[] columnNames = { "Name", "Type", "Array Size" };
324
325            for (int i = 0; i < columnNames.length; i++) {
326                TableColumn column = new TableColumn(memberTable, SWT.NONE);
327                column.setText(columnNames[i]);
328                column.setMoveable(false);
329            }
330
331            if (n > 0) {
332                String rowData[][] = new String[n][3];
333                final String names[] = compound.getMemberNames();
334                Datatype types[] = compound.getMemberTypes();
335                int orders[] = compound.getMemberOrders();
336
337                for (int i = 0; i < n; i++) {
338                    rowData[i][0] = new String(names[i]);
339
340                    if (rowData[i][0].contains(CompoundDS.SEPARATOR)) {
341                        rowData[i][0] = rowData[i][0].replaceAll(CompoundDS.SEPARATOR, "->");
342                    }
343
344                    int mDims[] = compound.getMemberDims(i);
345                    if (mDims == null) {
346                        rowData[i][2] = String.valueOf(orders[i]);
347
348                        if (isH4 && types[i].isString()) {
349                            rowData[i][2] = String.valueOf(types[i].getDatatypeSize());
350                        }
351                    }
352                    else {
353                        String mStr = String.valueOf(mDims[0]);
354                        int m = mDims.length;
355                        for (int j = 1; j < m; j++) {
356                            mStr += " x " + mDims[j];
357                        }
358                        rowData[i][2] = mStr;
359                    }
360                    rowData[i][1] = (types[i] == null) ? "null" : types[i].getDescription();
361                }
362
363                for (int i = 0; i < rowData.length; i++) {
364                    TableItem item = new TableItem(memberTable, SWT.NONE);
365                    item.setFont(curFont);
366                    item.setText(0, rowData[i][0]);
367                    item.setText(1, rowData[i][1]);
368                    item.setText(2, rowData[i][2]);
369                }
370
371                for (int i = 0; i < columnNames.length; i++) {
372                    memberTable.getColumn(i).pack();
373                }
374
375                // set cell height for large fonts
376                // int cellRowHeight = Math.max(16,
377                // table.getFontMetrics(table.getFont()).getHeight());
378                // table.setRowHeight(cellRowHeight);
379            } //  (n > 0)
380
381            // Prevent conflict from equal vertical grabbing
382            datasetLayoutGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
383        }
384    }
385
386}