org.mp4parser.tools.Path Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of isoparser Show documentation
Show all versions of isoparser Show documentation
A generic parser and writer for all ISO 14496 based files (MP4, Quicktime, DCF, PDCF, ...)
/*
* Copyright 2012 Sebastian Annies, Hamburg
*
* 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.mp4parser.tools;
import org.mp4parser.Box;
import org.mp4parser.Container;
import org.mp4parser.ParsableBox;
import org.mp4parser.support.AbstractContainerBox;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Path {
static Pattern component = Pattern.compile("(....|\\.\\.)(\\[(.*)\\])?");
private Path() {
}
public static T getPath(Box parsableBox, String path) {
List all = getPaths(parsableBox, path, true);
return all.isEmpty() ? null : all.get(0);
}
public static T getPath(Container container, String path) {
List all = getPaths(container, path, true);
return all.isEmpty() ? null : all.get(0);
}
public static T getPath(AbstractContainerBox containerBox, String path) {
List all = getPaths(containerBox, path, true);
return all.isEmpty() ? null : all.get(0);
}
public static List getPaths(Box box, String path) {
return getPaths(box, path, false);
}
public static List getPaths(Container container, String path) {
return getPaths(container, path, false);
}
private static List getPaths(AbstractContainerBox container, String path, boolean singleResult) {
return getPaths((Object) container, path, singleResult);
}
private static List getPaths(Container container, String path, boolean singleResult) {
return getPaths((Object) container, path, singleResult);
}
private static List getPaths(ParsableBox parsableBox, String path, boolean singleResult) {
return getPaths((Object) parsableBox, path, singleResult);
}
@SuppressWarnings("unchecked")
private static List getPaths(Object thing, String path, boolean singleResult) {
if (path.startsWith("/")) {
throw new RuntimeException("Cannot start at / - only relative path expression into the structure are allowed");
}
if (path.length() == 0) {
if (thing instanceof ParsableBox) {
return Collections.singletonList((T) thing);
} else {
throw new RuntimeException("Result of path expression seems to be the root container. This is not allowed!");
}
} else {
String later;
String now;
if (path.contains("/")) {
later = path.substring(path.indexOf('/') + 1);
now = path.substring(0, path.indexOf('/'));
} else {
now = path;
later = "";
}
Matcher m = component.matcher(now);
if (m.matches()) {
String type = m.group(1);
if ("..".equals(type)) {
throw new RuntimeException(".. notation no longer allowed");
} else {
if (thing instanceof Container) {
int index = -1;
if (m.group(2) != null) {
// we have a specific index
String indexString = m.group(3);
index = Integer.parseInt(indexString);
}
List children = new LinkedList();
int currentIndex = 0;
// I'm suspecting some Dalvik VM to create indexed loops from for-each loops
// using the iterator instead makes sure that this doesn't happen
// (and yes - it could be completely useless)
Iterator iterator = ((Container) thing).getBoxes().iterator();
while (iterator.hasNext()) {
Box box1 = iterator.next();
if (box1.getType().matches(type)) {
if (index == -1 || index == currentIndex) {
children.addAll(Path.getPaths(box1, later, singleResult));
}
currentIndex++;
}
if ((singleResult || index >= 0) && !children.isEmpty()) {
return children;
}
}
return children;
} else {
return Collections.emptyList();
}
}
} else {
throw new RuntimeException(now + " is invalid path.");
}
}
}
public static boolean isContained(Container ref, Box box, String path) {
return getPaths(ref, path).contains(box);
}
}