/* * Copyright (c) 2013, Francis Galiegue * * This program is free software: you can redistribute it and/or modify * it under the terms of the Lesser GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Lesser GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.github.fge.jackson.jsonpointer; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.MissingNode; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import javax.annotation.concurrent.Immutable; import java.util.List; /** * A {@link TreePointer} for {@link JsonNode} * *

This is the "original" JSON Pointer in that it addresses JSON documents. *

* *

It also has a lot of utility methods covering several usage scenarios.

*/ @Immutable public final class JsonPointer extends TreePointer { /** * The empty JSON Pointer */ private static final JsonPointer EMPTY = new JsonPointer(ImmutableList.>of()); /** * Return an empty JSON Pointer * * @return an empty, statically allocated JSON Pointer */ public static JsonPointer empty() { return EMPTY; } /** * Build a JSON Pointer out of a series of reference tokens * *

These tokens can be everything; be sure however that they implement * {@link Object#toString()} correctly!

* *

Each of these tokens are treated as raw tokens (ie, not * encoded).

* * @param first the first token * @param other other tokens * @return a JSON Pointer * @throws NullPointerException one input token is null */ public static JsonPointer of(final Object first, final Object... other) { final List tokens = Lists.newArrayList(); tokens.add(ReferenceToken.fromRaw(first.toString())); for (final Object o: other) tokens.add(ReferenceToken.fromRaw(o.toString())); return new JsonPointer(fromTokens(tokens)); } /** * The main constructor * * @param input the input string * @throws JsonPointerException malformed JSON Pointer * @throws NullPointerException null input */ public JsonPointer(final String input) throws JsonPointerException { this(fromTokens(tokensFromInput(input))); } /** * Alternate constructor * *

This calls {@link TreePointer#TreePointer(TreeNode, List)} with a * {@link MissingNode} as the missing tree node.

* * @param tokenResolvers the list of token resolvers */ public JsonPointer(final List> tokenResolvers) { super(MissingNode.getInstance(), tokenResolvers); } /** * Return a new pointer with a new token appended * * @param raw the raw token to append * @return a new pointer * @throws NullPointerException input is null */ public JsonPointer append(final String raw) { final ReferenceToken refToken = ReferenceToken.fromRaw(raw); final JsonNodeResolver resolver = new JsonNodeResolver(refToken); final List> list = Lists.newArrayList(tokenResolvers); list.add(resolver); return new JsonPointer(list); } /** * Return a new pointer with a new integer token appended * * @param index the integer token to append * @return a new pointer */ public JsonPointer append(final int index) { return append(Integer.toString(index)); } /** * Return a new pointer with another pointer appended * * @param other the other pointer * @return a new pointer * @throws NullPointerException other pointer is null */ public JsonPointer append(final JsonPointer other) { BUNDLE.checkNotNull(other, "nullInput"); final List> list = Lists.newArrayList(tokenResolvers); list.addAll(other.tokenResolvers); return new JsonPointer(list); } /** * Return the immediate parent of this JSON Pointer * *

The parent of the empty pointer is itself.

* * @return a new JSON Pointer representing the parent of the current one */ public JsonPointer parent() { final int size = tokenResolvers.size(); return size <= 1 ? EMPTY : new JsonPointer(tokenResolvers.subList(0, size - 1)); } /** * Build a list of token resolvers from a list of reference tokens * *

Here, the token resolvers are {@link JsonNodeResolver}s.

* * @param tokens the token list * @return a (mutable) list of token resolvers */ private static List> fromTokens( final List tokens) { final List> list = Lists.newArrayList(); for (final ReferenceToken token: tokens) list.add(new JsonNodeResolver(token)); return list; } }