/* * Copyright 2000-2010 JetBrains s.r.o. * * 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 jetbrains.buildServer.xmlReportPlugin.findBugs; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class FileFinder { private final List myJars; public FileFinder() { myJars = new LinkedList(); } public void addJars(List jars) { for (String jar : jars) { addJar(jar); } } public void addJar(String jar) { jar = getDependentPath(jar, File.separator); if (jar.endsWith(".zip") || jar.endsWith(".jar")) { try { myJars.add(new ArchiveEntry(new ZipFile(jar))); } catch (IOException e) { //just ignore } } else if (jar.endsWith(".class")) { myJars.add(new ClassEntry(jar)); } else { myJars.add(new DirectoryEntry(jar)); } } public String getVeryFullFilePath(String filePath) { if (filePath == null) { return ""; } filePath = getDependentPath(filePath, File.separator); if (filePath.contains("$") && filePath.endsWith(".java")) { filePath = filePath.substring(0, filePath.indexOf("$")) + ".class"; } for (Entry jar : myJars) { final String veryFullFilePath = jar.getFilePath(filePath); if (veryFullFilePath != null) { return veryFullFilePath; } } return ""; } public void close() { for (Entry jar : myJars) { jar.close(); } } private static String getDependentPath(String path, String separator) { return path.replace("\\", separator).replace("/", separator); } private static abstract class Entry { public abstract String getFilePath(String fileName); public void close() { } } private static final class DirectoryEntry extends Entry { private final String myRoot; public DirectoryEntry(String root) { myRoot = root; } public String getFilePath(String fileName) { return getFilePathRecursive(new File(myRoot).listFiles(), fileName); } private String getFilePathRecursive(File[] files, String relativePath) { if (files == null) { return null; } int i = 0; while (i < files.length) { if (files[i].isFile()) { final String path = files[i].getAbsolutePath(); if (path.endsWith(relativePath)) { return path; } } else if (files[i].isDirectory()) { final String path = getFilePathRecursive(files[i].listFiles(), relativePath); if (path != null) { return path; } } ++i; } return null; } } private static final class ArchiveEntry extends Entry { private final ZipFile myArchive; public ArchiveEntry(ZipFile archive) { myArchive = archive; } public String getFilePath(String fileName) { final String filePathInZip = getDependentPath(fileName, "/"); for (Enumeration e = myArchive.entries(); e.hasMoreElements();) { final String entry = e.nextElement().getName(); if (entry.endsWith(filePathInZip)) { return myArchive.getName() + File.separator + getDependentPath(entry, File.separator); } } return null; } public void close() { try { myArchive.close(); } catch (IOException e) { //TODO: log somehow } } } private static final class ClassEntry extends Entry { private final String myFile; public ClassEntry(String file) { myFile = file; } public String getFilePath(String fileName) { return myFile.endsWith(fileName) ? myFile : null; } } }