/* * Copyright (c) 2012, Inversoft Inc., All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the License. */ package org.primeframework.mvc.guice; import java.io.Closeable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.primeframework.mvc.PrimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Binding; 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.Scopes; import com.google.inject.spi.Message; /** * This class bootstraps Guice. * * @author Brian Pontarelli */ public class GuiceBootstrap { private static final Logger logger = LoggerFactory.getLogger(GuiceBootstrap.class); /** * Please do not invoke this method unless you know what you are doing. This initializes Guice and does it once only * so that synchronization is not used. This is called by the PrimeServletContextListener when the context is created * and should cover all cases. * * @param mainModule The main module for the application. * @return The Guice injector. */ public static Injector initialize(Module mainModule) { logger.debug("Initializing Guice"); try { return Guice.createInjector(mainModule); } catch (CreationException e) { logger.debug("Unable to create Guice injector", e); Collection<Message> messages = e.getErrorMessages(); Set<String> errorMessages = new HashSet<>(); messages.forEach((message) -> { if (message.getCause() != null) { errorMessages.add("[" + message.getMessage() + "] \n\t-> [" + message.getCause().getClass() + "] " + message.getCause().getMessage()); } else { errorMessages.add("[" + message.getMessage() + "]"); } }); logger.error( "\n\n===================================================================================================\n\n" + " Unable to start the server. Here's why: \n\n\n" + String.join("\n", errorMessages) + "\n\n===================================================================================================\n\n" ); logger.debug("Unable to start the server. Exception: \n", e); throw new PrimeException(); } } /** * Shuts down the Guice injector by locating all of the {@link Closeable} singletons classes and calling Close on each * of them. * * @param injector The Injector to shutdown. */ public static void shutdown(Injector injector) { Map<Key<?>, Binding<?>> bindings = injector.getBindings(); for (Key<?> key : bindings.keySet()) { Type type = key.getTypeLiteral().getType(); if (type instanceof ParameterizedType) { type = ((ParameterizedType) type).getRawType(); } if (type instanceof Class) { Class<?> bindingType = (Class<?>) type; if (Closeable.class.isAssignableFrom(bindingType) && Scopes.isSingleton(bindings.get(key))) { Closeable closable = (Closeable) injector.getInstance(key); try { closable.close(); } catch (Throwable t) { logger.error("Unable to shutdown Closeable [" + key + "]"); } } } } } }