1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.oracle.ipack.util;
  27 
  28 import java.io.File;
  29 
  30 public final class ResourceDescriptor {
  31     private final File baseDir;
  32     private final File file;
  33     private final String relativePath;
  34 
  35     public ResourceDescriptor(final File baseDir, final String path) {
  36         this(baseDir, createFile(baseDir, path));
  37     }
  38 
  39     public ResourceDescriptor(final File baseDir, final File file) {
  40         final File nrmFile = normalizeFile(file);
  41         if (nrmFile == null) {
  42             throw new IllegalArgumentException("Invalid file specified");
  43         }
  44 
  45         if (baseDir != null) {
  46             final File nrmBaseDir = normalizeFile(baseDir);
  47             if (nrmBaseDir == null) {
  48                 throw new IllegalArgumentException("Invalid basedir specified");
  49             }
  50 
  51             if (nrmFile.equals(nrmBaseDir)) {
  52                 this.file = nrmFile;
  53                 this.baseDir = nrmFile;
  54                 this.relativePath = "";
  55                 return;
  56             }
  57 
  58             final StringBuilder relativePathBuilder =
  59                     new StringBuilder(nrmFile.getName());
  60 
  61             File tempFile = nrmFile.getParentFile();
  62             while (tempFile != null) {
  63                 if (tempFile.equals(nrmBaseDir)) {
  64                     this.file = nrmFile;
  65                     this.baseDir = nrmBaseDir;
  66                     this.relativePath = relativePathBuilder.toString();
  67                     return;
  68                 }
  69 
  70                 relativePathBuilder.insert(0, '/');
  71                 relativePathBuilder.insert(0, tempFile.getName());
  72                 tempFile = tempFile.getParentFile();
  73             }
  74         }
  75 
  76         final File nrmParentFile = nrmFile.getParentFile();
  77 
  78         this.file = nrmFile;
  79         this.baseDir = (nrmParentFile != null) ? nrmParentFile : nrmFile;
  80         this.relativePath = nrmFile.getName();
  81     }
  82 
  83     public File getBaseDir() {
  84         return baseDir;
  85     }
  86 
  87     public File getFile() {
  88         return file;
  89     }
  90 
  91     public String getRelativePath() {
  92         return relativePath;
  93     }
  94 
  95     private static File normalizeFile(final File inputFile) {
  96         return normalizeFileImpl(inputFile.getAbsoluteFile());
  97     }
  98 
  99     private static File normalizeFileImpl(final File inputFile) {
 100         if (inputFile.getParentFile() == null) {
 101             return inputFile;
 102         }
 103 
 104         final File partiallyNormalizedFile =
 105                 normalizeFileImpl(inputFile.getParentFile());
 106 
 107         if (partiallyNormalizedFile == null) {
 108             // error
 109             return null;
 110         }
 111 
 112         final String fileName = inputFile.getName();
 113 
 114         if (fileName.equals(".")) {
 115             // ignore this path element
 116             return partiallyNormalizedFile;
 117         }
 118 
 119         if (fileName.equals("..")) {
 120             // remove the last path element
 121             return partiallyNormalizedFile.getParentFile();
 122         }
 123 
 124         return new File(partiallyNormalizedFile, fileName);
 125     }
 126 
 127     private static File createFile(final File baseDir, final String path) {
 128         final File testFile = new File(path);
 129         return testFile.isAbsolute()
 130                    ? testFile
 131                    : new File(baseDir == null
 132                                   ? null
 133                                   : baseDir.getAbsolutePath(),
 134                               path);
 135     }
 136 }