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 78539

Summary: Global Preference Collection Override preference doesn't work
Product: uml Reporter: bugbridge <bugbridge>
Component: GeneralAssignee: Craig Conover <conover>
Status: VERIFIED FIXED    
Severity: blocker CC: hlu, sj-nb
Priority: P1    
Version: 5.x   
Hardware: PC   
OS: Windows XP   
Issue Type: DEFECT Exception Reporter:
Bug Depends on: 84855, 88124    
Bug Blocks: 78473, 78541    

Description bugbridge 2006-06-20 12:43:19 UTC
Description:
reproducible with 050606_20,

steps to reproduce:
1. create class diagram
2. add class 'a' to the diagram
3. check Collection Override property (it is ArrayList by default)
(Tools->Options, UML->Round Trip Engineering|Java)
4. add attribute with multiplicity
result:
array is used for source generation.


Evaluation:
The methods in roundtrip APIs that pertain to multiplicity don't appear to be
getting invoked at all.

Evaluation (Entry 2):
As per Trey, the changes probably need to be performed in ideintegration module
in the NBEventProcessor class. However, it appears that this is too late in the
process and the changes might need to be made in core module in
JavaAttributeChangeHandler in method multiplicityChange. I think this is where
the multiplicity is transformed into an array and the collection override should
be handled.

Major problem I see is that the collection override property is freeform, so how
are we to know exactly what to do with it? Perhaps this property needs to be a
prese list of available datatypes?

Evaluation (Entry 3):
After a lot of investigation and thought, if you wanted to use an ArrayList or
any sort of Collection instead of an Array (String[]), wouldn't you just specify
it as such: "ArrayList foo"? Or is this not following the UML standards?

Because the modeler is specifying an attr to be of type String, then they are
declaring the multiplicity. But if they want to use Collections, why not just
specify the collection datatype of choice for the attr type?

Again, I might just not understand UML spec very well.

Evaluation (Entry 4):
/
We shouldn't mix modeling and code generation even if we generate code after
each modeling step, if user wants a set of strings he will specify ... string[]
name in model to see the type and to have a set, but when user want code for his
model he may want to use collections in source (feature was introduced when
there were no generics, of cause with generics it may be more appropriate for
users to specify collection type with geneic in model too if we are supporting
such specification).
/
As for automatic recognition of collectins and automatic adding of
multiplicities we can't rean users' mind (I hope there will be MindReader class
in Java-10 :)) and ArrayList and ArrayList[] isn't the same, first have no
multiplicity and second have.. as an option we may ask user on each collection
we see in code what to do with collection and if user specify collection will
have srings we can update model with string[] instead of CollectionX, but I
think it's a wast of time, espesially there may be too many dialogs during RE of
big java project.

Evaluation (Entry 5):
fix failed, build 060423
main issue:
- collection override do not work with Use generics = No 
additional (with Use Generics=Yes):
- addition of private String A[*] leads to next code:
public class dds {
    private ArrayList<String> a;
    public dds() {
    }
    public ArrayList<String> getA() {
        return a;
    }
    public void setA(ArrayList val) { //BUG
        this.a = val;
    }
}
may be one more CR shopuld be filed:
- after addition of import java.lang.ArrayList with ALT+SHIFT+I generic is
removed from getter.
additional:
- add second 'private Object B[*]', next accessors are generated:
    public ArrayList<ArrayList<Object>> getB() {//BUG
        return B;
    }

    public void setB(ArrayList val) {BUG
        this.B = val;
    }
- in both cases model should use the same syntax as attribute i.e. String[] or
Object[], it uses ArrayList type in accessors.


Comments (Entry 1):

It might be necessary to make the Collection Override a drop down list of fixed
Collection subtype classes. Here is the current list that Java API knows about:

AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList,
AbstractSet, ArrayBlockingQueue,  ArrayList, AttributeList,
BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedQueue,
CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet,
JobStateReasons, LinkedBlockingQueue, LinkedHashSet, LinkedList,
PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack,
SynchronousQueue, TreeSet, Vector

Comments (Entry 2):

I was able to override array types with a Collection type (ArrayList), but this
negates the Multiplicity setting in the UML world. This maybe better than no
Collection Override setting at all, but it is not the right way.

Ultimately, we want the UML module to recognize a type as a Collection type and
set/preserve Multiplicity setting for the Attrribute as appropriate.

This still remains a challenge and needs to be resolved.


Comments (Entry 3):
About why not use collection instead of string with muliplicity, I have rfe on
java5 generics support addition to the feature, the issue may arise on forums
etc when main issue will be fixed.
About automatic determination of multiplicity for collection classes, I thin it
may be handled in separate isse, this issue cover only forward round trip while
automatic recognision cover backward roundtrip and work on diagram without
sources at all.


Comments (Entry 4):

I have considered the first point (using generics) with this fix, but realize it
requires the addition of another flag or more thought as to whether to use
generics or not. 

As to the last point about fwd/bwd RT engineering, if I just fix it going
forward, I cause a regression: multiplicities are broken/removed when RT is in
affect. I don't think this issue should be addressed without addressing the
whole issue.


Comments (Entry 5):

The fix was very simple as it turns out. The Collection Override code that
populates this preference was commented out and then still needed some
adjustment to populate correctly.

So the end result is that the modeler can enter any thing they want in the
Collection Override property, so it is up to them to make sure it really is a
valid Collection type and that it is spelled correctly.

In the UML model, the modeler will enter something like this:
private String foot[10]

and the code that is generated will look like this (assuming ArrayList is the
Collection Override datatype specified):
private ArrayList foo = new ArrayList();

However, the UML model will then be adjusted by changing the multiplicity from
[5] to [0,*]. Since an ArrayList is dynamic and not bounded by an initial value,
this is correct even if the modeler wishes to specify a bounded multiplicy
setting like 1..5 or such. Perhaps this will lead to another CR to fix it so
that the multiplicity is not tampered with.


Comments (Entry 6):

Now working on adding in a "use generics" option flag that will generate the
proper generics code. Some of the code was already there, it just wasn't being
invoked. Multi-dimensional collection generics had to be implemented so that the
following would work:

These model attribute elements:
public String foo
public String foo[]
public String foo[][]
public String foo[][][]

should generate this code:
public String foo;
public ArrayList<String> foo;
public ArrayList<ArrayList<String>> foo;
public ArrayList<ArrayList<ArrayList<String>>> foo;


Comments (Entry 7):
It's all working as expected. The one drawback and potentially a CR bug
candidate is that if you Update Model from Source, and you have an attribute of
type ArrayList<String>, it will update the model to show the UML Attribute
element like this: public ArrayList foo, with no multiplicity settings. This is
another area altogether and probably should be address so that forward and
backward trips are consistent.


Comments (Entry 8):
Still trying to build locally to ensure it doesn't break anything before I
commit the mods. Should happen by noon today (4/20).


Comments (Entry 9):

Fixes have been delivered. I would suggest trying to break this in any way
possible. I did some thorough nested array like String[][][][] to ensure the
nested generic ArrayList was generated properly and that the multiplicity is
preserved.


Comments (Entry 10):
I was able to fix the problem where the seter/getter doesn't get the right
generic/collection type when the attriute is created/modified in the model. But
I am still working on what should be done if the attribute is created as an
array type in the source... what should the model do? Should it create the
multiplicity attr and then turnaround and change the source code to be a
generic/collection type or leave the source code as is?


Comments (Entry 11):
I think the best way to do only what user do, i.e. model should show attribute
of type entred by user without multiplicity at least for cases like
ArrayList<String>
in case ArrayList<String>[] the is a multiplicity of cause
in case ArrayList<ArrayList<String>> I do not know too.. may be the same as in
first case.
What about non generic option?


Comments (Entry 12):
After considerable debugging efforts to find the correct interception point, I
believe I have found it and the appropriate way to handle it. Now it is a matter
of addressing all the possible permutations of the states of the following
conditions:

Model attr type
Model attr multiplicity
Source attr type
Attr added in source or model
Attr type changed in source or model
Soure attr's type is Collection type (when updating model)
Collection Override is active
Use Generics for Collections is active
and so on...
Comment 1 Craig Conover 2006-08-21 21:37:50 UTC
*** Issue 78684 has been marked as a duplicate of this issue. ***
Comment 2 Craig Conover 2006-09-20 00:47:41 UTC
This issue will be address after roundtrip redesign efforts are completed.
Comment 3 Craig Conover 2006-10-11 20:39:31 UTC
This issue should be addressed after Roundtrip Redesign is finished
Comment 4 Craig Conover 2006-10-11 20:42:10 UTC
*** Issue 86840 has been marked as a duplicate of this issue. ***
Comment 5 Craig Conover 2006-10-18 05:58:42 UTC
I am very close to a simple solution to generating Collections for attributes
with multiplicity, but it is not very well tested. Only verified to work for
simple multiplicity scenarios. Multi-dimension not supported. So I am not
integrating at this time. Couple more days of work should and should be able to
have this implemented.
Comment 6 Craig Conover 2006-10-19 00:05:18 UTC
Integrated some progress, but the actionable code is disabled
Comment 7 Craig Conover 2006-10-26 17:23:14 UTC
I have the global Collection Override and Use Generics preferences working for
Generate Code. 

In other words, attributes, params and return types with multiplicity are having
code generated using the specified Collection Override data type and with
generics if the Use Generics pref is true. If the Collection Override pref is
empty, then simple arrays are generated and Use Generics is obviously ignored.

Reverse Engineer action is not parsing generics properly, though, but that is
another issue separate from this one.

The mods for this issue may not be checked in, however. This is because the
complete and proper fix for this is an enhancement (issue 78473) that adds the
Collection Override and Use Generics property at the attribute/parameter/return
type level, rather than a global preference for all of the elements in the model
project and every other model project. Completing the implementation for that
issue is (should be) just around the corner.
Comment 8 Craig Conover 2006-10-27 17:55:45 UTC
Added a dependency on issue 88124 (imports not being generated). The reason this
is dependent is because there are no imports generated for all the collections
that are used making this feature useless.
Comment 9 Craig Conover 2006-10-30 05:03:45 UTC
Code generation now checks for the Collection Override Default global
preference. If that pref contains a fully qualified Collection type (one that
can be validated as a Collection implementor or subclass of such type) will be
used in place of arrays for any attribute, parameter or return type that has
multiplicity. Multiple levels of multiplicity are considered as well for
multi-dimensional types.

The Use Generics Default global preference will be used in conjunction with the
Collection Override Default pref. When set to yes, generic types are generated
for the Collection data types based on the actual type of the element.

Most of the code involved in this has been overhauled, so rigorous testing is
recommended with anything related to the code generation wrt the types of the
elements.
Comment 10 Sergey Petrov 2006-11-13 14:15:06 UTC
verified from "options" point of view,preference exists and works in some cases,
another cases should be filed against code generation
verified with 061112-2