Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
<java.version>17</java.version>
<camel.version>4.10.9</camel.version>
<entur.helpers.version>5.50.0</entur.helpers.version>
<netex-validator-java.version>11.0.31</netex-validator-java.version>
<netex-parser-java.version>3.1.78</netex-parser-java.version>
<netex-validator-java.version>12.0.0</netex-validator-java.version>
<netex-parser-java.version>4.0.0</netex-parser-java.version>
<netex-java-model.version>2.0.16</netex-java-model.version>
<jts-core.version>1.20.0</jts-core.version>
<commons-io.version>2.11.0</commons-io.version>
<zt-zip.version>1.17</zt-zip.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected void collectDataFromLineFile(
jaxbValidationContext
.datedServiceJourneys()
.forEach(dsj -> {
var serviceJourneyRef = dsj.getJourneyRef().get(0).getValue().getRef();
var serviceJourneyRef = dsj.getJourneyRef().getValue().getRef();
var operatingDayRef = dsj.getOperatingDayRef().getRef();
var serviceJourneyDates = serviceJourneyToDates.getOrDefault(
ServiceJourneyId.ofValidId(serviceJourneyRef),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package no.entur.antu.validation.validator.servicejourney.servicealteration.support;

import jakarta.xml.bind.JAXBElement;
import java.util.Collection;
import org.entur.netex.validation.validator.jaxb.JAXBValidationContext;
import org.rutebanken.netex.model.DatedServiceJourney;
import org.rutebanken.netex.model.DatedServiceJourneyRefStructure;

public class ServiceAlterationUtils {

Expand All @@ -17,11 +15,11 @@ public static Collection<DatedServiceJourney> datedServiceJourneysWithReferenceT
.datedServiceJourneys()
.stream()
.filter(dsj ->
dsj
.getJourneyRef()
.stream()
.map(JAXBElement::getValue)
.anyMatch(DatedServiceJourneyRefStructure.class::isInstance)
dsj.getReplacedJourneys() != null &&
!dsj
.getReplacedJourneys()
.getDatedVehicleJourneyRefOrNormalDatedVehicleJourneyRef()
.isEmpty()
)
.toList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import no.entur.antu.validation.validator.xpath.rules.ValidateAllowedCodespaces;
import no.entur.antu.validation.validator.xpath.rules.ValidateAuthorityRef;
import no.entur.antu.validation.validator.xpath.rules.ValidateNSRCodespace;
import org.entur.netex.validation.validator.Severity;
import org.entur.netex.validation.validator.xpath.rules.ValidateNotExist;
import org.entur.netex.validation.validator.xpath.tree.DefaultTimetableFrameValidationTreeFactory;
import org.entur.netex.validation.validator.xpath.tree.PublicationDeliveryValidationTreeFactory;
import org.entur.netex.validation.validator.xpath.tree.ValidationTreeBuilder;
Expand Down Expand Up @@ -54,6 +56,18 @@ public ValidationTreeBuilder builder() {
DefaultTimetableFrameValidationTreeFactory.CODE_DATED_SERVICE_JOURNEY_4
);

// Reject old DatedServiceJourneyRef format (pre NeTEx 1.16)
timetableFrameValidationTreeBuilder()
.withRuleForLineFile(
new ValidateNotExist(
"vehicleJourneys/DatedServiceJourney/DatedServiceJourneyRef",
"DEPRECATED_DATED_SERVICE_JOURNEY_REF",
"DatedServiceJourney uses deprecated DatedServiceJourneyRef",
"DatedServiceJourney uses deprecated DatedServiceJourneyRef element. Use replacedJourneys/DatedVehicleJourneyRef instead",
Severity.ERROR
)
);

// No boarding at last stop point in journey pattern
serviceFrameValidationTreeBuilder()
.withRuleForLineFile(new NoBoardingAtLastStopPoint());
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/configuration.antu.sweden.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ validationRuleConfigs:
name: SE/Authority URL
severity: WARNING

# Reduced severity for invalid service links
- code: SERVICE_LINK_3
name: SE/ServiceLink missing element Projections
severity: WARNING


Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;

Check warning on line 13 in src/test/java/no/entur/antu/netextestdata/NetexEntitiesTestFactory.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused import 'java.util.Collection'.

See more on https://sonarcloud.io/project/issues?id=entur_antu&issues=AZzD7P5EUVJKAWNuir1h&open=AZzD7P5EUVJKAWNuir1h&pullRequest=714
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -794,30 +794,32 @@

public DatedServiceJourney create() {
DatedServiceJourney datedServiceJourney = new DatedServiceJourney()
.withId(ref());

Collection<JAXBElement<? extends JourneyRefStructure>> journeyRefs =
new ArrayList<>();
journeyRefs.add(
createJaxbElement(
new ServiceJourneyRefStructure().withRef(serviceJourneyRef.ref())
)
);
if (datedServiceJourneyRef != null) {
journeyRefs.add(
.withId(ref())
.withJourneyRef(
createJaxbElement(
new DatedServiceJourneyRefStructure()
.withRef(datedServiceJourneyRef.ref())
new ServiceJourneyRefStructure().withRef(serviceJourneyRef.ref())
)
);
}

return datedServiceJourney
.withJourneyRef(journeyRefs)
)
.withOperatingDayRef(
new OperatingDayRefStructure().withRef(operatingDayRef.ref())
)
.withServiceAlteration(serviceAlteration);

if (datedServiceJourneyRef != null) {
ReplacedJourneys_RelStructure replacedDSJ =
new ReplacedJourneys_RelStructure();
replacedDSJ
.getDatedVehicleJourneyRefOrNormalDatedVehicleJourneyRef()
.add(
createJaxbElement(
new DatedVehicleJourneyRefStructure()
.withRef(datedServiceJourneyRef.ref())
)
);
datedServiceJourney.withReplacedJourneys(replacedDSJ);
}

return datedServiceJourney;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package no.entur.antu.validation.validator.servicejourney.servicealteration;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.saxon.s9api.XdmNode;
import no.entur.antu.config.ValidationParametersConfig;
import no.entur.antu.organisation.SimpleOrganisationAliasRepository;
import no.entur.antu.validation.validator.xpath.EnturTimetableDataValidationTreeFactory;
import org.entur.netex.validation.validator.ValidationIssue;
import org.entur.netex.validation.validator.xpath.XPathRuleValidationContext;
import org.entur.netex.validation.validator.xpath.XPathRuleValidator;
import org.entur.netex.validation.xml.NetexXMLParser;
import org.junit.jupiter.api.Test;

class DeprecatedDatedServiceJourneyRefTest {

private static final String RULE_CODE =
"DEPRECATED_DATED_SERVICE_JOURNEY_REF";
private static final String CODESPACE = "TST";
private static final NetexXMLParser NETEX_XML_PARSER = new NetexXMLParser(
Set.of("SiteFrame")
);

@Test
void testOldFormatWithDatedServiceJourneyRefShouldFail() {

Check warning on line 29 in src/test/java/no/entur/antu/validation/validator/servicejourney/servicealteration/DeprecatedDatedServiceJourneyRefTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace these 4 tests with a single Parameterized one.

See more on https://sonarcloud.io/project/issues?id=entur_antu&issues=AZ2MAkxcs-8mmxzdfFqg&open=AZ2MAkxcs-8mmxzdfFqg&pullRequest=714
String xml = publicationDelivery(
"""
<DatedServiceJourney version="1" id="TST:DatedServiceJourney:1">
<ServiceJourneyRef ref="TST:ServiceJourney:1" version="1"/>
<DatedServiceJourneyRef ref="TST:DatedServiceJourney:2"/>
<OperatingDayRef ref="TST:OperatingDay:1"/>
</DatedServiceJourney>
"""
);

List<ValidationIssue> issues = validate(xml);

assertThat(issues.size(), is(1));
}

@Test
void testOldFormatMultipleDatedServiceJourneyRefsShouldFail() {
String xml = publicationDelivery(
"""
<DatedServiceJourney version="1" id="TST:DatedServiceJourney:1">
<ServiceJourneyRef ref="TST:ServiceJourney:1" version="1"/>
<DatedServiceJourneyRef ref="TST:DatedServiceJourney:2"/>
<OperatingDayRef ref="TST:OperatingDay:1"/>
</DatedServiceJourney>
<DatedServiceJourney version="1" id="TST:DatedServiceJourney:3">
<ServiceJourneyRef ref="TST:ServiceJourney:2" version="1"/>
<DatedServiceJourneyRef ref="TST:DatedServiceJourney:4"/>
<OperatingDayRef ref="TST:OperatingDay:1"/>
</DatedServiceJourney>
"""
);

List<ValidationIssue> issues = validate(xml);

assertThat(issues.size(), is(2));
}

@Test
void testNewFormatWithReplacedJourneysShouldBeOk() {
String xml = publicationDelivery(
"""
<DatedServiceJourney version="1" id="TST:DatedServiceJourney:1">
<ServiceJourneyRef ref="TST:ServiceJourney:1" version="1"/>
<replacedJourneys>
<DatedVehicleJourneyRef ref="TST:DatedServiceJourney:2"/>
</replacedJourneys>
<OperatingDayRef ref="TST:OperatingDay:1"/>
</DatedServiceJourney>
"""
);

List<ValidationIssue> issues = validate(xml);

assertThat(issues.size(), is(0));
}

@Test
void testDatedServiceJourneyWithoutReplacementShouldBeOk() {
String xml = publicationDelivery(
"""
<DatedServiceJourney version="1" id="TST:DatedServiceJourney:1">
<ServiceJourneyRef ref="TST:ServiceJourney:1" version="1"/>
<OperatingDayRef ref="TST:OperatingDay:1"/>
</DatedServiceJourney>
"""
);

List<ValidationIssue> issues = validate(xml);

assertThat(issues.size(), is(0));
}

private List<ValidationIssue> validate(String xml) {
XdmNode document = NETEX_XML_PARSER.parseByteArrayToXdmNode(xml.getBytes());
XPathRuleValidationContext context = new XPathRuleValidationContext(
document,
NETEX_XML_PARSER,
CODESPACE,
"line.xml"
);
XPathRuleValidator validator = new XPathRuleValidator(
new EnturTimetableDataValidationTreeFactory(
new SimpleOrganisationAliasRepository(new HashSet<>()),
new ValidationParametersConfig()
)
);
return validator
.validate(context)
.stream()
.filter(issue -> RULE_CODE.equals(issue.rule().code()))
.toList();
}

private static String publicationDelivery(String datedServiceJourneys) {
return (
"""
<PublicationDelivery xmlns="http://www.netex.org.uk/netex" version="1">
<dataObjects>
<CompositeFrame id="TST:CompositeFrame:1" version="1">
<codespaces>
<Codespace id="tst">
<Xmlns>TST</Xmlns>
<XmlnsUrl>http://www.rutebanken.org/ns/tst</XmlnsUrl>
</Codespace>
</codespaces>
<frames>
<TimetableFrame id="TST:TimetableFrame:1" version="1">
<vehicleJourneys>
""" +
datedServiceJourneys +
"""
</vehicleJourneys>
</TimetableFrame>
</frames>
</CompositeFrame>
</dataObjects>
</PublicationDelivery>
"""
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.entur.netex.NetexParser;
import org.entur.netex.index.api.NetexEntitiesIndex;
import org.entur.netex.validation.validator.ValidationIssue;
Expand All @@ -21,34 +23,60 @@

private static final String TEST_CODESPACE = "NSB";
private static final String TEST_LINE_XML_FILE = "line.xml";
private static final String TEST_FILE_INVALID =
"servicealteration/NSB_L1.xml";
private static final String TEST_FILE_VALID = "servicealteration/VYG_41.xml";
private static final String TEST_FILE = "servicealteration/NSB_L1.xml";
private static final NetexParser NETEX_PARSER = new NetexParser();

@Test
void testMissingServiceAlterationOnReplacedDSJs() throws IOException {
List<ValidationIssue> issues = getValidationIssues(TEST_FILE_INVALID);
assertEquals(2, issues.size());
List<ValidationIssue> issues = getValidationIssues(
TEST_FILE,
"${SERVICE_ALTERATION}",
""
);
assertEquals(1, issues.size());
}

@Test
void testMismatchedServiceAlterationOnReplacedDSJs() throws IOException {
List<ValidationIssue> issues = getValidationIssues(
TEST_FILE,
"${SERVICE_ALTERATION}",
"<ServiceAlteration>cancellation</ServiceAlteration>"
);
assertEquals(1, issues.size());
}

@Test
void testCorrectServiceAlterationOnReplacedDSJs() throws IOException {
List<ValidationIssue> issues = getValidationIssues(TEST_FILE_VALID);
List<ValidationIssue> issues = getValidationIssues(
TEST_FILE,
"${SERVICE_ALTERATION}",
"<ServiceAlteration>replaced</ServiceAlteration>"
);
assertTrue(issues.isEmpty());
}

private List<ValidationIssue> getValidationIssues(String testFile)
throws IOException {
private List<ValidationIssue> getValidationIssues(
String testFile,
String placeholder,
String replacement
) throws IOException {
String validationReportId = "Test1122";

try (
InputStream testDatasetAsStream = getClass()
.getResourceAsStream('/' + testFile)
) {
assert testDatasetAsStream != null;

String netex = new String(
testDatasetAsStream.readAllBytes(),
StandardCharsets.UTF_8
)
.replace(placeholder, replacement);

NetexEntitiesIndex netexEntitiesIndex = NETEX_PARSER.parse(
testDatasetAsStream
IOUtils.toInputStream(netex)

Check warning on line 79 in src/test/java/no/entur/antu/validation/validator/servicejourney/servicealteration/InvalidServiceAlterationValidatorIntegrationTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this use of "toInputStream"; it is deprecated.

See more on https://sonarcloud.io/project/issues?id=entur_antu&issues=AZzD7P53UVJKAWNuir1i&open=AZzD7P53UVJKAWNuir1i&pullRequest=714
);

CommonDataRepository commonDataRepository = mock(
Expand Down
Loading