Skip to content

Commit

Permalink
- Added support for the fn:name, fn:local-name, fn:namespace-uri, fn:…
Browse files Browse the repository at this point in the history
…root, fn:has-children, fn:innermost, and fn:outermost Metapath functions. (#288)

- Added support for node items that are backed by a data model implementation.
- Added the ability to dynamically build note item trees to support unit testing and future parsing use cases. Build a unit test of fn:name using this new functionality.
- Updated tests to point to OSCAL v1.1.3 to reduce missing value warnings during debugging.
- Improved the ability to test expected sequences and item types in functions. Used this capability to test that that FnName handles errors correctly.
- Fixed a bug causing the ancestor-related axis to not return results in document order. Added support for the fn:root Metapath function.
- Refactored node test implementation to support kind-based node tests. Added support for the fn:root Metapath function.
- Added check for another stream consumed case in stream-based sequences caused when the stream is already consumed before a list is requested.
  • Loading branch information
david-waltermire authored Dec 12, 2024
1 parent deb73be commit 3c96d58
Show file tree
Hide file tree
Showing 71 changed files with 2,824 additions and 252 deletions.
3 changes: 1 addition & 2 deletions core/src/main/antlr4/Metapath10.g4
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ reversestep : reverseaxis nodetest | abbrevreversestep ;
reverseaxis : KW_PARENT COLONCOLON | KW_ANCESTOR COLONCOLON | KW_PRECEDING_SIBLING COLONCOLON | KW_PRECEDING COLONCOLON | KW_ANCESTOR_OR_SELF COLONCOLON ;
// [45]
abbrevreversestep : DD ;
// nodetest : kindtest | nametest ;
nodetest : nametest ;
nodetest : kindtest | nametest ;
nametest : eqname | wildcard ;
wildcard : STAR | NCName CS | SC NCName | BracedURILiteral STAR ;
postfixexpr : primaryexpr (predicate | argumentlist | lookup)* ;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm;

import gov.nist.secauto.metaschema.core.mdm.impl.IDMModelNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IAssemblyNodeItem;
import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IAssemblyInstance;
import gov.nist.secauto.metaschema.core.model.IFieldInstance;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;

import edu.umd.cs.findbugs.annotations.NonNull;

/**
* An assembly node item implementation that is backed by a simple Metaschema
* module-based data model.
*/
public interface IDMAssemblyNodeItem
extends IAssemblyNodeItem, IDMModelNodeItem<IAssemblyDefinition, IAssemblyInstance> {
/**
* Create and add a new field to the underlying data model.
*
* @param instance
* the Metaschema field instance describing the field
* @param resourceLocation
* information about the location of the field within the containing
* resource
* @param value
* the atomic field value
* @return the new field node item
*/
@NonNull
IDMFieldNodeItem newField(
@NonNull IFieldInstance instance,
@NonNull IResourceLocation resourceLocation,
@NonNull IAnyAtomicItem value);

/**
* Create and add a new assembly to the underlying data model.
*
* @param instance
* the Metaschema assembly instance describing the assembly
* @param resourceLocation
* information about the location of the assembly within the containing
* resource
* @return the new assembly node item
*/
@NonNull
IDMAssemblyNodeItem newAssembly(
@NonNull IAssemblyInstance instance,
@NonNull IResourceLocation resourceLocation);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm;

import gov.nist.secauto.metaschema.core.mdm.impl.DocumentImpl;
import gov.nist.secauto.metaschema.core.metapath.item.node.IDocumentNodeItem;
import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;

import java.net.URI;

import edu.umd.cs.findbugs.annotations.NonNull;

/**
* A document node item implementation that is backed by a simple Metaschema
* module-based data model.
*/
public interface IDMDocumentNodeItem
extends IDocumentNodeItem {
@Override
IDMRootAssemblyNodeItem getRootAssemblyNodeItem();

/**
* Create a new Metaschema document-based data model.
*
* @param resource
* the base URI of the document resource
* @param resourceLocation
* information about the (intended) location of the document resource
* @param rootAssembly
* the assembly that is at the root of the node tree for this document
* @param rootAssemblyLocation
* information about the (intended) location of the root assembly
* resource
* @return the document node item
*/
@NonNull
static IDMDocumentNodeItem newInstance(
@NonNull URI resource,
@NonNull IResourceLocation resourceLocation,
@NonNull IAssemblyDefinition rootAssembly,
@NonNull IResourceLocation rootAssemblyLocation) {
return new DocumentImpl(resource, resourceLocation, rootAssembly, rootAssemblyLocation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm;

import gov.nist.secauto.metaschema.core.mdm.impl.IDMModelNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IFieldNodeItem;
import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
import gov.nist.secauto.metaschema.core.model.IFieldInstance;

/**
* A field node item implementation that is backed by a simple Metaschema
* module-based data model.
*/
public interface IDMFieldNodeItem
extends IFieldNodeItem, IDMModelNodeItem<IFieldDefinition, IFieldInstance> {
// no additional methods
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm;

import gov.nist.secauto.metaschema.core.metapath.item.node.IRootAssemblyNodeItem;

/**
* A root assembly node item implementation that is backed by a simple
* Metaschema module-based data model.
*/
public interface IDMRootAssemblyNodeItem
extends IDMAssemblyNodeItem, IRootAssemblyNodeItem {
// no additional methods
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm.impl;

import gov.nist.secauto.metaschema.core.mdm.IDMAssemblyNodeItem;
import gov.nist.secauto.metaschema.core.mdm.IDMFieldNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.AbstractNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IFlagNodeItem;
import gov.nist.secauto.metaschema.core.model.IAssemblyInstance;
import gov.nist.secauto.metaschema.core.model.IFieldInstance;
import gov.nist.secauto.metaschema.core.model.IFlagInstance;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.CollectionUtil;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import edu.umd.cs.findbugs.annotations.NonNull;

public abstract class AbstractDMAssemblyNodeItem
extends AbstractNodeItem
implements IDMAssemblyNodeItem {
@NonNull
private final Map<IEnhancedQName, IFlagNodeItem> flags = new ConcurrentHashMap<>();
@NonNull
private final Map<IEnhancedQName, List<IDMModelNodeItem<?, ?>>> modelItems
= new ConcurrentHashMap<>();

protected AbstractDMAssemblyNodeItem() {
// nothing to do
}

@Override
public Object getValue() {
return this;
}

@Override
public String stringValue() {
return "";
}

@Override
protected String getValueSignature() {
return "";
}

@Override
public Collection<? extends IFlagNodeItem> getFlags() {
return ObjectUtils.notNull(flags.values());
}

@Override
public IFlagNodeItem getFlagByName(IEnhancedQName name) {
return flags.get(name);
}

@Override
public IFlagNodeItem newFlag(
@NonNull IFlagInstance instance,
@NonNull IResourceLocation resourceLocation,
@NonNull IAnyAtomicItem value) {
IFlagNodeItem flag = new FlagImpl(instance, this, resourceLocation, value);
flags.put(instance.getQName(), flag);
return flag;
}

@Override
public Collection<List<IDMModelNodeItem<?, ?>>> getModelItems() {
return ObjectUtils.notNull(modelItems.values());
}

@Override
public List<? extends IDMModelNodeItem<?, ?>> getModelItemsByName(IEnhancedQName name) {
List<? extends IDMModelNodeItem<?, ?>> retval = modelItems.get(name);
return retval == null ? CollectionUtil.emptyList() : retval;
}

@Override
public IDMFieldNodeItem newField(IFieldInstance instance, IResourceLocation resourceLocation, IAnyAtomicItem value) {
List<IDMModelNodeItem<?, ?>> result = modelItems.computeIfAbsent(
instance.getQName(),
name -> Collections.synchronizedList(new LinkedList<IDMModelNodeItem<?, ?>>()));
IDMFieldNodeItem field = new FieldImpl(instance, this, resourceLocation, value);
result.add(field);
return field;
}

@Override
public IDMAssemblyNodeItem newAssembly(IAssemblyInstance instance, IResourceLocation resourceLocation) {
List<IDMModelNodeItem<?, ?>> result = modelItems.computeIfAbsent(
instance.getQName(),
name -> Collections.synchronizedList(new LinkedList<IDMModelNodeItem<?, ?>>()));
IDMAssemblyNodeItem assembly = new AssemblyImpl(instance, this, resourceLocation);
result.add(assembly);
return assembly;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm.impl;

import gov.nist.secauto.metaschema.core.metapath.StaticContext;
import gov.nist.secauto.metaschema.core.metapath.item.node.AbstractInstanceNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IModelNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
import gov.nist.secauto.metaschema.core.model.IDefinition;
import gov.nist.secauto.metaschema.core.model.IModelDefinition;
import gov.nist.secauto.metaschema.core.model.INamedInstance;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;

import edu.umd.cs.findbugs.annotations.NonNull;

public abstract class AbstractDMInstanceNodeItem<
D extends IDefinition,
I extends INamedInstance,
P extends IModelNodeItem<? extends IModelDefinition, ? extends INamedInstance>>
extends AbstractInstanceNodeItem<D, I, P>
implements INodeItem {
@NonNull
private final IResourceLocation resourceLocation;

protected AbstractDMInstanceNodeItem(
@NonNull I instance,
@NonNull P parent,
@NonNull IResourceLocation resourceLocation) {
super(instance, parent);
this.resourceLocation = resourceLocation;
}

@Override
public IResourceLocation getLocation() {
return resourceLocation;
}

@Override
public StaticContext getStaticContext() {
return getParentNodeItem().getStaticContext();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.mdm.impl;

import gov.nist.secauto.metaschema.core.mdm.IDMAssemblyNodeItem;
import gov.nist.secauto.metaschema.core.metapath.StaticContext;
import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IAssemblyInstance;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;

import edu.umd.cs.findbugs.annotations.NonNull;

public class AssemblyImpl
extends AbstractDMAssemblyNodeItem {
@NonNull
private final IAssemblyInstance instance;
@NonNull
private final IDMAssemblyNodeItem parent;
@NonNull
private final IResourceLocation resourceLocation;

public AssemblyImpl(
@NonNull IAssemblyInstance instance,
@NonNull IDMAssemblyNodeItem parent,
@NonNull IResourceLocation resourceLocation) {
this.instance = instance;
this.parent = parent;
this.resourceLocation = resourceLocation;
}

@Override
public IResourceLocation getLocation() {
return resourceLocation;
}

@Override
public int getPosition() {
return getParentNodeItem().getModelItemsByName(getQName()).indexOf(this);
}

@Override
@NonNull
public IDMAssemblyNodeItem getParentNodeItem() {
return getParentContentNodeItem();
}

@Override
@NonNull
public IDMAssemblyNodeItem getParentContentNodeItem() {
return parent;
}

@Override
public IAssemblyDefinition getDefinition() {
return getInstance().getDefinition();
}

@Override
public IAssemblyInstance getInstance() {
return instance;
}

@Override
public StaticContext getStaticContext() {
return getParentNodeItem().getStaticContext();
}
}
Loading

0 comments on commit 3c96d58

Please sign in to comment.