blob: 74eee2fa6aacfea3b7b745af336bf02177cab48e [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2009 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.edit.util.model.OrderInfo;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityType;
/**
* Helper class to handle manual sorting of Category elements
* @author Weiping Lu
*/
public class ManualSort {
public ManualSort() {
}
public List<Object> sort(ContentCategory cc, List<Object> elementList,
EStructuralFeature feature) {
List<OrderInfo> orderInfoList = new ArrayList<OrderInfo>();
for (Iterator iter = TngUtil.getContributors(cc); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof ContentCategory) {
ContentCategory contributor = (ContentCategory) obj;
OrderInfo orderInfo = TngUtil.getOrderInfo(contributor, ContentElementOrderList.ORDER_INFO_NAME);
if (orderInfo != null) {
orderInfoList.add(orderInfo);
}
}
}
if (orderInfoList.size() == 1){
return sort(elementList, orderInfoList.get(0));
}
OrderInfo orderInfo = TngUtil.getOrderInfo(cc, ContentElementOrderList.ORDER_INFO_NAME);
elementList = sort(elementList, orderInfo);
if (orderInfoList.isEmpty()) {
return elementList;
}
//Sorting by time-stamp to make sure contributing order is deterministic
Collections.sort(orderInfoList, orderInfoComp);
SortData sortData = new SortData(cc, elementList, feature);
for (OrderInfo info : orderInfoList) {
sortData.processOrderInfo(info);
}
return sortData.getSortedList();
}
static class SortData {
private Map<String, MethodElement> guidMap;
private Set<String> processedGuidSet;
private LinkedHashMap<String, List<MethodElement>> orderedMap;
private List<Object> elementList;
public SortData(ContentCategory cc, List<Object> elementList, EStructuralFeature feature) {
this.elementList = elementList;
//Build baseCategorizedElementGuids
Set<String> baseCategorizedElementGuids = new HashSet<String>();
ContentCategory base = cc;
while (base != null) {
addToBaseCategorizedElementGuids(feature, baseCategorizedElementGuids, base);
if (base != cc) {
for (Iterator iter = TngUtil.getContributors(base); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof ContentCategory) {
ContentCategory contributor = (ContentCategory) obj;
addToBaseCategorizedElementGuids(feature, baseCategorizedElementGuids, contributor);
}
}
}
if (base.getVariabilityType() == VariabilityType.EXTENDS ||
base.getVariabilityType() == VariabilityType.EXTENDS_REPLACES) {
base = (ContentCategory) base.getVariabilityBasedOnElement();
} else {
base = null;
}
}
//Build guidMap and orderedMap
guidMap = new HashMap<String, MethodElement>();
orderedMap = new LinkedHashMap<String, List<MethodElement>>();
for (Object obj : elementList) {
if (obj instanceof MethodElement) {
MethodElement element = (MethodElement) obj;
String guid = element.getGuid();
guidMap.put(guid, element);
if (baseCategorizedElementGuids.contains(guid)) {
List<MethodElement> list = new ArrayList<MethodElement>();
orderedMap.put(guid, list);
}
}
}
processedGuidSet = new HashSet<String>();
}
private void addToBaseCategorizedElementGuids(EStructuralFeature feature,
Set<String> baseCategorizedElementGuids, ContentCategory cc) {
Object value = cc.eGet(feature);
if (value instanceof List) {
for (Object obj : (List) value) {
if (obj instanceof MethodElement) {
baseCategorizedElementGuids.add(((MethodElement) obj).getGuid());
}
}
}
}
public void processOrderInfo(OrderInfo orderInfo) {
List<MethodElement> addedList = new ArrayList<MethodElement>();
for (String guid : (List<String>) orderInfo.getGUIDs()) {
MethodElement element = (MethodElement) guidMap.get(guid);
if (element != null) {
boolean processed = processedGuidSet.contains(guid);
if (! processed) {
processedGuidSet.add(guid);
addedList.add(element);
}
List list = orderedMap.get(guid);
if (list != null) {
addedList.addAll(list);
orderedMap.put(guid, addedList);
addedList = new ArrayList<MethodElement>();
}
}
}
}
public List<Object> getSortedList() {
List<Object> sortedList = new ArrayList<Object>();
for (Map.Entry entry : orderedMap.entrySet()) {
String guid = (String) entry.getKey();
List list = (List) entry.getValue();
if (list.isEmpty()) {
sortedList.add(guidMap.get(guid));
} else {
for (Object element : list) {
sortedList.add(element);
}
}
}
for (Object obj : elementList) {
if (obj instanceof MethodElement) {
if (! processedGuidSet.contains(((MethodElement) obj).getGuid())) {
sortedList.add(obj);
}
} else {
sortedList.add(obj);
}
}
return sortedList;
}
}
private static Comparator<OrderInfo> orderInfoComp = new Comparator<OrderInfo>() {
public int compare(OrderInfo o1, OrderInfo o2) {
long t1 = o1.getTimestamp();
long t2 = o2.getTimestamp();
if (t1 < t2) {
return -1;
} else if (t2 < t1) {
return 1;
}
return 0;
}
};
private List<Object> sort(List<Object> elementList, OrderInfo orderInfo) {
if (orderInfo == null) {
return elementList;
}
Map<String, MethodElement> guidMap = new HashMap<String, MethodElement>();
for (Object obj : elementList) {
if (obj instanceof MethodElement) {
guidMap.put(((MethodElement) obj).getGuid(), (MethodElement) obj);
}
}
List<Object> returnList = new ArrayList<Object>();
for (String guid : (List<String>) orderInfo.getGUIDs()) {
Object element = guidMap.get(guid);
if (element != null) {
returnList.add(element);
guidMap.remove(guid);
}
}
for (Object obj : elementList) {
if (obj instanceof MethodElement) {
if (guidMap.containsKey(((MethodElement) obj).getGuid())) {
returnList.add(obj);
}
} else {
returnList.add(obj);
}
}
return returnList;
}
}