Gridarta Editor
PathManagerUtils.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.model.io;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.regex.Pattern;
26 import org.jetbrains.annotations.NotNull;
27 
32 public class PathManagerUtils {
33 
37  @NotNull
38  private static final Pattern PATTERN_REDUNDANT = Pattern.compile("[^/]+/\\.\\./");
39 
43  @NotNull
44  private static final Pattern PATTERN_SLASHES = Pattern.compile("//*");
45 
49  private PathManagerUtils() {
50  }
51 
58  @NotNull
59  public static String getMapPath(@NotNull final File file, @NotNull final File baseDir) {
60  @NotNull final String mapDirName = baseDir.getPath();
61  String mapPath = file.getPath().replace('\\', '/');
62  if (mapPath.startsWith(mapDirName)) {
63  mapPath = mapPath.substring(mapDirName.length());
64  }
65  if (mapPath.startsWith(new File(mapDirName).getAbsolutePath())) {
66  mapPath = mapPath.substring(new File(mapDirName).getAbsolutePath().length());
67  }
68  try {
69  if (mapPath.startsWith(new File(mapDirName).getCanonicalPath())) {
70  mapPath = mapPath.substring(new File(mapDirName).getCanonicalPath().length());
71  }
72  } catch (final IOException ignored) {
73  // ignore
74  }
75  mapPath = mapPath.replace('\\', '/');
76  return mapPath;
77  }
78 
87  public static boolean isAbsolute(@NotNull final String path) {
88  return path.startsWith("/") || new File(path).isAbsolute();
89  }
90 
98  public static boolean isRelative(@NotNull final String path) {
99  return !path.startsWith("/") && !new File(path).isAbsolute();
100  }
101 
111  @NotNull
112  public static String relativeToAbsolute(@NotNull final String reference, @NotNull final String relative) {
113  final String normalizedReference = reference.replace('\\', '/');
114  final String normalizedRelative = relative.replace('\\', '/');
115  if (isAbsolute(normalizedRelative)) {
116  return normalizedRelative;
117  }
118  String work = normalizedReference.substring(0, normalizedReference.lastIndexOf('/') + 1) + normalizedRelative; // + 1 to include the "/"
119  String work2;
120  do {
121  work2 = work;
122  work = PATTERN_REDUNDANT.matcher(work2).replaceAll("");
123  } while (!work2.equals(work));
124  return work;
125  }
126 
136  @NotNull
137  public static String absoluteToRelative(@NotNull final String reference, @NotNull final String absolute) {
138  final String normalizedReference = reference.replace('\\', '/');
139  final String normalizedAbsolute = absolute.replace('\\', '/');
140  if (isRelative(normalizedAbsolute)) {
141  return normalizedAbsolute;
142  }
143  //String reference2 =
144  // First: Strip equal path parts
145  final int difference = findDifference(normalizedReference, normalizedAbsolute);
146  final StringBuilder relative = new StringBuilder(normalizedAbsolute.substring(difference));
147  final CharSequence referencePath = normalizedReference.substring(difference);
148  for (int i = 0, l = findOccurrences(referencePath, '/'); i < l; i++) {
149  relative.insert(0, "../");
150  }
151  return relative.toString();
152  }
153 
164  private static int findDifference(@NotNull final CharSequence s1, @NotNull final CharSequence s2) {
165  int s1slash = -1;
166  int s2slash = -1;
167  char c1 = (char) 0; // initialize for equality for first loop cycle
168  char c2 = (char) 0;
169  for (int index = 0, l1 = s1.length(), l2 = s2.length(); index < l1 && index < l2 && c1 == c2; index++) {
170  c1 = s1.charAt(index);
171  c2 = s2.charAt(index);
172  if (c1 == '/') {
173  s1slash = index;
174  }
175  if (c2 == '/') {
176  s2slash = index;
177  }
178  }
179  return Math.min(s1slash, s2slash) + 1;
180  }
181 
188  private static int findOccurrences(@NotNull final CharSequence s, final char c) {
189  int occurrences = 0;
190  for (int i = 0, l = s.length(); i < l; i++) {
191  if (s.charAt(i) == c) {
192  occurrences++;
193  }
194  }
195  return occurrences;
196  }
197 
203  @NotNull
204  public static String path(@NotNull final CharSequence str) {
205  String path = StringUtils.PATTERN_BACKSLASH.matcher(str).replaceAll("/");
206  path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
207  path = path.startsWith("file:") ? path.substring("file:".length()) : path;
208  path = PATTERN_SLASHES.matcher(path).replaceAll("/");
209  return path;
210  }
211 
217  @NotNull
218  public static String getAbsolutePath(@NotNull final CharSequence path) {
219  return relativeToAbsolute(System.getProperty("user.dir") + "/dummy", path(path));
220  }
221 
222 }
Utility class for string manipulation.
static String path(@NotNull final CharSequence str)
Create a reasonable path.
Utility class for converting relative map paths to absolute map paths and vice versa.
static int findDifference(@NotNull final CharSequence s1, @NotNull final CharSequence s2)
Helper method that returns the first string index at which two strings denoting paths aren&#39;t identica...
static String relativeToAbsolute(@NotNull final String reference, @NotNull final String relative)
Converts a relative path to an absolute path.
Base package of all Gridarta classes.
static final Pattern PATTERN_REDUNDANT
A Pattern that matches redundant directory parts like "dir/../".
static String getAbsolutePath(@NotNull final CharSequence path)
Returns the given path in absolute form.
static final Pattern PATTERN_SLASHES
A Pattern that matches redundant directory separators.
static String absoluteToRelative(@NotNull final String reference, @NotNull final String absolute)
Converts an absolute path to a relative path.
PathManagerUtils()
Private constructor to prevent instantiation.
static boolean isAbsolute(@NotNull final String path)
Check whether a path is absolute.
static final Pattern PATTERN_BACKSLASH
The pattern that matches a single backslash ("\").
static boolean isRelative(@NotNull final String path)
Check whether a path is relative.
static String getMapPath(@NotNull final File file, @NotNull final File baseDir)
Returns a relative path path for a File.
static int findOccurrences(@NotNull final CharSequence s, final char c)
Counts the occurrences of a character within a string.