Skip to content

Commit

Permalink
#451: Fixed translation of FilterSets between DSMLv2 and JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
unixoid committed Aug 5, 2024
1 parent 04fae29 commit 5937efd
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
*/
package org.openehealth.ipf.commons.ihe.hpd.stub.json

import jakarta.xml.bind.JAXBElement
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.Filter
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.FilterSet
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.ObjectFactory

import javax.xml.bind.JAXBElement

/**
* @author Dmytro Rud
*/
Expand All @@ -31,7 +30,7 @@ class FilterIntermediaryUtils {
static final List<String> FILTER_TYPES = ['and', 'or', 'not', 'equalityMatch', 'substring', 'greaterOrEqual', 'lessOrEqual', 'present', 'approxMatch', 'extensibleMatch']

static FilterIntermediary fromDsml(String filterType, Object dsml) {
return Class.forName("${FilterIntermediaryUtils.packageName + '.' + filterType.capitalize()}").declaredMethods.find { it.name == 'fromDsml' }.invoke(null, dsml) as FilterIntermediary
return Class.forName(FilterIntermediaryUtils.packageName + '.' + filterType.capitalize()).declaredMethods.find { it.name == 'fromDsml' }.invoke(null, dsml) as FilterIntermediary
}

static FilterIntermediary fromFilter(Filter f) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.openehealth.ipf.commons.ihe.hpd.stub.json

import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import groovy.transform.CompileStatic
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.*

Expand All @@ -25,6 +27,8 @@ import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.*
class SearchRequestIntermediary {

String requestId
@JsonSerialize(using = ControlListSerializer.class)
@JsonDeserialize(using = ControlListDeserializer.class)
List<Control> controls
FilterIntermediary filter
List<String> attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
package org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.openehealth.ipf.commons.ihe.hpd.stub.json.ControlListDeserializer;
import org.openehealth.ipf.commons.ihe.hpd.stub.json.ControlListSerializer;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -67,6 +71,8 @@
@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
public class DsmlMessage {

@JsonSerialize(using = ControlListSerializer.class)
@JsonDeserialize(using = ControlListDeserializer.class)
protected List<Control> control;
@XmlAttribute(name = "requestID")
protected String requestID;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openehealth.ipf.commons.ihe.hpd.stub.json;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.NotImplementedException;
import org.openehealth.ipf.commons.ihe.hpd.controls.ControlUtils;
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortControl2;
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortResponseControl2;
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.Control;

import javax.naming.ldap.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* JSON deserializer for {@link List}&lt;{@link Control}&gt;.
*
* @author Dmytro Rud
*/
public class ControlListDeserializer extends JsonDeserializer<List> {

@Override
public List deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
JsonNode arrayNode = jsonParser.readValueAsTree();
if (!arrayNode.isArray()) {
throw new IllegalArgumentException("'controls' shall be a JSON array");
}
List<Control> result = new ArrayList<>();
Iterator<JsonNode> controlNodes = arrayNode.elements();
while (controlNodes.hasNext()) {
result.add(ControlUtils.toDsmlv2(deserializeControl(controlNodes.next())));
}
return result;
}

private static BasicControl deserializeControl(JsonNode node) throws IOException {
switch (node.get("type").textValue()) {
case PagedResultsControl.OID:
return new PagedResultsControl(node.get("size").intValue(), node.get("cookie").binaryValue(), node.get("critical").booleanValue());
case SortControl.OID:
ArrayList<SortKey> keys = new ArrayList<>();
JsonNode keysNode = node.get("keys");
Iterator<JsonNode> keyNodes = keysNode.elements();
while (keyNodes.hasNext()) {
JsonNode keyNode = keyNodes.next();
keys.add(new SortKey(keyNode.get("attrId").textValue(), keyNode.get("ascending").booleanValue(), keyNode.get("matchingRuleId").textValue()));
}
return new SortControl2(node.get("critical").asBoolean(), keys.toArray(new SortKey[0]));
case SortResponseControl.OID:
return new SortResponseControl2(node.get("resultCode").intValue(), node.get("failedAttrId").asText(), node.get("critical").booleanValue());
default:
throw new NotImplementedException("Cannot handle control type " + node.get("type").asText());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openehealth.ipf.commons.ihe.hpd.stub.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.commons.lang3.NotImplementedException;
import org.openehealth.ipf.commons.ihe.hpd.controls.ControlUtils;
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortControl2;
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortResponseControl2;
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.Control;

import javax.naming.ldap.*;
import java.io.IOException;
import java.util.List;

/**
* JSON serializer for {@link List}&lt;{@link Control}&gt;.
*
* @author Dmytro Rud
*/
public class ControlListSerializer extends StdSerializer<List> {

public ControlListSerializer() {
super(List.class);
}

@Override
public void serialize(List list, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartArray(list);
for (Object object : list) {
Control dsmlcontrol = (Control) object;
BasicControl control = ControlUtils.extractControl((byte[]) dsmlcontrol.getControlValue(), dsmlcontrol.getType(), dsmlcontrol.isCriticality());
gen.writeStartObject();
gen.writeStringField("type", control.getID());
gen.writeBooleanField("critical", control.isCritical());
switch (dsmlcontrol.getType()) {
case PagedResultsControl.OID:
PagedResultsResponseControl paginationControl = (PagedResultsResponseControl) control;
gen.writeNumberField("size", paginationControl.getResultSize());
if (paginationControl.getCookie() != null) {
gen.writeBinaryField("cookie", paginationControl.getCookie());
}
break;
case SortControl.OID:
SortControl2 sortControl = (SortControl2) control;
gen.writeArrayFieldStart("keys");
for (SortKey sortKey : sortControl.getKeys()) {
gen.writeStartObject();
gen.writeStringField("attrId", sortKey.getAttributeID());
gen.writeStringField("matchingRuleId", sortKey.getMatchingRuleID());
gen.writeBooleanField("ascending", sortKey.isAscending());
gen.writeEndObject();
}
gen.writeEndArray();
break;
case SortResponseControl.OID:
SortResponseControl2 sortResponseControl = (SortResponseControl2) control;
gen.writeNumberField("resultCode", sortResponseControl.getResultCode());
if (sortResponseControl.getFailedAttributeName() != null) {
gen.writeStringField("failedAttrId", sortResponseControl.getFailedAttributeName());
}
break;
default:
throw new NotImplementedException("Cannot handle control type " + dsmlcontrol.getType());
}
gen.writeEndObject();
}
gen.writeEndArray();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ import groovy.util.logging.Slf4j
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.openehealth.ipf.commons.ihe.hpd.HpdValidator
import org.openehealth.ipf.commons.ihe.hpd.controls.ControlUtils
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortControl2
import org.openehealth.ipf.commons.ihe.hpd.controls.sorting.SortResponseControl2
import org.openehealth.ipf.commons.ihe.hpd.stub.dsmlv2.*
import org.openehealth.ipf.commons.xml.XmlUtils

import jakarta.xml.bind.JAXBElement

import javax.naming.ldap.PagedResultsControl
import javax.naming.ldap.SortKey

@Slf4j
class JsonTest {

Expand All @@ -53,6 +59,14 @@ class JsonTest {
dn: 'ou=HPDElectronicService',
scope: SearchRequest.SearchScope.WHOLE_SUBTREE,
derefAliases: SearchRequest.DerefAliasesType.NEVER_DEREF_ALIASES,
control: [
ControlUtils.toDsmlv2(new SortControl2(true, [
new SortKey('attr1', true, 'alg1'),
new SortKey('attr2', false, 'alg2'),
] as SortKey[])),
ControlUtils.toDsmlv2(new SortResponseControl2(42, 'attr3', true)),
ControlUtils.toDsmlv2(new PagedResultsControl(100, 'cookie'.bytes, false)),
],
filter: new Filter(
equalityMatch: new AttributeValueAssertion(name: 'hcIdentifier', value: '1234567')
),
Expand Down

0 comments on commit 5937efd

Please sign in to comment.