Merge changes from topic 'path'
* changes: SitePaths: Convert static content related paths to Path SitePaths: Convert tmp_dir to Path Convert @SitePath from File to Path
This commit is contained in:
		| @@ -43,7 +43,8 @@ import org.apache.sshd.common.KeyPairProvider; | ||||
| import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; | ||||
| import org.eclipse.jgit.lib.Config; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| class InMemoryTestingDatabaseModule extends LifecycleModule { | ||||
|   private final Config cfg; | ||||
| @@ -58,9 +59,10 @@ class InMemoryTestingDatabaseModule extends LifecycleModule { | ||||
|       .annotatedWith(GerritServerConfig.class) | ||||
|       .toInstance(cfg); | ||||
|  | ||||
|     bind(File.class) | ||||
|     // TODO(dborowitz): Use jimfs. | ||||
|     bind(Path.class) | ||||
|       .annotatedWith(SitePath.class) | ||||
|       .toInstance(new File("UNIT_TEST_GERRIT_SITE")); | ||||
|       .toInstance(Paths.get("UNIT_TEST_GERRIT_SITE")); | ||||
|  | ||||
|     bind(GitRepositoryManager.class) | ||||
|       .toInstance(new InMemoryRepositoryManager()); | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import org.eclipse.jgit.util.IO; | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Arrays; | ||||
|  | ||||
| public class FileUtil { | ||||
| @@ -42,6 +43,11 @@ public class FileUtil { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public static void chmod(final int mode, final Path path) { | ||||
|     // TODO(dborowitz): Is there a portable way to do this with NIO? | ||||
|     chmod(mode, path.toFile()); | ||||
|   } | ||||
|  | ||||
|   public static void chmod(final int mode, final File path) { | ||||
|     path.setReadable(false, false /* all */); | ||||
|     path.setWritable(false, false /* all */); | ||||
| @@ -63,4 +69,4 @@ public class FileUtil { | ||||
|  | ||||
|   private FileUtil() { | ||||
|   } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,9 @@ | ||||
|  | ||||
| package com.google.gerrit.httpd; | ||||
|  | ||||
| import static java.nio.file.Files.isExecutable; | ||||
| import static java.nio.file.Files.isRegularFile; | ||||
|  | ||||
| import com.google.gerrit.common.data.GitWebType; | ||||
| import com.google.gerrit.server.config.GerritServerConfig; | ||||
| import com.google.gerrit.server.config.SitePaths; | ||||
| @@ -23,16 +26,17 @@ import org.eclipse.jgit.lib.Config; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| public class GitWebConfig { | ||||
|   private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class); | ||||
|  | ||||
|   private final String url; | ||||
|   private final File gitweb_cgi; | ||||
|   private final File gitweb_css; | ||||
|   private final File gitweb_js; | ||||
|   private final File git_logo_png; | ||||
|   private final Path gitweb_cgi; | ||||
|   private final Path gitweb_css; | ||||
|   private final Path gitweb_js; | ||||
|   private final Path git_logo_png; | ||||
|   private GitWebType type; | ||||
|  | ||||
|   @Inject | ||||
| @@ -117,20 +121,20 @@ public class GitWebConfig { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     final File pkgCgi = new File("/usr/lib/cgi-bin/gitweb.cgi"); | ||||
|     final Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi"); | ||||
|     String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb", | ||||
|         "/var/www/static", "/var/www"}; | ||||
|     File cgi; | ||||
|     Path cgi; | ||||
|  | ||||
|     if (cfgCgi != null) { | ||||
|       // Use the CGI script configured by the administrator, failing if it | ||||
|       // cannot be used as specified. | ||||
|       // | ||||
|       cgi = sitePaths.resolve(cfgCgi); | ||||
|       if (!cgi.isFile()) { | ||||
|       cgi = sitePaths.resolve(cfgCgi).toPath(); | ||||
|       if (!isRegularFile(cgi)) { | ||||
|         throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi); | ||||
|       } | ||||
|       if (!cgi.canExecute()) { | ||||
|       if (!isExecutable(cgi)) { | ||||
|         throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi); | ||||
|       } | ||||
|  | ||||
| @@ -138,11 +142,11 @@ public class GitWebConfig { | ||||
|         // Assume the administrator pointed us to the distribution, | ||||
|         // which also has the corresponding CSS and logo file. | ||||
|         // | ||||
|         String absPath = cgi.getParentFile().getAbsolutePath(); | ||||
|         String absPath = cgi.getParent().toAbsolutePath().toString(); | ||||
|         resourcePaths = new String[] {absPath + "/static", absPath}; | ||||
|       } | ||||
|  | ||||
|     } else if (pkgCgi.isFile() && pkgCgi.canExecute()) { | ||||
|     } else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) { | ||||
|       // Use the OS packaged CGI. | ||||
|       // | ||||
|       log.debug("Assuming gitweb at " + pkgCgi); | ||||
| @@ -154,13 +158,13 @@ public class GitWebConfig { | ||||
|       resourcePaths = new String[] {}; | ||||
|     } | ||||
|  | ||||
|     File css = null, js = null, logo = null; | ||||
|     Path css = null, js = null, logo = null; | ||||
|     for (String path : resourcePaths) { | ||||
|       File dir = new File(path); | ||||
|       css = new File(dir, "gitweb.css"); | ||||
|       js = new File(dir, "gitweb.js"); | ||||
|       logo = new File(dir, "git-logo.png"); | ||||
|       if (css.isFile() && logo.isFile()) { | ||||
|       Path dir = Paths.get(path); | ||||
|       css = dir.resolve("gitweb.css"); | ||||
|       js = dir.resolve("gitweb.js"); | ||||
|       logo = dir.resolve("git-logo.png"); | ||||
|       if (isRegularFile(css) && isRegularFile(logo)) { | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
| @@ -191,22 +195,22 @@ public class GitWebConfig { | ||||
|   } | ||||
|  | ||||
|   /** @return local path to the CGI executable; null if we shouldn't execute. */ | ||||
|   public File getGitwebCGI() { | ||||
|   public Path getGitwebCGI() { | ||||
|     return gitweb_cgi; | ||||
|   } | ||||
|  | ||||
|   /** @return local path of the {@code gitweb.css} matching the CGI. */ | ||||
|   public File getGitwebCSS() { | ||||
|   public Path getGitwebCSS() { | ||||
|     return gitweb_css; | ||||
|   } | ||||
|  | ||||
|   /** @return local path of the {@code gitweb.js} for the CGI. */ | ||||
|   public File getGitwebJS() { | ||||
|   public Path getGitwebJS() { | ||||
|     return gitweb_js; | ||||
|   } | ||||
|  | ||||
|   /** @return local path of the {@code git-logo.png} for the CGI. */ | ||||
|   public File getGitLogoPNG() { | ||||
|   public Path getGitLogoPNG() { | ||||
|     return git_logo_png; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -23,14 +23,14 @@ import org.w3c.dom.NodeList; | ||||
| import org.xml.sax.SAXException; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.StringWriter; | ||||
| import java.nio.charset.Charset; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.zip.GZIPOutputStream; | ||||
|  | ||||
| import javax.xml.parsers.DocumentBuilder; | ||||
| @@ -187,8 +187,8 @@ public class HtmlDomUtil { | ||||
|   } | ||||
|  | ||||
|   /** Parse an XHTML file from the local drive and return the instance. */ | ||||
|   public static Document parseFile(File path) throws IOException { | ||||
|     try (InputStream in = new FileInputStream(path)) { | ||||
|   public static Document parseFile(Path path) throws IOException { | ||||
|     try (InputStream in = Files.newInputStream(path)) { | ||||
|       Document doc = newBuilder().parse(in); | ||||
|       compact(doc); | ||||
|       return doc; | ||||
| @@ -200,13 +200,13 @@ public class HtmlDomUtil { | ||||
|   } | ||||
|  | ||||
|   /** Read a UTF-8 text file from the local drive. */ | ||||
|   public static String readFile(File parentDir, String name) | ||||
|   public static String readFile(Path parentDir, String name) | ||||
|       throws IOException { | ||||
|     if (parentDir == null) { | ||||
|       return null; | ||||
|     } | ||||
|     File path = new File(parentDir, name); | ||||
|     try (FileInputStream in = new FileInputStream(path)) { | ||||
|     Path path = parentDir.resolve(name); | ||||
|     try (InputStream in = Files.newInputStream(path)) { | ||||
|       return new String(ByteStreams.toByteArray(in), ENC); | ||||
|     } catch (FileNotFoundException e) { | ||||
|       return null; | ||||
|   | ||||
| @@ -14,16 +14,17 @@ | ||||
|  | ||||
| package com.google.gerrit.httpd.gitweb; | ||||
|  | ||||
| import com.google.common.io.ByteStreams; | ||||
| import com.google.gerrit.httpd.GitWebConfig; | ||||
| import com.google.gwtexpui.server.CacheHeaders; | ||||
| import com.google.inject.Inject; | ||||
| import com.google.inject.Singleton; | ||||
|  | ||||
| import org.eclipse.jgit.util.IO; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| import javax.servlet.ServletOutputStream; | ||||
| @@ -38,16 +39,16 @@ class GitLogoServlet extends HttpServlet { | ||||
|   private final byte[] raw; | ||||
|  | ||||
|   @Inject | ||||
|   GitLogoServlet(final GitWebConfig gitWebConfig) throws IOException { | ||||
|   GitLogoServlet(GitWebConfig gitWebConfig) throws IOException { | ||||
|     byte[] png; | ||||
|     final File src = gitWebConfig.getGitLogoPNG(); | ||||
|     Path src = gitWebConfig.getGitLogoPNG(); | ||||
|     if (src != null) { | ||||
|       try { | ||||
|         png = IO.readFully(src); | ||||
|       try (InputStream in = Files.newInputStream(src)) { | ||||
|         png = ByteStreams.toByteArray(in); | ||||
|       } catch (FileNotFoundException e) { | ||||
|         png = null; | ||||
|       } | ||||
|       modified = src.lastModified(); | ||||
|       modified = Files.getLastModifiedTime(src).toMillis(); | ||||
|     } else { | ||||
|       modified = -1; | ||||
|       png = null; | ||||
|   | ||||
| @@ -22,8 +22,9 @@ import com.google.gwtjsonrpc.server.RPCServletUtils; | ||||
| import com.google.inject.Inject; | ||||
| import com.google.inject.Singleton; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| import javax.servlet.ServletOutputStream; | ||||
| @@ -55,14 +56,14 @@ abstract class GitWebCssServlet extends HttpServlet { | ||||
|   private final byte[] raw_css; | ||||
|   private final byte[] gz_css; | ||||
|  | ||||
|   GitWebCssServlet(final File src) | ||||
|   GitWebCssServlet(final Path src) | ||||
|       throws IOException { | ||||
|     if (src != null) { | ||||
|       final File dir = src.getParentFile(); | ||||
|       final String name = src.getName(); | ||||
|       final Path dir = src.getParent(); | ||||
|       final String name = src.getFileName().toString(); | ||||
|       final String raw = HtmlDomUtil.readFile(dir, name); | ||||
|       if (raw != null) { | ||||
|         modified = src.lastModified(); | ||||
|         modified = Files.getLastModifiedTime(src).toMillis(); | ||||
|         raw_css = raw.getBytes(ENC); | ||||
|         gz_css = HtmlDomUtil.compress(raw_css); | ||||
|       } else { | ||||
|   | ||||
| @@ -14,16 +14,17 @@ | ||||
|  | ||||
| package com.google.gerrit.httpd.gitweb; | ||||
|  | ||||
| import com.google.common.io.ByteStreams; | ||||
| import com.google.gerrit.httpd.GitWebConfig; | ||||
| import com.google.gwtexpui.server.CacheHeaders; | ||||
| import com.google.inject.Inject; | ||||
| import com.google.inject.Singleton; | ||||
|  | ||||
| import org.eclipse.jgit.util.IO; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| import javax.servlet.ServletOutputStream; | ||||
| @@ -40,14 +41,14 @@ class GitWebJavaScriptServlet extends HttpServlet { | ||||
|   @Inject | ||||
|   GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException { | ||||
|     byte[] png; | ||||
|     final File src = gitWebConfig.getGitwebJS(); | ||||
|     Path src = gitWebConfig.getGitwebJS(); | ||||
|     if (src != null) { | ||||
|       try { | ||||
|         png = IO.readFully(src); | ||||
|       try (InputStream in = Files.newInputStream(src)) { | ||||
|         png = ByteStreams.toByteArray(in); | ||||
|       } catch (FileNotFoundException e) { | ||||
|         png = null; | ||||
|       } | ||||
|       modified = src.lastModified(); | ||||
|       modified = Files.getLastModifiedTime(src).toMillis(); | ||||
|     } else { | ||||
|       modified = -1; | ||||
|       png = null; | ||||
|   | ||||
| @@ -29,6 +29,8 @@ | ||||
|  | ||||
| package com.google.gerrit.httpd.gitweb; | ||||
|  | ||||
| import static java.nio.charset.StandardCharsets.UTF_8; | ||||
|  | ||||
| import com.google.gerrit.common.data.GerritConfig; | ||||
| import com.google.gerrit.extensions.restapi.Url; | ||||
| import com.google.gerrit.httpd.GitWebConfig; | ||||
| @@ -54,7 +56,6 @@ import java.io.BufferedInputStream; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.EOFException; | ||||
| import java.io.File; | ||||
| import java.io.FileWriter; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.InputStreamReader; | ||||
| @@ -62,6 +63,8 @@ import java.io.OutputStream; | ||||
| import java.io.PrintWriter; | ||||
| import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Enumeration; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| @@ -81,7 +84,7 @@ class GitWebServlet extends HttpServlet { | ||||
|  | ||||
|   private final Set<String> deniedActions; | ||||
|   private final int bufferSize = 8192; | ||||
|   private final File gitwebCgi; | ||||
|   private final Path gitwebCgi; | ||||
|   private final URI gitwebUrl; | ||||
|   private final LocalDiskRepositoryManager repoManager; | ||||
|   private final ProjectControl.Factory projectControl; | ||||
| @@ -143,26 +146,28 @@ class GitWebServlet extends HttpServlet { | ||||
|  | ||||
|   private void makeSiteConfig(final SitePaths site, | ||||
|       final GerritConfig gerritConfig) throws IOException { | ||||
|     if (!site.tmp_dir.exists()) { | ||||
|       site.tmp_dir.mkdirs(); | ||||
|     if (!Files.exists(site.tmp_dir)) { | ||||
|       Files.createDirectories(site.tmp_dir); | ||||
|     } | ||||
|     File myconf = File.createTempFile("gitweb_config", ".perl", site.tmp_dir); | ||||
|     Path myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl"); | ||||
|  | ||||
|     // To make our configuration file only readable or writable by us; | ||||
|     // this reduces the chances of someone tampering with the file. | ||||
|     // | ||||
|     myconf.setWritable(false, false /* all */); | ||||
|     myconf.setReadable(false, false /* all */); | ||||
|     myconf.setExecutable(false, false /* all */); | ||||
|     // TODO(dborowitz): Is there a portable way to do this with NIO? | ||||
|     File myconfFile = myconf.toFile(); | ||||
|     myconfFile.setWritable(false, false /* all */); | ||||
|     myconfFile.setReadable(false, false /* all */); | ||||
|     myconfFile.setExecutable(false, false /* all */); | ||||
|  | ||||
|     myconf.setWritable(true, true /* owner only */); | ||||
|     myconf.setReadable(true, true /* owner only */); | ||||
|     myconfFile.setWritable(true, true /* owner only */); | ||||
|     myconfFile.setReadable(true, true /* owner only */); | ||||
|  | ||||
|     _env.set("GIT_DIR", "."); | ||||
|     _env.set("GITWEB_CONFIG", myconf.getAbsolutePath()); | ||||
|     _env.set("GITWEB_CONFIG", myconf.toAbsolutePath().toString()); | ||||
|  | ||||
|     final PrintWriter p = new PrintWriter(new FileWriter(myconf)); | ||||
|     try { | ||||
|     try (PrintWriter p = | ||||
|         new PrintWriter(Files.newBufferedWriter(myconf, UTF_8))) { | ||||
|       p.print("# Autogenerated by Gerrit Code Review \n"); | ||||
|       p.print("# DO NOT EDIT\n"); | ||||
|       p.print("\n"); | ||||
| @@ -170,12 +175,12 @@ class GitWebServlet extends HttpServlet { | ||||
|       // We are mounted at the same level in the context as the main | ||||
|       // UI, so we can include the same header and footer scheme. | ||||
|       // | ||||
|       final File hdr = site.site_header; | ||||
|       if (hdr.isFile()) { | ||||
|       Path hdr = site.site_header; | ||||
|       if (Files.isRegularFile(hdr)) { | ||||
|         p.print("$site_header = " + quoteForPerl(hdr) + ";\n"); | ||||
|       } | ||||
|       final File ftr = site.site_footer; | ||||
|       if (ftr.isFile()) { | ||||
|       Path ftr = site.site_footer; | ||||
|       if (Files.isRegularFile(ftr)) { | ||||
|         p.print("$site_footer = " + quoteForPerl(ftr) + ";\n"); | ||||
|       } | ||||
|  | ||||
| @@ -188,8 +193,8 @@ class GitWebServlet extends HttpServlet { | ||||
|       p.print("$logo = 'gitweb-logo.png';\n"); | ||||
|       p.print("$javascript = 'gitweb.js';\n"); | ||||
|       p.print("@stylesheets = ('gitweb-default.css');\n"); | ||||
|       final File css = site.site_css; | ||||
|       if (css.isFile()) { | ||||
|       Path css = site.site_css; | ||||
|       if (Files.isRegularFile(css)) { | ||||
|         p.print("push @stylesheets, 'gitweb-site.css';\n"); | ||||
|       } | ||||
|  | ||||
| @@ -290,15 +295,15 @@ class GitWebServlet extends HttpServlet { | ||||
|       // If the administrator has created a site-specific gitweb_config, | ||||
|       // load that before we perform any final overrides. | ||||
|       // | ||||
|       final File sitecfg = site.site_gitweb; | ||||
|       if (sitecfg.isFile()) { | ||||
|       Path sitecfg = site.site_gitweb; | ||||
|       if (Files.isRegularFile(sitecfg)) { | ||||
|         p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n"); | ||||
|         p.print("if (-e $GITWEB_CONFIG) {\n"); | ||||
|         p.print("  do " + quoteForPerl(sitecfg) + ";\n"); | ||||
|         p.print("}\n"); | ||||
|       } | ||||
|  | ||||
|       final File root = repoManager.getBasePath(); | ||||
|       Path root = repoManager.getBasePath().toPath(); | ||||
|       p.print("$projectroot = " + quoteForPerl(root) + ";\n"); | ||||
|  | ||||
|       // Permit exporting only the project we were started for. | ||||
| @@ -322,18 +327,16 @@ class GitWebServlet extends HttpServlet { | ||||
|       // | ||||
|       p.print("$feature{'forks'}{'override'} = 0;\n"); | ||||
|       p.print("$feature{'forks'}{'default'} = [0];\n"); | ||||
|     } finally { | ||||
|       p.close(); | ||||
|     } | ||||
|  | ||||
|     myconf.setReadOnly(); | ||||
|     myconfFile.setReadOnly(); | ||||
|   } | ||||
|  | ||||
|   private String quoteForPerl(File value) { | ||||
|     return quoteForPerl(value.getAbsolutePath()); | ||||
|   private static String quoteForPerl(Path value) { | ||||
|     return quoteForPerl(value.toAbsolutePath().toString()); | ||||
|   } | ||||
|  | ||||
|   private String quoteForPerl(String value) { | ||||
|   private static String quoteForPerl(String value) { | ||||
|     if (value == null || value.isEmpty()) { | ||||
|       return "''"; | ||||
|     } | ||||
| @@ -442,9 +445,10 @@ class GitWebServlet extends HttpServlet { | ||||
|   private void exec(final HttpServletRequest req, | ||||
|       final HttpServletResponse rsp, final ProjectControl project) throws IOException { | ||||
|     final Process proc = | ||||
|         Runtime.getRuntime().exec(new String[] {gitwebCgi.getAbsolutePath()}, | ||||
|         Runtime.getRuntime().exec( | ||||
|             new String[] {gitwebCgi.toAbsolutePath().toString()}, | ||||
|             makeEnv(req, project), | ||||
|             gitwebCgi.getAbsoluteFile().getParentFile()); | ||||
|             gitwebCgi.toAbsolutePath().getParent().toFile()); | ||||
|  | ||||
|     copyStderrToLog(proc.getErrorStream()); | ||||
|     if (0 < req.getContentLength()) { | ||||
| @@ -522,7 +526,7 @@ class GitWebServlet extends HttpServlet { | ||||
|     // | ||||
|     env.set("REQUEST_METHOD", req.getMethod()); | ||||
|     env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath()); | ||||
|     env.set("SCRIPT_FILENAME", gitwebCgi.getAbsolutePath()); | ||||
|     env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString()); | ||||
|     env.set("SERVER_NAME", req.getServerName()); | ||||
|     env.set("SERVER_PORT", Integer.toString(req.getServerPort())); | ||||
|     env.set("SERVER_PROTOCOL", req.getProtocol()); | ||||
|   | ||||
| @@ -14,6 +14,8 @@ | ||||
|  | ||||
| package com.google.gerrit.httpd.raw; | ||||
|  | ||||
| import static java.nio.file.Files.getLastModifiedTime; | ||||
|  | ||||
| import com.google.common.base.Strings; | ||||
| import com.google.common.collect.Lists; | ||||
| import com.google.common.hash.Hasher; | ||||
| @@ -47,12 +49,13 @@ import org.w3c.dom.Document; | ||||
| import org.w3c.dom.Element; | ||||
| import org.w3c.dom.Node; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.io.StringWriter; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.attribute.FileTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -160,16 +163,13 @@ public class HostPageServlet extends HttpServlet { | ||||
|  | ||||
|   private Page get() { | ||||
|     Page p = page; | ||||
|     if (refreshHeaderFooter && p.isStale()) { | ||||
|       final Page newPage; | ||||
|       try { | ||||
|         newPage = new Page(); | ||||
|       } catch (IOException e) { | ||||
|         log.error("Cannot refresh site header/footer", e); | ||||
|         return p; | ||||
|     try { | ||||
|       if (refreshHeaderFooter && p.isStale()) { | ||||
|         p = new Page(); | ||||
|         page = p; | ||||
|       } | ||||
|       p = newPage; | ||||
|       page = p; | ||||
|     } catch (IOException e) { | ||||
|       log.error("Cannot refresh site header/footer", e); | ||||
|     } | ||||
|     return p; | ||||
|   } | ||||
| @@ -288,16 +288,16 @@ public class HostPageServlet extends HttpServlet { | ||||
|   } | ||||
|  | ||||
|   private static class FileInfo { | ||||
|     private final File path; | ||||
|     private final long time; | ||||
|     private final Path path; | ||||
|     private final FileTime time; | ||||
|  | ||||
|     FileInfo(final File p) { | ||||
|     FileInfo(Path p) throws IOException { | ||||
|       path = p; | ||||
|       time = path.lastModified(); | ||||
|       time = getLastModifiedTime(path); | ||||
|     } | ||||
|  | ||||
|     boolean isStale() { | ||||
|       return time != path.lastModified(); | ||||
|     boolean isStale() throws IOException { | ||||
|       return !time.equals(getLastModifiedTime(path)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -340,7 +340,7 @@ public class HostPageServlet extends HttpServlet { | ||||
|       debug = new Content(hostDoc); | ||||
|     } | ||||
|  | ||||
|     boolean isStale() { | ||||
|     boolean isStale() throws IOException { | ||||
|       return css.isStale() || header.isStale() || footer.isStale(); | ||||
|     } | ||||
|  | ||||
| @@ -364,8 +364,8 @@ public class HostPageServlet extends HttpServlet { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     private FileInfo injectCssFile(final Document hostDoc, final String id, | ||||
|         final File src) throws IOException { | ||||
|     private FileInfo injectCssFile(Document hostDoc, String id, Path src) | ||||
|         throws IOException { | ||||
|       final FileInfo info = new FileInfo(src); | ||||
|       final Element banner = HtmlDomUtil.find(hostDoc, id); | ||||
|       if (banner == null) { | ||||
| @@ -376,7 +376,8 @@ public class HostPageServlet extends HttpServlet { | ||||
|         banner.removeChild(banner.getFirstChild()); | ||||
|       } | ||||
|  | ||||
|       String css = HtmlDomUtil.readFile(src.getParentFile(), src.getName()); | ||||
|       String css = | ||||
|           HtmlDomUtil.readFile(src.getParent(), src.getFileName().toString()); | ||||
|       if (css == null) { | ||||
|         return info; | ||||
|       } | ||||
| @@ -385,8 +386,8 @@ public class HostPageServlet extends HttpServlet { | ||||
|       return info; | ||||
|     } | ||||
|  | ||||
|     private FileInfo injectXmlFile(final Document hostDoc, final String id, | ||||
|         final File src) throws IOException { | ||||
|     private FileInfo injectXmlFile(Document hostDoc, String id, Path src) | ||||
|         throws IOException { | ||||
|       final FileInfo info = new FileInfo(src); | ||||
|       final Element banner = HtmlDomUtil.find(hostDoc, id); | ||||
|       if (banner == null) { | ||||
|   | ||||
| @@ -27,8 +27,10 @@ import org.slf4j.LoggerFactory; | ||||
| import org.w3c.dom.Document; | ||||
| import org.w3c.dom.Element; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.attribute.FileTime; | ||||
|  | ||||
| @Singleton | ||||
| public class SiteHeaderFooter { | ||||
| @@ -43,13 +45,13 @@ public class SiteHeaderFooter { | ||||
|     this.refreshHeaderFooter = cfg.getBoolean("site", "refreshHeaderFooter", true); | ||||
|     this.sitePaths = sitePaths; | ||||
|  | ||||
|     Template t = new Template(sitePaths); | ||||
|     try { | ||||
|       Template t = new Template(sitePaths); | ||||
|       t.load(); | ||||
|       template = t; | ||||
|     } catch (IOException e) { | ||||
|       log.warn("Cannot load site header or footer", e); | ||||
|     } | ||||
|     template = t; | ||||
|   } | ||||
|  | ||||
|   public Document parse(Class<?> clazz, String name) throws IOException { | ||||
| @@ -110,7 +112,7 @@ public class SiteHeaderFooter { | ||||
|     Element header; | ||||
|     Element footer; | ||||
|  | ||||
|     Template(SitePaths site) { | ||||
|     Template(SitePaths site) throws IOException { | ||||
|       cssFile = new FileInfo(site.site_css); | ||||
|       headerFile = new FileInfo(site.site_header); | ||||
|       footerFile = new FileInfo(site.site_footer); | ||||
| @@ -118,13 +120,13 @@ public class SiteHeaderFooter { | ||||
|  | ||||
|     void load() throws IOException { | ||||
|       css = HtmlDomUtil.readFile( | ||||
|           cssFile.path.getParentFile(), | ||||
|           cssFile.path.getName()); | ||||
|           cssFile.path.getParent(), | ||||
|           cssFile.path.getFileName().toString()); | ||||
|       header = readXml(headerFile); | ||||
|       footer = readXml(footerFile); | ||||
|     } | ||||
|  | ||||
|     boolean isStale() { | ||||
|     boolean isStale() throws IOException { | ||||
|       return cssFile.isStale() || headerFile.isStale() || footerFile.isStale(); | ||||
|     } | ||||
|  | ||||
| @@ -135,16 +137,16 @@ public class SiteHeaderFooter { | ||||
|   } | ||||
|  | ||||
|   private static class FileInfo { | ||||
|     final File path; | ||||
|     final long time; | ||||
|     final Path path; | ||||
|     final FileTime time; | ||||
|  | ||||
|     FileInfo(File p) { | ||||
|     FileInfo(Path p) throws IOException { | ||||
|       path = p; | ||||
|       time = path.lastModified(); | ||||
|       time = Files.getLastModifiedTime(path); | ||||
|     } | ||||
|  | ||||
|     boolean isStale() { | ||||
|       return time != path.lastModified(); | ||||
|     boolean isStale() throws IOException { | ||||
|       return !time.equals(Files.getLastModifiedTime(path)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -16,6 +16,8 @@ package com.google.gerrit.pgm; | ||||
|  | ||||
| import static com.google.gerrit.server.schema.DataSourceProvider.Context.MULTI_USER; | ||||
|  | ||||
| import static java.nio.charset.StandardCharsets.UTF_8; | ||||
|  | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import com.google.common.base.MoreObjects; | ||||
| import com.google.gerrit.common.ChangeHookRunner; | ||||
| @@ -92,10 +94,10 @@ import org.kohsuke.args4j.Option; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.lang.Thread.UncaughtExceptionHandler; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -147,7 +149,7 @@ public class Daemon extends SiteProgram { | ||||
|   private Injector sshInjector; | ||||
|   private Injector webInjector; | ||||
|   private Injector httpdInjector; | ||||
|   private File runFile; | ||||
|   private Path runFile; | ||||
|   private boolean test; | ||||
|   private AbstractModule luceneModule; | ||||
|  | ||||
| @@ -183,7 +185,7 @@ public class Daemon extends SiteProgram { | ||||
|     }); | ||||
|  | ||||
|     if (runId != null) { | ||||
|       runFile = new File(new File(getSitePath(), "logs"), "gerrit.run"); | ||||
|       runFile = getSitePath().resolve("logs").resolve("gerrit.run"); | ||||
|     } | ||||
|  | ||||
|     if (httpd == null) { | ||||
| @@ -207,7 +209,11 @@ public class Daemon extends SiteProgram { | ||||
|         public void run() { | ||||
|           log.info("caught shutdown, cleaning up"); | ||||
|           if (runId != null) { | ||||
|             runFile.delete(); | ||||
|             try { | ||||
|               Files.delete(runFile); | ||||
|             } catch (IOException err) { | ||||
|               log.warn("failed to delete " + runFile, err); | ||||
|             } | ||||
|           } | ||||
|           manager.stop(); | ||||
|         } | ||||
| @@ -216,15 +222,8 @@ public class Daemon extends SiteProgram { | ||||
|       log.info("Gerrit Code Review " + myVersion() + " ready"); | ||||
|       if (runId != null) { | ||||
|         try { | ||||
|           runFile.createNewFile(); | ||||
|           runFile.setReadable(true, false); | ||||
|  | ||||
|           FileOutputStream out = new FileOutputStream(runFile); | ||||
|           try { | ||||
|             out.write((runId + "\n").getBytes("UTF-8")); | ||||
|           } finally { | ||||
|             out.close(); | ||||
|           } | ||||
|           Files.write(runFile, (runId + "\n").getBytes(UTF_8)); | ||||
|           runFile.toFile().setReadable(true, false); | ||||
|         } catch (IOException err) { | ||||
|           log.warn("Cannot write --run-id to " + runFile, err); | ||||
|         } | ||||
|   | ||||
| @@ -37,8 +37,8 @@ import com.google.inject.util.Providers; | ||||
|  | ||||
| import org.kohsuke.args4j.Option; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -70,7 +70,7 @@ public class Init extends BaseInit { | ||||
|     super(new WarDistribution(), null); | ||||
|   } | ||||
|  | ||||
|   public Init(File sitePath) { | ||||
|   public Init(Path sitePath) { | ||||
|     super(sitePath, true, true, new WarDistribution(), null); | ||||
|     batchMode = true; | ||||
|     noAutoStart = true; | ||||
| @@ -106,7 +106,7 @@ public class Init extends BaseInit { | ||||
|     modules.add(new AbstractModule() { | ||||
|       @Override | ||||
|       protected void configure() { | ||||
|         bind(File.class).annotatedWith(SitePath.class).toInstance(getSitePath()); | ||||
|         bind(Path.class).annotatedWith(SitePath.class).toInstance(getSitePath()); | ||||
|         bind(Browser.class); | ||||
|         bind(String.class).annotatedWith(SecureStoreClassName.class) | ||||
|             .toProvider(Providers.of(getConfiguredSecureStoreClass())); | ||||
|   | ||||
| @@ -59,6 +59,11 @@ import org.slf4j.LoggerFactory; | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.FileVisitResult; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.SimpleFileVisitor; | ||||
| import java.nio.file.attribute.BasicFileAttributes; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.Iterator; | ||||
| @@ -86,12 +91,12 @@ public class BaseInit extends SiteProgram { | ||||
|     this.pluginsToInstall = pluginsToInstall; | ||||
|   } | ||||
|  | ||||
|   public BaseInit(File sitePath, boolean standalone, boolean initDb, | ||||
|   public BaseInit(Path sitePath, boolean standalone, boolean initDb, | ||||
|       PluginsDistribution pluginsDistribution, List<String> pluginsToInstall) { | ||||
|     this(sitePath, null, standalone, initDb, pluginsDistribution, pluginsToInstall); | ||||
|   } | ||||
|  | ||||
|   public BaseInit(File sitePath, final Provider<DataSource> dsProvider, | ||||
|   public BaseInit(Path sitePath, final Provider<DataSource> dsProvider, | ||||
|       boolean standalone, boolean initDb, | ||||
|       PluginsDistribution pluginsDistribution, List<String> pluginsToInstall) { | ||||
|     super(sitePath, dsProvider); | ||||
| @@ -132,7 +137,7 @@ public class BaseInit extends SiteProgram { | ||||
|       throw failure; | ||||
|     } | ||||
|  | ||||
|     System.err.println("Initialized " + getSitePath().getCanonicalPath()); | ||||
|     System.err.println("Initialized " + getSitePath().toRealPath().normalize()); | ||||
|     afterInit(run); | ||||
|     return 0; | ||||
|   } | ||||
| @@ -208,7 +213,7 @@ public class BaseInit extends SiteProgram { | ||||
|  | ||||
|   private SiteInit createSiteInit() { | ||||
|     final ConsoleUI ui = getConsoleUI(); | ||||
|     final File sitePath = getSitePath(); | ||||
|     final Path sitePath = getSitePath(); | ||||
|     final List<Module> m = new ArrayList<>(); | ||||
|     final SecureStoreInitData secureStoreInitData = discoverSecureStoreClass(); | ||||
|     final String currentSecureStoreClassName = getConfiguredSecureStoreClass(); | ||||
| @@ -228,7 +233,7 @@ public class BaseInit extends SiteProgram { | ||||
|       @Override | ||||
|       protected void configure() { | ||||
|         bind(ConsoleUI.class).toInstance(ui); | ||||
|         bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         List<String> plugins = | ||||
|             MoreObjects.firstNonNull( | ||||
|                 getInstallPlugins(), Lists.<String> newArrayList()); | ||||
| @@ -408,15 +413,41 @@ public class BaseInit extends SiteProgram { | ||||
|     return sysInjector; | ||||
|   } | ||||
|  | ||||
|   private static void recursiveDelete(File path) { | ||||
|     File[] entries = path.listFiles(); | ||||
|     if (entries != null) { | ||||
|       for (File e : entries) { | ||||
|         recursiveDelete(e); | ||||
|       } | ||||
|     } | ||||
|     if (!path.delete() && path.exists()) { | ||||
|       System.err.println("warn: Cannot remove " + path); | ||||
|   private static void recursiveDelete(Path path) { | ||||
|     final String msg = "warn: Cannot remove "; | ||||
|     try { | ||||
|       Files.walkFileTree(path, new SimpleFileVisitor<Path>() { | ||||
|         @Override | ||||
|         public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) | ||||
|             throws IOException { | ||||
|           try { | ||||
|             Files.delete(f); | ||||
|           } catch (IOException e) { | ||||
|             System.err.println(msg + f); | ||||
|           } | ||||
|           return FileVisitResult.CONTINUE; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public FileVisitResult postVisitDirectory(Path dir, IOException err) { | ||||
|           try { | ||||
|             // Previously warned if err was not null; if dir is not empty as a | ||||
|             // result, will cause an error that will be logged below. | ||||
|             Files.delete(dir); | ||||
|           } catch (IOException e) { | ||||
|             System.err.println(msg + dir); | ||||
|           } | ||||
|           return FileVisitResult.CONTINUE; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public FileVisitResult visitFileFailed(Path f, IOException e) { | ||||
|           System.err.println(msg + f); | ||||
|           return FileVisitResult.CONTINUE; | ||||
|         } | ||||
|       }); | ||||
|     } catch (IOException e) { | ||||
|       System.err.println(msg + path); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,8 @@ import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| import java.net.UnknownHostException; | ||||
| import java.nio.ByteBuffer; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| /** Utility functions to help initialize a site. */ | ||||
| public class InitUtil { | ||||
| @@ -51,9 +53,18 @@ public class InitUtil { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public static void mkdir(final File path) { | ||||
|     if (!path.isDirectory() && !path.mkdir()) { | ||||
|       throw die("Cannot make directory " + path); | ||||
|   public static void mkdir(File file) { | ||||
|     mkdir(file.toPath()); | ||||
|   } | ||||
|  | ||||
|   public static void mkdir(Path path) { | ||||
|     if (Files.isDirectory(path)) { | ||||
|       return; | ||||
|     } | ||||
|     try { | ||||
|       Files.createDirectory(path); | ||||
|     } catch (IOException e) { | ||||
|       throw die("Cannot make directory " + path, e); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import org.apache.log4j.PatternLayout; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| public class ErrorLogFile { | ||||
|   static final String LOG_NAME = "error_log"; | ||||
| @@ -47,7 +48,7 @@ public class ErrorLogFile { | ||||
|     root.addAppender(dst); | ||||
|   } | ||||
|  | ||||
|   public static LifecycleListener start(final File sitePath) | ||||
|   public static LifecycleListener start(final Path sitePath) | ||||
|       throws FileNotFoundException { | ||||
|     final File logdir = new SitePaths(sitePath).logs_dir; | ||||
|     if (!logdir.exists() && !logdir.mkdirs()) { | ||||
|   | ||||
| @@ -26,10 +26,11 @@ import org.apache.log4j.PatternLayout; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| public class GarbageCollectionLogFile { | ||||
|  | ||||
|   public static LifecycleListener start(File sitePath) | ||||
|   public static LifecycleListener start(Path sitePath) | ||||
|       throws FileNotFoundException { | ||||
|     File logdir = new SitePaths(sitePath).logs_dir; | ||||
|     if (!logdir.exists() && !logdir.mkdirs()) { | ||||
|   | ||||
| @@ -54,9 +54,11 @@ import org.eclipse.jgit.storage.file.FileBasedConfig; | ||||
| import org.eclipse.jgit.util.FS; | ||||
| import org.kohsuke.args4j.Option; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.lang.annotation.Annotation; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.sql.Connection; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| @@ -66,30 +68,30 @@ import javax.sql.DataSource; | ||||
|  | ||||
| public abstract class SiteProgram extends AbstractProgram { | ||||
|   @Option(name = "--site-path", aliases = {"-d"}, usage = "Local directory containing site data") | ||||
|   private File sitePath = new File("."); | ||||
|   private void setSitePath(String path) { | ||||
|     sitePath = Paths.get(path); | ||||
|   } | ||||
|  | ||||
|   protected Provider<DataSource> dsProvider; | ||||
|  | ||||
|   private Path sitePath; | ||||
|  | ||||
|   protected SiteProgram() { | ||||
|   } | ||||
|  | ||||
|   protected SiteProgram(File sitePath, final Provider<DataSource> dsProvider) { | ||||
|   protected SiteProgram(Path sitePath, final Provider<DataSource> dsProvider) { | ||||
|     this.sitePath = sitePath; | ||||
|     this.dsProvider = dsProvider; | ||||
|   } | ||||
|  | ||||
|   /** @return the site path specified on the command line. */ | ||||
|   protected File getSitePath() { | ||||
|     File path = sitePath.getAbsoluteFile(); | ||||
|     if (".".equals(path.getName())) { | ||||
|       path = path.getParentFile(); | ||||
|     } | ||||
|     return path; | ||||
|   protected Path getSitePath() { | ||||
|     return sitePath; | ||||
|   } | ||||
|  | ||||
|   /** Ensures we are running inside of a valid site, otherwise throws a Die. */ | ||||
|   protected void mustHaveValidSite() throws Die { | ||||
|     if (!new File(new File(getSitePath(), "etc"), "gerrit.config").exists()) { | ||||
|     if (!Files.exists(sitePath.resolve("etc").resolve("gerrit.config"))) { | ||||
|       throw die("not a Gerrit site: '" + getSitePath() + "'\n" | ||||
|           + "Perhaps you need to run init first?"); | ||||
|     } | ||||
| @@ -97,13 +99,13 @@ public abstract class SiteProgram extends AbstractProgram { | ||||
|  | ||||
|   /** @return provides database connectivity and site path. */ | ||||
|   protected Injector createDbInjector(final DataSourceProvider.Context context) { | ||||
|     final File sitePath = getSitePath(); | ||||
|     final Path sitePath = getSitePath(); | ||||
|     final List<Module> modules = new ArrayList<>(); | ||||
|  | ||||
|     Module sitePathModule = new AbstractModule() { | ||||
|       @Override | ||||
|       protected void configure() { | ||||
|         bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(String.class).annotatedWith(SecureStoreClassName.class) | ||||
|             .toProvider(Providers.of(getConfiguredSecureStoreClass())); | ||||
|       } | ||||
| @@ -191,7 +193,7 @@ public abstract class SiteProgram extends AbstractProgram { | ||||
|     Module m = new AbstractModule() { | ||||
|       @Override | ||||
|       protected void configure() { | ||||
|         bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(SitePaths.class); | ||||
|       } | ||||
|     }; | ||||
| @@ -222,7 +224,7 @@ public abstract class SiteProgram extends AbstractProgram { | ||||
|     modules.add(new AbstractModule() { | ||||
|       @Override | ||||
|       protected void configure() { | ||||
|         bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|       } | ||||
|     }); | ||||
|     modules.add(new GerritServerConfigModule()); | ||||
|   | ||||
| @@ -16,11 +16,11 @@ package com.google.gerrit.pgm.init; | ||||
|  | ||||
| import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| public abstract class InitTestCase extends LocalDiskRepositoryTestCase { | ||||
|   protected File newSitePath() throws IOException { | ||||
|     return new File(createWorkRepository().getWorkTree(), "test_site"); | ||||
|   protected Path newSitePath() throws IOException { | ||||
|     return createWorkRepository().getWorkTree().toPath().resolve("test_site"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -25,13 +25,13 @@ import com.google.inject.Provider; | ||||
|  | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| public class LibrariesTest { | ||||
|   @Test | ||||
|   public void testCreate() throws FileNotFoundException { | ||||
|     final SitePaths site = new SitePaths(new File(".")); | ||||
|     final SitePaths site = new SitePaths(Paths.get(".")); | ||||
|     final ConsoleUI ui = createStrictMock(ConsoleUI.class); | ||||
|  | ||||
|     replay(ui); | ||||
|   | ||||
| @@ -14,6 +14,8 @@ | ||||
|  | ||||
| package com.google.gerrit.pgm.init; | ||||
|  | ||||
| import static java.nio.charset.StandardCharsets.UTF_8; | ||||
|  | ||||
| import static org.easymock.EasyMock.createStrictMock; | ||||
| import static org.easymock.EasyMock.eq; | ||||
| import static org.easymock.EasyMock.expect; | ||||
| @@ -38,9 +40,9 @@ import org.eclipse.jgit.util.IO; | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileWriter; | ||||
| import java.io.IOException; | ||||
| import java.io.Writer; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -49,23 +51,18 @@ public class UpgradeFrom2_0_xTest extends InitTestCase { | ||||
|  | ||||
|   @Test | ||||
|   public void testUpgrade() throws IOException, ConfigInvalidException { | ||||
|     final File p = newSitePath(); | ||||
|     final Path p = newSitePath(); | ||||
|     final SitePaths site = new SitePaths(p); | ||||
|     assertTrue(site.isNew); | ||||
|     assertTrue(site.site_path.mkdir()); | ||||
|     assertTrue(site.etc_dir.mkdir()); | ||||
|  | ||||
|     for (String n : UpgradeFrom2_0_x.etcFiles) { | ||||
|       Writer w = new FileWriter(new File(p, n)); | ||||
|       try { | ||||
|         w.write("# " + n + "\n"); | ||||
|       } finally { | ||||
|         w.close(); | ||||
|       } | ||||
|       Files.write(p.resolve(n), ("# " + n + "\n").getBytes(UTF_8)); | ||||
|     } | ||||
|  | ||||
|     FileBasedConfig old = | ||||
|         new FileBasedConfig(new File(p, "gerrit.config"), FS.DETECTED); | ||||
|         new FileBasedConfig(p.resolve("gerrit.config").toFile(), FS.DETECTED); | ||||
|  | ||||
|     old.setString("ldap", null, "username", "ldap.user"); | ||||
|     old.setString("ldap", null, "password", "ldap.s3kr3t"); | ||||
| @@ -85,8 +82,11 @@ public class UpgradeFrom2_0_xTest extends InitTestCase { | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     expect(ui.yesno(eq(true), eq("Upgrade '%s'"), eq(p.getCanonicalPath()))) | ||||
|         .andReturn(true); | ||||
|     expect(ui.yesno( | ||||
|         eq(true), | ||||
|         eq("Upgrade '%s'"), | ||||
|         eq(p.toRealPath().normalize().toString()))) | ||||
|       .andReturn(true); | ||||
|     replay(ui); | ||||
|  | ||||
|     UpgradeFrom2_0_x u = new UpgradeFrom2_0_x(site, flags, ui, sections); | ||||
|   | ||||
| @@ -24,7 +24,6 @@ import com.google.inject.Inject; | ||||
| import org.eclipse.jgit.internal.storage.file.WindowCacheStatAccessor; | ||||
| import org.kohsuke.args4j.Option; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.lang.management.ManagementFactory; | ||||
| import java.lang.management.OperatingSystemMXBean; | ||||
| @@ -33,6 +32,8 @@ import java.lang.management.ThreadInfo; | ||||
| import java.lang.management.ThreadMXBean; | ||||
| import java.net.InetAddress; | ||||
| import java.net.UnknownHostException; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| @@ -43,7 +44,7 @@ import java.util.Map; | ||||
| public class GetSummary implements RestReadView<ConfigResource> { | ||||
|  | ||||
|   private final WorkQueue workQueue; | ||||
|   private final File sitePath; | ||||
|   private final Path sitePath; | ||||
|  | ||||
|   @Option(name = "--gc", usage = "perform Java GC before retrieving memory stats") | ||||
|   private boolean gc; | ||||
| @@ -62,7 +63,7 @@ public class GetSummary implements RestReadView<ConfigResource> { | ||||
|   } | ||||
|  | ||||
|   @Inject | ||||
|   public GetSummary(WorkQueue workQueue, @SitePath File sitePath) { | ||||
|   public GetSummary(WorkQueue workQueue, @SitePath Path sitePath) { | ||||
|     this.workQueue = workQueue; | ||||
|     this.sitePath = sitePath; | ||||
|   } | ||||
| @@ -186,7 +187,8 @@ public class GetSummary implements RestReadView<ConfigResource> { | ||||
|     } catch (UnknownHostException e) { | ||||
|     } | ||||
|  | ||||
|     jvmSummary.currentWorkingDirectory = path(new File(".").getAbsoluteFile().getParentFile()); | ||||
|     jvmSummary.currentWorkingDirectory = | ||||
|         path(Paths.get(".").toAbsolutePath().getParent()); | ||||
|     jvmSummary.site = path(sitePath); | ||||
|     return jvmSummary; | ||||
|   } | ||||
| @@ -210,11 +212,11 @@ public class GetSummary implements RestReadView<ConfigResource> { | ||||
|     return String.format("%1$6.2f%2$s", value, suffix).trim(); | ||||
|   } | ||||
|  | ||||
|   private static String path(File file) { | ||||
|   private static String path(Path path) { | ||||
|     try { | ||||
|       return file.getCanonicalPath(); | ||||
|       return path.toRealPath().normalize().toString(); | ||||
|     } catch (IOException err) { | ||||
|       return file.getAbsolutePath(); | ||||
|       return path.toAbsolutePath().normalize().toString(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import com.google.inject.Singleton; | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| /** Important paths within a {@link SitePath}. */ | ||||
| @Singleton | ||||
| @@ -32,7 +33,7 @@ public final class SitePaths { | ||||
|   public final File bin_dir; | ||||
|   public final File etc_dir; | ||||
|   public final File lib_dir; | ||||
|   public final File tmp_dir; | ||||
|   public final Path tmp_dir; | ||||
|   public final File logs_dir; | ||||
|   public final File plugins_dir; | ||||
|   public final File data_dir; | ||||
| @@ -55,22 +56,24 @@ public final class SitePaths { | ||||
|   public final File ssh_dsa; | ||||
|   public final File peer_keys; | ||||
|  | ||||
|   public final File site_css; | ||||
|   public final File site_header; | ||||
|   public final File site_footer; | ||||
|   public final File site_gitweb; | ||||
|   public final Path site_css; | ||||
|   public final Path site_header; | ||||
|   public final Path site_footer; | ||||
|   public final Path site_gitweb; | ||||
|  | ||||
|   /** {@code true} if {@link #site_path} has not been initialized. */ | ||||
|   public final boolean isNew; | ||||
|  | ||||
|   @Inject | ||||
|   public SitePaths(final @SitePath File sitePath) throws FileNotFoundException { | ||||
|     site_path = sitePath; | ||||
|   public SitePaths(final @SitePath Path sitePath) throws FileNotFoundException { | ||||
|     // TODO(dborowitz): Convert all of these to Paths. | ||||
|     site_path = sitePath.toFile(); | ||||
|     Path p = sitePath; | ||||
|  | ||||
|     bin_dir = new File(site_path, "bin"); | ||||
|     etc_dir = new File(site_path, "etc"); | ||||
|     lib_dir = new File(site_path, "lib"); | ||||
|     tmp_dir = new File(site_path, "tmp"); | ||||
|     tmp_dir = p.resolve("tmp"); | ||||
|     plugins_dir = new File(site_path, "plugins"); | ||||
|     data_dir = new File(site_path, "data"); | ||||
|     logs_dir = new File(site_path, "logs"); | ||||
| @@ -93,10 +96,11 @@ public final class SitePaths { | ||||
|     ssh_dsa = new File(etc_dir, "ssh_host_dsa_key"); | ||||
|     peer_keys = new File(etc_dir, "peer_keys"); | ||||
|  | ||||
|     site_css = new File(etc_dir, CSS_FILENAME); | ||||
|     site_header = new File(etc_dir, HEADER_FILENAME); | ||||
|     site_footer = new File(etc_dir, FOOTER_FILENAME); | ||||
|     site_gitweb = new File(etc_dir, "gitweb_config.perl"); | ||||
|     Path etcDirPath = etc_dir.toPath(); | ||||
|     site_css = etcDirPath.resolve(CSS_FILENAME); | ||||
|     site_header = etcDirPath.resolve(HEADER_FILENAME); | ||||
|     site_footer = etcDirPath.resolve(FOOTER_FILENAME); | ||||
|     site_gitweb = etcDirPath.resolve("gitweb_config.perl"); | ||||
|  | ||||
|     if (site_path.exists()) { | ||||
|       final String[] contents = site_path.list(); | ||||
|   | ||||
| @@ -33,7 +33,7 @@ import com.google.inject.Singleton; | ||||
| import org.eclipse.jgit.lib.Config; | ||||
| import org.eclipse.jgit.lib.PersonIdent; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| /** | ||||
|  * Copies critical objects from the {@code dbInjector} into a plugin. | ||||
| @@ -47,11 +47,11 @@ import java.io.File; | ||||
| class CopyConfigModule extends AbstractModule { | ||||
|   @Inject | ||||
|   @SitePath | ||||
|   private File sitePath; | ||||
|   private Path sitePath; | ||||
|  | ||||
|   @Provides | ||||
|   @SitePath | ||||
|   File getSitePath() { | ||||
|   Path getSitePath() { | ||||
|     return sitePath; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import java.io.InputStream; | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.net.URLClassLoader; | ||||
| import java.nio.file.Files; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| @@ -47,7 +48,8 @@ public class JarPluginProvider implements ServerPluginProvider { | ||||
|  | ||||
|   @Inject | ||||
|   JarPluginProvider(SitePaths sitePaths) { | ||||
|     tmpDir = sitePaths.tmp_dir; | ||||
|     // TODO(dborowitz): Convert to NIO. | ||||
|     tmpDir = sitePaths.tmp_dir.toFile(); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
| @@ -111,10 +113,11 @@ public class JarPluginProvider implements ServerPluginProvider { | ||||
|  | ||||
|   public static File storeInTemp(String pluginName, InputStream in, | ||||
|       SitePaths sitePaths) throws IOException { | ||||
|     if (!sitePaths.tmp_dir.exists()) { | ||||
|       sitePaths.tmp_dir.mkdirs(); | ||||
|     if (!Files.exists(sitePaths.tmp_dir)) { | ||||
|       Files.createDirectories(sitePaths.tmp_dir); | ||||
|     } | ||||
|     return asTemp(in, tempNameFor(pluginName), ".jar", sitePaths.tmp_dir); | ||||
|     return asTemp(in, tempNameFor(pluginName), ".jar", | ||||
|         sitePaths.tmp_dir.toFile()); | ||||
|   } | ||||
|  | ||||
|   private ServerPlugin loadJarPlugin(String name, File srcJar, | ||||
|   | ||||
| @@ -32,14 +32,14 @@ import com.google.inject.Inject; | ||||
| import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
| import org.eclipse.jgit.lib.PersonIdent; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Collections; | ||||
|  | ||||
| /** Creates the current database schema and populates initial code rows. */ | ||||
| public class SchemaCreator { | ||||
|   private final @SitePath | ||||
|   File site_path; | ||||
|   Path site_path; | ||||
|  | ||||
|   private final AllProjectsCreator allProjectsCreator; | ||||
|   private final AllUsersCreator allUsersCreator; | ||||
| @@ -55,10 +55,10 @@ public class SchemaCreator { | ||||
|       AllUsersCreator auc, | ||||
|       @GerritPersonIdent PersonIdent au, | ||||
|       DataSourceType dst) { | ||||
|     this(site.site_path, ap, auc, au, dst); | ||||
|     this(site.site_path.toPath(), ap, auc, au, dst); | ||||
|   } | ||||
|  | ||||
|   public SchemaCreator(@SitePath File site, | ||||
|   public SchemaCreator(@SitePath Path site, | ||||
|       AllProjectsCreator ap, | ||||
|       AllUsersCreator auc, | ||||
|       @GerritPersonIdent PersonIdent au, | ||||
| @@ -117,9 +117,9 @@ public class SchemaCreator { | ||||
|  | ||||
|     final SystemConfig s = SystemConfig.create(); | ||||
|     try { | ||||
|       s.sitePath = site_path.getCanonicalPath(); | ||||
|       s.sitePath = site_path.toRealPath().normalize().toString(); | ||||
|     } catch (IOException e) { | ||||
|       s.sitePath = site_path.getAbsolutePath(); | ||||
|       s.sitePath = site_path.toAbsolutePath().normalize().toString(); | ||||
|     } | ||||
|     c.systemConfig().insert(Collections.singleton(s)); | ||||
|     return s; | ||||
|   | ||||
| @@ -28,85 +28,86 @@ import org.junit.Test; | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
|  | ||||
| public class SitePathsTest { | ||||
|   @Test | ||||
|   public void testCreate_NotExisting() throws IOException { | ||||
|     final File root = random(); | ||||
|     final Path root = random(); | ||||
|     final SitePaths site = new SitePaths(root); | ||||
|     assertTrue(site.isNew); | ||||
|     assertEquals(root, site.site_path); | ||||
|     assertEquals(new File(root, "etc"), site.etc_dir); | ||||
|     assertEquals(root.toFile(), site.site_path); | ||||
|     assertEquals(root.resolve("etc").toFile(), site.etc_dir); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testCreate_Empty() throws IOException { | ||||
|     final File root = random(); | ||||
|     final Path root = random(); | ||||
|     try { | ||||
|       assertTrue(root.mkdir()); | ||||
|       Files.createDirectory(root); | ||||
|  | ||||
|       final SitePaths site = new SitePaths(root); | ||||
|       assertTrue(site.isNew); | ||||
|       assertEquals(root, site.site_path); | ||||
|       assertEquals(root.toFile(), site.site_path); | ||||
|     } finally { | ||||
|       root.delete(); | ||||
|       Files.delete(root); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testCreate_NonEmpty() throws IOException { | ||||
|     final File root = random(); | ||||
|     final File txt = new File(root, "test.txt"); | ||||
|     final Path root = random(); | ||||
|     final Path txt = root.resolve("test.txt"); | ||||
|     try { | ||||
|       assertTrue(root.mkdir()); | ||||
|       assertTrue(txt.createNewFile()); | ||||
|       Files.createDirectory(root); | ||||
|       Files.createFile(txt); | ||||
|  | ||||
|       final SitePaths site = new SitePaths(root); | ||||
|       assertFalse(site.isNew); | ||||
|       assertEquals(root, site.site_path); | ||||
|       assertEquals(root.toFile(), site.site_path); | ||||
|     } finally { | ||||
|       txt.delete(); | ||||
|       root.delete(); | ||||
|       Files.delete(txt); | ||||
|       Files.delete(root); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testCreate_NotDirectory() throws IOException { | ||||
|     final File root = random(); | ||||
|     final Path root = random(); | ||||
|     try { | ||||
|       assertTrue(root.createNewFile()); | ||||
|       Files.createFile(root); | ||||
|       try { | ||||
|         new SitePaths(root); | ||||
|         fail("Did not throw exception"); | ||||
|       } catch (FileNotFoundException e) { | ||||
|         assertEquals("Not a directory: " + root.getPath(), e.getMessage()); | ||||
|         assertEquals("Not a directory: " + root, e.getMessage()); | ||||
|       } | ||||
|     } finally { | ||||
|       root.delete(); | ||||
|       Files.delete(root); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testResolve() throws IOException { | ||||
|     final File root = random(); | ||||
|     final Path root = random(); | ||||
|     final SitePaths site = new SitePaths(root); | ||||
|  | ||||
|     assertNull(site.resolve(null)); | ||||
|     assertNull(site.resolve("")); | ||||
|  | ||||
|     assertNotNull(site.resolve("a")); | ||||
|     assertEquals(new File(root, "a").getCanonicalFile(), site.resolve("a")); | ||||
|     assertEquals(root.resolve("a").toAbsolutePath().normalize().toFile(), | ||||
|         site.resolve("a")); | ||||
|  | ||||
|     final String pfx = HostPlatform.isWin32() ? "C:/" : "/"; | ||||
|     assertNotNull(site.resolve(pfx + "a")); | ||||
|     assertEquals(new File(pfx + "a").getCanonicalFile(), site.resolve(pfx + "a")); | ||||
|   } | ||||
|  | ||||
|   private static File random() throws IOException { | ||||
|     File tmp = File.createTempFile("gerrit_test_", "_site"); | ||||
|     if (!tmp.delete()) { | ||||
|       throw new IOException("Cannot create " + tmp.getPath()); | ||||
|     } | ||||
|   private static Path random() throws IOException { | ||||
|     Path tmp = Files.createTempFile("gerrit_test_", "_site"); | ||||
|     Files.deleteIfExists(tmp); | ||||
|     return tmp; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -43,9 +43,10 @@ import org.junit.After; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
|  | ||||
| @@ -67,7 +68,7 @@ public class SchemaUpdaterTest { | ||||
|       IOException { | ||||
|     db.create(); | ||||
|  | ||||
|     final File site = new File(UUID.randomUUID().toString()); | ||||
|     final Path site = Paths.get(UUID.randomUUID().toString()); | ||||
|     final SitePaths paths = new SitePaths(site); | ||||
|     SchemaUpdater u = Guice.createInjector(new FactoryModule() { | ||||
|       @Override | ||||
|   | ||||
| @@ -69,11 +69,12 @@ import com.google.inject.servlet.RequestScoped; | ||||
| import org.eclipse.jgit.lib.Config; | ||||
| import org.eclipse.jgit.lib.PersonIdent; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.lang.reflect.Constructor; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.net.InetSocketAddress; | ||||
| import java.net.SocketAddress; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| public class InMemoryModule extends FactoryModule { | ||||
|   public static Config newDefaultConfig() { | ||||
| @@ -125,7 +126,8 @@ public class InMemoryModule extends FactoryModule { | ||||
|  | ||||
|     bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST); | ||||
|  | ||||
|     bind(File.class).annotatedWith(SitePath.class).toInstance(new File(".")); | ||||
|     // TODO(dborowitz): Use jimfs. | ||||
|     bind(Path.class).annotatedWith(SitePath.class).toInstance(Paths.get(".")); | ||||
|     bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg); | ||||
|     bind(SocketAddress.class).annotatedWith(RemotePeer.class).toInstance( | ||||
|         new InetSocketAddress(InetAddresses.forString("127.0.0.1"), 1234)); | ||||
|   | ||||
| @@ -20,7 +20,8 @@ import com.google.gerrit.pgm.init.PluginsDistribution; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.sql.Connection; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| @@ -47,21 +48,19 @@ public final class SiteInitializer { | ||||
|   public void init() { | ||||
|     try { | ||||
|       if (sitePath != null) { | ||||
|         File site = new File(sitePath); | ||||
|         LOG.info(String.format("Initializing site at %s", | ||||
|             site.getAbsolutePath())); | ||||
|         Path site = Paths.get(sitePath); | ||||
|         LOG.info("Initializing site at " + site.toRealPath().normalize()); | ||||
|         new BaseInit(site, false, true, pluginsDistribution, pluginsToInstall).run(); | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       try (Connection conn = connectToDb()) { | ||||
|         File site = getSiteFromReviewDb(conn); | ||||
|         Path site = getSiteFromReviewDb(conn); | ||||
|         if (site == null && initPath != null) { | ||||
|           site = new File(initPath); | ||||
|           site = Paths.get(initPath); | ||||
|         } | ||||
|         if (site != null) { | ||||
|           LOG.info(String.format("Initializing site at %s", | ||||
|               site.getAbsolutePath())); | ||||
|           LOG.info("Initializing site at " + site.toRealPath().normalize()); | ||||
|           new BaseInit(site, new ReviewDbDataSourceProvider(), false, false, | ||||
|               pluginsDistribution, pluginsToInstall).run(); | ||||
|         } | ||||
| @@ -76,12 +75,12 @@ public final class SiteInitializer { | ||||
|     return new ReviewDbDataSourceProvider().get().getConnection(); | ||||
|   } | ||||
|  | ||||
|   private File getSiteFromReviewDb(Connection conn) { | ||||
|   private Path getSiteFromReviewDb(Connection conn) { | ||||
|     try (Statement stmt = conn.createStatement(); | ||||
|         ResultSet rs = stmt.executeQuery( | ||||
|           "SELECT site_path FROM system_config")) { | ||||
|       if (rs.next()) { | ||||
|         return new File(rs.getString(1)); | ||||
|         return Paths.get(rs.getString(1)); | ||||
|       } | ||||
|     } catch (SQLException e) { | ||||
|       return null; | ||||
|   | ||||
| @@ -22,12 +22,13 @@ import com.google.gwtorm.server.SchemaFactory; | ||||
| import com.google.inject.Inject; | ||||
| import com.google.inject.Provider; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.List; | ||||
|  | ||||
| /** Provides {@link java.io.File} annotated with {@link SitePath}. */ | ||||
| class SitePathFromSystemConfigProvider implements Provider<File> { | ||||
|   private final File path; | ||||
| /** Provides {@link Path} annotated with {@link SitePath}. */ | ||||
| class SitePathFromSystemConfigProvider implements Provider<Path> { | ||||
|   private final Path path; | ||||
|  | ||||
|   @Inject | ||||
|   SitePathFromSystemConfigProvider(SchemaFactory<ReviewDb> schemaFactory) | ||||
| @@ -36,18 +37,18 @@ class SitePathFromSystemConfigProvider implements Provider<File> { | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public File get() { | ||||
|   public Path get() { | ||||
|     return path; | ||||
|   } | ||||
|  | ||||
|   private static File read(SchemaFactory<ReviewDb> schemaFactory) | ||||
|   private static Path read(SchemaFactory<ReviewDb> schemaFactory) | ||||
|       throws OrmException { | ||||
|     ReviewDb db = schemaFactory.open(); | ||||
|     try { | ||||
|       List<SystemConfig> all = db.systemConfig().all().toList(); | ||||
|       switch (all.size()) { | ||||
|         case 1: | ||||
|           return new File(all.get(0).sitePath); | ||||
|           return Paths.get(all.get(0).sitePath); | ||||
|         case 0: | ||||
|           throw new OrmException("system_config table is empty"); | ||||
|         default: | ||||
|   | ||||
| @@ -78,8 +78,9 @@ import org.eclipse.jgit.lib.Config; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| @@ -101,7 +102,7 @@ public class WebAppInitializer extends GuiceServletContextListener | ||||
|   private static final Logger log = | ||||
|       LoggerFactory.getLogger(WebAppInitializer.class); | ||||
|  | ||||
|   private File sitePath; | ||||
|   private Path sitePath; | ||||
|   private Injector dbInjector; | ||||
|   private Injector cfgInjector; | ||||
|   private Injector sysInjector; | ||||
| @@ -122,7 +123,7 @@ public class WebAppInitializer extends GuiceServletContextListener | ||||
|     if (manager == null) { | ||||
|       final String path = System.getProperty("gerrit.site_path"); | ||||
|       if (path != null) { | ||||
|         sitePath = new File(path); | ||||
|         sitePath = Paths.get(path); | ||||
|       } | ||||
|  | ||||
|       if (System.getProperty("gerrit.init") != null) { | ||||
| @@ -209,7 +210,7 @@ public class WebAppInitializer extends GuiceServletContextListener | ||||
|       Module sitePathModule = new AbstractModule() { | ||||
|         @Override | ||||
|         protected void configure() { | ||||
|           bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|           bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); | ||||
|         } | ||||
|       }; | ||||
|       modules.add(sitePathModule); | ||||
| @@ -261,7 +262,7 @@ public class WebAppInitializer extends GuiceServletContextListener | ||||
|       modules.add(new AbstractModule() { | ||||
|         @Override | ||||
|         protected void configure() { | ||||
|           bind(File.class).annotatedWith(SitePath.class).toProvider( | ||||
|           bind(Path.class).annotatedWith(SitePath.class).toProvider( | ||||
|               SitePathFromSystemConfigProvider.class).in(SINGLETON); | ||||
|         } | ||||
|       }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Dave Borowitz
					Dave Borowitz