Skip to content

Commit

Permalink
Merge branch 'release/1.0.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
emersonf committed Apr 11, 2016
2 parents 72373e3 + 9b6ccb1 commit fcbf2b9
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A repository of Open mHealth [schemas](http://www.openmhealth.org/documentation/#/schema-docs/overview). This repository also includes sample test data, a validator for that data, and a Java schema SDK.

[![Build Status](https://travis-ci.org/openmhealth/schemas.svg?branch=master)](https://travis-ci.org/openmhealth/schemas)
[![Build Status](https://travis-ci.org/openmhealth/schemas.svg?branch=develop)](https://travis-ci.org/openmhealth/schemas)

## Schemas
The schemas are located in the [schema](schema) directory.
Expand Down
4 changes: 2 additions & 2 deletions java-schema-sdk/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015 Open mHealth
* Copyright 2016 Open mHealth
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,7 @@ apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray' // see https://github.com/bintray/gradle-bintray-plugin for details

archivesBaseName = 'omh-schema-sdk'
version = '1.0.5'
version = '1.0.6'

ext {
jacksonVersion = '2.6.3'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015 Open mHealth
* Copyright 2016 Open mHealth
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,7 +18,10 @@

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.google.common.base.Splitter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;

Expand All @@ -34,18 +37,41 @@
public interface AdditionalPropertySupport {

/**
* Sets an additional property.
* Sets an additional property. This method supports dot-separated paths by creating nested maps when necessary.
*
* @param name the name of the property to set
* @param path the path of the property to set
* @param value the value of the property to set
*/
@SuppressWarnings("unchecked")
@JsonAnySetter
default void setAdditionalProperty(String name, Object value) {
default void setAdditionalProperty(String path, Object value) {

checkNotNull(name, "A name hasn't been specified.");
checkArgument(!name.isEmpty(), "An empty name has been specified.");
checkNotNull(path, "A path hasn't been specified.");
checkArgument(!path.isEmpty(), "An empty path has been specified.");

Iterator<String> names = Splitter.on(".").omitEmptyStrings().split(path).iterator();
Map<String, Object> currentCollection = getAdditionalProperties();

while (names.hasNext()) {
String currentName = names.next();

// set the value, potentially overriding an existing value
if (!names.hasNext()) {
currentCollection.put(currentName, value);
break;
}

// traverse into a collection if one exists
if (currentCollection.get(currentName) instanceof Map) {
currentCollection = (Map<String, Object>) currentCollection.get(currentName);
continue;
}

getAdditionalProperties().put(name, value);
// create a new collection, potentially overriding an existing value
Map<String, Object> map = new HashMap<>();
currentCollection.put(currentName, map);
currentCollection = map;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2016 Open mHealth
*
* 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.openmhealth.schema.domain.omh;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import org.openmhealth.schema.serializer.SerializationConstructor;


/**
* A measure whose only declared property is a schema identifier, requiring JSON Schema additional properties for any
* remaining properties.
*
* @author Emerson Farrugia
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public class FreeFormMeasure extends Measure {

private SchemaId schemaId;

@SerializationConstructor
protected FreeFormMeasure() {
}

public static class Builder extends Measure.Builder<FreeFormMeasure, FreeFormMeasure.Builder> {

private SchemaId schemaId;

public Builder(String schemaNamespace, String schemaName, String schemaVersion) {
this.schemaId = new SchemaId(schemaNamespace, schemaName, schemaVersion);
}

@Override
public FreeFormMeasure build() {
return new FreeFormMeasure(this);
}
}

private FreeFormMeasure(FreeFormMeasure.Builder builder) {
super(builder);

schemaId = builder.schemaId;
}

@Override
public SchemaId getSchemaId() {
return this.schemaId;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015 Open mHealth
* Copyright 2016 Open mHealth
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,8 +37,10 @@
*/
public class SchemaId implements Comparable<SchemaId>, SchemaSupport {

public static final Pattern NAMESPACE_PATTERN = compile("[a-zA-Z0-9.-]+");
public static final Pattern NAME_PATTERN = compile("[a-zA-Z0-9-]+");
public static final String NAMESPACE_PATTERN_STRING = "[a-zA-Z0-9.-]+";
public static final Pattern NAMESPACE_PATTERN = compile(NAMESPACE_PATTERN_STRING);
public static final String NAME_PATTERN_STRING = "[a-zA-Z0-9-]+";
public static final Pattern NAME_PATTERN = compile(NAME_PATTERN_STRING);

public static final SchemaId SCHEMA_ID = new SchemaId(OMH_NAMESPACE, "schema-id", "1.0");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015 Open mHealth
* Copyright 2016 Open mHealth
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import java.util.Map;
import java.util.Optional;

import static org.hamcrest.CoreMatchers.equalTo;
Expand Down Expand Up @@ -77,22 +78,90 @@ public void setAdditionalPropertyShouldThrowExceptionOnEmptyName() {
unitValue.setAdditionalProperty("", "bar");
}

@Test
public void setAdditionalPropertyShouldCreateRootProperty() {

// before: {}
// after: { "foo" : 2 }
unitValue.setAdditionalProperty("foo", 2L);

assertThat(unitValue.getAdditionalProperty("foo"), equalTo(Optional.of(2L)));
}

@Test
public void setAdditionalPropertyShouldOverrideRootProperty() {

unitValue.setAdditionalProperty("foo", 2L);

// before: { "foo" : 2 }
// after: { "foo" : "bar" }
unitValue.setAdditionalProperty("foo", "bar");

assertThat(unitValue.getAdditionalProperty("foo"), equalTo(Optional.of("bar")));
}

@SuppressWarnings("unchecked")
@Test
public void setAdditionalPropertyShouldCreateNestedProperties() {

// before: { }
// after: { "foo" : { "bar" : 2 } }
unitValue.setAdditionalProperty("foo.bar", 2L);

// before: { "foo" : { "bar" : 2 } }
// after: { "foo" : { "bar" : 2, "cafe" : "ideal } }
unitValue.setAdditionalProperty("foo.cafe", "ideal");

Optional<Object> fooProperty = unitValue.getAdditionalProperty("foo");

assertThat(fooProperty, notNullValue());
assertThat(fooProperty.isPresent(), equalTo(true));

Map<String, Object> fooMap = (Map<String, Object>) fooProperty.get();

assertThat(fooMap.get("bar"), equalTo(2L));
assertThat(fooMap.get("cafe"), equalTo("ideal"));
}

@Test
public void setAdditionalPropertyShouldOverrideNestedProperty() {

unitValue.setAdditionalProperty("foo", 2L);

// before: { "foo" : 2 }
// after: { "foo" : { "cafe" : "ideal" } }
unitValue.setAdditionalProperty("foo.cafe", "ideal");

Optional<Object> fooProperty = unitValue.getAdditionalProperty("foo");

assertThat(fooProperty, notNullValue());
assertThat(fooProperty.isPresent(), equalTo(true));

Map<String, Object> fooMap = (Map<String, Object>) fooProperty.get();

assertThat(fooMap.get("cafe"), equalTo("ideal"));
}


@Test
public void getAdditionalPropertiesShouldNotReturnNull() {

assertThat(unitValue.getAdditionalProperties(), notNullValue());
}


@Test
public void additionalPropertiesShouldSerializeCorrectly() throws Exception {

unitValue.setAdditionalProperty("foo", "bar");
unitValue.setAdditionalProperty("baz.cafe", "ideal");

String document = "{\n" +
" \"value\": 3,\n" +
" \"unit\": \"cups\",\n" +
" \"foo\": \"bar\"" +
" \"foo\": \"bar\",\n" +
" \"baz\": {\n" +
" \"cafe\": \"ideal\"\n" +
" }\n" +
"}";

serializationShouldCreateValidDocument(unitValue, document);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright 2016 Open mHealth
*
* 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.openmhealth.schema.domain.omh;

import org.testng.annotations.Test;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;


/**
* @author Emerson Farrugia
*/
public class FreeFormMeasureUnitTests extends SerializationUnitTests {

@Test(expectedExceptions = NullPointerException.class)
public void constructorShouldThrowExceptionOnUndefinedSchemaNamespace() {

new FreeFormMeasure.Builder(null, "body-weight", "1.0");
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void constructorShouldThrowExceptionOnInvalidSchemaNamespace() {

new FreeFormMeasure.Builder("%", "body-weight", "1.0");
}

@Test(expectedExceptions = NullPointerException.class)
public void constructorShouldThrowExceptionOnUndefinedSchemaName() {

new FreeFormMeasure.Builder("omh", null, "1.0");
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void constructorShouldThrowExceptionOnInvalidSchemaName() {

new FreeFormMeasure.Builder("omh", "%", "1.0");
}

@Test(expectedExceptions = NullPointerException.class)
public void constructorShouldThrowExceptionOnUndefinedSchemaVersion() {

new FreeFormMeasure.Builder("omh", "body-weight", null);
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void constructorShouldThrowExceptionOnInvalidSchemaVersion() {

new FreeFormMeasure.Builder("omh", "body-weight", "%");
}

@Test
public void buildShouldConstructMeasureUsingOnlyRequiredProperties() {

FreeFormMeasure measure = new FreeFormMeasure.Builder("omh", "body-weight", "1.0").build();

assertThat(measure, notNullValue());
assertThat(measure.getSchemaId(), equalTo(BodyWeight.SCHEMA_ID));
assertThat(measure.getEffectiveTimeFrame(), nullValue());
assertThat(measure.getDescriptiveStatistic(), nullValue());
assertThat(measure.getUserNotes(), nullValue());
}

@Override
protected String getSchemaFilename() {

// the serialization tests will work with the body weight schema as a use case
return BodyWeightUnitTests.SCHEMA_FILENAME;
}

@Test
public void measureShouldSerializeCorrectly() throws Exception {

FreeFormMeasure measure = new FreeFormMeasure.Builder("omh", "body-weight", "1.0").build();

measure.setAdditionalProperty("body_weight.value", 50L);
measure.setAdditionalProperty("body_weight.unit", "kg");
measure.setAdditionalProperty("effective_time_frame.time_interval.start_date_time", "2015-10-01T00:00:00Z");
measure.setAdditionalProperty("effective_time_frame.time_interval.end_date_time", "2015-11-01T00:00:00Z");
measure.setAdditionalProperty("descriptive_statistic", "minimum");

String document = "{\n" +
" \"body_weight\": {\n" +
" \"value\": 50,\n" +
" \"unit\": \"kg\"\n" +
" },\n" +
" \"effective_time_frame\": {\n" +
" \"time_interval\": {\n" +
" \"start_date_time\": \"2015-10-01T00:00:00Z\",\n" +
" \"end_date_time\": \"2015-11-01T00:00:00Z\"\n" +
" }\n" +
" },\n" +
" \"descriptive_statistic\": \"minimum\"\n" +
"}";

serializationShouldCreateValidDocument(measure, document);
}
}

0 comments on commit fcbf2b9

Please sign in to comment.