All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.xtce.XtceDb Maven / Gradle / Ivy

There is a newer version: 5.10.7
Show newest version
package org.yamcs.xtce;

import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.protobuf.Yamcs.NamedObjectId;
import org.yamcs.xtce.xml.XtceAliasSet;

/**
 * XtceDB database
 * 

* It contains a SpaceSystem as defined in the Xtce schema and has lots of hashes to help find things quickly * * */ public class XtceDb implements Serializable { private static final long serialVersionUID = 57L; final SpaceSystem rootSystem; // rwLock is used to guard the read/write of parameters, parameter types and spaceSystems which are the only ones // that can change dynamically as of now ReadWriteLock rwLock = new ReentrantReadWriteLock(); /** * Namespaces system parameters */ public static final String YAMCS_SPACESYSTEM_NAME = "/yamcs"; public static final String YAMCS_CMD_SPACESYSTEM_NAME = "/yamcs/cmd"; public static final String YAMCS_CMDARG_SPACESYSTEM_NAME = "/yamcs/cmd/arg"; public static final String YAMCS_CMDHIST_SPACESYSTEM_NAME = "/yamcs/cmdHist"; transient static Logger log = LoggerFactory.getLogger(XtceDb.class); // map from the fully qualified names to the objects protected HashMap spaceSystems = new HashMap<>(); protected Map sequenceContainers = new LinkedHashMap<>(); protected Map parameters = new LinkedHashMap<>(); protected Map parameterTypes = new LinkedHashMap<>(); protected Map argumentTypes = new LinkedHashMap<>(); protected HashMap algorithms = new HashMap<>(); protected HashMap commands = new HashMap<>(); @SuppressWarnings("rawtypes") private HashMap, NonStandardData> nonStandardDatas = new HashMap<>(); // different namespaces private NamedDescriptionIndex spaceSystemAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex parameterAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex parameterTypeAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex argumentTypeAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex sequenceContainerAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex algorithmAliases = new NamedDescriptionIndex<>(); private NamedDescriptionIndex commandAliases = new NamedDescriptionIndex<>(); private Map> indirectParameterRefEntries = new HashMap<>(); private Set namespaces = new HashSet<>(); // this is the default sequence container where the xtce processors start processing // specific ones can be defined per tm stream SequenceContainer rootSequenceContainer; /** * Maps the Parameter to a list of ParameterEntry such that we know from which container we can extract this * parameter */ private HashMap> parameter2ParameterEntryMap; /** * maps the SequenceContainer to a list of other EntryContainers in case of aggregation */ private HashMap> sequenceContainer2ContainerEntryMap; /** * maps the SequenceContainer to a list of containers inheriting this one */ private HashMap> sequenceContainer2InheritingContainerMap; public XtceDb(SpaceSystem spaceSystem) { this.rootSystem = spaceSystem; } public SequenceContainer getSequenceContainer(String qualifiedName) { return sequenceContainers.get(qualifiedName); } public SequenceContainer getSequenceContainer(String namespace, String name) { return sequenceContainerAliases.get(namespace, name); } public SequenceContainer getSequenceContainer(NamedObjectId id) { if (id.hasNamespace()) { return sequenceContainerAliases.get(id.getNamespace(), id.getName()); } else { return sequenceContainerAliases.get(id.getName()); } } /** * returns the parameter with the given qualified name or null if it does not exist */ public Parameter getParameter(String qualifiedName) { rwLock.readLock().lock(); try { int idx = qualifiedName.indexOf('/'); if (idx == 0) { return parameters.get(qualifiedName); } else if (idx > 0) { String namespace = qualifiedName.substring(0, idx); String name = qualifiedName.substring(idx + 1); return getParameter(namespace, name); } return null; } finally { rwLock.readLock().unlock(); } } public static NamedObjectId toNamedObjectId(String qualifiedName) { int idx = qualifiedName.indexOf('/'); if (idx == 0) { return NamedObjectId.newBuilder().setName(qualifiedName).build(); } else if (idx > 0) { return NamedObjectId.newBuilder() .setNamespace(qualifiedName.substring(0, idx)) .setName(qualifiedName.substring(idx + 1)) .build(); } throw new IllegalArgumentException("Invalid parameter id " + qualifiedName); } public Parameter getParameter(String namespace, String name) { rwLock.readLock().lock(); try { return parameterAliases.get(namespace, name); } finally { rwLock.readLock().unlock(); } } public Parameter getParameter(NamedObjectId id) { rwLock.readLock().lock(); try { if (id.hasNamespace()) { return parameterAliases.get(id.getNamespace(), id.getName()); } else { return parameterAliases.get(id.getName()); } } finally { rwLock.readLock().unlock(); } } public ParameterType getParameterType(String qualifiedName) { return parameterTypes.get(qualifiedName); } /** * Returns an argument type with the given qualified name or null if it does not exist *

* Note that not all argument types have qualified names, some are used only locally in the command definitions and * are never registered at the global level */ public ArgumentType getArgumentType(String qualifiedName) { return argumentTypes.get(qualifiedName); } public ParameterType getParameterType(String namespace, String name) { return (ParameterType) parameterTypeAliases.get(namespace, name); } public ParameterType getParameterType(NamedObjectId id) { if (id.hasNamespace()) { return (ParameterType) parameterTypeAliases.get(id.getNamespace(), id.getName()); } else { return (ParameterType) parameterTypeAliases.get(id.getName()); } } public SequenceContainer getRootSequenceContainer() { return rootSequenceContainer; } public void setRootSequenceContainer(SequenceContainer sc) { this.rootSequenceContainer = sc; } public Algorithm getAlgorithm(String qualifiedName) { return algorithmAliases.get(qualifiedName); } public Algorithm getAlgorithm(String namespace, String name) { return algorithmAliases.get(namespace, name); } public Algorithm getAlgorithm(NamedObjectId id) { if (id.hasNamespace()) { return algorithmAliases.get(id.getNamespace(), id.getName()); } else { return algorithmAliases.get(id.getName()); } } public Collection getAlgorithms() { return algorithms.values(); } public Collection getParameters() { rwLock.readLock().lock(); try { return new ArrayList<>(parameters.values()); } finally { rwLock.readLock().unlock(); } } public Collection getParameterTypes() { return parameterTypes.values(); } public boolean containsNamespace(String namespace) { return namespaces.contains(namespace); } public Set getNamespaces() { return namespaces; } /** * Returns a meta command by fully qualified name. * * @param qualifiedName * - fully qualified name of the command to be returned. * @return the meta command having the given qualified name. If no such command exists, null is * returned. */ public MetaCommand getMetaCommand(String qualifiedName) { rwLock.readLock().lock(); try { return commandAliases.get(qualifiedName); } finally { rwLock.readLock().unlock(); } } /** * Returns a command based on a name in a namespace * * @param namespace * @param name * @return the meta command having the given name in the given namespace. If no such meta command exists, * null is returned. */ public MetaCommand getMetaCommand(String namespace, String name) { rwLock.readLock().lock(); try { return commandAliases.get(namespace, name); } finally { rwLock.readLock().unlock(); } } public MetaCommand getMetaCommand(NamedObjectId id) { rwLock.readLock().lock(); try { if (id.hasNamespace()) { return commandAliases.get(id.getNamespace(), id.getName()); } else { return commandAliases.get(id.getName()); } } finally { rwLock.readLock().unlock(); } } /** * Returns the list of MetaCommmands in the XTCE database * * @return */ public Collection getMetaCommands() { rwLock.readLock().lock(); try { return commands.values(); } finally { rwLock.readLock().unlock(); } } public SpaceSystem getRootSpaceSystem() { return rootSystem; } public SpaceSystem getSpaceSystem(String qualifiedName) { rwLock.readLock().lock(); try { return spaceSystemAliases.get(qualifiedName); } finally { rwLock.readLock().unlock(); } } public SpaceSystem getSpaceSystem(String namespace, String name) { rwLock.readLock().lock(); try { return spaceSystemAliases.get(namespace, name); } finally { rwLock.readLock().unlock(); } } public SpaceSystem getSpaceSystem(NamedObjectId id) { rwLock.readLock().lock(); try { if (id.hasNamespace()) { return spaceSystemAliases.get(id.getNamespace(), id.getName()); } else { return spaceSystemAliases.get(id.getName()); } } finally { rwLock.readLock().unlock(); } } public Collection getSequenceContainers() { return sequenceContainers.values(); } /** * * @return list of ParameterEntry corresponding to a given parameter or null if no such entry exists. */ public List getParameterEntries(Parameter p) { return parameter2ParameterEntryMap.get(p); } /** * @return list of ContainerEntry corresponding to a given sequence container or null if no such entry * exists. */ public List getContainerEntries(SequenceContainer sc) { return sequenceContainer2ContainerEntryMap.get(sc); } public Collection getParameterNames() { return parameters.keySet(); } @SuppressWarnings("unchecked") public > T getNonStandardDataOfType(Class clazz) { if (nonStandardDatas.containsKey(clazz)) { return (T) nonStandardDatas.get(clazz); } else { return null; } } @SuppressWarnings("rawtypes") public Collection getNonStandardData() { return nonStandardDatas.values(); } /** * Called after the database has been populated to build the maps for quickly finding things * */ public void buildIndexMaps() { buildSpaceSystemsMap(rootSystem); buildParameterMap(rootSystem); buildParameterTypeMap(rootSystem); buildArgumentTypeMap(rootSystem); buildSequenceContainerMap(rootSystem); buildAlgorithmMap(rootSystem); buildMetaCommandMap(rootSystem); buildNonStandardDataMap(rootSystem); parameter2ParameterEntryMap = new HashMap<>(); sequenceContainer2ContainerEntryMap = new HashMap<>(); sequenceContainer2InheritingContainerMap = new HashMap<>(); for (SequenceContainer sc : sequenceContainers.values()) { for (SequenceEntry se : sc.getEntryList()) { if (se instanceof ParameterEntry) { ParameterEntry pe = (ParameterEntry) se; Parameter param = pe.getParameter(); ArrayList al = parameter2ParameterEntryMap.computeIfAbsent(param, k -> new ArrayList<>()); al.add(pe); } else if (se instanceof ContainerEntry) { ContainerEntry ce = (ContainerEntry) se; ArrayList al = sequenceContainer2ContainerEntryMap .computeIfAbsent(ce.getRefContainer(), k -> new ArrayList<>()); al.add(ce); } else if (se instanceof IndirectParameterRefEntry) { IndirectParameterRefEntry ipe = (IndirectParameterRefEntry) se; List l = indirectParameterRefEntries .computeIfAbsent(ipe.getAliasNameSpace(), k -> new ArrayList<>()); l.add(ipe); } } if (sc.baseContainer != null) { ArrayList al_sc = sequenceContainer2InheritingContainerMap .get(sc.baseContainer); if (al_sc == null) { al_sc = new ArrayList<>(); sequenceContainer2InheritingContainerMap.put(sc.getBaseContainer(), al_sc); } al_sc.add(sc); } } // build aliases maps for (SpaceSystem ss : spaceSystems.values()) { spaceSystemAliases.add(ss); XtceAliasSet aliases = ss.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (SequenceContainer sc : sequenceContainers.values()) { sequenceContainerAliases.add(sc); XtceAliasSet aliases = sc.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (Parameter p : parameters.values()) { parameterAliases.add(p); XtceAliasSet aliases = p.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (ParameterType t : parameterTypes.values()) { parameterTypeAliases.add((NameDescription) t); XtceAliasSet aliases = ((NameDescription) t).getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (ArgumentType t : argumentTypes.values()) { argumentTypeAliases.add((NameDescription) t); XtceAliasSet aliases = ((NameDescription) t).getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (Algorithm a : algorithms.values()) { algorithmAliases.add(a); XtceAliasSet aliases = a.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } for (MetaCommand mc : commands.values()) { commandAliases.add(mc); XtceAliasSet aliases = mc.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } } private void buildSpaceSystemsMap(SpaceSystem ss) { spaceSystems.put(ss.getQualifiedName(), ss); for (SpaceSystem ss1 : ss.getSubSystems()) { buildSpaceSystemsMap(ss1); } } private void buildParameterMap(SpaceSystem ss) { for (Parameter p : ss.getParameters()) { parameters.put(p.getQualifiedName(), p); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildParameterMap(ss1); } } private void buildParameterTypeMap(SpaceSystem ss) { for (ParameterType t : ss.getParameterTypes()) { String qualifiedName = ((NameDescription) t).getQualifiedName(); parameterTypes.put(qualifiedName, t); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildParameterTypeMap(ss1); } } private void buildArgumentTypeMap(SpaceSystem ss) { for (ArgumentType t : ss.getArgumentTypes()) { String qualifiedName = ((NameDescription) t).getQualifiedName(); argumentTypes.put(qualifiedName, t); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildArgumentTypeMap(ss1); } } private void buildSequenceContainerMap(SpaceSystem ss) { for (SequenceContainer sc : ss.getSequenceContainers()) { sequenceContainers.put(sc.getQualifiedName(), sc); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildSequenceContainerMap(ss1); } } private void buildAlgorithmMap(SpaceSystem ss) { for (Algorithm a : ss.getAlgorithms()) { algorithms.put(a.getQualifiedName(), a); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildAlgorithmMap(ss1); } } private void buildMetaCommandMap(SpaceSystem ss) { for (MetaCommand mc : ss.getMetaCommands()) { commands.put(mc.getQualifiedName(), mc); } for (SpaceSystem ss1 : ss.getSubSystems()) { buildMetaCommandMap(ss1); } } @SuppressWarnings({ "rawtypes", "unchecked" }) private void buildNonStandardDataMap(SpaceSystem ss) { for (NonStandardData data : ss.getNonStandardData()) { if (nonStandardDatas.containsKey(data.getClass())) { NonStandardData mergeResult = nonStandardDatas.get(data.getClass()).mergeWithChild(data); nonStandardDatas.put(data.getClass(), mergeResult); } else { nonStandardDatas.put(data.getClass(), data); } } for (SpaceSystem ss1 : ss.getSubSystems()) { buildNonStandardDataMap(ss1); } } /** * Get the list of containers inheriting from the given container * * @param container * @return */ public List getInheritingContainers(SequenceContainer container) { return sequenceContainer2InheritingContainerMap.get(container); } protected void doAddParameter(Parameter p, boolean addSpaceSystem, boolean addParameterType) { doAddParameters(List.of(p), addSpaceSystem, addParameterType); } /** * Adds a list of new parameters to the XTCE db. If createSpaceSystem is true, also create the Space Systems where * these parameters belong. * *

* Throws a IllegalArgumentException if: *

* - createSpaceSystem is false and the Space Systems do not exist. *

* - the parameter with the given qualified name already exist * * @param newparams * - the list of parameters to be added * @param addParameterTypes * - if true, add also the parameter types (if not already in the database) * @param addSpaceSystems * - if true, create all the necessary space systems */ protected void doAddParameters(List newparams, boolean addSpaceSystems, boolean addParameterTypes) { log.debug("Adding parameters {} , createSpaceSystem: {}", newparams, addSpaceSystems); rwLock.writeLock().lock(); try { for (var p : newparams) { if (parameters.containsKey(p.getQualifiedName())) { throw new IllegalArgumentException( "There is already a parameter with qualified name '" + p.getQualifiedName() + "'"); } if (!addSpaceSystems) { SpaceSystem ss = spaceSystems.get(p.getSubsystemName()); if (ss == null) { throw new IllegalArgumentException("No SpaceSystem by name '" + p.getSubsystemName() + "'"); } var pt = p.getParameterType(); if (pt != null) { ss = spaceSystems.get(NameDescription.getSubsystemName(pt.getQualifiedName())); if (ss == null) { throw new IllegalArgumentException("No SpaceSystem by name '" + p.getSubsystemName() + "' (required by the type of " + p.getQualifiedName() + ")"); } } } if (!addParameterTypes) { var pt = p.getParameterType(); if (pt != null) { var pt1 = parameterTypes.get(pt.getQualifiedName()); if (pt1 == null) { throw new IllegalArgumentException("Parameter Type '" + pt.getQualifiedName() + " required by " + p.getQualifiedName() + " not found"); } if (pt1 != pt) { throw new IllegalArgumentException("Parameter Type '" + pt.getQualifiedName() + " required by " + p.getQualifiedName() + " found but it is different than the one referenced in the parameter"); } } } } for (var p : newparams) { String ssname = p.getSubsystemName(); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null) { createAllSpaceSystems(ssname); ss = spaceSystems.get(ssname); } var pt = p.getParameterType(); if (pt != null) { var pt1 = parameterTypes.get(pt.getQualifiedName()); if (pt1 == null) { SpaceSystem ssPt = spaceSystems.get(NameDescription.getSubsystemName(pt.getQualifiedName())); if (ssPt == null) { createAllSpaceSystems(ssname); } ssPt.addParameterType(pt); } } ss.addParameter(p); parameters.put(p.getQualifiedName(), p); parameterAliases.add(p); XtceAliasSet aliases = p.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } } finally { rwLock.writeLock().unlock(); } } /** * Adds new parameter types to the XTCE db. *

* * If the SpaceSystem where this parameter type does not exist, and createSpaceSystem is false, throws an * IllegalArgumentException. *

* If the SpaceSystem where this parameter belongs exists and already contains an parameter type by this name, * throws and IllegalArgumentException *

* If the SpaceSystem where this parameter belongs does not exist, and createSpaceSystem is true, the whole * SpaceSystem hierarchy is created. * * * @param ptypeList * - the parameter types to be added * @param createSpaceSystem * - if true, create all the necessary space systems */ protected void doAddParameterType(List ptypeList, boolean createSpaceSystem) { log.debug("Adding parameter types {} , createSpaceSystem: {}", ptypeList, createSpaceSystem); rwLock.writeLock().lock(); try { for (var ptype : ptypeList) { String fqn = ptype.getQualifiedName(); if (parameterTypes.containsKey(fqn)) { throw new IllegalArgumentException( "There is already a parameter with qualified name '" + fqn + "'"); } String ssname = NameDescription.getSubsystemName(fqn); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null && !createSpaceSystem) { throw new IllegalArgumentException("No SpaceSystem by name '" + ssname + "'"); } } for (var ptype : ptypeList) { String fqn = ptype.getQualifiedName(); String ssname = NameDescription.getSubsystemName(fqn); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null) { createAllSpaceSystems(ssname); } ss = spaceSystems.get(ssname); ss.addParameterType(ptype); parameterTypes.put(fqn, ptype); parameterTypeAliases.add((NameDescription) ptype); XtceAliasSet aliases = ((NameDescription) ptype).getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } } finally { rwLock.writeLock().unlock(); } } /** * Adds new argument types to the XTCE db. *

* * If the SpaceSystem where this argument type does not exist, and createSpaceSystem is false, throws an * IllegalArgumentException. *

* If the SpaceSystem where this argument belongs exists and already contains an argument type by this name, throws * and IllegalArgumentException *

* If the SpaceSystem where this argument belongs does not exist, and createSpaceSystem is true, the whole * SpaceSystem hierarchy is created. * * * @param atypeList * - the argument types to be added * @param createSpaceSystem * - if true, create all the necessary space systems */ protected void doAddArgumentType(List atypeList, boolean createSpaceSystem) { log.debug("Adding argument types {} , createSpaceSystem: {}", atypeList, createSpaceSystem); rwLock.writeLock().lock(); try { for (var ptype : atypeList) { String fqn = ptype.getQualifiedName(); if (argumentTypes.containsKey(fqn)) { throw new IllegalArgumentException( "There is already an argument with qualified name '" + fqn + "'"); } String ssname = NameDescription.getSubsystemName(fqn); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null && !createSpaceSystem) { throw new IllegalArgumentException("No SpaceSystem by name '" + ssname + "'"); } } for (var ptype : atypeList) { String fqn = ptype.getQualifiedName(); String ssname = NameDescription.getSubsystemName(fqn); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null) { createAllSpaceSystems(ssname); } ss = spaceSystems.get(ssname); ss.addArgumentType(ptype); argumentTypes.put(fqn, ptype); argumentTypeAliases.add((NameDescription) ptype); XtceAliasSet aliases = ((NameDescription) ptype).getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } } finally { rwLock.writeLock().unlock(); } } private void createAllSpaceSystems(String ssname) { String[] a = ssname.split("/"); String qn = ""; for (String name : a) { if (name.isEmpty()) { continue; } qn = qn + "/" + name; if (getSpaceSystem(qn) == null) { SpaceSystem ss = new SpaceSystem(name); ss.setQualifiedName(qn); addSpaceSystem(ss); } } } /** * Adds a new command definition to the XTCE db. *

* Note that this method is used to create commands on the fly.
* The commands are not saved anywhere and they will not be available when this object is created with the * XtceDbFactory. */ public void addMetaCommand(MetaCommand c) { rwLock.writeLock().lock(); try { String ssname = c.getSubsystemName(); SpaceSystem ss = spaceSystems.get(ssname); if (ss == null) { throw new IllegalArgumentException("No SpaceSystem by name '" + ssname + "'"); } ss.addMetaCommand(c); commands.put(c.getQualifiedName(), c); commandAliases.add(c); XtceAliasSet aliases = c.getAliasSet(); if (aliases != null) { namespaces.addAll(aliases.getNamespaces()); } } finally { rwLock.writeLock().unlock(); } } /** * Adds a new {@link SpaceSystem} to the XTCE database. * * It throws an IllegalArgumentException in the following circumstances: *

    *
  • if a SpaceSystem with this name already exists *
  • if {@link SpaceSystem#getParent() system.getParent()} does not return null *
  • if the parent SpaceSystem (identified based on the {@link SpaceSystem#getSubsystemName()}) does not exist *
  • if the space system is not empty *
* * This method also sets the parent of the passed spacesystem to its parent object. * * Note that this method is used to create SpaceSystems on the fly. The SpaceSystems are not saved anywhere and they * will not be available when this object is created by the XtceDbFactory. * * @param system * - the space system to be added. * */ public void addSpaceSystem(SpaceSystem system) { rwLock.writeLock().lock(); try { if (system.getParent() != null) { throw new IllegalArgumentException( "The parent of the space system has to be null (it will be set by this method"); } if (!system.getParameters().isEmpty() || !system.getSequenceContainers().isEmpty() || !system.getAlgorithms().isEmpty() || !system.getMetaCommands().isEmpty() || !system.getSubSystems().isEmpty()) { throw new IllegalArgumentException( "The space system must be empty (no parameters, containers, commands, algorithms, subsystems)"); } String parentName = system.getSubsystemName(); SpaceSystem parent = spaceSystems.get(parentName); if (parent == null) { throw new IllegalArgumentException("The parent subsystem '" + parentName + "' does not exist"); } parent.addSpaceSystem(system); system.setParent(parent); spaceSystems.put(system.getQualifiedName(), system); spaceSystemAliases.add(system); XtceAliasSet aliases = system.getAliasSet(); if (aliases != null) { aliases.getNamespaces().forEach(ns -> namespaces.add(ns)); } } finally { rwLock.writeLock().unlock(); } } /** * Checks if the named object refers to a system parameter: *
    *
  • either the namespace starts with {@link XtceDb#YAMCS_SPACESYSTEM_NAME}
  • *
  • or there is no namespace and the fully qualified name starts with {@link XtceDb#YAMCS_SPACESYSTEM_NAME}
  • *
* * @param id * @return */ public static boolean isSystemParameter(NamedObjectId id) { boolean result; if (!id.hasNamespace()) { result = id.getName().startsWith(XtceDb.YAMCS_SPACESYSTEM_NAME); } else { result = id.getNamespace().startsWith(XtceDb.YAMCS_SPACESYSTEM_NAME); } return result; } /** * Checks if a fully qualified name is the name of a system parameter. That is if fqn starts with * {@link XtceDb#YAMCS_SPACESYSTEM_NAME} * * @param fqn * @return */ public static boolean isSystemParameter(String fqn) { return fqn.startsWith(XtceDb.YAMCS_SPACESYSTEM_NAME); } /** * Returns a collection of all the {@link SpaceSystem} objects in the XTCE database. * * @return the collection of space systems. */ public Collection getSpaceSystems() { return spaceSystems.values(); } /** * Retrieve the list of {@link IndirectParameterRefEntry} for a given alias namespace. * * @param namespace * - the namespace for which the indirect parameter reference entries should be retrieved. Can be null to * return the entries without a namespace. * @return the list of indirect parameter reference entries whose alias namespace is equal to the given namespace. * If no such entry exists, null is returned. */ public Collection getIndirectParameterRefEntries(String namespace) { return indirectParameterRefEntries.get(namespace); } private void print(SpaceSystem ss, PrintStream out) { if (ss.getHeader() != null) { out.println("=========SpaceSystem " + ss.getQualifiedName() + " version: " + ss.getHeader().getVersion() + " date: " + ss.getHeader().getDate() + "========="); } else { out.println("=========SpaceSystem " + ss.getQualifiedName() + " (no header information)========="); } Comparator comparator = (o1, o2) -> o1.getName().compareTo(o2.getName()); SequenceContainer[] sca = ss.getSequenceContainers().toArray(new SequenceContainer[0]); Arrays.sort(sca, comparator); for (SequenceContainer sc : sca) { sc.print(out); } Algorithm[] aa = ss.getAlgorithms().toArray(new Algorithm[0]); Arrays.sort(aa, comparator); for (Algorithm a : aa) { a.print(out); } MetaCommand[] mca = ss.getMetaCommands().toArray(new MetaCommand[0]); Arrays.sort(mca, comparator); for (MetaCommand mc : mca) { mc.print(out); } // print the list of system variables if any (because those will not be part of the sequence containers) List systemVariables = new ArrayList<>(); for (Parameter p : ss.getParameters()) { if (p instanceof SystemParameter) { systemVariables.add((SystemParameter) p); } } if (!systemVariables.isEmpty()) { out.println("System Parameters: "); SystemParameter[] sva = systemVariables.toArray(new SystemParameter[0]); Arrays.sort(sva, comparator); for (SystemParameter sv : sva) { out.println("\t" + sv.getName()); } } SpaceSystem[] ssa = ss.getSubSystems().toArray(new SpaceSystem[0]); Arrays.sort(ssa, comparator); for (SpaceSystem ss1 : ssa) { print(ss1, out); } } public void print(PrintStream out) { print(rootSystem, out); Set orphanedParameters = new HashSet<>(); orphanedParameters.addAll(parameters.values()); removeNonOrphaned(rootSystem, orphanedParameters); orphanedParameters.removeAll(parameter2ParameterEntryMap.keySet()); if (!orphanedParameters.isEmpty()) { out.println("================ Orphaned parameters (not referenced in any container or algorithm):"); for (Parameter p : orphanedParameters) { String namespaces = ""; if (p.getAliasSet() != null) { namespaces = ", aliases: " + p.getAliasSet(); } out.println(p.getQualifiedName() + ", datasource: " + p.getDataSource() + namespaces + " type: " + p.getParameterType()); } } } private static void removeNonOrphaned(SpaceSystem ss, Set orphanedParameters) { for (Algorithm a : ss.getAlgorithms()) { for (InputParameter p : a.getInputSet()) { ParameterInstanceRef pref = p.getParameterInstance(); if (pref != null) { orphanedParameters.remove(pref.getParameter()); } } for (OutputParameter p : a.getOutputSet()) { orphanedParameters.remove(p.getParameter()); } } for (SpaceSystem ss1 : ss.getSubSystems()) { removeNonOrphaned(ss1, orphanedParameters); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy