com.archivas.clienttools.arcmover.gui.properties.ObjectPropertiesDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.archivas.clienttools.arcmover.gui.properties.ObjectPropertiesDialog.java

Source

// Copyright 2007 Hitachi Data Systems
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package com.archivas.clienttools.arcmover.gui.properties;

import com.archivas.clienttools.arcmover.gui.HCPDataMigrator;
import com.archivas.clienttools.arcmover.gui.util.GUIHelper;
import com.archivas.clienttools.arcutils.api.ArcMoverEngine;
import com.archivas.clienttools.arcutils.api.JobException;
import com.archivas.clienttools.arcutils.impl.adapter.StorageAdapterException;
import com.archivas.clienttools.arcutils.profile.AbstractProfileBase;
import com.archivas.clienttools.arcutils.model.*;
import com.archivas.clienttools.arcutils.utils.StringUtils;
import com.archivas.clienttools.arcutils.utils.XMLValidator;
import com.archivas.clienttools.arcutils.utils.database.DatabaseDataType;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ObjectPropertiesDialog extends JDialog {
    // logging
    private static final Logger LOG = Logger.getLogger(ObjectPropertiesDialog.class.getName());
    private static final DecimalFormat decimalFormat = new DecimalFormat("0.00");

    private JPanel contentPane;
    private JButton closeButton;
    private JTable systemMetadataTable;
    private JTabbedPane propertiesTabs;
    private JTextPane customMetadataText;
    private JScrollPane cMetadataTab;
    private JButton saveButton;
    protected JScrollPane sMetadataTab;
    private ArcMoverEngine engine;
    private AbstractProfileBase profile;
    private ArcMoverFile currentFile;
    private JTextPane aclText;
    private JScrollPane cACLTab;

    private boolean hasCustomMetadata;
    private String savedCustomMetadata;
    private boolean hasACL = false;
    private String savedACL;

    private ObjectPropertiesDialog() {
    }

    @Override
    public void setVisible(final boolean b) {
        super.setVisible(b);
    }

    public ObjectPropertiesDialog(AbstractProfileBase profile, ArcMoverFile file, ArcMoverEngine engine)
            throws StorageAdapterException {
        super(HCPDataMigrator.getInstance());
        setContentPane(contentPane);
        setModal(true);
        getRootPane().setDefaultButton(closeButton);
        setTitle(file.getDisplayFileName() + " Properties");

        closeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        });

        // call onCancel() when cross is clicked
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        // call onCancel() on ESCAPE
        contentPane.registerKeyboardAction(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        saveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onSave();
            }
        });

        this.setMinimumSize(new Dimension(550, 350));
        this.profile = profile;

        populate(file, engine);
    }

    private void onCancel() {
        String typeString = null;
        if (customMetadataEdited() && aclEdited()) {
            typeString = "metadata";
        } else if (customMetadataEdited()) {
            typeString = "custom metadata";
        } else if (aclEdited()) {
            typeString = "acl";
        }

        if (typeString != null) {
            int changeMetadata = JOptionPane.showConfirmDialog(this, String.format(
                    "The %s has been edited and not yet saved.\nAre you sure you want to close without saving?",
                    typeString), "", JOptionPane.YES_NO_OPTION);

            if (changeMetadata == JOptionPane.YES_OPTION) {
                dispose();
            }
        } else {
            dispose();
        }
    }

    {
        // GUI initializer generated by IntelliJ IDEA GUI Designer
        // >>> IMPORTANT!! <<<
        // DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer >>> IMPORTANT!! <<< DO NOT edit this method OR
     * call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        contentPane = new JPanel();
        contentPane.setLayout(new FormLayout("left:4dlu:noGrow,left:250dlu:grow,left:5dlu:noGrow",
                "center:4dlu:noGrow,center:150dlu:grow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow"));
        propertiesTabs = new JTabbedPane();
        propertiesTabs.setToolTipText("Core Metadata");
        CellConstraints cc = new CellConstraints();
        contentPane.add(propertiesTabs, cc.xy(2, 2, CellConstraints.FILL, CellConstraints.FILL));
        sMetadataTab = new JScrollPane();
        sMetadataTab.setToolTipText("Filesystem Metadata");
        propertiesTabs.addTab("System Metadata", sMetadataTab);
        sMetadataTab.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), null));
        systemMetadataTable = new JTable();
        systemMetadataTable.setCellSelectionEnabled(true);
        systemMetadataTable.setFillsViewportHeight(true);
        sMetadataTab.setViewportView(systemMetadataTable);
        cMetadataTab = new JScrollPane();
        cMetadataTab.setToolTipText("Custom Metadata");
        propertiesTabs.addTab("Custom Metadata", cMetadataTab);
        cMetadataTab.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), null));
        customMetadataText = new JTextPane();
        customMetadataText.setEditable(true);
        customMetadataText.putClientProperty("JEditorPane.honorDisplayProperties", Boolean.TRUE);
        cMetadataTab.setViewportView(customMetadataText);
        cACLTab = new JScrollPane();
        cACLTab.setToolTipText("ACL");
        propertiesTabs.addTab("ACL", cACLTab);
        cACLTab.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), null));
        aclText = new JTextPane();
        aclText.setEditable(true);
        aclText.putClientProperty("JEditorPane.honorDisplayProperties", Boolean.TRUE);
        cACLTab.setViewportView(aclText);
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new FormLayout(
                "fill:50dlu:noGrow,left:4dlu:noGrow,fill:max(d;4px):grow,left:4dlu:noGrow,fill:50dlu:noGrow",
                "center:15dlu:noGrow"));
        contentPane.add(panel1, cc.xy(2, 4, CellConstraints.FILL, CellConstraints.DEFAULT));
        closeButton = new JButton();
        closeButton.setHorizontalAlignment(0);
        closeButton.setText("Close");
        panel1.add(closeButton, cc.xy(5, 1, CellConstraints.FILL, CellConstraints.FILL));
        saveButton = new JButton();
        saveButton.setText("Save");
        panel1.add(saveButton, cc.xy(1, 1));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return contentPane;
    }

    private class SystemTableModel extends AbstractTableModel {
        List<String> keys = new ArrayList<String>();
        List<Object> values = new ArrayList<Object>();

        private SystemTableModel(ArcMoverFile file) throws StorageAdapterException {
            keys.add("Name");
            values.add(file.getDisplayFileName());

            keys.add("Path");
            values.add(file.getDisplayPath());

            keys.add("Type");
            values.add(file.getFileType().getDisplay());

            String symlinkTarget = file.getDisplaySymlinkTarget();
            if (symlinkTarget != null) {
                keys.add("Symlink Target");
                values.add(symlinkTarget);
            }

            if (file.isFile()) {
                keys.add("Size");
                values.add(StringUtils.bytesToStringWithUnit(file.getSize(), decimalFormat));
            }

            if (file.getMetadata().hasCreationTime()) {
                keys.add("Ingested Time");
                values.add(file.getMetadata().getCreationTime());
            }

            if (file.getMetadata().hasDpl()) {
                keys.add("DPL");
                values.add(file.getMetadata().getDpl());
            }

            if (file.getMetadata().hasHashScheme()) {
                keys.add("Hash Algorithm");
                values.add(file.getMetadata().getHashScheme());
            }

            if (file.getMetadata().hasHashValue()) {
                keys.add("Hash Value");
                values.add(file.getMetadata().getHashValue());
            }

            if (file.getMetadata().hasSearchIndex()) {
                keys.add("Index");
                values.add(file.getMetadata().isSearchIndex());
            }

            if (file.getMetadata().hasShred()) {
                keys.add("Shred");
                values.add(file.getMetadata().isShred());
            }

            if (file.getMetadata().hasRetention()) {
                Retention retention = file.getMetadata().getRetention();
                keys.add("Retention Value");
                if (retention.getType() == Retention.Type.FIXED_DATE) {
                    values.add(retention.getDate());
                } else {
                    values.add(retention.getUIValue());
                }

                // If we are a retention class type and there is an date of expiration set, display
                // it here
                if (retention.getType() == Retention.Type.RETENTION_CLASS && !retention.getClassName().equals("")) {
                    keys.add("Retention Class");
                    values.add(retention.getClassName());
                }
            }

            if (file.getMetadata().hasRetentionHold()) {
                keys.add("Hold");
                values.add(file.getMetadata().isRetentionHold());
            }

            if (file.getMetadata().hasCtime()) {
                keys.add("Changed Time (ctime)");
                values.add(file.getMetadata().getCtime());
            }

            if (file.getMetadata().hasModTime()) {
                keys.add("Modified Time (mtime)");
                values.add(file.getMetadata().getModTime());
            }

            if (file.getMetadata().hasAccessTime()) {
                keys.add("Accessed Time (atime)");
                values.add(file.getMetadata().getAccessTime());
            }

            if (file.getMetadata().hasUid()) {
                keys.add("UID");
                values.add(file.getMetadata().getUid());
            }

            if (file.getMetadata().hasGid()) {
                keys.add("GID");
                values.add(file.getMetadata().getGid());
            }

            if (file.getMetadata().hasFileMode()) {
                keys.add("Permissions");
                values.add(file.getMetadata().getFileModeForUnixLsDisplay());
            }

            if (file.getMetadata().hasDirMode()) {
                keys.add("Permissions");
                values.add(file.getMetadata().getDirModeForUnixLsDisplay());
            }

            if (file.getMetadata().hasVersionNumber()) {
                keys.add("Version");
                values.add(file.getMetadata().getVersionNumber());
            }

            if (file.getMetadata().hasReplicated()) {
                keys.add("Replicated");
                values.add(file.getMetadata().isReplicated());
            }

            if (file.getMetadata().hasRestState()) {
                keys.add("State");
                values.add(file.getMetadata().getRestState());
            }

            if (file.getMetadata().hasOwner()) {
                if (file.getMetadata().getOwner().getOwnerType().equals(Owner.OwnerType.LOCAL)) {
                    keys.add("Owner");
                    values.add(file.getProfile().decode(file.getMetadata().getOwner().getOwnerName()));
                } else if (file.getMetadata().getOwner().getOwnerType().equals(Owner.OwnerType.EXTERNAL)) {
                    keys.add("Owner");
                    values.add(file.getProfile().decode(file.getMetadata().getOwner().getOwnerName()));
                    keys.add("Domain");
                    values.add(file.getMetadata().getOwner().getDomain());
                }
            }

            if (file.getMetadata().hasAnnotations()) {
                keys.add("Annotations");
                StringBuilder annotations = new StringBuilder();
                for (String annotation : file.getMetadata().getAnnotationList().keySet()) {
                    if (annotations.length() < 1) {
                        annotations.append(annotation);
                    } else {
                        annotations.append(", " + annotation);
                    }
                }
                values.add(annotations.toString());
            }
        }

        public int getColumnCount() {
            return 2;
        }

        public int getRowCount() {
            return keys.size();
        }

        public String getColumnName(int columnIndex) {
            return columnIndex == 0 ? "Property" : "Value";
        }

        public Object getValueAt(int row, int col) {
            return col == 0 ? keys.get(row) : values.get(row);
        }
    }

    protected TableModel getSystemMetadataTableModel(final ArcMoverFile file) throws StorageAdapterException {
        return new SystemTableModel(file);
    }

    private void populate(final ArcMoverFile file, ArcMoverEngine engine) throws StorageAdapterException {
        final FileMetadata baseMetadata = file.getMetadata();

        LOG.finest("Loading ArcMoverFile=" + file.toDetailString());
        LOG.finest("Loading ArcMetadata=" + (baseMetadata == null ? "null" : baseMetadata.toString()));

        this.currentFile = file;
        this.engine = engine;

        TableModel systemMetadataModel = getSystemMetadataTableModel(file);

        systemMetadataTable.setModel(systemMetadataModel);
        GUIHelper.autoResizeColWidth(systemMetadataTable);
        saveButton.setEnabled(false);

        if (!file.isDirectory() && !file.isSymlink() && baseMetadata != null) {
            propertiesTabs.addTab("Custom Metadata", cMetadataTab);
            cMetadataTab.setVisible(true);

            String customMetadataTextValue = "";

            if (baseMetadata.hasDefaultCustomMetadata()) {
                try {
                    Long version = null;
                    if (file.isVersion()) {
                        version = baseMetadata.getVersionNumber();
                    }
                    customMetadataTextValue = file.getCustomMetadata().getStringValue(profile, version);
                } catch (Exception e) {
                    Throwable rootCause = null;
                    Throwable th = e;
                    while (th != null) {
                        rootCause = th;
                        th = th.getCause();
                        if (th != null) {
                            rootCause = th;
                        }
                    }
                    if (rootCause != null && rootCause instanceof CustomMetadataTooLargeException) {
                        customMetadataTextValue = "Custom metadata too large to display";
                    } else {
                        // noinspection ConstantConditions
                        LOG.log(Level.WARNING,
                                "Error getting custom metadata for " + file.getPath() + ": " + e.getMessage(), e);
                        customMetadataTextValue = "Error getting custom metadata";
                    }
                }
            }

            hasCustomMetadata = !customMetadataTextValue.isEmpty();
            customMetadataText.setText(customMetadataTextValue);
            savedCustomMetadata = customMetadataTextValue;

            customMetadataText.setEditable(!file.isVersion());
            customMetadataText.setOpaque(!file.isVersion());

            customMetadataText.getDocument().addDocumentListener(new DocumentListener() {
                public void changedUpdate(DocumentEvent e) {
                    updateButtonStates();
                }

                public void insertUpdate(DocumentEvent e) {
                    updateButtonStates();
                }

                public void removeUpdate(DocumentEvent e) {
                    updateButtonStates();
                }
            });
            if (file.isVersion()) {
                customMetadataText.setForeground(Color.GRAY);
            }

            if (profile.supportsACLs()) {
                propertiesTabs.addTab("ACL", cACLTab);
                cACLTab.setVisible(true);
                aclText.setEditable(true);
                aclText.setOpaque(true);

                String aclTextValue = "";
                // @todo get acl
                if (baseMetadata.hasACL()) {
                    try {
                        long unUsedVersion = 0;
                        aclTextValue = baseMetadata.getACL().getStringValue(profile, unUsedVersion);
                    } catch (JobException e) {
                        LOG.log(Level.WARNING, "Error getting acl for " + file.getPath() + ": " + e.getMessage(),
                                e);
                        aclTextValue = "Error getting acl";
                    }
                }
                hasACL = !aclTextValue.isEmpty();
                aclText.setText(aclTextValue);
                savedACL = aclTextValue;

                aclText.getDocument().addDocumentListener(new DocumentListener() {
                    public void changedUpdate(DocumentEvent e) {
                        updateButtonStates();
                    }

                    public void insertUpdate(DocumentEvent e) {
                        updateButtonStates();
                    }

                    public void removeUpdate(DocumentEvent e) {
                        updateButtonStates();
                    }
                });
            } else {
                cACLTab.setVisible(false);
                propertiesTabs.remove(cACLTab);
            }

            // Setting the selected component here and later prevents a painting problem
            propertiesTabs.setSelectedComponent(cMetadataTab);
        } else {
            cMetadataTab.setVisible(false);
            propertiesTabs.remove(cMetadataTab);
            cACLTab.setVisible(false);
            propertiesTabs.remove(cACLTab);
        }
        // Setting the selected component here and earlier prevents a painting problem
        propertiesTabs.setSelectedComponent(sMetadataTab);
    }

    private void updateButtonStates() {
        saveButton.setEnabled(!currentFile.isVersion() && (customMetadataEdited() || aclEdited()));
    }

    private boolean customMetadataEdited() {
        return savedCustomMetadata != null
                && !savedCustomMetadata.trim().equals(customMetadataText.getText().trim());
    }

    private boolean aclEdited() {
        return savedACL != null && !savedACL.trim().equals(aclText.getText().trim());
    }

    @SuppressWarnings({ "ConstantConditions" })
    private void onSave() {
        Boolean changingCM = null;
        try {
            if (profile != null) {
                String newCMetadataText = customMetadataText.getText().trim();
                boolean deletingCM = newCMetadataText.isEmpty();

                String newACLTextString = aclText.getText().trim();
                boolean deletingACL = newACLTextString.isEmpty();

                String typeString;
                String actionString;

                if (customMetadataEdited() && aclEdited()) {
                    typeString = "Metadata";
                } else if (aclEdited()) {
                    typeString = "ACL";
                } else if (customMetadataEdited()) {
                    typeString = "custom metadata";
                } else {
                    throw new IllegalStateException(
                            "Saving Object Properties when neither custom metadata nor acls have changed");
                }

                if (deletingACL && deletingCM) {
                    actionString = "Delete";
                } else {
                    actionString = "Modify";
                }

                int changeMetadata = JOptionPane.showConfirmDialog(this,
                        String.format("Are you sure you want to %s the %s?", actionString.toLowerCase(),
                                typeString.toLowerCase()),
                        String.format("%s %s", actionString, typeString), JOptionPane.YES_NO_OPTION);

                if (changeMetadata == JOptionPane.YES_OPTION) {
                    if (customMetadataEdited()) {
                        changingCM = true;
                        if (newCMetadataText.length() > DatabaseDataType.MAX_VARCHAR_SIZE) {
                            String msg = "XML string too long";
                            JOptionPane.showMessageDialog(this, msg, "Error", JOptionPane.ERROR_MESSAGE);
                        } else if (deletingCM) {
                            // Don't try to delete the metadata if there wasn't any there to begin
                            // with. Otherwise we get
                            // an error back from the cluster.
                            if (hasCustomMetadata) {
                                engine.deleteCustomMetadata(profile, currentFile.getPath());
                                hasCustomMetadata = false;
                                savedCustomMetadata = "";
                            }
                            HCPDataMigrator.getInstance().refreshMatchingPanels(profile, currentFile.getParent());
                        } else if (!profile.isValidateCustomMetadata() || XMLValidator.isValid(newCMetadataText)) {
                            engine.setCustomMetadata(profile, currentFile.getPath(), newCMetadataText);
                            hasCustomMetadata = true;
                            savedCustomMetadata = newCMetadataText;
                            HCPDataMigrator.getInstance().refreshMatchingPanels(profile, currentFile.getParent());
                        } else {
                            String msg = "Invalid XML in Custom Metadata";
                            JOptionPane.showMessageDialog(this, msg, "Error", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                    if (aclEdited()) {
                        changingCM = false;
                        if (deletingACL) {
                            // an error back from the cluster.
                            if (hasACL) {
                                engine.deleteACL(profile, currentFile.getPath());
                                hasACL = false;
                                savedACL = "";
                            }
                        } else if (XMLValidator.isValid(newACLTextString)) {
                            ACLMetadata acl = new ACLMetadata(StructuredMetadata.Form.STRING, newACLTextString);
                            engine.setACL(profile, currentFile.getPath(), acl);
                            hasACL = true;
                            savedACL = newACLTextString;
                            HCPDataMigrator.getInstance().refreshMatchingPanels(profile, currentFile.getParent());
                        } else {
                            String msg = "Invalid XML in ACL";
                            JOptionPane.showMessageDialog(this, msg, "Error", JOptionPane.ERROR_MESSAGE);

                        }
                    }
                }
            }
        } catch (JobException e) {
            String msg;
            Throwable cause = e.getCause();
            if (cause instanceof StorageAdapterException) {
                msg = cause.getMessage();
                if (msg.indexOf("403 ") == 0) {
                    if (changingCM != null && changingCM) {
                        // Changing custom metadata is not allowed. In this case, set the text back
                        // to what is saved on the server
                        customMetadataText.setText(savedCustomMetadata);
                    } else if (changingCM != null && !changingCM) {
                        aclText.setText(savedACL);
                    }
                }
            } else {
                msg = "Unexpected Error";
            }
            LOG.log(Level.WARNING, msg, e);
            GUIHelper.showMessageDialog(this, msg, "Error", JOptionPane.ERROR_MESSAGE);
        }
        updateButtonStates();
    }

    public static void main(String[] args) {
        ObjectPropertiesDialog dialog = new ObjectPropertiesDialog();
        dialog.pack();
        dialog.setVisible(true);
        System.exit(0);
    }

}