/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.server;
import com.sun.enterprise.config.serverbeans.ExtensionModule;
import com.sun.enterprise.config.serverbeans.ElementProperty;
import com.sun.enterprise.config.serverbeans.J2eeApplication;
import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.Switch;
import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.interfaces.pluggable.ArchiveDescriptor;
import com.sun.enterprise.instance.ExtensionModuleConfigManager;
import com.sun.enterprise.security.acl.RoleMapper;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.web.WebModuleConfig;
import com.sun.enterprise.web.WebContainer;
import com.sun.logging.LogDomains;
import java.lang.Exception;
import java.lang.Throwable;
import java.io.File;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.deploy.shared.ModuleType;
import javax.naming.NamingException;
/**
* This class is a wrapper class that abstracts the loading/unloading functionality
* of the WebContainer, by providing utility methods that would call into the
* WebContainer.java . This class can be used by any Loader that would be used
* to deploy an ExtensionModule on the Web Container.
* @author prasad.subramanian@sun.com
*/
public class WebArchiveLoader extends AppArchiveLoader {
private ExtensionModuleConfigManager configManager;
private ModuleType moduleType;
static Logger _logger = LogDomains.getLogger(LogDomains.LOADER_LOGGER);
/**
* Creates a new instance of WebArchiveLoader
*/
public WebArchiveLoader() {
}
/**
* Utility method to get an ExtensionModule config bean from the
* ExtensionModuleConfigManager using the moduleID as the key.
* @param modID the moduleID
* @return ExtensionModule
*/
public ExtensionModule getExtensionModule(String modId) {
try {
return configManager.getExtensionModule(modId);
} catch (ConfigException ce) {
//ce.printStrackTrace();
return null;
}
}
/**
* Utility method to construct a WebModuleConfig object
* @param em ExtensionModule config bean
* @param wbd the WebBundleDescriptor object for this module
* @return WebModuleConfig
*/
public WebModuleConfig getModuleConfig(ExtensionModule em,
WebBundleDescriptor wbd) {
WebModuleConfig wmInfo = new WebModuleConfig();
wmInfo.setBean(em);
String wmID = em.getName();
try {
wmInfo.setDescriptor(wbd);
String vs = configManager.getVirtualServers(wmID);
wmInfo.setVirtualServers(vs);
} catch (Exception ce) {
wmInfo = null;
}
return wmInfo;
}
/**
* Wrapper method to load a Extended WebModule
* @param wmInfo WebModuleConfig object for this module
* @return boolean success/failure
* @throws Exception
*/
public boolean loadWebModule(WebModuleConfig wmInfo) throws Exception {
List<Throwable> throwables =
getWebContainer().loadWebModule(wmInfo, "null");
if (throwables != null && !throwables.isEmpty()) {
//we don't have the ability to return all errors. so return the
//first one, enough to signal the problem.
String msg = throwables.get(0).getMessage();
Exception ex = new Exception(msg);
ex.initCause(throwables.get(0));
throw ex;
} else {
return true;
}
}
/**
* Wrapper method to load a Extended WebModule
* @param em ExtensionModule config bean for this module
* @param wbd WebBundleDescriptor for this module
* @return boolean success/failure
* @throws Exception
*/
public boolean unloadWebModule(ExtensionModule em, WebBundleDescriptor wbd)
throws Exception {
String appName = null;
try {
Application app = configManager.getExtensionDescriptor(
em.getName(), em.getLocation(), true);
RoleMapper.removeRoleMapper(app.getRoleMapper().getName());
appName = app.getRegistrationName();
} catch (Exception ce) {
throw new Exception(ce);
}
String contextRoot = null;
ElementProperty ep = em.getElementPropertyByName("contextRoot");
if(ep != null ){
contextRoot = ep.getValue();
} else {
contextRoot = em.getName();
}
String virtualServers = null;
try {
virtualServers = configManager.getVirtualServers(em.getName());
} catch(Exception ce) {
throw new Exception("Exception getting virtual servers by app name "
+ appName, ce);
}
try {
getWebContainer().unloadWebModule(contextRoot, appName,
virtualServers, wbd);
// XXX : Fix me
return true;
} catch (Exception ex) {
_logger.log(Level.WARNING,"Exception thrown in the unload" + ex.toString());
return false;
} finally {
try {
Switch.getSwitch().getNamingManager().unbindObjects(wbd);
} catch (javax.naming.NamingException nameEx) {
throw new Exception("[WebExtensionLoader] "
+ " Exception during namingManager.unbindObject",
nameEx);
}
}
}
/**
* Wrapper method to enable a Extended WebModule
* @param wmInfo WebModuleConfig object for this module
* @return boolean success/failure
* @throws Exception
*/
public boolean enableWebModule(WebModuleConfig wmInfo) throws Exception {
getWebContainer().enableWebModule(wmInfo, "null");
// FIX ME : Need to refactor the WebContainer to return status.
return true;
}
/**
* Wrapper method to disable a Extended WebModule
* @param em ExtensionModule bean for this module
* @return boolean success/failure
* @throws Exception
*/
public boolean disableWebModule(ExtensionModule em) throws Exception {
String appName = null;
try {
Application app = configManager.getExtensionDescriptor(
em.getName(), em.getLocation(), true);
RoleMapper.removeRoleMapper(app.getRoleMapper().getName());
appName = app.getRegistrationName();
} catch (Exception ce) {
throw new Exception(ce);
}
String contextRoot = null;
ElementProperty ep = em.getElementPropertyByName("contextRoot");
if(ep != null ){
contextRoot = ep.getValue();
} else {
contextRoot = em.getName();
}
String virtualServers = null;
try {
virtualServers = configManager.getVirtualServers(em.getName());
} catch(Exception ce) {
throw new Exception("Exception getting virtual servers by app name "
+ appName, ce);
}
return getWebContainer().disableWebModule(contextRoot,
appName, virtualServers);
}
/**
* This method asbtracts the functionality for loading an Extension Module
* in the WebContainer
* @param descriptor the descriptor for the module
* @return boolean true if success
* @throws Exception
*/
public boolean loadJ2eeApplicationModule(ArchiveDescriptor descriptor)
throws Exception {
com.sun.enterprise.config.serverbeans.ExtensionModule em = null;
WebModuleConfig wmInfo = null;
Application appDesc = null;
J2eeApplication j2eeAppBean = getJ2eeAppBean();
ConfigContext eventConfigContext = j2eeAppBean.getConfigContext();
String id = j2eeAppBean.getName();
String location = j2eeAppBean.getLocation();
String resourceType = j2eeAppBean.getObjectType();
//TODO : Check if enabled and take action
// get the application descriptor
ApplicationRegistry registry = ApplicationRegistry.getInstance();
ClassLoader appLoader = registry.getClassLoaderForApplication(id);
if (appLoader != null) {
appDesc = registry.getApplication(appLoader);
}
// If the Application object is null then we should not load.
if(appDesc == null ) {
// log message
return false;
}
String j2eeApplication = appDesc.getRegistrationName();
// get the Bundle Descriptor
WebBundleDescriptor wbd = (WebBundleDescriptor)descriptor;
String moduleName = wbd.getModuleDescriptor().getArchiveUri();
StringBuffer dir = new StringBuffer(location);
dir.append(File.separator);
dir.append(FileUtils.makeFriendlyFilename(moduleName));
if (!(new File(dir.toString()).exists())) {
dir = new StringBuffer(location).append(
File.separator).append(moduleName);
}
// set the values in the ExtensionModule config bean
em = new com.sun.enterprise.config.serverbeans.ExtensionModule();
em.setLocation(dir.toString().trim());
em.setConfigContext(eventConfigContext);
em.setName(moduleName);
ElementProperty isConvergedProperty = new ElementProperty();
isConvergedProperty.setName("isConverged");
if(wbd.getContextRoot() != null) {
isConvergedProperty.setValue("true");
ElementProperty contextRootProperty = new ElementProperty();
contextRootProperty.setName("contextRoot");
contextRootProperty.setValue(wbd.getContextRoot());
em.addElementProperty(contextRootProperty);
} else {
isConvergedProperty.setValue("false");
}
em.addElementProperty(isConvergedProperty);
em.setEnabled(true);
em.setObjectType(resourceType);
// create and populate the WebModuleConfig object
wmInfo = new WebModuleConfig();
wmInfo.setBean(em);
wmInfo.setApplicationBean(j2eeAppBean);
wmInfo.setDescriptor(wbd);
wmInfo.setParentLoader(appLoader);
wmInfo.setVirtualServers(getVirtualServers(id, eventConfigContext));
// Call into the WebContainer
List<Throwable> throwables =
getWebContainer().loadWebModule(wmInfo, j2eeApplication);
setJ2eeAppBean(null);
if (throwables != null && !throwables.isEmpty()) {
//we don't have the ability to return all errors. so return the
//first one, enough to signal the problem.
String msg = throwables.get(0).getMessage();
Exception ex = new Exception(msg);
ex.initCause(throwables.get(0));
throw ex;
} else {
return true;
}
}
/**
* Method that process a module and call the WebContainer for unloading
* an extension module within an Application
* @param bd the BundleDescriptor object for the module being unloaded
* @return boolean true if success
* @throws Exception
*/
public boolean unloadJ2eeApplicationModule(ArchiveDescriptor bd)
throws Exception {
String virtualServers = null;
try {
virtualServers = getAppsManager().
getVirtualServersByAppName(getJ2eeAppBean().getName());
} catch(ConfigException ce) {
_logger.log(Level.WARNING, "[WebExtensionLoader] unload "
+ getJ2eeAppBean().getName()
+ ". error getting virtualServers", ce);
}
String appName = ((WebBundleDescriptor)bd).
getApplication().getRegistrationName();
try {
getWebContainer().unloadWebModule(
((WebBundleDescriptor)bd).getContextRoot(), appName,
virtualServers,
(WebBundleDescriptor)bd);
} finally {
try {
Switch.getSwitch().getNamingManager().unbindObjects(
((WebBundleDescriptor)bd));
setJ2eeAppBean(null);
} catch (javax.naming.NamingException nameEx) {
_logger.log(Level.WARNING, "[WebExtensionLoader] "
+ " Exception during namingManager.unbindObject",
nameEx);
}
}
return true;
}
/**
* Virtual servers are maintained in the reference contained
* in Server element. First, we need to find the server
* and then get the virtual server from the correct reference
*
* @param appName Name of the app to get vs
* @param configCtx config context to use to obtain virtual servers. If
* this parameter is null, config context cached at startup time will
* be used.
*
* @return virtual servers as a string (separated by space or comma)
*/
private String getVirtualServers(String appName, ConfigContext configCtx) {
String ret = null;
try {
ret = ServerBeansFactory.getVirtualServersByAppName(configCtx,
appName);
} catch (ConfigException ce) {
_logger.log(Level.WARNING,
"No virtual servers defined for " + appName,
ce);
}
return ret;
}
/**
* Setter method for ExtensionModuleConfigManager
* @param configManager the instance of the ExtensionModuleConfigManager set
* by the ExtensionModuleLoader
*/
public void setModulesManager(ExtensionModuleConfigManager configManager) {
this.configManager = configManager;
}
protected WebContainer getWebContainer() {
return WebContainer.getInstance();
}
}