me.tfeng.play.plugins.StartablePlugin Maven / Gradle / Ivy
/**
* Copyright 2014 Thomas Feng
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 me.tfeng.play.plugins;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import me.tfeng.play.spring.ExtendedStartable;
import me.tfeng.play.spring.Startable;
import me.tfeng.play.common.DependencyUtils;
import play.Application;
import play.Logger;
import play.Logger.ALogger;
import play.Play;
/**
* @author Thomas Feng ([email protected])
*/
public class StartablePlugin extends AbstractPlugin {
private static final ALogger LOG = Logger.of(StartablePlugin.class);
public static StartablePlugin getInstance() {
return Play.application().plugin(StartablePlugin.class);
}
private Set startables = new HashSet<>();
public StartablePlugin(Application application) {
super(application);
}
public void addStartable(Startable startable) {
startables.add(startable);
}
public void addStartables(Collection extends Startable> startables) {
this.startables.addAll(startables);
}
public List getStartables() {
BeanDefinitionRegistry registry =
(BeanDefinitionRegistry) getApplicationContext().getAutowireCapableBeanFactory();
Comparator> beanDependencyComparator =
(bean1, bean2) -> {
String beanName1 = bean1.getKey();
String beanName2 = bean2.getKey();
BeanDefinition beanDefinition1 = registry.getBeanDefinition(beanName1);
BeanDefinition beanDefinition2 = registry.getBeanDefinition(beanName2);
if (beanDefinition1 == null || beanDefinition2 == null) {
return 0;
} else if (ArrayUtils.contains(beanDefinition1.getDependsOn(), beanName2)) {
return 1;
} else if (ArrayUtils.contains(beanDefinition2.getDependsOn(), beanName1)) {
return -1;
} else {
return 0;
}
};
Set> entries =
getApplicationContext().getBeansOfType(Startable.class).entrySet();
List> sortedEntries =
DependencyUtils.dependencySort(entries, beanDependencyComparator);
List result = new ArrayList<>(startables.size() + sortedEntries.size());
result.addAll(startables);
for (Entry entry : sortedEntries) {
Startable startable = entry.getValue();
if (!startables.contains(startable)) {
result.add(startable);
}
}
return result;
}
@Override
public void onStart() {
super.onStart();
List startables = getStartables();
for (Startable startable: startables) {
if (startable instanceof ExtendedStartable) {
try {
((ExtendedStartable) startable).beforeStart();
} catch (Throwable t) {
onStartFailure(startable, t);
}
}
}
for (Startable startable: startables) {
try {
startable.onStart();
} catch (Throwable t) {
onStartFailure(startable, t);
}
}
for (Startable startable: startables) {
if (startable instanceof ExtendedStartable) {
try {
((ExtendedStartable) startable).afterStart();
} catch (Throwable t) {
onStartFailure(startable, t);
}
}
}
}
public void onStartFailure(Startable startable, Throwable t) {
throw new RuntimeException("Unable to start " + startable, t);
}
@Override
public void onStop() {
List startables = getStartables();
for (ListIterator iterator = startables.listIterator(startables.size());
iterator.hasPrevious();) {
Startable startable = iterator.previous();
if (startable instanceof ExtendedStartable) {
try {
((ExtendedStartable) startable).beforeStop();
} catch (Throwable t) {
onStartFailure(startable, t);
}
}
}
for (ListIterator iterator = startables.listIterator(startables.size());
iterator.hasPrevious();) {
Startable startable = iterator.previous();
try {
startable.onStop();
} catch (Throwable t) {
onStopFailure(startable, t);
}
}
for (ListIterator iterator = startables.listIterator(startables.size());
iterator.hasPrevious();) {
Startable startable = iterator.previous();
if (startable instanceof ExtendedStartable) {
try {
((ExtendedStartable) startable).afterStop();
} catch (Throwable t) {
onStartFailure(startable, t);
}
}
}
super.onStop();
}
public void onStopFailure(Startable startable, Throwable t) {
LOG.error("Unable to stop " + startable, t);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy