org.apache.openjpa.persistence.jest.JSONObject Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.jest;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* A JSON instance for persistence.
*
* Persistent instances have a persistent identity that extends beyond the process lifetime unlike other common
* identity such as {@linkplain System#identityHashCode(Object) identity hash code} for a Java instance in a JVM.
*
* A JSONObject instance must need such a persistent identity.
*
* @author Pinaki Poddar
*
*/
public class JSONObject implements JSON {
private final String _type;
private final String _id;
private final boolean _ref;
private final Map _values;
public JSONObject(String type, Object id, boolean ref) {
_type = type;
_id = id.toString();
_ref = ref;
_values = new LinkedHashMap<>();
}
public void set(String key, Object value) {
_values.put(key, value);
}
public void write(PrintWriter writer) {
writer.println(toString());
}
@Override
public String toString() {
return asString(0).toString();
}
@Override
public StringBuilder asString(int indent) {
StringBuilder buf = new StringBuilder().append(OBJECT_START);
buf.append(encodeField(_ref ? REF_MARKER : ID_MARKER, ior(), 0));
if (_ref) {
return buf.append(OBJECT_END);
}
StringBuilder tab = newIndent(indent+1);
for (Map.Entry e : _values.entrySet()) {
buf.append(FIELD_SEPARATOR).append(NEWLINE);
buf.append(tab).append(encodeField(e.getKey(), e.getValue(), indent+1));
}
buf.append(NEWLINE)
.append(newIndent(indent))
.append(OBJECT_END);
return buf;
}
/**
* Encoding a JSON field is a quoted field name, followed by a :, followed by a value (which itself can be JSON)
* @param field
* @param value
* @param indent
*/
private static StringBuilder encodeField(String field, Object value, int indent) {
return new StringBuilder()
.append(quoteFieldName(field))
.append(VALUE_SEPARATOR)
.append(quoteFieldValue(value, indent));
}
private static StringBuilder newIndent(int indent) {
char[] tabs = new char[indent*4];
Arrays.fill(tabs, SPACE);
return new StringBuilder().append(tabs);
}
StringBuilder ior() {
return new StringBuilder(_type).append('-').append(_id);
}
private static StringBuilder quoteFieldName(String s) {
return new StringBuilder().append(QUOTE).append(s).append(QUOTE);
}
/**
* Creates a StringBuilder for the given value.
* If the value is null, outputs null
without quote
* If the value is Number, outputs the value without quote
* If the value is JSON, outputs the string rendition of value
* Otherwise quoted value
* @param o
*/
private static StringBuilder quoteFieldValue(Object o, int indent) {
if (o == null) return new StringBuilder(NULL_LITERAL);
if (o instanceof Number) return new StringBuilder(o.toString());
if (o instanceof JSON) return ((JSON)o).asString(indent);
return quoted(o.toString());
}
private static StringBuilder quoted(Object o) {
if (o == null) return new StringBuilder(NULL_LITERAL);
return new StringBuilder().append(QUOTE).append(o.toString()).append(QUOTE);
}
/**
* An array of objects. Members can be JSON too.
*
* @author Pinaki Poddar
*
*/
public static class Array implements JSON {
private List