|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.xml.tree.nodes;
import java.io.*;
import java.awt.Image;
import java.awt.Component;
import java.awt.datatransfer.*;
import java.util.List;
import java.beans.*;
import java.lang.ref.*;
import org.openide.*;
import org.openide.loaders.*;
import org.openide.actions.*;
import org.openide.util.actions.*;
import org.openide.nodes.*;
import org.openide.explorer.propertysheet.editors.*;
import org.openide.util.datatransfer.*;
import org.openide.util.HelpCtx;
import org.openide.util.Utilities;
import org.netbeans.tax.*;
import org.netbeans.tax.io.*;
import org.netbeans.modules.xml.core.*;
import org.netbeans.modules.xml.core.cookies.*;
import org.netbeans.modules.xml.tree.children.*;
import org.netbeans.modules.xml.tree.nodes.*;
import org.netbeans.modules.xml.tree.settings.*;
import org.netbeans.modules.xml.tree.lib.GuiUtil;
import org.netbeans.modules.xml.tax.cookies.TreeDocumentCookie;
import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie;
/**
* DataNode that proxies a lot of functionality to actual root bean node.
* It updates state according to bean PROP_STATUS and ...
*
* @author Libor Kramolis
* @author Petr Kuzel
* @version 0.2
*/
public abstract class AbstractDataNode extends DataNode implements TreeObjectNode, DataNodeCookie, NodeViewType.Provider {
/** */
public static final String PROP_ROOT_NODE = "rootNode"; // NOI18N
private static final String XML_STATUS = "status"; // NOI18N
/** Last cached document cookie. */
private TreeDocumentCookie documentCookie;
/** Last cached document status. */
private int status;
/**
* Reference to root node allowing garbage collection of TAX model for
* collapsed nodes. Actual value can be accessed as getRootNode() .
* We do not need to listen to garbage collection as we listen at editor cookie status.
*/
private Reference rootRef;
/** */
public static final String NODE_VIEW_TYPE_ATTRIBUTE = "org.netbeans.modules.xml.tree.settings.NodeViewType"; // NOI18N
/** */
private NodeViewType nodeViewType;
//!!! where does it listen on PROP_NODE_VIEW_TYPE?
// listen on bean editor STATUS
private InnerListener listener;
//
// init
//
/** */
protected AbstractDataNode(XMLDataObjectLook dataObject) {
super ((DataObject)dataObject, new DataObjectChildren ((TreeEditorCookie)dataObject.getCookie (TreeEditorCookie.class)));
init (dataObject);
}
/** */
private void init (XMLDataObjectLook dataObject) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::init: status " + ((TreeEditorCookie)dataObject.getCookie (TreeEditorCookie.class)).getStatus()); // NOI18N
documentCookie = null;
status = -1;
rootRef = null;
listener = new InnerListener();
TreeEditorCookie cake = (TreeEditorCookie) dataObject.getCookie (TreeEditorCookie.class);
cake.addPropertyChangeListener (listener);
updateIconBase();
getCookieSet().add ((DataNodeCookie)this);
updateShortDescription();
initNodeViewType();
}
//
// from TreeObjectNode
//
/**
* @return related tree object.
*/
public final TreeObject getTreeObject () {
try {
return (TreeObject)getDocumentRoot();
} catch (Exception e) {
return null;
}
}
//
// itself
//
/** Get the associated xml data object.
* ({@link #getDataObject} is protected; this provides access to it.)
* @return the data object
*/
public final XMLDataObjectLook getXMLDataObjectLook () {
return (XMLDataObjectLook)getDataObject();
}
/**
*/
protected final TreeDocumentRoot getDocumentRoot () throws IOException, TreeException {
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null) {
return (TreeDocumentRoot)rootNode.getTreeObject();
}
return null;
}
/**
*/
protected final DataObjectChildren getDataObjectChildren () {
return (DataObjectChildren)getChildren();
}
//
// ShortDescription
//
/**
*/
private void updateShortDescription () {
setShortDescription (createShortDescription());
}
/**
*/
private String createShortDescription () {
StringBuffer sb = new StringBuffer ();
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
sb.append (rootNode.getShortDescription());
} else {
sb.append (getNodeDescription());
int status = ((TreeEditorCookie)getXMLDataObjectLook().getCookie (TreeEditorCookie.class)).getStatus();
if (status == TreeEditorCookie.STATUS_NOT) {
sb.append (' ').append (Util.THIS.getString ("TEXT_PART_not_parsed_yet"));
} else if (status == TreeEditorCookie.STATUS_ERROR) {
sb.append (' ').append (Util.THIS.getString ("TEXT_PART_error"));
}
}
return sb.toString();
}
abstract protected String getNodeDescription ();
//
// icon
//
/**
*/
public final Image getIcon (int type) {
Image icon = super.getIcon (type);
int status = ((TreeEditorCookie)getXMLDataObjectLook().getCookie (TreeEditorCookie.class)).getStatus();
if ( status == TreeEditorCookie.STATUS_ERROR ) {
Image errorBadge = Utilities.loadImage ("org/netbeans/modules/xml/tree/resources/errorbadge.gif");
icon = Utilities.mergeImages (icon, errorBadge, 8, 8);
}
return icon;
}
/**
*/
public final Image getOpenedIcon (int type) {
return getIcon (type);
}
/**
*/
protected final void updateIconBase () {
fireIconChange ();
fireOpenedIconChange ();
}
//
// from DataNodeCookie
//
/**
*/
public final DataNode getDataNode () {
String thisClassName = this.getClass().getName();
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode [ " + thisClassName + " ] ::getDataNode: this = " + this); // NOI18N
return this;
}
public HelpCtx getHelpCtx() {
return new HelpCtx (this.getClass());
}
//
// Node, Document
//
/**
*/
abstract protected AbstractRootNode createRootNode (TreeDocumentRoot documentRoot);
/**
*/
protected final void updateNode () {
TreeDocumentCookie newDocumentCookie = (TreeDocumentCookie)getDataObject().getCookie (TreeDocumentCookie.class);
int newStatus = ((TreeEditorCookie)getDataObject().getCookie (TreeEditorCookie.class)).getStatus();
if ( Util.THIS.isLoggable() ) /* then */ {
Util.THIS.debug ("AbstractDataNode::updateNode: status " + newStatus); // NOI18N
Util.THIS.debug (" ::updateNode: OLD documentCookie = " + this.documentCookie); // NOI18N
Util.THIS.debug (" ::updateNode: *new* DocumentCookie = " + newDocumentCookie); // NOI18N
}
if ( this.documentCookie != newDocumentCookie ) {
this.documentCookie = newDocumentCookie;
if (documentCookie == null) {
setRootNode (null);
} else {
setRootNode (createRootNode (documentCookie.getDocumentRoot()));
}
}
if ( status != newStatus ) {
this.status = newStatus;
updateSheet();
updateShortDescription();
updateIconBase();
}
}
/**
* Access weak root node property, may return null.
*/
public final AbstractRootNode getRootNode () {
Object rootNode = rootRef == null ? null : rootRef.get();
return (AbstractRootNode) rootNode;
}
/**
* Set new root node firing PROP_ROOT_NODE property.
*/
protected final void setRootNode (AbstractRootNode newRootNode) {
AbstractRootNode rootNode = getRootNode();
if ( Util.THIS.isLoggable() ) /* then */ {
Util.THIS.debug ("AbstractDataNode::setRootNode: OLD rootNode = " + rootNode); // NOI18N
Util.THIS.debug (" ::setRootNode: *new* rootNode = " + newRootNode); // NOI18N
}
if ( rootNode == newRootNode ) {
return;
}
AbstractRootNode oldRootNode = (AbstractRootNode) rootNode;
if (newRootNode != null) {
this.rootRef = new WeakReference(newRootNode);
} else {
this.rootRef = null;
}
if ( oldRootNode != null ) {
oldRootNode.setDataNode (null);
}
if ( newRootNode != null ) {
newRootNode.setDataNode (this);
}
if ( oldRootNode != null ) {
oldRootNode.removePropertyChangeListener (listener);
// oldRootNode.removeNodeListener (listener);
}
if ( newRootNode != null ) {
newRootNode.setNodeViewType (this.getNodeViewType());
newRootNode.addPropertyChangeListener (listener);
// newRootNode.addNodeListener (listener);
}
firePropertyChange (PROP_ROOT_NODE, oldRootNode, newRootNode);
}
//
// Sheet
//
/**
*/
protected final void updateSheet () {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("--> AbstractDataNode.updateSheet"); // NOI18N
setSheet (createSheet());
}
/** Create the property sheet.
* Subclasses may want to override this and add additional properties.
* @return the sheet
*/
protected Sheet createSheet () {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("--> AbstractDataNode.createSheet"); // NOI18N
Sheet sheet = super.createSheet();
sheet.put (updatePropertiesSheetSet (sheet));
sheet.put (createXMLSheetSet());
Sheet.Set viewSet = createViewSheetSet();
if ( viewSet != null ) {
sheet.put (viewSet);
}
return sheet;
}
/** To a standard properties sheet set add short description. */
private Sheet.Set updatePropertiesSheetSet (Sheet sheet) {
Sheet.Set propSet = sheet.get (Sheet.PROPERTIES);
if (propSet == null)
propSet = sheet.createPropertiesSet();
return propSet;
}
/** Creates new XML sheet set from TreeDocumentRoot properties. */
protected Sheet.Set createXMLSheetSet () {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("--> AbstractDataNode.createXMLSheetSet"); // NOI18N
Sheet.Set xmlSet = new Sheet.Set ();
xmlSet.setName ("__NAME__");
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
Node.PropertySet[] propertySets = rootNode.getPropertySets();
for (int i = 0; i < propertySets.length; i++) {
if (Sheet.PROPERTIES.equals (propertySets[i].getName())) {
xmlSet.put (propertySets[i].getProperties());
break;
}
}
} else {
int status = ((TreeEditorCookie)getXMLDataObjectLook().getCookie (TreeEditorCookie.class)).getStatus();
switch (status) {
case TreeEditorCookie.STATUS_NOT: // not parsed yet
xmlSet.put (new PropertySupport.ReadOnly
(XML_STATUS,
String.class,
Util.THIS.getString ("PROP_xmlStatus"),
Util.THIS.getString ("HINT_xmlStatus")) {
public Object getValue() {
return Util.THIS.getString ("MSG_not_parsed_yet");
}
});
break;
case TreeEditorCookie.STATUS_ERROR:
xmlSet.put (new PropertySupport.ReadOnly
(XML_STATUS,
String.class,
Util.THIS.getString ("PROP_xmlStatus"),
Util.THIS.getString ("HINT_xmlStatus")) {
public Object getValue () {
return Util.THIS.getString ("MSG_parsing_error");
}
});
break;
}
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("<-- .createXMLSheetSet: return = " + xmlSet); // NOI18N
return xmlSet;
}
/**
*/
protected Sheet.Set createViewSheetSet () {
Sheet.Set viewSet = null;
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
viewSet = rootNode.getViewSheetSet();
}
return viewSet;
}
//
// Customizer
//
/**
*/
public final boolean hasCustomizer () {
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
return rootNode.hasCustomizer();
}
return false;
}
/**
*/
public final Component getCustomizer () {
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
return rootNode.getCustomizer();
}
return null;
}
//
// from NodeViewType.Provider
//
/**
*/
public NodeViewType getNodeViewType () {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::getNodeViewType: this = " + this); // NOI18N
if ( nodeViewType != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::getNodeViewType: nodeViewType.name = " + nodeViewType.getName()); // NOI18N
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::getNodeViewType: nodeViewType = " + nodeViewType); // NOI18N
// if ( (nodeViewType != null) &&
// NodeViewType.isValid (nodeViewType) ) {
if ( nodeViewType != null ) {
return nodeViewType;
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::getNodeViewType: use DEFAULT value!"); // NOI18N
return TreeEditSettings.getDefault().getDefaultNodeViewType();
}
/**
*/
public final void setNodeViewType (NodeViewType nodeViewType) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::setNodeViewType: this = " + this); // NOI18N
if ( nodeViewType != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::setNodeViewType: NEW nodeViewType.name = " + nodeViewType.getName()); // NOI18N
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::setNodeViewType: NEW nodeViewType = " + nodeViewType); // NOI18N
if (this.nodeViewType == nodeViewType)
return;
NodeViewType oldNodeViewType = this.nodeViewType;
this.nodeViewType = nodeViewType;
if ( oldNodeViewType != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::setNodeViewType: OLD nodeViewType.name = " + oldNodeViewType.getName()); // NOI18N
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::setNodeViewType: OLD nodeViewType = " + oldNodeViewType); // NOI18N
saveNodeViewType();
firePropertyChange (PROP_NODE_VIEW_TYPE, oldNodeViewType, this.nodeViewType);
}
/**
*/
private void updateNodeViewType () {
AbstractRootNode rootNode = getRootNode();
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::updateNodeViewType: this = " + this); // NOI18N
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::updateNodeViewType: rootNode = " + rootNode); // NOI18N
if ( rootNode != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::updateNodeViewType: rawNodeViewType = " + rootNode.getRawNodeViewType()); // NOI18N
setNodeViewType (rootNode.getRawNodeViewType());
}
}
/**
*/
private void initNodeViewType () {
Object value = getDataObject().getPrimaryFile().getAttribute (NODE_VIEW_TYPE_ATTRIBUTE);
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::initNodeViewType: this = " + this); // NOI18N
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::initNodeViewType: value = " + value); // NOI18N
if ( value instanceof ServiceType.Handle ) {
nodeViewType = (NodeViewType)((ServiceType.Handle)value).getServiceType();
} else {
nodeViewType = NodeViewType.getValid ((NodeViewType)value);
}
if ( nodeViewType != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::initNodeViewType: NEW nodeViewType.name = " + nodeViewType.getName()); // NOI18N
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" ::initNodeViewType: NEW nodeViewType = " + nodeViewType); // NOI18N
}
/**
*/
private void saveNodeViewType () {
if ( this.nodeViewType != null ) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::saveNodeViewType: nodeViewType.name = " + this.nodeViewType.getName()); // NOI18N
}
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::saveNodeViewType: nodeViewType = " + this.nodeViewType); // NOI18N
try {
Object value = null;
if ( this.nodeViewType != null ) {
value = new ServiceType.Handle (this.nodeViewType);
}
getDataObject().getPrimaryFile().setAttribute (NODE_VIEW_TYPE_ATTRIBUTE, value);
} catch (IOException ioe) {
// ... will not be persistent!
ErrorManager.getDefault().notify (ErrorManager.INFORMATIONAL, ioe);
}
}
//
// NewTypes
//
/** Support for new types that can be created in this node.
* @return array of new type operations that are allowed
*/
public final NewType[] getNewTypes () {
AbstractRootNode rootNode = getRootNode();
if ( rootNode == null ) {
return new NewType[0];
}
return rootNode.getNewTypes();
}
//
// clipboard
//
/**
*/
protected void createPasteTypes (Transferable t, List s) {
AbstractRootNode rootNode = getRootNode();
if ( rootNode != null ) {
rootNode.createPasteTypes (t, s);
}
}
//
// class InnerListener
//
/**
* class InnerListener listen on
*/
private class InnerListener implements /*NodeListener,*/ PropertyChangeListener {
/** */
public void propertyChange (PropertyChangeEvent pche) {
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("AbstractDataNode::InnerListener::propertyChange: propertyName = '" + pche.getPropertyName() + "'"); // NOI18N
if (TreeEditorCookie.PROP_STATUS.equals (pche.getPropertyName())) {
// || DataObject.PROP_COOKIE.equals (pche.getPropertyName()) ) {
AbstractDataNode.this.updateNode();
} else if ( NodeViewType.Provider.PROP_NODE_VIEW_TYPE.equals (pche.getPropertyName()) ) {
AbstractDataNode.this.updateNodeViewType();
} else if (TreeDocument.PROP_ENCODING.equals (pche.getPropertyName())
|| TreeDocument.PROP_VERSION.equals (pche.getPropertyName())
|| TreeDocument.PROP_STANDALONE.equals (pche.getPropertyName())) {
AbstractDataNode.this.updateSheet();
}
}
/** Does nothing.
* @param ev event describing the action
*/
public void childrenAdded (NodeMemberEvent ev) {
}
/** Does nothing.
* @param ev event describing the action
*/
public void childrenRemoved (NodeMemberEvent ev) {
}
/** Does nothing.
* @param ev event describing the action
*/
public void childrenReordered (NodeReorderEvent ev) {
}
/* Does nothing.
* @param ev event describing the node
*/
public final void nodeDestroyed (NodeEvent ev) {
// AbstractDataNode.this.originalDestroyed(); //!!!
}
} // class InnerListener
}
|