blob: 0cf9152510476fa080ac074a407bca0aedf7201d [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.beans.beaninfo;
import java.beans.PropertyEditor;
import java.lang.reflect.InvocationTargetException;
import javax.swing.Action;
import javax.swing.GrayFilter;
import org.netbeans.api.java.source.SourceUtils;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;
/**
* This class represents BeanInfo root node.
*
* @author Petr Hrebejk
*/
public final class BiNode extends AbstractNode {
// static variables ...........................................................................
/** generated Serialized Version UID */
//static final long serialVersionUID = -6346315017458451778L;
private static String ICON_BASE = "org/netbeans/modules/beans/resources/beanInfo.gif"; // NOI18N
private static String ICON_BASE_PATTERNS = "org/netbeans/modules/beans/resources/patternGroup.gif"; // NOI18N
private static String WAIT_ICON_BASE = "org/netbeans/modules/beans/resources/wait.gif"; // NOI18N
private static String WARNING_ICON_BASE = "org/netbeans/modules/beans/resources/warning.gif"; // NOI18N
private static String PROP_NULL_DESCRIPTOR = "nullDescriptor"; // NOI18N
private static String PROP_NULL_PROPERTIES = "nullProperties"; // NOI18N
private static String PROP_NULL_EVENTS = "nullEvents"; // NOI18N
private static String PROP_NULL_METHODS = "nullMethods"; // NOI18N
private static String PROP_LAZY_DESCRIPTOR = "lazyDescriptor"; // NOI18N
private static String PROP_LAZY_PROPERTIES = "lazyProperties"; // NOI18N
private static String PROP_LAZY_EVENTS = "lazyEvents"; // NOI18N
private static String PROP_LAZY_METHODS = "lazyMethods"; // NOI18N
private static String PROP_BI_ICON_C16 = "iconColor16x16"; // NOI18N
private static String PROP_BI_ICON_M16 = "iconMono16x16"; // NOI18N
private static String PROP_BI_ICON_C32 = "iconColor32x32"; // NOI18N
private static String PROP_BI_ICON_M32 = "iconMono32x32"; // NOI18N
private static String PROP_BI_DEFAULT_PROPERTY = "defaultPropertyIndex"; // NOI18N
private static String PROP_BI_DEFAULT_EVENT = "defaultEventIndex"; // NOI18N
private static String PROP_USE_SUPERCLASS = "useSuperclass"; // NOI18N
static javax.swing.GrayFilter grayFilter = null;
static{
grayFilter = new GrayFilter(true, 5);
}
// variables ....................................................................................
private BiAnalyser biAnalyser;
private PropertySupport[] descSubnodeDescriptor = new PropertySupport[] {
new PropertySupport.ReadWrite<Boolean> (
PROP_NULL_DESCRIPTOR,
Boolean.TYPE,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_NULL_DESCRIPTOR ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_NULL_DESCRIPTOR )
) {
public Boolean getValue () {
return biAnalyser.isNullDescriptor ();
}
public void setValue (Boolean val) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
try {
biAnalyser.setNullDescriptor ( val );
} catch (ClassCastException e) {
throw new IllegalArgumentException ();
}
iconChange();
}
}
};
private PropertySupport[] propSubnodeProperties = new PropertySupport[] {
new PropertySupport.ReadWrite<Boolean> (
PROP_NULL_PROPERTIES,
Boolean.TYPE,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_NULL_PROPERTIES ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_NULL_PROPERTIES )
) {
public Boolean getValue () {
return biAnalyser.isNullProperties ();
}
public void setValue (Boolean val) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
try {
biAnalyser.setNullProperties ( val );
} catch (ClassCastException e) {
throw new IllegalArgumentException ();
}
iconChange();
}
}
};
private PropertySupport[] eventSubnodeProperties = new PropertySupport[] {
new PropertySupport.ReadWrite<Boolean> (
PROP_NULL_EVENTS,
Boolean.TYPE,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_NULL_EVENTS ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_NULL_EVENTS )
) {
public Boolean getValue () {
return biAnalyser.isNullEventSets ();
}
public void setValue (Boolean val) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
try {
biAnalyser.setNullEventSets ( val );
} catch (ClassCastException e) {
throw new IllegalArgumentException ();
}
iconChange();
}
}
};
private PropertySupport[] methodSubnodeProperties = new PropertySupport[] {
new PropertySupport.ReadWrite<Boolean> (
PROP_NULL_PROPERTIES,
Boolean.TYPE,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_NULL_METHODS ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_NULL_METHODS )
) {
public Boolean getValue () {
return biAnalyser.isNullMethods ();
}
public void setValue (Boolean val) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
try {
biAnalyser.setNullMethods ( val );
} catch (ClassCastException e) {
throw new IllegalArgumentException ();
}
iconChange();
}
}
};
// constructors ..................................................................................
/**
* Creates tree for BeanInfo Analyser.
*/
BiNode ( final BiAnalyser biAnalyser ) {
/*
super ( new BiChildren ( biAnalyser,
new Class[] {
BiFeature.Property.class,
BiFeature.IdxProperty.class,
BiFeature.EventSet.class } ) );
*/
super (new Children.Array() );
this.biAnalyser = biAnalyser;
setDisplayName (NbBundle.getBundle(BiNode.class).
getString ("CTL_NODE_BeanInfo"));
setIconBaseWithExtension (ICON_BASE);
Node[] subnodes = (biAnalyser.isOlderVersion() ?
new Node[] {
new SubNode( biAnalyser,
new Class[] { BiFeature.Property.class, BiFeature.IdxProperty.class },
"CTL_NODE_Properties", // NOI18N
ICON_BASE_PATTERNS,
propSubnodeProperties,
null ),
new SubNode( biAnalyser,
new Class[] { BiFeature.EventSet.class },
"CTL_NODE_EventSets", // NOI18N
ICON_BASE_PATTERNS,
eventSubnodeProperties,
null )
} : new Node[] {
new SubNode( biAnalyser,
new Class[] { BiFeature.Descriptor.class },
"CTL_NODE_Descriptor", // NOI18N
ICON_BASE_PATTERNS,
descSubnodeDescriptor ,
new Node.Property[] {
createProperty (biAnalyser, Boolean.TYPE,
PROP_LAZY_DESCRIPTOR,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_LAZY_DESCRIPTOR ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_LAZY_DESCRIPTOR ),
"isLazyDescriptor", "setLazyDescriptor" )} // NOI18N
),
new SubNode( biAnalyser,
new Class[] { BiFeature.Property.class, BiFeature.IdxProperty.class },
"CTL_NODE_Properties", // NOI18N
ICON_BASE_PATTERNS,
propSubnodeProperties,
new Node.Property[] {
createProperty (biAnalyser, Boolean.TYPE,
PROP_LAZY_DESCRIPTOR,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_LAZY_PROPERTIES ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_LAZY_PROPERTIES ),
"isLazyProperties", "setLazyProperties" )} // NOI18N
),
new SubNode( biAnalyser,
new Class[] { BiFeature.EventSet.class },
"CTL_NODE_EventSets", // NOI18N
ICON_BASE_PATTERNS,
eventSubnodeProperties,
new Node.Property[] {
createProperty (biAnalyser, Boolean.TYPE,
PROP_LAZY_EVENTS,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_LAZY_EVENTS ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_LAZY_EVENTS ),
"isLazyEventSets", "setLazyEventSets" )} // NOI18N
),
new SubNode( biAnalyser,
new Class[] { BiFeature.Method.class },
"CTL_NODE_Methods", // NOI18N
ICON_BASE_PATTERNS,
methodSubnodeProperties,
new Node.Property[] {
createProperty (biAnalyser, Boolean.TYPE,
PROP_LAZY_METHODS,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_LAZY_METHODS ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_LAZY_METHODS ),
"isLazyMethods", "setLazyMethods" )} // NOI18N
)
});
Sheet sheet = Sheet.createDefault();
Sheet.Set ps = sheet.get(Sheet.PROPERTIES);
ps.put( new ImagePropertySupportRW (
PROP_BI_ICON_C16,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_ICON_C16 ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_ICON_C16 )
) {
public BiIconEditor.BiImageIcon getValue () throws
IllegalAccessException, InvocationTargetException {
return biAnalyser.getIconC16() != null
? ie.iconFromText(biAnalyser.getIconC16())
: null;
}
public void setValue (BiIconEditor.BiImageIcon value) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
biAnalyser.setIconC16(ie.textFromIcon(value));
}
}
);
ps.put( new ImagePropertySupportRW (
PROP_BI_ICON_M16,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_ICON_M16 ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_ICON_M16 )
) {
public BiIconEditor.BiImageIcon getValue () throws
IllegalAccessException, InvocationTargetException {
return biAnalyser.getIconM16() != null
? ie.iconFromText(biAnalyser.getIconM16())
: null;
}
public void setValue (BiIconEditor.BiImageIcon value) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
biAnalyser.setIconM16(ie.textFromIcon(value));
}
}
);
ps.put( new ImagePropertySupportRW (
PROP_BI_ICON_C32,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_ICON_C32 ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_ICON_C32 )
) {
public BiIconEditor.BiImageIcon getValue () throws
IllegalAccessException, InvocationTargetException {
return biAnalyser.getIconC32() != null
? ie.iconFromText(biAnalyser.getIconC32())
: null;
}
public void setValue (BiIconEditor.BiImageIcon value) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
biAnalyser.setIconC32(ie.textFromIcon(value));
}
}
);
ps.put( new ImagePropertySupportRW (
PROP_BI_ICON_M32,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_ICON_M32 ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_ICON_M32 )
) {
public BiIconEditor.BiImageIcon getValue () throws
IllegalAccessException, InvocationTargetException {
return biAnalyser.getIconM32() != null
? ie.iconFromText(biAnalyser.getIconM32())
: null;
}
public void setValue (BiIconEditor.BiImageIcon value) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
biAnalyser.setIconM32(ie.textFromIcon(value));
}
}
);
ps.put( createProperty (biAnalyser, Integer.TYPE,
PROP_BI_DEFAULT_PROPERTY,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_DEFAULT_PROPERTY ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_DEFAULT_PROPERTY ),
"getDefaultPropertyIndex", "setDefaultPropertyIndex" ) ); // NOI18N
ps.put( createProperty (biAnalyser, Integer.TYPE,
PROP_BI_DEFAULT_EVENT,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_BI_DEFAULT_EVENT ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_BI_DEFAULT_EVENT ),
"getDefaultEventIndex", "setDefaultEventIndex" ) ); // NOI18N
//only if it is super class version (since 3.3)
if(biAnalyser.isSuperclassVersion()){
ps.put( createProperty (biAnalyser, Boolean.TYPE,
PROP_USE_SUPERCLASS,
GenerateBeanInfoAction.getString ("PROP_Bi_" + PROP_USE_SUPERCLASS ),
GenerateBeanInfoAction.getString ("HINT_Bi_" + PROP_USE_SUPERCLASS ),
"isUseSuperClass", "setUseSuperClass" ) ); // NOI18N
}
setSheet(sheet);
((Children.Array)getChildren()).add( subnodes );
}
/** refresh icons after get from introspection change */
public void iconChange(){
Node[] nodes = ((Children.Array)getChildren()).getNodes();
for( int i = 0; i < nodes.length; i++ ){
((SubNode)nodes[i]).iconChanged();
}
}
static final class SubNode extends AbstractNode implements Node.Cookie {
//private static SystemAction[] staticActions;
private BiAnalyser biAnalyser;
private Class<?> key;
SubNode ( BiAnalyser biAnalyser, Class<?>[] keys, String titleKey, String iconBase,
Node.Property[] properties, Node.Property[] expert ) {
super ( new BiChildren ( biAnalyser, keys ) );
setDisplayName (NbBundle.getBundle(BiNode.class).
getString (titleKey));
setIconBaseWithExtension ( iconBase );
this.biAnalyser = biAnalyser;
this.key = keys[0];
Sheet sheet = Sheet.createDefault();
Sheet.Set ps = sheet.get(Sheet.PROPERTIES);
for ( int i = 0; i < properties.length; i++ ) {
ps.put( properties[i] );
}
if( expert != null ){
Sheet.Set eps = Sheet.createExpertSet();
for ( int i = 0; i < expert.length; i++ ) {
eps.put( expert[i] );
}
sheet.put(eps);
}
setSheet(sheet);
getCookieSet().add ( this );
}
@Override
public java.awt.Image getIcon( int type ){
if( key == BiFeature.Descriptor.class && biAnalyser.isNullDescriptor() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.Property.class && biAnalyser.isNullProperties() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.EventSet.class && biAnalyser.isNullEventSets() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.Method.class && biAnalyser.isNullMethods() )
return GrayFilter.createDisabledImage(super.getIcon(type));
return super.getIcon(type);
}
@Override
public java.awt.Image getOpenedIcon( int type ){
if( key == BiFeature.Descriptor.class && biAnalyser.isNullDescriptor() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.Property.class && biAnalyser.isNullProperties() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.EventSet.class && biAnalyser.isNullEventSets() )
return GrayFilter.createDisabledImage(super.getIcon(type));
if( key == BiFeature.Method.class && biAnalyser.isNullMethods() )
return GrayFilter.createDisabledImage(super.getIcon(type));
return super.getOpenedIcon(type);
}
/** Getter for set of actions that should be present in the
* popup menu of this node. This set is used in construction of
* menu returned from getContextMenu and specially when a menu for
* more nodes is constructed.
*
* @return array of system actions that should be in popup menu
*/
@Override
public Action[] getActions ( boolean context ) {
if ( context ) {
return super.getActions( true );
}
else {
Children ch = getChildren();
Node[] nodes = ch.getNodes();
if ( nodes == null )
return new SystemAction[0];
if( nodes.length == 0 || ( nodes[0] != null && ((BiFeatureNode)nodes[0]).getBiFeature() instanceof BiFeature.Descriptor) )
return new SystemAction[0];
return new SystemAction[] {
SystemAction.get (BiIncludeAllAction.class),
SystemAction.get (BiExcludeAllAction.class),
null
};
}
}
void includeAll( boolean value) {
Children ch = getChildren();
Node[] nodes = ch.getNodes();
if ( nodes == null )
return;
for( int i = 0; i < nodes.length; i++ ) {
((BiFeatureNode)nodes[i]).include( value );
}
}
/** refresh icons after get from introspection change */
public void iconChanged(){
fireIconChange();
fireOpenedIconChange();
Children ch = getChildren();
Node[] nodes = ch.getNodes();
if ( nodes == null )
return;
for( int i = 0; i < nodes.length; i++ ) {
((BiFeatureNode)nodes[i]).iconChanged();
}
}
}
// Inner Class ---------------------------------------------------------------
static final class Wait extends AbstractNode {
Wait () {
super( Children.LEAF );
setDisplayName( SourceUtils.isScanInProgress()? NbBundle.getBundle( BiNode.class ).getString( "CTL_NODE_WaitScan" ) : NbBundle.getBundle( BiNode.class ).getString( "CTL_NODE_Wait" ) );
setIconBaseWithExtension( WAIT_ICON_BASE );
}
}
private static final class Error extends AbstractNode {
Error (String name) {
super( Children.LEAF );
setDisplayName(name);
setIconBaseWithExtension( WARNING_ICON_BASE );
}
}
public static Node createNoSourceNode(FileObject bi) {
String name = bi.getName();
name = name.substring(0, name.length() - "BeanInfo".length()); // NOI18N
String ext = bi.getExt();
if (ext.length() > 0) {
name += '.' + ext;
}
String msg = NbBundle.getMessage(BiNode.class, "CTL_NODE_MissingBeanFile", name);
return new Error(msg);
}
public static Node createBiNode(BiAnalyser bia, NotifyDescriptor error) {
if (bia == null) {
Object msg = error == null
? NbBundle.getMessage(BiNode.class, "CTL_NODE_UnknownBeanInfoState")
: error.getMessage();
return new Error(msg.toString());
} else if (bia.isBeanBroken()) {
String msg = NbBundle.getMessage(
BiNode.class, "MSG_BrokenBean",
bia.bis.getSourceDataObject().getPrimaryFile().getNameExt());
return new Error(msg);
} else if (!bia.bis.isNbBeanInfo()) {
String msg = NbBundle.getMessage(BiNode.class, "CTL_NODE_UnknownBeanInfoFormat");
return new Error(msg);
} else if (bia.bis.getSourceDataObject() == null) {
return createNoSourceNode(bia.bis.getDataObject().getPrimaryFile());
} else {
return new BiNode(bia);
}
}
abstract class ImagePropertySupportRW extends PropertySupport.ReadWrite<BiIconEditor.BiImageIcon> {
BiIconEditor ie = null;
ImagePropertySupportRW(String name, String displayName, String shortDescription) {
super(name, BiIconEditor.BiImageIcon.class, displayName, shortDescription);
ie = new BiIconEditor( biAnalyser.bis.getSourceDataObject().getPrimaryFile() );
}
@Override
public PropertyEditor getPropertyEditor() {
return ie;
}
}
public static <T> Node.Property<T> createProperty (Object inst, Class<T> type,
String name, String dispName,
String shortDesc,
String getter, String setter ) {
Node.Property<T> prop;
try {
prop = new PropertySupport.Reflection<T> (inst, type, getter, setter);
} catch (NoSuchMethodException e) {
throw new IllegalStateException (e.getMessage() + " " + getter); // NOI18N
}
prop.setName (name);
prop.setDisplayName (dispName);
prop.setShortDescription (shortDesc);
return prop;
}
}