Java tutorial
// 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 static com.google.inject.Scopes.SINGLETON; import static com.google.inject.Stage.PRODUCTION; import com.google.gerrit.lifecycle.LifecycleModule; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfigModule; import com.google.gerrit.server.config.SitePath; import com.google.gerrit.server.git.LocalDiskRepositoryManager; import com.google.gerrit.server.schema.DataSourceModule; import com.google.gerrit.server.schema.DataSourceProvider; import com.google.gerrit.server.schema.DataSourceType; import com.google.gerrit.server.schema.DatabaseModule; import com.google.gerrit.server.schema.SchemaModule; import com.google.gwtorm.server.OrmException; import com.google.inject.AbstractModule; import com.google.inject.CreationException; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; import com.google.inject.name.Names; import com.google.inject.spi.Message; import org.eclipse.jgit.lib.Config; import org.kohsuke.args4j.Option; import java.io.File; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; 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("."); protected SiteProgram() { } protected SiteProgram(File sitePath) { this.sitePath = sitePath; } /** @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; } /** 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()) { throw die("not a Gerrit site: '" + getSitePath() + "'\n" + "Perhaps you need to run init first?"); } } /** @return provides database connectivity and site path. */ protected Injector createDbInjector(final DataSourceProvider.Context context) { final File sitePath = getSitePath(); final List<Module> modules = new ArrayList<Module>(); Module sitePathModule = new AbstractModule() { @Override protected void configure() { bind(File.class).annotatedWith(SitePath.class).toInstance(sitePath); } }; modules.add(sitePathModule); modules.add(new LifecycleModule() { @Override protected void configure() { bind(DataSourceProvider.Context.class).toInstance(context); bind(Key.get(DataSource.class, Names.named("ReviewDb"))) .toProvider(SiteLibraryBasedDataSourceProvider.class).in(SINGLETON); listener().to(SiteLibraryBasedDataSourceProvider.class); } }); Module configModule = new GerritServerConfigModule(); modules.add(configModule); Injector cfgInjector = Guice.createInjector(sitePathModule, configModule); Config cfg = cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)); String dbType = cfg.getString("database", null, "type"); final DataSourceType dst = Guice.createInjector(new DataSourceModule(), configModule, sitePathModule) .getInstance(Key.get(DataSourceType.class, Names.named(dbType.toLowerCase()))); modules.add(new AbstractModule() { @Override protected void configure() { bind(DataSourceType.class).toInstance(dst); } }); modules.add(new DatabaseModule()); modules.add(new SchemaModule()); modules.add(new LocalDiskRepositoryManager.Module()); try { return Guice.createInjector(PRODUCTION, modules); } catch (CreationException ce) { final Message first = ce.getErrorMessages().iterator().next(); Throwable why = first.getCause(); if (why instanceof SQLException) { throw die("Cannot connect to SQL database", why); } if (why instanceof OrmException && why.getCause() != null && "Unable to determine driver URL".equals(why.getMessage())) { why = why.getCause(); if (isCannotCreatePoolException(why)) { throw die("Cannot connect to SQL database", why.getCause()); } throw die("Cannot connect to SQL database", why); } final StringBuilder buf = new StringBuilder(); if (why != null) { buf.append(why.getMessage()); why = why.getCause(); } else { buf.append(first.getMessage()); } while (why != null) { buf.append("\n caused by "); buf.append(why.toString()); why = why.getCause(); } throw die(buf.toString(), new RuntimeException("DbInjector failed", ce)); } } @SuppressWarnings("deprecation") private static boolean isCannotCreatePoolException(Throwable why) { return why instanceof org.apache.commons.dbcp.SQLNestedException && why.getCause() != null && why.getMessage().startsWith("Cannot create PoolableConnectionFactory"); } }