This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 51907 - Node.Property.isDefaultValue() should return false by default
Summary: Node.Property.isDefaultValue() should return false by default
Status: CLOSED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Nodes (show other bugs)
Version: 4.x
Hardware: All All
: P3 blocker (vote)
Assignee: Martin Krauskopf
URL:
Keywords: API_REVIEW_FAST
Depends on:
Blocks:
 
Reported: 2004-11-29 14:35 UTC by Martin Krauskopf
Modified: 2008-12-22 23:41 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
new isDefaultValue() implementation (2.39 KB, patch)
2004-11-29 14:36 UTC, Martin Krauskopf
Details | Diff
NodeProperty51907Test warning test (6.89 KB, text/plain)
2004-12-07 16:04 UTC, Martin Krauskopf
Details
51907-patch.diff (8.66 KB, patch)
2004-12-07 16:05 UTC, Martin Krauskopf
Details | Diff
arch diff (1.43 KB, patch)
2004-12-08 13:42 UTC, Martin Krauskopf
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Krauskopf 2004-11-29 14:35:48 UTC
method to be changed:
org.openide.nodes.Node.isDefaultValue()

bug to be fixed: 49031 - [Restore Default Value]
button is always enabled

RDV = "Restore Default Value"

In order to disable

1) RDV button in property sheet editors
2) RDV item in a popup menu of properties in
property sheet

I need to use this method to distignuish the
current state of the property. But this is problem
for older modules because the isDefaultValue()
method was added after the supportsDefaultValue()
method and return always true. So if some older
successors of Node.Property overrides
supportsDefaultValue() to return true but don't
overrides isDefaultValue() (which was added later)
they will have their RDV button and popup item
always disabled (because default isDefaultValue
implementation returns always true).

I think there is not any serious reason why we
couldn't return false as a default. At the worst
the RDV item and button will be always enabled
which would be much better than always disabled as
it can happen with current NetBeans version with
older modules.
Comment 1 Martin Krauskopf 2004-11-29 14:36:51 UTC
Created attachment 19067 [details]
new isDefaultValue() implementation
Comment 2 Martin Krauskopf 2004-11-29 14:41:04 UTC
Sorry. Mistyped the issue number to be fixed. The right one is 45871.
Comment 3 Jesse Glick 2004-11-29 21:07:33 UTC
I think this change is unnecessary. If you override
supportsDefaultValue() to return true, of course you have to also
override isDefaultValue() to return something meaningful. The default
return value of isDefaultValue() is completely irrelevant because it
should never be called unless it is also overridden. In fact I would
support having it be

public boolean isDefaultValue() {
    if (supportsDefaultValue()) {
        throw new IllegalStateException("You must override the
isDefaultValue method!");
    } else {
        // Should never get here if using default property sheet.
        // Irrelevant what this is.
        return false;
    }
}
Comment 4 Martin Krauskopf 2004-11-30 01:04:13 UTC
You proposal implementation is ok for modules which have been
developed after adding isDefaultValue() method. But the main reason to
make this change is to be "compatible" with old modules. Authors of
these modules didn't have to be aware of isDefaultValue() because such
method didn't exist when they were writing theirs Node.Property
implementations (as it was said in issue 45871 discussion). I'm not
able to estimate how much of such modules could exist (and are
actively used) today and how much we should help them with this
compatibility. So if you still insist on you proposal and nobody else
will add an opinion I'll go your way. Thanks for opinion.
Comment 5 Jesse Glick 2004-11-30 01:59:53 UTC
I don't understand why you don't simply disable the Restore Default
Value button when !supportsDefaultValue() - in such cases the property
does not understand default values so clearly the button should be
disabled, right? Why are you even calling isDefaultValue() in such cases?
Comment 6 Martin Krauskopf 2004-11-30 08:37:15 UTC
The exact behaviour as you described is already in trunk in
PropertySheet.java:

FeatureDescriptor fd = table.getSelection();
defaultValueItem.setEnabled(fd != null &&
        fd instanceof Node.Property &&
        ((Node.Property) fd).supportsDefaultValue());

But if we want to achieve the behaviour demanded by the 45871 issue we
need to change the code to:

FeatureDescriptor fd = table.getSelection();
defaultValueItem.setEnabled(fd != null &&
        fd instanceof Node.Property &&
        ((Node.Property) fd).supportsDefaultValue() &&
        !((Node.Property) fd).isDefaultValue());

so the "Restore To Default" will be enabled ONLY when the property
supports defaultValue but currently doesn't contain defaultValue
value, otherwise not.

And as I described above the only problem could be with "bad"
Node.Property implementations - which can be case with old ones
because... described above.

I hope it's clear now :)

PS: code above is for RDV popup item (the same would applies to RDV
property editor button)
Comment 7 Jesse Glick 2004-11-30 16:24:31 UTC
"And as I described above the only problem could be with "bad"
Node.Property implementations - which can be case with old ones
because... described above." - sorry, what? If you don't override
supportsDefaultValue(), then the button is already disabled, fine. If
you do, then you have to override isDefaultValue(), in which case the
button will be enabled or not as appropriate, fine. And if you
overrode only supportsDefaultValue() for some bizarre reason, then
your N.P code is obviously in error, so why don't you just fix it?
What problem are you trying to solve here?

Obviously defaultValueItem.setEnabled needs to check both sDV() and
iDV(), so if it doesn't currently, then clearly it needs to be fixed.
But that is just a bugfix, not an API change; the default return value
is iDV() is irrelevant because it will only be called in case sDV().
Comment 8 Jaroslav Tulach 2004-11-30 16:46:33 UTC
Here is explanation for "if you overrode only supportsDefaultValue()
for some bizarre reason"
- supportsDefaultValue() is there since version 1.0
- isDefaultValue() is there since version 3.19
so the bizarre reason is that somebody wrote a module before version
3.19 and wrote it correctly - e.g. did not override isDefaultValue, as
there was no such method - and the module worked correctly, the action
SetDefaultValue was enabled. What Martin wants to do right now, is to
enable/disable the state of the action based on value of
isDefaultValue. But that means it will break modules written before
version 3.19, as they will always return isDefaultValue true and the
action will be disabled, which breaks the contract they were written
against.
Comment 9 Martin Krauskopf 2004-11-30 17:01:27 UTC
Thanks for the help Jarda. This is exactly the point. So we can:

1) Fixed the PropertySheet.java with:

 FeatureDescriptor fd = table.getSelection();
 defaultValueItem.setEnabled(fd != null &&
         fd instanceof Node.Property &&
         ((Node.Property) fd).supportsDefaultValue() &&
+        !((Node.Property) fd).isDefaultValue());

and don't touch the current API which could hurts those old modules.

2) Change the API that N.P.iDV() will return false and fix the
PropertySheet.java as in first case. So for old modules which overrode
supportsDV but don't override iDV the button will be always enabled -
which is better than always disabled

3) won't fix the issue 45871

Neither is perfrect and this was the reason why I set up this issue. I
don't know if there are enough of such modules. Thanks again Jarda and
sorry for confusion Jesse :)

Comment 10 Jesse Glick 2004-11-30 17:16:09 UTC
Yarda's explanation makes sense (nothing in this issue or #45871
previously mentioned that isDefaultValue() was added after
supportsDefaultValue()), so I guess #2 is the only option.

How is it that this problem was missed when the isDefaultValue()
method was introduced?? Probably that method was not designed
correctly; should have been

/** return true, false, or null if unknown */
public Boolean isDefaultValue() {
    return supportsDefaultValue() ? Boolean.TRUE : null;
}

with supportsDefaultValue deprecated.
Comment 11 Martin Krauskopf 2004-11-30 17:59:59 UTC
"nothing in this issue or #45871 previously mentioned that
isDefaultValue() was added after supportsDefaultValue()"

I tried to mention it in the original comment with

"....But this is problem for older modules because the
isDefaultValue() method was added after the supportsDefaultValue()
method....."

But probably other explanation was somehow confusing and Jarda's one
is surely the first one which makes clear sense. Doesn't matter now :) 

"...so I guess #2 is the only option..."

Ok, I will do so next week with leaving note in the api-changes. BTW I
found the following there (added by dstrupl):

"Method public boolean isDefaultValue() has been added to class
Node.Property. The idea behind this is to visually mark modified
properties in the property sheet. If the method returns false it means
that the value has been modified by the user and visual feedback will
be shown. The reason why the default impl is returning true is to make
the old properties (properties using previous version of the API) look
the same as they did before the change."

I'm not sure if the property sheet is implemented in the way the
comment describes - probably not. I took a look at the Form Editor
module which provides such "marking" and it seems they handle the
marking in their own way. I didn't found the iDV() method usage at any
other place. I will communicate the exact wanted behaviour with HIE.
And it is probably off-topic for this thread.

Thanks for opinions.


Comment 12 Jan Chalupa 2004-11-30 18:49:38 UTC
So I assume it's evaluated now and the target milestone can be changed
to 4.1. Correct?
Comment 13 Jesse Glick 2004-11-30 19:06:48 UTC
Whoah, careful. dstrupl's explanation of the current behavior makes
sense - if you have some UI which is supposed to display whether the
current value is the default or not, then of course you want the
default value of iDV to be true, since old properties should not have
this marking (should not be boldfaced). Perhaps any such UI should be
disabled (never boldface) in case supportsDefaultValue() is false, and
we break compatibility for properties which overrode sDV but not iDV.

Given this new information, I would be more inclined to do #3 - i.e.,
nothing; old properties have to be fixed. (I consider the effects of
your suggested fix to be perhaps worse than the current situation.)
Having a sDV method with no iDV method simply did not make much sense,
and any properties which override sDV but not iDV cannot be expected
to work properly in general and will need to be rewritten. We can at
least do a runtime check: make the default impl of iDV be

private static final Set/*<String>*/ warnedNames = new HashSet();
public boolean isDefaultValue() {
    String name = getClass().getName();
    if (supportsDefaultValue() && warnedNames.add(name)) {
        ErrorManager.getDefault().log(ErrorManager.WARNING, "Class " +
name + " must override isDefaultValue() since it overrides
supportsDefaultValue() to be true");
    }
    return false; // or whatever
}

and use Find Usages to fix all of them that we know of.
Comment 14 Martin Krauskopf 2004-12-01 02:16:36 UTC
"Given this new information, I would be more inclined to do #3 - i.e.,
nothing; ........We can at least do a runtime check: make the default
impl of iDV be ........."

Ok, I will use your proposed iDV implementation which is nice since it
will warn us once per every "bizzare" N.P. impl. per IDE session and I
will change the resolution of 45871 issue to LATER or REMIND with
Target M. to future. Although if we use "return false; // or whatever"
we can fix the 45871 issue for all our modules (however not fully for
external modules) - so it could be probably marked as fixed.
Comment 15 Jesse Glick 2004-12-01 03:52:14 UTC
We don't use resolutions of LATER or REMIND - either it is open, or it
is FIXED / WONTFIX / INVALID / WORKSFORME.
Comment 16 Jaroslav Tulach 2004-12-01 08:13:08 UTC
Loggin a warning seems to me like a good idea. But just to be sure we
know what we want, here is a bit of evalution from a module writer
point of view. We have modules:

#1 - does not override supportsDefaultValue()
#2 - old module written without knowledge of isDefaultValue
#3 - newer module overwriting just supportsDefaultValue and relying on
default
#4 - new module that overrides both methods (otherwise there would be
the warning)

We want following behaviours (correct me if I am wrong). Btw. I am
asumming that there is a request to mark modified properties in sheet
that is going to be implemented someday as well):

#1 - no set default value action, no indication in property sheet that
the value is modified, no warnings (if isDefaultValue is not called
directly by someone else than the infrastructure)
#2 - set default value action enabled, properties are marked as
unmodified, warning printed (this is what we want, let's make old
modules work unchanged and warn them about necessary changes)
#3 - same as #2 (but this case is broken since the start,
isDefaultValue should have been overriden in first)
#4 - set default value always enabled, properties marked as
appropriate, no warning printed

If this is acceptable state, I believe issue 49031 should be WONTFIX.
If someone however insists on changing:

#4 - set default value action enabled and properties marked as
appropriate, no warning printed

we can simulate the Jesse's isDefaultValue method returning
Boolean[true,false,null] by using reflection to find out from the
explorer whether the method is Node.Property.isDefaultValue() is
overriden or not. If it is then call it, otherwise just leave the
action enabled. Just write a test for this fragile behaviour and make
sure it is documented in arch*explorer.xml and arch*nodes.xml.
Comment 17 Jesse Glick 2004-12-01 15:50:16 UTC
Yes, nice summary.
Comment 18 Martin Krauskopf 2004-12-06 16:25:08 UTC
Thanks for the review. I will go the last way proposed by Yarda (using
reflection). I will post a patch here when it is done.
Comment 19 Martin Krauskopf 2004-12-07 16:03:24 UTC
Hello again.

1) I reimplemented Node.Property.isDefaultValue() as was proposed by
Jesse.
2) PropertySheet will use the reflection to decide whethere RDV
(RestoreDefaultValue action) should be enabled or not as proposed by
Yarda. Implemented in new (package-private) method in
PropUtils.shallBeRDVEnabled()
3) There are tests for all of this  - new NodeProperty51907Test.java
to tests if Warning is (not) logged appropriately and
PropUtilsTest.testRestoreDefaultValueBehaviour() to test if reflection
in shallBeRDVEnabled() works correctly in misc. cases

I will commit attached patches (follows) in a few days this week if
there are no any complains.

Comment 20 Martin Krauskopf 2004-12-07 16:04:36 UTC
Created attachment 19179 [details]
NodeProperty51907Test warning test
Comment 21 Martin Krauskopf 2004-12-07 16:05:28 UTC
Created attachment 19180 [details]
51907-patch.diff
Comment 22 Martin Krauskopf 2004-12-08 13:42:27 UTC
Created attachment 19205 [details]
arch diff
Comment 23 Martin Krauskopf 2004-12-09 14:01:06 UTC
Closing issues, thanks for the review.

Changes performed:

Checking in openide/src/org/openide/nodes/Node.java;
/cvs/openide/src/org/openide/nodes/Node.java,v  <--  Node.java
new revision: 1.90; previous revision: 1.89
done
Checking in openide/src/org/openide/explorer/propertysheet/PropUtils.java;
/cvs/openide/src/org/openide/explorer/propertysheet/PropUtils.java,v 
<--  PropUtils.java
new revision: 1.43; previous revision: 1.42
done
RCS file:
/cvs/openide/test/unit/src/org/openide/nodes/NodeProperty51907Test.java,v
done
Checking in
openide/test/unit/src/org/openide/nodes/NodeProperty51907Test.java;
/cvs/openide/test/unit/src/org/openide/nodes/NodeProperty51907Test.java,v
 <--  NodeProperty51907Test.java
initial revision: 1.1
done
Checking in openide/arch/arch-openide-propertysheet.xml;
/cvs/openide/arch/arch-openide-propertysheet.xml,v  <-- 
arch-openide-propertysheet.xml
new revision: 1.21; previous revision: 1.20
done
Checking in
openide/test/unit/src/org/openide/explorer/propertysheet/PropUtilsTest.java;
/cvs/openide/test/unit/src/org/openide/explorer/propertysheet/PropUtilsTest.java,v
 <--  PropUtilsTest.java
new revision: 1.2; previous revision: 1.1
done

Comment 24 Jaromir Uhrik 2005-07-14 16:20:22 UTC
Verified.