Java tutorial
/* * This file is a component of thundr, a software library from 3wks. * Read more: http://www.3wks.com.au/thundr * Copyright (C) 2013 3wks, <thundr@3wks.com.au> * * 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 com.threewks.thundr.jrebel; import com.threewks.thundr.logger.Logger; import org.apache.commons.lang3.exception.ExceptionUtils; import org.zeroturnaround.javarebel.*; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Properties; import java.util.Set; public class ThundrJRebelPlugin implements Plugin { public static final String ApplicationModuleClassName = "ApplicationModule"; public static final String BaseModuleClassName = "com.threewks.thundr.injection.BaseModule"; public static final String ThundrServletClassName = "com.threewks.thundr.ThundrServlet"; private static final String PropertiesFileName = "jrebel-thundr-watch.properties"; private static final String ApplicationRoutesClassName = "ApplicationRoutesClassName"; @Override public void preinit() { Logger.info("Initializing %s", getName()); // Register the CBP Integration i = IntegrationFactory.getInstance(); ClassLoader cl = ThundrJRebelPlugin.class.getClassLoader(); i.addIntegrationProcessor(cl, ThundrServletClassName, new ReloadThundrServletClassBytecodeProcessor()); registerListener(); } @Override public boolean checkDependencies(ClassLoader classLoader, ClassResourceSource classResourceSource) { return classResourceSource.getClassResource(BaseModuleClassName) != null; } @Override public String getId() { return "thundr-plugin"; } @Override public String getName() { return "Thundr Plugin for JRebel 2"; } @Override public String getDescription() { return "Application module reloading for the Thundr framework"; } @Override public String getAuthor() { return "3wks"; } @Override public String getWebsite() { return "http://www.3wks.com.au"; } @Override public String getSupportedVersions() { return null; } @Override public String getTestedVersions() { return null; } @SuppressWarnings("unchecked") private void registerListener() { // Set up the reload listener final Set<String> watchedClasses = loadWatchedClassList(); ReloaderFactory.getInstance().addClassReloadListener(new ClassEventListener() { @Override public void onClassEvent(int eventType, Class klass) { try { Class applicationModuleClass = Class.forName(BaseModuleClassName); if (applicationModuleClass.isAssignableFrom(klass) || watchedClasses.contains(klass.getCanonicalName())) { Logger.info("%s was modified. InjectionContext will be reloaded on next request...", klass.getCanonicalName()); ThundrServletReloader.markDirty(); } } catch (Exception e) { Logger.error("Error marking ApplicationModule for reloading: %s", ExceptionUtils.getStackTrace(e)); } } @Override public int priority() { return 0; } }); } private Set<String> loadWatchedClassList() { Set<String> watchedClasses = new HashSet<String>(); watchedClasses.add(ApplicationRoutesClassName); InputStream inputStream = getClass().getClassLoader().getResourceAsStream(PropertiesFileName); if (inputStream == null) { Logger.info("No %s found using defaults.", PropertiesFileName); } else { Logger.info("Found %s, loading...", PropertiesFileName); try { Properties properties = new Properties(); properties.load(inputStream); watchedClasses.addAll((Set) properties.keySet()); } catch (IOException e) { Logger.error("There was a problem loading %s: %s; ignoring", PropertiesFileName, e.getMessage()); } } return watchedClasses; } }