| /********************************************************************************
|
| * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
|
| *
|
| * See the NOTICE file(s) distributed with this work for additional
|
| * information regarding copyright ownership.
|
| *
|
| * This program and the accompanying materials are made available under the
|
| * terms of the Eclipse Public License v. 2.0 which is available at
|
| * http://www.eclipse.org/legal/epl-2.0.
|
| *
|
| * SPDX-License-Identifier: EPL-2.0
|
| *
|
| ********************************************************************************/
|
| |
| |
| package org.eclipse.mdm.openatfx.mdf.util; |
| |
| import java.util.HashMap;
|
| import java.util.LinkedList;
|
| import java.util.List;
|
| import java.util.Map;
|
|
|
| import org.asam.ods.AoException;
|
| import org.asam.ods.AoSession;
|
| import org.asam.ods.ApplAttr;
|
| import org.asam.ods.ApplElem;
|
| import org.asam.ods.ApplElemAccess;
|
| import org.asam.ods.ApplRel;
|
| import org.asam.ods.ApplicationAttribute;
|
| import org.asam.ods.ApplicationElement;
|
| import org.asam.ods.ApplicationRelation;
|
| import org.asam.ods.ApplicationStructure;
|
| import org.asam.ods.ApplicationStructureValue;
|
| import org.asam.ods.BaseAttribute;
|
| import org.asam.ods.BaseElement;
|
| import org.asam.ods.BaseRelation;
|
| import org.asam.ods.BaseStructure;
|
| import org.asam.ods.DataType;
|
| import org.asam.ods.ElemId;
|
| import org.asam.ods.EnumerationAttributeStructure;
|
| import org.asam.ods.EnumerationDefinition;
|
| import org.asam.ods.EnumerationItemStructure;
|
| import org.asam.ods.EnumerationStructure;
|
| import org.asam.ods.ErrorCode;
|
| import org.asam.ods.NameValue;
|
| import org.asam.ods.NameValueIterator;
|
| import org.asam.ods.SeverityFlag;
|
| import org.asam.ods.T_LONGLONG;
|
| import org.slf4j.Logger;
|
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Cache for the ASAM-ODS application model. |
| * |
| * @author Christian Rechner |
| */ |
| public class ODSModelCache { |
|
|
| public static final String ATTR_NAME_MEAQU_RANK = "rank";
|
| public static final String ATTR_NAME_MEAQU_DIMENSION = "dimension";
|
| public static final String ATTR_NAME_MEAQU_COL_ORIENTED_TENSOR = "columnOriented";
|
|
|
| private static final Logger LOG = LoggerFactory.getLogger(ODSModelCache.class); |
| |
| // cached ODS AoSession (ODS interface) |
| private AoSession aoSession = null; |
| |
| // cached ODS context parameter |
| private NameValue[] context = null; |
| |
| // cached ODS BaseStructure (ODS interface) |
| private BaseStructure baseStructure = null; |
| |
| // cached ODS ApplicationStructure (ODS interface) |
| private ApplicationStructure applicationStructure = null; |
| |
| // cached application elements (ODS interface) |
| private Map<String, ApplicationElement> applicationElemCache; |
| |
| // cached application attributes (ODS interface) |
| private Map<String, ApplicationAttribute[]> applicationAttrCache; |
| |
| // cached application relations (ODS interface) |
| private Map<ApplicationRelKey, ApplicationRelation> applicationRelCache; |
| |
| // cached enumeration definitions (ODS interface) |
| private Map<String, EnumerationDefinition> enumDefCache; |
| |
| // cached applElemAccess (ODS interface) |
| private ApplElemAccess applElemAccess = null; |
| |
| // cached applicationStructureValue (ODS interface) |
| private ApplicationStructureValue applicationStructureValue = null; |
| |
| // cached applElemns (ODS struct) |
| private ApplElem[] applElems = null; |
| |
| private Map<String, ApplElem> aeName2applElemMap = null; |
| |
| private Map<Long, ApplElem> aid2applElemMap = null; |
| |
| // cached applRels (ODS struct) |
| private ApplRel[] applRels = null; |
| |
| // cached enumeration values |
| private EnumerationStructure[] enumerationStructure = null; |
| |
| // cached enumeration attributes |
| private EnumerationAttributeStructure[] enumerationAttributes = null; |
| |
| // map containing the enum definition <aid,aaName,enumName> |
| private Map<Long, Map<String, String>> enumerationAttributeMap = null; |
| |
| private Map<String, Map<Integer, String>> enumIndexToValueMap = null; |
| |
| private Map<String, Map<String, Integer>> enumValueToIndexMap = null; |
| |
| /** |
| * Constructor. |
| * |
| * @param aoSession |
| * the ODS session |
| */ |
| public ODSModelCache(AoSession aoSession) { |
| if (aoSession == null) { |
| throw new IllegalArgumentException("Parameter aoSession must not be null"); |
| } |
| applicationElemCache = new HashMap<String, ApplicationElement>(); |
| applicationAttrCache = new HashMap<String, ApplicationAttribute[]>(); |
| applicationRelCache = new HashMap<ApplicationRelKey, ApplicationRelation>(); |
| enumDefCache = new HashMap<String, EnumerationDefinition>();
|
|
|
| try
|
| {
|
| extendSourceApplicationStructure(aoSession);
|
| }
|
| catch (AoException e)
|
| {
|
| throw new RuntimeException("Error occurred trying to extend mdf datamodel with required additions: " + e.reason);
|
| }
|
| |
| this.aoSession = aoSession; |
| }
|
|
|
| /**
|
| * <p>
|
| * Adds attributes to model needed additionally to transport information on
|
| * specific mdf features to the ODS target. So far these are:
|
| * </p>
|
| * <p>
|
| * For array composition:
|
| * <ul>
|
| * <li>MeaQuantity - rank attribute: for the number of value dimensions in the
|
| * values tensor for this channel</li>
|
| * <li>MeaQuantity - dimension attribute: for the number of values in each
|
| * dimension of the values tensor for this channel</li>
|
| * <li>MeaQuantity - columnOriented attribute: to specify in which way the
|
| * tensor has to be interpreted when calculating the actual values</li>
|
| * </ul>
|
| * </p>
|
| * @throws AoException
|
| */
|
| private final void extendSourceApplicationStructure(AoSession aoSession) throws AoException
|
| {
|
| ApplicationStructure as = aoSession.getApplicationStructure();
|
|
|
| // Additional MeasurementQuantity attributes
|
| ApplicationElement meaQuantityAe = as.getElementsByBaseType("aomeasurementquantity")[0];
|
|
|
| // to handle array composition for channels
|
| ApplicationAttribute rankAttr = meaQuantityAe.createAttribute();
|
| BaseAttribute rankBaseAttr = meaQuantityAe.getBaseElement().getAttributes("rank")[0];
|
| rankAttr.setBaseAttribute(rankBaseAttr);
|
| rankAttr.setName(ATTR_NAME_MEAQU_RANK);
|
| ApplicationAttribute dimensionAttr = meaQuantityAe.createAttribute();
|
| BaseAttribute dimensionBaseAttr = meaQuantityAe.getBaseElement().getAttributes("dimension")[0];
|
| dimensionAttr.setBaseAttribute(dimensionBaseAttr);
|
| dimensionAttr.setName(ATTR_NAME_MEAQU_DIMENSION);
|
| ApplicationAttribute columnOrientedAttr = meaQuantityAe.createAttribute();
|
| columnOrientedAttr.setName(ATTR_NAME_MEAQU_COL_ORIENTED_TENSOR);
|
| columnOrientedAttr.setDataType(DataType.DT_BOOLEAN);
|
| } |
| |
| /** |
| * Returns a Java long from ODS T_LONGLONG. |
| * |
| * @param ll |
| * ODS T_LONGLONG value |
| * @return Java long with the same value as ll |
| */ |
| private static long asJLong(T_LONGLONG ll) { |
| long tmp; |
| if (ll.low >= 0) { |
| tmp = ll.high * 0x100000000L + ll.low; |
| } else { |
| tmp = (ll.high + 1) * 0x100000000L + ll.low; |
| } |
| return tmp; |
| } |
| |
| /** |
| * Return ODS T_LONGLONG from Java long. |
| * |
| * @param v |
| * Java long value |
| * @return ODS T_LONGLONG with the same value as v |
| */ |
| private static T_LONGLONG asODSLongLong(long v) { |
| return new T_LONGLONG((int) (v >> 32 & 0xffffffffL), (int) (v & 0xffffffffL)); |
| } |
| |
| /******************************************************************************************************************* |
| * Methods for accessing cached ODS objects. |
| ******************************************************************************************************************/ |
| |
| /** |
| * Returns the ODS session. |
| * |
| * @return the ODS session |
| */ |
| public final AoSession getAoSession() { |
| return aoSession; |
| } |
| |
| /** |
| * Returns the cached ODS server context. |
| * |
| * @return array containg context parameter |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final NameValue[] getContext() throws AoException { |
| if (context == null) { |
| NameValueIterator iter = getAoSession().getContext("*"); |
| int cnt = iter.getCount(); |
| context = new NameValue[cnt]; |
| for (int i = 0; i < cnt; i++) { |
| context[i] = iter.nextOne(); |
| } |
| LOG.debug("Context loaded"); |
| } |
| return context; |
| } |
| |
| /** |
| * Returns the cached ODS base structure. |
| * |
| * @return the cached BaseStructure |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final BaseStructure getBaseStructure() throws AoException { |
| if (baseStructure == null) { |
| baseStructure = getAoSession().getBaseStructure(); |
| LOG.debug("BaseStructure loaded"); |
| } |
| return baseStructure; |
| } |
| |
| /** |
| * Returns an ODS base element by given name. |
| * |
| * @param beName |
| * The base element name |
| * @return The base element object |
| * @throws AoException |
| * error getting base element |
| */ |
| public final BaseElement getBaseElement(String beName) throws AoException { |
| return getBaseStructure().getElementByType(beName); |
| } |
| |
| /** |
| * Returns the ODS base relation by given base element names. |
| * |
| * @param beNameFrom |
| * first base element name |
| * @param beNameTo |
| * second base element name |
| * @return the ODS base relation |
| * @throws AoException |
| * application elements or relation not found |
| */ |
| public final BaseRelation getBaseRelation(String beNameFrom, String beNameTo) throws AoException { |
| BaseElement beFrom = getBaseElement(beNameFrom); |
| BaseElement beTo = getBaseElement(beNameTo); |
| return getBaseStructure().getRelation(beFrom, beTo); |
| } |
| |
| /** |
| * Returns the cached ODS application structure. |
| * |
| * @return the cached application structure |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationStructure getApplicationStructure() throws AoException { |
| if (applicationStructure == null) { |
| applicationStructure = getAoSession().getApplicationStructure(); |
| LOG.debug("ApplicationStructure loaded"); |
| } |
| return applicationStructure; |
| } |
| |
| /** |
| * Returns the cached ODS application structure value. |
| * |
| * @return the cached applicationStructureValue |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationStructureValue getApplicationStructureValue() throws AoException { |
| if (applicationStructureValue == null) { |
| applicationStructureValue = getAoSession().getApplicationStructureValue(); |
| LOG.debug("ApplicationStructureValue loaded"); |
| } |
| return applicationStructureValue; |
| } |
| |
| /** |
| * Returns an application element of specified type. |
| * |
| * @param aeName |
| * the name of the application element to retrieve |
| * @return the cached application element |
| * @throws AoException |
| * application element not found |
| */ |
| public final ApplicationElement getApplicationElement(String aeName) throws AoException { |
| ApplicationElement ae = applicationElemCache.get(aeName); |
| if (ae == null) { |
| ApplicationStructure as = getApplicationStructure(); |
| ae = as.getElementByName(aeName); |
| applicationElemCache.put(aeName, ae); |
| LOG.debug("ApplicationElement [name=" + aeName + "] loaded"); |
| } |
| return ae; |
| } |
| |
| /** |
| * Returns an array containing all application attributes for an application |
| * element. |
| * |
| * @param aeName |
| * the application element name |
| * @return the ODS <code>ApplicationAttribute</code> |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationAttribute[] getApplicationAttributes(String aeName) throws AoException { |
| ApplicationAttribute[] attrs = applicationAttrCache.get(aeName); |
| if (attrs == null) { |
| attrs = getApplicationElement(aeName).getAttributes("*"); |
| applicationAttrCache.put(aeName, attrs); |
| LOG.debug("ApplicationAttributes [aeName=" + aeName + "] loaded"); |
| } |
| return attrs; |
| } |
| |
| /** |
| * Returns the ODS application attribute for an application element. |
| * |
| * @param aeName |
| * the application element name |
| * @param aaName |
| * the application attribute name |
| * @return the ODS <code>ApplicationAttribute</code> |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationAttribute getApplicationAttribute(String aeName, String aaName) throws AoException { |
| for (ApplicationAttribute attr : getApplicationAttributes(aeName)) { |
| if (attr.getName().equals(aaName)) { |
| return attr; |
| } |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "ApplicationAttribute [aeName=" + aeName + ",aaName=" + aaName + "] not found"); |
| } |
| |
| /** |
| * Returns an application relation between two elements. |
| * |
| * @param ae1Name |
| * the source application element |
| * @param ae2Name |
| * the target application element |
| * @return the ODS application relation |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationRelation getApplicationRelation(String ae1Name, String ae2Name) throws AoException { |
| // lookup in cache for application relation |
| ApplicationRelKey appRelKey = new ApplicationRelKey(ae1Name, ae2Name); |
| ApplicationRelation rel = applicationRelCache.get(appRelKey); |
| if (rel != null) { |
| return rel; |
| } |
| |
| // retrieve relation |
| ApplicationStructure as = getApplicationStructure(); |
| ApplicationElement ae1 = getApplicationElement(ae1Name); |
| ApplicationElement ae2 = getApplicationElement(ae2Name); |
| ApplicationRelation[] ars = as.getRelations(ae1, ae2); |
| |
| // check if relation exist |
| if (ars.length < 1) { |
| throw new AoException(ErrorCode.AO_INVALID_RELATION, SeverityFlag.ERROR, 1, |
| "ApplicationRelation between [ae1Name=" + ae1Name + ",ae2Name=" + ae2Name + "] not found"); |
| } |
| |
| // check if multiple relations between two elements exist |
| if (ars.length > 1) { |
| isSelfRelation(ae1Name, ae2Name, ars); |
| } |
| |
| // put to cache |
| applicationRelCache.put(appRelKey, ars[0]); |
| |
| LOG.debug("ApplicationRelation between [ae1Name=" + ae1Name + ",ae2Name=" + ae2Name + "] loaded"); |
| return ars[0]; |
| } |
| |
| /** |
| * Checks for self relation. |
| * |
| * @param ae1Name |
| * Application element name 1. |
| * @param ae2Name |
| * Application element name 2. |
| * @param ars |
| * Application relations. |
| * @throws AoException |
| * Thrown if a self relation is detected. |
| */ |
| private void isSelfRelation(String ae1Name, String ae2Name, ApplicationRelation[] ars) throws AoException { |
| if (ars.length != 2 && !ars[0].getRelationName().equals(ars[1].getInverseRelationName())) { |
| throw new AoException(ErrorCode.AO_INVALID_RELATION, SeverityFlag.ERROR, 1, |
| "More than one relation between [ae1Name=" + ae1Name + ",ae2Name=" + ae2Name + "] found"); |
| |
| } |
| } |
| |
| /** |
| * Returns an application relation between two elements with given name. |
| * |
| * @param ae1Name |
| * the source application element |
| * @param ae2Name |
| * the target application element |
| * @param relName |
| * the relation name |
| * @return the ODS application relation |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplicationRelation getApplicationRelation(String ae1Name, String ae2Name, String relName) |
| throws AoException { |
| |
| // lookup in cache for application relation |
| ApplicationRelKey appRelKey = new ApplicationRelKey(ae1Name, ae2Name); |
| ApplicationRelation rel = applicationRelCache.get(appRelKey); |
| if (rel != null && rel.getRelationName().equals(relName)) { |
| return rel; |
| } |
| |
| // retrieve relation |
| ApplicationStructure as = getApplicationStructure(); |
| ApplicationElement ae1 = getApplicationElement(ae1Name); |
| ApplicationElement ae2 = getApplicationElement(ae2Name); |
| ApplicationRelation[] ars = as.getRelations(ae1, ae2); |
| |
| // get relation with right name |
| for (ApplicationRelation ar : ars) { |
| if (ar.getRelationName().equals(relName)) { |
| LOG.debug("ApplicationRelation between [ae1Name=" + ae1Name + ",ae2Name=" + ae2Name + ",relName=" |
| + relName + "] loaded"); |
| applicationRelCache.put(appRelKey, ar); |
| return ar; |
| } |
| } |
| |
| throw new AoException(ErrorCode.AO_INVALID_RELATION, SeverityFlag.ERROR, 1, "ApplicationRelation [ae1Name=" |
| + ae1Name + ",ae2Name=" + ae2Name + ",relName=" + relName + "] not found"); |
| } |
| |
| /** |
| * Returns an ODS enumeration definition by given name. |
| * |
| * @param enumName |
| * the enumeration name |
| * @return the ODS <code>EnumerationDefinition</code> or null if the |
| * <code>EnumerationDefinition</code> does not exits * |
| * @throws AoException |
| * if something is wrong |
| */ |
| public final EnumerationDefinition getEnumerationDefinition(String enumName) throws AoException { |
| EnumerationDefinition enumDef = enumDefCache.get(enumName); |
| if (enumDef == null) { |
| ApplicationStructure as = getApplicationStructure(); |
| try { |
| enumDef = as.getEnumerationDefinition(enumName); |
| enumDefCache.put(enumName, enumDef); |
| } catch (AoException aoe) { |
| LOG.debug("EnumerationDefinition [name=" + enumName + "] not found!"); |
| return null; |
| } |
| |
| LOG.debug("EnumerationDefinition [name=" + enumName + "] loaded"); |
| } |
| return enumDef; |
| } |
| |
| /** |
| * Returns the cached ODS applElemAccess. |
| * |
| * @return the cached applElemAccess |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplElemAccess getApplElemAccess() throws AoException { |
| if (applElemAccess == null) { |
| applElemAccess = getAoSession().getApplElemAccess(); |
| LOG.debug("ApplElemAccess loaded"); |
| } |
| return applElemAccess; |
| } |
| |
| /******************************************************************************************************************* |
| * methods for accessing cached ODS structs. |
| ******************************************************************************************************************/ |
| |
| /** |
| * Returns all structs of ODS <code>ApplElem</code>. |
| * |
| * @return the <code>ApplElem</code> |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplElem[] getApplElems() throws AoException { |
| if (applElems == null) { |
| applElems = getApplicationStructureValue().applElems; |
| } |
| return applElems; |
| } |
| |
| /** |
| * Returns the map between application element name and application element |
| * structure. |
| * |
| * @return The map. |
| * @throws AoException |
| * Error loading application element mapping. |
| */ |
| private Map<String, ApplElem> getAeName2applElemMap() throws AoException { |
| if (aeName2applElemMap == null) { |
| aeName2applElemMap = new HashMap<String, ApplElem>(); |
| for (ApplElem applElem : getApplElems()) { |
| aeName2applElemMap.put(applElem.aeName, applElem); |
| } |
| } |
| return aeName2applElemMap; |
| } |
| |
| /** |
| * Returns the map between application element id and application element |
| * structure. |
| * |
| * @return The map. |
| * @throws AoException |
| * Error loading application element mapping. |
| */ |
| private Map<Long, ApplElem> getAid2applElemMap() throws AoException { |
| if (aid2applElemMap == null) { |
| aid2applElemMap = new HashMap<Long, ApplElem>(); |
| for (ApplElem applElem : getApplElems()) { |
| aid2applElemMap.put(asJLong(applElem.aid), applElem); |
| } |
| } |
| return aid2applElemMap; |
| } |
| |
| /** |
| * Returns all ODS <code>ApplElems</code> by base name. |
| * |
| * @param beName |
| * the base element name |
| * @return array of <code>ApplElemns</code> |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplElem[] getApplElemsByBaseName(String beName) throws AoException { |
| List<ApplElem> list = new LinkedList<ApplElem>(); |
| for (ApplElem applElem : getApplElems()) { |
| if (applElem.beName.equalsIgnoreCase(beName)) { |
| list.add(applElem); |
| } |
| } |
| return list.toArray(new ApplElem[list.size()]); |
| } |
| |
| /** |
| * Returns all application element names by given base name |
| * |
| * @param beName |
| * the base element name |
| * @return list of application element names |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final String[] getAeNamesByBaseName(String beName) throws AoException { |
| List<String> list = new LinkedList<String>(); |
| for (ApplElem applElem : getApplElemsByBaseName(beName)) { |
| list.add(applElem.aeName); |
| } |
| return list.toArray(new String[list.size()]); |
| } |
| |
| /** |
| * Returns an ODS <code>ApplElem</code> by given base name. If none or |
| * multiple were found, an exception is thrown. |
| * |
| * @param beName |
| * the base element name |
| * @return the <code>ApplElem</code> if found |
| * @throws AoException |
| * none or multiple application elements by given base name have |
| * been found |
| */ |
| public final ApplElem getApplElemByBaseName(String beName) throws AoException { |
| ApplElem[] elems = getApplElemsByBaseName(beName); |
| if (elems.length < 1) { |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "AE for base name [beName=" + beName + "] not found"); |
| } else if (elems.length > 1) { |
| throw new AoException(ErrorCode.AO_NOT_UNIQUE, SeverityFlag.ERROR, 01, |
| "Multiple AEs for base name [beName=" + beName + " found"); |
| } |
| return elems[0]; |
| } |
| |
| /** |
| * Returns an ODS <code>ApplElem</code> by given aid. |
| * |
| * @param aid |
| * the id of the application element |
| * @return the <code>ApplElem</code> |
| * @throws AoException |
| * application element by given id not found |
| */ |
| public final ApplElem getApplElem(long aid) throws AoException { |
| ApplElem applElem = getAid2applElemMap().get(aid); |
| if (applElem != null) { |
| return applElem; |
| } |
| throw new AoException(ErrorCode.AO_INVALID_ELEMENT, SeverityFlag.ERROR, 0, "AE [aid=" + aid + "] not found"); |
| } |
| |
| /** |
| * Returns an ODS <code>ApplElem</code> by given aid as ODS |
| * <code>T_LONGLONG</code>. |
| * |
| * @param aid |
| * the id of the application element |
| * @return the <code>ApplElem</code> |
| * @throws AoException |
| * application element by given id not found |
| */ |
| public final ApplElem getApplElem(T_LONGLONG aid) throws AoException { |
| return getApplElem(asJLong(aid)); |
| } |
| |
| /** |
| * Returns an ODS <code>ApplElem</code> by given name. |
| * |
| * @param aeName |
| * the name of the application element |
| * @return the <code>ApplElem</code> |
| * @throws AoException |
| * application element with given name not found |
| */ |
| public final ApplElem getApplElem(String aeName) throws AoException { |
| ApplElem applElem = getAeName2applElemMap().get(aeName); |
| if (applElem != null) { |
| return applElem; |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, "AE [aeName=" + aeName + "] not found!"); |
| } |
| |
| /** |
| * Checks whether an application element with specified name exists. |
| * |
| * @param aeName |
| * the name of the ApplicationElement |
| * @return true, if the ApplicationElement exists, otherwise false |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final boolean applElemExists(String aeName) throws AoException { |
| return getAeName2applElemMap().containsKey(aeName); |
| } |
| |
| /** |
| * Creates an ODS <code>org.asam.ods.ElemId</code> by given application |
| * element name and instance id. |
| * |
| * @param aeName |
| * the application element name |
| * @param instanceId |
| * the instance id |
| * @return the <code>org.asam.ods.ElemId</code> |
| * @throws AoException |
| * application element not found |
| */ |
| public final ElemId createElemId(String aeName, long instanceId) throws AoException { |
| T_LONGLONG aid = getApplElem(aeName).aid; |
| T_LONGLONG iid = asODSLongLong(instanceId); |
| return new ElemId(aid, iid); |
| } |
| |
| /** |
| * Returns an ODS <code>ApplAttr</code> by given name. |
| * |
| * @param aeName |
| * the name of the application element |
| * @param aaName |
| * name of the application attribute |
| * @return the <code>ApplAttr</code>, null if not found |
| * @throws AoException |
| * application attribute not found |
| */ |
| public final ApplAttr getApplAttr(String aeName, String aaName) throws AoException { |
| ApplElem applElem = getApplElem(aeName); |
| for (ApplAttr applAttr : applElem.attributes) { |
| if (applAttr.aaName.equals(aaName)) { |
| return applAttr; |
| } |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "ApplicationAttribute [aeName=" + aeName + ",aaName=" + aaName + "] not found!"); |
| } |
| |
| /** |
| * Checks whether an application attribute exists. |
| * |
| * @param aeName |
| * the name of the application element |
| * @param aaName |
| * the name of the application attribute |
| * @return true, if the application attribute exists, otherwise false |
| * @throws AoException |
| * error accessing the application structure |
| */ |
| public final boolean applAttrExists(String aeName, String aaName) throws AoException { |
| if (!applElemExists(aeName)) { |
| return false; |
| } |
| ApplElem applElem = getApplElem(aeName); |
| for (ApplAttr applAttr : applElem.attributes) { |
| if (applAttr.aaName.equals(aaName)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns an application attribute definition by given base base element |
| * and base attribute name. |
| * |
| * @param beName |
| * the base element name |
| * @param baName |
| * the base attribute name |
| * @return the application atttribute definition |
| * @throws AoException |
| * none or multiple attributes found |
| */ |
| public final ApplAttr getApplAttrByBaseName(String beName, String baName) throws AoException { |
| ApplElem applElem = getApplElemByBaseName(beName); |
| for (ApplAttr applAttr : applElem.attributes) { |
| if (applAttr.baName.equals(baName)) { |
| return applAttr; |
| } |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "ApplAttr [beName=" + beName + ",baName=" + baName + "] not found!"); |
| } |
| |
| /** |
| * Returns all application relations as strucuture. |
| * |
| * @return array of application relation structures |
| * @throws AoException |
| * error accessing the application structure |
| */ |
| public final ApplRel[] getApplRels() throws AoException { |
| if (applRels == null) { |
| applRels = getApplicationStructureValue().applRels; |
| } |
| return applRels; |
| } |
| |
| /** |
| * Checks whether an application relation exists. |
| * |
| * @param elem1 |
| * the first application element |
| * @param elem2 |
| * the target application element |
| * @param relName |
| * the relations name |
| * @return true, if the relation exists, otherwise false |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final boolean applRelExists(String elem1, String elem2, String relName) throws AoException { |
| long aidElem1 = asJLong(getApplElem(elem1).aid); |
| long aidElem2 = asJLong(getApplElem(elem2).aid); |
| for (ApplRel applRel : getApplRels()) { |
| if (asJLong(applRel.elem1) == aidElem1 && asJLong(applRel.elem2) == aidElem2 |
| && applRel.arName.equals(relName)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns all ApplRels for an ODS application element. |
| * |
| * @param aeName |
| * the name of the application element |
| * @return list of ApplRels |
| * @throws AoException |
| * if something went wrong |
| */ |
| public final ApplRel[] getApplRelsForAe(String aeName) throws AoException { |
| List<ApplRel> list = new LinkedList<ApplRel>(); |
| long aid = asJLong(getApplElem(aeName).aid); |
| for (ApplRel applRel : getApplRels()) { |
| long aidelem1 = asJLong(applRel.elem1); |
| if (aid == aidelem1) { |
| list.add(applRel); |
| } |
| } |
| return list.toArray(new ApplRel[list.size()]); |
| } |
| |
| /** |
| * Returns all application relations as structure for an application element |
| * by given base element name. |
| * |
| * @param beName |
| * the base element name |
| * @return array of application relation structures |
| * @throws AoException |
| * none or multiple application elements with given basename |
| * found |
| */ |
| public final ApplRel[] getApplRelsByBaseName(String beName) throws AoException { |
| ApplElem applElem = getApplElemByBaseName(beName); |
| long aid = asJLong(applElem.aid); |
| |
| List<ApplRel> list = new LinkedList<ApplRel>(); |
| for (ApplRel applRel : getApplRels()) { |
| long elem1Aid = asJLong(applRel.elem1); |
| if (elem1Aid == aid) { |
| list.add(applRel); |
| } |
| } |
| |
| return list.toArray(new ApplRel[list.size()]); |
| } |
| |
| /** |
| * Returns an application relation as structure for an application element |
| * found by given base element and base relation name. |
| * |
| * @param beName |
| * the base element name |
| * @param brName |
| * the base relation name |
| * @return the ApplRel structure |
| * @throws AoException |
| * none or multiple application elements with given base element |
| * found or application relation not existing |
| */ |
| public final ApplRel getApplRelByBaseName(String beName, String brName) throws AoException { |
| for (ApplRel applRel : getApplRelsByBaseName(beName)) { |
| if (applRel.brName.equals(brName)) { |
| return applRel; |
| } |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "ApplRel [beName=" + beName + ",brName=" + brName + "] not found!"); |
| } |
| |
| /******************************************************************************************************************* |
| * Methods for accessing enumeration values |
| ******************************************************************************************************************/ |
| |
| /** |
| * Returns the enumeration structure. |
| * |
| * @return The enumeration structure. |
| * @throws AoException |
| * Error getting enumeration structure. |
| */ |
| public EnumerationStructure[] getEnumerationStructure() throws AoException { |
| if (enumerationStructure == null) { |
| enumerationStructure = getAoSession().getEnumerationStructure(); |
| } |
| return enumerationStructure; |
| } |
| |
| /** |
| * Returns the enumeration attribute structure. |
| * |
| * @return The enumeration attributes. |
| * @throws AoException |
| * Error getting enumeration attributes. |
| */ |
| public EnumerationAttributeStructure[] getEnumerationAttributes() throws AoException { |
| if (enumerationAttributes == null) { |
| enumerationAttributes = getAoSession().getEnumerationAttributes(); |
| } |
| return enumerationAttributes; |
| } |
| |
| /** |
| * Returns the name of the enumeration definition associated to an |
| * application attribute. |
| * |
| * @param aeName |
| * The application element name. |
| * @param aaName |
| * The application attribute name. |
| * @return The name of the enumeration definition. |
| * @throws AoException |
| * No enumeration definition defined at the attribute. |
| */ |
| public String getEnumName(String aeName, String aaName) throws AoException { |
| long aid = asJLong(getApplElem(aeName).aid); |
| // fill cache |
| if (enumerationAttributeMap == null) { |
| enumerationAttributeMap = new HashMap<Long, Map<String, String>>(); |
| for (EnumerationAttributeStructure eas : getEnumerationAttributes()) { |
| Map<String, String> attrMap = enumerationAttributeMap.get(aid); |
| if (attrMap == null) { |
| attrMap = new HashMap<String, String>(); |
| enumerationAttributeMap.put(aid, attrMap); |
| } |
| attrMap.put(eas.aaName, eas.enumName); |
| } |
| } |
| // lookup |
| Map<String, String> attrMap = enumerationAttributeMap.get(aid); |
| if (attrMap != null) { |
| String enumName = attrMap.get(aaName); |
| if (enumName != null) { |
| return enumName; |
| } |
| } |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "No enumeration definition found for [aeName=" + aeName + ",aaName=" + aaName + "]"); |
| } |
| |
| /** |
| * Returns the enumeration item for a enumeration value. |
| * |
| * @param enumName |
| * The name of the enumeration definition. |
| * @param enumValue |
| * The enumeration value. |
| * @return The enumeration item. |
| * @throws AoException |
| * Enumeration definition or value not found. |
| */ |
| public final int getEnumItem(String enumName, String enumValue) throws AoException { |
| // fill cache |
| if (enumValueToIndexMap == null) { |
| enumValueToIndexMap = new HashMap<String, Map<String, Integer>>(); |
| for (EnumerationStructure es : getEnumerationStructure()) { |
| Map<String, Integer> map = new HashMap<String, Integer>(); |
| for (EnumerationItemStructure item : es.items) { |
| map.put(item.itemName, item.index); |
| } |
| enumValueToIndexMap.put(es.enumName, map); |
| } |
| } |
| |
| // lookup |
| Map<String, Integer> map = enumValueToIndexMap.get(enumName); |
| if (map != null) { |
| Integer item = map.get(enumValue); |
| if (item != null) { |
| return item; |
| } |
| } |
| |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "Enumeration item not found for [enumName=" + enumName + ",enumValue=" + enumValue + "]"); |
| } |
| |
| /** |
| * Returns the enumeration value for an enumeration item. |
| * |
| * @param enumName |
| * The name of the enumeration definition. |
| * @param enumItem |
| * The enumeration item. |
| * @return The enumeration value. |
| * @throws AoException |
| * Enumeration definition or item not found. |
| */ |
| public final String getEnumValue(String enumName, int enumItem) throws AoException { |
| // fill cache |
| if (enumIndexToValueMap == null) { |
| enumIndexToValueMap = new HashMap<String, Map<Integer, String>>(); |
| for (EnumerationStructure es : getEnumerationStructure()) { |
| Map<Integer, String> map = new HashMap<Integer, String>(); |
| for (EnumerationItemStructure item : es.items) { |
| map.put(item.index, item.itemName); |
| } |
| enumIndexToValueMap.put(es.enumName, map); |
| } |
| } |
| |
| // lookup |
| Map<Integer, String> map = enumIndexToValueMap.get(enumName); |
| if (map != null) { |
| String value = map.get(enumItem); |
| if (value != null) { |
| return value; |
| } |
| } |
| |
| throw new AoException(ErrorCode.AO_NOT_FOUND, SeverityFlag.ERROR, 0, |
| "Enumeration value not found for [enumName=" + enumName + ",enumItem=" + enumItem + "]"); |
| } |
| |
| /** |
| * Unique key for an application relation. |
| */ |
| private static class ApplicationRelKey { |
| |
| private final String ae1name; |
| |
| private final String ae2name; |
| |
| /** |
| * Creates a new ApplicationRelKey. |
| * |
| * @param ae1name |
| * the source application element name |
| * @param ae2name |
| * the target application element name |
| */ |
| public ApplicationRelKey(String ae1name, String ae2name) { |
| this.ae1name = ae1name; |
| this.ae2name = ae2name; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = 1; |
| result = prime * result + (ae1name == null ? 0 : ae1name.hashCode()); |
| result = prime * result + (ae2name == null ? 0 : ae2name.hashCode()); |
| return result; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj == null) { |
| return false; |
| } |
| if (getClass() != obj.getClass()) { |
| return false; |
| } |
| final ApplicationRelKey other = (ApplicationRelKey) obj; |
| if (ae1name == null) { |
| if (other.ae1name != null) { |
| return false; |
| } |
| } else if (!ae1name.equals(other.ae1name)) { |
| return false; |
| } |
| if (ae2name == null) { |
| if (other.ae2name != null) { |
| return false; |
| } |
| } else if (!ae2name.equals(other.ae2name)) { |
| return false; |
| } |
| return true; |
| } |
| |
| } |
| |
| } |