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