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