org.nakedobjects.metamodel.facets.ordering.memberorder.DeweyOrderSet Maven / Gradle / Ivy
package org.nakedobjects.metamodel.facets.ordering.memberorder;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.nakedobjects.metamodel.facets.ordering.OrderSet;
import org.nakedobjects.metamodel.specloader.internal.peer.NakedObjectMemberPeer;
/**
* Represents a nested hierarchy of ordered members.
*
*
* At each level the elements are either {@link NakedObjectMemberPeer}s or they are instances of
* {@link OrderSet} represent a group of {@link NakedObjectMemberPeer}s that have a {@link MemberOrderFacet}
* of the same name.
*
*
* With no name, (ie name="" is the default), at the top level
*
*
* MemberOrder(sequence="1")
* MemberOrder(sequence="1.1")
* MemberOrder(sequence="1.2")
* MemberOrder(sequence="1.2.1")
* MemberOrder(sequence="1.3")
*
*
*
* With names, creates a hierarchy.
*
*
* MemberOrder(sequence="1.1") // no parent
* MemberOrder(sequence="1.2.1")
* MemberOrder(sequence="1.3")
* MemberOrder(name="abc", sequence="1") // group is abc, parent is ""
* MemberOrder(name="abc", sequence="1.2")
* MemberOrder(name="abc,def", sequence="1") // group is def, parent is abc
* MemberOrder(name="abc,def", sequence="1.2")
*
*
*/
public class DeweyOrderSet extends OrderSet {
public static DeweyOrderSet createOrderSet(final NakedObjectMemberPeer[] members) {
final SortedMap sortedMembersByGroup = new TreeMap();
final SortedSet nonAnnotatedGroup = new TreeSet(new MemberIdentifierComparator());
// spin over all the members and put them into a Map of SortedSets
// any non-annotated members go into additional nonAnnotatedGroup set.
for (int i = 0; i < members.length; i++) {
final NakedObjectMemberPeer member = members[i];
final MemberOrderFacet memberOrder = member.getFacet(MemberOrderFacet.class);
if (memberOrder == null) {
nonAnnotatedGroup.add(member);
continue;
}
final SortedSet sortedMembersForGroup = getSortedSet(sortedMembersByGroup, memberOrder.name());
sortedMembersForGroup.add(member);
}
// add the non-annotated group to the first "" group.
final SortedSet defaultSet = getSortedSet(sortedMembersByGroup, "");
defaultSet.addAll(nonAnnotatedGroup);
// create OrderSets, wiring up parents and children.
// since sortedMembersByGroup is a SortedMap, the
// iteration will be in alphabetical order (ie parent groups before their children).
final Set groupNames = sortedMembersByGroup.keySet();
final SortedMap orderSetsByGroup = new TreeMap();
for (final Iterator iter = groupNames.iterator(); iter.hasNext();) {
final String groupName = (String) iter.next();
final DeweyOrderSet deweyOrderSet = new DeweyOrderSet(groupName);
orderSetsByGroup.put(groupName, deweyOrderSet);
ensureParentFor(orderSetsByGroup, deweyOrderSet);
}
// now populate the OrderSets
for (final Iterator iter = groupNames.iterator(); iter.hasNext();) {
final String groupName = (String) iter.next();
final DeweyOrderSet deweyOrderSet = (DeweyOrderSet) orderSetsByGroup.get(groupName);
final SortedSet sortedMembers = (SortedSet) sortedMembersByGroup.get(groupName);
deweyOrderSet.addAll(sortedMembers);
deweyOrderSet.copyOverChildren();
}
return (DeweyOrderSet) orderSetsByGroup.get("");
}
/**
* Recursively creates parents all the way up to root (""), along the way associating each child
* with its parent and adding the child as an element of its parent.
*
* @param orderSetsByGroup
* @param deweyOrderSet
*/
private static void ensureParentFor(final SortedMap orderSetsByGroup, final DeweyOrderSet deweyOrderSet) {
final String parentGroup = deweyOrderSet.getGroupPath();
DeweyOrderSet parentOrderSet = (DeweyOrderSet) orderSetsByGroup.get(parentGroup);
if (parentOrderSet == null) {
parentOrderSet = new DeweyOrderSet(parentGroup);
orderSetsByGroup.put(parentGroup, parentOrderSet);
if (!parentGroup.equals("")) {
ensureParentFor(orderSetsByGroup, deweyOrderSet);
}
}
// check in case at root
if (deweyOrderSet != parentOrderSet) {
deweyOrderSet.setParent(parentOrderSet);
parentOrderSet.addChild(deweyOrderSet);
}
}
/**
* Gets the SortedSet with the specified group from the supplied Map of SortedSets.
*
*
* If there is no such SortedSet, creates.
*
* @param sortedMembersByGroup
* @param groupName
* @return
*/
private static SortedSet getSortedSet(final SortedMap sortedMembersByGroup, final String groupName) {
SortedSet sortedMembersForGroup;
sortedMembersForGroup = (SortedSet) sortedMembersByGroup.get(groupName);
if (sortedMembersForGroup == null) {
sortedMembersForGroup = new TreeSet(new MemberOrderComparator(true));
sortedMembersByGroup.put(groupName, sortedMembersForGroup);
}
return sortedMembersForGroup;
}
// /////////////////////////////////////////////////////////////////////////
private DeweyOrderSet(final String groupName) {
super(groupName);
}
/**
* Format is: abc,def:XXel/YYm/ZZch
*
* where abc,def is group name, XX is number of elements,
* YY is number of members, and
* ZZ is number of child order sets.
*/
@Override
public String toString() {
return getGroupFullName() + ":" + size() + "el/" + (size() - childOrderSets.size()) + "m/" + childOrderSets.size() + "ch";
}
}
// Copyright (c) Naked Objects Group Ltd.