Stefano Lenzi | 476013d | 2007-09-21 23:59:54 +0000 | [diff] [blame] | 1 | /*
|
| 2 | * Licensed to the Apache Software Foundation (ASF) under one
|
| 3 | * or more contributor license agreements. See the NOTICE file
|
| 4 | * distributed with this work for additional information
|
| 5 | * regarding copyright ownership. The ASF licenses this file
|
| 6 | * to you under the Apache License, Version 2.0 (the
|
| 7 | * "License"); you may not use this file except in compliance
|
| 8 | * with the License. You may obtain a copy of the License at
|
| 9 | *
|
| 10 | * http://www.apache.org/licenses/LICENSE-2.0
|
| 11 | *
|
| 12 | * Unless required by applicable law or agreed to in writing,
|
| 13 | * software distributed under the License is distributed on an
|
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
| 15 | * KIND, either express or implied. See the License for the
|
| 16 | * specific language governing permissions and limitations
|
| 17 | * under the License.
|
| 18 | */
|
| 19 | package org.apache.felix.sandbox.obr.plugin;
|
| 20 |
|
| 21 | import java.io.File;
|
| 22 | import java.io.FileInputStream;
|
| 23 | import java.io.FileOutputStream;
|
| 24 | import java.io.IOException;
|
| 25 | import java.net.URI;
|
| 26 | import java.net.URISyntaxException;
|
| 27 | import java.nio.channels.FileChannel;
|
| 28 |
|
| 29 | /**
|
| 30 | * this class provide some functions to simplify file manipulation.
|
| 31 | * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
|
| 32 | */
|
| 33 | public class PathFile {
|
| 34 |
|
| 35 | /**
|
| 36 | * full filename.
|
| 37 | */
|
| 38 | private String m_fullFilename;
|
| 39 |
|
| 40 | /**
|
| 41 | * store only the filename of the file.
|
| 42 | */
|
| 43 | private String m_fileName;
|
| 44 |
|
| 45 | /**
|
| 46 | * store only the path of this file.
|
| 47 | */
|
| 48 | private String m_pathFile;
|
| 49 |
|
| 50 | /**
|
| 51 | * store the base Directory in case of relative path.
|
| 52 | */
|
| 53 | private String m_baseDir;
|
| 54 |
|
| 55 | /**
|
| 56 | * store the protocol used (ie:file, http...).
|
| 57 | */
|
| 58 | private String m_protocol;
|
| 59 |
|
| 60 | /**
|
| 61 | * if the path is relative or absolute.
|
| 62 | */
|
| 63 | private boolean m_relative;
|
| 64 |
|
| 65 | /**
|
| 66 | * if this file is a folder.
|
| 67 | */
|
| 68 | private boolean m_folder;
|
| 69 |
|
| 70 | /**
|
| 71 | * if the file exist or not.
|
| 72 | */
|
| 73 | private boolean m_exist;
|
| 74 |
|
| 75 | /**
|
| 76 | * if this file is a file (not a folder).
|
| 77 | */
|
| 78 | private boolean m_file;
|
| 79 |
|
| 80 | /**
|
| 81 | * if this filename is valid or incomplete.
|
| 82 | */
|
| 83 | private boolean m_valid;
|
| 84 |
|
| 85 | /**
|
| 86 | * build all the attribute information.
|
| 87 | * @param filename path to the file
|
| 88 | */
|
| 89 | public PathFile(String filename) {
|
| 90 |
|
| 91 | this.m_fullFilename = filename;
|
| 92 | if (filename == null) {
|
| 93 | this.m_valid = false;
|
| 94 | return;
|
| 95 | }
|
| 96 | this.m_valid = true;
|
| 97 | m_protocol = extractProtocol(filename);
|
| 98 | m_pathFile = extractPathFile(filename);
|
| 99 | if (m_pathFile.startsWith("//")) {
|
| 100 | // avoid problems on Unix like system
|
| 101 | m_pathFile = m_pathFile.substring(1);
|
| 102 | }
|
| 103 | m_fileName = extractFileName(filename);
|
| 104 | m_relative = extractRelative();
|
| 105 | if (!m_relative && (getProtocol().compareTo("file") == 0 || getProtocol().compareTo("") == 0)) {
|
| 106 | File f = new File(getOnlyAbsoluteFilename());
|
| 107 | m_file = f.isFile();
|
| 108 | m_folder = f.isDirectory();
|
| 109 | m_exist = f.exists();
|
| 110 | if (m_folder) {
|
| 111 | m_pathFile = m_pathFile + m_fileName + File.separator;
|
| 112 | m_fileName = "";
|
| 113 | }
|
| 114 | }
|
| 115 | if (m_exist) {
|
| 116 | m_protocol = "file";
|
| 117 | } else {
|
| 118 | if (m_fileName.compareTo("") == 0) {
|
| 119 | m_folder = true;
|
| 120 | m_file = false;
|
| 121 | } else {
|
| 122 | m_folder = false;
|
| 123 | m_file = true;
|
| 124 | }
|
| 125 |
|
| 126 | }
|
| 127 |
|
| 128 | // add the '/' before the complete path if it is absolute path
|
| 129 | if (!this.isRelative() && !m_pathFile.startsWith("/")) { m_pathFile = "/".concat(m_pathFile); }
|
| 130 |
|
| 131 | }
|
| 132 |
|
| 133 | /**
|
| 134 | * get if the filename is relative or absolute.
|
| 135 | * @return true if the path is relative, else false
|
| 136 | */
|
| 137 | private boolean extractRelative() {
|
| 138 | if (m_pathFile.startsWith("." + File.separator, 1) || m_pathFile.startsWith(".." + File.separator, 1)) {
|
| 139 | m_pathFile = m_pathFile.substring(1);
|
| 140 | m_valid = false;
|
| 141 | return true;
|
| 142 | }
|
| 143 |
|
| 144 | return false;
|
| 145 | }
|
| 146 |
|
| 147 | /**
|
| 148 | * get only the name from the filname.
|
| 149 | * @param fullFilename full filename
|
| 150 | * @return the name of the file or folder
|
| 151 | */
|
| 152 | private String extractFileName(String fullFilename) {
|
| 153 | int index = fullFilename.lastIndexOf(File.separator);
|
| 154 | return fullFilename.substring(index + 1, fullFilename.length());
|
| 155 | }
|
| 156 |
|
| 157 | /**
|
| 158 | * get the path form the filename.
|
| 159 | * @param fullFilename full filename
|
| 160 | * @return the path of the file
|
| 161 | */
|
| 162 | private String extractPathFile(String fullFilename) {
|
| 163 | String substring;
|
| 164 | if (extractFileName(fullFilename).compareTo("") == 0) {
|
| 165 | // it is a folder
|
| 166 | substring = fullFilename;
|
| 167 | } else {
|
| 168 | substring = fullFilename.substring(0, fullFilename.indexOf(extractFileName(fullFilename)));
|
| 169 | }
|
| 170 |
|
| 171 | if (getProtocol().compareTo("") != 0) {
|
| 172 | substring = substring.substring(5);
|
| 173 | }
|
| 174 |
|
| 175 | return substring;
|
| 176 | }
|
| 177 |
|
| 178 | /**
|
| 179 | * determine which protocol is used.
|
| 180 | * @param filename the full fileneme
|
| 181 | * @return "file" or "http" or ""
|
| 182 | */
|
| 183 | private String extractProtocol(String filename) {
|
| 184 | if (filename.startsWith("file:")) { return "file"; }
|
| 185 | if (filename.startsWith("http:")) { return "http"; }
|
| 186 | return "";
|
| 187 | }
|
| 188 |
|
| 189 | /**
|
| 190 | * set the base directory.
|
| 191 | * @param baseDir new value for the base directory
|
| 192 | */
|
| 193 | public void setBaseDir(String baseDir) {
|
| 194 | this.m_baseDir = baseDir;
|
| 195 | if (isRelative() && this.m_fullFilename != null) {
|
| 196 | this.m_valid = true;
|
| 197 | if (getProtocol().compareTo("file") == 0 || getProtocol().compareTo("") == 0) {
|
| 198 | File f = new File(getOnlyAbsoluteFilename());
|
| 199 | m_file = f.isFile();
|
| 200 | m_folder = f.isDirectory();
|
| 201 | m_exist = f.exists();
|
| 202 | }
|
| 203 | if (m_exist) {
|
| 204 | m_protocol = "file";
|
| 205 | }
|
| 206 | }
|
| 207 |
|
| 208 | }
|
| 209 |
|
| 210 | /**
|
| 211 | * get the base directory.
|
| 212 | * @return base directory
|
| 213 | */
|
| 214 | public String getBaseDir() {
|
| 215 | return this.m_baseDir;
|
| 216 | }
|
| 217 |
|
| 218 | public boolean isValid() {
|
| 219 | return m_valid;
|
| 220 | }
|
| 221 |
|
| 222 | public boolean isRelative() {
|
| 223 | return m_relative;
|
| 224 | }
|
| 225 |
|
| 226 | public boolean isExists() {
|
| 227 | return m_exist;
|
| 228 | }
|
| 229 |
|
| 230 | public boolean isFile() {
|
| 231 | return m_file;
|
| 232 | }
|
| 233 |
|
| 234 | public boolean isFolder() {
|
| 235 | return m_folder;
|
| 236 | }
|
| 237 |
|
| 238 | /**
|
| 239 | * get a File which points on the same file.
|
| 240 | * @return a File object
|
| 241 | */
|
| 242 | public File getFile() {
|
| 243 | if (!this.isValid()) { return null; }
|
| 244 | String path = PathFile.uniformSeparator(this.getOnlyAbsoluteFilename());
|
| 245 | if (File.separatorChar == '\\') { path = path.replace('\\', '/'); }
|
| 246 | File f = new File(path);
|
| 247 | return f;
|
| 248 | }
|
| 249 |
|
| 250 | /**
|
| 251 | * get an URI which points on the same file.
|
| 252 | * @return an URI object
|
| 253 | */
|
| 254 | public URI getUri() {
|
| 255 | if (!this.isValid()) { return null; }
|
| 256 | String path = PathFile.uniformSeparator(getAbsoluteFilename());
|
| 257 | if (File.separatorChar == '\\') {
|
Stuart McCulloch | bfc05cf | 2007-09-26 15:34:00 +0000 | [diff] [blame] | 258 | path = path.replace('\\', '/');
|
| 259 | path = path.replaceAll(" ", "%20");
|
Stefano Lenzi | 476013d | 2007-09-21 23:59:54 +0000 | [diff] [blame] | 260 | }
|
| 261 |
|
| 262 | URI uri = null;
|
| 263 | try {
|
| 264 | uri = new URI(path);
|
| 265 | } catch (URISyntaxException e) {
|
| 266 | System.err.println("Malformed URI: " + path);
|
| 267 | System.err.println(e.getMessage());
|
| 268 | return null;
|
| 269 | }
|
| 270 | return uri;
|
| 271 | }
|
| 272 |
|
| 273 | /**
|
| 274 | * get protocol + relative path of this file.
|
| 275 | * @return the relative path or null if it is not valid
|
| 276 | */
|
| 277 | public String getRelativePath() {
|
| 278 | if (!this.isValid()) { return null; }
|
| 279 |
|
| 280 | return getProtocol() + ":/" + getOnlyRelativePath();
|
| 281 | }
|
| 282 |
|
| 283 | /**
|
| 284 | * get only (without protocol) relative path of this file.
|
| 285 | * @return the relative path or null if it is not valid
|
| 286 | */
|
| 287 | public String getOnlyRelativePath() {
|
| 288 | if (!this.isValid()) { return null; }
|
| 289 | if (this.isRelative()) {
|
| 290 | return m_pathFile;
|
| 291 |
|
| 292 | } else {
|
| 293 | if (m_baseDir != null) {
|
| 294 | // System.err.println(m_pathFile);
|
| 295 | // System.err.println(m_baseDir);
|
| 296 | if (m_pathFile.startsWith(m_baseDir)) {
|
| 297 | /*
|
| 298 | * String ch1 = m_pathFile; String ch2 = m_baseDir; System.err.println(ch1); System.err.println(ch2); System.err.println("."+File.separator+ch1.substring(ch2.length()));
|
| 299 | */
|
| 300 | return "." + File.separator + m_pathFile.substring(m_baseDir.length());
|
| 301 | }
|
| 302 | }
|
| 303 | return null;
|
| 304 | }
|
| 305 | }
|
| 306 |
|
| 307 | /**
|
| 308 | * calcul absolute path from relative path.
|
| 309 | * @param baseDir base directory
|
| 310 | * @param path path to convert
|
| 311 | * @return the absolute path or null
|
| 312 | */
|
| 313 | private String calculAbsolutePath(String baseDir, String path) {
|
| 314 | if (path.startsWith(".." + File.separatorChar)) {
|
| 315 | String base = baseDir;
|
| 316 | int lastIndex;
|
| 317 | lastIndex = base.lastIndexOf(File.separator);
|
| 318 | if (lastIndex == base.length()) {
|
| 319 | base = base.substring(0, base.length() - 1);
|
| 320 | lastIndex = base.lastIndexOf(File.separator);
|
| 321 | }
|
| 322 | if (lastIndex < base.length()) {
|
| 323 | return calculAbsolutePath(base.substring(0, lastIndex + 1), path.substring(3));
|
| 324 | } else {
|
| 325 | return null;
|
| 326 | }
|
| 327 | } else if (path.startsWith("." + File.separatorChar)) {
|
| 328 | String res;
|
| 329 | if (File.separatorChar == '\\') {
|
| 330 | res = path.replaceFirst(".", baseDir.replace('\\', '/'));
|
| 331 | } else {
|
| 332 | res = path.replaceFirst(".", baseDir);
|
| 333 | }
|
| 334 |
|
| 335 | return PathFile.uniformSeparator(res);
|
| 336 | } else {
|
| 337 | return PathFile.uniformSeparator(baseDir + path);
|
| 338 | }
|
| 339 | }
|
| 340 |
|
| 341 | /**
|
| 342 | * get only (without protocol) absolute path (without filename).
|
| 343 | * @return absolute path
|
| 344 | */
|
| 345 | public String getOnlyAbsolutePath() {
|
| 346 | if (!this.isValid()) { return null; }
|
| 347 | if (isRelative()) {
|
| 348 | return calculAbsolutePath(m_baseDir, m_pathFile);
|
| 349 | } else {
|
| 350 | return m_pathFile;
|
| 351 | }
|
| 352 | }
|
| 353 |
|
| 354 | /**
|
| 355 | * get protocol + absolute path (without filename).
|
| 356 | * @return absolute path
|
| 357 | */
|
| 358 | public String getAbsolutePath() {
|
| 359 |
|
| 360 | if (isRelative()) {
|
| 361 | return getProtocol() + ":/" + calculAbsolutePath(m_baseDir, m_pathFile);
|
| 362 | } else {
|
| 363 | if (getProtocol().compareTo("") == 0 || m_pathFile == null) {
|
| 364 | return m_pathFile;
|
| 365 | } else {
|
| 366 | return getProtocol() + ":" + m_pathFile;
|
| 367 | }
|
| 368 | }
|
| 369 | }
|
| 370 |
|
| 371 | /**
|
| 372 | * get only (without protocol) absolute path + filename.
|
| 373 | * @return absolute filename
|
| 374 | */
|
| 375 | public String getOnlyAbsoluteFilename() {
|
| 376 | if (getOnlyAbsolutePath() != null && getFilename() != null) {
|
| 377 | return getOnlyAbsolutePath() + getFilename();
|
| 378 | } else {
|
| 379 | return null;
|
| 380 | }
|
| 381 | }
|
| 382 |
|
| 383 | /**
|
| 384 | * get protocol + absolute path + filename.
|
| 385 | * @return absolute filenama
|
| 386 | */
|
| 387 | public String getAbsoluteFilename() {
|
| 388 | if (getAbsolutePath() != null && getFilename() != null) {
|
| 389 | return getAbsolutePath() + getFilename();
|
| 390 | } else {
|
| 391 | return null;
|
| 392 | }
|
| 393 | }
|
| 394 |
|
| 395 | /**
|
| 396 | * get only (without protocol) relative path + filename.
|
| 397 | * @return relative filename
|
| 398 | */
|
| 399 | public String getOnlyRelativeFilename() {
|
| 400 | if (!this.isValid()) { return ""; }
|
| 401 |
|
| 402 | return getOnlyRelativePath() + getFilename();
|
| 403 |
|
| 404 | }
|
| 405 |
|
| 406 | /**
|
| 407 | * get protocol + relative path + filename.
|
| 408 | * @return relative filename
|
| 409 | */
|
| 410 | public String getRelativeFilename() {
|
| 411 | if (!this.isValid()) { return ""; }
|
| 412 |
|
| 413 | if (this.isRelative()) {
|
| 414 | return getRelativePath() + getFilename();
|
| 415 | } else {
|
| 416 | return getAbsoluteFilename();
|
| 417 | }
|
| 418 | }
|
| 419 |
|
| 420 | public String getFilename() {
|
| 421 | return m_fileName;
|
| 422 | }
|
| 423 |
|
| 424 | public String getProtocol() {
|
| 425 | return m_protocol;
|
| 426 | }
|
| 427 |
|
| 428 | /**
|
| 429 | * create all the directories not also present in the current path.
|
| 430 | * @return true if all directories was created, else false
|
| 431 | */
|
| 432 | public boolean createPath() {
|
| 433 | File path = new File(this.getOnlyAbsolutePath());
|
| 434 | if (path.exists()) { return true; }
|
| 435 | return path.mkdirs();
|
| 436 | }
|
| 437 |
|
| 438 | /**
|
| 439 | * create all the directories not also present in the current path and the file.
|
| 440 | * @return true it was created, else false
|
| 441 | */
|
| 442 | public boolean createFile() {
|
| 443 | File path = new File(this.getOnlyAbsolutePath());
|
| 444 | if (!path.exists()) {
|
| 445 | if (!this.createPath()) { return false; }
|
| 446 | }
|
| 447 | path = new File(this.getOnlyAbsoluteFilename());
|
| 448 | try {
|
| 449 | return path.createNewFile();
|
| 450 | } catch (IOException e) {
|
| 451 | return false;
|
| 452 | }
|
| 453 |
|
| 454 | }
|
| 455 |
|
| 456 | /**
|
| 457 | * delete the current file.
|
| 458 | * @return true if it was deleted, else false
|
| 459 | */
|
| 460 | public boolean delete() {
|
| 461 | File path = new File(this.getAbsoluteFilename());
|
| 462 | if (path.exists()) {
|
| 463 | return path.delete();
|
| 464 | } else {
|
| 465 | return true;
|
| 466 | }
|
| 467 |
|
| 468 | }
|
| 469 |
|
Stuart McCulloch | bfc05cf | 2007-09-26 15:34:00 +0000 | [diff] [blame] | 470 | private static final String REGEXP_BACKSLASH = "\\\\";
|
| 471 |
|
Stefano Lenzi | 476013d | 2007-09-21 23:59:54 +0000 | [diff] [blame] | 472 | /**
|
| 473 | * replace all '\' by '\\' in the given string.
|
| 474 | * @param path string where replace the search pattern
|
| 475 | * @return string replaced
|
| 476 | */
|
| 477 | public static String doubleSeparator(String path) {
|
| 478 | // double the '\' in the path
|
| 479 | if (path != null && File.separatorChar == '\\') {
|
Stuart McCulloch | bfc05cf | 2007-09-26 15:34:00 +0000 | [diff] [blame] | 480 | return path.replaceAll(REGEXP_BACKSLASH, REGEXP_BACKSLASH + REGEXP_BACKSLASH);
|
Stefano Lenzi | 476013d | 2007-09-21 23:59:54 +0000 | [diff] [blame] | 481 | } else {
|
| 482 | return null;
|
| 483 | }
|
| 484 | }
|
| 485 |
|
| 486 | /**
|
| 487 | * file separator('\' or '/') by the one of the current system.
|
| 488 | * @param path string where replace the search pattern
|
| 489 | * @return string replaced
|
| 490 | */
|
| 491 | public static String uniformSeparator(String path) {
|
| 492 | if (File.separatorChar == '\\') {
|
| 493 | if (path.startsWith("/")) {
|
| 494 | return path.substring(1).replace('/', File.separatorChar);
|
| 495 | } else {
|
| 496 | return path.replace('/', File.separatorChar);
|
| 497 | }
|
| 498 | } else {
|
| 499 | return path.replace('\\', File.separatorChar);
|
| 500 | }
|
| 501 | }
|
| 502 |
|
| 503 | /**
|
| 504 | * copy file from src to dest.
|
| 505 | * @param src source file
|
| 506 | * @param dest destination file
|
| 507 | * @return true if the file was correctly copied, else false
|
| 508 | */
|
| 509 | public static boolean copyFile(PathFile src, PathFile dest) {
|
| 510 | FileChannel in = null;
|
| 511 | FileChannel out = null;
|
| 512 |
|
| 513 | if (!src.isExists()) {
|
| 514 | System.err.println("src file must exist: " + src.getAbsoluteFilename());
|
| 515 | return false;
|
| 516 | }
|
| 517 | if (!dest.isExists()) {
|
| 518 | dest.createFile();
|
| 519 | }
|
| 520 | try {
|
| 521 | in = new FileInputStream(src.getOnlyAbsoluteFilename()).getChannel();
|
| 522 | out = new FileOutputStream(dest.getOnlyAbsoluteFilename()).getChannel();
|
| 523 |
|
| 524 | in.transferTo(0, in.size(), out);
|
| 525 | } catch (Exception e) {
|
| 526 | e.printStackTrace();
|
| 527 | } finally {
|
| 528 | if (in != null) {
|
| 529 | try {
|
| 530 | in.close();
|
| 531 | } catch (IOException e) {
|
| 532 | return false;
|
| 533 | }
|
| 534 | }
|
| 535 | if (out != null) {
|
| 536 | try {
|
| 537 | out.close();
|
| 538 | } catch (IOException e) {
|
| 539 | return false;
|
| 540 | }
|
| 541 | }
|
| 542 | }
|
| 543 | return true;
|
| 544 | }
|
| 545 |
|
| 546 | }
|