Java tutorial
// 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); } }