/*
* Copyright 2010 Ronnie Kolehmainen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.cssxfire;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: Ronnie
*/
public class RouteUtils {
private static final Logger LOG = Logger.getInstance(RouteUtils.class.getName());
private static final String[] ROOT_MAPPING = new String[]{""};
/**
* Finds the local file for a given route, if any. This method does not perform any I/O
* operations but works only with the paths of the files.
*
* @param project the project
* @param filePath the remote file path, e.g. the string returnd from {@link java.net.URL#getPath()}
* @return the mapped local file in given project, or <tt>null</tt> if no mapping can be detected
*/
@Nullable
public static VirtualFile detectLocalFile(@NotNull final Project project, @NotNull final String filePath) {
final RoutePerFileMappings routes = ProjectSettings.getInstance(project).getRoutes();
String[] parts = filePath.split("/");
Map<VirtualFile, String> mappings = routes.getMappings();
if (LOG.isDebugEnabled()) {
LOG.debug("Detect local file, path: " + filePath + " routes: " + mappings);
}
String[] longestMatch = new String[0];
VirtualFile bestMatch = null;
String bestRoute = null;
for (Map.Entry<VirtualFile, String> entry : mappings.entrySet()) {
VirtualFile file = entry.getKey();
String route = entry.getValue();
if (filePath.equals(route)) {
// full match
if (LOG.isDebugEnabled()) {
LOG.debug("Full match, route: " + route + ", file: " + file);
}
return file;
}
if (!file.isDirectory()) {
continue;
}
String[] routeParts = "/".equals(route) ? ROOT_MAPPING : route.split("/"); // fix for String.split() inconsistency
if (routeParts.length <= parts.length && routeParts.length > longestMatch.length) {
if (startsWith(parts, routeParts)) {
longestMatch = routeParts;
bestMatch = file;
bestRoute = route;
}
}
}
if (longestMatch.length == 0) {
// no route matched
LOG.debug("No match");
return null;
}
//noinspection ConstantConditions
VirtualFile virtualFile = bestMatch.findFileByRelativePath(filePath.substring(bestRoute.length()));
if (LOG.isDebugEnabled()) {
LOG.debug("Partial match, route: " + bestRoute + ", best match: " + bestMatch + ", local file: " + virtualFile);
}
return virtualFile;
}
private static boolean startsWith(@NotNull String[] array, @NotNull String[] start) {
if (start.length > array.length) {
return false;
}
for (int i = 0; i < start.length; i++) {
if (!array[i].equals(start[i])) {
return false;
}
}
return true;
}
}