Skip to content

Commit

Permalink
Tag 0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
keilw committed Dec 13, 2019
1 parent 23599aa commit 16590d4
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 36 deletions.
3 changes: 3 additions & 0 deletions desktop/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.settings/
/.classpath
/.project
9 changes: 9 additions & 0 deletions desktop/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>tec.uom.client</groupId>
<artifactId>uom-clients</artifactId>
<version>0.4</version>
</parent>
<artifactId>uom-desktop</artifactId>
</project>
121 changes: 121 additions & 0 deletions desktop/src/main/java/tech/uom/client/desktop/EncodingUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Units of Measurement Reference Implementation
* Copyright (c) 2005-2019, Units of Measurement project.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package tech.uom.client.desktop;

import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;

import javax.measure.Quantity;

import tech.units.indriya.quantity.time.TemporalQuantity;
import tech.units.indriya.quantity.time.TimeUnitQuantity;

/**
* Provides support for JavaBeans XML serialization of {@link Quantity} instances.
* @see {@link java.beans.XMLEncoder}
* @author Andi Huber
* @since 2.0.2
*/
public class EncodingUtil {

public static void setupXMLEncoder(XMLEncoder encoder) {
encoder.setPersistenceDelegate(NumberQuantity.class, QUANTITY_PERSISTENCE_DELEGATE);
encoder.setPersistenceDelegate(TemporalQuantity.class, QUANTITY_PERSISTENCE_DELEGATE);
encoder.setPersistenceDelegate(TimeUnitQuantity.class, QUANTITY_PERSISTENCE_DELEGATE);
}

public static String base64Encode(Quantity<?> quantity) throws IOException {

byte[] buffer;

try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(quantity);
oos.close();
buffer = bos.toByteArray();
}

return Base64.getEncoder().encodeToString(buffer);
}

public static Quantity<?> base64Decode(String base64) throws IOException, ClassNotFoundException {

final byte[] buffer = Base64.getDecoder().decode(base64);

Quantity<?> q;

try(ByteArrayInputStream bis = new ByteArrayInputStream(buffer)) {
ObjectInputStream ois = new ObjectInputStream(bis);
q = (Quantity<?>) ois.readObject();
}

return q;
}


// -- HELPER

private final static PersistenceDelegateForQuantity QUANTITY_PERSISTENCE_DELEGATE =
new PersistenceDelegateForQuantity();

private static class PersistenceDelegateForQuantity extends PersistenceDelegate {

@Override
protected Expression instantiate(Object oldInstance, Encoder out) {

Quantity<?> quantity = (Quantity<?>) oldInstance;
String base64EncodedQuantity;

try {
base64EncodedQuantity = base64Encode(quantity);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}

return new Expression(
oldInstance,
EncodingUtil.class,
"base64Decode",
new Object[]{
base64EncodedQuantity
});
}
}


}
178 changes: 178 additions & 0 deletions desktop/src/test/java/tech/uom/client/desktop/EncodingUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Units of Measurement Reference Implementation
* Copyright (c) 2005-2019, Units of Measurement project.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package tech.uom.client.desktop;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.stream.Stream;

import javax.measure.Prefix;
import javax.measure.Quantity;
import javax.measure.Unit;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import tech.units.indriya.format.SamplingUtil;
import tech.units.indriya.unit.Units;

/**
* Testing serialization round-trips for all built-in Quantity types.
*/
class EncodingUtilTest {

private EncodingRoundtrip encodingRoundtrip;

@BeforeEach
void setup() {
encodingRoundtrip = new EncodingRoundtrip();
}

@Test
void encodeDecodeRoundtripWhenCompound() throws IOException {
@SuppressWarnings("unchecked")
Quantity<?> quantity = Quantities.getQuantity(
new Number[]{1, 2, 3},
new Unit[]{Units.DAY, Units.HOUR, Units.MINUTE});
encodingRoundtrip.test(quantity);
}


/**
* We cycle through all {Unit, Amount} combinations and test
* whether XML encoding/decoding are consistent.
* @throws IOException
*/
@ParameterizedTest(name = "{index} => unit=''{0}'', amount=''{1}'' ")
@DisplayName("XML serialization roundtrip spanning {Unit, Amount} should succeed")
@MethodSource("provideRoundtripArgs_unit_amount")
void encodeDecodeRoundtrip(Unit<?> unit, Number amount) throws IOException {
Quantity<?> quantity = Quantities.getQuantity(amount, unit);
encodingRoundtrip.test(quantity);
}

/**
* We cycle through all {Unit, Prefix} combinations and test
* whether XML encoding/decoding are consistent.
* @throws IOException
*/
@ParameterizedTest(name = "{index} => unit=''{0}'', prefix=''{1}'' ")
@DisplayName("XML serialization roundtrip spanning {Unit, Prefix} should succeed")
@MethodSource("provideRoundtripArgs_unit_prefix")
void encodeDecodeRoundtrip(Unit<?> unit, Prefix prefix) throws IOException {
Quantity<?> quantity = Quantities.getQuantity(1.2345, unit.prefix(prefix));
encodingRoundtrip.test(quantity);
}

// -- HELPER

private static Stream<Arguments> provideRoundtripArgs_unit_amount() {
// span a 2 dimensional finite space of {Unit, Amount}
return SamplingUtil.units()
.flatMap(unit->
SamplingUtil.numbers()
.map(amount->Arguments.of(unit, amount))
);

}

private static Stream<Arguments> provideRoundtripArgs_unit_prefix() {
// span a 2 dimensional finite space of {Unit, Prefix}
return SamplingUtil.units()
.flatMap(unit->
SamplingUtil.prefixes()
.map(prefix->Arguments.of(unit, prefix))
);

}


private static <Q extends Quantity<? extends Q>> void assertQuantityEquals(Q q1, Q q2) {
assertEquals(q1, q2);
}

private static class EncodingRoundtrip {

public <Q extends Quantity<? extends Q>> void test(final Q quantity) throws IOException {
assertQuantityEquals(quantity, run(quantity));
}

/**
* Writes given originalQuantity as serialized XML to in-memory buffer,
* then reconstructs the quantity from same buffer and returns it
* @throws IOException
*/
@SuppressWarnings("unchecked")
private <Q extends Quantity<? extends Q>> Q run(final Q originalQuantity) throws IOException {

byte[] buffer;

// write XML to buffer
try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
XMLEncoder encoder = new XMLEncoder(bos);
EncodingUtil.setupXMLEncoder(encoder);

encoder.writeObject(originalQuantity);
encoder.close();

buffer = bos.toByteArray();

}

// debug .. System.out.println(new String(buffer));

Q reconstructedQuantity;

// read XML from buffer
try(ByteArrayInputStream bis = new ByteArrayInputStream(buffer)) {
XMLDecoder decoder = new XMLDecoder(bis);

reconstructedQuantity = (Q) decoder.readObject();

decoder.close();
}

return reconstructedQuantity;

}


}

}
4 changes: 2 additions & 2 deletions fitbit/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
<parent>
<artifactId>uom-clients</artifactId>
<groupId>tec.uom.client</groupId>
<version>0.1-SNAPSHOT</version>
<version>0.4</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<version>0.4-SNAPSHOT</version>
<version>0.4</version>
<artifactId>uom-fitbit</artifactId>
<packaging>pom</packaging>
<inceptionYear>2014</inceptionYear>
Expand Down
2 changes: 1 addition & 1 deletion fitbit/uom-fitbit-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>tec.uom.client</groupId>
<artifactId>uom-fitbit</artifactId>
<version>0.4-SNAPSHOT</version>
<version>0.4</version>
</parent>
<artifactId>uom-fitbit-api</artifactId>
<name>Units of Measurement for Fitbit API</name>
Expand Down
2 changes: 1 addition & 1 deletion fitbit/uom-fitbit-cdi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>tec.uom.client</groupId>
<artifactId>uom-fitbit</artifactId>
<version>0.4-SNAPSHOT</version>
<version>0.4</version>
</parent>
<artifactId>uom-fitbit-cdi</artifactId>
<name>Units of Measurement for Fitbit CDI Implementation</name>
Expand Down
7 changes: 4 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

<parent>
<artifactId>uom-parent</artifactId>
<groupId>tec.uom</groupId>
<version>1.0</version>
<groupId>tech.uom</groupId>
<version>2.0</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>tec.uom.client</groupId>
<version>0.1-SNAPSHOT</version>
<version>0.4</version>
<artifactId>uom-clients</artifactId>
<packaging>pom</packaging>
<inceptionYear>2014</inceptionYear>
Expand Down Expand Up @@ -41,6 +41,7 @@
<module>runkeeper</module>
<module>strava</module>
<module>withings</module>
<!-- >module>desktop</module -->
</modules>
<name>Units of Measurement Clients</name>
<description>Units of Measurement Client Libraries</description>
Expand Down
2 changes: 1 addition & 1 deletion runkeeper/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<artifactId>uom-clients</artifactId>
<groupId>tec.uom.client</groupId>
<version>0.1-SNAPSHOT</version>
<version>0.4</version>
</parent>

<modelVersion>4.0.0</modelVersion>
Expand Down
2 changes: 1 addition & 1 deletion runkeeper/uom-runkeeper-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>tec.uom.client</groupId>
<artifactId>uom-runkeeper</artifactId>
<version>0.1-SNAPSHOT</version>
<version>0.4</version>
</parent>
<artifactId>uom-runkeeper-api</artifactId>
<name>Units of Measurement for RunKeeper API</name>
Expand Down
2 changes: 1 addition & 1 deletion runkeeper/uom-runkeeper-cdi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>tec.uom.client</groupId>
<artifactId>uom-runkeeper</artifactId>
<version>0.1-SNAPSHOT</version>
<version>0.4</version>
</parent>
<artifactId>uom-runkeeper-cdi</artifactId>
<name>Units of Measurement for RunKeeper CDI Implementation</name>
Expand Down
Loading

0 comments on commit 16590d4

Please sign in to comment.