Commit d99e19e9 authored by Tobias Wich's avatar Tobias Wich
Browse files

Merge branch 'java11'

parents 6e8048f3 4ff34aa3
[submodule "crypto/bouncycastle/src/bc"]
path = crypto/bouncycastle/src/bc
url = https://github.com/bcgit/bc-java.git
......@@ -4,16 +4,21 @@ Prerequisites
In order to build the Open eCard project, some additional tools are needed.
Required dependencies are:
* Java JDK 7 or higher
Oracle JDK and OpenJDK are working correctly
* Java JDK 11 or higher - Oracle JDK and OpenJDK are working correctly (jlink is required for building modular runtime images)
* Maven in at least version 3.6.1
* Maven in at least version 3.0.3 for JRE builds and 3.1.1 for Android builds
https://maven.apache.org/download.html
* Git 1.7.11 or higher (older versions are probably also ok)
http://git-scm.com/downloads
Optional dependencies are:
* Java JDK 14 with the new jpackage tool for creating native packages (early-access builds are available)
https://jdk.java.net/jpackage/)
* Android SDK
The Android SDK dependent modules are built when the environment variable
ANDROID_HOME is set and points to the installation directory of the Android
......@@ -30,27 +35,69 @@ Optional dependencies are:
https://developer.android.com/tools/sdk/ndk/index.html
Prior to starting the build, all Git submodules must be initialized with the
following command, which must be issued form the project root:
$ git submodule update --init
Git submodule updates may also be necessary after pulling changes from the
remote repository. The `git status` command indicates when this is needed.
Native packages can be created with an early-access build of JDK-14 which contains the new jpackage tool. For this purpose, JDK-14 must be managed independently of other JDK versions. This can be done with Maven toolchains. For this purpose, a `toolchains.xml` file is required on the building machine. The default location of this file is `~/.m2/toolchains.xml`. It should look similar to this one (JDK paths must be adjusted):
```xml
<?xml version="1.0" encoding="UTF8"?>
<toolchains>
<!-- JDK toolchains -->
<toolchain>
<type>jdk</type>
<provides>
<version>14</version>
<vendor>OpenJDK</vendor>
<id>JavaSE-14</id>
</provides>
<configuration>
<jdkHome>/usr/lib/jvm/jdk-14/</jdkHome>
</configuration>
</toolchain>
<toolchain>
<type>jdk</type>
<provides>
<version>11</version>
<vendor>OpenJDK</vendor>
<id>JavaSE-11</id>
</provides>
<configuration>
<jdkHome>/usr/lib/jvm/java-11-openjdk-amd64/</jdkHome>
</configuration>
</toolchain>
</toolchains>
```
If native packages are not created on the building machine, the first toolchain is not required.
Build Sources
=============
A standard build is performed by the command:
$ mvn clean install
$ mvn clean install
In order to create Javadoc and source artifacts, perform the following command:
$ mvn clean javadoc:javadoc javadoc:jar source:jar install
$ mvn clean javadoc:javadoc javadoc:jar source:jar install
By default, only a modular runtime image is created. However, if the early-access build of JDK-14 with the new jpackage tool is added to the toolchains, a native application package can be created by using the property `desktop-package`:
$ mvn clean install -Ddesktop-package
Usually, the predefined package formats are used: dmg for Mac OS, deb for Linux and msi and exe for Windows. An additional property `jlink-jpackager.package-type` can replace the predefined format of the native application package (only for Mac and Linux). The possible formats are:
- dmg
- pkg
- deb
- rpm
A native package with the `pkg` format can be created by using the following command:
$ mvn clean install -Ddesktop-package -Djlink-jpackager.package-type=pkg
The developer has to make sure that all necessary packaging tools are installed. In case of Windows, msi and exe packages are built. For this purpose, two additional tools are required:
- [WiX toolset](https://wixtoolset.org/) - to create msi installers
- [Inno Setup](http://www.jrsoftware.org/isinfo.php) - to create exe installers (Path environment variable must be set)
Build Profiles
--------------
......@@ -61,7 +108,7 @@ performed and which artifacts are created.
Maven profiles are selected on the commandline by adding the -P option as
follows:
$ mvn -Pprofile1,profile2 <Maven goals>
$ mvn -Pprofile1,profile2 <Maven goals>
The following global profiles are defined:
......
......@@ -25,7 +25,6 @@ The simplified build instructions are as follows:
$ git clone git://github.com/ecsec/open-ecard.git
$ cd open-ecard
$ git submodule update --init
$ mvn clean install
......@@ -36,6 +35,34 @@ as follows:
$ cd open-ecard-$version
$ mvn clean install
Finally, you can run the Open eCard App from command line:
$ ./packager/richclient-packager/target/open-ecard/bin/open-ecard
Packaging
-----------
Native packages which are based on a modular runtime image can be built with the new [jpackage](https://openjdk.java.net/jeps/343) tool which is a candidate for JDK-14. Early-access builds are already [provided](https://jdk.java.net/jpackage/). Native packages for the Open eCard can be built by downloading the JDK-14 early-access build, referencing it as toolchain and by specifying the following property:
$ mvn clean install -Ddesktop-package
By default, the packager will take the predefined package types, such as dmg for Mac OS and deb for Linux-based systems. The package type can be overridden for Mac and Linux packages by using the following user property:
$ mvn clean install -Ddesktop-package -Djlink-jpackager.package-type=<type>
Thereby, the following types are available:
- dmg
- pkg
- deb
- rpm
You have to make sure the required packaging tools are installed. In case of Windows, msi and exe packages are built. For this purpose, two additional tools are required:
- [WiX toolset](https://wixtoolset.org/) - to create msi installers
- [Inno Setup](http://www.jrsoftware.org/isinfo.php) - to create exe installers (Path environment variable must be set)
More information about the required JDK versions and the setup of the toolchain, can be found in the INSTALL.md file.
License
=======
......
......@@ -2,11 +2,12 @@
<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>org.openecard</groupId>
<artifactId>app</artifactId>
<version>1.4.0-rc.4-SNAPSHOT</version>
</parent>
<parent>
<groupId>org.openecard</groupId>
<artifactId>src-parent</artifactId>
<version>1.4.0-rc.4-SNAPSHOT</version>
<relativePath>../src-parent/</relativePath>
</parent>
<groupId>org.openecard</groupId>
<artifactId>addon</artifactId>
......
/****************************************************************************
* Copyright (C) 2013-2014 ecsec GmbH.
* Copyright (C) 2013-2019 ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
......@@ -22,17 +22,11 @@
package org.openecard.addon.bind;
import javax.annotation.Nonnull;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import javax.annotation.Nullable;
import javax.xml.bind.DatatypeConverter;
import javax.xml.transform.TransformerException;
import org.openecard.ws.marshal.MarshallingTypeException;
import org.openecard.ws.marshal.WSMarshaller;
import org.openecard.ws.marshal.WSMarshallerException;
import org.openecard.ws.marshal.WSMarshallerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
/**
......@@ -45,66 +39,31 @@ import org.w3c.dom.Node;
*/
public abstract class Body {
private static final Logger logger = LoggerFactory.getLogger(Body.class);
private static final Logger LOG = LoggerFactory.getLogger(Body.class);
private String value;
private byte[] value;
private Charset encoding;
private String mimeType;
private boolean base64Encoded;
private WSMarshaller m;
/**
* Creates a body without any content and the default marshaller.
*
* @throws WSMarshallerException Thrown in case the default marshaller could not be loaded.
*/
protected Body() throws WSMarshallerException {
this(loadEmptyMarshaller());
protected Body() {
this((byte[]) null, null, null);
}
/**
* Creates a body without any content and the given marshaller.
*
* @param m The marshaller which can be used by this instance to serialize and marshal XML. {@code null} values are
* permitted, but then each XML based function throws a {@link NullPointerException} when used.
*/
protected Body(@Nullable WSMarshaller m) {
this(null, null, false, m);
protected Body(String value, Charset encoding, String mimeType) {
this(value.getBytes(encoding), encoding, mimeType);
}
/**
* Creates a body with the given content and the default marshaller.
* The marshaller is not initialized with any classes for JAXB serialization to speed up the creation process.
* Creates a body with the given content.
*
* @param value Value to use as the bodies content, or {@code null} if the body should be empty.
* @param encoding Encoding of the value if applicable.
* @param mimeType MIME type of the value or, {@code null} if the value is {@code null}.
* @param base64Encoded Boolean indicating if the content is BASE64 encoded.
* @throws WSMarshallerException Thrown in case the default marshaller could not be loaded.
*/
protected Body(@Nullable String value, @Nullable String mimeType, boolean base64Encoded)
throws WSMarshallerException {
this(value, mimeType, base64Encoded, loadEmptyMarshaller());
}
/**
* Creates a body with the given content and the given marshaller.
*
* @param value Value to use as the bodies content, or {@code null} if the body should be empty.
* @param mimeType MIME type of the value or, {@code null} if the value is {@code null}.
* @param base64Encoded Boolean indicating if the content is BASE64 encoded.
* @param m The marshaller which can be used by this instance to serialize and marshal XML. {@code null} values are
* permitted, but then each XML based function throws a {@link NullPointerException} when used.
*/
protected Body(@Nullable String value, @Nullable String mimeType, boolean base64Encoded, @Nullable WSMarshaller m) {
protected Body(@Nullable byte[] value, @Nullable Charset encoding, @Nullable String mimeType) {
this.value = value;
this.encoding = encoding;
this.mimeType = mimeType;
this.base64Encoded = base64Encoded;
this.m = m;
}
private static WSMarshaller loadEmptyMarshaller() throws WSMarshallerException {
WSMarshaller m = WSMarshallerFactory.createInstance();
m.removeAllTypeClasses();
return m;
}
/**
......@@ -116,172 +75,126 @@ public abstract class Body {
return value != null;
}
public boolean hasStringValue() {
return value != null && encoding != null;
}
/**
* Gets the value of this body instance.
*
* @return The value, or {@code null} if no value is set.
*/
@Nullable
public String getValue() {
public byte[] getValue() {
return value;
}
/**
* Gets the MIME type of this body's value.
* Gets the value of the nbody as a string.
* This method only returns a value if this body is representable by a string.
*
* @return The MIME type, or {@code null} if no value and thus no MIME type is set.
* @return The value of the string if it is set, {@code null} otherwise.
*/
@Nullable
public String getMimeType() {
return mimeType;
public String getValueString() {
if (hasStringValue()) {
return new String(value, encoding);
} else {
return null;
}
}
/**
* Gets whether the value of this body instance is BASE64 encoded, or not.
*
* @return {@code true} if the body's value is BASE64 encoded, {@code false} otherwise.
* Gets the encoding of the
* @return
*/
public boolean isBase64() {
return base64Encoded;
@Nullable
public Charset getEncoding() {
return encoding;
}
/**
* Gets the marshaller managed by this instance.
* Gets the MIME type of this body's value.
*
* @return The marshaller used for this instance. {@code null} if no marshaller has been initialized.
* @return The MIME type, or {@code null} if no value and thus no MIME type is set.
*/
@Nullable
protected WSMarshaller getMarshaller() {
return m;
public String getMimeType() {
return mimeType;
}
/**
* Sets the value of the body.
* The MIME type and BASE64 encoding flag get corrected accordingly to the value. Note that no detection of the MIME
* type is performed.
*
* @param value The value to be set in the body. {@code null} values are permitted.
* @param encoding The encoding of the value, or {@code null} if not used.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
* @param base64Encoded {@code true} if the value is BASE64 encoded, false otherwise.
*/
public void setValue(@Nullable String value, @Nullable String mimeType, boolean base64Encoded) {
// use default for mime type if the value is omitted
public void setValue(@Nullable byte[] value, @Nullable Charset encoding, @Nullable String mimeType) {
if (value == null) {
mimeType = null;
} else if (mimeType == null || "".equals(mimeType)) {
logger.warn("No MIME type specified, falling back to 'text/plain'.");
mimeType = "text/plain";
}
// preemptively correct base64 if no value is supplied
if (value == null) {
base64Encoded = false;
encoding = null;
}
this.value = value;
this.encoding = encoding;
this.mimeType = mimeType;
this.base64Encoded = base64Encoded;
}
/**
* Sets the value of the body.
* A MIME type of {@code text/plain} is assumed.
*
* @param value The value to be set in the body. {@code null} values are permitted.
*/
public void setValue(@Nullable String value) {
setValue(value, "text/plain");
}
/**
* Sets the value of the body.
*
* @param value The value to be set in the body. {@code null} values are permitted.
* @param encoding The encoding of the value, or {@code null} if not used.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
*/
public void setValue(@Nullable String value, @Nullable String mimeType) {
setValue(value, mimeType, false);
}
/**
* Sets the value of the body.
* The given array gets BASE64 encoded before it is saved.
*
* @param value The value to be set in the body.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
* @throws NullPointerException Thrown in case the value or the marshaller is {@code null}.
*/
public void setValue(@Nonnull byte[] value, @Nullable String mimeType) {
public void setValue(@Nullable String value, @Nullable Charset encoding, @Nullable String mimeType) {
// use default for mime type if the value is omitted
if (value == null) {
throw new NullPointerException("The supplied value is null.");
mimeType = null;
encoding = null;
} else {
if (mimeType == null || "".equals(mimeType)) {
LOG.warn("No MIME type specified, falling back to 'text/plain'.");
mimeType = "text/plain";
}
if (encoding == null) {
LOG.warn("No encoding specified, using UTF-8.");
encoding = StandardCharsets.UTF_8;
}
}
String encVal = DatatypeConverter.printBase64Binary(value);
setValue(encVal, mimeType, true);
}
/**
* Sets the value of the body.
* The given DOM node is serialized with the marshaller of this instance. The MIME type is set to
* {@code application/xml}.
*
* @param domNode The value to be set in the body.
* @throws TransformerException Thrown in case the node could not be serialized.
* @throws NullPointerException Thrown in case the node or the marshaller is {@code null}.
*/
@SuppressWarnings("null")
public void setValue(@Nonnull Node domNode) throws TransformerException {
setValue(domNode, null);
setValue(value != null ? value.getBytes(encoding) : null, encoding, mimeType);
}
/**
* Sets the value of the body.
* The given DOM node is serialized with the marshaller of this instance.
* A MIME type of {@code text/plain} is assumed.
*
* @param domNode The value to be set in the body.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
* @throws TransformerException Thrown in case the node could not be serialized.
* @throws NullPointerException Thrown in case the node or the marshaller is {@code null}.
* @param value The value to be set in the body. {@code null} values are permitted.
*/
@SuppressWarnings("null")
public void setValue(@Nonnull Node domNode, @Nullable String mimeType) throws TransformerException {
String nodeVal = getMarshaller().doc2str(domNode);
if (mimeType == null || "".equals(mimeType)) {
setValue(nodeVal, "application/xml");
} else {
setValue(nodeVal, mimeType);
}
public void setValue(@Nullable String value) {
setValue(value, StandardCharsets.UTF_8, "text/plain");
}
/**
* Sets the value of the body.
* The given JAXB object is serialized with the marshaller of this instance. The MIME type is set to
* {@code application/xml} if no value is provided.
*
* @param jaxbObj The JAXB object to be set in the body.
* @throws MarshallingTypeException Thrown in case the object could not be marshalled.
* @throws TransformerException Thrown in case the node could not be serialized.
* @throws NullPointerException Thrown in case the JAXB element or the marshaller is {@code null}.
* @param value The value to be set in the body. {@code null} values are permitted.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
*/
@SuppressWarnings("null")
public void setJAXBObjectValue(@Nonnull Object jaxbObj) throws MarshallingTypeException, TransformerException {
setJAXBObjectValue(jaxbObj, null);
public void setValue(@Nullable String value, @Nullable String mimeType) {
setValue(value, StandardCharsets.UTF_8, mimeType);
}
/**
* Sets the value of the body.
* The given JAXB object is serialized with the marshaller of this instance. The MIME type is set to
* {@code application/xml}.
*
* @param jaxbObj The JAXB object to be set in the body.
* @param value The value to be set in the body.
* @param mimeType The MIME type of the value. {@code null} values are permitted.
* @throws MarshallingTypeException Thrown in case the object could not be marshalled.
* @throws TransformerException Thrown in case the node could not be serialized.
* @throws NullPointerException Thrown in case the JAXB element or the marshaller is {@code null}.
*/
@SuppressWarnings("null")
public void setJAXBObjectValue(@Nonnull Object jaxbObj, @Nullable String mimeType) throws MarshallingTypeException,
TransformerException {
Node nodeVal = getMarshaller().marshal(jaxbObj);
setValue(nodeVal, mimeType);
public void setValue(@Nullable byte[] value, @Nullable String mimeType) {
setValue(value, null, mimeType);
}
}
/****************************************************************************
* Copyright (C) 2014 ecsec GmbH.
* Copyright (C) 2014-2019 ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
......@@ -22,13 +22,12 @@
package org.openecard.addon.bind;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import org.openecard.common.util.StringUtils;
import org.openecard.ws.marshal.WSMarshaller;
import org.openecard.ws.marshal.WSMarshallerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -49,16 +48,11 @@ public class RequestBody extends Body {
*/
private final String path;
public RequestBody(String path) throws WSMarshallerException {
public RequestBody(String path) {
super();
this.path = path;
}
public RequestBody(String path, WSMarshaller m) {
super(m);
this.path = path;
}
/**
* Get the resource path of this request.
*
......@@ -69,23 +63,20 @@ public class RequestBody extends Body {
}
public Map<String, String> getFormParamValue() {
Charset utf8 = StandardCharsets.UTF_8;
Map<String, String> result = new HashMap<>();
String value = StringUtils.nullToEmpty(getValue()).trim();
String value = StringUtils.nullToEmpty(getValueString()).trim();
String[] entries = value.split("&");
for (String entry : entries) {
String[] split = entry.split("=");
try {
if (split.length == 1) {
String key = URLDecoder.decode(split[0], "UTF-8");
result.put(key, null);
} else if (split.length == 2) {
String key = URLDecoder.decode(split[0], "UTF-8");
String val = URLDecoder.decode(split[1], "UTF-8");
result.put(key, val);
}
} catch (UnsupportedEncodingException ex) {
LOG.error("Default encoding is not supported by this JVM.", ex);
if (split.length == 1) {
String key = URLDecoder.decode(split[0], utf8);
result.put(key, null);
} else if (split.length == 2) {
String key = URLDecoder.decode(split[0], utf8);
String val = URLDecoder.decode(split[1], utf8);
result.put(key, val);
}
}
......
/****************************************************************************
* Copyright (C) 2014 ecsec GmbH.
* Copyright (C) 2014-2019 ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
......@@ -22,8 +22,7 @@
package org.openecard.addon.bind;
import org.openecard.ws.marshal.WSMarshaller;
import org.openecard.ws.marshal.WSMarshallerException;
import java.nio.charset.Charset;
/**
......@@ -34,20 +33,12 @@ import org.openecard.ws.marshal.WSMarshallerException;
*/
public class ResponseBody extends Body {
public ResponseBody() throws WSMarshallerException {
public ResponseBody() {
super();
}
public ResponseBody(WSMarshaller m) {
super(m);
}
<