/* * Copyright 2013-2016 Grzegorz Ligas <[email protected]> and other contributors * (see the CONTRIBUTORS file). * * 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 org.intellij.xquery.psi; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.ContainerUtil; import org.intellij.xquery.XQueryFileType; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import static java.util.Arrays.asList; /** * User: ligasgr * Date: 08/06/13 * Time: 21:40 */ public class XQueryUtil { public static List<XQueryFile> findXQueryFileByName(Project project, final String filename, PsiFile containingFile) { final String name = unifyNameFormatAndRemoveProtocol(filename); if (isNotAbsolutePath(name)) { PsiFile fileFoundRelatively = getFileByRelativePath(project, filename, containingFile); if (fileFoundRelatively != null) { List<XQueryFile> filteredList = getOnlyXQueryFiles(asList(fileFoundRelatively)); if (filteredList.size() > 0) { return filteredList; } } } List<String> splitFilename = StringUtil.split(name, "/"); String lastPartOfTheFilename = ContainerUtil.iterateAndGetLastItem(splitFilename); PsiFile[] filesByName = getFilesByName(project, lastPartOfTheFilename); List<PsiFile> filesThatEndWithFullName = getOnlyFilesThatEndWithFullName(name, filesByName); return getOnlyXQueryFiles(filesThatEndWithFullName); } private static boolean isNotAbsolutePath(String name) { return !name.startsWith("/"); } private static PsiFile getFileByRelativePath(Project project, String filename, PsiFile containingFile) { if (!containingFile.isPhysical()) return null; VirtualFile containingDirectory = containingFile.getParent().getVirtualFile(); VirtualFile foundByRelativePath = containingDirectory.findFileByRelativePath(filename); if (foundByRelativePath != null) { PsiFile found = PsiManager.getInstance(project).findFile(foundByRelativePath); if (found != null) { return found; } } return null; } private static List<XQueryFile> getOnlyXQueryFiles(List<PsiFile> filesThatEndWithFullName) { List<XQueryFile> xqueryFiles = new ArrayList<XQueryFile>(); for (PsiFile file : filesThatEndWithFullName) { if (file instanceof XQueryFile) { xqueryFiles.add((XQueryFile) file); } } return xqueryFiles; } private static List<PsiFile> getOnlyFilesThatEndWithFullName(final String name, PsiFile[] filesByName) { return ContainerUtil.filter(filesByName, new Condition<PsiFile>() { @Override public boolean value(PsiFile psiFile) { VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) return false; String canonicalPath = virtualFile.getCanonicalPath(); if (canonicalPath == null) return false; return canonicalPath.endsWith(name); } }); } private static PsiFile[] getFilesByName(Project project, String lastPartOfTheFilename) { return FilenameIndex.getFilesByName(project, lastPartOfTheFilename, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), XQueryFileType .INSTANCE)); } private static String unifyNameFormatAndRemoveProtocol(String filename) { return filename.replaceFirst("(.*):", "").replaceAll("\\\\", "/"); } public static Collection<XQueryFile> getReferencesToExistingFilesInImport(XQueryModuleImport moduleImport) { Collection<XQueryFile> results = new LinkedList<XQueryFile>(); XQueryModuleImportNamespace moduleImportNamespace = moduleImport.getModuleImportNamespace(); if (moduleImportNamespace != null) { addFileIfReferencedAndExists(results, moduleImportNamespace.getModuleImportPath()); } for (XQueryModuleImportPath path : moduleImport.getModuleImportPathList()) { addFileIfReferencedAndExists(results, path); } return results; } private static void addFileIfReferencedAndExists(Collection<XQueryFile> results, XQueryModuleImportPath path) { if (path.getReference() != null) { XQueryFile xQueryFile = (XQueryFile) path.getReference().resolve(); if (xQueryFile != null && xQueryFile.getModuleNamespaceName() != null) { results.add(xQueryFile); } } } }