Skip to content

Commit

Permalink
Reworked how Metapath expressions are compiled to ensure the static c…
Browse files Browse the repository at this point in the history
…ontext from their source is used in compilation. (metaschema-framework#305)

Also improved node item, definition, and instance creation for easier use in unit tests.
  • Loading branch information
david-waltermire authored Dec 20, 2024
1 parent f4b5016 commit f457b9f
Show file tree
Hide file tree
Showing 105 changed files with 2,398 additions and 1,382 deletions.
2 changes: 1 addition & 1 deletion core/src/main/antlr4/Metapath10.g4
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ parenthesizeditemtype : OP itemtype CP ;


// Error in the spec. EQName also includes acceptable keywords.
eqname : NCName | QName | URIQualifiedName
eqname : URIQualifiedName | NCName | QName
| KW_ANCESTOR
| KW_ANCESTOR_OR_SELF
| KW_AND
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/antlr4/Metapath10Lexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ DecimalLiteral : '.' FragDigits | FragDigits '.' [0-9]*;
DoubleLiteral : ('.' FragDigits | FragDigits ('.' [0-9]*)?) [eE] [+-]? FragDigits;
StringLiteral : '"' (~["] | FragEscapeQuot)* '"' | '\'' (~['] | FragEscapeApos)* '\'';
URIQualifiedName : BracedURILiteral NCName;
BracedURILiteral : 'Q' '{' [^{}]* '}';
BracedURILiteral : 'Q' '{' ~[{}]* '}';
// Error in spec: EscapeQuot and EscapeApos are not terminals!
fragment FragEscapeQuot : '""';
fragment FragEscapeApos : '\'\'';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,71 @@

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

import gov.nist.secauto.metaschema.core.mdm.impl.DefinitionAssemblyNodeItem;
import gov.nist.secauto.metaschema.core.mdm.impl.IDMModelNodeItem;
import gov.nist.secauto.metaschema.core.metapath.StaticContext;
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.
* Represents a Metapath assembly node item that is backed by a simple
* Metaschema module-based data model.
* <p>
* The {@link #newInstance(IAssemblyDefinition, StaticContext)} method can be
* used to create a node from an {@link IAssemblyDefinition} that is orphaned
* from a document model.
* <p>
* Child nodes can be created using the
* {@link #newFlag(gov.nist.secauto.metaschema.core.model.IFlagInstance, IAnyAtomicItem)},
* {@link #newAssembly(IAssemblyInstance)}, and
* {@link #newField(IFieldInstance, IAnyAtomicItem)} methods. These children are
* added to this assembly.
*/
public interface IDMAssemblyNodeItem
extends IAssemblyNodeItem, IDMModelNodeItem<IAssemblyDefinition, IAssemblyInstance> {
/**
* Create new assembly node item that is detached from a parent node item.
*
* @param definition
* the Metaschema field definition describing the assembly
* @param staticContext
* the atomic field value
* @return the new field node item
*/
@NonNull
static IDMAssemblyNodeItem newInstance(
@NonNull IAssemblyDefinition definition,
@NonNull StaticContext staticContext) {
return new DefinitionAssemblyNodeItem(definition, staticContext);
}

/**
* 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);
@NonNull IAssemblyInstance instance);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@

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

import gov.nist.secauto.metaschema.core.mdm.impl.DocumentImpl;
import gov.nist.secauto.metaschema.core.mdm.impl.DocumentNodeItem;
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.
* Represents a Metapath document node item that is backed by a simple
* Metaschema module-based data model.
* <p>
* The {@link #newInstance(URI, IAssemblyDefinition)} method can be used to
* create a new document-based data model.
*/
public interface IDMDocumentNodeItem
extends IDocumentNodeItem {
Expand All @@ -28,21 +30,14 @@ public interface IDMDocumentNodeItem
*
* @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);
@NonNull IAssemblyDefinition rootAssembly) {
return new DocumentNodeItem(resource, rootAssembly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,44 @@

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

import gov.nist.secauto.metaschema.core.mdm.impl.DefinitionFieldNodeItem;
import gov.nist.secauto.metaschema.core.mdm.impl.IDMModelNodeItem;
import gov.nist.secauto.metaschema.core.metapath.StaticContext;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IAtomicValuedNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IFieldNodeItem;
import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
import gov.nist.secauto.metaschema.core.model.IFieldInstance;

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

/**
* A field node item implementation that is backed by a simple Metaschema
* Represents a Metapath field node item that is backed by a simple Metaschema
* module-based data model.
* <p>
* The {@link #newInstance(IFieldDefinition, IAnyAtomicItem, StaticContext)}
* method can be used to create a node from an {@link IAssemblyDefinition} that
* is orphaned from a document model.
*/
public interface IDMFieldNodeItem
extends IFieldNodeItem, IDMModelNodeItem<IFieldDefinition, IFieldInstance> {
// no additional methods
extends IFieldNodeItem, IDMModelNodeItem<IFieldDefinition, IFieldInstance>, IAtomicValuedNodeItem, IDMNodeItem {
/**
* Create new field node item that is detached from a parent node item.
*
* @param definition
* the Metaschema field definition describing the field
* @param value
* the field's initial value
* @param staticContext
* the atomic field value
* @return the new field node item
*/
@NonNull
static IDMFieldNodeItem newInstance(
@NonNull IFieldDefinition definition,
@NonNull IAnyAtomicItem value,
@NonNull StaticContext staticContext) {
return new DefinitionFieldNodeItem(definition, value, staticContext);
}
}
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.IAtomicValuedNodeItem;
import gov.nist.secauto.metaschema.core.metapath.item.node.IFlagNodeItem;

/**
* Represents a Metapath flag node item that is backed by a simple Metaschema
* module-based data model.
*/
public interface IDMFlagNodeItem extends IFlagNodeItem, IDMNodeItem, IAtomicValuedNodeItem {
// no additional methods
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.INodeItem;
import gov.nist.secauto.metaschema.core.model.IResourceLocation;

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

/**
* Represents a Metapath node item that is backed by a simple Metaschema
* module-based data model.
*/
public interface IDMNodeItem extends INodeItem {
/**
* Provides a means to change the location information for the node item.
*
* @param location
* information about the location of the node within the containing
* resource
*/
void setLocation(@NonNull IResourceLocation location);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
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.
* Represents a Metapath root assembly node item implementation that is backed
* by a simple Metaschema module-based data model.
*/
public interface IDMRootAssemblyNodeItem
extends IDMAssemblyNodeItem, IRootAssemblyNodeItem {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
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.IAssemblyDefinition;
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;
Expand All @@ -27,22 +24,22 @@

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

/**
* This abstract Metapath assmebly node item implementation supports creating a
* Metaschema module-based data model.
*/
public abstract class AbstractDMAssemblyNodeItem
extends AbstractNodeItem
extends AbstractDMModelNodeItem<IAssemblyDefinition, IAssemblyInstance>
implements IDMAssemblyNodeItem {
@NonNull
private final Map<IEnhancedQName, IFlagNodeItem> flags = new ConcurrentHashMap<>();
@NonNull
private final Map<IEnhancedQName, List<IDMModelNodeItem<?, ?>>> modelItems
= new ConcurrentHashMap<>();

/**
* Construct a new node item.
*/
protected AbstractDMAssemblyNodeItem() {
// nothing to do
}

@Override
public Object getValue() {
return this;
// only allow extending classes to create instances
}

@Override
Expand All @@ -55,26 +52,6 @@ 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());
Expand All @@ -87,21 +64,21 @@ public IFlagNodeItem newFlag(
}

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

@Override
public IDMAssemblyNodeItem newAssembly(IAssemblyInstance instance, IResourceLocation resourceLocation) {
public IDMAssemblyNodeItem newAssembly(IAssemblyInstance instance) {
List<IDMModelNodeItem<?, ?>> result = modelItems.computeIfAbsent(
instance.getQName(),
name -> Collections.synchronizedList(new LinkedList<IDMModelNodeItem<?, ?>>()));
IDMAssemblyNodeItem assembly = new AssemblyImpl(instance, this, resourceLocation);
name -> Collections.synchronizedList(new LinkedList<>()));
IDMAssemblyNodeItem assembly = new ChildAssemblyNodeItem(instance, this);
result.add(assembly);
return assembly;
}
Expand Down
Loading

0 comments on commit f457b9f

Please sign in to comment.