init: Move optional library download configuration to config file

Shifting our optional library downloads setup into a configuration
file gets the URLs and SHA1 strings out of the source code and
into a nice clean text format we can more easily update later on.
It really was bothering me that this data was hardcoded into our
source in random spots throughout init.

Change-Id: Ie9493c7607242f58a3045813eb4c0ffa4e9aba51
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce 2009-12-16 19:15:17 -08:00
parent 92cb0d213a
commit 3bccd773c2
4 changed files with 150 additions and 26 deletions

View File

@ -23,7 +23,7 @@ import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.pgm.util.DataSourceProvider; import com.google.gerrit.pgm.util.DataSourceProvider;
import com.google.gerrit.pgm.util.ErrorLogFile; import com.google.gerrit.pgm.util.ErrorLogFile;
import com.google.gerrit.pgm.util.IoUtil; import com.google.gerrit.pgm.util.IoUtil;
import com.google.gerrit.pgm.util.LibraryDownloader; import com.google.gerrit.pgm.util.Libraries;
import com.google.gerrit.pgm.util.SiteProgram; import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.AuthType; import com.google.gerrit.reviewdb.AuthType;
import com.google.gerrit.reviewdb.Project; import com.google.gerrit.reviewdb.Project;
@ -91,6 +91,7 @@ public class Init extends SiteProgram {
private boolean isNew; private boolean isNew;
private boolean deleteOnFailure; private boolean deleteOnFailure;
private ConsoleUI ui; private ConsoleUI ui;
private Libraries libraries;
private Injector dbInjector; private Injector dbInjector;
private Injector sysInjector; private Injector sysInjector;
@ -113,6 +114,7 @@ public class Init extends SiteProgram {
public int run() throws Exception { public int run() throws Exception {
ErrorLogFile.errorOnlyConsole(); ErrorLogFile.errorOnlyConsole();
ui = ConsoleUI.getInstance(batchMode); ui = ConsoleUI.getInstance(batchMode);
libraries = new Libraries(ui, getSitePath());
initPathLocations(); initPathLocations();
if (site_path.exists()) { if (site_path.exists()) {
@ -389,9 +391,7 @@ public class Init extends SiteProgram {
private void downloadOptionalLibraries() { private void downloadOptionalLibraries() {
// Download and install BouncyCastle if the user wants to use it. // Download and install BouncyCastle if the user wants to use it.
// //
createDownloader().setRequired(false).setName("Bouncy Castle Crypto v144") libraries.bouncyCastle.downloadOptional();
.setJarUrl("http://www.bouncycastle.org/download/bcprov-jdk16-144.jar")
.setSHA1("6327a5f7a3dc45e0fd735adb5d08c5a74c05c20c").download();
loadSiteLib(); loadSiteLib();
} }
@ -421,12 +421,7 @@ public class Init extends SiteProgram {
switch (db_type) { switch (db_type) {
case MYSQL: case MYSQL:
createDownloader() libraries.mysqlDriver.downloadRequired();
.setRequired(true)
.setName("MySQL Connector/J 5.1.10")
.setJarUrl(
"http://repo2.maven.org/maven2/mysql/mysql-connector-java/5.1.10/mysql-connector-java-5.1.10.jar")
.setSHA1("b83574124f1a00d6f70d56ba64aa52b8e1588e6d").download();
loadSiteLib(); loadSiteLib();
break; break;
} }
@ -999,10 +994,6 @@ public class Init extends SiteProgram {
return dbInjector.createChildInjector(modules); return dbInjector.createChildInjector(modules);
} }
private LibraryDownloader createDownloader() {
return new LibraryDownloader(ui, getSitePath());
}
private static String version() { private static String version() {
return com.google.gerrit.common.Version.getVersion(); return com.google.gerrit.common.Version.getVersion();
} }

View File

@ -0,0 +1,107 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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.google.gerrit.pgm.util;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/** Standard {@link LibraryDownloader} instances derived from configuration. */
public class Libraries {
private static final String RESOURCE_FILE =
"com/google/gerrit/pgm/libraries.config";
private final ConsoleUI ui;
private final File sitePath;
public LibraryDownloader bouncyCastle;
public LibraryDownloader mysqlDriver;
public Libraries(final ConsoleUI ui, final File sitePath) {
this.ui = ui;
this.sitePath = sitePath;
init();
}
private void init() {
final Config cfg = new Config();
try {
cfg.fromText(read(RESOURCE_FILE));
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ConfigInvalidException e) {
throw new RuntimeException(e.getMessage(), e);
}
for (final Field f : Libraries.class.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0
&& f.getType() == LibraryDownloader.class) {
try {
init(f, cfg);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Cannot initialize " + f.getName());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Cannot initialize " + f.getName());
}
}
}
}
private void init(final Field field, final Config cfg)
throws IllegalArgumentException, IllegalAccessException {
final String n = field.getName();
final LibraryDownloader dl = new LibraryDownloader(ui, sitePath);
dl.setName(get(cfg, n, "name"));
dl.setJarUrl(get(cfg, n, "url"));
dl.setSHA1(get(cfg, n, "sha1"));
field.set(this, dl);
}
private static String get(Config cfg, String name, String key) {
String val = cfg.getString("library", name, key);
if (val == null || val.isEmpty()) {
throw new IllegalStateException("Variable library." + name + "." + key
+ " is required within " + RESOURCE_FILE);
}
return val;
}
private static String read(final String p) throws IOException {
InputStream in = Libraries.class.getClassLoader().getResourceAsStream(p);
if (in == null) {
throw new FileNotFoundException("Cannot load resource " + p);
}
final Reader r = new InputStreamReader(in, "UTF-8");
try {
final StringBuilder buf = new StringBuilder();
final char[] tmp = new char[512];
int n;
while (0 < (n = r.read(tmp))) {
buf.append(tmp, 0, n);
}
return buf.toString();
} finally {
r.close();
}
}
}

View File

@ -46,27 +46,29 @@ public class LibraryDownloader {
this.libDirectory = new File(sitePath, "lib"); this.libDirectory = new File(sitePath, "lib");
} }
public LibraryDownloader setRequired(final boolean required) { public void setName(final String name) {
this.required = required;
return this;
}
public LibraryDownloader setName(final String name) {
this.name = name; this.name = name;
return this;
} }
public LibraryDownloader setJarUrl(final String url) { public void setJarUrl(final String url) {
this.jarUrl = url; this.jarUrl = url;
return this;
} }
public LibraryDownloader setSHA1(final String sha1) { public void setSHA1(final String sha1) {
this.sha1 = sha1; this.sha1 = sha1;
return this;
} }
public void download() { public void downloadRequired() {
this.required = true;
download();
}
public void downloadOptional() {
this.required = false;
download();
}
private void download() {
if (jarUrl == null || !jarUrl.contains("/")) { if (jarUrl == null || !jarUrl.contains("/")) {
throw new IllegalStateException("Invalid JarUrl for " + name); throw new IllegalStateException("Invalid JarUrl for " + name);
} }

View File

@ -0,0 +1,24 @@
# Copyright (C) 2009 The Android Open Source Project
#
# 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.
[library "bouncyCastle"]
name = Bouncy Castle Crypto v144
url = http://www.bouncycastle.org/download/bcprov-jdk16-144.jar
sha1 = 6327a5f7a3dc45e0fd735adb5d08c5a74c05c20c
[library "mysqlDriver"]
name = MySQL Connector/J 5.1.10
url = http://repo2.maven.org/maven2/mysql/mysql-connector-java/5.1.10/mysql-connector-java-5.1.10.jar
sha1 = b83574124f1a00d6f70d56ba64aa52b8e1588e6d