| //------------------------------------------------------------------------------ |
| // 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.MethodConfiguration; |
| 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, MethodConfiguration config) { |
| |
| 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; |
| if (config != null && !LibraryEditUtil.getInstance().inConfig(contributor, config)) { |
| continue; |
| } |
| 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; |
| } |
| |
| |
| } |