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.sun.javafx.tools.resource; 27 28 import java.io.File; 29 30 @Deprecated 31 public abstract class DetailedResourceTraversal implements ResourceTraversal { 32 private String lastRelativePath; 33 34 private boolean lastIsDirectory; 35 36 public DetailedResourceTraversal() { 37 lastRelativePath = ""; 38 lastIsDirectory = true; 39 } 40 41 public final boolean traverse(final PackagerResource rootResource, 42 final File file, 43 final String relativePath) { 44 final boolean isDirectory = file.isDirectory(); 45 if (!traverseBetween(lastRelativePath, lastIsDirectory, 46 relativePath, isDirectory)) { 47 return false; 48 } 49 50 lastRelativePath = relativePath; 51 lastIsDirectory = isDirectory; 52 53 return isDirectory ? true 54 : traverseFile(rootResource, file, relativePath); 55 } 56 57 public final void finish() { 58 traverseBetween(lastRelativePath, lastIsDirectory, "", true); 59 60 lastRelativePath = ""; 61 lastIsDirectory = true; 62 } 63 64 protected abstract boolean enterDirectory(String relativePath); 65 66 protected abstract boolean exitDirectory(String relativePath); 67 68 protected abstract boolean traverseFile(PackagerResource rootResource, 69 File file, 70 String relativePath); 71 72 private boolean traverseBetween(final String relPath1, 73 final boolean isDirectory1, 74 final String relPath2, 75 final boolean isDirectory2) { 76 final int commonPathLength = getCommonPathLength(relPath1, relPath2); 77 78 return traverseDown(relPath1, isDirectory1, commonPathLength) 79 && traverseUp(relPath2, isDirectory2, commonPathLength); 80 } 81 82 private boolean traverseDown(final String relPath, 83 final boolean isDirectory, 84 final int commonPathLength) { 85 if (relPath.length() == commonPathLength) { 86 return true; 87 } 88 89 if (isDirectory && !exitDirectory(relPath)) { 90 return false; 91 } 92 93 int prevSeparator = findPrevSeparator(relPath, relPath.length() - 1, 94 commonPathLength); 95 96 while (prevSeparator > commonPathLength) { 97 if (!exitDirectory(relPath.substring(0, prevSeparator))) { 98 return false; 99 } 100 101 prevSeparator = findPrevSeparator(relPath, prevSeparator - 1, 102 commonPathLength); 103 } 104 105 return true; 106 } 107 108 private boolean traverseUp(final String relPath, 109 final boolean isDirectory, 110 final int commonPathLength) { 111 if (relPath.length() == commonPathLength) { 112 return true; 113 } 114 115 final int pathLength = relPath.length(); 116 117 int nextSeparator = findNextSeparator(relPath, commonPathLength + 1, 118 pathLength); 119 120 while (nextSeparator < pathLength) { 121 if (!enterDirectory(relPath.substring(0, nextSeparator))) { 122 return false; 123 } 124 125 nextSeparator = findNextSeparator(relPath, nextSeparator + 1, 126 pathLength); 127 } 128 129 if (isDirectory && !enterDirectory(relPath)) { 130 return false; 131 } 132 133 return true; 134 } 135 136 private static int findPrevSeparator(final String relPath, 137 final int fromIndex, 138 final int minIndex) { 139 final int prevSeparator = relPath.lastIndexOf('/', fromIndex); 140 return (prevSeparator < minIndex) ? minIndex : prevSeparator; 141 } 142 143 private static int findNextSeparator(final String relPath, 144 final int fromIndex, 145 final int maxIndex) { 146 final int nextSeparator = relPath.indexOf('/', fromIndex); 147 return ((nextSeparator == -1) || (nextSeparator > maxIndex)) 148 ? maxIndex : nextSeparator; 149 } 150 151 private static int getCommonPathLength(final String relPath1, 152 final String relPath2) { 153 final char[] path1Chars = relPath1.toCharArray(); 154 final char[] path2Chars = relPath2.toCharArray(); 155 156 int lastMatchIndex = 0; 157 int i; 158 for (i = 0; (i < path1Chars.length) 159 && (i < path2Chars.length) 160 && (path1Chars[i] == path2Chars[i]); ++i) { 161 if (path1Chars[i] == '/') { 162 lastMatchIndex = i; 163 } 164 } 165 166 if (i == path1Chars.length) { 167 if ((i == path2Chars.length) || (path2Chars[i] == '/')) { 168 lastMatchIndex = i; 169 } 170 } else if ((i == path2Chars.length) && (path1Chars[i] == '/')) { 171 lastMatchIndex = i; 172 } 173 174 return lastMatchIndex; 175 } 176 }