Skip to content

Commit b83d36f

Browse files
Added support for the array:get Metapath function. Refactored array handling to ensure that array members are always items.
1 parent 1858857 commit b83d36f

30 files changed

+217
-195
lines changed

core/src/main/java/gov/nist/secauto/metaschema/core/datatype/DataTypeService.java

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ public final class DataTypeService {
5151
private static final Logger LOGGER = LogManager.getLogger(DataTypeService.class);
5252
private static final Lazy<DataTypeService> INSTANCE = Lazy.lazy(() -> new DataTypeService());
5353

54-
private Map<String, IDataTypeAdapter<?>> libraryByName;
55-
private Map<Class<? extends IDataTypeAdapter<?>>, IDataTypeAdapter<?>> libraryByClass;
54+
private final Map<String, IDataTypeAdapter<?>> libraryByName;
55+
private final Map<Class<? extends IDataTypeAdapter<?>>, IDataTypeAdapter<?>> libraryByClass;
5656

5757
/**
5858
* Get the singleton service instance, which will be lazy constructed on first
@@ -67,45 +67,7 @@ public static DataTypeService getInstance() {
6767
}
6868

6969
private DataTypeService() {
70-
load();
71-
}
72-
73-
/**
74-
* Lookup a specific {@link IDataTypeAdapter} instance by its name.
75-
*
76-
* @param name
77-
* the data type name of data type adapter to get the instance for
78-
* @return the instance or {@code null} if the instance is unknown to the type
79-
* system
80-
*/
81-
@Nullable
82-
public IDataTypeAdapter<?> getJavaTypeAdapterByName(@NonNull String name) {
83-
return libraryByName.get(name);
84-
}
8570

86-
/**
87-
* Lookup a specific {@link IDataTypeAdapter} instance by its class.
88-
*
89-
* @param clazz
90-
* the adapter class to get the instance for
91-
* @param <TYPE>
92-
* the type of the requested adapter
93-
* @return the instance or {@code null} if the instance is unknown to the type
94-
* system
95-
*/
96-
@SuppressWarnings("unchecked")
97-
@Nullable
98-
public <TYPE extends IDataTypeAdapter<?>> TYPE getJavaTypeAdapterByClass(@NonNull Class<TYPE> clazz) {
99-
return (TYPE) libraryByClass.get(clazz);
100-
}
101-
102-
/**
103-
* Load available data types registered with the {@link IDataTypeProvider} SPI.
104-
*
105-
* @throws IllegalStateException
106-
* if there are two adapters with the same name
107-
*/
108-
private void load() {
10971
ServiceLoader<IDataTypeProvider> loader = ServiceLoader.load(IDataTypeProvider.class);
11072
List<IDataTypeAdapter<?>> dataTypes = loader.stream()
11173
.map(Provider<IDataTypeProvider>::get)
@@ -142,10 +104,36 @@ private void load() {
142104
return v1;
143105
},
144106
ConcurrentHashMap::new));
107+
this.libraryByName = libraryByName;
108+
this.libraryByClass = libraryByClass;
109+
}
110+
111+
/**
112+
* Lookup a specific {@link IDataTypeAdapter} instance by its name.
113+
*
114+
* @param name
115+
* the data type name of data type adapter to get the instance for
116+
* @return the instance or {@code null} if the instance is unknown to the type
117+
* system
118+
*/
119+
@Nullable
120+
public IDataTypeAdapter<?> getJavaTypeAdapterByName(@NonNull String name) {
121+
return libraryByName.get(name);
122+
}
145123

146-
synchronized (this) {
147-
this.libraryByName = libraryByName;
148-
this.libraryByClass = libraryByClass;
149-
}
124+
/**
125+
* Lookup a specific {@link IDataTypeAdapter} instance by its class.
126+
*
127+
* @param clazz
128+
* the adapter class to get the instance for
129+
* @param <TYPE>
130+
* the type of the requested adapter
131+
* @return the instance or {@code null} if the instance is unknown to the type
132+
* system
133+
*/
134+
@SuppressWarnings("unchecked")
135+
@Nullable
136+
public <TYPE extends IDataTypeAdapter<?>> TYPE getJavaTypeAdapterByClass(@NonNull Class<TYPE> clazz) {
137+
return (TYPE) libraryByClass.get(clazz);
150138
}
151139
}

core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlEventWriter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import com.vladsch.flexmark.parser.ListOptions;
3030

31+
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.impl.AbstractMarkupWriter;
3132
import gov.nist.secauto.metaschema.core.util.CollectionUtil;
3233
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
3334

core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlStreamWriter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
import com.vladsch.flexmark.parser.ListOptions;
3030

31+
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.impl.AbstractMarkupWriter;
32+
3133
import java.util.Map;
3234

3335
import javax.xml.namespace.QName;

core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/AbstractMarkupWriter.java renamed to core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/impl/AbstractMarkupWriter.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
2525
*/
2626

27-
package gov.nist.secauto.metaschema.core.datatype.markup.flexmark; // NOPMD AST processor has many members
27+
package gov.nist.secauto.metaschema.core.datatype.markup.flexmark.impl; // NOPMD AST processor has many members
2828

2929
import com.vladsch.flexmark.ast.AutoLink;
3030
import com.vladsch.flexmark.ast.BlockQuote;
@@ -63,7 +63,9 @@
6363
import com.vladsch.flexmark.util.sequence.BasedSequence;
6464
import com.vladsch.flexmark.util.sequence.Escaping;
6565

66+
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.IMarkupWriter;
6667
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.HtmlQuoteTagExtension.DoubleQuoteNode;
68+
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.IMarkupWriter.ChildHandler;
6769
import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.InsertAnchorExtension.InsertAnchorNode;
6870
import gov.nist.secauto.metaschema.core.util.CollectionUtil;
6971
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
@@ -111,9 +113,11 @@ public abstract class AbstractMarkupWriter<T, E extends Throwable> // NOPMD not
111113
// normal cases
112114
// ENTITY_MAP.put("&amp;", "&");
113115
/*
114-
* ENTITY_MAP.put("&lsquo;", "‘"); ENTITY_MAP.put("&rsquo;", "’"); ENTITY_MAP.put("&hellip;", "…");
115-
* ENTITY_MAP.put("&mdash;", "—"); ENTITY_MAP.put("&ndash;", "–"); ENTITY_MAP.put("&ldquo;", "“");
116-
* ENTITY_MAP.put("&rdquo;", "”"); ENTITY_MAP.put("&laquo;", "«"); ENTITY_MAP.put("&raquo;", "»");
116+
* ENTITY_MAP.put("&lsquo;", "‘"); ENTITY_MAP.put("&rsquo;", "’");
117+
* ENTITY_MAP.put("&hellip;", "…"); ENTITY_MAP.put("&mdash;", "—");
118+
* ENTITY_MAP.put("&ndash;", "–"); ENTITY_MAP.put("&ldquo;", "“");
119+
* ENTITY_MAP.put("&rdquo;", "”"); ENTITY_MAP.put("&laquo;", "«");
120+
* ENTITY_MAP.put("&raquo;", "»");
117121
*/
118122
}
119123

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/ISequence.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import gov.nist.secauto.metaschema.core.metapath.impl.StreamSequence;
3333
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
3434
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
35-
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayMember;
3635
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
3736

3837
import java.util.ArrayList;
@@ -61,7 +60,7 @@
6160
* the Java type of the items in a sequence
6261
*/
6362
@SuppressWarnings("PMD.ShortMethodName")
64-
public interface ISequence<ITEM extends IItem> extends List<ITEM>, IArrayMember, IStringValued {
63+
public interface ISequence<ITEM extends IItem> extends List<ITEM>, IStringValued {
6564
/**
6665
* Get an empty sequence.
6766
*
@@ -207,7 +206,7 @@ public BinaryOperator<List<ITEM_TYPE>> combiner() {
207206

208207
@Override
209208
public Function<List<ITEM_TYPE>, ISequence<ITEM_TYPE>> finisher() {
210-
return list -> of(ObjectUtils.notNull(list));
209+
return list -> ofCollection(ObjectUtils.notNull(list));
211210
}
212211

213212
@Override
@@ -265,7 +264,7 @@ static <T extends IItem> ISequence<T> of( // NOPMD - intentional
265264
* @return the new sequence
266265
*/
267266
@NonNull
268-
static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> of( // NOPMD - intentional
267+
static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> ofCollection( // NOPMD - intentional
269268
@NonNull List<ITEM_TYPE> items) {
270269
ISequence<ITEM_TYPE> retval;
271270
if (items.isEmpty()) {

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/AbstractExpressionVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ public RESULT visitArray(ArraySequence expr, CONTEXT context) {
359359
}
360360

361361
@Override
362-
public RESULT visitArray(ArrayMembers expr, CONTEXT context) {
362+
public RESULT visitArray(ArraySquare expr, CONTEXT context) {
363363
return visitChildren(expr, context);
364364
}
365365
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/ArraySequence.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828

2929
import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
3030
import gov.nist.secauto.metaschema.core.metapath.ISequence;
31-
import gov.nist.secauto.metaschema.core.metapath.function.library.FnData;
3231
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
33-
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayMember;
3432

3533
import java.util.List;
3634

@@ -66,8 +64,7 @@ public List<? extends IExpression> getChildren() {
6664
public ISequence<IArrayItem<?>> accept(DynamicContext dynamicContext, ISequence<?> focus) {
6765
ISequence<IArrayItem<?>> retval;
6866
if (expr != null) {
69-
List<? extends IArrayMember> result = FnData.fnData(expr.accept(dynamicContext, focus));
70-
IArrayItem<?> array = IArrayItem.of(result);
67+
IArrayItem<?> array = IArrayItem.ofCollection(expr.accept(dynamicContext, focus));
7168
retval = ISequence.of(array);
7269
} else {
7370
retval = ISequence.of();

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/ArrayMembers.java renamed to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/ArraySquare.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,18 @@
2828

2929
import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
3030
import gov.nist.secauto.metaschema.core.metapath.ISequence;
31-
import gov.nist.secauto.metaschema.core.metapath.function.library.FnData;
3231
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
3332
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
34-
import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayMember;
3533

3634
import java.util.List;
3735

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

40-
public class ArrayMembers implements IExpression {
38+
public class ArraySquare implements IExpression {
4139
@NonNull
4240
private final List<IExpression> children;
4341

44-
public ArrayMembers(@NonNull List<IExpression> children) {
42+
public ArraySquare(@NonNull List<IExpression> children) {
4543
this.children = children;
4644
}
4745

@@ -53,19 +51,19 @@ public List<? extends IExpression> getChildren() {
5351
@Override
5452
public ISequence<? extends IItem> accept(DynamicContext dynamicContext, ISequence<?> focus) {
5553
return ISequence.of(getChildren().stream()
56-
.map(expr -> {
57-
ISequence<? extends IArrayMember> result = FnData.fnData(expr.accept(dynamicContext, focus));
54+
.map(expr -> expr.accept(dynamicContext, focus))
55+
.map(sequence -> {
5856

59-
IArrayMember retval;
60-
switch (result.size()) {
57+
IItem retval;
58+
switch (sequence.size()) {
6159
case 0:
62-
retval = ISequence.of();
60+
retval = IArrayItem.empty();
6361
break;
6462
case 1:
65-
retval = result.iterator().next();
63+
retval = sequence.iterator().next();
6664
break;
6765
default:
68-
retval = result;
66+
retval = IArrayItem.ofCollection(sequence);
6967
}
7068
return retval;
7169
})

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/BuildCSTVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ protected IExpression handleLet(LetexprContext context) {
268268
protected IExpression handleArrayConstructor(SquarearrayconstructorContext context) {
269269
if (context.getChildCount() == 2) {
270270
// empty
271-
return new ArrayMembers(CollectionUtil.emptyList());
271+
return new ArraySquare(CollectionUtil.emptyList());
272272
}
273273

274274
return nAiryToCollection(context, 1, 2,
@@ -279,7 +279,7 @@ protected IExpression handleArrayConstructor(SquarearrayconstructorContext conte
279279
},
280280
children -> {
281281
assert children != null;
282-
return new ArrayMembers(children);
282+
return new ArraySquare(children);
283283
});
284284
}
285285

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/CSTPrinter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ public String visitArray(ArraySequence expr, State context) {
342342
}
343343

344344
@Override
345-
public String visitArray(ArrayMembers expr, State context) {
345+
public String visitArray(ArraySquare expr, State context) {
346346
return appendNode(expr, super.visitArray(expr, context), context);
347347
}
348348
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/For.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,6 @@ public ISequence<? extends IItem> accept(DynamicContext dynamicContext, ISequenc
8282
subDynamicContext.bindVariableValue(variable.getName(), ISequence.of(item));
8383
retval.addAll(getReturnExpression().accept(subDynamicContext, focus));
8484
}
85-
return ISequence.of(retval);
85+
return ISequence.ofCollection(retval);
8686
}
8787
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/IExpressionVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,5 +531,5 @@ public interface IExpressionVisitor<RESULT, CONTEXT> {
531531
* the processing context
532532
* @return the visitation result or {@code null} if no result was produced
533533
*/
534-
RESULT visitArray(@NonNull ArrayMembers expr, @NonNull CONTEXT context);
534+
RESULT visitArray(@NonNull ArraySquare expr, @NonNull CONTEXT context);
535535
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/cst/Range.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public ISequence<IIntegerItem> accept(DynamicContext dynamicContext, ISequence<?
8484
range.add(IIntegerItem.valueOf(val));
8585
}
8686

87-
retval = ISequence.of(range);
87+
retval = ISequence.ofCollection(range);
8888
}
8989
return retval;
9090
}

core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionService.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public final class FunctionService {
4242
@NonNull
4343
private final ServiceLoader<IFunctionLibrary> loader;
4444
@NonNull
45-
private IFunctionLibrary library;
45+
private final IFunctionLibrary library;
4646

4747
/**
4848
* Get the singleton instance of the function service.
@@ -59,28 +59,14 @@ public static FunctionService getInstance() {
5959
@SuppressWarnings("null")
6060
public FunctionService() {
6161
this.loader = ServiceLoader.load(IFunctionLibrary.class);
62-
this.library = load();
63-
}
64-
65-
/**
66-
* Load all known functions registered with this function service.
67-
*
68-
* @return the function library
69-
*/
70-
@NonNull
71-
public IFunctionLibrary load() {
7262
ServiceLoader<IFunctionLibrary> loader = getLoader();
7363

7464
FunctionLibrary functionLibrary = new FunctionLibrary();
7565
loader.stream()
7666
.map(Provider<IFunctionLibrary>::get)
7767
.flatMap(IFunctionLibrary::getFunctionsAsStream)
7868
.forEachOrdered(function -> functionLibrary.registerFunction(ObjectUtils.notNull(function)));
79-
80-
synchronized (this) {
81-
this.library = functionLibrary;
82-
}
83-
return functionLibrary;
69+
this.library = functionLibrary;
8470
}
8571

8672
/**

0 commit comments

Comments
 (0)