Skip to content

Improve metapath exceptions for v3.0.0 #405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: develop
Choose a base branch
from

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

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

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

/**
* <a href= "https://www.w3.org/TR/xpath-31/#ERRXPDY0002">err:MPDY0002</a>: It
* is a <a href="https://www.w3.org/TR/xpath-31/#dt-dynamic-error">dynamic
* error</a> if evaluation of an expression relies on some part of the
* <a href="https://www.w3.org/TR/xpath-31/#dt-dynamic-context">dynamic
* context</a> that is
* <a href="https://www.w3.org/TR/xpath-datamodel-31/#dt-absent">absent</a>.
*/
public class ContextAbsentDynamicMetapathException
extends DynamicMetapathException {

private static final long serialVersionUID = 1L;

/**
* Constructs a new exception with the provided {@code message} and no cause.
*
* @param message
* the exception message
*/
public ContextAbsentDynamicMetapathException(@Nullable String message) {
super(DYNAMIC_CONTEXT_ABSENT, message);
}

/**
* Constructs a new exception with the provided {@code message} and
* {@code cause}.
*
* @param message
* the exception message
* @param cause
* the original exception cause
*/
public ContextAbsentDynamicMetapathException(
@Nullable String message,
@Nullable Throwable cause) {
super(DYNAMIC_CONTEXT_ABSENT, message, cause);
}

/**
* Constructs a new exception with the provided {@code cause} and no message.
*
* @param cause
* the original exception cause
*/
public ContextAbsentDynamicMetapathException(@Nullable Throwable cause) {
super(DYNAMIC_CONTEXT_ABSENT, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import gov.nist.secauto.metaschema.core.metapath.item.node.IDocumentNodeItem;
import gov.nist.secauto.metaschema.core.model.IUriResolver;
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.io.IOException;
Expand All @@ -31,11 +30,9 @@
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -223,17 +220,15 @@ public Map<URI, IDocumentNodeItem> getAvailableDocuments() {
* Get the document loader assigned to this dynamic context.
*
* @return the loader
* @throws DynamicMetapathException
* with an error code
* {@link DynamicMetapathException#DYNAMIC_CONTEXT_ABSENT} if a
* document loader is not configured for this dynamic context
* @throws ContextAbsentDynamicMetapathException
* if a document loader is not configured for this dynamic context
*/
@NonNull
public IDocumentLoader getDocumentLoader() {
IDocumentLoader retval = sharedState.documentLoader;
if (retval == null) {
throw new DynamicMetapathException(DynamicMetapathException.DYNAMIC_CONTEXT_ABSENT,
"No document loader configured for the dynamic context.");
throw new UnsupportedOperationException(
"No document loader configured for the dynamic context. Use setDocumentLoader(loader) to confgure one.");
}
return retval;
}
Expand Down Expand Up @@ -324,20 +319,18 @@ public IConfiguration<MetapathEvaluationFeature<?>> getConfiguration() {
* @param name
* the variable qualified name
* @return the non-null variable value
* @throws MetapathException
* @throws DynamicMetapathException
* of the variable has not been assigned or if the variable value is
* {@code null}
*/
@NonNull
public ISequence<?> getVariableValue(@NonNull IEnhancedQName name) {
ISequence<?> retval = letVariableMap.get(name.getIndexPosition());
if (retval == null) {
if (letVariableMap.containsKey(name.getIndexPosition())) {
throw new MetapathException(String.format("Variable '%s' has null contents.", name));
}
throw new StaticMetapathException(
StaticMetapathException.NOT_DEFINED,
String.format("Variable '%s' not defined in the dynamic context.", name));
String.format("Variable '%s' not defined in the dynamic context.", name))
.registerEvaluationContext(this);
}
return retval;
}
Expand All @@ -355,8 +348,8 @@ public ISequence<?> getVariableValue(@NonNull IEnhancedQName name) {
* a matching function was not found
*/
@NonNull
public IFunction getFunction(@NonNull IEnhancedQName name, int arity) {
return StaticContext.lookupFunction(name, arity);
public IFunction lookupFunction(@NonNull IEnhancedQName name, int arity) {
return getStaticContext().lookupFunction(name, arity);
}

/**
Expand Down Expand Up @@ -403,8 +396,8 @@ public void popExecutionStack(@NonNull IExpression expression) {
* @return the execution stack
*/
@NonNull
public List<IExpression> getExecutionStack() {
return CollectionUtil.unmodifiableList(new ArrayList<>(this.sharedState.executionStack));
public Deque<IExpression> getExecutionStack() {
return new ArrayDeque<>(this.sharedState.executionStack);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@

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

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

/**
* MPDY: Exceptions related to the Metapath dynamic context and dynamic
* evaluation.
*/
public class DynamicMetapathException
extends AbstractCodedMetapathException {
extends MetapathException {
@NonNull
private static final String PREFIX = "MPDY";

/**
* the serial version UID.
Expand All @@ -25,7 +30,7 @@ public class DynamicMetapathException
* context</a> that is
* <a href="https://www.w3.org/TR/xpath-datamodel-31/#dt-absent">absent</a>.
*/
public static final int DYNAMIC_CONTEXT_ABSENT = 2;
protected static final int DYNAMIC_CONTEXT_ABSENT = 2;

/**
* <a href= "https://www.w3.org/TR/xpath-31/#ERRXPDY0050">err:MPDY0050</a>: It
Expand All @@ -40,7 +45,7 @@ public class DynamicMetapathException
* "/" or "//" in a path expression is an abbreviation for an initial step that
* includes the clause <code>treat as document-node()</code>.
*/
public static final int TREAT_DOES_NOT_MATCH_TYPE = 50;
protected static final int TREAT_DOES_NOT_MATCH_TYPE = 50;

/**
* Constructs a new exception with the provided {@code code}, {@code message},
Expand All @@ -51,8 +56,10 @@ public class DynamicMetapathException
* @param message
* the exception message
*/
public DynamicMetapathException(int code, String message) {
super(code, message);
public DynamicMetapathException(
int code,
@Nullable String message) {
super(IErrorCode.of(PREFIX, code), message);
}

/**
Expand All @@ -66,8 +73,11 @@ public DynamicMetapathException(int code, String message) {
* @param cause
* the original exception cause
*/
public DynamicMetapathException(int code, String message, Throwable cause) {
super(code, message, cause);
public DynamicMetapathException(
int code,
@Nullable String message,
@Nullable Throwable cause) {
super(IErrorCode.of(PREFIX, code), message, cause);
}

/**
Expand All @@ -79,12 +89,9 @@ public DynamicMetapathException(int code, String message, Throwable cause) {
* @param cause
* the original exception cause
*/
public DynamicMetapathException(int code, Throwable cause) {
super(code, cause);
}

@Override
public String getCodePrefix() {
return "MPDY";
public DynamicMetapathException(
int code,
@Nullable Throwable cause) {
super(IErrorCode.of(PREFIX, code), cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

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

import gov.nist.secauto.metaschema.core.metapath.impl.ErrorCodeImpl;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

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

/**
* Provides an error code that identifies the type of message.
* <p>
* Implementations of this interface are expected to be immutable.
*/
public interface IErrorCode {
@SuppressWarnings("PMD.ShortMethodName")
@NonNull
static IErrorCode of(@NonNull String prefix, int code) {
return new ErrorCodeImpl(prefix, code);
}

/**
* Get the error code prefix, which indicates what type of error it is.
*
* @return the error code prefix
*/
@NonNull
String getPrefix();

/**
* Get the error code value.
*
* @return the error code value
*/
int getCode();

/**
* Get a combination of the error code family and value.
*
* @return the full error code.
*/
@NonNull
default String getCodeAsString() {
return ObjectUtils.notNull(String.format("%s%04d", getPrefix(), getCode()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface IExpression {
* @return the expression text
*/
@NonNull
String getText();
String getPath();

/**
* Retrieve the child expressions associated with this expression.
Expand Down
Loading
Loading