org.camunda.spin.impl.json.jackson.JacksonJsonNode Maven / Gradle / Ivy
/* Licensed 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.camunda.spin.impl.json.jackson;
import static org.camunda.commons.utils.EnsureUtil.ensureNotNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.camunda.spin.SpinList;
import org.camunda.spin.impl.SpinListImpl;
import org.camunda.spin.impl.json.jackson.format.JacksonJsonDataFormat;
import org.camunda.spin.impl.json.jackson.format.JacksonJsonDataFormatMapper;
import org.camunda.spin.impl.json.jackson.query.JacksonJsonPathQuery;
import org.camunda.spin.impl.logging.SpinLogger;
import org.camunda.spin.json.SpinJsonDataFormatException;
import org.camunda.spin.json.SpinJsonException;
import org.camunda.spin.json.SpinJsonNode;
import org.camunda.spin.json.SpinJsonPathQuery;
import org.camunda.spin.spi.DataFormatMapper;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jayway.jsonpath.InvalidPathException;
import com.jayway.jsonpath.JsonPath;
/**
* Wrapper for a Jackson Json Tree Node.
*
* @author Thorben Lindhauer
* @author Stefan Hentschel
*/
public class JacksonJsonNode extends SpinJsonNode {
private static final JacksonJsonLogger LOG = SpinLogger.JSON_TREE_LOGGER;
protected final JsonNode jsonNode;
protected final JacksonJsonDataFormat dataFormat;
public JacksonJsonNode(JsonNode jsonNode, JacksonJsonDataFormat dataFormat) {
this.jsonNode = jsonNode;
this.dataFormat = dataFormat;
}
public String getDataFormatName() {
return dataFormat.getName();
}
public JsonNode unwrap() {
return jsonNode;
}
public String toString() {
return writeToWriter(new StringWriter()).toString();
}
public OutputStream toStream() {
OutputStream out = new ByteArrayOutputStream();
return writeToStream(out);
}
public S writeToStream(S outputStream) {
dataFormat.getWriter().writeToStream(outputStream, jsonNode);
return outputStream;
}
public W writeToWriter(W writer) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writeToStream(baos);
try {
writer.write(new String(baos.toByteArray(), Charset.forName("UTF-8")));
return writer;
}
catch (IOException e) {
throw LOG.unableToWriteJsonNode(e);
}
}
/**
* fetch correct array index if index is less than 0
*
* ArrayNode will convert all negative integers into 0...
*
* @param index wanted index
* @return {@link Integer} new index
*/
protected Integer getCorrectIndex(Integer index) {
Integer size = jsonNode.size();
Integer newIndex = index;
// reverse walking through the array
if(index < 0) {
newIndex = size + index;
}
// the negative index would be greater than the size a second time!
if(newIndex < 0) {
throw LOG.indexOutOfBounds(index, size);
}
// the index is greater as the actual size
if(index > size) {
throw LOG.indexOutOfBounds(index, size);
}
return newIndex;
}
public Integer indexOf(Object searchObject) {
ensureNotNull("searchObject", searchObject);
if(this.isArray()) {
Integer i = 0;
JsonNode node = dataFormat.createJsonNode(searchObject);
for (Iterator nodeIterator = jsonNode.elements(); nodeIterator.hasNext(); i++) {
JsonNode n = nodeIterator.next();
if (n.equals(node)) {
return i;
}
}
// when searchObject is not found
throw LOG.unableToFindProperty(node.asText());
} else {
throw LOG.unableToGetIndex(jsonNode.getNodeType().name());
}
}
public Integer lastIndexOf(Object searchObject) {
ensureNotNull("searchObject", searchObject);
if(this.isArray()) {
Integer i = 0;
Integer j = -1;
JsonNode node = dataFormat.createJsonNode(searchObject);
for (Iterator nodeIterator = jsonNode.elements(); nodeIterator.hasNext(); i++) {
JsonNode n = nodeIterator.next();
if (n.equals(node)) {
j = i;
}
}
// when searchObject is not found
if(j == -1) {
throw LOG.unableToFindProperty(node.getNodeType().name());
}
return j;
} else {
throw LOG.unableToGetIndex(jsonNode.getNodeType().name());
}
}
public boolean isObject() {
return jsonNode.isObject();
}
public boolean hasProp(String name) {
return jsonNode.has(name);
}
public SpinJsonNode prop(String name) {
ensureNotNull("name", name);
if(jsonNode.has(name)) {
JsonNode property = jsonNode.get(name);
return dataFormat.createWrapperInstance(property);
} else {
throw LOG.unableToFindProperty(name);
}
}
public SpinJsonNode prop(String name, String newProperty) {
ObjectNode node = (ObjectNode) jsonNode;
node.put(name, newProperty);
return this;
}
public SpinJsonNode prop(String name, Number newProperty) {
ObjectNode node = (ObjectNode) jsonNode;
// Numbers magic because Jackson has no native .put(Number value)
if(newProperty instanceof Long) {
node.put(name, newProperty.longValue());
} else if(newProperty instanceof Integer) {
node.put(name, newProperty.intValue());
} else if(newProperty instanceof Float) {
node.put(name, newProperty.floatValue());
} else {
// convert any other sub class of Number into Float
node.put(name, newProperty.floatValue());
}
return this;
}
public SpinJsonNode prop(String name, int newProperty) {
return prop(name, (Number) newProperty);
}
public SpinJsonNode prop(String name, float newProperty) {
return prop(name, (Number) newProperty);
}
public SpinJsonNode prop(String name, long newProperty) {
return prop(name, (Number) newProperty);
}
public SpinJsonNode prop(String name, boolean newProperty) {
return prop(name, (Boolean) newProperty);
}
public SpinJsonNode prop(String name, Boolean newProperty) {
ObjectNode node = (ObjectNode) jsonNode;
node.put(name, newProperty);
return this;
}
public SpinJsonNode prop(String name, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy