blob: b13be96274f0177063cdc5305e521587a24f8e7a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.xml.catalog;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JTree;
import javax.swing.text.DefaultEditorKit;
import org.netbeans.modules.xml.catalog.spi.CatalogWriter;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFilter;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Index;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
/**
*
* @author Pavel Buzek
*/
public class CatalogPanel extends TopComponent implements ExplorerManager.Provider {
private ExplorerManager manager;
private CatalogTreeView view;
private JTree tree;
static private Set newlyCreatedFolders;
static private FileObject catalogRoot;
/** Creates new form CatalogPanel */
public CatalogPanel() {
ActionMap map = getActionMap();
map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(getExplorerManager()));
map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(getExplorerManager()));
map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(getExplorerManager()));
map.put("delete", ExplorerUtils.actionDelete(getExplorerManager(), true)); // NOI18N
initComponents();
createCatalogView();
treePanel.add(view, BorderLayout.CENTER);
associateLookup(ExplorerUtils.createLookup(getExplorerManager(), map));
initialize();
}
public ExplorerManager getExplorerManager() {
if (manager == null) {
manager = new ExplorerManager();
}
return manager;
}
private void createCatalogView() {
if (view == null) {
view = new CatalogTreeView();
}
view.setRootVisible(true);
view.setPopupAllowed(true);
view.setDefaultActionAllowed(false);
}
private static class CatalogTreeView extends BeanTreeView {
private Action startEditing;
private void invokeInplaceEditing() {
if (startEditing == null) {
Object o = tree.getActionMap().get("startEditing"); // NOI18N
if (o != null && o instanceof Action) {
startEditing = (Action) o;
}
}
assert startEditing != null : "startEditing is on tree ActionMap " + Arrays.asList(tree.getActionMap().keys());
startEditing.actionPerformed(new ActionEvent(tree, 0, "startEditing")); // NOI18N
}
}
private class SelectionListener implements PropertyChangeListener {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
final Node [] nodes = (Node []) evt.getNewValue();
boolean res = nodes != null && nodes.length > 0;
int i = 0;
while (res && i < nodes.length) {
Node n = nodes [i++];
if(n instanceof CatalogNode && ((CatalogNode)n).isRemovable()) {
res = true;
break;
}
Object node = n.getCookie(CatalogEntryNode.class);
res = node instanceof CatalogEntryNode && ((CatalogEntryNode)node).isCatalogWriter();
}
removeButton.setEnabled(res);
if (nodes.length>0) {
Object node = nodes[0].getCookie(CatalogNode.class);
addLocalButton.setEnabled(node instanceof CatalogNode
&& ((CatalogNode)node).getCatalogReader() instanceof CatalogWriter);
}
}
}
}
private void initialize() {
getExplorerManager().setRootContext(getCatalogRootNode());
getExplorerManager().addPropertyChangeListener(new SelectionListener());
removeButton.setEnabled(false);
addButton.setEnabled(true);
addLocalButton.setEnabled(false);
}
static Node getCatalogRootNode() {
return new CatalogRootNode();
}
static private final class TemplateFilter implements DataFilter {
public boolean acceptDataObject(DataObject obj) {
return acceptTemplate(obj);
}
private boolean acceptTemplate(DataObject d) {
if (d.isTemplate() || d instanceof DataFolder) {
Object o = d.getPrimaryFile().getAttribute("simple"); // NOI18N
return o == null || Boolean.TRUE.equals(o);
} else {
return false;
}
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
templatesLabel = new javax.swing.JLabel();
treePanel = new javax.swing.JPanel();
buttonsPanel = new javax.swing.JPanel();
addButton = new javax.swing.JButton();
addLocalButton = new javax.swing.JButton();
removeButton = new javax.swing.JButton();
jSeparator2 = new javax.swing.JSeparator();
jSeparator3 = new javax.swing.JSeparator();
setPreferredSize(new java.awt.Dimension(500, 300));
setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(templatesLabel, org.openide.util.NbBundle.getBundle(CatalogPanel.class).getString("LBL_CatalogPanel_CatalogLabel")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
add(templatesLabel, gridBagConstraints);
treePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
treePanel.setLayout(new java.awt.BorderLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(0, 12, 11, 0);
add(treePanel, gridBagConstraints);
buttonsPanel.setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getBundle(CatalogPanel.class).getString("BTN_CatalogPanel_Add")); // NOI18N
addButton.setToolTipText(org.openide.util.NbBundle.getMessage(CatalogPanel.class, "ACD_CatalogPanel_Add")); // NOI18N
addButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 8, 3, 0);
buttonsPanel.add(addButton, gridBagConstraints);
addButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CatalogPanel.class, "ACD_CatalogPanel_Add")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(addLocalButton, org.openide.util.NbBundle.getBundle(CatalogPanel.class).getString("BTN_CatalogPanel_AddLocal")); // NOI18N
addLocalButton.setToolTipText(org.openide.util.NbBundle.getMessage(CatalogPanel.class, "ACD_CatalogPanel_AddLocal")); // NOI18N
addLocalButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addLocalButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(0, 8, 3, 0);
buttonsPanel.add(addLocalButton, gridBagConstraints);
addLocalButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CatalogPanel.class, "ACD_CatalogPanel_AddLocal")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getBundle(CatalogPanel.class).getString("BTN_CatalogPanel_RemoveButton")); // NOI18N
removeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
removeButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(0, 8, 3, 0);
buttonsPanel.add(removeButton, gridBagConstraints);
removeButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CatalogPanel.class, "ACD_CatalogPanel_Remove")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 8;
gridBagConstraints.insets = new java.awt.Insets(4, 8, 4, 0);
buttonsPanel.add(jSeparator2, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 5;
gridBagConstraints.insets = new java.awt.Insets(4, 8, 4, 0);
buttonsPanel.add(jSeparator3, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
gridBagConstraints.insets = new java.awt.Insets(0, 11, 11, 8);
add(buttonsPanel, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
private void addLocalButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addLocalButtonActionPerformed
AddCatalogEntryAction.perform(manager.getSelectedNodes());
}//GEN-LAST:event_addLocalButtonActionPerformed
private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
Node [] nodes = manager.getSelectedNodes();
try {
for(Node n : nodes) {
n.destroy();
}
} catch (IOException e) {
Logger.getLogger(CatalogPanel.class.getName()).log(Level.SEVERE, e.getLocalizedMessage(), e);
}
}//GEN-LAST:event_removeButtonActionPerformed
private void addButtonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
CatalogRootNode.mountCatalog(new Node[] {manager.getRootContext()});
}//GEN-LAST:event_addButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addButton;
private javax.swing.JButton addLocalButton;
private javax.swing.JPanel buttonsPanel;
private javax.swing.JSeparator jSeparator2;
private javax.swing.JSeparator jSeparator3;
private javax.swing.JButton removeButton;
private javax.swing.JLabel templatesLabel;
private javax.swing.JPanel treePanel;
// End of variables declaration//GEN-END:variables
static private DataObject getDOFromNode(Node n) {
DataObject dobj = n.getLookup().lookup(DataObject.class);
assert dobj != null : "DataObject for node " + n;
return dobj;
}
static private DataFolder getTargetFolder(Node [] nodes) {
DataFolder folder = null;
if (nodes == null || nodes.length == 0) {
folder = DataFolder.findFolder(getCatalogRoot());
} else {
// try if has a data folder (alert: leaf node can be a empty folder)
folder = nodes [0].getLookup().lookup(DataFolder.class);
// if not this node then try its parent
if (folder == null && nodes [0].isLeaf()) {
Node parent = nodes [0].getParentNode();
folder = parent.getLookup().lookup(DataFolder.class);
}
}
return folder;
}
static DataObject createTemplateFromFile(File file, DataFolder preferred) {
if (file == null) {
throw new IllegalArgumentException("Argument file cannot be null!"); // NOI18N
}
FileObject sourceFO = FileUtil.toFileObject(FileUtil.normalizeFile(file));
assert sourceFO != null : "FileObject found for file " + file;
DataObject sourceDO = null;
try {
sourceDO = DataObject.find(sourceFO);
} catch (DataObjectNotFoundException donfe) {
Logger.getLogger(CatalogPanel.class.getName()).log(Level.WARNING, null, donfe);
}
assert sourceDO != null : "DataObject found for FileObject " + sourceFO;
DataFolder folder = preferred == null ? DataFolder.findFolder(getCatalogRoot()) : preferred;
DataObject template = null;
try {
template = sourceDO.copy(folder);
template.setTemplate(true);
} catch (IOException ioe) {
Logger.getLogger(CatalogPanel.class.getName()).log(Level.WARNING, null, ioe);
}
return template;
}
private static DataFolder doNewFolder(Node [] nodes) {
DataFolder df = null;
// new folder
DataFolder pref = getTargetFolder(nodes);
if (pref == null) {
pref = DataFolder.findFolder(getCatalogRoot());
assert pref != null : "DataFolder found for FO " + getCatalogRoot();
}
try {
df = DataFolder.create(pref, NbBundle.getBundle(CatalogPanel.class).getString("TXT_CatalogPanel_NewFolderName")); // NOI18N
assert df != null : "New subfolder found in folder " + pref;
} catch (IOException ioe) {
Logger.getLogger(CatalogPanel.class.getName()).log(Level.WARNING, null, ioe);
}
return df;
}
static DataObject createDuplicateFromNode(Node n) {
DataObject source = getDOFromNode(n);
try {
return source.copy(source.getFolder());
} catch (IOException ioe) {
Logger.getLogger(CatalogPanel.class.getName()).log(Level.WARNING, null, ioe);
}
return null;
}
static FileObject getCatalogRoot() {
if (catalogRoot == null) {
catalogRoot = FileUtil.getConfigFile("Catalog"); // NOI18N
}
return catalogRoot;
}
private int getNodePosition(Node n) {
Index supp = getIndexSupport(n);
DataFolder df = n.getParentNode().getLookup().lookup(DataFolder.class);
df.getNodeDelegate().getChildren().getNodes(true);
int pos = supp.indexOf(n);
assert pos != -1 : "Node " + n + " has position " + pos + " in children " + Arrays.asList(n.getParentNode().getChildren().getNodes());
return pos;
}
private Index getIndexSupport(Node n) {
Node parent = n.getParentNode();
assert parent != null : "Node " + n + " has a parent.";
Index index = parent.getLookup().lookup(Index.class);
assert index != null : "Node " + parent + " has Index cookie.";
return index;
}
}