2 * Copyright (c) 2014 Red Hat, Inc. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.aaa.idpmapping;
11 import java.io.BufferedReader;
12 import java.io.IOException;
13 import java.io.StringReader;
14 import java.io.StringWriter;
15 import java.nio.charset.StandardCharsets;
16 import java.nio.file.Files;
17 import java.nio.file.Path;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.LinkedHashMap;
21 import java.util.List;
23 import javax.json.Json;
24 import javax.json.JsonValue;
25 import javax.json.stream.JsonGenerator;
26 import javax.json.stream.JsonGeneratorFactory;
27 import javax.json.stream.JsonLocation;
28 import javax.json.stream.JsonParser;
29 import javax.json.stream.JsonParser.Event;
32 * Converts between JSON and the internal data structures used in the
35 * @author John Dennis <jdennis@redhat.com>
38 public class IdpJson {
43 public Object loadJson(java.io.Reader in) {
44 JsonParser parser = Json.createParser(in);
47 // Prime the pump. Get the first item from the parser.
48 event = parser.next();
51 return loadJsonItem(parser, event);
54 public Object loadJson(Path filename) throws IOException {
55 BufferedReader reader = Files.newBufferedReader(filename, StandardCharsets.UTF_8);
56 return loadJson(reader);
59 public Object loadJson(String string) {
60 StringReader reader = new StringReader(string);
61 return loadJson(reader);
65 * Process current parser item indicated by event. Consumes exactly the
66 * number of parser events necessary to load the item. Caller must advance
67 * the parser via parser.next() after this method returns.
69 private Object loadJsonItem(JsonParser parser, Event event) {
72 return loadJsonObject(parser, event);
75 return loadJsonArray(parser, event);
81 if (parser.isIntegralNumber()) {
82 return parser.getLong();
84 return parser.getBigDecimal().doubleValue();
88 return parser.getString();
97 JsonLocation location = parser.getLocation();
98 throw new IllegalStateException(String.format(
99 "unknown JSON parsing event %s, location(line=%d column=%d offset=%d)", event,
100 location.getLineNumber(), location.getColumnNumber(),
101 location.getStreamOffset()));
106 private List<Object> loadJsonArray(JsonParser parser, Event event) {
107 List<Object> list = new ArrayList<Object>();
109 if (event != Event.START_ARRAY) {
110 JsonLocation location = parser.getLocation();
111 throw new IllegalStateException(
113 "expected JSON parsing event to be START_ARRAY, not %s location(line=%d column=%d offset=%d)",
114 event, location.getLineNumber(), location.getColumnNumber(),
115 location.getStreamOffset()));
117 event = parser.next(); // consume START_ARRAY
118 while (event != Event.END_ARRAY) {
121 obj = loadJsonItem(parser, event);
123 event = parser.next(); // next array item or END_ARRAY
128 private Map<String, Object> loadJsonObject(JsonParser parser, Event event) {
129 Map<String, Object> map = new LinkedHashMap<String, Object>();
131 if (event != Event.START_OBJECT) {
132 JsonLocation location = parser.getLocation();
133 throw new IllegalStateException(String.format(
134 "expected JSON parsing event to be START_OBJECT, not %s, ",
135 "location(line=%d column=%d offset=%d)", event, location.getLineNumber(),
136 location.getColumnNumber(), location.getStreamOffset()));
138 event = parser.next(); // consume START_OBJECT
139 while (event != Event.END_OBJECT) {
140 if (event == Event.KEY_NAME) {
144 key = parser.getString();
145 event = parser.next(); // consume key
146 value = loadJsonItem(parser, event);
149 JsonLocation location = parser.getLocation();
150 throw new IllegalStateException(
152 "expected JSON parsing event to be KEY_NAME, not %s, location(line=%d column=%d offset=%d)",
153 event, location.getLineNumber(), location.getColumnNumber(),
154 location.getStreamOffset()));
157 event = parser.next(); // next key or END_OBJECT
162 public String dumpJson(Object obj) {
163 Map<String, Object> properties = new HashMap<String, Object>(1);
164 properties.put(JsonGenerator.PRETTY_PRINTING, true);
165 JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(properties);
166 StringWriter stringWriter = new StringWriter();
167 JsonGenerator generator = generatorFactory.createGenerator(stringWriter);
169 dumpJsonItem(generator, obj);
171 return stringWriter.toString();
174 private void dumpJsonItem(JsonGenerator generator, Object obj) {
175 // ordered by expected occurrence
176 if (obj instanceof String) {
177 generator.write((String) obj);
178 } else if (obj instanceof List) {
179 generator.writeStartArray();
180 @SuppressWarnings("unchecked")
181 List<Object> list = (List<Object>) obj;
182 dumpJsonArray(generator, list);
183 } else if (obj instanceof Map) {
184 generator.writeStartObject();
185 @SuppressWarnings("unchecked")
186 Map<String, Object> map = (Map<String, Object>) obj;
187 dumpJsonObject(generator, map);
188 } else if (obj instanceof Long) {
189 generator.write(((Long) obj).longValue());
190 } else if (obj instanceof Boolean) {
191 generator.write(((Boolean) obj).booleanValue());
192 } else if (obj == null) {
193 generator.writeNull();
194 } else if (obj instanceof Double) {
195 generator.write(((Double) obj).doubleValue());
197 throw new IllegalStateException(
199 "unsupported data type, must be String, Long, Double, Boolean, List, Map, or null, not %s",
200 obj.getClass().getSimpleName()));
204 private void dumpJsonArray(JsonGenerator generator, List<Object> list) {
205 for (Object obj : list) {
206 dumpJsonItem(generator, obj);
208 generator.writeEnd();
211 private void dumpJsonObject(JsonGenerator generator, Map<String, Object> map) {
213 for (Map.Entry<String, Object> entry : map.entrySet()) {
214 String key = entry.getKey();
215 Object obj = entry.getValue();
217 // ordered by expected occurrence
218 if (obj instanceof String) {
219 generator.write(key, (String) obj);
220 } else if (obj instanceof List) {
221 generator.writeStartArray(key);
222 @SuppressWarnings("unchecked")
223 List<Object> list = (List<Object>) obj;
224 dumpJsonArray(generator, list);
225 } else if (obj instanceof Map) {
226 generator.writeStartObject(key);
227 @SuppressWarnings("unchecked")
228 Map<String, Object> map1 = (Map<String, Object>) obj;
229 dumpJsonObject(generator, map1);
230 } else if (obj instanceof Long) {
231 generator.write(key, ((Long) obj).longValue());
232 } else if (obj instanceof Boolean) {
233 generator.write(key, ((Boolean) obj).booleanValue());
234 } else if (obj == null) {
235 generator.write(key, JsonValue.NULL);
236 } else if (obj instanceof Double) {
237 generator.write(key, ((Double) obj).doubleValue());
239 throw new IllegalStateException(
241 "unsupported data type, must be String, Long, Double, Boolean, List, Map, or null, not %s",
242 obj.getClass().getSimpleName()));
245 generator.writeEnd();