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-2023 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.utils;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.regex.Pattern;
25 import org.jetbrains.annotations.NotNull;
26 
31 public class PathManagerUtils {
32 
36  @NotNull
37  private static final Pattern PATTERN_REDUNDANT = Pattern.compile("[^/]+/\\.\\./");
38 
42  @NotNull
43  private static final Pattern PATTERN_SLASHES = Pattern.compile("//*");
44 
48  private PathManagerUtils() {
49  }
50 
57  @NotNull
58  public static String getMapPath(@NotNull final File file, @NotNull final File baseDir) {
59  final String mapDirName = baseDir.getPath();
60  String mapPath = file.getPath().replace('\\', '/');
61  if (mapPath.startsWith(mapDirName)) {
62  mapPath = mapPath.substring(mapDirName.length());
63  }
64  if (mapPath.startsWith(new File(mapDirName).getAbsolutePath())) {
65  mapPath = mapPath.substring(new File(mapDirName).getAbsolutePath().length());
66  }
67  try {
68  if (mapPath.startsWith(new File(mapDirName).getCanonicalPath())) {
69  mapPath = mapPath.substring(new File(mapDirName).getCanonicalPath().length());
70  }
71  } catch (final IOException ignored) {
72  // ignore
73  }
74  mapPath = mapPath.replace('\\', '/');
75  return mapPath;
76  }
77 
86  public static boolean isAbsolute(@NotNull final String path) {
87  return path.startsWith("/") || new File(path).isAbsolute();
88  }
89 
97  public static boolean isRelative(@NotNull final String path) {
98  return !path.startsWith("/") && !new File(path).isAbsolute();
99  }
100 
110  @NotNull
111  public static String relativeToAbsolute(@NotNull final String reference, @NotNull final String relative) {
112  final String normalizedRelative = relative.replace('\\', '/');
113  if (isAbsolute(normalizedRelative)) {
114  return normalizedRelative;
115  }
116 
117  final String normalizedReference = reference.replace('\\', '/');
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 normalizedAbsolute = absolute.replace('\\', '/');
139  if (isRelative(normalizedAbsolute)) {
140  return normalizedAbsolute;
141  }
142 
143  //String reference2 =
144  // First: Strip equal path parts
145  final String normalizedReference = reference.replace('\\', '/');
146  final int difference = findDifference(normalizedReference, normalizedAbsolute);
147  final StringBuilder relative = new StringBuilder(normalizedAbsolute.substring(difference));
148  final CharSequence referencePath = normalizedReference.substring(difference);
149  for (int i = 0, l = findOccurrences(referencePath, '/'); i < l; i++) {
150  relative.insert(0, "../");
151  }
152  return relative.toString();
153  }
154 
165  private static int findDifference(@NotNull final CharSequence s1, @NotNull final CharSequence s2) {
166  int s1slash = -1;
167  int s2slash = -1;
168  char c1 = 0; // initialize for equality for first loop cycle
169  char c2 = 0;
170  for (int index = 0, l1 = s1.length(), l2 = s2.length(); index < l1 && index < l2 && c1 == c2; index++) {
171  c1 = s1.charAt(index);
172  c2 = s2.charAt(index);
173  if (c1 == '/') {
174  s1slash = index;
175  }
176  if (c2 == '/') {
177  s2slash = index;
178  }
179  }
180  return Math.min(s1slash, s2slash) + 1;
181  }
182 
189  private static int findOccurrences(@NotNull final CharSequence s, final char c) {
190  int occurrences = 0;
191  for (int i = 0, l = s.length(); i < l; i++) {
192  if (s.charAt(i) == c) {
193  occurrences++;
194  }
195  }
196  return occurrences;
197  }
198 
204  @NotNull
205  public static String path(@NotNull final CharSequence str) {
206  String path = StringUtils.PATTERN_BACKSLASH.matcher(str).replaceAll("/");
207  path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
208  path = path.startsWith("file:") ? path.substring("file:".length()) : path;
209  path = PATTERN_SLASHES.matcher(path).replaceAll("/");
210  return path;
211  }
212 
218  @NotNull
219  public static String getAbsolutePath(@NotNull final CharSequence path) {
220  return relativeToAbsolute(System.getProperty("user.dir") + "/dummy", path(path));
221  }
222 
223 }
net.sf.gridarta.utils.PathManagerUtils.PATTERN_SLASHES
static final Pattern PATTERN_SLASHES
A Pattern that matches redundant directory separators.
Definition: PathManagerUtils.java:43
net.sf.gridarta.utils.PathManagerUtils.absoluteToRelative
static String absoluteToRelative(@NotNull final String reference, @NotNull final String absolute)
Converts an absolute path to a relative path.
Definition: PathManagerUtils.java:137
net.sf.gridarta.utils.PathManagerUtils.PathManagerUtils
PathManagerUtils()
Private constructor to prevent instantiation.
Definition: PathManagerUtils.java:48
net.sf.gridarta.utils.PathManagerUtils.path
static String path(@NotNull final CharSequence str)
Creates a reasonable path.
Definition: PathManagerUtils.java:205
net.sf.gridarta.utils.PathManagerUtils.getMapPath
static String getMapPath(@NotNull final File file, @NotNull final File baseDir)
Returns a relative path path for a File.
Definition: PathManagerUtils.java:58
net.sf.gridarta.utils.PathManagerUtils.isAbsolute
static boolean isAbsolute(@NotNull final String path)
Check whether a path is absolute.
Definition: PathManagerUtils.java:86
net.sf.gridarta.utils.StringUtils
Utility class for string manipulation.
Definition: StringUtils.java:31
net.sf.gridarta.utils.PathManagerUtils
Utility class for converting relative map paths to absolute map paths and vice versa.
Definition: PathManagerUtils.java:31
net.sf.gridarta.utils.PathManagerUtils.PATTERN_REDUNDANT
static final Pattern PATTERN_REDUNDANT
A Pattern that matches redundant directory parts like "dir/../".
Definition: PathManagerUtils.java:37
net.sf.gridarta.utils.PathManagerUtils.isRelative
static boolean isRelative(@NotNull final String path)
Check whether a path is relative.
Definition: PathManagerUtils.java:97
net.sf.gridarta.utils.StringUtils.PATTERN_BACKSLASH
static final Pattern PATTERN_BACKSLASH
The pattern that matches a single backslash ("\").
Definition: StringUtils.java:85
net.sf.gridarta.utils.PathManagerUtils.findDifference
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't identica...
Definition: PathManagerUtils.java:165
net.sf.gridarta.utils.PathManagerUtils.findOccurrences
static int findOccurrences(@NotNull final CharSequence s, final char c)
Counts the occurrences of a character within a string.
Definition: PathManagerUtils.java:189
net.sf.gridarta.utils.PathManagerUtils.getAbsolutePath
static String getAbsolutePath(@NotNull final CharSequence path)
Returns the given path in absolute form.
Definition: PathManagerUtils.java:219
net.sf.gridarta.utils.PathManagerUtils.relativeToAbsolute
static String relativeToAbsolute(@NotNull final String reference, @NotNull final String relative)
Converts a relative path to an absolute path.
Definition: PathManagerUtils.java:111