
com.github.sommeri.less4j.utils.URIUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of less4j Show documentation
Show all versions of less4j Show documentation
Less language is an extension of css and less4j compiles it into regular css. It adds several dynamic features into css: variables, expressions, nested rules.
Less4j is a port. The original compiler was written in JavaScript and is called less.js. The less language is mostly defined in less.js documentation/issues and by what less.js actually do. Links to less.js:
* home page: http://lesscss.org/
* source code & issues: https://github.com/cloudhead/less.js
package com.github.sommeri.less4j.utils;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.regex.Pattern;
import org.apache.commons.io.FilenameUtils;
import com.github.sommeri.less4j.LessSource;
import com.github.sommeri.less4j.LessSource.FileSource;
import com.github.sommeri.less4j.platform.Constants;
public class URIUtils {
public static final String URI_FILE_SEPARATOR = "/";
public static URL toParentURL(URL url) {
String path = url.getPath();
int i = path.lastIndexOf(URI_FILE_SEPARATOR);
if (i != -1) {
path = path.substring(0, i + 1);
}
try {
return new URL(url, path + url.getQuery());
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
}
}
public static String relativize(File from, File to) {
URI fromURI = from.toURI();
URI toURI = to.toURI();
String relative = getRelativePath(fromURI.toString(), toURI.toString(), URIUtils.URI_FILE_SEPARATOR);
relative = convertUriToPlatformSeparator(relative);
return relative;
}
public static String relativizeSourceURIs(LessSource from, LessSource to) {
if (to == null)
return "";
if (to.getURI() == null)
return to.getName() == null ? "" : to.getName();
if (from == null || from.getURI() == null)
return to.getURI().toString();
String fromURI = from.getURI().toString();
String toURI = to.getURI().toString();
return getRelativePath(fromURI, toURI, URIUtils.URI_FILE_SEPARATOR);
}
public static String convertUriToPlatformSeparator(String relative) {
return relative.replace(URI_FILE_SEPARATOR, Constants.FILE_SEPARATOR);
}
public static String convertPlatformSeparatorToUri(String relative) {
return relative.replace(Constants.FILE_SEPARATOR, URI_FILE_SEPARATOR);
}
/**
* taken from stackoverflow:
* http://stackoverflow.com/questions/204784/how-to-construct
* -a-relative-path-in-java-from-two-absolute-paths-or-urls
*
* Get the relative path from one file to another, specifying the directory
* separator. If one of the provided resources does not exist, it is assumed
* to be a file unless it ends with '/' or '\'.
*
* @param basePath
* basePath is calculated from this file
* @param targetPath
* targetPath is calculated to this file
* @param pathSeparator
* directory separator. The platform default is not assumed so that
* we can test Unix behaviour when running on Windows (for example)
*
* @return
*/
public static String getRelativePath(String basePath, String targetPath, String pathSeparator) {
// Normalize the paths
String normalizedTargetPath = normalizeNoEndSeparator(targetPath, pathSeparator);
String normalizedBasePath = normalizeNoEndSeparator(basePath, pathSeparator);
if (normalizedTargetPath==null)
return "";
if (normalizedBasePath==null)
return targetPath;
String[] base = normalizedBasePath.split(Pattern.quote(pathSeparator));
String[] target = normalizedTargetPath.split(Pattern.quote(pathSeparator));
// First get all the common elements. Store them as a string,
// and also count how many of them there are.
StringBuffer common = new StringBuffer();
int commonIndex = 0;
while (commonIndex < target.length && commonIndex < base.length && target[commonIndex].equals(base[commonIndex])) {
common.append(target[commonIndex] + pathSeparator);
commonIndex++;
}
if (commonIndex == 0) {
// No single common path element. This most
// likely indicates differing drive letters, like C: and D:.
// These paths cannot be relativized.
return normalizedTargetPath;
// throw new PathResolutionException("No common path element found for '" + normalizedTargetPath + "' and '" + normalizedBasePath + "'");
}
// The number of directories we have to backtrack depends on whether the base is a file or a dir
// For example, the relative path from
//
// /foo/bar/baz/gg/ff to /foo/bar/baz
//
// ".." if ff is a file
// "../.." if ff is a directory
//
// The following is a heuristic to figure out if the base refers to a file or dir. It's not perfect, because
// the resource referred to by this path may not actually exist, but it's the best I can do
boolean baseIsFile = true;
File baseResource = new File(normalizedBasePath);
if (baseResource.exists()) {
baseIsFile = baseResource.isFile();
} else if (basePath.endsWith(pathSeparator)) {
baseIsFile = false;
}
StringBuffer relative = new StringBuffer();
if (base.length != commonIndex) {
int numDirsUp = baseIsFile ? base.length - commonIndex - 1 : base.length - commonIndex;
for (int i = 0; i < numDirsUp; i++) {
relative.append(".." + pathSeparator);
}
}
relative.append(safeSubstring(normalizedTargetPath, common.length()));
return relative.toString();
}
public static String normalizeNoEndSeparator(String path, String separator) {
String result = RelativeFilenameUtils.normalizeNoEndSeparator(path);
// Undo the changes to the separators made by normalization
if (separator.equals("/")) {
result = FilenameUtils.separatorsToUnix(result);
} else if (separator.equals("\\")) {
result = FilenameUtils.separatorsToWindows(result);
} else {
throw new IllegalArgumentException("Unrecognised dir separator '" + separator + "'");
}
return result;
}
private static String safeSubstring(String string, int beginIndex) {
if (beginIndex > string.length())
return "";
return string.substring(beginIndex);
}
public static String addPLatformSlashIfNeeded(String directory) {
if (directory.endsWith(Constants.FILE_SEPARATOR))
return directory;
return directory + Constants.FILE_SEPARATOR;
}
public static URI changeSuffix(URI uri, String dottedSuffix) {
if (uri==null)
return null;
String newPath = changeSuffix(uri.getPath(), dottedSuffix);
try {
URI result = new URI(uri.getScheme(),uri.getUserInfo(), uri.getHost(), uri.getPort(), newPath, null, null);
return result;
} catch (URISyntaxException ex) {
//TODO do something more reasonable, maybe return null?
throw new IllegalStateException(ex);
}
}
public static String changeSuffix(String filename, String dottedSuffix) {
if (filename == null)
return null;
int lastIndexOf = filename.lastIndexOf('.');
if (lastIndexOf == -1)
return filename + dottedSuffix;
return filename.substring(0, lastIndexOf) + dottedSuffix;
}
public static String addSuffix(String filename, String dottedSuffix) {
if (filename == null)
return null;
return filename + dottedSuffix;
}
public static File changeSuffix(File file, String dottedSuffix) {
if (file == null)
return null;
String filename = changeSuffix(file.toString(), dottedSuffix);
return new File(filename);
}
public static FileSource changeSuffix(FileSource source, String dottedSuffix) {
if (source == null)
return null;
return new LessSource.FileSource(changeSuffix(source.getInputFile(), dottedSuffix));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy