/******************************************************************************* * Copyright (c) 2013, 2015 Tasktop Technologies and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * David Green - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.wikitext.html.internal; import static com.google.common.base.Preconditions.checkNotNull; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.mylyn.wikitext.parser.Attributes; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; abstract class ElementStrategies, ElementStrategy, HtmlElementStrategyType extends HtmlElementStrategy> { private Map elementStrategyByElementType; private final List elementStrategies; ElementStrategies(Class elementTypeClass, Set elementTypes, List elementStrategies) { checkNotNull(elementTypeClass); checkNotNull(elementTypes); this.elementStrategies = ImmutableList.copyOf(checkNotNull(elementStrategies)); initialize(elementTypeClass, elementTypes); } public ElementStrategy getStrategy(ElementType elementType, Attributes attributes) { checkNotNull(elementType); for (HtmlElementStrategyType strategy : elementStrategies) { if (strategy.matcher().matches(elementType, attributes)) { return getElementStrategy(strategy); } } return checkNotNull(elementStrategyByElementType.get(elementType)); } abstract ElementStrategy getElementStrategy(HtmlElementStrategyType strategy); private void initialize(Class elementTypeClass, Set elementTypes) { Map elementStrategyByElementType = Maps.newHashMap(); for (ElementType elementType : elementTypes) { addSupportedElementType(elementStrategyByElementType, elementType); } addImplicitElementTypes(elementStrategyByElementType, elementTypes); Map alternativesByElementType = Maps.newHashMap(); for (ElementType elementType : EnumSet.allOf(elementTypeClass)) { if (!elementStrategyByElementType.containsKey(elementType)) { alternativesByElementType.put(elementType, calculateFallBackElementStrategy(elementStrategyByElementType, elementType)); } } elementStrategyByElementType.putAll(alternativesByElementType); this.elementStrategyByElementType = ImmutableMap.copyOf(elementStrategyByElementType); } abstract void addImplicitElementTypes(Map blockStrategyByElementType, Set elementTypes); void addSupportedElementType(Map elementStrategyByElementType, ElementType elementType) { elementStrategyByElementType.put(elementType, getSupportedStrategy(elementType)); } abstract ElementStrategy getSupportedStrategy(ElementType elementType); abstract ElementStrategy getUnsupportedElementStrategy(ElementType elementType); abstract ElementStrategy createSubstitutionElementStrategy(ElementType alternative); abstract Map> getElementTypeToAlternatives(); private ElementStrategy calculateFallBackElementStrategy(Map strategies, ElementType elementType) { ElementStrategy elementStrategy = null; List alternatives = getElementTypeToAlternatives().get(elementType); if (alternatives != null) { for (ElementType alternative : alternatives) { if (strategies.containsKey(alternative)) { elementStrategy = createSubstitutionElementStrategy(alternative); break; } } } if (elementStrategy == null) { elementStrategy = getUnsupportedElementStrategy(elementType); } return elementStrategy; } }