/*
*
* * Copyright (c) 2016. David Sowerby
* *
* * 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 uk.q3c.krail.core.navigate;
import java.util.Stack;
/**
* Utility class used in decoding the structure of the [map] section of the Sitemap
*
* @author David Sowerby 3 Jul 2013
*/
public class URITracker {
private final Stack<String> stack = new Stack<>();
/**
* From the previous uri, attaches the {@code segment} at the {@code indent} level. If there is no previous uri,
* {@code segment is taken to be a root segment}. There are three conditions
* <ol>
* <li>indent is greater than current indent level. {@code segment} is appended to the current uri
* <li>indent is less than current level. {@code segment} is appended to the current uri, but at a level which puts
* {@code segment} at the correct {@code indent} level.
* <li>indent is the same as the current indent level. segment is attached to the parent of the current last
* segment, or if the current segment is a root, then the new segment becomes the new root <br>
* <br>
* indent starts at 1 (that is, root is at indent 1). An indent level of < 1 is set to 1
*
* @param indent
* @param segment
*
* @return
*/
public String track(int indent, String segment) {
if (indent < 1) {
indent = 1;
}
int currentIndent = stack.size();
if (indent > currentIndent) {
// append to current uri
stack.push(segment);
return uri();
}
if (indent == currentIndent) {
// append to last but one segment
// or replace existing root if indent==1
stack.pop();
stack.push(segment);
return uri();
}
// walk back to one less than required indent and attach segment there
while (stack.size() > (indent - 1)) {
stack.pop();
}
stack.push(segment);
return uri();
}
/**
* builds URI from stack
*
* @return
*/
public String uri() {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < stack.size(); i++) {
if (i != 0) {
buf.append('/');
}
buf.append(stack.get(i));
}
return buf.toString();
}
}