| /******************************************************************************* |
| * Copyright (c) 2010, 2015 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 API and implementation |
| *******************************************************************************/ |
| package org.eclipse.help.internal.criteria; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.help.IUAElement; |
| import org.eclipse.help.internal.UAElement; |
| |
| /* |
| * Assembles individual criteria definition contributions into a complete, fully |
| * criteria definition. |
| */ |
| public class CriteriaDefinitionAssembler { |
| |
| /* |
| * Assembles the given criteria definition contributions into a complete criteria definition. |
| * The originals are not modified. |
| */ |
| public CriteriaDefinition assemble(List contributions) { |
| return merge(contributions); |
| } |
| |
| /* |
| * Merge all criteria definition contributions into one. |
| */ |
| private CriteriaDefinition merge(List contributions) { |
| CriteriaDefinition criteriaDefinition = new CriteriaDefinition(); |
| Iterator iter = contributions.iterator(); |
| while (iter.hasNext()) { |
| CriteriaDefinitionContribution contribution = (CriteriaDefinitionContribution)iter.next(); |
| mergeChildren(criteriaDefinition, (CriteriaDefinition)contribution.getCriteriaDefinition()); |
| contribution.setCriteriaDefinition(null); |
| } |
| return criteriaDefinition; |
| } |
| |
| /* |
| * Merges the children of nodes a and b, and stores them into a. If the two |
| * contain the same criterion id, only one is kept but its children are merged, |
| * recursively. In one criterion, if multiple criterion values exist with the |
| * same id, only the first one found is kept. |
| * |
| * Insure criterion has its id at least, and criterion value has both its id and name. |
| */ |
| private void mergeChildren(UAElement a, UAElement b) { |
| Map criterionById = new HashMap(); |
| Set criterionValueIds = new HashSet(); |
| |
| IUAElement[] childrenA = a.getChildren(); |
| for(int i = 0; i < childrenA.length; ++i){ |
| UAElement childA = (UAElement)childrenA[i]; |
| if(childA instanceof CriterionDefinition) { |
| String id = childA.getAttribute(CriterionDefinition.ATTRIBUTE_ID); |
| if(null != id && id.trim().length() > 0) { |
| criterionById.put(childA.getAttribute(CriterionDefinition.ATTRIBUTE_ID), childA); |
| } |
| } else if(childA instanceof CriterionValueDefinition) { |
| String valueId = childA.getAttribute(CriterionValueDefinition.ATTRIBUTE_ID); |
| String valueName = childA.getAttribute(CriterionValueDefinition.ATTRIBUTE_NAME); |
| if(null != valueId && valueId.trim().length() > 0 && null != valueName && valueName.trim().length() > 0){ |
| criterionValueIds.add(childA.getAttribute(CriterionValueDefinition.ATTRIBUTE_ID)); |
| } |
| } |
| } |
| |
| IUAElement[] childrenB = b.getChildren(); |
| for(int i = 0; i < childrenB.length; ++i){ |
| UAElement childB = (UAElement) childrenB[i]; |
| if(childB instanceof CriterionDefinition) { |
| String idB = childB.getAttribute(CriterionDefinition.ATTRIBUTE_ID); |
| if(null != idB && idB.trim().length() > 0){ |
| if (criterionById.containsKey(idB)) { |
| // duplicate id; merge children |
| mergeChildren((CriterionDefinition)criterionById.get(idB), childB); |
| } else { |
| // wasn't a duplicate |
| a.appendChild(childB); |
| criterionById.put(idB, childB); |
| } |
| } |
| } else if(childB instanceof CriterionValueDefinition) { |
| String valueIdB = childB.getAttribute(CriterionValueDefinition.ATTRIBUTE_ID); |
| String valueNameB = childB.getAttribute(CriterionValueDefinition.ATTRIBUTE_NAME); |
| if(null != valueIdB && valueIdB.trim().length() > 0 && null != valueNameB && valueNameB.trim().length() > 0){ |
| if (!criterionValueIds.contains(valueIdB)) { |
| // For one criterion, add criterion value only if id doesn't exist yet |
| a.appendChild(childB); |
| criterionValueIds.add(valueIdB); |
| } |
| } |
| } |
| } |
| } |
| } |