| /******************************************************************************* |
| * Copyright (C) 2021 the Eclipse BaSyx Authors |
| * |
| * 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 |
| ******************************************************************************/ |
| package org.eclipse.basyx.submodel.metamodel.map.reference; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException; |
| import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; |
| import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable; |
| import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; |
| import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; |
| import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; |
| import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType; |
| import org.eclipse.basyx.vab.model.VABModelMap; |
| |
| /** |
| * Reference as described by DAAS document <br/> |
| * <br/> |
| * Reference to either a model element of the same or another AAS or to an |
| * external entity. A reference is an ordered list of keys, each key referencing |
| * an element. The complete list of keys may for example be concatenated to a |
| * path that then gives unique access to an element or entity. |
| * |
| * @author schnicke |
| * |
| */ |
| public class Reference extends VABModelMap<Object> implements IReference { |
| public static final String KEY = "keys"; |
| |
| /** |
| * Constructor |
| */ |
| public Reference() { |
| setKeys(new ArrayList<IKey>()); |
| } |
| |
| /** |
| * Constructs a reference based on an {@link IIdentifiable} and additional |
| * information (see {@link Key#Key(KeyElements, boolean, String, KeyType)}). |
| * |
| * @param identifiable |
| * @param keyElement |
| * @param local |
| */ |
| public Reference(IIdentifiable identifiable, KeyElements keyElement, boolean local) { |
| this(identifiable.getIdentification(), keyElement, local); |
| } |
| |
| /** |
| * Constructs a reference based on an {@link IIdentifier} and additional |
| * information (see {@link Key#Key(KeyElements, boolean, String, KeyType)}). |
| * |
| * @param identifiable |
| * @param keyElement |
| * @param local |
| */ |
| public Reference(IIdentifier identifier, KeyElements keyElement, boolean local) { |
| this(new Key(keyElement, local, identifier.getId(), identifier.getIdType())); |
| } |
| |
| /** |
| * |
| * @param key Unique reference in its name space. |
| */ |
| public Reference(List<IKey> keys) { |
| setKeys(keys); |
| } |
| |
| /** |
| * |
| * @param key |
| * Unique reference in its name space. |
| */ |
| public Reference(Key key) { |
| this(Collections.singletonList(key)); |
| } |
| |
| /** |
| * Creates a Reference object from a map |
| * |
| * @param obj |
| * a Reference object as raw map |
| * @return a Reference object, that behaves like a facade for the given map |
| */ |
| public static Reference createAsFacade(Map<String, Object> map) { |
| if (map == null) { |
| return null; |
| } |
| |
| if (!isValid(map)) { |
| throw new MetamodelConstructionException(Reference.class, map); |
| } |
| |
| Reference ret = new Reference(); |
| ret.setMap(map); |
| return ret; |
| } |
| |
| /** |
| * Check whether all mandatory elements for the metamodel |
| * exist in a map |
| * @return true/false |
| */ |
| @SuppressWarnings("unchecked") |
| public static boolean isValid(Map<String, Object> map) { |
| if (map != null && map.containsKey(Reference.KEY)) { |
| Collection<Map<String, Object>> keysCollection = (Collection<Map<String, Object>>)map.get(Reference.KEY); |
| for (Map<String, Object> key : keysCollection) { |
| if (!Key.isValid(key)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Creates a Reference object from a map |
| * without checking mandatory attributes present |
| * |
| * @param obj |
| * a Reference object as raw map |
| * @return a Reference object, that behaves like a facade for the given map |
| */ |
| public static Reference createAsFacadeNonStrict(Map<String, Object> map) { |
| if (map == null) { |
| return null; |
| } |
| |
| Reference ret = new Reference(); |
| ret.setMap(map); |
| return ret; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static boolean isReference(Object value) { |
| if(!(value instanceof Map<?, ?>)) { |
| return false; |
| } |
| |
| Map<String, Object> map = (Map<String, Object>) value; |
| |
| if(!(map.get(KEY) instanceof Collection<?>)) { |
| return false; |
| } |
| |
| return ((Collection<Key>) map.get(KEY)).stream().allMatch(Key::isKey); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IKey> getKeys() { |
| List<IKey> ret = new ArrayList<>(); |
| |
| // Transform list of maps to set of IKey |
| Collection<Map<String, Object>> coll = (Collection<Map<String, Object>>) get(Reference.KEY); |
| for (Map<String, Object> m : coll) { |
| ret.add(Key.createAsFacade(m)); |
| } |
| |
| return ret; |
| } |
| |
| public void setKeys(List<IKey> keys) { |
| // Copy the key list to make sure an actual hashmap is put inside this map |
| List<IKey> copy = new ArrayList<>(); |
| for (IKey key : keys) { |
| copy.add(new Key(key.getType(), key.isLocal(), key.getValue(), key.getIdType())); |
| } |
| put(Reference.KEY, copy); |
| } |
| |
| @Override |
| public String toString() { |
| return "Reference [getKeys()=" + getKeys() + "]"; |
| } |
| |
| } |