/*
* (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* matic
*/
package org.nuxeo.runtime.tomcat.dev;
import java.io.File;
import java.lang.reflect.Method;
/**
* Invokes the ReloadService by reflection as this module does not have access to the runtime context.
*
* @author matic
* @since 5.5
*/
public class ReloadServiceInvoker {
protected Object reloadService;
protected Method deployBundle;
protected Method undeployBundle;
/**
* Method to run the deployment preprocessor, previously handled by the deployBundle method
*
* @since 5.6
*/
protected Method runDeploymentPreprocessor;
/**
* Method to install local web resources, as the deployment preprocessor won't see dev bundles as defined by Nuxeo
* IDE
*
* @since 5.6
*/
protected Method installWebResources;
protected Method flush;
protected Method reload;
protected Method flushSeam;
protected Method reloadSeam;
public ReloadServiceInvoker(ClassLoader cl) throws ReflectiveOperationException {
Class<?> frameworkClass = cl.loadClass("org.nuxeo.runtime.api.Framework");
Class<?> reloadServiceClass = cl.loadClass("org.nuxeo.runtime.reload.ReloadService");
Method getLocalService = frameworkClass.getDeclaredMethod("getLocalService", new Class<?>[] { Class.class });
reloadService = getLocalService.invoke(null, new Object[] { reloadServiceClass });
deployBundle = reloadServiceClass.getDeclaredMethod("deployBundle", new Class<?>[] { File.class });
undeployBundle = reloadServiceClass.getDeclaredMethod("undeployBundle", new Class<?>[] { String.class });
runDeploymentPreprocessor = reloadServiceClass.getDeclaredMethod("runDeploymentPreprocessor", new Class<?>[0]);
installWebResources = reloadServiceClass.getDeclaredMethod("installWebResources", new Class<?>[] { File.class });
flush = reloadServiceClass.getDeclaredMethod("flush", new Class<?>[0]);
reload = reloadServiceClass.getDeclaredMethod("reload", new Class<?>[0]);
flushSeam = reloadServiceClass.getDeclaredMethod("flushSeamComponents", new Class<?>[0]);
reloadSeam = reloadServiceClass.getDeclaredMethod("reloadSeamComponents", new Class<?>[0]);
}
public void hotDeployBundles(DevBundle[] bundles) throws ReflectiveOperationException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(reloadService.getClass().getClassLoader());
flush();
boolean hasSeam = false;
// rebuild existing war, this will remove previously copied web
// resources
// commented out for now, see NXP-9642
// runDeploymentPreprocessor();
for (DevBundle bundle : bundles) {
if (bundle.devBundleType == DevBundleType.Bundle) {
bundle.name = (String) deployBundle.invoke(reloadService, new Object[] { bundle.file() });
// install its web resources
installWebResources.invoke(reloadService, new Object[] { bundle.file() });
} else if (bundle.devBundleType.equals(DevBundleType.Seam)) {
hasSeam = true;
}
}
if (hasSeam) {
reloadSeam();
}
reload();
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
}
public void hotUndeployBundles(DevBundle[] bundles) throws ReflectiveOperationException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(reloadService.getClass().getClassLoader());
boolean hasSeam = false;
for (DevBundle bundle : bundles) {
if (bundle.devBundleType.equals(DevBundleType.Bundle) && bundle.name != null) {
undeployBundle.invoke(reloadService, new Object[] { bundle.name });
} else if (bundle.devBundleType.equals(DevBundleType.Seam)) {
hasSeam = true;
}
}
// run deployment preprocessor again: this will remove potential
// resources that were copied in the war at deploy
// commented out for now, see NXP-9642
// runDeploymentPreprocessor();
if (hasSeam) {
flushSeam.invoke(reloadService);
}
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
}
protected void flush() throws ReflectiveOperationException {
flush.invoke(reloadService);
}
protected void reload() throws ReflectiveOperationException {
reload.invoke(reloadService);
}
protected void reloadSeam() throws ReflectiveOperationException {
reloadSeam.invoke(reloadService);
}
protected void runDeploymentPreprocessor() throws ReflectiveOperationException {
runDeploymentPreprocessor.invoke(reloadService);
}
}