blob: 7478630509a25ce0bb4f9c96f19649175ff93511 [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.event.*;
import java.awt.*;
import java.beans.*;
import java.util.*;
import java.io.*;
import java.net.*;
import javax.swing.event.*;
import org.openide.*;
import org.openide.nodes.*;
import org.openide.util.actions.*;
import org.openide.util.datatransfer.*;
import org.openide.actions.*;
import org.netbeans.modules.xml.catalog.spi.*;
import org.netbeans.modules.xml.catalog.impl.*;
import org.netbeans.modules.xml.catalog.settings.CatalogSettings;
import org.openide.util.HelpCtx;
import java.awt.event.ActionEvent;
import javax.swing.*;
import org.openide.util.NbBundle;
/**
* Node representing catalog root in the Runtime tab. It retrieves all
* mounted catalogs from current project settings.
*
* To be registered in manifest file as:
* <pre>
* Name: org.netbeans.modules.xml.catalog.CatalogNode.class
* OpenIDE-Module-Class: Environment
* </pre>
*
* <p><b>Implementation Note:</b>
* <p>The node has session lifetime but its model has project lifetime, so there
* is implemented a logic for model instance changing (see children).
*
* @author Petr Kuzel
* @version 1.0
*/
public final class CatalogRootNode extends AbstractNode implements Node.Cookie {
/** Creates new CatalogNode */
public CatalogRootNode() {
super(new RootChildren());
setName("XML-CATALOG"); // NOI18N
setDisplayName (NbBundle.getMessage(CatalogRootNode.class, "TEXT_catalog_root")); // NOI18N
setIconBaseWithExtension("org/netbeans/modules/xml/catalog/resources/catalog-root.gif"); // NOI18N
setShortDescription(NbBundle.getMessage(CatalogRootNode.class, "PROP_catalog_root_desc"));
getCookieSet().add(this);
}
protected SystemAction[] createActions() {
return new SystemAction[] {
SystemAction.get(CatalogRootNode.MountAction.class),
null,
SystemAction.get(PropertiesAction.class)
};
}
/** We can mount entity catalogs. */
// public NewType[] getNewTypes() {
// return new NewType[] {new CatalogMounter()};
// }
/**
* Mounts new catalalog as specified by user.
*/
class CatalogMounter extends NewType implements ActionListener {
CatalogMounterModel model = null;
Dialog myDialog = null;
public void create() throws IOException {
Iterator it = ProvidersRegistry.getProviderClasses(new Class[] {CatalogReader.class});
model = new CatalogMounterModel(it);
Object rpanel = new CatalogMounterPanel(model);
DialogDescriptor dd = new DialogDescriptor(rpanel,
NbBundle.getMessage(CatalogRootNode.class, "PROP_Mount_Catalog"), true, this);
dd.setHelpCtx(new HelpCtx(CatalogMounterPanel.class));
myDialog = DialogDisplayer.getDefault().createDialog(dd);
// set dialog size to 60x10 characters
JTextArea template = new JTextArea();
template.setColumns(60);
template.setRows(8 + 2); // 8 lines, 2 bottom line with buttons
Dimension dimension = template.getPreferredSize();
//#33996 this is insets size as prescribed by UI guidelines
final int insets = 12;
// small fonts have problems that insets are times more important
// then font size, include also insets
int heightInsets = dimension.height + 10 * insets; // 10 lines * 12 inset size
int widthInsets = dimension.width + 4 * insets;
Dimension fullDimension = new Dimension(widthInsets, heightInsets);
myDialog.setSize(fullDimension); //^ packing never creates bigger window :-(
myDialog.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == DialogDescriptor.OK_OPTION) {
Object catalog = model.getCatalog();
if (catalog == null) return;
CatalogSettings mounted = CatalogSettings.getDefault();
mounted.addCatalog((CatalogReader)catalog);
}
if (myDialog != null) {
myDialog.dispose();
myDialog = null;
}
}
public String getName() {
return NbBundle.getMessage(CatalogRootNode.class, "LBL_mount"); // NOI18N
}
}
// ~~~~~~~~~~~~~~~~~~~~~~ Serialization stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
//if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("Reading CatalogRoot node " + this); // NOI18N
in.defaultReadObject();
}
private void writeObject(ObjectOutputStream out) throws IOException {
//if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("Writing " + this); // NOI18N
out.defaultWriteObject();
}
public HelpCtx getHelpCtx() {
//return new HelpCtx(CatalogRootNode.class);
return HelpCtx.DEFAULT_HELP;
}
// ~~~~~~~~~~~~~~~~~~~~~~ NODE KIDS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Kids driven by CatalogSettings. Only one instance may be used
* since redefined equals() method.
*/
private static class RootChildren extends Children.Keys implements Comparator, PropertyChangeListener {
/** Contains CatalogReader instances. */
private final Set<CatalogReader> keys = new TreeSet<>(this);
/**
* Create new keys, register itself as listener.
*/
public synchronized void addNotify() {
CatalogSettings mounted = CatalogSettings.getDefault();
mounted.addPropertyChangeListener(this);
createKeys(mounted);
}
/**
* Remove listener and keys.
*/
public synchronized void removeNotify() {
CatalogSettings mounted = CatalogSettings.getDefault();
if (mounted != null) mounted.removePropertyChangeListener(this);
keys.clear();
setKeys(keys);
}
/**
* Create CatalogNodes initialized by provider instance.
*/
public Node[] createNodes(Object key) {
try {
return new Node[] { new CatalogNode((CatalogReader)key) };
} catch (IntrospectionException ex) {
return new Node[] {};
}
}
/**
* The only instance (see equals) listens on ProvidersRegistry
* for its state changes.
*/
public synchronized void propertyChange(PropertyChangeEvent e) {
if (CatalogSettings.PROP_MOUNTED_CATALOGS.equals(e.getPropertyName())) {
createKeys((CatalogSettings)e.getSource());
}
}
/**
* Creates new keys according to CatalogSettings.
*/
private void createKeys(CatalogSettings mounted) {
keys.clear();
if (mounted != null) {
Iterator<CatalogReader> it = mounted.getCatalogs(new Class[] {CatalogReader.class});
while (it.hasNext()) {
keys.add(it.next()); //!!! use immutable key wrappers, some
// instances may overwrite equals() so
// they cannot be used as a children key
}
}
setKeys(keys);
}
/**
* We are also comparators. Use class based equality.
*/
public boolean equals(java.lang.Object peer) {
return peer.getClass().equals(getClass());
}
/**
* Compare keys giving highest priority to system catalog.
* Other catalogs sort by display name if available.
*/
public int compare(java.lang.Object one,java.lang.Object two) {
if (one == two) return 0;
if (one instanceof SystemCatalogReader) return -1;
if (two instanceof SystemCatalogReader) return 1;
if (one instanceof CatalogDescriptorBase && two instanceof CatalogDescriptorBase) {
int test = (((CatalogDescriptorBase)one).getDisplayName()).compareTo(
((CatalogDescriptorBase)two).getDisplayName()
);
if (test != 0) return test;
} else {
if (one instanceof CatalogDescriptorBase) return -1;
if (two instanceof CatalogDescriptorBase) return 1;
}
// show all catalogs never return 0
return (long)one.hashCode() - (long)two.hashCode() > 0L ? 1 : -1;
}
}
/**
* Give to action your own name
*/
private static final class MountAction extends NodeAction {
/** Serial Version UID */
private static final long serialVersionUID = -3608629636833099065L;
public MountAction() {
}
public String getName() {
return NbBundle.getMessage(CatalogRootNode.class, "LBL_mount");
}
public HelpCtx getHelpCtx() {
return new HelpCtx(MountAction.class);
}
protected synchronized boolean enable(Node[] activatedNodes) {
return activatedNodes.length > 0;
}
protected boolean asynchronous() {
return false;
}
protected synchronized void performAction(Node[] activatedNodes) {
mountCatalog(activatedNodes);
}
}
public static void mountCatalog(Node[] activatedNodes) {
if (activatedNodes.length == 0) return;
try {
Node current = activatedNodes[0];
CatalogRootNode me = current.getCookie(CatalogRootNode.class);
CatalogMounter newType = me.new CatalogMounter();
newType.create();
} catch (IOException ex) {
//Util.THIS.debug(ex);
} finally {
}
}
}