/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.admin.rest.client.utils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.glassfish.api.logging.LogHelper;
/**
*
* @author jasonlee
*/
public class MarshallingUtils {
public static List<Map<String, String>> getPropertiesFromJson(String json) {
List<Map<String, String>> properties = null;
json = json.trim();
if (json.startsWith("{")) {
properties = new ArrayList<Map<String, String>>();
properties.add(processJsonMap(json));
} else if (json.startsWith("[")) {
try {
properties = processJsonArray(new JSONArray(json));
} catch (JSONException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
} else {
throw new RuntimeException("The JSON string must start with { or ["); // i18n
}
return properties;
}
public static List<Map<String, String>> getPropertiesFromXml(String xml) {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
InputStream input = null;
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
input = new ByteArrayInputStream(xml.trim().getBytes("UTF-8"));
XMLStreamReader parser = inputFactory.createXMLStreamReader(input);
while (parser.hasNext()) {
int event = parser.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT: {
if ("list".equals(parser.getLocalName())) {
list = processXmlList(parser);
}
break;
}
default: {
// no-op
}
}
}
} catch (UnsupportedEncodingException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_ENCODING_ERROR, ex, "UTF-8");
throw new RuntimeException(ex);
} catch (XMLStreamException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_XML_STREAM_ERROR, ex);
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_IO_ERROR, ex);
}
}
return list;
}
public static String getXmlForProperties(final Map<String, String> properties) {
return getXmlForProperties(new ArrayList<Map<String, String>>() {{ add(properties); }} );
}
public static String getXmlForProperties(List<Map<String, String>> properties) {
try {
String xml = null;
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
StringWriter sw = new StringWriter();
XMLStreamWriter writer = outputFactory.createXMLStreamWriter(sw);
writer.writeStartDocument("UTF-8","1.0");
writer.writeStartElement("list");
for (Map<String, String> property : properties) {
writer.writeStartElement("map");
for (Map.Entry<String, String> entry : property.entrySet()) {
writer.writeStartElement("entry");
writer.writeAttribute("key", entry.getKey());
writer.writeAttribute("value", entry.getValue());
writer.writeEndElement();
}
writer.writeEndElement();
}
writer.writeEndElement();
writer.writeEndDocument();
writer.flush();
writer.close();
return sw.toString();
} catch (XMLStreamException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_XML_STREAM_ERROR, ex);
throw new RuntimeException(ex);
}
}
public static String getJsonForProperties(final Map<String, String> properties) {
return getJsonForProperties(new ArrayList<Map<String, String>>() {{ add(properties); }} );
}
public static String getJsonForProperties(List<Map<String, String>> properties) {
JSONArray list = new JSONArray();
for (Map<String, String> property : properties) {
list.put(property);
}
return list.toString();
}
public static Map buildMapFromDocument(String text) {
Map map = null;
if ((text == null) || text.isEmpty()) {
return new HashMap();
}
text = text.trim();
if (text.startsWith("{")) {
map = processJsonMap(text);
} else if (text.startsWith("<")) {
InputStream input = null;
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_VALIDATING, false);
input = new ByteArrayInputStream(text.trim().getBytes("UTF-8"));
XMLStreamReader parser = inputFactory.createXMLStreamReader(input);
while (parser.hasNext()) {
int event = parser.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT: {
if ("map".equals(parser.getLocalName())) {
map = processXmlMap(parser);
}
break;
}
default: {
// No-op
}
}
}
} catch (UnsupportedEncodingException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_ENCODING_ERROR, ex, "UTF-8");
throw new RuntimeException(ex);
} catch (XMLStreamException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_XML_STREAM_ERROR, ex);
throw new RuntimeException(ex);
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException ex) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_IO_ERROR, ex);
}
}
} else {
System.out.println(text);
throw new RuntimeException ("An unknown document type was provided: " + text); //.substring(0, 10));
}
return map;
}
/**************************************************************************/
private static Map processJsonMap(String json) {
Map map;
try {
map = processJsonObject(new JSONObject(json));
} catch (JSONException e) {
map = new HashMap();
}
return map;
}
private static Map processJsonObject(JSONObject jo) {
Map<String, Object> map = new HashMap<String, Object>();
try {
Iterator i = jo.keys();
while (i.hasNext()) {
String key = (String)i.next();
Object value = jo.get(key);
if (value instanceof JSONArray) {
map.put(key, processJsonArray((JSONArray)value));
} else if (value instanceof JSONObject) {
map.put(key, processJsonObject((JSONObject)value));
} else if (value.getClass().getSimpleName().equalsIgnoreCase("null")) {
// The Map may not store null values, but we shouldn't rely on
// that behavior, just to be safe
map.put(key, null);
} else {
map.put(key, value);
}
}
} catch (JSONException e) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_JSON_ERROR, e);
}
return map;
}
private static List processJsonArray(JSONArray ja) {
List results = new ArrayList();
try {
for (int i = 0; i < ja.length(); i++) {
Object entry = ja.get(i);
if (entry instanceof JSONArray) {
results.add(processJsonArray((JSONArray)entry));
} else if (entry instanceof JSONObject) {
results.add(processJsonObject((JSONObject)entry));
} else {
results.add(entry);
}
}
} catch (JSONException e) {
LogHelper.log(RestClientLogging.logger, Level.SEVERE, RestClientLogging.REST_CLIENT_JSON_ERROR, e);
}
return results;
}
private static Map processXmlMap(XMLStreamReader parser) throws XMLStreamException {
boolean endOfMap = false;
Map<String, Object> entry = new HashMap<String, Object>();
String key = null;
String element = null;
while (!endOfMap) {
int event = parser.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT: {
if ("entry".equals(parser.getLocalName())) {
key = parser.getAttributeValue(null, "key");
String value = parser.getAttributeValue(null, "value");
if (value != null) {
entry.put(key, value);
key = null;
}
} else if ("map".equals(parser.getLocalName())) {
Map value = processXmlMap(parser);
entry.put(key, value);
} else if ("list".equals(parser.getLocalName())) {
List value = processXmlList(parser);
entry.put(key, value);
} else {
element = parser.getLocalName();
}
break;
}
case XMLStreamConstants.END_ELEMENT: {
if ("map".equals(parser.getLocalName())) {
endOfMap = true;
}
element = null;
break;
}
default: {
String text=parser.getText();
if (element != null) {
if ("number".equals(element)) {
if (text.contains(".")) {
entry.put(key, Double.parseDouble(text));
} else {
entry.put(key, Long.parseLong(text));
}
} else if ("string".equals(element)) {
entry.put(key, text);
}
element = null;
}
}
}
}
return entry;
}
private static List processXmlList(XMLStreamReader parser) throws XMLStreamException {
List list = new ArrayList();
boolean endOfList = false;
String element = null;
while (!endOfList) {
int event = parser.next();
switch (event) {
case XMLStreamConstants.START_ELEMENT: {
if ("map".equals(parser.getLocalName())) {
list.add(processXmlMap(parser));
} else {
element = parser.getLocalName();
}
break;
}
case XMLStreamConstants.END_ELEMENT: {
if ("list".equals(parser.getLocalName())) {
endOfList = true;
}
element = null;
break;
}
default: {
String text = parser.getText();
if (element != null) {
if ("number".equals(element)) {
if (text.contains(".")) {
list.add(Double.parseDouble(text));
} else {
list.add(Long.parseLong(text));
}
} else if ("string".equals(element)) {
list.add(text);
}
element = null;
}
}
}
}
return list;
}
}