/* * Copyright 2012 Ludovic Claude. * * 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.debian.maven.packager.util; import java.io.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.debian.maven.packager.DebianDependency; import org.debian.maven.repo.Dependency; public class PackageScanner { private final boolean offline; // Keep the list of known files and their package private Map<File, String> filesInPackages = new HashMap<File, String>(); private Map<String, List<String>> cacheOfSharedJars = new HashMap<String, List<String>>(); public PackageScanner(boolean offline) { this.offline = offline; } public PackageScanner newInstanceWithFreshCaches() { return new PackageScanner(offline); } public DebianDependency searchPkg(File dir, String extension) { // lookup the cache first File cacheId = new File(dir, "<ANY>" + extension); if (filesInPackages.containsKey(cacheId)) { return new DebianDependency(filesInPackages.get(cacheId)); } GetPackageContainingPatternResult packageResult = new GetPackageContainingPatternResult(extension); IOUtil.executeProcess(new String[]{"dpkg", "--search", dir.getAbsolutePath() + "/*/*"}, packageResult); if (!packageResult.getPackages().isEmpty()) { String pkg = packageResult.getPackages().iterator().next(); filesInPackages.put(cacheId, pkg); return new DebianDependency(pkg); } // Debian policy prevents the use of apt-file during a build if (offline) { System.err.println("Offline mode. Give up looking for package containing " + dir); return null; } if (!new File("/usr/bin/apt-file").exists()) { System.err.println("/usr/bin/apt-file not found. Give up looking for package containing " + dir); return null; } IOUtil.executeProcess(new String[]{"apt-file", "search", dir.getAbsolutePath()}, packageResult); if (!packageResult.getPackages().isEmpty()) { String pkg = packageResult.getPackages().iterator().next(); filesInPackages.put(cacheId, pkg); new DebianDependency(pkg); } return null; } public DebianDependency searchPkgContainingPom(Dependency dependency) { // TODO shouldn't we use the mavenRepo property of DependencySolver for the mavenRepo path? return searchPkg(new File("/usr/share/maven-repo/" + dependency.getGroupId().replace('.', '/') + "/" + dependency.getArtifactId()) , ".pom"); } public DebianDependency searchPkgContainingJar(Dependency dependency) { return searchPkg(new File("/usr/share/java/" + dependency.getArtifactId() + ".jar")); } /** * Searches the package containing the Javadoc for the specified package. * * @param dependency */ public DebianDependency searchJavaDocPkg(DebianDependency dependency) { DebianDependency pkg = searchPkg(new File("/usr/share/doc/" + dependency.getPackageName() + "/api/index.html")); if (pkg == null) { pkg = searchPkg(new File("/usr/share/doc/" + dependency.getPackageName() + "-doc/api/index.html")); } if (pkg == null) { pkg = searchPkg(new File("/usr/share/doc/" + dependency.getPackageName() + "/apidocs/index.html")); } if (pkg == null) { pkg = searchPkg(new File("/usr/share/doc/" + dependency.getPackageName() + "-doc/apidocs/index.html")); } return pkg; } public DebianDependency searchPkg(File fileToSearch) { // lookup the cache first if (filesInPackages.containsKey(fileToSearch)) { return new DebianDependency(filesInPackages.get(fileToSearch)); } GetPackageResult packageResult = new GetPackageResult(); IOUtil.executeProcess(new String[]{"dpkg", "--search", fileToSearch.getAbsolutePath()}, packageResult); if (!packageResult.getResult().isEmpty()) { String pkg = packageResult.getResult().iterator().next(); filesInPackages.put(fileToSearch, pkg); return new DebianDependency(pkg); } // Debian policy prevents the use of apt-file during a build if (offline) { System.err.println("Offline mode. Give up looking for package containing " + fileToSearch); return null; } if (!new File("/usr/bin/apt-file").exists()) { System.err.println("/usr/bin/apt-file not found. Give up looking for package containing " + fileToSearch); return null; } IOUtil.executeProcess(new String[]{"apt-file", "search", fileToSearch.getAbsolutePath()}, packageResult); if (!packageResult.getResult().isEmpty()) { String pkg = packageResult.getResult().iterator().next(); filesInPackages.put(fileToSearch, pkg); return new DebianDependency(pkg); } return null; } public String getPackageVersion(DebianDependency pkg, boolean onlyInstalled) { GetPackageVersionResult packageResult = new GetPackageVersionResult(); IOUtil.executeProcess(new String[]{"dpkg", "--status", pkg.getPackageName()}, packageResult); if (packageResult.getResult() != null) { return packageResult.getResult(); } if (!onlyInstalled) { GetChangelogVersionResult versionResult = new GetChangelogVersionResult(pkg.getPackageName()); IOUtil.executeProcess(new String[]{"apt-get", "--no-act", "--verbose-versions", "install", pkg.getPackageName()}, versionResult); if (versionResult.getResult() != null) { return versionResult.getResult(); } } return null; } public List<String> listSharedJars(String library) { if (cacheOfSharedJars.get(library) != null) { return cacheOfSharedJars.get(library); } final List<String> jars = new ArrayList<String>(); if (library.indexOf("(") > 0) { library = library.substring(0, library.indexOf("(")).trim(); } System.out.println(); System.out.println("Looking for shared jars in package " + library + "..."); IOUtil.executeProcess(new String[]{"dpkg", "--listfiles", library}, new SharedJarOutputHandler(jars)); cacheOfSharedJars.put(library, jars); return jars; } public List<DebianDependency> addDocDependencies(Collection<DebianDependency> debianDeps, Map<DebianDependency, Dependency> versionedPackagesAndDependencies) { List<DebianDependency> docDeps = new ArrayList<DebianDependency>(); for (DebianDependency dependency : debianDeps) { Dependency runtimeDependency = versionedPackagesAndDependencies.get(dependency); if (runtimeDependency != null && runtimeDependency.isPom()) { continue; } DebianDependency docPkg = searchJavaDocPkg(dependency); if (docPkg != null) { docDeps.add(docPkg); } } return docDeps; } }