Skip to content

Commit

Permalink
Merge pull request #3620 from IBM/issue-3619
Browse files Browse the repository at this point in the history
issue #3619 - populate 'path' field for SystemValueNodes in context tree
  • Loading branch information
lmsurpre authored May 9, 2022
2 parents 0a876d6 + 7663d0f commit 2f0fac9
Show file tree
Hide file tree
Showing 16 changed files with 532 additions and 159 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2019
* (C) Copyright IBM Corp. 2019, 2022
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -9,6 +9,12 @@
import static com.ibm.fhir.model.util.ModelSupport.delimit;
import static com.ibm.fhir.model.util.ModelSupport.isKeyword;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -128,26 +134,194 @@ public final void visitStart(java.lang.String elementName, int elementIndex, Res
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for non-visitable elements
* of type {@code http://hl7.org/fhirpath/System.String}.
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code byte[]}.
* Subclasses can override {@link #doVisit(String, byte[])} to provide specific visit behavior.
* @implNote Needed for FHIR.base64binary element values.
*/
@Override
public final void visit(java.lang.String elementName, byte[] value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code BigDecimal}.
* Subclasses can override {@link #doVisit(String, BigDecimal)} to provide specific visit behavior.
* @implNote Needed for FHIR.decimal element values.
*/
@Override
public final void visit(java.lang.String elementName, BigDecimal value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code Boolean}.
* Subclasses can override {@link #doVisit(String, Boolean)} to provide specific visit behavior.
* @implNote Needed for FHIR.decimal element values.
*/
@Override
public final void visit(java.lang.String elementName, java.lang.Boolean value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code Integer}.
* Subclasses can override {@link #doVisit(String, Integer)} to provide specific visit behavior.
* @implNote Needed for FHIR.integer, FHIR.unsignedInt, and FHIR.positiveInt element values.
*/
@Override
public final void visit(java.lang.String elementName, java.lang.Integer value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code LocalDate}.
* Subclasses can override {@link #doVisit(String, LocalDate)} to provide specific visit behavior.
* @implNote Needed for FHIR.date element values.
*/
@Override
public final void visit(java.lang.String elementName, LocalDate value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code LocalTime}.
* Subclasses can override {@link #doVisit(String, LocalTime)} to provide specific visit behavior.
* @implNote Needed for FHIR.time element values.
*/
@Override
public final void visit(java.lang.String elementName, LocalTime value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values and non-visitable elements of type {@code String}.
* Subclasses can override {@link #doVisit(String, String)} to provide specific visit behavior.
* @implNote Needed for FHIR elements like Resource.id, Element.id, and Extension.url which are system strings
* but also valid FHIRPath nodes.
* @implNote Needed for both
* 1. FHIR elements like Resource.id, Element.id, and Extension.url which are system strings; and
* 2. FHIR.string, FHIR.uri, FHIR.code, FHIR.oid, FHIR.id, FHIR.uuid, FHIR.sid, and FHIR.markdown element values.
*/
@Override
public final void visit(String elementName, String value) {
if (!"value".equals(elementName)) {
pathStackPush(elementName, -1);
}
public final void visit(java.lang.String elementName, java.lang.String value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
if (!"value".equals(elementName)) {
pathStackPop();
}
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code Year}.
* Subclasses can override {@link #doVisit(String, Year)} to provide specific visit behavior.
* @implNote Needed for FHIR.date and FHIR.dateTime element values with resolution to the year.
*/
@Override
public final void visit(java.lang.String elementName, Year value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code YearMonth}.
* Subclasses can override {@link #doVisit(String, YearMonth)} to provide specific visit behavior.
* @implNote Needed for FHIR.date and FHIR.dateTime element values with resolution to the month.
*/
@Override
public final void visit(java.lang.String elementName, YearMonth value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec PathAwareVisitor makes this method final to ensure that we always set the path for primitive
* values of type {@code ZonedDateTime}.
* Subclasses can override {@link #doVisit(String, ZonedDateTime)} to provide specific visit behavior.
* @implNote Needed for FHIR.dateTime and FHIR.instant element values.
*/
@Override
public final void visit(java.lang.String elementName, ZonedDateTime value) {
pathStackPush(elementName, -1);
doVisit(elementName, value);
pathStackPop();
}

/**
* @implSpec {@link #visit(String, byte[])} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for byte[] values.
*/
protected void doVisit(java.lang.String elementName, byte[] value) { }

/**
* @implSpec {@link #visit(String, BigDecimal)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for BigDecimal values.
*/
protected void doVisit(java.lang.String elementName, BigDecimal value) { }

/**
* @implSpec {@link #visit(String, Boolean)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for java.lang.Boolean values.
*/
protected void doVisit(java.lang.String elementName, Boolean value) { }

/**
* @implSpec {@link #visit(String, Integer)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for java.lang.Integer values.
*/
protected void doVisit(java.lang.String elementName, Integer value) { }

/**
* @implSpec {@link #visit(String, LocalDate)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for LocalDate values.
*/
protected void doVisit(java.lang.String elementName, LocalDate value) { }

/**
* @implSpec {@link #visit(String, LocalTime)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for LocalTime values.
*/
protected void doVisit(java.lang.String elementName, LocalTime value) { }

/**
* @implSpec {@link #visit(String, String)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for java.lang.String values.
*/
protected void doVisit(String elementName, String value) { }
protected void doVisit(java.lang.String elementName, String value) { }

/**
* @implSpec {@link #visit(String, Year)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for Year values.
*/
protected void doVisit(java.lang.String elementName, Year value) { }

/**
* @implSpec {@link #visit(String, YearMonth)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for YearMonth values.
*/
protected void doVisit(java.lang.String elementName, YearMonth value) { }

/**
* @implSpec {@link #visit(String, ZonedDateTime)} was made final (to avoid potential issues with the pathStack)
* and so this method was introduced to allow subclasses to implement visit behavior for ZonedDateTime values.
*/
protected void doVisit(java.lang.String elementName, ZonedDateTime value) { }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2019, 2021
* (C) Copyright IBM Corp. 2019, 2022
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -116,36 +116,36 @@ public boolean visit(java.lang.String elementName, int index, com.ibm.fhir.model
}

@Override
public void visit(java.lang.String elementName, byte[] value) {
public void doVisit(java.lang.String elementName, byte[] value) {
digest.update(getPath().getBytes(StandardCharsets.UTF_8));
digest.update(value);
}

@Override
public void visit(java.lang.String elementName, BigDecimal value) {
public void doVisit(java.lang.String elementName, BigDecimal value) {
updateDigest(getPath(), value.toString());
}

@Override
public void visit(java.lang.String elementName, java.lang.Boolean value) {
public void doVisit(java.lang.String elementName, java.lang.Boolean value) {
updateDigest(getPath(), value.toString());
}

@Override
public void visit(java.lang.String elementName, java.lang.Integer value) {
public void doVisit(java.lang.String elementName, java.lang.Integer value) {
ByteBuffer bb = ByteBuffer.allocate(4);
bb.putInt(value);
bb.flip();
digest.update(bb);
}

@Override
public void visit(java.lang.String elementName, LocalDate value) {
public void doVisit(java.lang.String elementName, LocalDate value) {
updateDigest(getPath(), value.toString());
}

@Override
public void visit(java.lang.String elementName, LocalTime value) {
public void doVisit(java.lang.String elementName, LocalTime value) {
updateDigest(getPath(), value.toString());
}

Expand All @@ -158,17 +158,17 @@ public void doVisit(java.lang.String elementName, java.lang.String value) {
}

@Override
public void visit(java.lang.String elementName, Year value) {
public void doVisit(java.lang.String elementName, Year value) {
updateDigest(getPath(), value.toString());
}

@Override
public void visit(java.lang.String elementName, YearMonth value) {
public void doVisit(java.lang.String elementName, YearMonth value) {
updateDigest(getPath(), value.toString());
}

@Override
public void visit(java.lang.String elementName, ZonedDateTime value) {
public void doVisit(java.lang.String elementName, ZonedDateTime value) {
updateDigest(getPath(), value.toString());
}

Expand Down
Loading

0 comments on commit 2f0fac9

Please sign in to comment.