Bug #464207 - Created examples/moxy/json-processing example that uses JsonReader/JsonWriter and JsonParser/JsonGenerator to convert between a JSON representation and a Java class instance

Signed-off-by: John Clingan <john.clingan@oracle.com>
Reviewed-by: Martin Vojtek <martin.vojtek@oracle.com>
diff --git a/moxy/json-processing/.gitignore b/moxy/json-processing/.gitignore
new file mode 100644
index 0000000..430b1ae
--- /dev/null
+++ b/moxy/json-processing/.gitignore
@@ -0,0 +1,3 @@
+.classpath
+.project
+.settings
diff --git a/moxy/json-processing/README.md b/moxy/json-processing/README.md
new file mode 100644
index 0000000..3c202aa
--- /dev/null
+++ b/moxy/json-processing/README.md
@@ -0,0 +1,14 @@
+# EclipseLink MOXy JSON Processing (JSR 353) Example
+
+This example will demonstrate how to use the Json Processing API (JSR 353) using EclipseLink. The example consists of:
+
+- Use the JSON Writer API to write the customer from a file in JSON format
+- Use the JSON Reader API to read the JSON representation of a customer from a file
+- Use the JSON Generator API to write a Customer to a file in JSON format
+- Use the JSON Parser API to read the JSON representation of a customer from a file
+
+ Simply run 'mvn'. The default goal is 'install'
+
+Two files will be created:
+- Created by JsonWriter:    target/customer.generator.json
+- Created by JsonGenerator: target/customer.writer.json
diff --git a/moxy/json-processing/pom.xml b/moxy/json-processing/pom.xml
new file mode 100644
index 0000000..4005a89
--- /dev/null
+++ b/moxy/json-processing/pom.xml
@@ -0,0 +1,106 @@
+<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>
+	<groupId>eclipselink.example.moxy</groupId>
+	<artifactId>json-processing</artifactId>
+	<version>2.6.0</version>
+
+	<name>EclipseLink MOXy JSON Processing Example</name>
+	<url>http://wiki.eclipse.org/EclipseLink/Examples/MOXy</url>
+
+	<scm>
+		<connection>git://git.eclipse.org/gitroot/eclipselink/examples.git</connection>
+		<url>http://git.eclipse.org/c/eclipselink/examples.git/</url>
+	</scm>
+
+	<licenses>
+		<license>
+			<name>EPL: Eclipse Public License</name>
+			<url>http://www.eclipse.org/legal/epl-v10.html</url>
+		</license>
+		<license>
+			<name>EDL: Eclipse Distribution License</name>
+			<url>http://www.eclipse.org/org/documents/edl-v10.php</url>
+		</license>
+	</licenses>
+
+	<developers>
+		<developer>
+			<name>John Clingan</name>
+			<organization>Oracle</organization>
+			<email>john.oracle@oracle.com</email>
+		</developer>
+	</developers>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<eclipselink.groupid>org.eclipse.persistence</eclipselink.groupid>
+		<eclipselink.artifactid>eclipselink</eclipselink.artifactid>
+		<eclipselink.version>2.6.0</eclipselink.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>${eclipselink.groupid}</groupId>
+			<artifactId>${eclipselink.artifactid}</artifactId>
+			<version>${eclipselink.version}</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>commonj.sdo</artifactId>
+					<groupId>commonj.sdo</groupId>
+				</exclusion>
+			</exclusions>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>javax</groupId>
+			<artifactId>javaee-api</artifactId>
+			<version>7.0</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<defaultGoal>install</defaultGoal>
+
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>exec-maven-plugin</artifactId>
+				<version>1.3.2</version>
+				<executions>
+					<execution>
+						<phase>install</phase>
+						<goals>
+							<goal>java</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<classpathScope>test</classpathScope>
+					<mainClass>eclipselink.example.moxy.json.jsonprocessing.Main</mainClass>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.2</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+
+		</plugins>
+	</build>
+
+</project>
diff --git a/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/Main.java b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/Main.java
new file mode 100644
index 0000000..ac581df
--- /dev/null
+++ b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/Main.java
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+
+package eclipselink.example.moxy.json.jsonprocessing;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonReader;
+import javax.json.JsonWriter;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonParser;
+
+import eclipselink.example.moxy.json.jsonprocessing.model.Customer;
+import eclipselink.example.moxy.json.jsonprocessing.model.PhoneNumber;
+
+/**
+ * This example executes the following basic steps:
+ *
+ * 1) Create a Customer instance that embeds a list of Phone Numbers
+ *
+ * 2) Use the JSON Writer API to write the customer from a file in JSON format
+ *
+ * 3) Use the JSON Reader API to read the JSON representation of a customer from
+ * a file
+ *
+ * 4) Use the JSON Generator API to write a Customer to a file in JSON format
+ *
+ * 5) Use the JSON Parser API to read the JSON representation of a customer
+ * from a file
+ *
+ * @author johnclingan
+ * @since EclipseLink 2.6.0
+ */
+
+public class Main {
+	public static final String FILENAME_WRITER = "target" + File.separator
+			+ "customer.writer.json";
+
+	public static final String FILENAME_GENERATOR = "target"
+			+ File.separator + "customer.generator.json";
+
+	public static void main(String[] args) throws Exception {
+
+		System.out.println();
+		System.out.println("Running EclipseLink MOXy JSON Processing Example");
+
+		// Step 1 - Create a customer
+		Customer customer = createCustomer();
+
+		// Step 2 - Write Customer to a file in JSON format using JsonWriter
+		try (JsonWriter writer = Json.createWriter(new FileOutputStream(
+				FILENAME_WRITER))) {
+			JsonObject jsonCustomer = createCustomerJsonObject(customer);
+			writer.writeObject(jsonCustomer);
+			System.out.println();
+			System.out.println("Customer instance written to " + FILENAME_WRITER
+					+ " using JsonWriter");
+		}
+
+		// Step 3 - Read JSON representation of a customer from a file using
+		// JsonReader and create a customer instance
+		try (JsonReader reader = Json.createReader(new FileInputStream(
+				FILENAME_WRITER))) {
+			JsonObject jsonObject = reader.readObject();
+			Customer customer2 = createCustomerFromJsonObject(jsonObject);
+			System.out.println();
+			System.out.println("Customer read from "
+			     + FILENAME_WRITER + " using JsonReader:");
+			System.out.println(customer2);
+		}
+
+		// Step 4 - Write a Customer to a file using the JsonGenerator API
+		try (JsonGenerator generator = Json
+				.createGenerator(new FileOutputStream(FILENAME_GENERATOR))) {
+			generateCustomer(customer, generator);
+			System.out.println();
+			System.out.println("Customer instance written to " + FILENAME_GENERATOR
+					+ " using JsonGenerator");
+		}
+
+		// Step 5 - Read JSON representation of customer from a file
+		// using JsonParser
+		Customer parsedCustomer = parseJsonCustomer(FILENAME_GENERATOR);
+		System.out.println();
+		System.out.println("Customer read from "
+		         + FILENAME_GENERATOR + " using JsonParser:");
+		System.out.println(parsedCustomer);
+
+		System.out.println();
+		System.out.println();
+	}
+
+	/********************************************
+	 * Create an instance of a customer
+	 ********************************************/
+
+	private static Customer createCustomer() {
+		PhoneNumber p1 = new PhoneNumber("555-1111", "Mobile");
+		PhoneNumber p2 = new PhoneNumber("555-2222", "Home");
+
+		return new Customer(1, "John", "Doe", Arrays.asList(p1, p2));
+	}
+
+	/********************************************
+	 * Creates a JsonObject from Customer instance
+	 ********************************************/
+
+	private static JsonObject createCustomerJsonObject(Customer customer) {
+
+		JsonArrayBuilder phoneArrayBuilder = Json.createArrayBuilder();
+
+		for (PhoneNumber p : customer.getPhoneNumbers()) {
+			JsonObjectBuilder phoneBuilder = Json.createObjectBuilder();
+			phoneBuilder.add("number", p.getNumber()).add("type", p.getType());
+			phoneArrayBuilder.add(phoneBuilder);
+		}
+
+		JsonObjectBuilder builder = Json.createObjectBuilder();
+		builder.add("id", customer.getId())
+				.add("firstName", customer.getFirstName())
+				.add("lastName", customer.getLastName())
+				.add("phoneNumbers", phoneArrayBuilder);
+
+		return builder.build();
+	}
+
+	/*****************************************************
+	 * Create an instance of a customer from a jsonObject
+	 *****************************************************/
+
+	private static Customer createCustomerFromJsonObject(JsonObject jsonObject) {
+		Customer customer = new Customer();
+
+		customer.setId(jsonObject.getInt("id"));
+		customer.setFirstName(jsonObject.getString("firstName"));
+		customer.setLastName(jsonObject.getString("lastName"));
+
+		JsonArray jsonPhoneArray = jsonObject.getJsonArray("phoneNumbers");
+
+		for (JsonObject jsonPhone : jsonPhoneArray
+				.getValuesAs(JsonObject.class)) {
+			PhoneNumber phoneNumber = new PhoneNumber();
+
+			phoneNumber.setNumber(jsonPhone.getString("number"));
+			phoneNumber.setType(jsonPhone.getString("type"));
+
+			customer.getPhoneNumbers().add(phoneNumber);
+		}
+
+		return customer;
+	}
+
+	/*************************************************************************
+	 * Read a JSON-formatted customer into a Customer instance using the JSON
+	 * parsing API. Parsing JSON takes more work (more code), but has two
+	 * distinct advantages:
+	 *
+	 * 1) A potentially very large JsonObject does not have to be stored in
+	 * memory
+	 *
+	 * 2) If only a subset of data is needed, parsing can immediately
+	 * return
+	 *
+	 *************************************************************************/
+
+	private static Customer parseJsonCustomer(String filename) {
+		Customer customer = new Customer();
+		String key = ""; // They key of the JSON key/value pair
+		PhoneNumber phoneNumber = new PhoneNumber();
+		boolean inPhoneNumberArray = false;
+
+		try (JsonParser parser = Json
+				.createParser(new FileInputStream(filename))) {
+
+			while (parser.hasNext()) {
+				switch (parser.next()) {
+				case KEY_NAME:
+					key = parser.getString();
+					break;
+
+				case VALUE_NUMBER:
+					// There is only one "number" in customer - id - so just
+					// assume it is the id
+					customer.setId(parser.getInt());
+					break;
+
+				case VALUE_STRING:
+					// Get the "value" of the key/value pair
+					String value = parser.getString();
+
+					switch (key) {
+					case "firstName":
+						customer.setFirstName(value);
+						break;
+					case "lastName":
+						customer.setLastName(value);
+						break;
+
+					case "number":
+						phoneNumber.setNumber(value);
+						break;
+
+					case "type":
+						phoneNumber.setType(value);
+						break;
+					}
+
+					break;
+
+				case START_OBJECT:
+					if (inPhoneNumberArray) {
+						phoneNumber = new PhoneNumber();
+					}
+					break;
+
+				case END_OBJECT:
+					if (inPhoneNumberArray) {
+						customer.getPhoneNumbers().add(phoneNumber);
+					}
+					break;
+
+				case START_ARRAY:
+					// There is only one JSON Array in Customer - the list of
+					// phone numbers so we can hard-code this
+					inPhoneNumberArray = true;
+					break;
+
+				case END_ARRAY:
+					// There is only one JSON Array in Customer - the list of
+					// phone numbers, so we can hard-code adding phone number
+					inPhoneNumberArray = false;
+					break;
+
+				}
+			}
+		} catch (FileNotFoundException ex) {
+			System.out.println(ex);
+		}
+
+		return customer;
+	}
+
+	/*************************************************************************
+	 * Write a customer instance to a file using the JsonGenerator API
+	 *************************************************************************/
+	private static void generateCustomer(Customer customer,
+			JsonGenerator generator) {
+		generator.writeStartObject()
+				.write("id", customer.getId())
+				.write("firstName", customer.getFirstName())
+				.write("lastName", customer.getLastName())
+				.writeStartArray("phoneNumbers");
+
+		for (PhoneNumber phoneNumber : customer.getPhoneNumbers()) {
+			generator.writeStartObject()
+					.write("number", phoneNumber.getNumber())
+					.write("type", phoneNumber.getType()).writeEnd();
+		}
+
+		generator.writeEnd()   // Write end of phone number array
+				.writeEnd();	// Write end of customer
+	}
+
+}
\ No newline at end of file
diff --git a/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/Customer.java b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/Customer.java
new file mode 100644
index 0000000..e18ec24
--- /dev/null
+++ b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/Customer.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.json.jsonprocessing.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Customer {
+
+    private int id;
+	private String firstName;
+    private String lastName;
+    private List<PhoneNumber> phoneNumbers;
+
+    public Customer() {
+	phoneNumbers = new ArrayList<PhoneNumber>();
+    }
+
+    public Customer(int id, String firstName, String lastName, List<PhoneNumber> phoneNumbers) {
+	this.id = id;
+	this.firstName = firstName;
+	this.lastName = lastName;
+	this.phoneNumbers = phoneNumbers;
+    }
+
+    public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getFirstName() {
+		return firstName;
+	}
+
+	public void setFirstName(String firstName) {
+		this.firstName = firstName;
+	}
+
+	public String getLastName() {
+		return lastName;
+	}
+
+	public void setLastName(String lastName) {
+		this.lastName = lastName;
+	}
+
+	public List<PhoneNumber> getPhoneNumbers() {
+		return phoneNumbers;
+	}
+
+	public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
+		this.phoneNumbers = phoneNumbers;
+	}
+
+	@Override
+	public String toString() {
+		String string = id + ": " + firstName + " " + lastName;
+
+		for (PhoneNumber phoneNumber : phoneNumbers) {
+			string += ", " + phoneNumber;
+		}
+
+		return string;
+	}
+
+}
\ No newline at end of file
diff --git a/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/PhoneNumber.java b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/PhoneNumber.java
new file mode 100644
index 0000000..6c42168
--- /dev/null
+++ b/moxy/json-processing/src/main/java/eclipselink/example/moxy/json/jsonprocessing/model/PhoneNumber.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.json.jsonprocessing.model;
+
+
+public class PhoneNumber {
+
+    private String type;
+    private String number;
+
+    public PhoneNumber() { }
+
+    public PhoneNumber(String number, String type) {
+	this.number = number;
+	this.type = type;
+    }
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getNumber() {
+		return number;
+	}
+
+	public void setNumber(String number) {
+		this.number = number;
+	}
+
+	@Override
+	public String toString() {
+		return "[number: " + number + ", type: " + type + "]";
+	}
+
+}
\ No newline at end of file