blob: f1cd88c204aeb16bd2ccdaf4c4cd1bb0f1502983 [file] [log] [blame]
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() + "]";
}
}