| /********************************************************************************* |
| * Copyright (c) 2020, 2021 Robert Bosch GmbH and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Robert Bosch GmbH - initial API and implementation |
| ******************************************************************************** |
| */ |
| |
| package org.eclipse.app4mc.amalthea.converters097.utils; |
| |
| import java.io.File; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.eclipse.app4mc.amalthea.converters.common.ServiceConstants; |
| import org.eclipse.app4mc.amalthea.converters.common.base.ICache; |
| import org.eclipse.app4mc.amalthea.converters.common.utils.AmaltheaNamespaceRegistry; |
| import org.eclipse.app4mc.amalthea.converters.common.utils.HelperUtil; |
| import org.eclipse.app4mc.amalthea.converters.common.utils.ModelVersion; |
| import org.eclipse.app4mc.util.sessionlog.SessionLogger; |
| import org.jdom2.Attribute; |
| import org.jdom2.Document; |
| import org.jdom2.Element; |
| import org.osgi.service.component.annotations.Component; |
| import org.osgi.service.component.annotations.Reference; |
| |
| @Component( |
| property = ServiceConstants.INPUT_MODEL_VERSION_PROPERTY + "=0.9.6", |
| service= {ICache.class, ComponentPortInterfaceCacheBuilder.class}) |
| |
| public class ComponentPortInterfaceCacheBuilder implements ICache { |
| |
| @Reference |
| SessionLogger logger; |
| |
| public static final String INTERFACE_CACHE_KEY = "ComponentPort_Interface_Names"; |
| public static final String INSTANCE_PARENT_CACHE_KEY = "ComponentInstance_Parent_Names"; |
| |
| private final HashMap<File, Map<String, Object>> map = new HashMap<>(); |
| |
| |
| @Override |
| public void buildCache(Map<File, Document> fileDocumentMapping) { |
| |
| if (logger != null) { |
| logger.info("Build up ComponentPortInterfaceCache for 0.9.6"); |
| } |
| |
| HashSet<String> uniqueInterfaceNames = new HashSet<>(); |
| HashMap<String, String> componentInstanceNames = new HashMap<>(); |
| |
| for (Entry<File, Document> entry : fileDocumentMapping.entrySet()) { |
| Document document1 = entry.getValue(); |
| |
| if (document1 == null) { |
| // log error message |
| continue; |
| } |
| |
| Element rootElement = document1.getRootElement(); |
| |
| // collect interface names |
| final List<Element> componentPorts = HelperUtil.getXpathResult( |
| rootElement, |
| "./componentsModel/components/ports[@interfaceName]", |
| Element.class, |
| AmaltheaNamespaceRegistry.getNamespace(ModelVersion._097, "am"), |
| AmaltheaNamespaceRegistry.getGenericNamespace("xsi")); |
| |
| |
| for (Element port : componentPorts) { |
| String attrVal = port.getAttributeValue("interfaceName"); |
| if (attrVal != null && attrVal.trim().length() > 0) { |
| uniqueInterfaceNames.add(attrVal.trim()); |
| } |
| } |
| |
| // collect component instance names |
| final List<Element> componentInstances = HelperUtil.getXpathResult( |
| rootElement, |
| "./componentsModel/components/componentInstances", |
| Element.class, |
| AmaltheaNamespaceRegistry.getNamespace(ModelVersion._097, "am"), |
| AmaltheaNamespaceRegistry.getGenericNamespace("xsi")); |
| |
| |
| for (Element componentInstance : componentInstances) { |
| String instanceName = componentInstance.getAttributeValue("name"); |
| if (instanceName != null && instanceName.trim().length() > 0) { |
| |
| Element parentElement = getParentElement(componentInstance); |
| if (parentElement != null) { |
| Attribute name = parentElement.getAttribute("name"); |
| String parentName = (name != null) ? name.getValue() : ""; |
| // store the encoded parent name for the encoded instance name |
| componentInstanceNames.put( |
| HelperUtil.encodeName(instanceName), |
| HelperUtil.encodeName(parentName)); |
| } |
| } |
| } |
| } |
| |
| //construct a simple list of all interfaceNames without any duplicate. |
| //get the first file from the map as the target destination file where all unique interfaces will be created. |
| Map<String, Object> cache = new HashMap<>(); |
| cache.put(INTERFACE_CACHE_KEY, uniqueInterfaceNames); |
| cache.put(INSTANCE_PARENT_CACHE_KEY, componentInstanceNames); |
| |
| Entry<File, Document> firstEntry = fileDocumentMapping.entrySet().stream() |
| .sorted((e1, e2) -> e1.getKey().getName().compareTo(e2.getKey().getName())) |
| .findFirst() |
| .orElse(null); |
| if (firstEntry != null) { |
| File targetFile = firstEntry.getKey(); |
| this.map.put(targetFile, cache); |
| } |
| } |
| |
| private Element getParentElement(Element element) { |
| if (element == null || element.isRootElement()) { |
| return null; |
| } |
| |
| if ("systems".equals(element.getName())) { |
| return element; |
| } |
| |
| if ("components".equals(element.getName())) { |
| Attribute type = element.getAttribute("type", AmaltheaNamespaceRegistry.getGenericNamespace("xsi")); |
| if (type != null && "am:Composite".equals(type.getValue())) { |
| return element; |
| } |
| } |
| |
| return getParentElement(element.getParentElement()); |
| } |
| |
| /** |
| * |
| * @return Collection of component port interface names. |
| */ |
| @SuppressWarnings("unchecked") |
| public Collection<String> getCachedInterfaceNames() { |
| if (this.map.size() > 0) { |
| Map<String, Object> interfaceMap = this.map.values().iterator().next(); |
| Collection<String> interfaceNames = (Collection<String>) interfaceMap.get(ComponentPortInterfaceCacheBuilder.INTERFACE_CACHE_KEY); |
| if (interfaceNames != null) { |
| return interfaceNames; |
| } |
| } |
| return new HashSet<>(); |
| } |
| |
| /** |
| * |
| * @return Collection of component instance parent names. |
| */ |
| @SuppressWarnings("unchecked") |
| public Map<String, String> getCachedComponentInstanceParentNames() { |
| if (this.map.size() > 0) { |
| Map<String, Object> cacheMap = this.map.values().iterator().next(); |
| HashMap<String,String> parentNames = |
| (HashMap<String, String>) cacheMap.get(ComponentPortInterfaceCacheBuilder.INSTANCE_PARENT_CACHE_KEY); |
| if (parentNames != null) { |
| return parentNames; |
| } |
| } |
| return new HashMap<>(); |
| } |
| |
| @Override |
| public Map<File, Map<String, Object>> getCacheMap() { |
| return this.map; |
| } |
| |
| @Override |
| public void clearCacheMap() { |
| this.map.clear(); |
| } |
| |
| } |