Author: bpoussin Date: 2010-12-15 15:49:44 +0100 (Wed, 15 Dec 2010) New Revision: 614 Url: http://nuiton.org/repositories/revision/wikitty/614 Log: Anomalie #1149: Generator Helper set method implementation for collection is buggus - generate addAll method for collection - user LinkedHashSet as default Set implementation - fix bug in getFieldAsSet in wikittyImpl that don't copy collection before return it (prevent bad side effect) - fix small bug in generator Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyDTOGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/WikittyImpl.java 2010-12-15 14:49:44 UTC (rev 614) @@ -37,6 +37,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -658,20 +659,12 @@ * @see org.nuiton.wikitty.Wikitty#getFieldAsList(java.lang.String, java.lang.String, java.lang.Class) */ @Override - public <E> List<E> getFieldAsList(String ext, String fieldName, final Class<E> clazz) { + public <E> List<E> getFieldAsList(String ext, String fieldName, Class<E> clazz) { try { - final Collection<E> collection = (Collection<E>) getFieldAsObject(ext, fieldName); + Collection<E> collection = (Collection<E>) getFieldAsObject(ext, fieldName); if (collection != null) { // return unmodiable collection that check type of element - return new AbstractList<E>() { - List<E> contained = new ArrayList<E>(collection); - @Override public E get(int index) { - return WikittyUtil.cast( contained.get(index), clazz ); - } - @Override public int size() { - return contained.size(); - } - }; + return new UnModifiableCopyList<E>(clazz, collection); } return null; } catch (Exception eee) { @@ -685,38 +678,14 @@ * @see org.nuiton.wikitty.Wikitty#getFieldAsSet(java.lang.String, java.lang.String, java.lang.Class) */ @Override - public <E> Set<E> getFieldAsSet(String ext, String fieldName, final Class<E> clazz) { + public <E> Set<E> getFieldAsSet(String ext, String fieldName, Class<E> clazz) { try { - final Set<E> result = (Set<E>) getFieldAsObject(ext, fieldName); - if (result != null) { + Collection<E> collection = (Collection<E>) getFieldAsObject(ext, fieldName); + if (collection != null) { // return unmodifable Set - return new AbstractSet<E>() { - Set<E> contained = result; - @Override public int size() { - return contained.size(); - } - @Override - public Iterator<E> iterator() { - return new Iterator<E>() { - Iterator containedIterator = contained.iterator(); - public boolean hasNext() { - return containedIterator.hasNext(); - } - - public E next() { - Object o = containedIterator.next(); - return WikittyUtil.cast(o, clazz); - } - - public void remove() { - throw new UnsupportedOperationException("Not supported operation"); - } - }; - - } - }; + return new UnModifiableCopySet<E>(clazz, collection); } - return result; + return null; } catch (Exception eee) { throw new WikittyException(String.format( "Can't get value to field '%s'", @@ -734,7 +703,8 @@ Collection col = (Collection) getFieldAsObject(ext, fieldName); if (col == null) { if (fieldType.isUnique()) { - col = new HashSet(); + // LinkedHashSet to try to maintains order + col = new LinkedHashSet(); } else { col = new ArrayList(); } @@ -966,4 +936,68 @@ return result; } + /** + * unmodifiable collection, source is copied to prevent source modification + * after creation. + */ + static class UnModifiableCopyList<E> extends AbstractList<E> { + protected Class<E> clazz; + protected List<E> contained; + + public UnModifiableCopyList(Class<E> clazz, Collection<E> source) { + this.clazz = clazz; + // make copy to prevent modification of source collection + contained = new ArrayList<E>(source); + } + + @Override + public E get(int index) { + return WikittyUtil.cast(contained.get(index), clazz); + } + @Override + public int size() { + return contained.size(); + } + // no need to Override iterator, because AbstractList based all iterator + // operation on AbstractList aperation + } + + + /** + * unmodifiable collection, source is copied to prevent source modification + * after creation. + */ + static class UnModifiableCopySet<E> extends AbstractSet<E> { + protected Class<E> clazz; + protected Set<E> contained; + public UnModifiableCopySet(Class<E> clazz, Collection<E> source) { + this.clazz = clazz; + // make copy to prevent modification of source collection + contained = new LinkedHashSet<E>(source); + } + + @Override + public int size() { + return contained.size(); + } + @Override + public Iterator<E> iterator() { + return new Iterator<E>() { + Iterator containedIterator = contained.iterator(); + public boolean hasNext() { + return containedIterator.hasNext(); + } + + public E next() { + Object o = containedIterator.next(); + return WikittyUtil.cast(o, clazz); + } + + public void remove() { + throw new UnsupportedOperationException("Not supported operation"); + } + }; + } + } + } Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/api/WikittyUtilTest.java 2010-12-15 14:49:44 UTC (rev 614) @@ -33,6 +33,7 @@ import java.util.Date; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.commons.beanutils.BeanUtils; @@ -618,7 +619,7 @@ protected String wikittyId; protected String wikittyVersion = "0.0"; @WikittyField(fqn="WikittyLabel.labels") - protected Set<String> labels = new HashSet<String>(); + protected Set<String> labels = new LinkedHashSet<String>(); public LabelDTO(String wikittyId) { this.wikittyId = wikittyId; @@ -648,10 +649,16 @@ return labels; } + @Override public void setLabels(Set<String> labels) { - this.labels = labels; + this.labels = new LinkedHashSet<String>(labels); } + @Override + public void addAllLabels(Set<String> labels) { + this.labels.addAll(labels); + } + /** * addLabels : * @param element Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2010-12-15 14:49:44 UTC (rev 614) @@ -360,7 +360,19 @@ getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, oldValue, <%= getter.getName() %>()); }*/; setOperationBody(setter, setterBody); - + + String addAllName = "addAll" + capitalizedAttributeName; + ObjectModelOperation addAll = addOperation(abstractClass, addAllName, "void"); + addAnnotation(abstractClass, addAll, "Override"); + addParameter(addAll, attributeTypeSimpleNameInSet, attributeName); + String addAllBody = "" +/*{ + <%=attributeTypeSimpleNameInSet%> oldValue = get<%=capitalizedAttributeName%>(); + <%=helperClassName%>.<%=addAllName%>(getWikitty(), <%=attributeName%>); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, oldValue, <%= getter.getName() %>()); +}*/; + setOperationBody(addAll, addAllBody); + String addName = "add" + capitalizedAttributeName; ObjectModelOperation adder = addOperation(abstractClass, addName, "void"); addAnnotation(abstractClass, adder, "Override"); @@ -622,17 +634,37 @@ String setterName = "set" + attributeNameCapitalized; ObjectModelOperation setter = addOperation(abstractClassForThisMetaExtension, setterName, "void"); addAnnotation(abstractClassForThisMetaExtension, setter, "Override"); - addParameter(setter,"Set<String>","values"); + addParameter(setter, attributeTypeSimpleNameInSet, "values"); String setterBody = "" /*{ - for (String value:values){ - add<%=attributeNameCapitalized%>(value); + if (extensionForMetaExtension == null) { + <%=helperClassName%>.<%=setterName%>(getWikitty(), values); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%=getter.getName()%>()); + } else { + <%=helperClassName%>.<%=setterName%>(extensionForMetaExtension.getName(), getWikitty(), values); + String fieldName = <%=helperClassName%>.getMetaFieldName(extensionForMetaExtension, "<%=attributeName%>"); + getPropertyChangeSupport().firePropertyChange(fieldName, null, <%=getter.getName()%>()); } }*/; setOperationBody(setter, setterBody); + String addAllName = "addAll" + attributeNameCapitalized; + ObjectModelOperation addAll = addOperation(abstractClassForThisMetaExtension, addAllName, "void"); + addAnnotation(abstractClassForThisMetaExtension, addAll, "Override"); + addParameter(addAll, attributeTypeSimpleNameInSet, "values"); + String addAllBody = "" +/*{ + if (extensionForMetaExtension == null) { + <%=helperClassName%>.<%=addAllName%>(getWikitty(), values); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%=getter.getName()%>()); + } else { + <%=helperClassName%>.<%=addAllName%>(extensionForMetaExtension.getName(), getWikitty(), values); + String fieldName = <%=helperClassName%>.getMetaFieldName(extensionForMetaExtension, "<%=attributeName%>"); + getPropertyChangeSupport().firePropertyChange(fieldName, null, <%=getter.getName()%>()); + } +}*/; + setOperationBody(addAll, addAllBody); - String addName = "add" + attributeNameCapitalized; ObjectModelOperation adder = addOperation(abstractClassForThisMetaExtension, addName, "void"); addAnnotation(abstractClassForThisMetaExtension, adder, "Override"); Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java 2010-12-15 14:49:44 UTC (rev 614) @@ -229,6 +229,10 @@ ObjectModelOperation setter = addOperation(contract, setterName, "void"); addParameter(setter, attributeTypeSimpleNameInSet, attributeName); + String addAllName = "addAll" + StringUtils.capitalize(attributeName); + ObjectModelOperation addAll = addOperation(contract, addAllName, "void"); + addParameter(addAll, attributeTypeSimpleNameInSet, attributeName); + String addName = "add" + StringUtils.capitalize(attributeName); ObjectModelOperation adder = addOperation(contract, addName, "void"); addParameter(adder, "String", "element"); Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyDTOGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyDTOGenerator.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyDTOGenerator.java 2010-12-15 14:49:44 UTC (rev 614) @@ -29,6 +29,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -195,8 +196,8 @@ String collectionType = WikittyTransformerUtil.getCollectionTypeName(attribute); if (Set.class.getSimpleName().equals(collectionType)){ addImport(abstractClass, Set.class); - addImport(abstractClass, HashSet.class); - attributeTypeInSetImpl = "HashSet<String>"; + addImport(abstractClass, LinkedHashSet.class); + attributeTypeInSetImpl = "LinkedHashSet<String>"; } if (List.class.getSimpleName().equals(collectionType)){ addImport(abstractClass, List.class); @@ -234,12 +235,28 @@ if (<%=attributeName%> == null){ this.<%=attributeName%> = new <%=attributeTypeInSetImpl%>(); } else { - this.<%=attributeName%>=<%=attributeName%>; + // make copy to prevent modification of source collection + this.<%=attributeName%>=new <%=attributeTypeInSetImpl%>(<%=attributeName%>); } modificationCount++; }*/; setOperationBody(setter, setterBody); + // adding the addAll + String addAllName = "addAll" + StringUtils.capitalize(attributeName); + ObjectModelOperation addAll = addOperation(abstractClass, addAllName, "void"); + addAnnotation(abstractClass, addAll, "Override"); + addParameter(addAll, attributeTypeInSet, attributeName); + String addAllBody = "" +/*{ + if (this.<%=attributeName%> == null){ + this.<%=attributeName%> = new <%=attributeTypeInSetImpl%>(); + } + this.<%=attributeName%>.addAll(<%=attributeName%>); + modificationCount++; +}*/; + setOperationBody(addAll, addAllBody); + //adding the add method String addName = "add" + StringUtils.capitalize(attributeName); ObjectModelOperation adder = addOperation(abstractClass, addName, "void"); @@ -247,10 +264,10 @@ addParameter(adder, attributeType, "element"); String adderBody = "" /*{ - if (<%=attributeName%> == null){ + if (this.<%=attributeName%> == null){ this.<%=attributeName%> = new <%=attributeTypeInSetImpl%>(); } - <%=attributeName%>.add(element); + this.<%=attributeName%>.add(element); modificationCount++; }*/; setOperationBody(adder, adderBody); @@ -634,7 +651,7 @@ String collectionType = WikittyTransformerUtil.getCollectionTypeName(attribute); if (Set.class.getSimpleName().equals(collectionType)) { attributeTypeInSet = "Set<String>"; - attributeTypeInSetImpl = "HashSet<String>"; + attributeTypeInSetImpl = "LinkedHashSet<String>"; } if (List.class.getSimpleName().equals(collectionType)) { attributeTypeInSet = "List<String>"; Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-12-15 11:58:08 UTC (rev 613) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-12-15 14:49:44 UTC (rev 614) @@ -143,13 +143,24 @@ addParameter(setter, attributeTypeSimpleNameInSet, attributeName); String setterBody = "" /*{ + clear<%=attributeNameCapitalized%>(wikitty); + addAll<%=attributeNameCapitalized%>(wikitty, <%=attributeName%>); +}*/; + setOperationBody(setter, setterBody); + + String addAllName = "addAll" + attributeNameCapitalized; + ObjectModelOperation addAll = addOperation(helper, addAllName, "void", ObjectModelModifier.STATIC); + addParameter(addAll, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + addParameter(addAll, attributeTypeSimpleNameInSet, attributeName); + String addAllBody = "" +/*{ if(<%=attributeName%> != null){ for (String id:<%=attributeName%>){ add<%=attributeNameCapitalized%>(wikitty, id); } } }*/; - setOperationBody(setter, setterBody); + setOperationBody(addAll, addAllBody); String addName = "add" + attributeNameCapitalized; ObjectModelOperation adder = addOperation(helper, addName, "void", ObjectModelModifier.STATIC); @@ -382,16 +393,30 @@ String setterName = "set" + capitalizedAttributeName; ObjectModelOperation setter = addOperation(helper, setterName, "void", ObjectModelModifier.STATIC); addParameter(setter, "String", "extensionName"); + addParameter(setter, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); addParameter(setter, attributeTypeSimpleNameInSet, attributeName); - addParameter(setter, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); String setterBody = "" /*{ - for (String id:<%=attributeName%>){ - add<%=capitalizedAttributeName%>(extensionName, wikitty, id); - } + clear<%=capitalizedAttributeName%>(extensionName, wikitty); + addAll<%=capitalizedAttributeName%>(extensionName, wikitty, <%=attributeName%>); }*/; setOperationBody(setter, setterBody); + String addAllName = "addAll" + capitalizedAttributeName; + ObjectModelOperation addAll = addOperation(helper, addAllName, "void", ObjectModelModifier.STATIC); + addParameter(addAll, "String", "extensionName"); + addParameter(addAll, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + addParameter(addAll, attributeTypeSimpleNameInSet, attributeName); + String addAllBody = "" +/*{ + if(<%=attributeName%> != null){ + for (String id:<%=attributeName%>){ + add<%=capitalizedAttributeName%>(extensionName, wikitty, id); + } + } +}*/; + setOperationBody(addAll, addAllBody); + String addName = "add" + capitalizedAttributeName; ObjectModelOperation adder = addOperation(helper, addName, "void", ObjectModelModifier.STATIC); addParameter(adder, "String", "extensionName");