下面列出了怎么用com.fasterxml.jackson.databind.node.ContainerNode的API类实例代码及写法,或者点击链接到github查看源代码。
protected JsonCache add(JsonPointer ptr, JsonNode node) {
// If ptr ends with an array index, this implies inserting at the specified index.
// If ptr does not end with an array index, this implies appending to the end of the array.
// In both cases the array in question and its ancestors must be created if they do not already exist.
String lastProperty = ptr.last().getMatchingProperty();
boolean isIndexed = isInteger(lastProperty);
ContainerNode<?> container = ensureContainerExists(ptr, !isIndexed);
switch (container.getNodeType()) {
case ARRAY:
ArrayNode array = (ArrayNode) container;
int index = isIndexed ? Integer.parseInt(lastProperty) : array.size();
if (index < array.size()) {
array.insert(index, node);
} else {
// Fill any gap between current size and index with nulls (Jackson doesn't support sparse arrays).
for (int i = array.size(); i < index; i++)
array.add(array.nullNode());
array.add(node);
}
break;
default:
throw new IllegalArgumentException(ptr + " does not identify an array");
}
setDirty();
return this;
}
@Override
public Root load(InputStream in) throws CacheException {
Objects.requireNonNull(in, "in is required");
try (InputStream is = in) {
if (isLoaded) {
if (mergePolicy != MergePolicy.NO_MERGE) {
ContainerNode<?> tree = (ContainerNode<?>) mapper.readTree(in);
// The cache is already loaded, so merge the incoming object tree into the existing root.
merge(root, tree);
}
} else {
root = (ContainerNode<?>) mapper.readTree(in);
isDirty = false;
isLoaded = true;
}
} catch (IOException e) {
throw new CacheException(e);
}
return this;
}
@Override
public void onValueNode(ValueNode node, Optional<ContainerNode<?>> parent, List<PathElement> path) {
String value = node.isTextual() ? node.textValue() : node.toString();
List<Placeholder> placeholders = extractPlaceholders(value);
if (!placeholders.isEmpty()) {
for (Placeholder placeholder : placeholders) {
if (placeholder.hasDefaultValue()) {
String valueWithReplacements = replacePlaceholder(value, placeholder.name(), placeholder.defaultValue());
last(path).setChild(parent.get(), TextNode.valueOf(valueWithReplacements));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("At {}, replaced {} with {}", new Object[]{path, value, valueWithReplacements});
}
}
}
}
}
@Override
public JsonCache set(JsonPointer ptr, Object value) {
String property = ptr.last().getMatchingProperty();
ContainerNode<?> container = ensureContainerExists(ptr);
JsonNode node = nodeFor(value);
switch (container.getNodeType()) {
case ARRAY:
ArrayNode array = (ArrayNode) container;
int index = Integer.parseInt(property);
if (index < array.size()) {
array.set(index, node);
} else {
// Fill any gap between current size and index with nulls (Jackson doesn't support sparse arrays).
for (int i = array.size(); i < index; i++)
array.add(array.nullNode());
array.add(node);
}
break;
case OBJECT:
((ObjectNode) container).set(property, node);
break;
default:
throw new IllegalArgumentException(ptr + " does not identify a settable container");
}
setDirty();
return this;
}
@Override
public void onValueNode(ValueNode node, Optional<ContainerNode<?>> parent, List<PathElement> pathAsList) {
String path = new NodePath(pathAsList).toString();
String value = node.isTextual() ? node.textValue() : node.toString();
List<Placeholder> placeholders = extractPlaceholders(value);
if (placeholders.isEmpty() && !resolved.containsKey(path)) {
resolved.put(path, value);
passAgain = true;
} else {
boolean changes = false;
for (Placeholder placeholder : placeholders) {
String replacement = resolved.get(placeholder.name());
if (replacement != null) {
String valueWithReplacements = replacePlaceholder(value, placeholder.name(), replacement);
last(pathAsList).setChild(parent.get(), TextNode.valueOf(valueWithReplacements));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("At {}, replaced {} with {}", new Object[]{pathAsList, value, valueWithReplacements});
}
value = valueWithReplacements;
changes = true;
}
}
passAgain |= changes;
}
}
@Override
public void onValueNode(ValueNode node, Optional<ContainerNode<?>> parent, List<PathElement> path) {
String value = node.isTextual() ? node.textValue() : node.toString();
List<String> placeholders = extractPlaceholderStrings(value);
if (!placeholders.isEmpty()) {
String pathString = new NodePath(path).toString();
for (String placeholder : placeholders) {
unresolvedPlaceholderDescriptions.add(new UnresolvedPlaceholder(pathString, value, placeholder));
}
}
}
public static void stripEmptyContainerNodes(ObjectNode objectNode) {
Iterator<Map.Entry<String, JsonNode>> i = objectNode.fields();
while (i.hasNext()) {
Map.Entry<String, JsonNode> entry = i.next();
JsonNode value = entry.getValue();
if (value instanceof ContainerNode && ((ContainerNode<?>) value).size() == 0) {
// remove empty nodes, e.g. unused "smtp" and "alerts" nodes
i.remove();
}
}
}
@NotNull
public static String addPropertyToObject(AddPropertyToObjectInputs addPropertyToObjectInputs, ObjectMapper objectMapper) throws Exception {
JsonNode jsonRoot = objectMapper.readTree(addPropertyToObjectInputs.getJsonObject());
if (!(jsonRoot instanceof ObjectNode)) {
throw new Exception(ADD_PROPERTY_EXCEPTION);
}
ContainerNode jsonResult = ((ObjectNode) jsonRoot).put(addPropertyToObjectInputs.getNewPropertyName(),
addPropertyToObjectInputs.getNewPropertyValue());
if (jsonResult == null) {
throw new Exception(ADD_PROPERTY_EXCEPTION);
}
return jsonResult.toString();
}
private HttpURLConnection request(final ContainerNode json,
final Consumer<HttpURLConnection> preRequest) throws IOException {
final HttpURLConnection conn = startJsonPostRequest();
preRequest.accept(conn);
try (final OutputStream requestBody = conn.getOutputStream()) {
JSON_MAPPER.writeValue(requestBody, json);
}
// This is the canonical way to wait for the server to respond.
conn.getResponseCode();
return conn;
}
/**
* 解析每条 json 数据, 并将表信息和数据信息封装为 ClickHouseSinkData 对象
*/
private ClickHouseSinkData handlerRecord(ObjectMapper mapper, Map<String, Map<String, String>> tableColumns, SinkRecord record) throws IOException, SQLException, ParseException {
JsonNode jsonNode = mapper.readTree((String) record.value());
String topic = record.topic();
ClickHouseTableInfo clickHouseTableInfo = sinkTableMap.get(topic);
Map<String, String> ckTabColumns = tableColumns.get(clickHouseTableInfo.getTable());
if (ckTabColumns == null) {
ckTabColumns = dataSource.descTableColType(String.format("`%s`.`%s`", sinkDb, clickHouseTableInfo.getTable()));
tableColumns.put(clickHouseTableInfo.getTable(), ckTabColumns);
}
ClickHouseSinkData clickHouseSinkData = new ClickHouseSinkData();
List<String> columns = new ArrayList<>();
List<Object> values = new ArrayList<>();
Iterator<String> keys = jsonNode.fieldNames();
while (keys.hasNext()) {
String fieldName = keys.next();
String colType = ckTabColumns.get(fieldName);
if (colType != null) {
columns.add("`" + fieldName + "`");
JsonNode nodeValue = jsonNode.get(fieldName);
if (ClickHouseTypeConvert.isNumberType(colType)) {
values.add(nodeValue.asText());
} else if (nodeValue instanceof ContainerNode) {
values.add(String.format("'%s'", nodeValue.toString().replaceAll("'", "\\\\'")));
} else {
values.add(String.format("'%s'", nodeValue.asText().replaceAll("'", "\\\\'")));
}
} else {
throw new ConfigException(String.format("topic: %s, 列: %s, 不存在ClickHouse表: %s中, 该表所有列: %s",
topic, fieldName, clickHouseTableInfo.getTable(), StringUtils.join(ckTabColumns.keySet(), ", ")));
}
}
columns.add("`" + clickHouseTableInfo.getSinkDateCol() + "`");
if (StringUtils.isNotEmpty(clickHouseTableInfo.getSourceDateCol())) {
JsonNode sourceDateNode = jsonNode.get(clickHouseTableInfo.getSourceDateCol());
if (sourceDateNode != null) {
values.add(String.format("'%s'", dateFormat.format(clickHouseTableInfo.getDf().parse(sourceDateNode.asText()))));
} else {
values.add(String.format("'%s'", dateFormat.format(System.currentTimeMillis())));
}
} else {
values.add(String.format("'%s'", dateFormat.format(System.currentTimeMillis())));
}
clickHouseSinkData.setTable(clickHouseTableInfo.getTable());
clickHouseSinkData.setLocalTable(clickHouseTableInfo.getLocalTable());
clickHouseSinkData.setColumns(StringUtils.join(columns, ", "));
clickHouseSinkData.putValue(String.format("(%s)", StringUtils.join(values, ", ")));
return clickHouseSinkData;
}
/**
* Ensures that all ancestor containers exist for the specified JSON pointer.
*
* @param ptr A <a href="https://tools.ietf.org/html/rfc6901">JSON Pointer</a> to the property to set.
* @param forceArray <code>true</code> to create an array for the last segment of the pointer if it is non-integral.
* @return The container that owns the property identified by <code>path</code>.
*/
protected ContainerNode<?> ensureContainerExists(JsonPointer ptr, boolean forceArray) {
if (root == null) {
root = isInteger(ptr.getMatchingProperty()) // split
? JsonNodeFactory.instance.arrayNode()
: JsonNodeFactory.instance.objectNode();
}
String lastProperty = ptr.last().getMatchingProperty();
Deque<String> stack = new ArrayDeque<>();
JsonPointer ancestorPtr = forceArray && !isInteger(lastProperty) ? ptr : ptr.head();
JsonNode ancestor = root.at(ancestorPtr);
while (ancestor.isMissingNode()) {
stack.push(ancestorPtr.last().getMatchingProperty());
ancestorPtr = ancestorPtr.head();
ancestor = root.at(ancestorPtr);
}
if (!ancestor.isContainerNode())
throw new IllegalArgumentException(ancestorPtr + " does not identify a container node");
while (!stack.isEmpty()) {
String ancestorProperty = stack.pop();
String childProperty = stack.isEmpty() // split
? forceArray && !isInteger(lastProperty) // split
? "0" // split
: lastProperty // split
: stack.peek();
// Parent can be array or object; child can be array or object - that's four possible combinations.
// Infer the child container type from the child property name: an integer pattern implies an array node.
if (isInteger(childProperty)) {
switch (ancestor.getNodeType()) {
case ARRAY:
// ARRAY/ARRAY
ancestor = ((ArrayNode) ancestor).insertArray(Integer.parseInt(ancestorProperty));
break;
case OBJECT:
// OBJECT/ARRAY
ancestor = ((ObjectNode) ancestor).putArray(ancestorProperty);
break;
default:
throw new IllegalArgumentException(ancestorProperty + " does not identify an array node");
}
} else {
switch (ancestor.getNodeType()) {
case ARRAY:
// ARRAY/OBJECT
ancestor = ((ArrayNode) ancestor).insertObject(Integer.parseInt(ancestorProperty));
break;
case OBJECT:
// OBJECT/OBJECT
ancestor = ((ObjectNode) ancestor).putObject(ancestorProperty);
break;
default:
throw new IllegalArgumentException(ancestorProperty + " does not identify an array node");
}
}
setDirty();
}
return (ContainerNode<?>) ancestor;
}
protected void merge(ContainerNode<?> dest, ContainerNode<?> src) {
if (dest.getNodeType() == src.getNodeType()) {
if (dest.isArray()) {
ArrayNode destArray = (ArrayNode) dest;
ArrayNode srcArray = (ArrayNode) src;
outer:
for (int i = 0; i < srcArray.size(); i++) {
// Only add a source element if it is not already present in the destination array.
JsonNode srcElem = srcArray.get(i);
for (int j = 0; j < destArray.size(); j++) {
if (destArray.get(j).equals(srcElem))
continue outer;
}
destArray.add(srcElem);
}
} else if (dest.isObject()) {
ObjectNode destObject = (ObjectNode) dest;
ObjectNode srcObject = (ObjectNode) src;
Iterator<Entry<String, JsonNode>> fields = srcObject.fields();
while (fields.hasNext()) {
Entry<String, JsonNode> field = fields.next();
String fieldName = field.getKey();
JsonNode srcChild = field.getValue();
if (destObject.has(fieldName)) {
JsonNode destChild = destObject.get(fieldName);
switch (mergePolicy) {
case OVERWRITE_EXISTING:
destObject.set(fieldName, srcChild);
// Mark the cache as dirty as we've added items from another file.
isDirty = true;
LOGGER.info("Existing root property '" + fieldName
+ "' has been overwritten by incoming data");
break;
case MERGE_RECURSIVE:
if (destChild.isContainerNode() && srcChild.isContainerNode())
merge((ContainerNode<?>) destChild, (ContainerNode<?>) srcChild);
break;
case KEEP_EXISTING:
LOGGER.info("Existing root property '" + fieldName
+ "' will not be overwritten by incoming data");
default:
// Nothing to do.
break;
}
} else {
destObject.set(fieldName, srcChild);
LOGGER.info("New property '" + fieldName + "' has been added from incoming data");
// Mark the cache as dirty as we've added items from another file.
isDirty = true;
}
}
}
} else {
LOGGER.warn("Cannot merge containers of differing types");
}
}
private Call(ValueNode node, Optional<ContainerNode<?>> parent, List<PathElement> path) {
this.node = node;
this.parent = parent;
this.path = path;
}
public Audit build(ObjectMapper mapper) {
Audit audit = new Audit();
audit.setId(id);
audit.setTransactionId(transactionalId);
audit.setReferenceType(referenceType);
audit.setReferenceId(referenceId);
audit.setType(type);
audit.setTimestamp(timestamp);
// The actor and/or target of an event is dependent on the action performed.
// All events have actors but not all have targets.
AuditEntity actor = new AuditEntity();
actor.setId(actorId);
actor.setType(actorType);
actor.setAlternativeId(actorAlternativeId);
actor.setDisplayName(actorDisplayName);
actor.setReferenceType(actorReferenceType);
actor.setReferenceId(actorReferenceId);
audit.setActor(actor);
// Network access point
AuditAccessPoint accessPoint = new AuditAccessPoint();
accessPoint.setId(accessPointId);
accessPoint.setAlternativeId(accessPointAlternativeId);
accessPoint.setDisplayName(accessPointName);
accessPoint.setIpAddress(ipAddress);
accessPoint.setUserAgent(userAgent);
audit.setAccessPoint(accessPoint);
// target
if (targetId != null) {
AuditEntity target = new AuditEntity();
target.setId(targetId);
target.setType(targetType);
target.setAlternativeId(targetAlternativeId);
target.setDisplayName(targetDisplayName);
target.setReferenceType(targetReferenceType);
target.setReferenceId(targetReferenceId);
audit.setTarget(target);
}
// result
AuditOutcome result = new AuditOutcome();
if (throwable == null) {
result.setStatus(Status.SUCCESS);
// set details
if (newValue != null || oldValue != null) {
ContainerNode oldNode;
ContainerNode newNode;
if (EventType.USER_CONSENT_CONSENTED.equals(type) || EventType.USER_CONSENT_REVOKED.equals(type)) {
oldNode = mapper.createArrayNode();
newNode = mapper.createArrayNode();
mapper.convertValue(newValue, ArrayNode.class).forEach(jsonNode -> {
((ArrayNode) newNode).add(((ObjectNode) jsonNode).remove(Arrays.asList("updatedAt", "createdAt", "expiresAt", "userId", "domain")));
});
} else {
oldNode = oldValue == null
? mapper.createObjectNode()
: mapper.convertValue(oldValue, ObjectNode.class).remove(Arrays.asList("updatedAt", "createdAt", "lastEvent"));
newNode = newValue == null
? mapper.createObjectNode()
: mapper.convertValue(newValue, ObjectNode.class).remove(Arrays.asList("updatedAt", "createdAt", "lastEvent"));
}
clean(oldNode, null, null);
clean(newNode, null, null);
result.setMessage(JsonDiff.asJson(oldNode, newNode).toString());
}
} else {
result.setStatus(Status.FAILURE);
result.setMessage(throwable.getMessage());
}
audit.setOutcome(result);
return audit;
}
/**
* Performs single JSON-RPC request and return JSON-RPC response
*
* @param request JSON-RPC request as a Java object
* @param service service object
* @return JSON-RPC response as a Java object
* @throws Exception in case of a runtime error (reflections, business logic...)
*/
@NotNull
private Response handleSingle(@NotNull Request request, @NotNull Object service) throws Exception {
// Check mandatory fields and correct protocol version
String requestMethod = request.getMethod();
String jsonrpc = request.getJsonrpc();
ValueNode id = request.getId();
if (jsonrpc == null || requestMethod == null) {
log.error("Not a JSON-RPC request: " + request);
return new ErrorResponse(id, INVALID_REQUEST);
}
if (!jsonrpc.equals(VERSION)) {
log.error("Not a JSON_RPC 2.0 request: " + request);
return new ErrorResponse(id, INVALID_REQUEST);
}
JsonNode params = request.getParams();
if (!params.isObject() && !params.isArray() && !params.isNull()) {
log.error("Params of request: '" + request + "' should be an object, an array or null");
return new ErrorResponse(id, INVALID_REQUEST);
}
ClassMetadata classMetadata = classesMetadata.get(service.getClass());
if (!classMetadata.isService()) {
log.warn(service.getClass() + " is not available as a JSON-RPC 2.0 service");
return new ErrorResponse(id, METHOD_NOT_FOUND);
}
MethodMetadata method = classMetadata.getMethods().get(requestMethod);
if (method == null) {
log.error("Unable find a method: '" + requestMethod + "' in a " + service.getClass());
return new ErrorResponse(id, METHOD_NOT_FOUND);
}
ContainerNode<?> notNullParams = !params.isNull() ?
(ContainerNode<?>) params : mapper.createObjectNode();
Object[] methodParams;
try {
methodParams = convertToMethodParams(notNullParams, method);
} catch (IllegalArgumentException e) {
log.error("Bad params: " + notNullParams + " of a method '" + method.getName() + "'", e);
return new ErrorResponse(id, INVALID_PARAMS);
}
Object result = method.getMethod().invoke(service, methodParams);
return new SuccessResponse(id, result);
}
/**
* Converts JSON params to java params in the appropriate order of the invoked method
*
* @param params json params (map or array)
* @param method invoked method metadata
* @return array of java objects for passing to the method
*/
@NotNull
private Object[] convertToMethodParams(@NotNull ContainerNode<?> params,
@NotNull MethodMetadata method) {
int methodParamsSize = method.getParams().size();
int jsonParamsSize = params.size();
// Check amount arguments
if (jsonParamsSize > methodParamsSize) {
throw new IllegalArgumentException("Wrong amount arguments: " + jsonParamsSize +
" for a method '" + method.getName() + "'. Actual amount: " + methodParamsSize);
}
Object[] methodParams = new Object[methodParamsSize];
int processed = 0;
for (ParameterMetadata param : method.getParams().values()) {
Class<?> parameterType = param.getType();
int index = param.getIndex();
String name = param.getName();
JsonNode jsonNode = params.isObject() ? params.get(name) : params.get(index);
// Handle omitted value
if (jsonNode == null || jsonNode.isNull()) {
if (param.isOptional()) {
methodParams[index] = getDefaultValue(parameterType);
if (jsonNode != null) {
processed++;
}
continue;
} else {
throw new IllegalArgumentException("Mandatory parameter '" + name +
"' of a method '" + method.getName() + "' is not set");
}
}
// Convert JSON object to an actual Java object
try {
JsonParser jsonParser = mapper.treeAsTokens(jsonNode);
JavaType javaType = mapper.getTypeFactory().constructType(param.getGenericType());
methodParams[index] = mapper.readValue(jsonParser, javaType);
processed++;
} catch (IOException e) {
throw new IllegalArgumentException("Wrong param: " + jsonNode + ". Expected type: '" + param, e);
}
}
// Check that some unprocessed parameters were not passed
if (processed < jsonParamsSize) {
throw new IllegalArgumentException("Some unspecified parameters in " + params +
" are passed to a method '" + method.getName() + "'");
}
return methodParams;
}
private HttpURLConnection request(final ContainerNode json) throws IOException {
return request(json, noop());
}
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.workplacestore");
log.info("appId=" + appId);
KryoNamespace workplaceNamespace = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
.register(WorkflowData.class)
.register(Workplace.class)
.register(DefaultWorkplace.class)
.register(WorkflowContext.class)
.register(DefaultWorkflowContext.class)
.register(SystemWorkflowContext.class)
.register(WorkflowState.class)
.register(ProgramCounter.class)
.register(DataModelTree.class)
.register(JsonDataModelTree.class)
.register(List.class)
.register(ArrayList.class)
.register(JsonNode.class)
.register(ObjectNode.class)
.register(TextNode.class)
.register(LinkedHashMap.class)
.register(ArrayNode.class)
.register(BaseJsonNode.class)
.register(BigIntegerNode.class)
.register(BinaryNode.class)
.register(BooleanNode.class)
.register(ContainerNode.class)
.register(DecimalNode.class)
.register(DoubleNode.class)
.register(FloatNode.class)
.register(IntNode.class)
.register(JsonNodeType.class)
.register(LongNode.class)
.register(MissingNode.class)
.register(NullNode.class)
.register(NumericNode.class)
.register(POJONode.class)
.register(ShortNode.class)
.register(ValueNode.class)
.register(JsonNodeCreator.class)
.register(JsonNodeFactory.class)
.build();
localWorkplaceMap.clear();
workplaceMap = storageService.<String, WorkflowData>consistentMapBuilder()
.withSerializer(Serializer.using(workplaceNamespace))
.withName("workplace-map")
.withApplicationId(appId)
.build();
workplaceMap.addListener(workplaceMapEventListener);
localContextMap.clear();
contextMap = storageService.<String, WorkflowData>consistentMapBuilder()
.withSerializer(Serializer.using(workplaceNamespace))
.withName("workflow-context-map")
.withApplicationId(appId)
.build();
contextMap.addListener(contextMapEventListener);
workplaceMapEventListener.syncLocal();
contextMapEventListener.syncLocal();
log.info("Started");
}
/**
* Ensures that a suitable container exists for the specified JSON pointer.
*
* @param ptr A <a href="https://tools.ietf.org/html/rfc6901">JSON Pointer</a> to the property to set.
* @return The container that owns the property identified by <code>path</code>.
*/
protected ContainerNode<?> ensureContainerExists(JsonPointer ptr) {
return ensureContainerExists(ptr, false);
}
void onValueNode(ValueNode node, Optional<ContainerNode<?>> parent, List<PathElement> path);