1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/* 2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Copyright 2012 Sebastian Annies, Hamburg 3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the License); 5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * you may not use this file except in compliance with the License. 6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * You may obtain a copy of the License at 7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * distributed under the License is distributed on an AS IS BASIS, 12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * See the License for the specific language governing permissions and 14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * limitations under the License. 15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.googlecode.mp4parser.util; 17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoFile; 20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.Box; 21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.ContainerBox; 22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Collections; 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.LinkedList; 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.List; 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.regex.Matcher; 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.regex.Pattern; 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class Path { 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private Path() { 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu static Pattern component = Pattern.compile("(....|\\.\\.)(\\[(.*)\\])?"); 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static String createPath(Box box) { 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return createPath(box, ""); 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static String createPath(Box box, String path) { 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (box instanceof IsoFile) { 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return path; 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<?> boxesOfBoxType = box.getParent().getBoxes(box.getClass()); 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int index = boxesOfBoxType.indexOf(box); 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu path = String.format("/%s[%d]", box.getType(), index) + path; 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return createPath(box.getParent(), path); 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static Box getPath(Box box, String path) { 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<Box> all = getPaths(box, path); 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return all.isEmpty() ? null : all.get(0); 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static List<Box> getPaths(Box box, String path) { 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (path.startsWith("/")) { 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu Box isoFile = box; 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (isoFile.getParent() != null) { 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu isoFile = isoFile.getParent(); 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu assert isoFile instanceof IsoFile : isoFile.getType() + " has no parent"; 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return getPaths(isoFile, path.substring(1)); 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else if (path.isEmpty()) { 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return Collections.singletonList(box); 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String later; 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String now; 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (path.contains("/")) { 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu later = path.substring(path.indexOf('/') + 1); 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu now = path.substring(0, path.indexOf('/')); 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu now = path; 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu later = ""; 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu Matcher m = component.matcher(now); 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (m.matches()) { 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String type = m.group(1); 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ("..".equals(type)) { 83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return getPaths(box.getParent(), later); 84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int index = -1; 86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (m.group(2) != null) { 87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu // we have a specific index 88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String indexString = m.group(3); 89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu index = Integer.parseInt(indexString); 90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<Box> children = new LinkedList<Box>(); 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int currentIndex = 0; 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (Box box1 : ((ContainerBox) box).getBoxes()) { 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (box1.getType().matches(type)) { 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (index == -1 || index == currentIndex) { 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu children.addAll(getPaths(box1, later)); 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu currentIndex++; 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return children; 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new RuntimeException(now + " is invalid path."); 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static boolean isContained(Box box, String path) { 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu assert path.startsWith("/") : "Absolute path required"; 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return getPaths(box, path).contains(box); 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu} 116