Java tutorial
/** * Copyright 2010 CosmoCode GmbH * * 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 de.cosmocode.palava.core; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import com.google.common.io.Closeables; import com.google.common.io.Resources; import com.google.gag.annotation.disclaimer.LegacySucks; import com.google.gag.annotation.remark.RTFM; import com.google.gag.annotation.team.Blame; import com.google.inject.ConfigurationException; import com.google.inject.Inject; import com.google.inject.Module; import com.google.inject.ProvisionException; import com.google.inject.Stage; import de.cosmocode.palava.core.inject.Settings; /** * Static factory class for framework instances. * * @since 2.0 * @author Willi Schoenborn */ public final class Palava { private static final Logger LOG = LoggerFactory.getLogger(Palava.class); private static final String RESOURCE_NAME = "application.properties"; private static final Set<Framework> FRAMEWORKS = Sets.newHashSet(); private Palava() { } /** * Adds the given framework to the set of all frameworks * running in this virtual machine. * * @since 2.7 * @param framework the framework to be added * @throws NullPointerException if framework is null */ static void addFramework(Framework framework) { Preconditions.checkNotNull(framework, "Framework"); FRAMEWORKS.add(framework); } /** * Removes the given framework from the set of all frameworks * running in this virtual machine. * * @since 2.7 * @param framework the framework to be removed * @throws NullPointerException if framework is null */ static void removeFramework(Framework framework) { Preconditions.checkNotNull(framework, "Framework"); FRAMEWORKS.remove(framework); } /** * Provides a static access to the one and only framework instance * that is currently running. * * <p> * <strong>IMPORTANT:</strong> This sole purpose of this method * is to support static lookups via legacy apis. Use this method * with extreme caution and only if you really need to do so. * </p> * * @deprecated use {@link Inject} if possible * @since 2.7 * @return the current framework instance * @throws IllegalStateException if none or more than one framework has been started */ @Deprecated @LegacySucks @RTFM @Blame(person = "Tobias Sarnowski") public static Framework getCurrentFramework() { final int size = FRAMEWORKS.size(); Preconditions.checkState(size == 1, "Expected one framework to be started but was %s", size); return FRAMEWORKS.iterator().next(); } /** * Creates a new {@link Framework} using properties provided as a classpath * resource. * <p> * This method assumes there is a classpath resource named "application.properties". * </p> * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @return a new configured {@link Framework} instance * @throws IllegalArgumentException if the application.properties resource does not exist * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework() { return newFramework(Resources.getResource(RESOURCE_NAME)); } /** * Creates a new {@link Framework} using the specified module and properties * provided as a classpath resource. * <p> * This method assumes there is a classpath resource named "application.properties". * </p> * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @param module the application main module * @return a new configured {@link Framework} instance * @throws NullPointerException if module is null * @throws IllegalArgumentException if the application.properties resource does not exist * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Module module) { Preconditions.checkNotNull(module, "Module"); return newFramework(module, Resources.getResource(RESOURCE_NAME)); } /** * Creates a new {@link Framework} using a properties file. * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @param file the file pointing to the properties file * @return a new configured {@link Framework} instance * @throws NullPointerException if file is null * @throws IllegalArgumentException if the file does not exist * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(File file) { Preconditions.checkNotNull(file, "File"); Preconditions.checkArgument(file.exists(), "%s does not exist", file); try { return newFramework(file.toURI().toURL()); } catch (MalformedURLException e) { throw new IllegalArgumentException(e); } } /** * Creates a new {@link Framework} using a properties url. * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @param url the url pointing to the properties file * @return a new configured {@link Framework} instance * @throws NullPointerException if url is null * @throws IllegalArgumentException if reading from the specified url failed * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(URL url) { Preconditions.checkNotNull(url, "URL"); final InputStream stream; try { stream = url.openStream(); } catch (IOException e) { throw new IllegalArgumentException(e); } try { final Properties properties = new Properties(); properties.load(stream); return newFramework(properties); } catch (IOException e) { throw new IllegalArgumentException(e); } finally { Closeables.closeQuietly(stream); } } /** * Creates a new {@link Framework} using the specified module and * a properties file. * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @param module the application main module * @param file the file pointing to the properties file * @return a new configured {@link Framework} instance * @throws NullPointerException if module or file is null * @throws IllegalArgumentException if the file does not exist * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Module module, File file) { Preconditions.checkNotNull(module, "Module"); Preconditions.checkNotNull(file, "File"); Preconditions.checkArgument(file.exists(), "%s does not exist", file); try { return newFramework(module, file.toURI().toURL()); } catch (MalformedURLException e) { throw new IllegalArgumentException(e); } } /** * Creates a new {@link Framework} using the specified module and * a properties url. * <p> * The loaded properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.4 * @param module the application main module * @param url the url pointing to the properties file * @return a new configured {@link Framework} instance * @throws NullPointerException if module or url is null * @throws IllegalArgumentException if reading from the specified url failed * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Module module, URL url) { Preconditions.checkNotNull(module, "Module"); Preconditions.checkNotNull(url, "URL"); final InputStream stream; try { stream = url.openStream(); } catch (IOException e) { throw new IllegalArgumentException(e); } try { final Properties properties = new Properties(); properties.load(stream); return newFramework(module, properties); } catch (IOException e) { throw new IllegalArgumentException(e); } finally { Closeables.closeQuietly(stream); } } /** * Creates a new {@link Framework} using the specified properties. * <p> * This method assumes the specified properties contain the fully * qualified class name of the main module under the default configuration * key {@link CoreConfig#APPLICATION}. The class will be loaded vi reflection. * </p> * <p> * The specified properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.3 * @param properties the settings * @return a new configured {@link Framework} instance * @throws NullPointerException if properties is null or properties do not contain {@link CoreConfig#APPLICATION} * @throws IllegalArgumentException if the specified class does not exist or no instance could be created * @throws ClassCastException if the addressed main module class is no subclass of {@link Module} * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Properties properties) { Preconditions.checkNotNull(properties, "Properties"); final String className = properties.getProperty(CoreConfig.APPLICATION); Preconditions.checkNotNull(className, "Missing %s", CoreConfig.APPLICATION); final Class<? extends Module> mainModuleClass; try { mainModuleClass = Class.forName(className).asSubclass(Module.class); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } LOG.debug("Creating new framework using {}", properties); return newFramework(mainModuleClass, properties); } /** * Creates a new {@link Framework} using the specified properties. * <p> * This method creates a new instance of the given module class using * {@link Class#newInstance()}. As a consequence this class must provide * a public no argument constructor. * </p> * <p> * The specified properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.3 * @param moduleClass the class literal of the main module * @param properties the application properties * @return a new configured {@link Framework} instance * @throws NullPointerException if mainModuleClass or properties is null * @throws IllegalArgumentException if creating instance of mainModuleClass failed * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Class<? extends Module> moduleClass, Properties properties) { Preconditions.checkNotNull(moduleClass, "ModuleClass"); Preconditions.checkNotNull(properties, "Properties"); final Module module; try { module = moduleClass.newInstance(); } catch (InstantiationException e) { throw new IllegalArgumentException(e); } catch (IllegalAccessException e) { throw new IllegalArgumentException(e); } return newFramework(module, properties); } /** * Creates a {@link Framework} which loads the given {@link Module}. * <p> * The specified properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.3 * @param module the application main module * @param properties the application properties * @return a new configured {@link Framework} instance * @throws NullPointerException if mainModule or properties is null * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Module module, Properties properties) { Preconditions.checkNotNull(module, "Module"); Preconditions.checkNotNull(properties, "Properties"); final String stageName = properties.getProperty(CoreConfig.STAGE); final Stage stage = StringUtils.isBlank(stageName) ? Stage.PRODUCTION : Stage.valueOf(stageName); return newFramework(module, stage, properties); } /** * Creates a {@link Framework} which loads the given {@link Module} using the specified * guice {@link Stage}. * <p> * The specified properties will be bound using the {@link Settings} annotation. * </p> * * @since 2.3 * @param module the application main module * @param stage the desired injector stage * @param properties the application properties * @return a new configured {@link Framework} instance * @throws NullPointerException if mainModule, stage or properties is null * @throws ConfigurationException if guice configuration failed * @throws ProvisionException if providing an instance during creation failed */ public static Framework newFramework(Module module, Stage stage, Properties properties) { Preconditions.checkNotNull(module, "Module"); Preconditions.checkNotNull(stage, "Stage"); Preconditions.checkNotNull(properties, "Properties"); return new BootstrapFramework(module, stage, properties); } }