package org.jboss.web.tomcat.tc5;
import java.io.File;
import java.util.Iterator;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.security.jacc.PolicyContext;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.connector.Connector;
import org.apache.commons.modeler.Registry;
import org.jboss.deployment.DeploymentInfo;
import org.jboss.system.server.Server;
import org.jboss.system.server.ServerImplMBean;
import org.jboss.web.AbstractWebContainer;
import org.jboss.web.AbstractWebDeployer;
import org.jboss.web.tomcat.security.HttpServletRequestPolicyContextHandler;
import org.jboss.web.tomcat.tc5.session.SessionIDGenerator;
import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
public class Tomcat5 extends AbstractWebContainer
implements Tomcat5MBean, NotificationListener
{
public static final String NAME = "Tomcat5";
public static final String DEFAULT_CACHE_NAME =
"jboss.cache:service=TomcatClusteringCache";
private String contextClassName =
"org.apache.catalina.core.StandardContext";
private String catalinaDomain = "Catalina";
private String cacheName = DEFAULT_CACHE_NAME;
protected String managerClass = "org.jboss.web.tomcat.tc5.session.JBossCacheManager";
private int snapshotInterval = 1000;
private String snapshotMode = "instant";
private boolean useLocalCache = true;
private boolean useJK = false;
private boolean useJBossWebLoader = true;
private String serverConfigFile = "server.xml";
private String subjectAttributeName = null;
private boolean allowSelfPrivilegedWebApps = false;
private JaasSecurityManagerServiceMBean secMgrService;
private String[] filteredPackages;
public Tomcat5()
{
}
public String getName()
{
return NAME;
}
public String getManagerClass()
{
return managerClass;
}
public void setManagerClass(String managerClass)
{
this.managerClass = managerClass;
}
public String getDomain()
{
return this.catalinaDomain;
}
public void setDomain(String catalinaDomain)
{
this.catalinaDomain = catalinaDomain;
}
public void setContextMBeanCode(String className)
{
this.contextClassName = className;
}
public String getContextMBeanCode()
{
return contextClassName;
}
public void setSnapshotInterval(int interval)
{
this.snapshotInterval = interval;
}
public int getSnapshotInterval()
{
return this.snapshotInterval;
}
public void setSnapshotMode(String mode)
{
this.snapshotMode = mode;
}
public String getSnapshotMode()
{
return this.snapshotMode;
}
public String getCacheName()
{
return cacheName;
}
public void setCacheName(String cacheName)
{
this.cacheName = cacheName;
}
public boolean isUseLocalCache()
{
return useLocalCache;
}
public void setUseLocalCache(boolean useLocalCache)
{
this.useLocalCache = useLocalCache;
}
public boolean isUseJK()
{
return useJK;
}
public void setUseJK(boolean useJK)
{
this.useJK = useJK;
}
public void setSessionIdAlphabet(String sessionIdAlphabet)
{
SessionIDGenerator.getInstance().setSessionIdAlphabet(sessionIdAlphabet);
}
public String getSessionIdAlphabet()
{
return SessionIDGenerator.getInstance().getSessionIdAlphabet();
}
public boolean getUseJBossWebLoader()
{
return useJBossWebLoader;
}
public void setUseJBossWebLoader(boolean flag)
{
this.useJBossWebLoader = flag;
}
public String getConfigFile()
{
return serverConfigFile;
}
public void setConfigFile(String configFile)
{
this.serverConfigFile = configFile;
}
public String getSubjectAttributeName()
{
return this.subjectAttributeName;
}
public void setSubjectAttributeName(String name)
{
this.subjectAttributeName = name;
}
public boolean isAllowSelfPrivilegedWebApps()
{
return allowSelfPrivilegedWebApps;
}
public void setAllowSelfPrivilegedWebApps(boolean allowSelfPrivilegedWebApps)
{
this.allowSelfPrivilegedWebApps = allowSelfPrivilegedWebApps;
}
public void setSecurityManagerService(JaasSecurityManagerServiceMBean mgr)
{
this.secMgrService = mgr;
}
public String[] getFilteredPackages()
{
return filteredPackages;
}
public void setFilteredPackages(String[] pkgs)
{
this.filteredPackages = pkgs;
}
public void startService()
throws Exception
{
System.setProperty("catalina.ext.dirs",
(System.getProperty("jboss.server.home.dir")
+ File.separator + "lib"));
String objectNameS = catalinaDomain + ":type=server";
ObjectName objectName = new ObjectName(objectNameS);
Registry.getRegistry().setMBeanServer(server);
server.createMBean("org.apache.commons.modeler.BaseModelMBean",
objectName,
new Object[]{"org.apache.catalina.startup.Catalina"},
new String[]{"java.lang.String"});
server.setAttribute(objectName, new Attribute
("catalinaHome",
System.getProperty("jboss.server.home.dir")));
server.setAttribute(objectName, new Attribute
("configFile", serverConfigFile));
server.setAttribute(objectName, new Attribute
("useNaming", new Boolean(false)));
server.setAttribute(objectName, new Attribute
("useShutdownHook", new Boolean(false)));
server.setAttribute(objectName, new Attribute
("await", new Boolean(false)));
server.invoke(objectName, "create", new Object[]{},
new String[]{});
server.invoke(objectName, "start", new Object[]{},
new String[]{});
ObjectName ssoQuery = new ObjectName(catalinaDomain + ":type=Valve,*");
Iterator iterator = server.queryMBeans(ssoQuery, null).iterator();
while (iterator.hasNext())
{
ObjectName ssoObjectName =
((ObjectInstance) iterator.next()).getObjectName();
String name = ssoObjectName.getKeyProperty("name");
if (cacheName != null && "ClusteredSingleSignOn".equals(name))
{
String tcName = (String) server.getAttribute(ssoObjectName,
"treeCacheName");
tcName = (tcName != null ? tcName : DEFAULT_CACHE_NAME);
ObjectName ssoCacheName = new ObjectName(tcName);
if (ssoCacheName.equals(new ObjectName(DEFAULT_CACHE_NAME)))
{
log.info("Setting the cache name to " + cacheName +
" on " + ssoObjectName);
server.setAttribute(ssoObjectName,
new Attribute("treeCacheName", cacheName));
}
}
}
HttpServletRequestPolicyContextHandler handler = new HttpServletRequestPolicyContextHandler();
PolicyContext.registerHandler(HttpServletRequestPolicyContextHandler.WEB_REQUEST_KEY,
handler, false);
super.startService();
Boolean started = (Boolean)server.getAttribute(ServerImplMBean.OBJECT_NAME, "Started");
if (started.booleanValue() == true)
{
log.debug("Server '" + ServerImplMBean.OBJECT_NAME +
"' already started, starting connectors now");
startConnectors();
}
else
{
log.debug("Server '" + ServerImplMBean.OBJECT_NAME +
"' not started, registering for start-up notification");
server.addNotificationListener(ServerImplMBean.OBJECT_NAME, this, null, null);
}
}
public void stopService()
throws Exception
{
String objectNameS = catalinaDomain + ":type=server";
ObjectName objectName = new ObjectName(objectNameS);
server.invoke(objectName, "stop", new Object[]{},
new String[]{});
server.invoke(objectName, "destroy", new Object[]{},
new String[]{});
server.unregisterMBean(objectName);
MBeanServer server2 = server;
super.stopService();
ObjectName queryObjectName = new ObjectName
(catalinaDomain + ":*");
Iterator iterator =
server2.queryMBeans(queryObjectName, null).iterator();
while (iterator.hasNext())
{
ObjectInstance oi = (ObjectInstance) iterator.next();
ObjectName toRemove = oi.getObjectName();
if (!"WebServer".equals(toRemove.getKeyProperty("service")))
{
if (server2.isRegistered(toRemove))
{
server2.unregisterMBean(toRemove);
}
}
}
queryObjectName = new ObjectName("Catalina:*");
iterator = server2.queryMBeans(queryObjectName, null).iterator();
while (iterator.hasNext())
{
ObjectInstance oi = (ObjectInstance) iterator.next();
ObjectName name = oi.getObjectName();
server2.unregisterMBean(name);
}
}
public void startConnectors() throws Exception
{
ObjectName service = new ObjectName(catalinaDomain + ":type=Service,serviceName=jboss.web");
Object[] args = {};
String[] sig = {};
Connector[] connectors = (Connector[]) server.invoke(service,
"findConnectors", args, sig);
for (int n = 0; n < connectors.length; n++)
{
Lifecycle lc = (Lifecycle) connectors[n];
lc.start();
}
sendNotification(new Notification(TOMCAT_CONNECTORS_STARTED,
this, getNextNotificationSequenceNumber()));
}
public void stopConnectors() throws Exception
{
ObjectName service = new ObjectName(catalinaDomain + ":type=Service,serviceName=jboss.web");
Object[] args = {};
String[] sig = {};
Connector[] connectors = (Connector[]) server.invoke(service,
"findConnectors", args, sig);
for (int n = 0; n < connectors.length; n++)
{
Lifecycle lc = (Lifecycle) connectors[n];
lc.stop();
}
}
public void handleNotification(Notification msg, Object handback)
{
String type = msg.getType();
if (type.equals(Server.START_NOTIFICATION_TYPE))
{
log.debug("Saw " + type + " notification, starting connectors");
try
{
startConnectors();
}
catch (Exception e)
{
log.warn("Failed to startConnectors", e);
}
}
}
public AbstractWebDeployer getDeployer(DeploymentInfo di) throws Exception
{
ClassLoader loader = di.ucl;
Class deployerClass = loader.loadClass("org.jboss.web.tomcat.tc5.TomcatDeployer");
AbstractWebDeployer deployer = (AbstractWebDeployer) deployerClass.newInstance();
DeployerConfig config = new DeployerConfig();
config.setDefaultSecurityDomain(this.defaultSecurityDomain);
config.setSubjectAttributeName(this.subjectAttributeName);
config.setServiceClassLoader(getClass().getClassLoader());
config.setManagerClass(this.managerClass);
config.setJava2ClassLoadingCompliance(this.java2ClassLoadingCompliance);
config.setUnpackWars(this.unpackWars);
config.setLenientEjbLink(this.lenientEjbLink);
config.setCatalinaDomain(catalinaDomain);
config.setContextClassName(contextClassName);
config.setServiceName(serviceName);
config.setSnapshotInterval(this.snapshotInterval);
config.setSnapshotMode(this.snapshotMode);
config.setUseLocalCache(this.useLocalCache);
config.setUseJK(this.useJK);
config.setSubjectAttributeName(this.subjectAttributeName);
config.setUseJBossWebLoader(this.useJBossWebLoader);
config.setAllowSelfPrivilegedWebApps(this.allowSelfPrivilegedWebApps);
config.setSecurityManagerService(this.secMgrService);
config.setFilteredPackages(filteredPackages);
deployer.setServer(server);
deployer.init(config);
return deployer;
}
}