/*
* Copyright (C) 2011 Rhegium Team
*
* 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.rhegium.internal.modules;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.rhegium.api.AbstractService;
import org.rhegium.api.lifecycle.LifecycleManager;
import org.rhegium.api.modules.FrameworkPlugin;
import org.rhegium.api.modules.PluginLifecycleListener;
import org.rhegium.api.modules.PluginManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Injector;
class DefaultPluginManager extends AbstractService implements PluginManager {
private static final Logger LOG = LoggerFactory.getLogger(DefaultPluginManager.class);
private final Set<PluginLifecycleListener> listeners = new CopyOnWriteArraySet<>();
private final Map<FrameworkPlugin, ClassLoader> classLoaders = new ConcurrentHashMap<>();
private final Map<String, FrameworkPlugin> plugins = new ConcurrentHashMap<>();
@Inject
private LifecycleManager lifecycleManager;
@Inject
private Injector injector;
@Inject
DefaultPluginManager(LifecycleManager lifecycleManager) {
lifecycleManager.registerLifecycleAware(this);
}
@Override
public void initialized() throws Exception {
super.initialized();
Iterator<FrameworkPlugin> iterator = plugins.values().iterator();
while (iterator.hasNext()) {
final FrameworkPlugin plugin = iterator.next();
try {
LOG.info(String.format("Configure Plugin '%s'...", plugin.getName()));
// New inject member instances
injector.injectMembers(plugin);
}
catch (final Exception e) {
iterator.remove();
e.printStackTrace();
}
}
iterator = plugins.values().iterator();
while (iterator.hasNext()) {
final FrameworkPlugin plugin = iterator.next();
try {
LOG.info(String.format("Initialize Plugin '%s'...", plugin.getName()));
plugin.initialize();
}
catch (final Exception e) {
iterator.remove();
e.printStackTrace();
}
}
}
@Override
public void start() throws Exception {
super.start();
final Iterator<FrameworkPlugin> iterator = plugins.values().iterator();
while (iterator.hasNext()) {
final FrameworkPlugin plugin = iterator.next();
try {
LOG.info(String.format("Starting Plugin '%s'...", plugin.getName()));
plugin.startup();
}
catch (final Exception e) {
iterator.remove();
e.printStackTrace();
}
}
}
@Override
public void shutdown() throws Exception {
super.shutdown();
final List<FrameworkPlugin> list = new ArrayList<>(plugins.values());
Collections.reverse(list);
final Iterator<FrameworkPlugin> iterator = list.iterator();
while (iterator.hasNext()) {
final FrameworkPlugin plugin = iterator.next();
try {
LOG.info("Stopping Plugin '" + plugin.getName() + "'...");
plugin.destroy();
}
catch (final Exception e) {
iterator.remove();
e.printStackTrace();
}
}
lifecycleManager.removeLifecycleAware(this);
}
@Override
public void registerPluginLifecycleListener(PluginLifecycleListener listener) {
listeners.add(listener);
}
@Override
public void removePluginLifecycleListener(PluginLifecycleListener listener) {
listeners.remove(listener);
}
@Override
public Collection<PluginLifecycleListener> getPluginLifecycleListeners() {
return Collections.unmodifiableCollection(listeners);
}
@Override
public FrameworkPlugin getPlugin(String name) {
return plugins.get(name);
}
@Override
public ClassLoader getPluginClassLoader(FrameworkPlugin plugin) {
return classLoaders.get(plugin);
}
@Override
public Class<?> loadClass(FrameworkPlugin plugin, String className) throws ClassNotFoundException {
final ClassLoader classLoader = getPluginClassLoader(plugin);
if (classLoader == null) {
return null;
}
return classLoader.loadClass(className);
}
@Override
public InputStream loadResourceAsStream(FrameworkPlugin plugin, String path) {
final ClassLoader classLoader = getPluginClassLoader(plugin);
if (classLoader == null) {
return null;
}
return classLoader.getResourceAsStream(path);
}
@Override
public Collection<FrameworkPlugin> getRegisteredPlugins() {
return Collections.unmodifiableCollection(plugins.values());
}
@Override
public void registerPlugin(FrameworkPlugin plugin) {
plugins.put(plugin.getName(), plugin);
classLoaders.put(plugin, plugin.getClass().getClassLoader());
}
}