diff --git a/.gitignore b/.gitignore
index 33b19b91..60c91d68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
*.jar
*.war
*.ear
+.DS_Store
# Exception for gradle-wrapper
!tools/gradlew-simplejava/wrapper.jar
diff --git a/contributions/build.gradle b/contributions/build.gradle
index 648b7bf8..16fd0d34 100644
--- a/contributions/build.gradle
+++ b/contributions/build.gradle
@@ -8,7 +8,7 @@ subprojects {
apply plugin: 'eclipse'
// If we don't set this, Eclipse will get confused
- sourceCompatibility = '1.7'
+ sourceCompatibility = '10'
// Use the maven repository to fetch dependencies
repositories {
diff --git a/contributions/jaxbComposition/build.gradle b/contributions/jaxbComposition/build.gradle
index b7aa716f..5d53bf3c 100644
--- a/contributions/jaxbComposition/build.gradle
+++ b/contributions/jaxbComposition/build.gradle
@@ -6,7 +6,11 @@ version = '1.0.0'
// Implementation specifics
// This implementation uses JUnit for testing
+// Added JAXB Dependencies, which are deprecated in JDK9+
dependencies {
+ compile('javax.activation:activation:1.1')
+ compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.4.0-b180830.0359'
+ compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.4.0-b180830.0438'
testCompile group: 'junit', name: 'junit', version: '4.11+'
}
// Generate model classes with xjc
diff --git a/contributions/jaxbCompositionJava10/README.md b/contributions/jaxbCompositionJava10/README.md
new file mode 100644
index 00000000..988b6054
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/README.md
@@ -0,0 +1,102 @@
+== Headline ==
+
+[[Object-XML mapping]] with [[Technology:JAXB|]] and [Language:Java|]]8 [[Namespace:Feature]]s
+
+== Characteristics ==
+
+For the overall motivation of exercising [[Technology:JAXB]] see [[Contribution:jaxbComposition]]. This contribution is an overhaul of [[Contribution:jaxbComposition]] by applying new [[Namespace:Feature]]s introduced with [[Language:Java 8|]] such as [[Feature:Lambda Expressions]], [[Feature:Method references]] and [[Feature:Streams]]. The general idea behind this modernization is to update all necessary project dependencies, improve code readability and represent code in a more functional fashion by applying the aforementioned features.
+
+== Illustration ==
+
+[[Feature:Open serialization]] is implemented using [[Technology:JAXB]] Un-/Marshaller. Furthermore the code has been reduced by employing Method chaining:
+
+
+
+ public static Company deserializeCompany(File input)
+ throws JAXBException
+ {
+ initializeJaxbContext();
+ return (Company) jaxbContext.createUnmarshaller().unmarshal(input);
+ }
+
+
+
+
+public static void serializeCompany(File output, Company c)
+ throws JAXBException,
+ FileNotFoundException,
+ XMLStreamException
+ {
+ initializeJaxbContext();
+ XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(new FileOutputStream(output));
+ jaxbContext.createMarshaller().marshal(c, writer);
+ }
+
+[[Feature:Total]] features [[Feature:Streams]] as a way of processing elements and [[Feature:Cut]] relies on Optionals for dealing with possible null values:
+
+
+
+public static double total(Department department) {
+
+ double total = Optional.ofNullable(department.getManager()).map(Employee::getSalary).orElse(0.0);
+
+ total += department.getDepartment()
+ .stream()
+ .map(dep -> total(dep))
+ .reduce(0.0, Double::sum);
+
+ return total += department.getEmployee()
+ .stream()
+ .map(emp -> emp.getSalary())
+ .reduce(0.0, Double::sum);
+ }
+
+
+
+
+public static void cut(Company company) {
+ Optional.ofNullable(company)
+ .map(Company::getDepartment)
+ .ifPresent(depts -> depts.forEach(Cut::cut));
+ }
+
+Test cases are implemented for all [[Namespace:Feature]]s.
+
+== Relationships ==
+
+For Object/XML mapping see [[Contribution:jaxbChoice]] (XSD with choice for different subunits), [[Contribution:jaxbComposition]] (XSD with object composition), [[Contribution:jaxbExtension]] (XSD with type extension) and [[Contribution:jaxbSubstitution]] (XSD with substitution groups).
+
+== Architecture ==
+
+The contribution follows a standardized structure:
+* inputs contains input files for tests
+* src/main/java contains the following packages:
+** org.softlang.company.features for implementations of [[Functional requirements]].
+* src/test/java contains the following packages:
+** org.softlang.company.tests for [[Technology:JUnit]] test cases for [[Namespace:Feature]]s.
+
+== Usage ==
+
+This contribution uses [[Technology:Gradle]] for building. [[Technology:Eclipse]] is supported.
+
+See https://github.com/101companies/101simplejava/blob/master/README.md
+
+== Metadata ==
+
+* [[implements::Feature:Hierarchical company]]
+* [[implements::Feature:Mapping]]
+* [[implements::Feature:Open serialization]]
+* [[implements::Feature:Total]]
+* [[implements::Feature:Cut]]
+* [[memberOf::Theme:Java mapping]]
+* [[memberOf::Theme:XML programming]]
+* [[uses::Language:Java]]
+* [[uses::Language:XML]]
+* [[uses::Language:XSD]]
+* [[uses::Technology:JAXB]]
+* [[uses::Technology:xjc]]
+* [[uses::Technology:JUnit]]
+* [[uses::Technology:Gradle]]
+* [[uses::Concept:Lambdaware]]
+
+
diff --git a/contributions/jaxbCompositionJava10/build.gradle b/contributions/jaxbCompositionJava10/build.gradle
new file mode 100644
index 00000000..5d53bf3c
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+group = 'org.softlang.company'
+version = '1.0.0'
+
+// Implementation specifics
+// This implementation uses JUnit for testing
+// Added JAXB Dependencies, which are deprecated in JDK9+
+dependencies {
+ compile('javax.activation:activation:1.1')
+ compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.4.0-b180830.0359'
+ compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.4.0-b180830.0438'
+ testCompile group: 'junit', name: 'junit', version: '4.11+'
+}
+// Generate model classes with xjc
+task xjc(type: Exec) {
+ commandLine 'xjc'
+ args = ['inputs/Company.xsd', '-d', 'src/main/java', '-p' , 'org.softlang.company.xjc']
+ doFirst {
+ mkdir 'src/main/java/org/softlang/company/xjc'
+ }
+}
+// Execute xjc before compiling Java code
+compileJava {
+ dependsOn 'xjc'
+}
+// Additional cleanup for outputs and generated files
+clean {
+ dependsOn cleanEclipse
+ doFirst {
+ delete 'outputs'
+ delete 'src/main/java/org/softlang/company/xjc'
+ }
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/inputs/Company.xsd b/contributions/jaxbCompositionJava10/inputs/Company.xsd
new file mode 100644
index 00000000..16f3cfbf
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/inputs/Company.xsd
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contributions/jaxbCompositionJava10/inputs/sampleCompany.xml b/contributions/jaxbCompositionJava10/inputs/sampleCompany.xml
new file mode 100644
index 00000000..fd698c12
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/inputs/sampleCompany.xml
@@ -0,0 +1,55 @@
+
+
+ ACME Corporation
+
+
+ Research
+
+ Craig
+ Redmond
+ 123456
+
+
+ Erik
+ Utrecht
+ 12345
+
+
+ Ralf
+ Koblenz
+ 1234
+
+
+
+
+ Development
+
+ Ray
+ Redmond
+ 234567
+
+
+ Dev1
+
+ Klaus
+ Boston
+ 23456
+
+
+ Dev1.1
+
+ Karl
+ Riga
+ 2345
+
+
+ Joe
+ Wifi City
+ 2344
+
+
+
+
+
diff --git a/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Cut.java b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Cut.java
new file mode 100644
index 00000000..7833fd07
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Cut.java
@@ -0,0 +1,29 @@
+
+package org.softlang.company.features;
+
+import java.util.Optional;
+
+import org.softlang.company.xjc.*;
+
+public class Cut {
+
+ public static void cut(Company company) {
+ Optional.ofNullable(company)
+ .map(Company::getDepartment)
+ .ifPresent(depts -> depts.forEach(Cut::cut));
+ }
+
+ public static void cut(Department department) {
+ Optional.ofNullable(department.getManager())
+ .ifPresent(Cut::cut);
+ Optional.ofNullable(department.getDepartment())
+ .ifPresent(dep -> dep.forEach(Cut::cut));
+ Optional.ofNullable(department.getEmployee())
+ .ifPresent(employee -> employee.forEach(Cut::cut));
+ }
+
+ public static void cut(Employee employee) {
+ employee.setSalary(employee.getSalary() / 2);
+ }
+
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Serialization.java b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Serialization.java
new file mode 100644
index 00000000..f50a9f58
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Serialization.java
@@ -0,0 +1,44 @@
+package org.softlang.company.features;
+
+import org.softlang.company.xjc.Company;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+
+public class Serialization {
+
+ private static JAXBContext jaxbContext;
+
+ public static void initializeJaxbContext()
+ throws JAXBException
+ {
+ if (jaxbContext==null)
+ jaxbContext =
+ JAXBContext.newInstance("org.softlang.company.xjc");
+ }
+
+ public static Company deserializeCompany(File input)
+ throws JAXBException
+ {
+ initializeJaxbContext();
+ return (Company) jaxbContext.createUnmarshaller().unmarshal(input);
+ }
+
+ public static void serializeCompany(File output, Company c)
+ throws JAXBException,
+ FileNotFoundException,
+ XMLStreamException
+ {
+ initializeJaxbContext();
+ XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(new FileOutputStream(output));
+ jaxbContext.createMarshaller().marshal(c, writer);
+ }
+
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Total.java b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Total.java
new file mode 100644
index 00000000..f92e0ae9
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/main/java/org/softlang/company/features/Total.java
@@ -0,0 +1,32 @@
+
+package org.softlang.company.features;
+
+import java.util.Optional;
+
+import org.softlang.company.xjc.*;
+
+public class Total {
+
+ public static double total(Company company) {
+
+ return company.getDepartment()
+ .stream()
+ .map(depts -> total(depts))
+ .reduce(0.0, Double::sum);
+ }
+
+ public static double total(Department department) {
+
+ double total = Optional.ofNullable(department.getManager()).map(Employee::getSalary).orElse(0.0);
+
+ total += department.getDepartment()
+ .stream()
+ .map(dep -> total(dep))
+ .reduce(0.0, Double::sum);
+
+ return total += department.getEmployee()
+ .stream()
+ .map(emp -> emp.getSalary())
+ .reduce(0.0, Double::sum);
+ }
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/CutTest.java b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/CutTest.java
new file mode 100644
index 00000000..7b21cda6
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/CutTest.java
@@ -0,0 +1,45 @@
+package org.softlang.company.tests;
+
+import static org.softlang.company.features.Serialization.*;
+import org.softlang.company.features.Cut;
+import org.softlang.company.features.Total;
+import org.softlang.company.xjc.*;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.junit.Before;
+
+public class CutTest {
+
+ private static String sampleCompany = "inputs" + File.separator + "sampleCompany.xml";
+ private Company c;
+
+ @Before
+ public void initCompany() throws JAXBException {
+ c = deserializeCompany(new File(sampleCompany));
+ }
+
+ @Test
+ public void testCut()
+ throws
+ JAXBException,
+ FileNotFoundException,
+ XMLStreamException
+ {
+ new File("outputs").mkdir();
+ Cut.cut(c);
+ File tmp = new File("outputs" + File.separator + "cutCompany.tmp");
+ serializeCompany(tmp, c);
+ c = deserializeCompany(tmp);
+ Double total = Total.total(c);
+ assertEquals(399747 / 2.0d, total, 0);
+ tmp.delete();
+ }
+
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/SerializationTest.java b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/SerializationTest.java
new file mode 100644
index 00000000..ec947563
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/SerializationTest.java
@@ -0,0 +1,43 @@
+package org.softlang.company.tests;
+
+import org.softlang.company.xjc.*;
+import static org.softlang.company.features.Serialization.*;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import org.junit.Test;
+import org.junit.Before;
+
+public class SerializationTest {
+
+ private static String sampleCompany = "inputs" + File.separator + "sampleCompany.xml";
+ private Company c;
+
+ @Before
+ public void initCompany() throws JAXBException {
+ c = deserializeCompany(new File(sampleCompany));
+ }
+
+ @Test
+ public void testDeserialization() throws JAXBException {
+ deserializeCompany(new File(sampleCompany));
+ }
+
+ @Test
+ public void testSerialization()
+ throws
+ JAXBException,
+ FileNotFoundException,
+ XMLStreamException
+ {
+ new File("outputs").mkdir();
+ File out = new File("outputs" + File.separator + "sampleCompany.tmp");
+ serializeCompany(out, c);
+ c = deserializeCompany(out);
+ }
+
+}
\ No newline at end of file
diff --git a/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/TotalTest.java b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/TotalTest.java
new file mode 100644
index 00000000..1d3cd0e8
--- /dev/null
+++ b/contributions/jaxbCompositionJava10/src/test/java/org/softlang/company/tests/TotalTest.java
@@ -0,0 +1,38 @@
+package org.softlang.company.tests;
+
+import static org.softlang.company.features.Serialization.*;
+import org.softlang.company.features.Total;
+import org.softlang.company.xjc.*;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.stream.XMLStreamException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.junit.Before;
+
+public class TotalTest {
+
+ private static String sampleCompany = "inputs" + File.separator + "sampleCompany.xml";
+ private Company c;
+
+ @Before
+ public void initCompany() throws JAXBException {
+ c = deserializeCompany(new File(sampleCompany));
+ }
+
+ @Test
+ public void testTotal()
+ throws
+ JAXBException,
+ FileNotFoundException,
+ XMLStreamException
+ {
+ double total = Total.total(c);
+ assertEquals(399747, total, 0);
+ }
+
+}
\ No newline at end of file
diff --git a/contributions/settings.gradle b/contributions/settings.gradle
index b78bc2ee..f4d420e7 100644
--- a/contributions/settings.gradle
+++ b/contributions/settings.gradle
@@ -39,6 +39,7 @@ include 'javaTemplate'
include 'javaVisitor'
include 'jaxbChoice'
include 'jaxbComposition'
+include 'jaxbCompositionJava10'
include 'jaxbExtension'
include 'jaxbSubstitution'
include 'jdom'
diff --git a/tools/gradlew-simplejava/wrapper.properties b/tools/gradlew-simplejava/wrapper.properties
index 71e03452..faed7457 100644
--- a/tools/gradlew-simplejava/wrapper.properties
+++ b/tools/gradlew-simplejava/wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip