LifecycleHandlerProvider.java
01 /*
02  * Copyright 2008-2016 the original author or authors.
03  *
04  * Licensed under the Apache License, Version 2.0 (the "License");
05  * you may not use this file except in compliance with the License.
06  * You may obtain a copy of the License at
07  *
08  *     http://www.apache.org/licenses/LICENSE-2.0
09  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.codehaus.griffon.runtime.core;
17 
18 import griffon.core.ApplicationClassLoader;
19 import griffon.core.GriffonApplication;
20 import griffon.core.LifecycleHandler;
21 import griffon.exceptions.InstanceNotFoundException;
22 
23 import javax.annotation.Nonnull;
24 import javax.inject.Inject;
25 import javax.inject.Provider;
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 
29 import static griffon.util.AnnotationUtils.named;
30 import static griffon.util.GriffonNameUtils.requireNonBlank;
31 import static java.util.Objects.requireNonNull;
32 
33 /**
34  @author Andres Almiray
35  @since 2.0.0
36  */
37 public class LifecycleHandlerProvider implements Provider<LifecycleHandler> {
38     private final String basename;
39 
40     private GriffonApplication application;
41     private ApplicationClassLoader applicationClassLoader;
42 
43     public LifecycleHandlerProvider(@Nonnull String basename) {
44         this.basename = requireNonBlank(basename, "Argument 'basename' must not be blank");
45     }
46 
47     @Inject
48     public void setGriffonApplication(@Nonnull GriffonApplication application) {
49         this.application = requireNonNull(application, "Argument 'application' must not be null");
50     }
51 
52     @Inject
53     public void setApplicationClassLoader(ApplicationClassLoader applicationClassLoader) {
54         this.applicationClassLoader = requireNonNull(applicationClassLoader, "Argument 'applicationClassLoader' must not be null");
55     }
56 
57     @Override
58     @SuppressWarnings("unchecked")
59     public LifecycleHandler get() {
60         Class<LifecycleHandler> handlerClass;
61         try {
62             handlerClass = (Class<LifecycleHandler>applicationClassLoader.get().loadClass(basename);
63         catch (ClassNotFoundException e) {
64             return new NoopLifecycleHandler(application);
65         }
66 
67         try {
68             Constructor<LifecycleHandler> ctor = handlerClass.getDeclaredConstructor(GriffonApplication.class);
69             LifecycleHandler handler = ctor.newInstance(application);
70             application.getInjector().injectMembers(handler);
71             return handler;
72         catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) {
73             throw new InstanceNotFoundException(handlerClass, named(basename), e);
74         catch (InvocationTargetException e) {
75             throw new InstanceNotFoundException(handlerClass, named(basename), e.getTargetException());
76         }
77     }
78 
79     private static class NoopLifecycleHandler extends AbstractLifecycleHandler {
80         public NoopLifecycleHandler(@Nonnull GriffonApplication application) {
81             super(application);
82         }
83 
84         @Override
85         public void execute() {
86             // noop
87         }
88     }
89 }