Skip to content

Commit

Permalink
Merge pull request #38 from OP-TED/release/1.9.0
Browse files Browse the repository at this point in the history
Prepare release of SDK Analyzer 1.9.0
  • Loading branch information
bertrand-lorentz authored Aug 24, 2023
2 parents cd19a9a + 3ca943e commit 6614cea
Show file tree
Hide file tree
Showing 50 changed files with 18,424 additions and 46 deletions.
13 changes: 0 additions & 13 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,6 @@ jobs:
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'adopt'
server-id: op-ted-github_mdd-entities
server-username: GH_USER
server-password: GH_PASSWORD
- name: Build
run: mvn --batch-mode clean install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_USER: ${{ secrets.GH_USER }}
GH_PASSWORD: ${{ secrets.GH_PASSWORD }}
- uses: actions/setup-java@v3
with:
java-version: '11'
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ Each check should have corresponding unit tests, with both valid and invalid tes

Those tests are defined using [Cucumber](https://cucumber.io/).

In order to run tests for only one Cucumber feature, you can filter based on the tag indicated at the top of the feature file:

```shell
mvn test -Dcucumber.filter.tags="@tedefo-2447"
```

Unit tests for other parts of the application can be defined as regular JUnit tests.

## Licence
Expand Down
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>eu.europa.ted.eforms</groupId>
<artifactId>eforms-sdk-analyzer</artifactId>
<version>1.8.0</version>
<version>1.9.0</version>
<packaging>kjar</packaging>

<name>eforms-sdk-analyzer</name>
Expand All @@ -29,14 +29,15 @@
<finalName>${project.artifactId}-${project.version}</finalName>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>2023-08-24T14:17:24Z</project.build.outputTimestamp>

<java.version>11</java.version>

<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

<version.eforms-core-java>1.0.5</version.eforms-core-java>
<version.efx-toolkit>1.2.0</version.efx-toolkit>
<version.efx-toolkit>2.0.0-alpha.1</version.efx-toolkit>

<!-- Version - Third-party libraries -->
<version.commons-collections4>4.4</version.commons-collections4>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* </p>
*/
@JsonPropertyOrder({"id", "parentNodeId", "name", "btId", "xpathAbsolute", "xpathRelative", "type",
"attributeName", "attributeOf", "attributes",
"presetValue", "idSchemes", "idScheme", "schemeName", "legalType", "maxLength", "privacy",
"repeatable", "forbidden", "mandatory", "pattern", "rangeNumeric", "codeList", "inChangeNotice",
"inContinueProcedure", "assert"})
Expand All @@ -41,6 +42,9 @@ public class Field implements Serializable {
private List<XmlElementPosition> xsdSequenceOrder;

private String type;
private String attributeOf;
private String attributeName;
private List<String> attributes;
private String presetValue;

private List<String> idSchemes;
Expand Down Expand Up @@ -119,6 +123,18 @@ public String getType() {
return type;
}

public String getAttributeOf() {
return attributeOf;
}

public String getAttributeName() {
return attributeName;
}

public List<String> getAttributes() {
return attributes;
}

public String getPresetValue() {
return presetValue;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
package eu.europa.ted.eforms.sdk.analysis.efx.mock;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import eu.europa.ted.efx.interfaces.MarkupGenerator;
import eu.europa.ted.efx.model.Expression;
import eu.europa.ted.efx.model.Expression.PathExpression;
import eu.europa.ted.efx.model.Expression.StringExpression;
import eu.europa.ted.efx.model.Markup;
import eu.europa.ted.efx.model.expressions.Expression;
import eu.europa.ted.efx.model.expressions.path.PathExpression;
import eu.europa.ted.efx.model.expressions.scalar.NumericExpression;
import eu.europa.ted.efx.model.expressions.scalar.StringExpression;
import eu.europa.ted.efx.model.templates.Markup;

public class MarkupGeneratorMock implements MarkupGenerator {
@Override
public Markup renderVariableExpression(Expression valueReference) {
return new Markup(String.format("eval(%s)", valueReference.script));
return new Markup(String.format("eval(%s)", valueReference.getScript()));
}

@Override
public Markup renderLabelFromKey(StringExpression key) {
return new Markup(String.format("label(%s)", key.script));
return new Markup(String.format("label(%s)", key.getScript()));
}

@Override
public Markup renderLabelFromExpression(Expression expression) {
return new Markup(String.format("label(%s)", expression.script));
return new Markup(String.format("label(%s)", expression.getScript()));
}

@Override
Expand All @@ -34,10 +34,6 @@ public Markup renderFreeText(String freeText) {
}

@Override
public Markup composeFragmentDefinition(String name, String number, Markup content) {
return this.composeFragmentDefinition(name, number, content, new LinkedHashSet<>());
}

public Markup composeFragmentDefinition(String name, String number, Markup content,
Set<String> parameters) {
if (StringUtils.isBlank(number)) {
Expand All @@ -49,13 +45,9 @@ public Markup composeFragmentDefinition(String name, String number, Markup conte
}

@Override
public Markup renderFragmentInvocation(String name, PathExpression context) {
return this.renderFragmentInvocation(name, context, new LinkedHashSet<>());
}

public Markup renderFragmentInvocation(String name, PathExpression context,
Set<Pair<String, String>> variables) {
return new Markup(String.format("for-each(%s).call(%s(%s))", context.script, name,
return new Markup(String.format("for-each(%s).call(%s(%s))", context.getScript(), name,
variables.stream()
.map(v -> String.format("%s:%s", v.getLeft(), v.getRight()))
.collect(Collectors.joining(", "))));
Expand All @@ -67,4 +59,25 @@ public Markup composeOutputFile(List<Markup> body, List<Markup> templates) {
templates.stream().map(t -> t.script).collect(Collectors.joining("\n")),
body.stream().map(t -> t.script).collect(Collectors.joining("\n"))));
}

@Override
public Markup renderLabelFromKey(StringExpression key, NumericExpression quantity) {
if (quantity.isEmpty()) {
return new Markup(String.format("label(%s)", key.getScript()));
}
return new Markup(String.format("label(%s, %s)", key.getScript(), quantity.getScript()));
}

@Override
public Markup renderLabelFromExpression(Expression expression, NumericExpression quantity) {
if (quantity.isEmpty()) {
return new Markup(String.format("label(%s)", expression.getScript()));
}
return new Markup(String.format("label(%s, %s)", expression.getScript(), quantity.getScript()));
}

@Override
public Markup renderLineBreak() {
return new Markup("<line-break>");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import eu.europa.ted.eforms.sdk.analysis.domain.field.XmlElementPosition;
import eu.europa.ted.eforms.sdk.analysis.domain.field.XmlStructureNode;
import eu.europa.ted.eforms.sdk.analysis.util.XPathSplitter;
import eu.europa.ted.eforms.sdk.analysis.util.XPathUtils;
import eu.europa.ted.eforms.sdk.analysis.util.XPathSplitter.StepInfo;

public class FieldFact implements SdkComponentFact<String> {
private static final long serialVersionUID = -8325643682910825716L;
Expand Down Expand Up @@ -125,11 +127,39 @@ public int getXpathRelativeStepCount() {
return stepCount;
}

public List<String> getInvalidXpathRelativeSteps() {
List<String> badSteps = XPathSplitter.getStepElementNames(getXpathRelative()).stream()
.filter(s -> XPathUtils.isAscendingStep(s))
.collect(Collectors.toList());

return badSteps;
}

public String getType() {
return field.getType();
}

/*
/**
* Return true if the last step of the relative path corresponds to an XML attribute.
*/
public boolean isAttribute() {
List<StepInfo> steps = XPathSplitter.getSteps(getXpathRelative());
return steps.get(steps.size() - 1).isAttribute();
}

public String getAttributeOf() {
return field.getAttributeOf();
}

public String getAttributeName() {
return field.getAttributeName();
}

public List<String> getAttributes() {
return field.getAttributes();
}

/**
* Return a stream of the dynamic properties of the field
*/
private Stream<AbstractFieldProperty<? extends AbstractConstraint<?>, ?>> getDynamicProperties() {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/eu/europa/ted/eforms/sdk/analysis/fact/NodeFact.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import eu.europa.ted.eforms.sdk.analysis.domain.field.XmlElementPosition;
import eu.europa.ted.eforms.sdk.analysis.domain.field.XmlStructureNode;
import eu.europa.ted.eforms.sdk.analysis.util.XPathSplitter;
import eu.europa.ted.eforms.sdk.analysis.util.XPathUtils;

public class NodeFact implements SdkComponentFact<String> {
private static final long serialVersionUID = -6237630016231337698L;
Expand Down Expand Up @@ -85,6 +87,14 @@ public int getXpathRelativeStepCount() {
return stepCount;
}

public List<String> getInvalidXpathRelativeSteps() {
List<String> badSteps = XPathSplitter.getStepElementNames(getXpathRelative()).stream()
.filter(s -> XPathUtils.isAscendingStep(s))
.collect(Collectors.toList());

return badSteps;
}

@Override
public String getId() {
return node.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
import eu.europa.ted.efx.xpath.XPath20BaseListener;
import eu.europa.ted.efx.xpath.XPath20Lexer;
import eu.europa.ted.efx.xpath.XPath20Parser;
import eu.europa.ted.efx.xpath.XPath20Parser.AxisstepContext;
import eu.europa.ted.efx.xpath.XPath20Parser.FilterexprContext;
import eu.europa.ted.efx.xpath.XPath20Parser.PredicateContext;
import eu.europa.ted.efx.xpath.XPath20Parser.StepexprContext;;

public class XPathSplitter extends XPath20BaseListener {

Expand Down Expand Up @@ -81,9 +82,44 @@ private Boolean inPredicateMode() {
}

@Override
public void exitStepexpr(StepexprContext ctx) {
if (!inPredicateMode()) {
this.steps.offer(new StepInfo(ctx, this::getInputText));
public void exitAxisstep(AxisstepContext ctx) {
if (inPredicateMode()) {
return;
}

// When we recognize a step, we add it to the queue if is is empty.
// If the queue is not empty, and the depth of the new step is not smaller than
// the depth of the last step in the queue, then this step needs to be added to
// the queue too.
// Otherwise, the last step in the queue is a sub-expression of the new step,
// and we need to
// replace it in the queue with the new step.
if (this.steps.isEmpty() || !this.steps.getLast().isPartOf(ctx.getSourceInterval())) {
this.steps.offer(new AxisStepInfo(ctx, this::getInputText));
} else {
Interval removedInterval = ctx.getSourceInterval();
while(!this.steps.isEmpty() && this.steps.getLast().isPartOf(removedInterval)) {
this.steps.removeLast();
}
this.steps.offer(new AxisStepInfo(ctx, this::getInputText));
}
}

@Override
public void exitFilterexpr(FilterexprContext ctx) {
if (inPredicateMode()) {
return;
}

// Same logic as for axis steps here (sse exitAxisstep).
if (this.steps.isEmpty() || !this.steps.getLast().isPartOf(ctx.getSourceInterval())) {
this.steps.offer(new FilterStepInfo(ctx, this::getInputText));
} else {
Interval removedInterval = ctx.getSourceInterval();
while(!this.steps.isEmpty() && this.steps.getLast().isPartOf(removedInterval)) {
this.steps.removeLast();
}
this.steps.offer(new FilterStepInfo(ctx, this::getInputText));
}
}

Expand All @@ -97,18 +133,28 @@ public void exitPredicate(PredicateContext ctx) {
this.predicateMode--;
}

public class AxisStepInfo extends StepInfo {

public AxisStepInfo(AxisstepContext ctx, Function<ParserRuleContext, String> getInputText) {
super(ctx.reversestep() != null? getInputText.apply(ctx.reversestep()) : getInputText.apply(ctx.forwardstep()),
ctx.predicatelist().predicate().stream().map(getInputText).collect(Collectors.toList()), ctx.getSourceInterval());
}
}

public class FilterStepInfo extends StepInfo {

public FilterStepInfo(FilterexprContext ctx, Function<ParserRuleContext, String> getInputText) {
super(getInputText.apply(ctx.primaryexpr()),
ctx.predicatelist().predicate().stream().map(getInputText).collect(Collectors.toList()), ctx.getSourceInterval());
}
}

public class StepInfo {
String stepText;
List<String> predicates;
int a;
int b;

public StepInfo(StepexprContext ctx, Function<ParserRuleContext, String> getInputText) {
this.stepText = getInputText.apply(ctx.step());
this.predicates =
ctx.predicatelist().predicate().stream().map(getInputText).collect(Collectors.toList());
}

protected StepInfo(String stepText, List<String> predicates, Interval interval) {
this.stepText = stepText;
this.predicates = predicates;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package eu.europa.ted.eforms.sdk.analysis.util;

import java.util.regex.Pattern;

public class XPathUtils {
private XPathUtils() {}

private static Pattern ascendingAxes =
Pattern.compile("^\\.\\.|(parent|ancestor|ancestor-or-self)::.*");

public static boolean isAscendingStep(String step) {
return ascendingAxes.matcher(step).matches();
}
}
Loading

0 comments on commit 6614cea

Please sign in to comment.