All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minidev.json.actions.path.TreePath Maven / Gradle / Ivy

package net.minidev.json.actions.path;

import java.util.Arrays;
import java.util.Map;
import java.util.List;
import java.util.ListIterator;

/**
 * {@link TreePath} represents an n-gram formatted path
 * corresponding to a branch in a tree of {@link Map}s
 * and {@link List}s
 * 

* See package-info for more details * * @author [email protected] */ public class TreePath { protected enum Step { NONE, NEXT, PREV } protected final String path; protected List keys; protected ListIterator keysItr; protected String currKey; protected Step lastStep; protected StringBuilder origin; protected StringBuilder remainder; protected PathDelimiter delim; public TreePath(String path, PathDelimiter delim) { this.delim = delim; checkPath(path); this.path = path; this.keys = Arrays.asList(path.split(delim.regex())); reset(); } public void reset() { keysItr = keys.listIterator(); currKey = ""; lastStep = Step.NONE; origin = new StringBuilder(""); remainder = new StringBuilder(path); } public boolean hasNext() { return keysItr.hasNext(); } public int nextIndex() { return keysItr.nextIndex(); } public String next() { currKey = keysItr.next(); /** when changing direction the {@link ListIterator} does not really * move backward so an extra step is performed */ if (!lastStep.equals(Step.PREV)) { originIncrement(); remainderDecrement(); } lastStep = Step.NEXT; return currKey; } public boolean hasPrev() { return keysItr.hasPrevious(); } public int prevIndex() { return keysItr.previousIndex(); } public String prev() { String temp = currKey; currKey = keysItr.previous(); /** when changing direction the {@link ListIterator} does not really * move backward so an extra step is performed */ if (!lastStep.equals(Step.NEXT)) { remainderIncrement(temp); originDecrement(); } lastStep = Step.PREV; return currKey; } private void remainderDecrement() { if (length() == 1) remainder = new StringBuilder(""); else if (remainder.indexOf(delim.str()) < 0) remainder = new StringBuilder(""); else remainder.delete(0, remainder.indexOf(delim.str()) + 1); } private void originDecrement() { if (length() == 1) origin = new StringBuilder(""); else if (origin.indexOf(delim.str()) < 0) origin = new StringBuilder(""); else origin.delete(origin.lastIndexOf(delim.str()), origin.length()); } private void originIncrement() { if (origin.length() != 0) { origin.append(delim.chr()); } origin.append(currKey); } private void remainderIncrement(String prev) { if (remainder.length() == 0) remainder = new StringBuilder(prev); else remainder = new StringBuilder(prev).append(delim.chr()).append(remainder); } /** * @return An n-gram path from the first key to the current key (inclusive) */ public String path() { return path; } /** * @return An n-gram path from the first key to the current key (inclusive) */ public String origin() { return origin.toString(); } /** * @return An n-gram path from the current key to the last key (inclusive) */ public String remainder() { return remainder.toString(); } /** * @return first element in the JSONPath */ public String first() { return keys.get(0); } /** * @return last element in the JSONPath */ public String last() { return keys.get(keys.size() - 1); } /** * @return current element pointed to by the path iterator */ public String curr() { return currKey; } public int length() { return keys.size(); } public String subPath(int firstIndex, int lastIndex) { if (lastIndex < firstIndex) { throw new IllegalArgumentException("bad call to subPath"); } StringBuilder sb = new StringBuilder(path.length()); for (int i = firstIndex; i <= lastIndex; i++) { sb.append(keys.get(i)); if (i < lastIndex) { sb.append(delim.chr()); } } sb.trimToSize(); return sb.toString(); } private void checkPath(String path) { if (path == null || path.equals("")) throw new IllegalArgumentException("path cannot be null or empty"); if (path.startsWith(delim.str()) || path.endsWith(delim.str()) || path.contains(delim.str() + delim.str())) throw new IllegalArgumentException(String.format("path cannot start or end with %s or contain '%s%s'", delim.str(), delim.str(), delim.str())); } @Override public TreePath clone() throws CloneNotSupportedException { TreePath cloned = new TreePath(this.path, this.delim); while (cloned.nextIndex() != this.nextIndex()) { cloned.next(); } if (cloned.prevIndex() != this.prevIndex()) { cloned.prev(); } cloned.lastStep = this.lastStep; cloned.currKey = new String(this.currKey); cloned.origin = new StringBuilder(this.origin); cloned.remainder = new StringBuilder(this.remainder); return cloned; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TreePath treePath = (TreePath) o; return path().equals(treePath.path()) && hasNext() == treePath.hasNext() && hasPrev() == treePath.hasPrev() && curr().equals(treePath.curr()) && origin().equals(treePath.origin()) && remainder().equals(treePath.remainder()) && lastStep == treePath.lastStep && delim.equals(treePath.delim); } @Override public int hashCode() { int result = path.hashCode(); result = 31 * result + keys.hashCode(); result = 31 * result + keysItr.hashCode(); result = 31 * result + currKey.hashCode(); result = 31 * result + lastStep.hashCode(); result = 31 * result + origin.hashCode(); result = 31 * result + remainder.hashCode(); result = 31 * result + delim.hashCode(); return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy