diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..bdb0cabc87 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/README.md b/README.md index b1ecc59068..59b330061e 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,46 @@ -# PSI Probe - -[![Build Status](https://travis-ci.org/psi-probe/psi-probe.svg?branch=master)](https://travis-ci.org/psi-probe/psi-probe) -[![Project Stats](https://www.openhub.net/p/psi-probe/widgets/project_thin_badge.gif)](https://www.openhub.net/p/psi-probe) - -## Contributions ## - -Please follow [GitHub Flow](https://guides.github.com/introduction/flow/), with the following additions: - -* **Ensure an [issue](//github.com/psi-probe/psi-probe/issues) exists** before you begin work. If not, file one. - * You can get input from others before you begin. - * Issues power the release changelogs, so your change will be made known to users after it's done. -* **One PR per issue.** Include the issue number in your commit(s) and PR so that merging it will close the issue. -* **One issue per PR.** Keep changes minimal, and keep the scope narrow. - * Avoid making formatting changes alongside functionality changes. This is a recipe for conflicts. - * Avoid bumping version numbers or correcting spelling errors along with your changes unless they're necessary. - * Feel free to make these sorts of corrections in a separate PR, though! - -## Building from Source ## - -1. **Clone PSI Probe's git repository.** - - *Note: If you plan to contribute to PSI Probe, you should create your own fork on GitHub first and clone that. Otherwise, follow these steps to build the latest version of PSI Probe for yourself.* - - Execute the following command: - - git clone https://github.com/psi-probe/psi-probe - - This will create directory called `psi-probe`. Subsequent steps will refer to this as "your PSI Probe base directory." - -2. **Download and install Maven 3.** - - You may download it from the [Apache Maven website](http://maven.apache.org/download.cgi). - -3. **Run Maven.** - - Execute the following command from your PSI Probe base directory: - - mvn package - - This will create a deployable file at `web/target/probe.war`. - -## User Groups - -* [Announcements](http://groups.google.com/group/psi-probe/) -* [Discussions](http://groups.google.com/group/psi-probe-discuss/) +# PSI Probe + +[![Build Status](https://travis-ci.org/psi-probe/psi-probe.svg?branch=master)](https://travis-ci.org/psi-probe/psi-probe) +[![Project Stats](https://www.openhub.net/p/psi-probe/widgets/project_thin_badge.gif)](https://www.openhub.net/p/psi-probe) + +## Contributions ## + +Please follow [GitHub Flow](https://guides.github.com/introduction/flow/), with the following additions: + +* **Ensure an [issue](//github.com/psi-probe/psi-probe/issues) exists** before you begin work. If not, file one. + * You can get input from others before you begin. + * Issues power the release changelogs, so your change will be made known to users after it's done. +* **One PR per issue.** Include the issue number in your commit(s) and PR so that merging it will close the issue. +* **One issue per PR.** Keep changes minimal, and keep the scope narrow. + * Avoid making formatting changes alongside functionality changes. This is a recipe for conflicts. + * Avoid bumping version numbers or correcting spelling errors along with your changes unless they're necessary. + * Feel free to make these sorts of corrections in a separate PR, though! + +## Building from Source ## + +1. **Clone PSI Probe's git repository.** + + *Note: If you plan to contribute to PSI Probe, you should create your own fork on GitHub first and clone that. Otherwise, follow these steps to build the latest version of PSI Probe for yourself.* + + Execute the following command: + + git clone https://github.com/psi-probe/psi-probe + + This will create directory called `psi-probe`. Subsequent steps will refer to this as "your PSI Probe base directory." + +2. **Download and install Maven 3.** + + You may download it from the [Apache Maven website](http://maven.apache.org/download.cgi). + +3. **Run Maven.** + + Execute the following command from your PSI Probe base directory: + + mvn package + + This will create a deployable file at `web/target/probe.war`. + +## User Groups + +* [Announcements](http://groups.google.com/group/psi-probe/) +* [Discussions](http://groups.google.com/group/psi-probe-discuss/) diff --git a/core/pom.xml b/core/pom.xml index dfe2c40f81..e2971c5709 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -1,258 +1,258 @@ - - - 4.0.0 - - com.googlecode.psiprobe - psi-probe - 2.4.0-SNAPSHOT - - core - jar - PSI Probe Core - - Core logic, data models, and controllers - - - scm:git:ssh://git@github.com:psi-probe/psi-probe.git - scm:git:ssh://git@github.com:psi-probe/psi-probe.git - https://github.com/psi-probe/psi-probe/ - - - ../ - - - - - tomcat - catalina - 5.5.23 - provided - - - tomcat - jasper-compiler - 5.5.23 - provided - - - tomcat - jasper-runtime - 5.5.23 - provided - - - javax.servlet - servlet-api - - - - - tomcat - naming-factory - 5.5.23 - provided - - - tomcat - naming-factory-dbcp - 5.5.23 - provided - - - tomcat - naming-resources - 5.5.23 - provided - - - - javax.servlet - servlet-api - provided - - - javax.mail - mail - - - c3p0 - c3p0 - provided - - - com.oracle - ucp - provided - - - com.oracle - ojdbc14 - provided - - - commons-dbcp - commons-dbcp - provided - - - org.apache.tomcat - tomcat-jdbc - provided - - - com.jolbox - bonecp - provided - - - tanukisoft - wrapper - provided - - - org.apache.openejb - openejb-core - provided - - - - com.thoughtworks.xstream - xstream - compile - - - com.uwyn - jhighlight - compile - - - javax.servlet - servlet-api - - - - - commons-beanutils - commons-beanutils - compile - - - commons-collections - commons-collections - compile - - - commons-fileupload - commons-fileupload - compile - - - commons-io - commons-io - compile - - - commons-lang - commons-lang - compile - - - commons-logging - commons-logging - compile - - - commons-modeler - commons-modeler - compile - - - javainetlocator - inetaddresslocator - compile - - - javax.transaction - jta - compile - - - org.jfree - jfreechart - compile - - - log4j - log4j - runtime - - - opensymphony - quartz - compile - - - opensymphony - sitemesh - compile - - - javax.management - jmxri - ${jmxri.scope} - - - xpp3 - xpp3_min - compile - - - org.springframework - spring-beans - compile - - - org.springframework - spring-webmvc - compile - - - org.springframework - spring-tx - compile - - - org.springframework - spring-context - compile - - - org.springframework.security - spring-security-core - compile - - - junit - junit - test - - - - - - true - - - compile - - - - jboss - - provided - - - - + + + 4.0.0 + + com.googlecode.psiprobe + psi-probe + 2.4.0-SNAPSHOT + + core + jar + PSI Probe Core + + Core logic, data models, and controllers + + + scm:git:ssh://git@github.com:psi-probe/psi-probe.git + scm:git:ssh://git@github.com:psi-probe/psi-probe.git + https://github.com/psi-probe/psi-probe/ + + + ../ + + + + + tomcat + catalina + 5.5.23 + provided + + + tomcat + jasper-compiler + 5.5.23 + provided + + + tomcat + jasper-runtime + 5.5.23 + provided + + + javax.servlet + servlet-api + + + + + tomcat + naming-factory + 5.5.23 + provided + + + tomcat + naming-factory-dbcp + 5.5.23 + provided + + + tomcat + naming-resources + 5.5.23 + provided + + + + javax.servlet + servlet-api + provided + + + javax.mail + mail + + + c3p0 + c3p0 + provided + + + com.oracle + ucp + provided + + + com.oracle + ojdbc14 + provided + + + commons-dbcp + commons-dbcp + provided + + + org.apache.tomcat + tomcat-jdbc + provided + + + com.jolbox + bonecp + provided + + + tanukisoft + wrapper + provided + + + org.apache.openejb + openejb-core + provided + + + + com.thoughtworks.xstream + xstream + compile + + + com.uwyn + jhighlight + compile + + + javax.servlet + servlet-api + + + + + commons-beanutils + commons-beanutils + compile + + + commons-collections + commons-collections + compile + + + commons-fileupload + commons-fileupload + compile + + + commons-io + commons-io + compile + + + commons-lang + commons-lang + compile + + + commons-logging + commons-logging + compile + + + commons-modeler + commons-modeler + compile + + + javainetlocator + inetaddresslocator + compile + + + javax.transaction + jta + compile + + + org.jfree + jfreechart + compile + + + log4j + log4j + runtime + + + opensymphony + quartz + compile + + + opensymphony + sitemesh + compile + + + javax.management + jmxri + ${jmxri.scope} + + + xpp3 + xpp3_min + compile + + + org.springframework + spring-beans + compile + + + org.springframework + spring-webmvc + compile + + + org.springframework + spring-tx + compile + + + org.springframework + spring-context + compile + + + org.springframework.security + spring-security-core + compile + + + junit + junit + test + + + + + + true + + + compile + + + + jboss + + provided + + + + diff --git a/core/src/main/java/com/googlecode/psiprobe/AbstractTomcatContainer.java b/core/src/main/java/com/googlecode/psiprobe/AbstractTomcatContainer.java index 055a623471..3292705fec 100644 --- a/core/src/main/java/com/googlecode/psiprobe/AbstractTomcatContainer.java +++ b/core/src/main/java/com/googlecode/psiprobe/AbstractTomcatContainer.java @@ -1,465 +1,465 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe; - -import com.googlecode.psiprobe.model.jsp.Item; -import com.googlecode.psiprobe.model.jsp.Summary; - -import org.apache.catalina.Container; -import org.apache.catalina.Context; -import org.apache.catalina.Engine; -import org.apache.catalina.Host; -import org.apache.catalina.core.StandardContext; -import org.apache.commons.lang.reflect.MethodUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.jasper.EmbeddedServletOptions; -import org.apache.jasper.JasperException; -import org.apache.jasper.JspCompilationContext; -import org.apache.jasper.Options; -import org.apache.jasper.compiler.JspRuntimeContext; -import org.apache.naming.ContextBindings; -import org.springframework.util.ClassUtils; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; - -/** - * Abstraction layer to implement some functionality, which is common between different container - * adaptors. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public abstract class AbstractTomcatContainer implements TomcatContainer { - - protected Log logger = LogFactory.getLog(getClass()); - - public boolean installContext(String contextName) throws Exception { - contextName = formatContextName(contextName); - String contextFilename = formatContextFilename(contextName); - File f = new File(getConfigBase(), contextFilename + ".xml"); - installContextInternal(contextName, f); - return findContext(contextName) != null; - } - - public void remove(String contextName) throws Exception { - contextName = formatContextName(contextName); - Context ctx = findContext(contextName); - - if (ctx != null) { - - try { - stop(contextName); - } catch (Throwable e) { - logger.info("Stopping " + contextName + " threw this exception:", e); - // make sure we always re-throw ThreadDeath - if (e instanceof ThreadDeath) { - throw (ThreadDeath) e; - } - } - - File appDir; - File docBase = new File(ctx.getDocBase()); - - if (!docBase.isAbsolute()) { - appDir = new File(getAppBase(), ctx.getDocBase()); - } else { - appDir = docBase; - } - - logger.debug("Deleting " + appDir.getAbsolutePath()); - Utils.delete(appDir); - - String warFilename = formatContextFilename(contextName); - File warFile = new File(getAppBase(), warFilename + ".war"); - logger.debug("Deleting " + warFile.getAbsolutePath()); - Utils.delete(warFile); - - File configFile = getConfigFile(ctx); - if (configFile != null) { - logger.debug("Deleting " + configFile.getAbsolutePath()); - Utils.delete(configFile); - } - - removeInternal(contextName); - } - } - - /** - * Binds a naming context to the current thread's classloader. - * - * @param context the catalina context - */ - public void bindToContext(Context context) throws NamingException { - Object token = null; - ContextBindings.bindClassLoader(context, token, Thread.currentThread().getContextClassLoader()); - } - - /** - * Unbinds a naming context from the current thread's classloader. - * - * @param context the catalina context - */ - public void unbindFromContext(Context context) throws NamingException { - Object token = null; - ContextBindings.unbindClassLoader(context, token, Thread.currentThread() - .getContextClassLoader()); - } - - public Context findContext(String name) { - String safeName = formatContextName(name); - if (safeName == null) { - return null; - } - Context result = findContextInternal(safeName); - if (result == null && "".equals(safeName)) { - result = findContextInternal("/"); - } - return result; - } - - public String formatContextName(String name) { - if (name == null) { - return null; - } - String result = name.trim(); - if (!result.startsWith("/")) { - result = "/" + result; - } - if ("/".equals(result) || "/ROOT".equals(result)) { - result = ""; - } - return result; - } - - public String formatContextFilename(String contextName) { - if (contextName == null) { - return null; - } else if ("".equals(contextName)) { - return "ROOT"; - } else if (contextName.startsWith("/")) { - return contextName.substring(1); - } else { - return contextName; - } - } - - public void discardWorkDir(Context context) { - if (context instanceof StandardContext) { - StandardContext standardContext = (StandardContext) context; - logger.info("Discarding " + standardContext.getWorkPath()); - Utils.delete(new File(standardContext.getWorkPath(), "org")); - } else { - logger.error("context " + context.getName() + " is not an instance of " - + context.getClass().getName() + ", expected StandardContext"); - } - } - - public String getServletFileNameForJsp(Context context, String jspName) { - String servletName = null; - - ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); - if (servletConfig != null) { - ServletContext sctx = context.getServletContext(); - Options opt = new EmbeddedServletOptions(servletConfig, sctx); - JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); - JspCompilationContext jcctx = - createJspCompilationContext(jspName, false, opt, sctx, jrctx, null); - servletName = jcctx.getServletJavaFileName(); - } else { - logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); - } - return servletName; - } - - /** - * Compiles a list of JSPs. Names of JSP files are expected to be relative to the webapp root. The - * method updates summary with compilation details. - * - * @param context - * @param summary - * @param names - */ - public void recompileJsps(Context context, Summary summary, List names) { - ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); - if (servletConfig != null) { - if (summary != null) { - synchronized (servletConfig) { - ServletContext sctx = context.getServletContext(); - Options opt = new EmbeddedServletOptions(servletConfig, sctx); - - JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); - try { - /* - * we need to pass context classloader here, so the jsps can reference /WEB-INF/classes - * and /WEB-INF/lib. JspCompilationContext would only take URLClassLoader, so we fake it - */ - URLClassLoader classLoader = - new URLClassLoader(new URL[] {}, context.getLoader().getClassLoader()); - for (Iterator it = names.iterator(); it.hasNext();) { - String name = (String) it.next(); - long time = System.currentTimeMillis(); - JspCompilationContext jcctx = - createJspCompilationContext(name, false, opt, sctx, jrctx, classLoader); - ClassLoader prevCl = ClassUtils.overrideThreadContextClassLoader(classLoader); - try { - Item item = (Item) summary.getItems().get(name); - if (item != null) { - try { - org.apache.jasper.compiler.Compiler c = jcctx.createCompiler(); - c.compile(); - item.setState(Item.STATE_READY); - item.setException(null); - logger.info("Compiled " + name + ": OK"); - } catch (Exception e) { - item.setState(Item.STATE_FAILED); - item.setException(e); - logger.info("Compiled " + name + ": FAILED", e); - } - item.setCompileTime(System.currentTimeMillis() - time); - } else { - logger.error(name + " is not on the summary list, ignored"); - } - } finally { - ClassUtils.overrideThreadContextClassLoader(prevCl); - } - } - } finally { - jrctx.destroy(); - } - } - } else { - logger.error("summary is null for " + context.getName() + ", request ignored"); - } - } else { - logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); - } - } - - /** - * Lists and optionally compiles all JSPs for the given context. Compilation details are added to - * the summary. - * - * @param context - * @param summary - * @param compile - * @throws Exception - */ - public void listContextJsps(Context context, Summary summary, boolean compile) throws Exception { - ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); - if (servletConfig != null) { - synchronized (servletConfig) { - ServletContext sctx = context.getServletContext(); - Options opt = new EmbeddedServletOptions(servletConfig, sctx); - - JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); - try { - if (summary.getItems() == null) { - summary.setItems(new HashMap()); - } - - /* - * mark all items as missing - */ - for (Iterator it = summary.getItems().keySet().iterator(); it.hasNext();) { - Item item = (Item) summary.getItems().get(it.next()); - item.setMissing(true); - } - - /* - * we need to pass context classloader here, so the jsps can reference /WEB-INF/classes - * and /WEB-INF/lib. JspCompilationContext would only take URLClassLoader, so we fake it - */ - compileItem("/", opt, context, jrctx, summary, new URLClassLoader(new URL[] {}, context - .getLoader().getClassLoader()), 0, compile); - } finally { - jrctx.destroy(); - } - } - - // - // delete "missing" items by keeping "not missing" ones - // - Map hashMap = new HashMap(); - for (Iterator it = summary.getItems().keySet().iterator(); it.hasNext();) { - Object key = it.next(); - Item item = (Item) summary.getItems().get(key); - if (!item.isMissing()) { - hashMap.put(key, item); - } - } - - summary.setItems(hashMap); - } else { - logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); - } - } - - public File getConfigFile(Context ctx) { - String configFilePath = ctx.getConfigFile(); - if (configFilePath != null) { - return new File(configFilePath); - } else { - return null; - } - } - - protected String getConfigBase(Container container) { - File configBase = new File(System.getProperty("catalina.base"), "conf"); - Container baseHost = null; - Container baseEngine = null; - while (container != null) { - if (container instanceof Host) { - baseHost = container; - } - if (container instanceof Engine) { - baseEngine = container; - } - container = container.getParent(); - } - if (baseEngine != null) { - configBase = new File(configBase, baseEngine.getName()); - } - if (baseHost != null) { - configBase = new File(configBase, baseHost.getName()); - } - return configBase.getAbsolutePath(); - } - - /** - * Lists and optionally compiles a directory recursively. - * - * @param jspName name of JSP file or directory to be listed and compiled. - * @param opt - * @param ctx - * @param jrctx - * @param summary - * @param classLoader - * @param level - * @param compile - */ - protected void compileItem(String jspName, Options opt, Context ctx, JspRuntimeContext jrctx, - Summary summary, URLClassLoader classLoader, int level, boolean compile) { - ServletContext sctx = ctx.getServletContext(); - Set paths = sctx.getResourcePaths(jspName); - - if (paths != null) { - for (Iterator it = paths.iterator(); it.hasNext();) { - String name = (String) it.next(); - boolean isJsp = false; - - try { - isJsp = - name.endsWith(".jsp") || name.endsWith(".jspx") || opt.getJspConfig().isJspPage(name); - } catch (JasperException e) { - logger.info("isJspPage() thrown an error for " + name, e); - } - - if (isJsp) { - JspCompilationContext jcctx = - createJspCompilationContext(name, false, opt, sctx, jrctx, classLoader); - ClassLoader prevCl = ClassUtils.overrideThreadContextClassLoader(classLoader); - try { - Item item = (Item) summary.getItems().get(name); - - if (item == null) { - item = new Item(); - item.setName(name); - } - - item.setLevel(level); - item.setCompileTime(-1); - - Long objects[] = this.getResourceAttributes(name, ctx); - item.setSize(objects[0].longValue()); - item.setLastModified(objects[1].longValue()); - - long time = System.currentTimeMillis(); - try { - org.apache.jasper.compiler.Compiler c = jcctx.createCompiler(); - if (compile) { - c.compile(); - item.setState(Item.STATE_READY); - item.setException(null); - } else { - if (!c.isOutDated()) { - item.setState(Item.STATE_READY); - item.setException(null); - } else if (item.getState() != Item.STATE_FAILED) { - item.setState(Item.STATE_OOD); - item.setException(null); - } - } - logger.info("Compiled " + name + ": OK"); - } catch (Exception e) { - item.setState(Item.STATE_FAILED); - item.setException(e); - logger.info("Compiled " + name + ": FAILED", e); - } - if (compile) { - item.setCompileTime(System.currentTimeMillis() - time); - } - item.setMissing(false); - summary.getItems().put(name, item); - } finally { - ClassUtils.overrideThreadContextClassLoader(prevCl); - } - } else { - compileItem(name, opt, ctx, jrctx, summary, classLoader, level + 1, compile); - } - } - } else { - logger.debug("getResourcePaths() is null for " + jspName + ". Empty dir? Or Tomcat bug?"); - } - } - - protected JspCompilationContext createJspCompilationContext(String name, boolean isErrPage, - Options opt, ServletContext sctx, JspRuntimeContext jrctx, ClassLoader cl) { - - JspCompilationContext jcctx = new JspCompilationContext(name, false, opt, sctx, null, jrctx); - if (cl != null && cl instanceof URLClassLoader) { - try { - jcctx.setClassLoader((URLClassLoader) cl); - } catch (NoSuchMethodError err) { - // JBoss Web 2.1 has a different method signature for setClassLoader(). - try { - MethodUtils.invokeMethod(jcctx, "setClassLoader", cl); - } catch (NoSuchMethodException ex) { - throw new RuntimeException(ex); - } catch (IllegalAccessException ex) { - throw new RuntimeException(ex); - } catch (InvocationTargetException ex) { - throw new RuntimeException(ex); - } - } - } - return jcctx; - } - - protected abstract void removeInternal(String name) throws Exception; - - protected abstract void installContextInternal(String contextName, File f) throws Exception; - - protected abstract Context findContextInternal(String contextName); - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe; + +import com.googlecode.psiprobe.model.jsp.Item; +import com.googlecode.psiprobe.model.jsp.Summary; + +import org.apache.catalina.Container; +import org.apache.catalina.Context; +import org.apache.catalina.Engine; +import org.apache.catalina.Host; +import org.apache.catalina.core.StandardContext; +import org.apache.commons.lang.reflect.MethodUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jasper.EmbeddedServletOptions; +import org.apache.jasper.JasperException; +import org.apache.jasper.JspCompilationContext; +import org.apache.jasper.Options; +import org.apache.jasper.compiler.JspRuntimeContext; +import org.apache.naming.ContextBindings; +import org.springframework.util.ClassUtils; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +/** + * Abstraction layer to implement some functionality, which is common between different container + * adaptors. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public abstract class AbstractTomcatContainer implements TomcatContainer { + + protected Log logger = LogFactory.getLog(getClass()); + + public boolean installContext(String contextName) throws Exception { + contextName = formatContextName(contextName); + String contextFilename = formatContextFilename(contextName); + File f = new File(getConfigBase(), contextFilename + ".xml"); + installContextInternal(contextName, f); + return findContext(contextName) != null; + } + + public void remove(String contextName) throws Exception { + contextName = formatContextName(contextName); + Context ctx = findContext(contextName); + + if (ctx != null) { + + try { + stop(contextName); + } catch (Throwable e) { + logger.info("Stopping " + contextName + " threw this exception:", e); + // make sure we always re-throw ThreadDeath + if (e instanceof ThreadDeath) { + throw (ThreadDeath) e; + } + } + + File appDir; + File docBase = new File(ctx.getDocBase()); + + if (!docBase.isAbsolute()) { + appDir = new File(getAppBase(), ctx.getDocBase()); + } else { + appDir = docBase; + } + + logger.debug("Deleting " + appDir.getAbsolutePath()); + Utils.delete(appDir); + + String warFilename = formatContextFilename(contextName); + File warFile = new File(getAppBase(), warFilename + ".war"); + logger.debug("Deleting " + warFile.getAbsolutePath()); + Utils.delete(warFile); + + File configFile = getConfigFile(ctx); + if (configFile != null) { + logger.debug("Deleting " + configFile.getAbsolutePath()); + Utils.delete(configFile); + } + + removeInternal(contextName); + } + } + + /** + * Binds a naming context to the current thread's classloader. + * + * @param context the catalina context + */ + public void bindToContext(Context context) throws NamingException { + Object token = null; + ContextBindings.bindClassLoader(context, token, Thread.currentThread().getContextClassLoader()); + } + + /** + * Unbinds a naming context from the current thread's classloader. + * + * @param context the catalina context + */ + public void unbindFromContext(Context context) throws NamingException { + Object token = null; + ContextBindings.unbindClassLoader(context, token, Thread.currentThread() + .getContextClassLoader()); + } + + public Context findContext(String name) { + String safeName = formatContextName(name); + if (safeName == null) { + return null; + } + Context result = findContextInternal(safeName); + if (result == null && "".equals(safeName)) { + result = findContextInternal("/"); + } + return result; + } + + public String formatContextName(String name) { + if (name == null) { + return null; + } + String result = name.trim(); + if (!result.startsWith("/")) { + result = "/" + result; + } + if ("/".equals(result) || "/ROOT".equals(result)) { + result = ""; + } + return result; + } + + public String formatContextFilename(String contextName) { + if (contextName == null) { + return null; + } else if ("".equals(contextName)) { + return "ROOT"; + } else if (contextName.startsWith("/")) { + return contextName.substring(1); + } else { + return contextName; + } + } + + public void discardWorkDir(Context context) { + if (context instanceof StandardContext) { + StandardContext standardContext = (StandardContext) context; + logger.info("Discarding " + standardContext.getWorkPath()); + Utils.delete(new File(standardContext.getWorkPath(), "org")); + } else { + logger.error("context " + context.getName() + " is not an instance of " + + context.getClass().getName() + ", expected StandardContext"); + } + } + + public String getServletFileNameForJsp(Context context, String jspName) { + String servletName = null; + + ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); + if (servletConfig != null) { + ServletContext sctx = context.getServletContext(); + Options opt = new EmbeddedServletOptions(servletConfig, sctx); + JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); + JspCompilationContext jcctx = + createJspCompilationContext(jspName, false, opt, sctx, jrctx, null); + servletName = jcctx.getServletJavaFileName(); + } else { + logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); + } + return servletName; + } + + /** + * Compiles a list of JSPs. Names of JSP files are expected to be relative to the webapp root. The + * method updates summary with compilation details. + * + * @param context + * @param summary + * @param names + */ + public void recompileJsps(Context context, Summary summary, List names) { + ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); + if (servletConfig != null) { + if (summary != null) { + synchronized (servletConfig) { + ServletContext sctx = context.getServletContext(); + Options opt = new EmbeddedServletOptions(servletConfig, sctx); + + JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); + try { + /* + * we need to pass context classloader here, so the jsps can reference /WEB-INF/classes + * and /WEB-INF/lib. JspCompilationContext would only take URLClassLoader, so we fake it + */ + URLClassLoader classLoader = + new URLClassLoader(new URL[] {}, context.getLoader().getClassLoader()); + for (Iterator it = names.iterator(); it.hasNext();) { + String name = (String) it.next(); + long time = System.currentTimeMillis(); + JspCompilationContext jcctx = + createJspCompilationContext(name, false, opt, sctx, jrctx, classLoader); + ClassLoader prevCl = ClassUtils.overrideThreadContextClassLoader(classLoader); + try { + Item item = (Item) summary.getItems().get(name); + if (item != null) { + try { + org.apache.jasper.compiler.Compiler c = jcctx.createCompiler(); + c.compile(); + item.setState(Item.STATE_READY); + item.setException(null); + logger.info("Compiled " + name + ": OK"); + } catch (Exception e) { + item.setState(Item.STATE_FAILED); + item.setException(e); + logger.info("Compiled " + name + ": FAILED", e); + } + item.setCompileTime(System.currentTimeMillis() - time); + } else { + logger.error(name + " is not on the summary list, ignored"); + } + } finally { + ClassUtils.overrideThreadContextClassLoader(prevCl); + } + } + } finally { + jrctx.destroy(); + } + } + } else { + logger.error("summary is null for " + context.getName() + ", request ignored"); + } + } else { + logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); + } + } + + /** + * Lists and optionally compiles all JSPs for the given context. Compilation details are added to + * the summary. + * + * @param context + * @param summary + * @param compile + * @throws Exception + */ + public void listContextJsps(Context context, Summary summary, boolean compile) throws Exception { + ServletConfig servletConfig = (ServletConfig) context.findChild("jsp"); + if (servletConfig != null) { + synchronized (servletConfig) { + ServletContext sctx = context.getServletContext(); + Options opt = new EmbeddedServletOptions(servletConfig, sctx); + + JspRuntimeContext jrctx = new JspRuntimeContext(sctx, opt); + try { + if (summary.getItems() == null) { + summary.setItems(new HashMap()); + } + + /* + * mark all items as missing + */ + for (Iterator it = summary.getItems().keySet().iterator(); it.hasNext();) { + Item item = (Item) summary.getItems().get(it.next()); + item.setMissing(true); + } + + /* + * we need to pass context classloader here, so the jsps can reference /WEB-INF/classes + * and /WEB-INF/lib. JspCompilationContext would only take URLClassLoader, so we fake it + */ + compileItem("/", opt, context, jrctx, summary, new URLClassLoader(new URL[] {}, context + .getLoader().getClassLoader()), 0, compile); + } finally { + jrctx.destroy(); + } + } + + // + // delete "missing" items by keeping "not missing" ones + // + Map hashMap = new HashMap(); + for (Iterator it = summary.getItems().keySet().iterator(); it.hasNext();) { + Object key = it.next(); + Item item = (Item) summary.getItems().get(key); + if (!item.isMissing()) { + hashMap.put(key, item); + } + } + + summary.setItems(hashMap); + } else { + logger.error("Context " + context.getName() + " does not have \"jsp\" servlet"); + } + } + + public File getConfigFile(Context ctx) { + String configFilePath = ctx.getConfigFile(); + if (configFilePath != null) { + return new File(configFilePath); + } else { + return null; + } + } + + protected String getConfigBase(Container container) { + File configBase = new File(System.getProperty("catalina.base"), "conf"); + Container baseHost = null; + Container baseEngine = null; + while (container != null) { + if (container instanceof Host) { + baseHost = container; + } + if (container instanceof Engine) { + baseEngine = container; + } + container = container.getParent(); + } + if (baseEngine != null) { + configBase = new File(configBase, baseEngine.getName()); + } + if (baseHost != null) { + configBase = new File(configBase, baseHost.getName()); + } + return configBase.getAbsolutePath(); + } + + /** + * Lists and optionally compiles a directory recursively. + * + * @param jspName name of JSP file or directory to be listed and compiled. + * @param opt + * @param ctx + * @param jrctx + * @param summary + * @param classLoader + * @param level + * @param compile + */ + protected void compileItem(String jspName, Options opt, Context ctx, JspRuntimeContext jrctx, + Summary summary, URLClassLoader classLoader, int level, boolean compile) { + ServletContext sctx = ctx.getServletContext(); + Set paths = sctx.getResourcePaths(jspName); + + if (paths != null) { + for (Iterator it = paths.iterator(); it.hasNext();) { + String name = (String) it.next(); + boolean isJsp = false; + + try { + isJsp = + name.endsWith(".jsp") || name.endsWith(".jspx") || opt.getJspConfig().isJspPage(name); + } catch (JasperException e) { + logger.info("isJspPage() thrown an error for " + name, e); + } + + if (isJsp) { + JspCompilationContext jcctx = + createJspCompilationContext(name, false, opt, sctx, jrctx, classLoader); + ClassLoader prevCl = ClassUtils.overrideThreadContextClassLoader(classLoader); + try { + Item item = (Item) summary.getItems().get(name); + + if (item == null) { + item = new Item(); + item.setName(name); + } + + item.setLevel(level); + item.setCompileTime(-1); + + Long objects[] = this.getResourceAttributes(name, ctx); + item.setSize(objects[0].longValue()); + item.setLastModified(objects[1].longValue()); + + long time = System.currentTimeMillis(); + try { + org.apache.jasper.compiler.Compiler c = jcctx.createCompiler(); + if (compile) { + c.compile(); + item.setState(Item.STATE_READY); + item.setException(null); + } else { + if (!c.isOutDated()) { + item.setState(Item.STATE_READY); + item.setException(null); + } else if (item.getState() != Item.STATE_FAILED) { + item.setState(Item.STATE_OOD); + item.setException(null); + } + } + logger.info("Compiled " + name + ": OK"); + } catch (Exception e) { + item.setState(Item.STATE_FAILED); + item.setException(e); + logger.info("Compiled " + name + ": FAILED", e); + } + if (compile) { + item.setCompileTime(System.currentTimeMillis() - time); + } + item.setMissing(false); + summary.getItems().put(name, item); + } finally { + ClassUtils.overrideThreadContextClassLoader(prevCl); + } + } else { + compileItem(name, opt, ctx, jrctx, summary, classLoader, level + 1, compile); + } + } + } else { + logger.debug("getResourcePaths() is null for " + jspName + ". Empty dir? Or Tomcat bug?"); + } + } + + protected JspCompilationContext createJspCompilationContext(String name, boolean isErrPage, + Options opt, ServletContext sctx, JspRuntimeContext jrctx, ClassLoader cl) { + + JspCompilationContext jcctx = new JspCompilationContext(name, false, opt, sctx, null, jrctx); + if (cl != null && cl instanceof URLClassLoader) { + try { + jcctx.setClassLoader((URLClassLoader) cl); + } catch (NoSuchMethodError err) { + // JBoss Web 2.1 has a different method signature for setClassLoader(). + try { + MethodUtils.invokeMethod(jcctx, "setClassLoader", cl); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + } + return jcctx; + } + + protected abstract void removeInternal(String name) throws Exception; + + protected abstract void installContextInternal(String contextName, File f) throws Exception; + + protected abstract Context findContextInternal(String contextName); + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/ProbeServlet.java b/core/src/main/java/com/googlecode/psiprobe/ProbeServlet.java index 4a4d8f54b8..f878ea494d 100644 --- a/core/src/main/java/com/googlecode/psiprobe/ProbeServlet.java +++ b/core/src/main/java/com/googlecode/psiprobe/ProbeServlet.java @@ -1,70 +1,70 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe; - -import com.googlecode.psiprobe.beans.ContainerWrapperBean; - -import org.apache.catalina.ContainerServlet; -import org.apache.catalina.Wrapper; -import org.springframework.web.servlet.DispatcherServlet; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Main dispatcher servlet. Spring default dispatcher servlet had to be superceeded to handle - * "privileged" application context features. The actual requirement is to capture passed Wrapper - * instance into ContainerWrapperBean. Wrapper instance is our gateway to Tomcat. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class ProbeServlet extends DispatcherServlet implements ContainerServlet { - - private Wrapper wrapper; - - public Wrapper getWrapper() { - return wrapper; - } - - public void setWrapper(Wrapper wrapper) { - this.wrapper = wrapper; - logger.info("setWrapper() called"); - } - - public void init(ServletConfig config) throws ServletException { - super.init(config); - if (wrapper != null) { - getContainerWrapperBean().setWrapper(wrapper); - } else { - throw new ServletException("Wrapper is null"); - } - } - - protected void doDispatch(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse) throws Exception { - - httpServletRequest.setCharacterEncoding("UTF-8"); - super.doDispatch(httpServletRequest, httpServletResponse); - } - - public void destroy() { - getContainerWrapperBean().setWrapper(null); - super.destroy(); - } - - protected ContainerWrapperBean getContainerWrapperBean() { - return (ContainerWrapperBean) getWebApplicationContext().getBean("containerWrapper"); - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe; + +import com.googlecode.psiprobe.beans.ContainerWrapperBean; + +import org.apache.catalina.ContainerServlet; +import org.apache.catalina.Wrapper; +import org.springframework.web.servlet.DispatcherServlet; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Main dispatcher servlet. Spring default dispatcher servlet had to be superceeded to handle + * "privileged" application context features. The actual requirement is to capture passed Wrapper + * instance into ContainerWrapperBean. Wrapper instance is our gateway to Tomcat. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class ProbeServlet extends DispatcherServlet implements ContainerServlet { + + private Wrapper wrapper; + + public Wrapper getWrapper() { + return wrapper; + } + + public void setWrapper(Wrapper wrapper) { + this.wrapper = wrapper; + logger.info("setWrapper() called"); + } + + public void init(ServletConfig config) throws ServletException { + super.init(config); + if (wrapper != null) { + getContainerWrapperBean().setWrapper(wrapper); + } else { + throw new ServletException("Wrapper is null"); + } + } + + protected void doDispatch(HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse) throws Exception { + + httpServletRequest.setCharacterEncoding("UTF-8"); + super.doDispatch(httpServletRequest, httpServletResponse); + } + + public void destroy() { + getContainerWrapperBean().setWrapper(null); + super.destroy(); + } + + protected ContainerWrapperBean getContainerWrapperBean() { + return (ContainerWrapperBean) getWebApplicationContext().getBean("containerWrapper"); + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/TomcatContainer.java b/core/src/main/java/com/googlecode/psiprobe/TomcatContainer.java index 91c74e9583..0c5245eda8 100644 --- a/core/src/main/java/com/googlecode/psiprobe/TomcatContainer.java +++ b/core/src/main/java/com/googlecode/psiprobe/TomcatContainer.java @@ -1,103 +1,103 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe; - -import com.googlecode.psiprobe.model.jsp.Summary; - -import org.apache.catalina.Context; -import org.apache.catalina.Wrapper; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; - -/** - * Part of Tomcat container version abstraction layer. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public interface TomcatContainer { - - Context findContext(String name); - - String formatContextName(String name); - - String formatContextFilename(String contextName); - - List findContexts(); - - void stop(String name) throws Exception; - - void start(String name) throws Exception; - - void remove(String name) throws Exception; - - /** - * Installs .war file at the given context name. - * - * @param name the name of the context - * @param url pointer to .war file to be deployed - * @throws Exception - */ - void installWar(String name, URL url) throws Exception; - - /** - * This method always returns absolute path, no matter what Tomcat is up to. - * - * @return absolute path to applications base (normally "webapps") - */ - File getAppBase(); - - File getConfigFile(Context ctx); - - String getConfigBase(); - - void setWrapper(Wrapper wrapper); - - boolean canBoundTo(String binding); - - boolean installContext(String contextName) throws Exception; - - void listContextJsps(Context context, Summary summary, boolean compile) throws Exception; - - void recompileJsps(Context context, Summary summary, List names); - - void discardWorkDir(Context context); - - Object getLogger(Context context); - - String getHostName(); - - String getName(); - - String getServletFileNameForJsp(Context context, String jspName); - - List getApplicationFilterMaps(Context context); - - boolean getAvailable(Context context); - - public void addContextResource(Context context, List resourceList, boolean contextBound); - - public void addContextResourceLink(Context context, List resourceList, boolean contextBound); - - public List getApplicationFilters(Context context); - - public List getApplicationInitParams(Context context); - - boolean resourceExists(String name, Context context); - - InputStream getResourceStream(String name, Context context) throws IOException; - - public Long[] getResourceAttributes(String name, Context context); -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe; + +import com.googlecode.psiprobe.model.jsp.Summary; + +import org.apache.catalina.Context; +import org.apache.catalina.Wrapper; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; + +/** + * Part of Tomcat container version abstraction layer. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public interface TomcatContainer { + + Context findContext(String name); + + String formatContextName(String name); + + String formatContextFilename(String contextName); + + List findContexts(); + + void stop(String name) throws Exception; + + void start(String name) throws Exception; + + void remove(String name) throws Exception; + + /** + * Installs .war file at the given context name. + * + * @param name the name of the context + * @param url pointer to .war file to be deployed + * @throws Exception + */ + void installWar(String name, URL url) throws Exception; + + /** + * This method always returns absolute path, no matter what Tomcat is up to. + * + * @return absolute path to applications base (normally "webapps") + */ + File getAppBase(); + + File getConfigFile(Context ctx); + + String getConfigBase(); + + void setWrapper(Wrapper wrapper); + + boolean canBoundTo(String binding); + + boolean installContext(String contextName) throws Exception; + + void listContextJsps(Context context, Summary summary, boolean compile) throws Exception; + + void recompileJsps(Context context, Summary summary, List names); + + void discardWorkDir(Context context); + + Object getLogger(Context context); + + String getHostName(); + + String getName(); + + String getServletFileNameForJsp(Context context, String jspName); + + List getApplicationFilterMaps(Context context); + + boolean getAvailable(Context context); + + public void addContextResource(Context context, List resourceList, boolean contextBound); + + public void addContextResourceLink(Context context, List resourceList, boolean contextBound); + + public List getApplicationFilters(Context context); + + public List getApplicationInitParams(Context context); + + boolean resourceExists(String name, Context context); + + InputStream getResourceStream(String name, Context context) throws IOException; + + public Long[] getResourceAttributes(String name, Context context); +} diff --git a/core/src/main/java/com/googlecode/psiprobe/UptimeListener.java b/core/src/main/java/com/googlecode/psiprobe/UptimeListener.java index 40b89d6df4..7890e4ecc5 100644 --- a/core/src/main/java/com/googlecode/psiprobe/UptimeListener.java +++ b/core/src/main/java/com/googlecode/psiprobe/UptimeListener.java @@ -1,34 +1,34 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -/** - * Simple listener that registers its startup time in the ServletContext object. - * - * @author Vlad Ilyushchenko - * @author Adriano Machado - * @author Mark Lewis - */ -public class UptimeListener implements ServletContextListener { - - public static final String START_TIME_KEY = "UPTIME_START"; - - public void contextInitialized(ServletContextEvent sce) { - sce.getServletContext().setAttribute(START_TIME_KEY, new Long(System.currentTimeMillis())); - } - - public void contextDestroyed(ServletContextEvent sce) { - sce.getServletContext().removeAttribute(START_TIME_KEY); - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +/** + * Simple listener that registers its startup time in the ServletContext object. + * + * @author Vlad Ilyushchenko + * @author Adriano Machado + * @author Mark Lewis + */ +public class UptimeListener implements ServletContextListener { + + public static final String START_TIME_KEY = "UPTIME_START"; + + public void contextInitialized(ServletContextEvent sce) { + sce.getServletContext().setAttribute(START_TIME_KEY, new Long(System.currentTimeMillis())); + } + + public void contextDestroyed(ServletContextEvent sce) { + sce.getServletContext().removeAttribute(START_TIME_KEY); + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/Utils.java b/core/src/main/java/com/googlecode/psiprobe/Utils.java index 454d780da8..fe79e7703e 100644 --- a/core/src/main/java/com/googlecode/psiprobe/Utils.java +++ b/core/src/main/java/com/googlecode/psiprobe/Utils.java @@ -1,438 +1,438 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe; - -import com.googlecode.psiprobe.tokenizer.StringTokenizer; -import com.googlecode.psiprobe.tokenizer.Token; -import com.googlecode.psiprobe.tokenizer.Tokenizer; -import com.googlecode.psiprobe.tokenizer.TokenizerSymbol; - -import com.uwyn.jhighlight.renderer.Renderer; -import com.uwyn.jhighlight.renderer.XhtmlRendererFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.modeler.Registry; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.io.Reader; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Misc. static helper methods. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class Utils { - - private static Log logger = LogFactory.getLog(Utils.class.getName()); - - public static int calcPoolUsageScore(int max, int value) { - return max > 0 ? Math.max(0, value) * 100 / max : 0; - } - - /** - * Reads a file on disk. The method uses default file encoding (see: file.encoding system - * property) - * - * @param file to be read - * @return String representation of the file contents - */ - public static String readFile(File file, String charsetName) throws IOException { - String result = null; - FileInputStream fis = new FileInputStream(file); - try { - result = readStream(fis, charsetName); - } finally { - fis.close(); - } - return result; - } - - /** - * Reads strings from the intput stream using the given charset. This method closes the input - * stream after it has been consumed. - * - * @param is - * @param charsetName - * @return the contents of the given input stream - * @throws IOException - */ - public static String readStream(InputStream is, String charsetName) throws IOException { - - // - // use system's default encoding if the passed encoding is unsupported - // - Charset charset = Charset.forName(System.getProperty("file.encoding")); - if (Charset.isSupported(charsetName)) { - charset = Charset.forName(charsetName); - } - - StringBuffer out = new StringBuffer(); - BufferedReader r = new BufferedReader(new InputStreamReader(is, charset), 4096); - try { - String b; - while ((b = r.readLine()) != null) { - out.append(b).append("\n"); - } - } finally { - r.close(); - } - - return out.toString(); - } - - public static void delete(File f) { - if (f != null && f.exists()) { - if (f.isDirectory()) { - File[] files = f.listFiles(); - for (int i = 0; i < files.length; i++) { - delete(files[i]); - } - } - if (!f.delete()) { - logger.debug("Cannot delete " + f.getAbsolutePath()); - } - } else { - logger.debug(f + " does not exist"); - } - } - - public static int toInt(String num, int defaultValue) { - if (num != null) { - try { - return Integer.parseInt(num); - } catch (NumberFormatException e) { - // ignore - } - } - return defaultValue; - } - - public static int toIntHex(String num, int defaultValue) { - try { - if (num != null && num.startsWith("#")) { - num = num.substring(1); - } - return Integer.parseInt(num, 16); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public static int toInt(Integer num, int defaultValue) { - return num == null ? defaultValue : num.intValue(); - } - - public static long toLong(String num, long defaultValue) { - if (num != null) { - try { - return Long.parseLong(num); - } catch (NumberFormatException e) { - // ignore - } - } - return defaultValue; - } - - public static long toLong(Long num, long defaultValue) { - return num == null ? defaultValue : num.longValue(); - } - - public static float toFloat(String num, float defaultValue) { - if (num != null) { - try { - return Float.parseFloat(num); - } catch (NumberFormatException e) { - // ignore - } - } - return defaultValue; - } - - public static String getJSPEncoding(InputStream is) throws IOException { - - String encoding = null; - String contentType = null; - - Tokenizer jspTokenizer = new Tokenizer(); - jspTokenizer.addSymbol("\n", true); - jspTokenizer.addSymbol(" ", true); - jspTokenizer.addSymbol("\t", true); - jspTokenizer.addSymbol(new TokenizerSymbol("dir", "<%@", "%>", false, false, true, false)); - - StringTokenizer directiveTokenizer = new StringTokenizer(); - directiveTokenizer.addSymbol("\n", true); - directiveTokenizer.addSymbol(" ", true); - directiveTokenizer.addSymbol("\t", true); - directiveTokenizer.addSymbol("="); - directiveTokenizer.addSymbol("\"", "\"", false); - directiveTokenizer.addSymbol("'", "'", false); - - StringTokenizer contentTypeTokenizer = new StringTokenizer(); - contentTypeTokenizer.addSymbol(" ", true); - contentTypeTokenizer.addSymbol(";", true); - - - Reader reader = new InputStreamReader(is, "ISO-8859-1"); - try { - jspTokenizer.setReader(reader); - while (jspTokenizer.hasMore()) { - Token token = jspTokenizer.nextToken(); - if ("dir".equals(token.getName())) { - directiveTokenizer.setString(token.getInnerText()); - if (directiveTokenizer.hasMore() - && directiveTokenizer.nextToken().getText().equals("page")) { - while (directiveTokenizer.hasMore()) { - Token dTk = directiveTokenizer.nextToken(); - if ("pageEncoding".equals(dTk.getText())) { - if (directiveTokenizer.hasMore() - && "=".equals(directiveTokenizer.nextToken().getText())) { - if (directiveTokenizer.hasMore()) { - encoding = directiveTokenizer.nextToken().getInnerText(); - break; - } - } - } else if ("contentType".equals(dTk.getText())) { - if (directiveTokenizer.hasMore() - && "=".equals(directiveTokenizer.nextToken().getText())) { - if (directiveTokenizer.hasMore()) { - contentType = directiveTokenizer.nextToken().getInnerText(); - } - } - } - } - } - } - } - } finally { - reader.close(); - } - - if (encoding == null && contentType != null) { - contentTypeTokenizer.setString(contentType); - while (contentTypeTokenizer.hasMore()) { - String token = contentTypeTokenizer.nextToken().getText(); - if (token.startsWith("charset=")) { - encoding = token.substring("charset=".length()); - break; - } - } - } - - return encoding != null ? encoding : "ISO-8859-1"; - } - - public static void sendFile(HttpServletRequest request, HttpServletResponse response, File file) - throws IOException { - - OutputStream out = response.getOutputStream(); - RandomAccessFile raf = new RandomAccessFile(file, "r"); - try { - long fileSize = raf.length(); - long rangeStart = 0; - long rangeFinish = fileSize - 1; - - // accept attempts to resume download (if any) - String range = request.getHeader("Range"); - if (range != null && range.startsWith("bytes=")) { - String pureRange = range.replaceAll("bytes=", ""); - int rangeSep = pureRange.indexOf("-"); - - try { - rangeStart = Long.parseLong(pureRange.substring(0, rangeSep)); - if (rangeStart > fileSize || rangeStart < 0) { - rangeStart = 0; - } - } catch (NumberFormatException e) { - // ignore the exception, keep rangeStart unchanged - } - - if (rangeSep < pureRange.length() - 1) { - try { - rangeFinish = Long.parseLong(pureRange.substring(rangeSep + 1)); - if (rangeFinish < 0 || rangeFinish >= fileSize) { - rangeFinish = fileSize - 1; - } - } catch (NumberFormatException e) { - // ignore the exception - } - } - } - - // set some headers - response.setContentType("application/x-download"); - response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); - response.setHeader("Accept-Ranges", "bytes"); - response.setHeader("Content-Length", Long.toString(rangeFinish - rangeStart + 1)); - response.setHeader("Content-Range", "bytes " + rangeStart + "-" + rangeFinish + "/" - + fileSize); - - // seek to the requested offset - raf.seek(rangeStart); - - // send the file - byte[] buffer = new byte[4096]; - - long len; - int totalRead = 0; - boolean nomore = false; - while (true) { - len = raf.read(buffer); - if (len > 0 && totalRead + len > rangeFinish - rangeStart + 1) { - // read more then required? - // adjust the length - len = rangeFinish - rangeStart + 1 - totalRead; - nomore = true; - } - - if (len > 0) { - out.write(buffer, 0, (int) len); - totalRead += len; - if (nomore) { - break; - } - } else { - break; - } - } - } finally { - raf.close(); - } - } - - public static Thread getThreadByName(String name) { - if (name != null) { - // get top ThreadGroup - ThreadGroup masterGroup = Thread.currentThread().getThreadGroup(); - while (masterGroup.getParent() != null) { - masterGroup = masterGroup.getParent(); - } - - - Thread[] threads = new Thread[masterGroup.activeCount()]; - int numThreads = masterGroup.enumerate(threads); - - for (int i = 0; i < numThreads; i++) { - if (threads[i] != null && name.equals(threads[i].getName())) { - return threads[i]; - } - } - } - return null; - } - - public static String highlightStream(String name, InputStream input, String rendererName, - String encoding) throws IOException { - - Renderer jspRenderer = XhtmlRendererFactory.getRenderer(rendererName); - if (jspRenderer != null) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - jspRenderer.highlight(name, input, bos, encoding, true); - - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - - Tokenizer tokenizer = new Tokenizer(new InputStreamReader(bis, encoding)); - tokenizer.addSymbol(new TokenizerSymbol("EOL", "\n", null, false, false, true, false)); - tokenizer.addSymbol(new TokenizerSymbol("EOL", "\r\n", null, false, false, true, false)); - - // - // JHighlight adds HTML comment as the first line, so if - // we number the lines we could end up with a line number and no line - // to avoid that we just ignore the first line alltogether. - // - StringBuffer buffer = new StringBuffer(); - long counter = 0; - while (tokenizer.hasMore()) { - Token tk = tokenizer.nextToken(); - if ("EOL".equals(tk.getName())) { - counter++; - buffer.append(tk.getText()); - } else if (counter > 0) { - buffer.append(""); - buffer.append(""); - buffer.append(leftPad(Long.toString(counter), 6, " ")); - buffer.append(""); - buffer.append(tk.getText()); - buffer.append(""); - } - } - return buffer.toString(); - } - return null; - } - - public static String leftPad(String s, int len, String fill) { - StringBuffer sb = new StringBuffer(len); - if (s.length() < len) { - for (int i = s.length(); i < len; i++) { - sb.append(fill); - } - } - sb.append(s); - return sb.toString(); - } - - public static List getNamesForLocale(String baseName, Locale locale) { - List result = new ArrayList(3); - String language = locale.getLanguage(); - String country = locale.getCountry(); - String variant = locale.getVariant(); - StringBuffer temp = new StringBuffer(baseName); - - if (language.length() > 0) { - temp.append('_').append(language); - result.add(0, temp.toString()); - } - - if (country.length() > 0) { - temp.append('_').append(country); - result.add(0, temp.toString()); - } - - if (variant.length() > 0) { - temp.append('_').append(variant); - result.add(0, temp.toString()); - } - - return result; - } - - public static boolean isThreadingEnabled() { - try { - MBeanServer mBeanServer = new Registry().getMBeanServer(); - ObjectName threadingOName = new ObjectName("java.lang:type=Threading"); - Set s = mBeanServer.queryMBeans(threadingOName, null); - return s != null && s.size() > 0; - } catch (MalformedObjectNameException e) { - return false; - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe; + +import com.googlecode.psiprobe.tokenizer.StringTokenizer; +import com.googlecode.psiprobe.tokenizer.Token; +import com.googlecode.psiprobe.tokenizer.Tokenizer; +import com.googlecode.psiprobe.tokenizer.TokenizerSymbol; + +import com.uwyn.jhighlight.renderer.Renderer; +import com.uwyn.jhighlight.renderer.XhtmlRendererFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.modeler.Registry; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.io.Reader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Misc. static helper methods. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class Utils { + + private static Log logger = LogFactory.getLog(Utils.class.getName()); + + public static int calcPoolUsageScore(int max, int value) { + return max > 0 ? Math.max(0, value) * 100 / max : 0; + } + + /** + * Reads a file on disk. The method uses default file encoding (see: file.encoding system + * property) + * + * @param file to be read + * @return String representation of the file contents + */ + public static String readFile(File file, String charsetName) throws IOException { + String result = null; + FileInputStream fis = new FileInputStream(file); + try { + result = readStream(fis, charsetName); + } finally { + fis.close(); + } + return result; + } + + /** + * Reads strings from the intput stream using the given charset. This method closes the input + * stream after it has been consumed. + * + * @param is + * @param charsetName + * @return the contents of the given input stream + * @throws IOException + */ + public static String readStream(InputStream is, String charsetName) throws IOException { + + // + // use system's default encoding if the passed encoding is unsupported + // + Charset charset = Charset.forName(System.getProperty("file.encoding")); + if (Charset.isSupported(charsetName)) { + charset = Charset.forName(charsetName); + } + + StringBuffer out = new StringBuffer(); + BufferedReader r = new BufferedReader(new InputStreamReader(is, charset), 4096); + try { + String b; + while ((b = r.readLine()) != null) { + out.append(b).append("\n"); + } + } finally { + r.close(); + } + + return out.toString(); + } + + public static void delete(File f) { + if (f != null && f.exists()) { + if (f.isDirectory()) { + File[] files = f.listFiles(); + for (int i = 0; i < files.length; i++) { + delete(files[i]); + } + } + if (!f.delete()) { + logger.debug("Cannot delete " + f.getAbsolutePath()); + } + } else { + logger.debug(f + " does not exist"); + } + } + + public static int toInt(String num, int defaultValue) { + if (num != null) { + try { + return Integer.parseInt(num); + } catch (NumberFormatException e) { + // ignore + } + } + return defaultValue; + } + + public static int toIntHex(String num, int defaultValue) { + try { + if (num != null && num.startsWith("#")) { + num = num.substring(1); + } + return Integer.parseInt(num, 16); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static int toInt(Integer num, int defaultValue) { + return num == null ? defaultValue : num.intValue(); + } + + public static long toLong(String num, long defaultValue) { + if (num != null) { + try { + return Long.parseLong(num); + } catch (NumberFormatException e) { + // ignore + } + } + return defaultValue; + } + + public static long toLong(Long num, long defaultValue) { + return num == null ? defaultValue : num.longValue(); + } + + public static float toFloat(String num, float defaultValue) { + if (num != null) { + try { + return Float.parseFloat(num); + } catch (NumberFormatException e) { + // ignore + } + } + return defaultValue; + } + + public static String getJSPEncoding(InputStream is) throws IOException { + + String encoding = null; + String contentType = null; + + Tokenizer jspTokenizer = new Tokenizer(); + jspTokenizer.addSymbol("\n", true); + jspTokenizer.addSymbol(" ", true); + jspTokenizer.addSymbol("\t", true); + jspTokenizer.addSymbol(new TokenizerSymbol("dir", "<%@", "%>", false, false, true, false)); + + StringTokenizer directiveTokenizer = new StringTokenizer(); + directiveTokenizer.addSymbol("\n", true); + directiveTokenizer.addSymbol(" ", true); + directiveTokenizer.addSymbol("\t", true); + directiveTokenizer.addSymbol("="); + directiveTokenizer.addSymbol("\"", "\"", false); + directiveTokenizer.addSymbol("'", "'", false); + + StringTokenizer contentTypeTokenizer = new StringTokenizer(); + contentTypeTokenizer.addSymbol(" ", true); + contentTypeTokenizer.addSymbol(";", true); + + + Reader reader = new InputStreamReader(is, "ISO-8859-1"); + try { + jspTokenizer.setReader(reader); + while (jspTokenizer.hasMore()) { + Token token = jspTokenizer.nextToken(); + if ("dir".equals(token.getName())) { + directiveTokenizer.setString(token.getInnerText()); + if (directiveTokenizer.hasMore() + && directiveTokenizer.nextToken().getText().equals("page")) { + while (directiveTokenizer.hasMore()) { + Token dTk = directiveTokenizer.nextToken(); + if ("pageEncoding".equals(dTk.getText())) { + if (directiveTokenizer.hasMore() + && "=".equals(directiveTokenizer.nextToken().getText())) { + if (directiveTokenizer.hasMore()) { + encoding = directiveTokenizer.nextToken().getInnerText(); + break; + } + } + } else if ("contentType".equals(dTk.getText())) { + if (directiveTokenizer.hasMore() + && "=".equals(directiveTokenizer.nextToken().getText())) { + if (directiveTokenizer.hasMore()) { + contentType = directiveTokenizer.nextToken().getInnerText(); + } + } + } + } + } + } + } + } finally { + reader.close(); + } + + if (encoding == null && contentType != null) { + contentTypeTokenizer.setString(contentType); + while (contentTypeTokenizer.hasMore()) { + String token = contentTypeTokenizer.nextToken().getText(); + if (token.startsWith("charset=")) { + encoding = token.substring("charset=".length()); + break; + } + } + } + + return encoding != null ? encoding : "ISO-8859-1"; + } + + public static void sendFile(HttpServletRequest request, HttpServletResponse response, File file) + throws IOException { + + OutputStream out = response.getOutputStream(); + RandomAccessFile raf = new RandomAccessFile(file, "r"); + try { + long fileSize = raf.length(); + long rangeStart = 0; + long rangeFinish = fileSize - 1; + + // accept attempts to resume download (if any) + String range = request.getHeader("Range"); + if (range != null && range.startsWith("bytes=")) { + String pureRange = range.replaceAll("bytes=", ""); + int rangeSep = pureRange.indexOf("-"); + + try { + rangeStart = Long.parseLong(pureRange.substring(0, rangeSep)); + if (rangeStart > fileSize || rangeStart < 0) { + rangeStart = 0; + } + } catch (NumberFormatException e) { + // ignore the exception, keep rangeStart unchanged + } + + if (rangeSep < pureRange.length() - 1) { + try { + rangeFinish = Long.parseLong(pureRange.substring(rangeSep + 1)); + if (rangeFinish < 0 || rangeFinish >= fileSize) { + rangeFinish = fileSize - 1; + } + } catch (NumberFormatException e) { + // ignore the exception + } + } + } + + // set some headers + response.setContentType("application/x-download"); + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); + response.setHeader("Accept-Ranges", "bytes"); + response.setHeader("Content-Length", Long.toString(rangeFinish - rangeStart + 1)); + response.setHeader("Content-Range", "bytes " + rangeStart + "-" + rangeFinish + "/" + + fileSize); + + // seek to the requested offset + raf.seek(rangeStart); + + // send the file + byte[] buffer = new byte[4096]; + + long len; + int totalRead = 0; + boolean nomore = false; + while (true) { + len = raf.read(buffer); + if (len > 0 && totalRead + len > rangeFinish - rangeStart + 1) { + // read more then required? + // adjust the length + len = rangeFinish - rangeStart + 1 - totalRead; + nomore = true; + } + + if (len > 0) { + out.write(buffer, 0, (int) len); + totalRead += len; + if (nomore) { + break; + } + } else { + break; + } + } + } finally { + raf.close(); + } + } + + public static Thread getThreadByName(String name) { + if (name != null) { + // get top ThreadGroup + ThreadGroup masterGroup = Thread.currentThread().getThreadGroup(); + while (masterGroup.getParent() != null) { + masterGroup = masterGroup.getParent(); + } + + + Thread[] threads = new Thread[masterGroup.activeCount()]; + int numThreads = masterGroup.enumerate(threads); + + for (int i = 0; i < numThreads; i++) { + if (threads[i] != null && name.equals(threads[i].getName())) { + return threads[i]; + } + } + } + return null; + } + + public static String highlightStream(String name, InputStream input, String rendererName, + String encoding) throws IOException { + + Renderer jspRenderer = XhtmlRendererFactory.getRenderer(rendererName); + if (jspRenderer != null) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + jspRenderer.highlight(name, input, bos, encoding, true); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + + Tokenizer tokenizer = new Tokenizer(new InputStreamReader(bis, encoding)); + tokenizer.addSymbol(new TokenizerSymbol("EOL", "\n", null, false, false, true, false)); + tokenizer.addSymbol(new TokenizerSymbol("EOL", "\r\n", null, false, false, true, false)); + + // + // JHighlight adds HTML comment as the first line, so if + // we number the lines we could end up with a line number and no line + // to avoid that we just ignore the first line alltogether. + // + StringBuffer buffer = new StringBuffer(); + long counter = 0; + while (tokenizer.hasMore()) { + Token tk = tokenizer.nextToken(); + if ("EOL".equals(tk.getName())) { + counter++; + buffer.append(tk.getText()); + } else if (counter > 0) { + buffer.append(""); + buffer.append(""); + buffer.append(leftPad(Long.toString(counter), 6, " ")); + buffer.append(""); + buffer.append(tk.getText()); + buffer.append(""); + } + } + return buffer.toString(); + } + return null; + } + + public static String leftPad(String s, int len, String fill) { + StringBuffer sb = new StringBuffer(len); + if (s.length() < len) { + for (int i = s.length(); i < len; i++) { + sb.append(fill); + } + } + sb.append(s); + return sb.toString(); + } + + public static List getNamesForLocale(String baseName, Locale locale) { + List result = new ArrayList(3); + String language = locale.getLanguage(); + String country = locale.getCountry(); + String variant = locale.getVariant(); + StringBuffer temp = new StringBuffer(baseName); + + if (language.length() > 0) { + temp.append('_').append(language); + result.add(0, temp.toString()); + } + + if (country.length() > 0) { + temp.append('_').append(country); + result.add(0, temp.toString()); + } + + if (variant.length() > 0) { + temp.append('_').append(variant); + result.add(0, temp.toString()); + } + + return result; + } + + public static boolean isThreadingEnabled() { + try { + MBeanServer mBeanServer = new Registry().getMBeanServer(); + ObjectName threadingOName = new ObjectName("java.lang:type=Threading"); + Set s = mBeanServer.queryMBeans(threadingOName, null); + return s != null && s.size() > 0; + } catch (MalformedObjectNameException e) { + return false; + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/BoneCPDatasourceAccessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/BoneCPDatasourceAccessor.java index 52716a8725..0f4a994ee7 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/BoneCPDatasourceAccessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/BoneCPDatasourceAccessor.java @@ -1,63 +1,63 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.DataSourceInfo; - -import com.jolbox.bonecp.BoneCP; -import com.jolbox.bonecp.BoneCPDataSource; - -import java.lang.reflect.Field; - -/** - * - * @author akhawatrah - * @author Mark Lewis - */ -public class BoneCPDatasourceAccessor implements DatasourceAccessor { - - public DataSourceInfo getInfo(final Object resource) throws Exception { - DataSourceInfo dataSourceInfo = null; - if (canMap(resource)) { - final BoneCPDataSource source = (BoneCPDataSource) resource; - BoneCP pool; - try { - pool = source.getPool(); - } catch (NoSuchMethodError ex) { - // This is an older version of BoneCP (pre-0.8.0) - final Field poolField = BoneCPDataSource.class.getDeclaredField("pool"); - poolField.setAccessible(true); - pool = (BoneCP) poolField.get(source); - } - - dataSourceInfo = new DataSourceInfo(); - dataSourceInfo.setBusyConnections(source.getTotalLeased()); - dataSourceInfo.setEstablishedConnections(pool.getTotalCreatedConnections()); - dataSourceInfo.setMaxConnections(source.getPartitionCount() - * source.getMaxConnectionsPerPartition()); - dataSourceInfo.setJdbcURL(source.getJdbcUrl()); - dataSourceInfo.setUsername(source.getUsername()); - dataSourceInfo.setResettable(false); - dataSourceInfo.setType("bonecp"); - } - return dataSourceInfo; - } - - public boolean reset(final Object resource) throws Exception { - return false; - } - - public boolean canMap(final Object resource) { - return "com.jolbox.bonecp.BoneCPDataSource".equals(resource.getClass().getName()) - && resource instanceof BoneCPDataSource; - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.DataSourceInfo; + +import com.jolbox.bonecp.BoneCP; +import com.jolbox.bonecp.BoneCPDataSource; + +import java.lang.reflect.Field; + +/** + * + * @author akhawatrah + * @author Mark Lewis + */ +public class BoneCPDatasourceAccessor implements DatasourceAccessor { + + public DataSourceInfo getInfo(final Object resource) throws Exception { + DataSourceInfo dataSourceInfo = null; + if (canMap(resource)) { + final BoneCPDataSource source = (BoneCPDataSource) resource; + BoneCP pool; + try { + pool = source.getPool(); + } catch (NoSuchMethodError ex) { + // This is an older version of BoneCP (pre-0.8.0) + final Field poolField = BoneCPDataSource.class.getDeclaredField("pool"); + poolField.setAccessible(true); + pool = (BoneCP) poolField.get(source); + } + + dataSourceInfo = new DataSourceInfo(); + dataSourceInfo.setBusyConnections(source.getTotalLeased()); + dataSourceInfo.setEstablishedConnections(pool.getTotalCreatedConnections()); + dataSourceInfo.setMaxConnections(source.getPartitionCount() + * source.getMaxConnectionsPerPartition()); + dataSourceInfo.setJdbcURL(source.getJdbcUrl()); + dataSourceInfo.setUsername(source.getUsername()); + dataSourceInfo.setResettable(false); + dataSourceInfo.setType("bonecp"); + } + return dataSourceInfo; + } + + public boolean reset(final Object resource) throws Exception { + return false; + } + + public boolean canMap(final Object resource) { + return "com.jolbox.bonecp.BoneCPDataSource".equals(resource.getClass().getName()) + && resource instanceof BoneCPDataSource; + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/C3P0DatasourceAccessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/C3P0DatasourceAccessor.java index 349d137491..3d416a8d9b 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/C3P0DatasourceAccessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/C3P0DatasourceAccessor.java @@ -1,54 +1,54 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.DataSourceInfo; - -import com.mchange.v2.c3p0.ComboPooledDataSource; - -/** - * Abstraction layer for c3p0. Maps c3p0 datasource properties on our generic DataSourceInfo bean. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class C3P0DatasourceAccessor implements DatasourceAccessor { - - public DataSourceInfo getInfo(Object resource) throws Exception { - DataSourceInfo dataSourceInfo = null; - if (canMap(resource)) { - ComboPooledDataSource source = (ComboPooledDataSource) resource; - - dataSourceInfo = new DataSourceInfo(); - dataSourceInfo.setBusyConnections(source.getNumBusyConnections()); - dataSourceInfo.setEstablishedConnections(source.getNumConnections()); - dataSourceInfo.setMaxConnections(source.getMaxPoolSize()); - dataSourceInfo.setJdbcURL(source.getJdbcUrl()); - dataSourceInfo.setUsername(source.getUser()); - dataSourceInfo.setResettable(true); - dataSourceInfo.setType("c3p0"); - } - return dataSourceInfo; - } - - public boolean reset(Object resource) throws Exception { - if (canMap(resource)) { - ((ComboPooledDataSource) resource).hardReset(); - return true; - } - return false; - } - - public boolean canMap(Object resource) { - return "com.mchange.v2.c3p0.ComboPooledDataSource".equals(resource.getClass().getName()) - && resource instanceof ComboPooledDataSource; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.DataSourceInfo; + +import com.mchange.v2.c3p0.ComboPooledDataSource; + +/** + * Abstraction layer for c3p0. Maps c3p0 datasource properties on our generic DataSourceInfo bean. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class C3P0DatasourceAccessor implements DatasourceAccessor { + + public DataSourceInfo getInfo(Object resource) throws Exception { + DataSourceInfo dataSourceInfo = null; + if (canMap(resource)) { + ComboPooledDataSource source = (ComboPooledDataSource) resource; + + dataSourceInfo = new DataSourceInfo(); + dataSourceInfo.setBusyConnections(source.getNumBusyConnections()); + dataSourceInfo.setEstablishedConnections(source.getNumConnections()); + dataSourceInfo.setMaxConnections(source.getMaxPoolSize()); + dataSourceInfo.setJdbcURL(source.getJdbcUrl()); + dataSourceInfo.setUsername(source.getUser()); + dataSourceInfo.setResettable(true); + dataSourceInfo.setType("c3p0"); + } + return dataSourceInfo; + } + + public boolean reset(Object resource) throws Exception { + if (canMap(resource)) { + ((ComboPooledDataSource) resource).hardReset(); + return true; + } + return false; + } + + public boolean canMap(Object resource) { + return "com.mchange.v2.c3p0.ComboPooledDataSource".equals(resource.getClass().getName()) + && resource instanceof ComboPooledDataSource; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/ClusterWrapperBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/ClusterWrapperBean.java index 82e89b9fd1..2844270722 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/ClusterWrapperBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/ClusterWrapperBean.java @@ -1,176 +1,176 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.jmx.AsyncClusterSender; -import com.googlecode.psiprobe.model.jmx.Cluster; -import com.googlecode.psiprobe.model.jmx.ClusterSender; -import com.googlecode.psiprobe.model.jmx.PooledClusterSender; -import com.googlecode.psiprobe.model.jmx.SyncClusterSender; -import com.googlecode.psiprobe.tools.JmxTools; - -import org.apache.commons.modeler.Registry; - -import java.util.Set; - -import javax.management.MBeanServer; -import javax.management.ObjectInstance; -import javax.management.ObjectName; - -/** - * - * @author Vlad Ilyushchenko - */ -public class ClusterWrapperBean { - - public Cluster getCluster(String serverName, String hostName, boolean loadMembers) - throws Exception { - - Cluster cluster = null; - - MBeanServer mBeanServer = new Registry().getMBeanServer(); - ObjectName membershipOName = - new ObjectName(serverName + ":type=ClusterMembership,host=" + hostName); - ObjectName receiverOName = - new ObjectName(serverName + ":type=ClusterReceiver,host=" + hostName); - ObjectName senderOName = new ObjectName(serverName + ":type=ClusterSender,host=" + hostName); - - /* - * should be just one set, this is just to find out if this instance is cluster-enabled and the - * cluster supports JMX - */ - Set clusters = mBeanServer.queryMBeans(new ObjectName("*:type=Cluster,host=" + hostName), null); - Set membership = mBeanServer.queryMBeans(membershipOName, null); - if (clusters != null && clusters.size() > 0 && membership != null && membership.size() > 0) { - ObjectName clusterOName = ((ObjectInstance) clusters.iterator().next()).getObjectName(); - cluster = new Cluster(); - - cluster.setName(JmxTools.getStringAttr(mBeanServer, clusterOName, "clusterName")); - cluster.setInfo(JmxTools.getStringAttr(mBeanServer, clusterOName, "info")); - cluster.setManagerClassName(JmxTools.getStringAttr(mBeanServer, clusterOName, - "managerClassName")); - - cluster.setMcastAddress(JmxTools.getStringAttr(mBeanServer, membershipOName, "mcastAddr")); - cluster.setMcastBindAddress(JmxTools.getStringAttr(mBeanServer, membershipOName, - "mcastBindAddress")); - cluster.setMcastClusterDomain(JmxTools.getStringAttr(mBeanServer, membershipOName, - "mcastClusterDomain")); - cluster.setMcastDropTime(JmxTools.getLongAttr(mBeanServer, membershipOName, "mcastDropTime")); - cluster.setMcastFrequency(JmxTools - .getLongAttr(mBeanServer, membershipOName, "mcastFrequency")); - cluster.setMcastPort(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastPort")); - cluster - .setMcastSoTimeout(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastSoTimeout")); - cluster.setMcastTTL(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastTTL")); - - cluster.setTcpListenAddress(JmxTools.getStringAttr(mBeanServer, receiverOName, - "tcpListenAddress")); - cluster.setTcpListenPort(JmxTools.getIntAttr(mBeanServer, receiverOName, "tcpListenPort")); - cluster.setNrOfMsgsReceived(JmxTools.getLongAttr(mBeanServer, receiverOName, - "nrOfMsgsReceived")); - cluster.setTotalReceivedBytes(JmxTools.getLongAttr(mBeanServer, receiverOName, - "totalReceivedBytes")); - // cluster.setTcpSelectorTimeout( - // JmxTools.getLongAttr(mBeanServer, receiverOName, "tcpSelectorTimeout")); - // cluster.setTcpThreadCount( - // JmxTools.getIntAttr(mBeanServer, receiverOName, "tcpThreadCount")); - - cluster.setSenderAckTimeout(JmxTools.getLongAttr(mBeanServer, senderOName, "ackTimeout")); - cluster.setSenderAutoConnect(((Boolean) mBeanServer.getAttribute(senderOName, "autoConnect")) - .booleanValue()); - cluster.setSenderFailureCounter(JmxTools.getLongAttr(mBeanServer, senderOName, - "failureCounter")); - cluster.setSenderNrOfRequests(JmxTools.getLongAttr(mBeanServer, senderOName, "nrOfRequests")); - cluster.setSenderReplicationMode(JmxTools.getStringAttr(mBeanServer, senderOName, - "replicationMode")); - cluster.setSenderTotalBytes(JmxTools.getLongAttr(mBeanServer, senderOName, "totalBytes")); - - if (loadMembers) { - ObjectName senders[] = - (ObjectName[]) mBeanServer.getAttribute(senderOName, "senderObjectNames"); - for (int i = 0; i < senders.length; i++) { - - ClusterSender sender; - - if ("pooled".equals(cluster.getSenderReplicationMode())) { - sender = new PooledClusterSender(); - } else if ("synchronous".equals(cluster.getSenderReplicationMode())) { - sender = new SyncClusterSender(); - } else if ("asynchronous".equals(cluster.getSenderReplicationMode()) - || "fastasyncqueue".equals(cluster.getSenderReplicationMode())) { - sender = new AsyncClusterSender(); - } else { - sender = new ClusterSender(); - } - ObjectName localSenderOName = senders[i]; - - sender.setAddress(JmxTools.getStringAttr(mBeanServer, localSenderOName, "address")); - sender.setPort(JmxTools.getIntAttr(mBeanServer, localSenderOName, "port")); - - sender.setAvgMessageSize(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "avgMessageSize", -1)); - sender.setAvgProcessingTime(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "avgProcessingTime", -1)); - - sender.setConnectCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "connectCounter")); - sender.setDisconnectCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "disconnectCounter")); - sender.setConnected(((Boolean) mBeanServer.getAttribute(localSenderOName, "connected")) - .booleanValue()); - sender.setKeepAliveTimeout(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "keepAliveTimeout")); - sender.setNrOfRequests(JmxTools - .getLongAttr(mBeanServer, localSenderOName, "nrOfRequests")); - sender.setTotalBytes(JmxTools.getLongAttr(mBeanServer, localSenderOName, "totalBytes")); - sender.setResend(((Boolean) mBeanServer.getAttribute(localSenderOName, "resend")) - .booleanValue()); - sender.setSuspect(((Boolean) mBeanServer.getAttribute(localSenderOName, "suspect")) - .booleanValue()); - - if (sender instanceof PooledClusterSender) { - ((PooledClusterSender) sender).setMaxPoolSocketLimit(JmxTools.getIntAttr(mBeanServer, - localSenderOName, "maxPoolSocketLimit")); - } - - if (sender instanceof SyncClusterSender) { - SyncClusterSender syncSender = (SyncClusterSender) sender; - syncSender.setDataFailureCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "dataFailureCounter")); - syncSender.setDataResendCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "dataResendCounter")); - syncSender.setSocketOpenCounter(JmxTools.getIntAttr(mBeanServer, localSenderOName, - "socketOpenCounter")); - syncSender.setSocketCloseCounter(JmxTools.getIntAttr(mBeanServer, localSenderOName, - "socketCloseCounter")); - syncSender.setSocketOpenFailureCounter(JmxTools.getIntAttr(mBeanServer, - localSenderOName, "socketOpenFailureCounter")); - } - - if (sender instanceof AsyncClusterSender) { - AsyncClusterSender asyncSender = (AsyncClusterSender) sender; - asyncSender.setInQueueCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "inQueueCounter")); - asyncSender.setOutQueueCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "outQueueCounter")); - asyncSender.setQueueSize(JmxTools - .getIntAttr(mBeanServer, localSenderOName, "queueSize")); - asyncSender.setQueuedNrOfBytes(JmxTools.getLongAttr(mBeanServer, localSenderOName, - "queuedNrOfBytes")); - } - cluster.getMembers().add(sender); - } - } - } - return cluster; - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.jmx.AsyncClusterSender; +import com.googlecode.psiprobe.model.jmx.Cluster; +import com.googlecode.psiprobe.model.jmx.ClusterSender; +import com.googlecode.psiprobe.model.jmx.PooledClusterSender; +import com.googlecode.psiprobe.model.jmx.SyncClusterSender; +import com.googlecode.psiprobe.tools.JmxTools; + +import org.apache.commons.modeler.Registry; + +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +/** + * + * @author Vlad Ilyushchenko + */ +public class ClusterWrapperBean { + + public Cluster getCluster(String serverName, String hostName, boolean loadMembers) + throws Exception { + + Cluster cluster = null; + + MBeanServer mBeanServer = new Registry().getMBeanServer(); + ObjectName membershipOName = + new ObjectName(serverName + ":type=ClusterMembership,host=" + hostName); + ObjectName receiverOName = + new ObjectName(serverName + ":type=ClusterReceiver,host=" + hostName); + ObjectName senderOName = new ObjectName(serverName + ":type=ClusterSender,host=" + hostName); + + /* + * should be just one set, this is just to find out if this instance is cluster-enabled and the + * cluster supports JMX + */ + Set clusters = mBeanServer.queryMBeans(new ObjectName("*:type=Cluster,host=" + hostName), null); + Set membership = mBeanServer.queryMBeans(membershipOName, null); + if (clusters != null && clusters.size() > 0 && membership != null && membership.size() > 0) { + ObjectName clusterOName = ((ObjectInstance) clusters.iterator().next()).getObjectName(); + cluster = new Cluster(); + + cluster.setName(JmxTools.getStringAttr(mBeanServer, clusterOName, "clusterName")); + cluster.setInfo(JmxTools.getStringAttr(mBeanServer, clusterOName, "info")); + cluster.setManagerClassName(JmxTools.getStringAttr(mBeanServer, clusterOName, + "managerClassName")); + + cluster.setMcastAddress(JmxTools.getStringAttr(mBeanServer, membershipOName, "mcastAddr")); + cluster.setMcastBindAddress(JmxTools.getStringAttr(mBeanServer, membershipOName, + "mcastBindAddress")); + cluster.setMcastClusterDomain(JmxTools.getStringAttr(mBeanServer, membershipOName, + "mcastClusterDomain")); + cluster.setMcastDropTime(JmxTools.getLongAttr(mBeanServer, membershipOName, "mcastDropTime")); + cluster.setMcastFrequency(JmxTools + .getLongAttr(mBeanServer, membershipOName, "mcastFrequency")); + cluster.setMcastPort(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastPort")); + cluster + .setMcastSoTimeout(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastSoTimeout")); + cluster.setMcastTTL(JmxTools.getIntAttr(mBeanServer, membershipOName, "mcastTTL")); + + cluster.setTcpListenAddress(JmxTools.getStringAttr(mBeanServer, receiverOName, + "tcpListenAddress")); + cluster.setTcpListenPort(JmxTools.getIntAttr(mBeanServer, receiverOName, "tcpListenPort")); + cluster.setNrOfMsgsReceived(JmxTools.getLongAttr(mBeanServer, receiverOName, + "nrOfMsgsReceived")); + cluster.setTotalReceivedBytes(JmxTools.getLongAttr(mBeanServer, receiverOName, + "totalReceivedBytes")); + // cluster.setTcpSelectorTimeout( + // JmxTools.getLongAttr(mBeanServer, receiverOName, "tcpSelectorTimeout")); + // cluster.setTcpThreadCount( + // JmxTools.getIntAttr(mBeanServer, receiverOName, "tcpThreadCount")); + + cluster.setSenderAckTimeout(JmxTools.getLongAttr(mBeanServer, senderOName, "ackTimeout")); + cluster.setSenderAutoConnect(((Boolean) mBeanServer.getAttribute(senderOName, "autoConnect")) + .booleanValue()); + cluster.setSenderFailureCounter(JmxTools.getLongAttr(mBeanServer, senderOName, + "failureCounter")); + cluster.setSenderNrOfRequests(JmxTools.getLongAttr(mBeanServer, senderOName, "nrOfRequests")); + cluster.setSenderReplicationMode(JmxTools.getStringAttr(mBeanServer, senderOName, + "replicationMode")); + cluster.setSenderTotalBytes(JmxTools.getLongAttr(mBeanServer, senderOName, "totalBytes")); + + if (loadMembers) { + ObjectName senders[] = + (ObjectName[]) mBeanServer.getAttribute(senderOName, "senderObjectNames"); + for (int i = 0; i < senders.length; i++) { + + ClusterSender sender; + + if ("pooled".equals(cluster.getSenderReplicationMode())) { + sender = new PooledClusterSender(); + } else if ("synchronous".equals(cluster.getSenderReplicationMode())) { + sender = new SyncClusterSender(); + } else if ("asynchronous".equals(cluster.getSenderReplicationMode()) + || "fastasyncqueue".equals(cluster.getSenderReplicationMode())) { + sender = new AsyncClusterSender(); + } else { + sender = new ClusterSender(); + } + ObjectName localSenderOName = senders[i]; + + sender.setAddress(JmxTools.getStringAttr(mBeanServer, localSenderOName, "address")); + sender.setPort(JmxTools.getIntAttr(mBeanServer, localSenderOName, "port")); + + sender.setAvgMessageSize(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "avgMessageSize", -1)); + sender.setAvgProcessingTime(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "avgProcessingTime", -1)); + + sender.setConnectCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "connectCounter")); + sender.setDisconnectCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "disconnectCounter")); + sender.setConnected(((Boolean) mBeanServer.getAttribute(localSenderOName, "connected")) + .booleanValue()); + sender.setKeepAliveTimeout(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "keepAliveTimeout")); + sender.setNrOfRequests(JmxTools + .getLongAttr(mBeanServer, localSenderOName, "nrOfRequests")); + sender.setTotalBytes(JmxTools.getLongAttr(mBeanServer, localSenderOName, "totalBytes")); + sender.setResend(((Boolean) mBeanServer.getAttribute(localSenderOName, "resend")) + .booleanValue()); + sender.setSuspect(((Boolean) mBeanServer.getAttribute(localSenderOName, "suspect")) + .booleanValue()); + + if (sender instanceof PooledClusterSender) { + ((PooledClusterSender) sender).setMaxPoolSocketLimit(JmxTools.getIntAttr(mBeanServer, + localSenderOName, "maxPoolSocketLimit")); + } + + if (sender instanceof SyncClusterSender) { + SyncClusterSender syncSender = (SyncClusterSender) sender; + syncSender.setDataFailureCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "dataFailureCounter")); + syncSender.setDataResendCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "dataResendCounter")); + syncSender.setSocketOpenCounter(JmxTools.getIntAttr(mBeanServer, localSenderOName, + "socketOpenCounter")); + syncSender.setSocketCloseCounter(JmxTools.getIntAttr(mBeanServer, localSenderOName, + "socketCloseCounter")); + syncSender.setSocketOpenFailureCounter(JmxTools.getIntAttr(mBeanServer, + localSenderOName, "socketOpenFailureCounter")); + } + + if (sender instanceof AsyncClusterSender) { + AsyncClusterSender asyncSender = (AsyncClusterSender) sender; + asyncSender.setInQueueCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "inQueueCounter")); + asyncSender.setOutQueueCounter(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "outQueueCounter")); + asyncSender.setQueueSize(JmxTools + .getIntAttr(mBeanServer, localSenderOName, "queueSize")); + asyncSender.setQueuedNrOfBytes(JmxTools.getLongAttr(mBeanServer, localSenderOName, + "queuedNrOfBytes")); + } + cluster.getMembers().add(sender); + } + } + } + return cluster; + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/ContainerListenerBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/ContainerListenerBean.java index 3531993452..11a02c62ef 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/ContainerListenerBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/ContainerListenerBean.java @@ -1,325 +1,325 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.Connector; -import com.googlecode.psiprobe.model.RequestProcessor; -import com.googlecode.psiprobe.model.ThreadPool; -import com.googlecode.psiprobe.model.jmx.ThreadPoolObjectName; -import com.googlecode.psiprobe.tools.JmxTools; - -import net.sf.javainetlocator.InetAddressLocator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.management.InstanceNotFoundException; -import javax.management.MBeanServer; -import javax.management.MBeanServerNotification; -import javax.management.Notification; -import javax.management.NotificationListener; -import javax.management.ObjectInstance; -import javax.management.ObjectName; -import javax.management.RuntimeOperationsException; - -/** - * This class interfaces Tomcat JMX functionality to read connection status. The class essentially - * provides and maintains the list of connection ThreadPools. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class ContainerListenerBean implements NotificationListener { - - private Log logger = LogFactory.getLog(getClass()); - private List poolNames = null; - private List executorNames = null; - - /** - * Used to obtain required {@link MBeanServer} instance. - */ - private ContainerWrapperBean containerWrapper; - - public ContainerWrapperBean getContainerWrapper() { - return containerWrapper; - } - - public void setContainerWrapper(ContainerWrapperBean containerWrapper) { - this.containerWrapper = containerWrapper; - } - - private boolean isInitialized() { - return poolNames != null && poolNames.size() > 0; - } - - /** - * Finds ThreadPoolObjectName by its string name. - * - * @param name - pool name - * - * @return null if the input name is null or ThreadPoolObjectName is not found - */ - private ThreadPoolObjectName findPool(String name) { - if (name != null && isInitialized()) { - for (Iterator it = poolNames.iterator(); it.hasNext();) { - ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); - if (name.equals(threadPoolObjectName.getThreadPoolName().getKeyProperty("name"))) { - return threadPoolObjectName; - } - } - } - return null; - } - - /** - * Handles creation and deletion of new "worker" threads. - */ - public synchronized void handleNotification(Notification notification, Object object) { - if (notification instanceof MBeanServerNotification) { - ObjectName objectName = ((MBeanServerNotification) notification).getMBeanName(); - - if (notification.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) { - - if ("RequestProcessor".equals(objectName.getKeyProperty("type"))) { - ThreadPoolObjectName threadPoolObjectName = findPool(objectName.getKeyProperty("worker")); - if (threadPoolObjectName != null) { - threadPoolObjectName.getRequestProcessorNames().add(objectName); - } - } - - } else if (notification.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { - - if ("RequestProcessor".equals(objectName.getKeyProperty("type"))) { - ThreadPoolObjectName threadPoolObjectName = findPool(objectName.getKeyProperty("worker")); - if (threadPoolObjectName != null) { - threadPoolObjectName.getRequestProcessorNames().remove(objectName); - } - } - } - } - } - - /** - * Load ObjectNames for the relevant MBeans so they can be queried at a later stage without - * searching MBean server over and over again. - * - * @throws Exception - this method does not handle any of the exceptions that may be thrown when - * querying MBean server. - */ - private synchronized void initialize() throws Exception { - - MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); - String serverName = getContainerWrapper().getTomcatContainer().getName(); - Set threadPools = server.queryMBeans(new ObjectName(serverName + ":type=ThreadPool,*"), null); - poolNames = new ArrayList(threadPools.size()); - for (Iterator it = threadPools.iterator(); it.hasNext();) { - - ThreadPoolObjectName threadPoolObjectName = new ThreadPoolObjectName(); - ObjectName threadPoolName = ((ObjectInstance) it.next()).getObjectName(); - - String name = threadPoolName.getKeyProperty("name"); - - threadPoolObjectName.setThreadPoolName(threadPoolName); - ObjectName grpName = - server.getObjectInstance( - new ObjectName(threadPoolName.getDomain() + ":type=GlobalRequestProcessor,name=" - + name)).getObjectName(); - threadPoolObjectName.setGlobalRequestProcessorName(grpName); - - /* - * unfortunately exact workers could not be found at the time of testing so we filter out the - * relevant workers within the loop - */ - Set workers = - server.queryMBeans( - new ObjectName(threadPoolName.getDomain() + ":type=RequestProcessor,*"), null); - - for (Iterator wrkIt = workers.iterator(); wrkIt.hasNext();) { - ObjectName wrkName = ((ObjectInstance) wrkIt.next()).getObjectName(); - if (name.equals(wrkName.getKeyProperty("worker"))) { - threadPoolObjectName.getRequestProcessorNames().add(wrkName); - } - } - - poolNames.add(threadPoolObjectName); - } - - Set executors = server.queryMBeans(new ObjectName(serverName + ":type=Executor,*"), null); - executorNames = new ArrayList(executors.size()); - for (Iterator it = executors.iterator(); it.hasNext();) { - ObjectName executorName = ((ObjectInstance) it.next()).getObjectName(); - executorNames.add(executorName); - } - - // Register with MBean server - server.addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"), - this, null, null); - - } - - public synchronized List getThreadPools() throws Exception { - - if (!isInitialized()) { - initialize(); - } - - List threadPools = new ArrayList(poolNames.size()); - - MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); - - for (Iterator it = executorNames.iterator(); it.hasNext();) { - ObjectName executorName = (ObjectName) it.next(); - - ThreadPool threadPool = new ThreadPool(); - threadPool.setName(executorName.getKeyProperty("name")); - threadPool.setMaxThreads(JmxTools.getIntAttr(server, executorName, "maxThreads")); - threadPool.setMaxSpareThreads(JmxTools.getIntAttr(server, executorName, "largestPoolSize")); - threadPool.setMinSpareThreads(JmxTools.getIntAttr(server, executorName, "minSpareThreads")); - threadPool.setCurrentThreadsBusy(JmxTools.getIntAttr(server, executorName, "activeCount")); - threadPool.setCurrentThreadCount(JmxTools.getIntAttr(server, executorName, "poolSize")); - - threadPools.add(threadPool); - } - - for (Iterator it = poolNames.iterator(); it.hasNext();) { - - ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); - try { - ObjectName poolName = threadPoolObjectName.getThreadPoolName(); - - ThreadPool threadPool = new ThreadPool(); - threadPool.setName(poolName.getKeyProperty("name")); - threadPool.setMaxThreads(JmxTools.getIntAttr(server, poolName, "maxThreads")); - - if (JmxTools.hasAttribute(server, poolName, "maxSpareThreads")) { - threadPool.setMaxSpareThreads(JmxTools.getIntAttr(server, poolName, "maxSpareThreads")); - threadPool.setMinSpareThreads(JmxTools.getIntAttr(server, poolName, "minSpareThreads")); - } - - threadPool.setCurrentThreadsBusy(JmxTools - .getIntAttr(server, poolName, "currentThreadsBusy")); - threadPool.setCurrentThreadCount(JmxTools - .getIntAttr(server, poolName, "currentThreadCount")); - - /* - * Tomcat 6.0.21+ will return -1 for maxThreads if the connector uses an executor for its - * threads. In this case, don't add its ThreadPool to the results. - */ - if (threadPool.getMaxThreads() > -1) { - threadPools.add(threadPool); - } - } catch (InstanceNotFoundException e) { - logger.error("Failed to query entire thread pool " + threadPoolObjectName); - logger.debug(" Stack trace:", e); - } - } - return threadPools; - } - - public synchronized List getConnectors(boolean includeRequestProcessors) throws Exception { - boolean workerThreadNameSupported = true; - - if (!isInitialized()) { - initialize(); - } - - List connectors = new ArrayList(poolNames.size()); - - MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); - - for (Iterator it = poolNames.iterator(); it.hasNext();) { - - ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); - boolean remoteAddrAvailable = true; - try { - ObjectName poolName = threadPoolObjectName.getThreadPoolName(); - - Connector connector = new Connector(); - connector.setName(poolName.getKeyProperty("name")); - - ObjectName grpName = threadPoolObjectName.getGlobalRequestProcessorName(); - - connector.setMaxTime(JmxTools.getLongAttr(server, grpName, "maxTime")); - connector.setProcessingTime(JmxTools.getLongAttr(server, grpName, "processingTime")); - connector.setBytesReceived(JmxTools.getLongAttr(server, grpName, "bytesReceived")); - connector.setBytesSent(JmxTools.getLongAttr(server, grpName, "bytesSent")); - connector.setRequestCount(JmxTools.getIntAttr(server, grpName, "requestCount")); - connector.setErrorCount(JmxTools.getIntAttr(server, grpName, "errorCount")); - - if (includeRequestProcessors) { - for (Iterator wrkIt = threadPoolObjectName.getRequestProcessorNames().iterator(); wrkIt - .hasNext();) { - ObjectName wrkName = (ObjectName) wrkIt.next(); - - try { - RequestProcessor rp = new RequestProcessor(); - rp.setName(wrkName.getKeyProperty("name")); - rp.setStage(JmxTools.getIntAttr(server, wrkName, "stage")); - rp.setProcessingTime(JmxTools.getLongAttr(server, wrkName, "requestProcessingTime")); - rp.setBytesSent(JmxTools.getLongAttr(server, wrkName, "requestBytesSent")); - rp.setBytesReceived(JmxTools.getLongAttr(server, wrkName, "requestBytesReceived")); - try { - String remoteAddr = JmxTools.getStringAttr(server, wrkName, "remoteAddr"); - rp.setRemoteAddr(remoteAddr); - rp.setRemoteAddrLocale(InetAddressLocator.getLocale(InetAddress.getByName( - remoteAddr).getAddress())); - } catch (RuntimeOperationsException ex) { - /* - * if it's not available for this request processor, then it's not available for any - * request processor in this thread pool - */ - remoteAddrAvailable = false; - } - rp.setVirtualHost(JmxTools.getStringAttr(server, wrkName, "virtualHost")); - rp.setMethod(JmxTools.getStringAttr(server, wrkName, "method")); - rp.setCurrentUri(JmxTools.getStringAttr(server, wrkName, "currentUri")); - rp.setCurrentQueryString(JmxTools - .getStringAttr(server, wrkName, "currentQueryString")); - rp.setProtocol(JmxTools.getStringAttr(server, wrkName, "protocol")); - - // Relies on https://issues.apache.org/bugzilla/show_bug.cgi?id=41128 - if (workerThreadNameSupported - && JmxTools.hasAttribute(server, wrkName, "workerThreadName")) { - - rp.setWorkerThreadName(JmxTools.getStringAttr(server, wrkName, "workerThreadName")); - rp.setWorkerThreadNameSupported(true); - } else { - /* - * attribute should consistently either exist or be missing across all the workers - * so it does not make sense to check attribute existence if we have found once that - * it is not supported - */ - rp.setWorkerThreadNameSupported(false); - workerThreadNameSupported = false; - } - connector.addRequestProcessor(rp); - } catch (InstanceNotFoundException e) { - logger.info("Failed to query RequestProcessor " + wrkName); - logger.debug(" Stack trace:", e); - } - } - } - - connectors.add(connector); - } catch (InstanceNotFoundException e) { - logger.error("Failed to query entire thread pool " + threadPoolObjectName); - logger.debug(" Stack trace:", e); - } - } - return connectors; - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.Connector; +import com.googlecode.psiprobe.model.RequestProcessor; +import com.googlecode.psiprobe.model.ThreadPool; +import com.googlecode.psiprobe.model.jmx.ThreadPoolObjectName; +import com.googlecode.psiprobe.tools.JmxTools; + +import net.sf.javainetlocator.InetAddressLocator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanServer; +import javax.management.MBeanServerNotification; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.RuntimeOperationsException; + +/** + * This class interfaces Tomcat JMX functionality to read connection status. The class essentially + * provides and maintains the list of connection ThreadPools. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class ContainerListenerBean implements NotificationListener { + + private Log logger = LogFactory.getLog(getClass()); + private List poolNames = null; + private List executorNames = null; + + /** + * Used to obtain required {@link MBeanServer} instance. + */ + private ContainerWrapperBean containerWrapper; + + public ContainerWrapperBean getContainerWrapper() { + return containerWrapper; + } + + public void setContainerWrapper(ContainerWrapperBean containerWrapper) { + this.containerWrapper = containerWrapper; + } + + private boolean isInitialized() { + return poolNames != null && poolNames.size() > 0; + } + + /** + * Finds ThreadPoolObjectName by its string name. + * + * @param name - pool name + * + * @return null if the input name is null or ThreadPoolObjectName is not found + */ + private ThreadPoolObjectName findPool(String name) { + if (name != null && isInitialized()) { + for (Iterator it = poolNames.iterator(); it.hasNext();) { + ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); + if (name.equals(threadPoolObjectName.getThreadPoolName().getKeyProperty("name"))) { + return threadPoolObjectName; + } + } + } + return null; + } + + /** + * Handles creation and deletion of new "worker" threads. + */ + public synchronized void handleNotification(Notification notification, Object object) { + if (notification instanceof MBeanServerNotification) { + ObjectName objectName = ((MBeanServerNotification) notification).getMBeanName(); + + if (notification.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) { + + if ("RequestProcessor".equals(objectName.getKeyProperty("type"))) { + ThreadPoolObjectName threadPoolObjectName = findPool(objectName.getKeyProperty("worker")); + if (threadPoolObjectName != null) { + threadPoolObjectName.getRequestProcessorNames().add(objectName); + } + } + + } else if (notification.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { + + if ("RequestProcessor".equals(objectName.getKeyProperty("type"))) { + ThreadPoolObjectName threadPoolObjectName = findPool(objectName.getKeyProperty("worker")); + if (threadPoolObjectName != null) { + threadPoolObjectName.getRequestProcessorNames().remove(objectName); + } + } + } + } + } + + /** + * Load ObjectNames for the relevant MBeans so they can be queried at a later stage without + * searching MBean server over and over again. + * + * @throws Exception - this method does not handle any of the exceptions that may be thrown when + * querying MBean server. + */ + private synchronized void initialize() throws Exception { + + MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); + String serverName = getContainerWrapper().getTomcatContainer().getName(); + Set threadPools = server.queryMBeans(new ObjectName(serverName + ":type=ThreadPool,*"), null); + poolNames = new ArrayList(threadPools.size()); + for (Iterator it = threadPools.iterator(); it.hasNext();) { + + ThreadPoolObjectName threadPoolObjectName = new ThreadPoolObjectName(); + ObjectName threadPoolName = ((ObjectInstance) it.next()).getObjectName(); + + String name = threadPoolName.getKeyProperty("name"); + + threadPoolObjectName.setThreadPoolName(threadPoolName); + ObjectName grpName = + server.getObjectInstance( + new ObjectName(threadPoolName.getDomain() + ":type=GlobalRequestProcessor,name=" + + name)).getObjectName(); + threadPoolObjectName.setGlobalRequestProcessorName(grpName); + + /* + * unfortunately exact workers could not be found at the time of testing so we filter out the + * relevant workers within the loop + */ + Set workers = + server.queryMBeans( + new ObjectName(threadPoolName.getDomain() + ":type=RequestProcessor,*"), null); + + for (Iterator wrkIt = workers.iterator(); wrkIt.hasNext();) { + ObjectName wrkName = ((ObjectInstance) wrkIt.next()).getObjectName(); + if (name.equals(wrkName.getKeyProperty("worker"))) { + threadPoolObjectName.getRequestProcessorNames().add(wrkName); + } + } + + poolNames.add(threadPoolObjectName); + } + + Set executors = server.queryMBeans(new ObjectName(serverName + ":type=Executor,*"), null); + executorNames = new ArrayList(executors.size()); + for (Iterator it = executors.iterator(); it.hasNext();) { + ObjectName executorName = ((ObjectInstance) it.next()).getObjectName(); + executorNames.add(executorName); + } + + // Register with MBean server + server.addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"), + this, null, null); + + } + + public synchronized List getThreadPools() throws Exception { + + if (!isInitialized()) { + initialize(); + } + + List threadPools = new ArrayList(poolNames.size()); + + MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); + + for (Iterator it = executorNames.iterator(); it.hasNext();) { + ObjectName executorName = (ObjectName) it.next(); + + ThreadPool threadPool = new ThreadPool(); + threadPool.setName(executorName.getKeyProperty("name")); + threadPool.setMaxThreads(JmxTools.getIntAttr(server, executorName, "maxThreads")); + threadPool.setMaxSpareThreads(JmxTools.getIntAttr(server, executorName, "largestPoolSize")); + threadPool.setMinSpareThreads(JmxTools.getIntAttr(server, executorName, "minSpareThreads")); + threadPool.setCurrentThreadsBusy(JmxTools.getIntAttr(server, executorName, "activeCount")); + threadPool.setCurrentThreadCount(JmxTools.getIntAttr(server, executorName, "poolSize")); + + threadPools.add(threadPool); + } + + for (Iterator it = poolNames.iterator(); it.hasNext();) { + + ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); + try { + ObjectName poolName = threadPoolObjectName.getThreadPoolName(); + + ThreadPool threadPool = new ThreadPool(); + threadPool.setName(poolName.getKeyProperty("name")); + threadPool.setMaxThreads(JmxTools.getIntAttr(server, poolName, "maxThreads")); + + if (JmxTools.hasAttribute(server, poolName, "maxSpareThreads")) { + threadPool.setMaxSpareThreads(JmxTools.getIntAttr(server, poolName, "maxSpareThreads")); + threadPool.setMinSpareThreads(JmxTools.getIntAttr(server, poolName, "minSpareThreads")); + } + + threadPool.setCurrentThreadsBusy(JmxTools + .getIntAttr(server, poolName, "currentThreadsBusy")); + threadPool.setCurrentThreadCount(JmxTools + .getIntAttr(server, poolName, "currentThreadCount")); + + /* + * Tomcat 6.0.21+ will return -1 for maxThreads if the connector uses an executor for its + * threads. In this case, don't add its ThreadPool to the results. + */ + if (threadPool.getMaxThreads() > -1) { + threadPools.add(threadPool); + } + } catch (InstanceNotFoundException e) { + logger.error("Failed to query entire thread pool " + threadPoolObjectName); + logger.debug(" Stack trace:", e); + } + } + return threadPools; + } + + public synchronized List getConnectors(boolean includeRequestProcessors) throws Exception { + boolean workerThreadNameSupported = true; + + if (!isInitialized()) { + initialize(); + } + + List connectors = new ArrayList(poolNames.size()); + + MBeanServer server = getContainerWrapper().getResourceResolver().getMBeanServer(); + + for (Iterator it = poolNames.iterator(); it.hasNext();) { + + ThreadPoolObjectName threadPoolObjectName = (ThreadPoolObjectName) it.next(); + boolean remoteAddrAvailable = true; + try { + ObjectName poolName = threadPoolObjectName.getThreadPoolName(); + + Connector connector = new Connector(); + connector.setName(poolName.getKeyProperty("name")); + + ObjectName grpName = threadPoolObjectName.getGlobalRequestProcessorName(); + + connector.setMaxTime(JmxTools.getLongAttr(server, grpName, "maxTime")); + connector.setProcessingTime(JmxTools.getLongAttr(server, grpName, "processingTime")); + connector.setBytesReceived(JmxTools.getLongAttr(server, grpName, "bytesReceived")); + connector.setBytesSent(JmxTools.getLongAttr(server, grpName, "bytesSent")); + connector.setRequestCount(JmxTools.getIntAttr(server, grpName, "requestCount")); + connector.setErrorCount(JmxTools.getIntAttr(server, grpName, "errorCount")); + + if (includeRequestProcessors) { + for (Iterator wrkIt = threadPoolObjectName.getRequestProcessorNames().iterator(); wrkIt + .hasNext();) { + ObjectName wrkName = (ObjectName) wrkIt.next(); + + try { + RequestProcessor rp = new RequestProcessor(); + rp.setName(wrkName.getKeyProperty("name")); + rp.setStage(JmxTools.getIntAttr(server, wrkName, "stage")); + rp.setProcessingTime(JmxTools.getLongAttr(server, wrkName, "requestProcessingTime")); + rp.setBytesSent(JmxTools.getLongAttr(server, wrkName, "requestBytesSent")); + rp.setBytesReceived(JmxTools.getLongAttr(server, wrkName, "requestBytesReceived")); + try { + String remoteAddr = JmxTools.getStringAttr(server, wrkName, "remoteAddr"); + rp.setRemoteAddr(remoteAddr); + rp.setRemoteAddrLocale(InetAddressLocator.getLocale(InetAddress.getByName( + remoteAddr).getAddress())); + } catch (RuntimeOperationsException ex) { + /* + * if it's not available for this request processor, then it's not available for any + * request processor in this thread pool + */ + remoteAddrAvailable = false; + } + rp.setVirtualHost(JmxTools.getStringAttr(server, wrkName, "virtualHost")); + rp.setMethod(JmxTools.getStringAttr(server, wrkName, "method")); + rp.setCurrentUri(JmxTools.getStringAttr(server, wrkName, "currentUri")); + rp.setCurrentQueryString(JmxTools + .getStringAttr(server, wrkName, "currentQueryString")); + rp.setProtocol(JmxTools.getStringAttr(server, wrkName, "protocol")); + + // Relies on https://issues.apache.org/bugzilla/show_bug.cgi?id=41128 + if (workerThreadNameSupported + && JmxTools.hasAttribute(server, wrkName, "workerThreadName")) { + + rp.setWorkerThreadName(JmxTools.getStringAttr(server, wrkName, "workerThreadName")); + rp.setWorkerThreadNameSupported(true); + } else { + /* + * attribute should consistently either exist or be missing across all the workers + * so it does not make sense to check attribute existence if we have found once that + * it is not supported + */ + rp.setWorkerThreadNameSupported(false); + workerThreadNameSupported = false; + } + connector.addRequestProcessor(rp); + } catch (InstanceNotFoundException e) { + logger.info("Failed to query RequestProcessor " + wrkName); + logger.debug(" Stack trace:", e); + } + } + } + + connectors.add(connector); + } catch (InstanceNotFoundException e) { + logger.error("Failed to query entire thread pool " + threadPoolObjectName); + logger.debug(" Stack trace:", e); + } + } + return connectors; + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/ContainerWrapperBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/ContainerWrapperBean.java index 65913dc786..32093be02f 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/ContainerWrapperBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/ContainerWrapperBean.java @@ -1,201 +1,201 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.TomcatContainer; -import com.googlecode.psiprobe.model.ApplicationResource; - -import org.apache.catalina.Context; -import org.apache.catalina.Wrapper; -import org.apache.catalina.util.ServerInfo; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * This class wires support for Tomcat "privileged" context functionality into Spring. If - * application context is privileged Tomcat would always call servlet.setWrapper method on each - * request. ContainerWrapperBean wires the passed wrapper to the relevant Tomcat container adaptor - * class, which in turn helps the Probe to interpret the wrapper. Container adaptors are required - * because internal wrapper structure is quite different between Tomcat 5.5.x and Tomcat 5.0.x - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class ContainerWrapperBean { - - private Log logger = LogFactory.getLog(getClass()); - - private TomcatContainer tomcatContainer = null; - private final Object lock = new Object(); - - /** - * List of class names to adapt particular Tomcat implementation to TomcatContainer interface - */ - private List adaptorClasses; - - private ResourceResolver resourceResolver; - - private boolean forceFirstAdaptor = false; - - private Map resourceResolvers; - - public boolean isForceFirstAdaptor() { - return forceFirstAdaptor; - } - - public void setForceFirstAdaptor(boolean forceFirstAdaptor) { - this.forceFirstAdaptor = forceFirstAdaptor; - } - - public void setWrapper(Wrapper wrapper) { - if (tomcatContainer == null) { - - synchronized (lock) { - - if (tomcatContainer == null) { - - String serverInfo = ServerInfo.getServerInfo(); - logger.info("Server info: " + serverInfo); - for (int i = 0; i < adaptorClasses.size(); i++) { - String className = (String) adaptorClasses.get(i); - try { - Object o = Class.forName(className).newInstance(); - logger.debug("Testing container adaptor: " + className); - if (o instanceof TomcatContainer) { - if (forceFirstAdaptor || ((TomcatContainer) o).canBoundTo(serverInfo)) { - logger.info("Using " + className); - tomcatContainer = (TomcatContainer) o; - tomcatContainer.setWrapper(wrapper); - break; - } else { - logger.debug("Cannot bind " + className + " to " + serverInfo); - } - } else { - logger.error(className + " does not implement " + TomcatContainer.class.getName()); - } - } catch (Throwable e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed to load " + className, e); - } else { - logger.info("Failed to load " + className); - } - // - // make sure we always re-throw ThreadDeath - // - if (e instanceof ThreadDeath) { - throw (ThreadDeath) e; - } - } - } - - if (tomcatContainer == null) { - logger.fatal("No suitable container adaptor found!"); - } - } - } - } - - try { - if (tomcatContainer != null && wrapper == null) { - logger.info("Unregistering container adaptor"); - tomcatContainer.setWrapper(null); - } - } catch (Throwable e) { - logger.error("Could not unregister container adaptor", e); - // - // make sure we always re-throw ThreadDeath - // - if (e instanceof ThreadDeath) { - throw (ThreadDeath) e; - } - } - } - - public TomcatContainer getTomcatContainer() { - return tomcatContainer; - } - - public List getAdaptorClasses() { - return adaptorClasses; - } - - public void setAdaptorClasses(List adaptorClasses) { - this.adaptorClasses = adaptorClasses; - } - - public ResourceResolver getResourceResolver() { - if (resourceResolver == null) { - if (System.getProperty("jboss.server.name") != null) { - resourceResolver = (ResourceResolver) resourceResolvers.get("jboss"); - logger.info("Using JBOSS resource resolver"); - } else { - resourceResolver = (ResourceResolver) resourceResolvers.get("default"); - logger.info("Using DEFAULT resource resolver"); - } - } - return resourceResolver; - } - - public Map getResourceResolvers() { - return resourceResolvers; - } - - public void setResourceResolvers(Map resourceResolvers) { - this.resourceResolvers = resourceResolvers; - } - - public List getDataSources() throws Exception { - List resources = new ArrayList(); - resources.addAll(getPrivateDataSources()); - resources.addAll(getGlobalDataSources()); - return resources; - } - - public List getPrivateDataSources() throws Exception { - List resources = new ArrayList(); - if (tomcatContainer != null && getResourceResolver().supportsPrivateResources()) { - List apps = getTomcatContainer().findContexts(); - - for (int i = 0; i < apps.size(); i++) { - List appResources = - getResourceResolver().getApplicationResources((Context) apps.get(i), this); - // add only those resources that have data source info - filterDataSources(appResources, resources); - } - } - return resources; - } - - public List getGlobalDataSources() throws Exception { - List resources = new ArrayList(); - if (getResourceResolver().supportsGlobalResources()) { - List globalResources = getResourceResolver().getApplicationResources(); - // add only those resources that have data source info - filterDataSources(globalResources, resources); - } - return resources; - } - - protected void filterDataSources(List resources, List dataSources) { - for (Iterator it = resources.iterator(); it.hasNext();) { - ApplicationResource res = (ApplicationResource) it.next(); - if (res.getDataSourceInfo() != null) { - dataSources.add(res); - } - } - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.TomcatContainer; +import com.googlecode.psiprobe.model.ApplicationResource; + +import org.apache.catalina.Context; +import org.apache.catalina.Wrapper; +import org.apache.catalina.util.ServerInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * This class wires support for Tomcat "privileged" context functionality into Spring. If + * application context is privileged Tomcat would always call servlet.setWrapper method on each + * request. ContainerWrapperBean wires the passed wrapper to the relevant Tomcat container adaptor + * class, which in turn helps the Probe to interpret the wrapper. Container adaptors are required + * because internal wrapper structure is quite different between Tomcat 5.5.x and Tomcat 5.0.x + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class ContainerWrapperBean { + + private Log logger = LogFactory.getLog(getClass()); + + private TomcatContainer tomcatContainer = null; + private final Object lock = new Object(); + + /** + * List of class names to adapt particular Tomcat implementation to TomcatContainer interface + */ + private List adaptorClasses; + + private ResourceResolver resourceResolver; + + private boolean forceFirstAdaptor = false; + + private Map resourceResolvers; + + public boolean isForceFirstAdaptor() { + return forceFirstAdaptor; + } + + public void setForceFirstAdaptor(boolean forceFirstAdaptor) { + this.forceFirstAdaptor = forceFirstAdaptor; + } + + public void setWrapper(Wrapper wrapper) { + if (tomcatContainer == null) { + + synchronized (lock) { + + if (tomcatContainer == null) { + + String serverInfo = ServerInfo.getServerInfo(); + logger.info("Server info: " + serverInfo); + for (int i = 0; i < adaptorClasses.size(); i++) { + String className = (String) adaptorClasses.get(i); + try { + Object o = Class.forName(className).newInstance(); + logger.debug("Testing container adaptor: " + className); + if (o instanceof TomcatContainer) { + if (forceFirstAdaptor || ((TomcatContainer) o).canBoundTo(serverInfo)) { + logger.info("Using " + className); + tomcatContainer = (TomcatContainer) o; + tomcatContainer.setWrapper(wrapper); + break; + } else { + logger.debug("Cannot bind " + className + " to " + serverInfo); + } + } else { + logger.error(className + " does not implement " + TomcatContainer.class.getName()); + } + } catch (Throwable e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to load " + className, e); + } else { + logger.info("Failed to load " + className); + } + // + // make sure we always re-throw ThreadDeath + // + if (e instanceof ThreadDeath) { + throw (ThreadDeath) e; + } + } + } + + if (tomcatContainer == null) { + logger.fatal("No suitable container adaptor found!"); + } + } + } + } + + try { + if (tomcatContainer != null && wrapper == null) { + logger.info("Unregistering container adaptor"); + tomcatContainer.setWrapper(null); + } + } catch (Throwable e) { + logger.error("Could not unregister container adaptor", e); + // + // make sure we always re-throw ThreadDeath + // + if (e instanceof ThreadDeath) { + throw (ThreadDeath) e; + } + } + } + + public TomcatContainer getTomcatContainer() { + return tomcatContainer; + } + + public List getAdaptorClasses() { + return adaptorClasses; + } + + public void setAdaptorClasses(List adaptorClasses) { + this.adaptorClasses = adaptorClasses; + } + + public ResourceResolver getResourceResolver() { + if (resourceResolver == null) { + if (System.getProperty("jboss.server.name") != null) { + resourceResolver = (ResourceResolver) resourceResolvers.get("jboss"); + logger.info("Using JBOSS resource resolver"); + } else { + resourceResolver = (ResourceResolver) resourceResolvers.get("default"); + logger.info("Using DEFAULT resource resolver"); + } + } + return resourceResolver; + } + + public Map getResourceResolvers() { + return resourceResolvers; + } + + public void setResourceResolvers(Map resourceResolvers) { + this.resourceResolvers = resourceResolvers; + } + + public List getDataSources() throws Exception { + List resources = new ArrayList(); + resources.addAll(getPrivateDataSources()); + resources.addAll(getGlobalDataSources()); + return resources; + } + + public List getPrivateDataSources() throws Exception { + List resources = new ArrayList(); + if (tomcatContainer != null && getResourceResolver().supportsPrivateResources()) { + List apps = getTomcatContainer().findContexts(); + + for (int i = 0; i < apps.size(); i++) { + List appResources = + getResourceResolver().getApplicationResources((Context) apps.get(i), this); + // add only those resources that have data source info + filterDataSources(appResources, resources); + } + } + return resources; + } + + public List getGlobalDataSources() throws Exception { + List resources = new ArrayList(); + if (getResourceResolver().supportsGlobalResources()) { + List globalResources = getResourceResolver().getApplicationResources(); + // add only those resources that have data source info + filterDataSources(globalResources, resources); + } + return resources; + } + + protected void filterDataSources(List resources, List dataSources) { + for (Iterator it = resources.iterator(); it.hasNext();) { + ApplicationResource res = (ApplicationResource) it.next(); + if (res.getDataSourceInfo() != null) { + dataSources.add(res); + } + } + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/DatasourceAccessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/DatasourceAccessor.java index e177986919..6a2f845db2 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/DatasourceAccessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/DatasourceAccessor.java @@ -1,27 +1,27 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.DataSourceInfo; - -/** - * Part of datasource type abstraction layer. Allows to extent Probe functionality to any kind of - * datasources. - * - * @author Vlad Ilyushchenko - */ -public interface DatasourceAccessor { - DataSourceInfo getInfo(Object resource) throws Exception; - - boolean reset(Object resource) throws Exception; - - boolean canMap(Object resource); -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.DataSourceInfo; + +/** + * Part of datasource type abstraction layer. Allows to extent Probe functionality to any kind of + * datasources. + * + * @author Vlad Ilyushchenko + */ +public interface DatasourceAccessor { + DataSourceInfo getInfo(Object resource) throws Exception; + + boolean reset(Object resource) throws Exception; + + boolean canMap(Object resource); +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/DbcpDatasourceAccessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/DbcpDatasourceAccessor.java index f749c8b577..a9e224ae93 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/DbcpDatasourceAccessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/DbcpDatasourceAccessor.java @@ -1,48 +1,48 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.DataSourceInfo; - -import org.apache.commons.dbcp.BasicDataSource; - -/** - * DBCP datasource abstraction layer. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class DbcpDatasourceAccessor implements DatasourceAccessor { - public DataSourceInfo getInfo(Object resource) throws Exception { - DataSourceInfo dataSourceInfo = null; - if (canMap(resource)) { - BasicDataSource source = (BasicDataSource) resource; - dataSourceInfo = new DataSourceInfo(); - dataSourceInfo.setBusyConnections(source.getNumActive()); - dataSourceInfo.setEstablishedConnections(source.getNumIdle() + source.getNumActive()); - dataSourceInfo.setMaxConnections(source.getMaxActive()); - dataSourceInfo.setJdbcURL(source.getUrl()); - dataSourceInfo.setUsername(source.getUsername()); - dataSourceInfo.setResettable(false); - dataSourceInfo.setType("commons-dbcp"); - } - return dataSourceInfo; - } - - public boolean reset(Object resource) throws Exception { - return false; - } - - public boolean canMap(Object resource) { - return "org.apache.commons.dbcp.BasicDataSource".equals(resource.getClass().getName()) - && resource instanceof BasicDataSource; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.DataSourceInfo; + +import org.apache.commons.dbcp.BasicDataSource; + +/** + * DBCP datasource abstraction layer. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class DbcpDatasourceAccessor implements DatasourceAccessor { + public DataSourceInfo getInfo(Object resource) throws Exception { + DataSourceInfo dataSourceInfo = null; + if (canMap(resource)) { + BasicDataSource source = (BasicDataSource) resource; + dataSourceInfo = new DataSourceInfo(); + dataSourceInfo.setBusyConnections(source.getNumActive()); + dataSourceInfo.setEstablishedConnections(source.getNumIdle() + source.getNumActive()); + dataSourceInfo.setMaxConnections(source.getMaxActive()); + dataSourceInfo.setJdbcURL(source.getUrl()); + dataSourceInfo.setUsername(source.getUsername()); + dataSourceInfo.setResettable(false); + dataSourceInfo.setType("commons-dbcp"); + } + return dataSourceInfo; + } + + public boolean reset(Object resource) throws Exception { + return false; + } + + public boolean canMap(Object resource) { + return "org.apache.commons.dbcp.BasicDataSource".equals(resource.getClass().getName()) + && resource instanceof BasicDataSource; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/JBossResourceResolverBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/JBossResourceResolverBean.java index 51955e42c3..99ca79a082 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/JBossResourceResolverBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/JBossResourceResolverBean.java @@ -1,178 +1,178 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.ApplicationResource; -import com.googlecode.psiprobe.model.DataSourceInfo; - -import org.apache.catalina.Context; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.naming.NamingException; -import javax.sql.DataSource; - -/** - * An Adaptor to convert information retrieved from JBoss JMX beans into internal resource model. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class JBossResourceResolverBean implements ResourceResolver { - - protected Log logger = LogFactory.getLog(getClass()); - - public MBeanServer getMBeanServer() { - for (Iterator it = MBeanServerFactory.findMBeanServer(null).iterator(); it.hasNext();) { - MBeanServer server = (MBeanServer) it.next(); - if ("jboss".equals(server.getDefaultDomain()) - || "DefaultDomain".equals(server.getDefaultDomain())) { - return server; - } - } - return null; - } - - public boolean supportsPrivateResources() { - return false; - } - - public boolean supportsGlobalResources() { - return true; - } - - public boolean supportsDataSourceLookup() { - return false; - } - - public List getApplicationResources() throws NamingException { - - List resources = new ArrayList(); - - MBeanServer server = getMBeanServer(); - if (server != null) { - try { - Set dsNames = - server.queryNames(new ObjectName("jboss.jca:service=ManagedConnectionPool,*"), null); - for (Iterator it = dsNames.iterator(); it.hasNext();) { - ObjectName managedConnectionPoolOName = (ObjectName) it.next(); - - ApplicationResource resource = new ApplicationResource(); - resource.setName(managedConnectionPoolOName.getKeyProperty("name")); - resource.setType("jboss"); - String criteria = (String) server.getAttribute(managedConnectionPoolOName, "Criteria"); - if ("ByApplication".equals(criteria)) { - resource.setAuth("Application"); - } else if ("ByContainerAndApplication".equals(criteria)) { - resource.setAuth("Both"); - } else { - resource.setAuth("Container"); - } - DataSourceInfo dsInfo = new DataSourceInfo(); - dsInfo.setMaxConnections(((Integer) server.getAttribute(managedConnectionPoolOName, - "MaxSize")).intValue()); - dsInfo.setEstablishedConnections(((Integer) server.getAttribute( - managedConnectionPoolOName, "ConnectionCount")).intValue()); - dsInfo.setBusyConnections(((Long) server.getAttribute(managedConnectionPoolOName, - "InUseConnectionCount")).intValue()); - - - ObjectName connectionFactoryOName = - new ObjectName("jboss.jca:service=ManagedConnectionFactory,name=" - + resource.getName()); - Element elm = - (Element) server.getAttribute(connectionFactoryOName, - "ManagedConnectionFactoryProperties"); - - if (elm != null) { - NodeList nl = elm.getChildNodes(); - for (int i = 0; i < nl.getLength(); i++) { - Node n = nl.item(i); - Node na = n.getAttributes().getNamedItem("name"); - if (na != null) { - if ("ConnectionURL".equals(na.getNodeValue())) { - dsInfo.setJdbcURL(n.getFirstChild().getNodeValue()); - } - - if ("UserName".equals(na.getNodeValue())) { - dsInfo.setUsername(n.getFirstChild().getNodeValue()); - } - - // JMS datasource - if ("JmsProviderAdapterJNDI".equals(na.getNodeValue())) { - dsInfo.setJdbcURL(n.getFirstChild().getNodeValue()); - resource.setType("jms"); - } - } - } - } - - dsInfo.setResettable(true); - - resource.setDataSourceInfo(dsInfo); - resources.add(resource); - } - } catch (Exception e) { - logger.fatal("There was an error querying JBoss JMX server:", e); - } - } - return resources; - } - - public List getApplicationResources(Context context) throws NamingException { - return new ArrayList(); - } - - public boolean resetResource(Context context, String resourceName, - ContainerWrapperBean containerWrapper) throws NamingException { - try { - ObjectName poolOName = - new ObjectName("jboss.jca:service=ManagedConnectionPool,name=" + resourceName); - MBeanServer server = getMBeanServer(); - if (server != null) { - try { - server.invoke(poolOName, "stop", null, null); - server.invoke(poolOName, "start", null, null); - return true; - } catch (Exception e) { - logger.error("Could not reset resource \"" + resourceName + "\"", e); - } - } - return false; - } catch (MalformedObjectNameException e) { - throw new NamingException("Resource name: \"" + resourceName - + "\" makes a malformed ObjectName"); - } - } - - public DataSource lookupDataSource(Context context, String resourceName, - ContainerWrapperBean containerWrapper) throws NamingException { - throw new UnsupportedOperationException( - "This feature has not been implemented for JBoss server yet."); - } - - public List getApplicationResources(Context context, ContainerWrapperBean containerWrapper) - throws NamingException { - throw new UnsupportedOperationException("Not supported yet."); - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.ApplicationResource; +import com.googlecode.psiprobe.model.DataSourceInfo; + +import org.apache.catalina.Context; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * An Adaptor to convert information retrieved from JBoss JMX beans into internal resource model. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class JBossResourceResolverBean implements ResourceResolver { + + protected Log logger = LogFactory.getLog(getClass()); + + public MBeanServer getMBeanServer() { + for (Iterator it = MBeanServerFactory.findMBeanServer(null).iterator(); it.hasNext();) { + MBeanServer server = (MBeanServer) it.next(); + if ("jboss".equals(server.getDefaultDomain()) + || "DefaultDomain".equals(server.getDefaultDomain())) { + return server; + } + } + return null; + } + + public boolean supportsPrivateResources() { + return false; + } + + public boolean supportsGlobalResources() { + return true; + } + + public boolean supportsDataSourceLookup() { + return false; + } + + public List getApplicationResources() throws NamingException { + + List resources = new ArrayList(); + + MBeanServer server = getMBeanServer(); + if (server != null) { + try { + Set dsNames = + server.queryNames(new ObjectName("jboss.jca:service=ManagedConnectionPool,*"), null); + for (Iterator it = dsNames.iterator(); it.hasNext();) { + ObjectName managedConnectionPoolOName = (ObjectName) it.next(); + + ApplicationResource resource = new ApplicationResource(); + resource.setName(managedConnectionPoolOName.getKeyProperty("name")); + resource.setType("jboss"); + String criteria = (String) server.getAttribute(managedConnectionPoolOName, "Criteria"); + if ("ByApplication".equals(criteria)) { + resource.setAuth("Application"); + } else if ("ByContainerAndApplication".equals(criteria)) { + resource.setAuth("Both"); + } else { + resource.setAuth("Container"); + } + DataSourceInfo dsInfo = new DataSourceInfo(); + dsInfo.setMaxConnections(((Integer) server.getAttribute(managedConnectionPoolOName, + "MaxSize")).intValue()); + dsInfo.setEstablishedConnections(((Integer) server.getAttribute( + managedConnectionPoolOName, "ConnectionCount")).intValue()); + dsInfo.setBusyConnections(((Long) server.getAttribute(managedConnectionPoolOName, + "InUseConnectionCount")).intValue()); + + + ObjectName connectionFactoryOName = + new ObjectName("jboss.jca:service=ManagedConnectionFactory,name=" + + resource.getName()); + Element elm = + (Element) server.getAttribute(connectionFactoryOName, + "ManagedConnectionFactoryProperties"); + + if (elm != null) { + NodeList nl = elm.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + Node n = nl.item(i); + Node na = n.getAttributes().getNamedItem("name"); + if (na != null) { + if ("ConnectionURL".equals(na.getNodeValue())) { + dsInfo.setJdbcURL(n.getFirstChild().getNodeValue()); + } + + if ("UserName".equals(na.getNodeValue())) { + dsInfo.setUsername(n.getFirstChild().getNodeValue()); + } + + // JMS datasource + if ("JmsProviderAdapterJNDI".equals(na.getNodeValue())) { + dsInfo.setJdbcURL(n.getFirstChild().getNodeValue()); + resource.setType("jms"); + } + } + } + } + + dsInfo.setResettable(true); + + resource.setDataSourceInfo(dsInfo); + resources.add(resource); + } + } catch (Exception e) { + logger.fatal("There was an error querying JBoss JMX server:", e); + } + } + return resources; + } + + public List getApplicationResources(Context context) throws NamingException { + return new ArrayList(); + } + + public boolean resetResource(Context context, String resourceName, + ContainerWrapperBean containerWrapper) throws NamingException { + try { + ObjectName poolOName = + new ObjectName("jboss.jca:service=ManagedConnectionPool,name=" + resourceName); + MBeanServer server = getMBeanServer(); + if (server != null) { + try { + server.invoke(poolOName, "stop", null, null); + server.invoke(poolOName, "start", null, null); + return true; + } catch (Exception e) { + logger.error("Could not reset resource \"" + resourceName + "\"", e); + } + } + return false; + } catch (MalformedObjectNameException e) { + throw new NamingException("Resource name: \"" + resourceName + + "\" makes a malformed ObjectName"); + } + } + + public DataSource lookupDataSource(Context context, String resourceName, + ContainerWrapperBean containerWrapper) throws NamingException { + throw new UnsupportedOperationException( + "This feature has not been implemented for JBoss server yet."); + } + + public List getApplicationResources(Context context, ContainerWrapperBean containerWrapper) + throws NamingException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/JvmMemoryInfoAccessorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/JvmMemoryInfoAccessorBean.java index 689527b0ca..165ca409b7 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/JvmMemoryInfoAccessorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/JvmMemoryInfoAccessorBean.java @@ -1,93 +1,93 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.jmx.MemoryPool; -import com.googlecode.psiprobe.tools.JmxTools; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.modeler.Registry; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import javax.management.MBeanServer; -import javax.management.ObjectInstance; -import javax.management.ObjectName; -import javax.management.openmbean.CompositeDataSupport; - -/** - * - * @author Vlad Ilyushchenko - */ -public class JvmMemoryInfoAccessorBean { - - private Log logger = LogFactory.getLog(this.getClass()); - - public List getPools() throws Exception { - - List memoryPools = new LinkedList(); - MBeanServer mBeanServer = new Registry().getMBeanServer(); - Set memoryOPools = mBeanServer.queryMBeans(new ObjectName("java.lang:type=MemoryPool,*"), null); - - // totals - long totalInit = 0; - long totalMax = 0; - long totalUsed = 0; - long totalCommitted = 0; - - for (Iterator it = memoryOPools.iterator(); it.hasNext();) { - ObjectInstance oi = (ObjectInstance) it.next(); - ObjectName oName = oi.getObjectName(); - MemoryPool memoryPool = new MemoryPool(); - memoryPool.setName(JmxTools.getStringAttr(mBeanServer, oName, "Name")); - memoryPool.setType(JmxTools.getStringAttr(mBeanServer, oName, "Type")); - - CompositeDataSupport cd = (CompositeDataSupport) mBeanServer.getAttribute(oName, "Usage"); - /* - * It seems that "Usage" attribute of one of the pools may turn into null intermittently. We - * better have a dip in the graph then an NPE though. - */ - if (cd != null) { - memoryPool.setMax(JmxTools.getLongAttr(cd, "max")); - memoryPool.setUsed(JmxTools.getLongAttr(cd, "used")); - memoryPool.setInit(JmxTools.getLongAttr(cd, "init")); - memoryPool.setCommitted(JmxTools.getLongAttr(cd, "committed")); - } else { - logger.error("Oops, JVM problem? " + oName.toString() + " \"Usage\" attribute is NULL!"); - } - - totalInit += memoryPool.getInit(); - totalMax += memoryPool.getMax(); - totalUsed += memoryPool.getUsed(); - totalCommitted += memoryPool.getCommitted(); - - memoryPools.add(memoryPool); - } - - if (!memoryPools.isEmpty()) { - MemoryPool pool = new MemoryPool(); - pool.setName("Total"); - pool.setType("TOTAL"); - pool.setInit(totalInit); - pool.setUsed(totalUsed); - pool.setMax(totalMax); - pool.setCommitted(totalCommitted); - memoryPools.add(pool); - } - - return memoryPools; - - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.jmx.MemoryPool; +import com.googlecode.psiprobe.tools.JmxTools; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.modeler.Registry; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.openmbean.CompositeDataSupport; + +/** + * + * @author Vlad Ilyushchenko + */ +public class JvmMemoryInfoAccessorBean { + + private Log logger = LogFactory.getLog(this.getClass()); + + public List getPools() throws Exception { + + List memoryPools = new LinkedList(); + MBeanServer mBeanServer = new Registry().getMBeanServer(); + Set memoryOPools = mBeanServer.queryMBeans(new ObjectName("java.lang:type=MemoryPool,*"), null); + + // totals + long totalInit = 0; + long totalMax = 0; + long totalUsed = 0; + long totalCommitted = 0; + + for (Iterator it = memoryOPools.iterator(); it.hasNext();) { + ObjectInstance oi = (ObjectInstance) it.next(); + ObjectName oName = oi.getObjectName(); + MemoryPool memoryPool = new MemoryPool(); + memoryPool.setName(JmxTools.getStringAttr(mBeanServer, oName, "Name")); + memoryPool.setType(JmxTools.getStringAttr(mBeanServer, oName, "Type")); + + CompositeDataSupport cd = (CompositeDataSupport) mBeanServer.getAttribute(oName, "Usage"); + /* + * It seems that "Usage" attribute of one of the pools may turn into null intermittently. We + * better have a dip in the graph then an NPE though. + */ + if (cd != null) { + memoryPool.setMax(JmxTools.getLongAttr(cd, "max")); + memoryPool.setUsed(JmxTools.getLongAttr(cd, "used")); + memoryPool.setInit(JmxTools.getLongAttr(cd, "init")); + memoryPool.setCommitted(JmxTools.getLongAttr(cd, "committed")); + } else { + logger.error("Oops, JVM problem? " + oName.toString() + " \"Usage\" attribute is NULL!"); + } + + totalInit += memoryPool.getInit(); + totalMax += memoryPool.getMax(); + totalUsed += memoryPool.getUsed(); + totalCommitted += memoryPool.getCommitted(); + + memoryPools.add(memoryPool); + } + + if (!memoryPools.isEmpty()) { + MemoryPool pool = new MemoryPool(); + pool.setName("Total"); + pool.setType("TOTAL"); + pool.setInit(totalInit); + pool.setUsed(totalUsed); + pool.setMax(totalMax); + pool.setCommitted(totalCommitted); + memoryPools.add(pool); + } + + return memoryPools; + + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/OracleDatasourceAccessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/OracleDatasourceAccessor.java index 4c8fb1b88c..11afddb69f 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/OracleDatasourceAccessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/OracleDatasourceAccessor.java @@ -1,82 +1,82 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.Utils; -import com.googlecode.psiprobe.model.DataSourceInfo; - -import oracle.jdbc.pool.OracleConnectionCacheManager; -import oracle.jdbc.pool.OracleDataSource; - -import java.util.Properties; - -/** - * Accesses oracle.jdbc.pool.OracleDataSource. - * - * Oracle connection pool is quite different from any other available for Tomcat. Datasources are - * run by static OracleConnectionCacheManager, whereby application context scope datasource would - * have a named entry in OracleConnectionCacheManager. - * - * Datasources do not have information about pool as such, therefore this accessor has to do quite - * tedious job of verifying whether the datasource has a record in the cache manager or not. The - * pool information is subsequently retrieved from the relevant cache manager entry. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class OracleDatasourceAccessor implements DatasourceAccessor { - - public DataSourceInfo getInfo(Object resource) throws Exception { - DataSourceInfo dataSourceInfo = null; - - if (canMap(resource)) { - OracleDataSource source = (OracleDataSource) resource; - OracleConnectionCacheManager occm = - OracleConnectionCacheManager.getConnectionCacheManagerInstance(); - Properties cacheProperties = source.getConnectionCacheProperties(); - String cacheName = source.getConnectionCacheName(); - cacheName = cacheName != null && occm.existsCache(cacheName) ? cacheName : null; - - if (cacheProperties != null) { - - dataSourceInfo = new DataSourceInfo(); - if (cacheName != null) { - dataSourceInfo.setBusyConnections(occm.getNumberOfActiveConnections(cacheName)); - dataSourceInfo.setEstablishedConnections(occm.getNumberOfAvailableConnections(cacheName) - + dataSourceInfo.getBusyConnections()); - } else { - dataSourceInfo.setBusyConnections(0); - dataSourceInfo.setEstablishedConnections(0); - } - - dataSourceInfo.setMaxConnections(Utils.toInt(cacheProperties.getProperty("MaxLimit"), -1)); - dataSourceInfo.setJdbcURL(source.getURL()); - dataSourceInfo.setUsername(source.getUser()); - dataSourceInfo.setResettable(true); - dataSourceInfo.setType("oracle-jdbc"); - } - } - return dataSourceInfo; - } - - public boolean reset(Object resource) throws Exception { - if (canMap(resource)) { - ((OracleDataSource) resource).close(); - return true; - } - return false; - } - - public boolean canMap(Object resource) { - return "oracle.jdbc.pool.OracleDataSource".equals(resource.getClass().getName()) - && resource instanceof OracleDataSource; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.Utils; +import com.googlecode.psiprobe.model.DataSourceInfo; + +import oracle.jdbc.pool.OracleConnectionCacheManager; +import oracle.jdbc.pool.OracleDataSource; + +import java.util.Properties; + +/** + * Accesses oracle.jdbc.pool.OracleDataSource. + * + * Oracle connection pool is quite different from any other available for Tomcat. Datasources are + * run by static OracleConnectionCacheManager, whereby application context scope datasource would + * have a named entry in OracleConnectionCacheManager. + * + * Datasources do not have information about pool as such, therefore this accessor has to do quite + * tedious job of verifying whether the datasource has a record in the cache manager or not. The + * pool information is subsequently retrieved from the relevant cache manager entry. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class OracleDatasourceAccessor implements DatasourceAccessor { + + public DataSourceInfo getInfo(Object resource) throws Exception { + DataSourceInfo dataSourceInfo = null; + + if (canMap(resource)) { + OracleDataSource source = (OracleDataSource) resource; + OracleConnectionCacheManager occm = + OracleConnectionCacheManager.getConnectionCacheManagerInstance(); + Properties cacheProperties = source.getConnectionCacheProperties(); + String cacheName = source.getConnectionCacheName(); + cacheName = cacheName != null && occm.existsCache(cacheName) ? cacheName : null; + + if (cacheProperties != null) { + + dataSourceInfo = new DataSourceInfo(); + if (cacheName != null) { + dataSourceInfo.setBusyConnections(occm.getNumberOfActiveConnections(cacheName)); + dataSourceInfo.setEstablishedConnections(occm.getNumberOfAvailableConnections(cacheName) + + dataSourceInfo.getBusyConnections()); + } else { + dataSourceInfo.setBusyConnections(0); + dataSourceInfo.setEstablishedConnections(0); + } + + dataSourceInfo.setMaxConnections(Utils.toInt(cacheProperties.getProperty("MaxLimit"), -1)); + dataSourceInfo.setJdbcURL(source.getURL()); + dataSourceInfo.setUsername(source.getUser()); + dataSourceInfo.setResettable(true); + dataSourceInfo.setType("oracle-jdbc"); + } + } + return dataSourceInfo; + } + + public boolean reset(Object resource) throws Exception { + if (canMap(resource)) { + ((OracleDataSource) resource).close(); + return true; + } + return false; + } + + public boolean canMap(Object resource) { + return "oracle.jdbc.pool.OracleDataSource".equals(resource.getClass().getName()) + && resource instanceof OracleDataSource; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/OracleUcpDatasourceAssessor.java b/core/src/main/java/com/googlecode/psiprobe/beans/OracleUcpDatasourceAssessor.java index 172b67a06f..2aa7b1d95a 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/OracleUcpDatasourceAssessor.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/OracleUcpDatasourceAssessor.java @@ -1,53 +1,53 @@ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.DataSourceInfo; - -import oracle.ucp.jdbc.JDBCConnectionPoolStatistics; -import oracle.ucp.jdbc.PoolDataSource; - -/** - * Accesses an Oracle Universal Connection Pool (UCP) resource. - * - * @author polaris.keith - * @author Mark Lewis - */ -public class OracleUcpDatasourceAssessor implements DatasourceAccessor { - - public DataSourceInfo getInfo(Object resource) throws Exception { - DataSourceInfo dataSourceInfo = null; - if (canMap(resource)) { - PoolDataSource source = (PoolDataSource) resource; - JDBCConnectionPoolStatistics stats = source.getStatistics(); - - dataSourceInfo = new DataSourceInfo(); - /* - * If the pool starts with 0 instances, the JDBCConnectionPoolStatistics will be null. The - * JDBCConnectionPoolStatistics only initializes when there is at least one connection - * instance created. - */ - if (stats != null) { - dataSourceInfo.setBusyConnections(stats.getBorrowedConnectionsCount()); - dataSourceInfo.setEstablishedConnections(stats.getTotalConnectionsCount()); - } else { - dataSourceInfo.setBusyConnections(0); - dataSourceInfo.setEstablishedConnections(0); - } - dataSourceInfo.setMaxConnections(source.getMaxPoolSize()); - dataSourceInfo.setJdbcURL(source.getURL()); - dataSourceInfo.setUsername(source.getUser()); - dataSourceInfo.setResettable(false); - dataSourceInfo.setType("oracle-ucp"); - } - return dataSourceInfo; - } - - public boolean reset(Object resource) throws Exception { - return false; - } - - public boolean canMap(Object resource) { - return ("oracle.ucp.jdbc.PoolDataSourceImpl".equals(resource.getClass().getName()) || "oracle.ucp.jdbc.PoolXADataSourceImpl" - .equals(resource.getClass().getName())) && resource instanceof PoolDataSource; - } - -} +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.DataSourceInfo; + +import oracle.ucp.jdbc.JDBCConnectionPoolStatistics; +import oracle.ucp.jdbc.PoolDataSource; + +/** + * Accesses an Oracle Universal Connection Pool (UCP) resource. + * + * @author polaris.keith + * @author Mark Lewis + */ +public class OracleUcpDatasourceAssessor implements DatasourceAccessor { + + public DataSourceInfo getInfo(Object resource) throws Exception { + DataSourceInfo dataSourceInfo = null; + if (canMap(resource)) { + PoolDataSource source = (PoolDataSource) resource; + JDBCConnectionPoolStatistics stats = source.getStatistics(); + + dataSourceInfo = new DataSourceInfo(); + /* + * If the pool starts with 0 instances, the JDBCConnectionPoolStatistics will be null. The + * JDBCConnectionPoolStatistics only initializes when there is at least one connection + * instance created. + */ + if (stats != null) { + dataSourceInfo.setBusyConnections(stats.getBorrowedConnectionsCount()); + dataSourceInfo.setEstablishedConnections(stats.getTotalConnectionsCount()); + } else { + dataSourceInfo.setBusyConnections(0); + dataSourceInfo.setEstablishedConnections(0); + } + dataSourceInfo.setMaxConnections(source.getMaxPoolSize()); + dataSourceInfo.setJdbcURL(source.getURL()); + dataSourceInfo.setUsername(source.getUser()); + dataSourceInfo.setResettable(false); + dataSourceInfo.setType("oracle-ucp"); + } + return dataSourceInfo; + } + + public boolean reset(Object resource) throws Exception { + return false; + } + + public boolean canMap(Object resource) { + return ("oracle.ucp.jdbc.PoolDataSourceImpl".equals(resource.getClass().getName()) || "oracle.ucp.jdbc.PoolXADataSourceImpl" + .equals(resource.getClass().getName())) && resource instanceof PoolDataSource; + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolver.java b/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolver.java index db886e45a9..46fbbdc4ac 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolver.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolver.java @@ -1,81 +1,81 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import org.apache.catalina.Context; - -import java.util.List; - -import javax.management.MBeanServer; -import javax.naming.NamingException; -import javax.sql.DataSource; - -/** - * Interface of beans that retrieve information about "resources" of application server. Typically - * those resources would be datasources. - * - * @author Vlad Ilyushchenko - * @author Andy Shapoval - * @author Mark Lewis - */ -public interface ResourceResolver { - - /** - * Standalone Tomcat supports declaration of application-local resources. In that case it makes - * sense to associate display of resource/datasource information with the owner application. JBoss - * on other hand can only declate "global" resources, which alters the way resource information is - * displayed (and accessed). - * - * @return true if datasources can be associated with applications, otherwise false. - * - * @see #getApplicationResources(org.apache.catalina.Context) - */ - boolean supportsPrivateResources(); - - /** - * Most servlet containers support global resources, but for those that do not, this returns - * false. - * - * @return true if the servlet container supports global resources, otherwise false. - * - * @see #getApplicationResources() - */ - boolean supportsGlobalResources(); - - /** - * Indicates whether this servlet container exposes datasources via JNDI. - * - * @return true if the servlet container supports datasource lookup - * - * @see #lookupDataSource(org.apache.catalina.Context, java.lang.String, - * com.googlecode.psiprobe.beans.ContainerWrapperBean) - */ - boolean supportsDataSourceLookup(); - - List getApplicationResources() throws NamingException; - - List getApplicationResources(Context context, ContainerWrapperBean containerWrapper) - throws NamingException; - - boolean resetResource(Context context, String resourceName, ContainerWrapperBean containerWrapper) - throws NamingException; - - DataSource lookupDataSource(Context context, String resourceName, - ContainerWrapperBean containerWrapper) throws NamingException; - - /** - * Method that gets {@link MBeanServer} instance that is "default" for the current environment. It - * is preferably to use this method to locate the "default" {@link MBeanServer} implementation. - * - * @return "default" {@link MBeanServer} instance for the current environment - */ - MBeanServer getMBeanServer(); -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import org.apache.catalina.Context; + +import java.util.List; + +import javax.management.MBeanServer; +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * Interface of beans that retrieve information about "resources" of application server. Typically + * those resources would be datasources. + * + * @author Vlad Ilyushchenko + * @author Andy Shapoval + * @author Mark Lewis + */ +public interface ResourceResolver { + + /** + * Standalone Tomcat supports declaration of application-local resources. In that case it makes + * sense to associate display of resource/datasource information with the owner application. JBoss + * on other hand can only declate "global" resources, which alters the way resource information is + * displayed (and accessed). + * + * @return true if datasources can be associated with applications, otherwise false. + * + * @see #getApplicationResources(org.apache.catalina.Context) + */ + boolean supportsPrivateResources(); + + /** + * Most servlet containers support global resources, but for those that do not, this returns + * false. + * + * @return true if the servlet container supports global resources, otherwise false. + * + * @see #getApplicationResources() + */ + boolean supportsGlobalResources(); + + /** + * Indicates whether this servlet container exposes datasources via JNDI. + * + * @return true if the servlet container supports datasource lookup + * + * @see #lookupDataSource(org.apache.catalina.Context, java.lang.String, + * com.googlecode.psiprobe.beans.ContainerWrapperBean) + */ + boolean supportsDataSourceLookup(); + + List getApplicationResources() throws NamingException; + + List getApplicationResources(Context context, ContainerWrapperBean containerWrapper) + throws NamingException; + + boolean resetResource(Context context, String resourceName, ContainerWrapperBean containerWrapper) + throws NamingException; + + DataSource lookupDataSource(Context context, String resourceName, + ContainerWrapperBean containerWrapper) throws NamingException; + + /** + * Method that gets {@link MBeanServer} instance that is "default" for the current environment. It + * is preferably to use this method to locate the "default" {@link MBeanServer} implementation. + * + * @return "default" {@link MBeanServer} instance for the current environment + */ + MBeanServer getMBeanServer(); +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolverBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolverBean.java index 2022d863ca..832e199bff 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolverBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/ResourceResolverBean.java @@ -1,311 +1,311 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.AbstractTomcatContainer; -import com.googlecode.psiprobe.model.ApplicationResource; -import com.googlecode.psiprobe.model.DataSourceInfo; - -import org.apache.catalina.Context; -import org.apache.catalina.Server; -import org.apache.catalina.core.StandardServer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.modeler.Registry; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.management.MBeanServer; -import javax.management.ObjectName; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.sql.DataSource; - -/** - * - * @author Vlad Ilyushchenko - * @author Andy Shapoval - * @author Mark Lewis - * @author Henry Caballero - */ -public class ResourceResolverBean implements ResourceResolver { - - private Log logger = LogFactory.getLog(getClass()); - - /** - * The default resource prefix for JNDI objects in the global scope: java:. - */ - public static final String DEFAULT_GLOBAL_RESOURCE_PREFIX = ""; - - /** - * The default resource prefix for objects in a private application scope: - * java:comp/env/. - */ - public static final String DEFAULT_RESOURCE_PREFIX = DEFAULT_GLOBAL_RESOURCE_PREFIX - + "java:comp/env/"; - - private List datasourceMappers; - - public List getApplicationResources() throws NamingException { - logger.info("Reading GLOBAL resources"); - List resources = new ArrayList(); - - MBeanServer server = getMBeanServer(); - if (server != null) { - try { - Set dsNames = - server.queryNames(new ObjectName("Catalina:type=Resource,resourcetype=Global,*"), null); - for (Iterator it = dsNames.iterator(); it.hasNext();) { - ObjectName objectName = (ObjectName) it.next(); - ApplicationResource resource = new ApplicationResource(); - - logger.info("reading resource: " + objectName); - resource.setName(getStringAttribute(server, objectName, "name")); - resource.setType(getStringAttribute(server, objectName, "type")); - resource.setScope(getStringAttribute(server, objectName, "scope")); - resource.setAuth(getStringAttribute(server, objectName, "auth")); - resource.setDescription(getStringAttribute(server, objectName, "description")); - - lookupResource(resource, true, true); - - resources.add(resource); - } - } catch (Exception e) { - logger.error("There was an error querying JMX server:", e); - } - } - return resources; - } - - public synchronized List getApplicationResources(Context context, - ContainerWrapperBean containerWrapper) throws NamingException { - - List resourceList = new ArrayList(); - - boolean contextAvailable = containerWrapper.getTomcatContainer().getAvailable(context); - if (contextAvailable) { - - logger.info("Reading CONTEXT " + context.getName()); - - boolean contextBound = false; - - try { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); - contextBound = true; - } catch (NamingException e) { - logger.error("Cannot bind to context. useNaming=false ?"); - logger.debug(" Stack trace:", e); - } - - try { - containerWrapper.getTomcatContainer().addContextResource(context, resourceList, - contextBound); - - containerWrapper.getTomcatContainer().addContextResourceLink(context, resourceList, - contextBound); - for (int i = 0; i < resourceList.size(); i++) { - lookupResource((ApplicationResource) resourceList.get(i), contextBound, false); - } - - } finally { - if (contextBound) { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) - .unbindFromContext(context); - } - } - } - - return resourceList; - } - - - - public void lookupResource(ApplicationResource resource, boolean contextBound, boolean global) { - DataSourceInfo dataSourceInfo = null; - if (contextBound) { - try { - javax.naming.Context ctx = !global ? new InitialContext() : getGlobalNamingContext(); - String jndiName = resolveJndiName(resource.getName(), global); - Object o = ctx.lookup(jndiName); - resource.setLookedUp(true); - for (Iterator it = datasourceMappers.iterator(); it.hasNext();) { - DatasourceAccessor accessor = (DatasourceAccessor) it.next(); - dataSourceInfo = accessor.getInfo(o); - if (dataSourceInfo != null) { - break; - } - } - - } catch (Throwable e) { - resource.setLookedUp(false); - dataSourceInfo = null; - logger.error("Failed to lookup: " + resource.getName(), e); - // - // make sure we always re-throw ThreadDeath - // - if (e instanceof ThreadDeath) { - throw (ThreadDeath) e; - } - } - } else { - resource.setLookedUp(false); - } - - /* - * Tomcat 5.0.x DBCP datasources would have URL set to null if they incorrectly configured so we - * need to deal with this little feature - */ - if (dataSourceInfo != null && dataSourceInfo.getJdbcURL() == null) { - resource.setLookedUp(false); - } - - if (resource.isLookedUp() && dataSourceInfo != null) { - resource.setDataSourceInfo(dataSourceInfo); - } - } - - public synchronized boolean resetResource(final Context context, String resourceName, - ContainerWrapperBean containerWrapper) throws NamingException { - - if (context != null) { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); - } - try { - javax.naming.Context ctx = - (context != null) ? new InitialContext() : getGlobalNamingContext(); - String jndiName = resolveJndiName(resourceName, (context == null)); - Object o = ctx.lookup(jndiName); - try { - for (Iterator it = datasourceMappers.iterator(); it.hasNext();) { - DatasourceAccessor accessor = (DatasourceAccessor) it.next(); - if (accessor.reset(o)) { - return true; - } - } - return false; - } catch (Throwable e) { - // - // make sure we always re-throw ThreadDeath - // - if (e instanceof ThreadDeath) { - throw (ThreadDeath) e; - } - return false; - } - } finally { - if (context != null) { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) - .unbindFromContext(context); - } - } - } - - public synchronized DataSource lookupDataSource(final Context context, String resourceName, - ContainerWrapperBean containerWrapper) throws NamingException { - - if (context != null) { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); - } - try { - javax.naming.Context ctx = - (context != null) ? new InitialContext() : getGlobalNamingContext(); - String jndiName = resolveJndiName(resourceName, (context == null)); - Object o = ctx.lookup(jndiName); - - if (o instanceof DataSource) { - return (DataSource) o; - } else { - return null; - } - } finally { - if (context != null) { - ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) - .unbindFromContext(context); - } - } - } - - public List getDatasourceMappers() { - return datasourceMappers; - } - - public void setDatasourceMappers(List datasourceMappers) { - this.datasourceMappers = datasourceMappers; - } - - public boolean supportsPrivateResources() { - return true; - } - - public boolean supportsGlobalResources() { - return true; - } - - public boolean supportsDataSourceLookup() { - return true; - } - - public MBeanServer getMBeanServer() { - return new Registry().getMBeanServer(); - } - - /** - * Resolves a JNDI resource name by prepending the scope-appropriate prefix. - * - * @param global whether to use the global prefix - * @param name the JNDI name of the resource - * - * @return the JNDI resource name with the prefix appended - * - * @see #DEFAULT_GLOBAL_RESOURCE_PREFIX - * @see #DEFAULT_RESOURCE_PREFIX - */ - protected static String resolveJndiName(String name, boolean global) { - return (global ? DEFAULT_GLOBAL_RESOURCE_PREFIX : DEFAULT_RESOURCE_PREFIX) + name; - } - - private String getStringAttribute(MBeanServer server, ObjectName objectName, String attributeName) { - try { - return (String) server.getAttribute(objectName, attributeName); - } catch (Exception e) { - logger.error("Error getting attribute '" + attributeName + "' from '" + objectName + "'", e); - return null; - } - } - - /** - * Returns the Server's global naming context - * - * @return the global JNDI context - */ - protected javax.naming.Context getGlobalNamingContext() { - - javax.naming.Context globalContext = null; - MBeanServer mBeanServer = getMBeanServer(); - if (mBeanServer != null) { - try { - ObjectName name = new ObjectName("Catalina:type=Server"); - Server server = (Server) mBeanServer.getAttribute(name, "managedResource"); - // getGlobalNamingContext() was added to Server interface in Tomcat 7.0.11 - if (server instanceof StandardServer) { - globalContext = ((StandardServer) server).getGlobalNamingContext(); - } - } catch (Exception e) { - logger.error("There was an error getting globalContext through JMX server:", e); - } - } - - return globalContext; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.AbstractTomcatContainer; +import com.googlecode.psiprobe.model.ApplicationResource; +import com.googlecode.psiprobe.model.DataSourceInfo; + +import org.apache.catalina.Context; +import org.apache.catalina.Server; +import org.apache.catalina.core.StandardServer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.modeler.Registry; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; + +/** + * + * @author Vlad Ilyushchenko + * @author Andy Shapoval + * @author Mark Lewis + * @author Henry Caballero + */ +public class ResourceResolverBean implements ResourceResolver { + + private Log logger = LogFactory.getLog(getClass()); + + /** + * The default resource prefix for JNDI objects in the global scope: java:. + */ + public static final String DEFAULT_GLOBAL_RESOURCE_PREFIX = ""; + + /** + * The default resource prefix for objects in a private application scope: + * java:comp/env/. + */ + public static final String DEFAULT_RESOURCE_PREFIX = DEFAULT_GLOBAL_RESOURCE_PREFIX + + "java:comp/env/"; + + private List datasourceMappers; + + public List getApplicationResources() throws NamingException { + logger.info("Reading GLOBAL resources"); + List resources = new ArrayList(); + + MBeanServer server = getMBeanServer(); + if (server != null) { + try { + Set dsNames = + server.queryNames(new ObjectName("Catalina:type=Resource,resourcetype=Global,*"), null); + for (Iterator it = dsNames.iterator(); it.hasNext();) { + ObjectName objectName = (ObjectName) it.next(); + ApplicationResource resource = new ApplicationResource(); + + logger.info("reading resource: " + objectName); + resource.setName(getStringAttribute(server, objectName, "name")); + resource.setType(getStringAttribute(server, objectName, "type")); + resource.setScope(getStringAttribute(server, objectName, "scope")); + resource.setAuth(getStringAttribute(server, objectName, "auth")); + resource.setDescription(getStringAttribute(server, objectName, "description")); + + lookupResource(resource, true, true); + + resources.add(resource); + } + } catch (Exception e) { + logger.error("There was an error querying JMX server:", e); + } + } + return resources; + } + + public synchronized List getApplicationResources(Context context, + ContainerWrapperBean containerWrapper) throws NamingException { + + List resourceList = new ArrayList(); + + boolean contextAvailable = containerWrapper.getTomcatContainer().getAvailable(context); + if (contextAvailable) { + + logger.info("Reading CONTEXT " + context.getName()); + + boolean contextBound = false; + + try { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); + contextBound = true; + } catch (NamingException e) { + logger.error("Cannot bind to context. useNaming=false ?"); + logger.debug(" Stack trace:", e); + } + + try { + containerWrapper.getTomcatContainer().addContextResource(context, resourceList, + contextBound); + + containerWrapper.getTomcatContainer().addContextResourceLink(context, resourceList, + contextBound); + for (int i = 0; i < resourceList.size(); i++) { + lookupResource((ApplicationResource) resourceList.get(i), contextBound, false); + } + + } finally { + if (contextBound) { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) + .unbindFromContext(context); + } + } + } + + return resourceList; + } + + + + public void lookupResource(ApplicationResource resource, boolean contextBound, boolean global) { + DataSourceInfo dataSourceInfo = null; + if (contextBound) { + try { + javax.naming.Context ctx = !global ? new InitialContext() : getGlobalNamingContext(); + String jndiName = resolveJndiName(resource.getName(), global); + Object o = ctx.lookup(jndiName); + resource.setLookedUp(true); + for (Iterator it = datasourceMappers.iterator(); it.hasNext();) { + DatasourceAccessor accessor = (DatasourceAccessor) it.next(); + dataSourceInfo = accessor.getInfo(o); + if (dataSourceInfo != null) { + break; + } + } + + } catch (Throwable e) { + resource.setLookedUp(false); + dataSourceInfo = null; + logger.error("Failed to lookup: " + resource.getName(), e); + // + // make sure we always re-throw ThreadDeath + // + if (e instanceof ThreadDeath) { + throw (ThreadDeath) e; + } + } + } else { + resource.setLookedUp(false); + } + + /* + * Tomcat 5.0.x DBCP datasources would have URL set to null if they incorrectly configured so we + * need to deal with this little feature + */ + if (dataSourceInfo != null && dataSourceInfo.getJdbcURL() == null) { + resource.setLookedUp(false); + } + + if (resource.isLookedUp() && dataSourceInfo != null) { + resource.setDataSourceInfo(dataSourceInfo); + } + } + + public synchronized boolean resetResource(final Context context, String resourceName, + ContainerWrapperBean containerWrapper) throws NamingException { + + if (context != null) { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); + } + try { + javax.naming.Context ctx = + (context != null) ? new InitialContext() : getGlobalNamingContext(); + String jndiName = resolveJndiName(resourceName, (context == null)); + Object o = ctx.lookup(jndiName); + try { + for (Iterator it = datasourceMappers.iterator(); it.hasNext();) { + DatasourceAccessor accessor = (DatasourceAccessor) it.next(); + if (accessor.reset(o)) { + return true; + } + } + return false; + } catch (Throwable e) { + // + // make sure we always re-throw ThreadDeath + // + if (e instanceof ThreadDeath) { + throw (ThreadDeath) e; + } + return false; + } + } finally { + if (context != null) { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) + .unbindFromContext(context); + } + } + } + + public synchronized DataSource lookupDataSource(final Context context, String resourceName, + ContainerWrapperBean containerWrapper) throws NamingException { + + if (context != null) { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context); + } + try { + javax.naming.Context ctx = + (context != null) ? new InitialContext() : getGlobalNamingContext(); + String jndiName = resolveJndiName(resourceName, (context == null)); + Object o = ctx.lookup(jndiName); + + if (o instanceof DataSource) { + return (DataSource) o; + } else { + return null; + } + } finally { + if (context != null) { + ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()) + .unbindFromContext(context); + } + } + } + + public List getDatasourceMappers() { + return datasourceMappers; + } + + public void setDatasourceMappers(List datasourceMappers) { + this.datasourceMappers = datasourceMappers; + } + + public boolean supportsPrivateResources() { + return true; + } + + public boolean supportsGlobalResources() { + return true; + } + + public boolean supportsDataSourceLookup() { + return true; + } + + public MBeanServer getMBeanServer() { + return new Registry().getMBeanServer(); + } + + /** + * Resolves a JNDI resource name by prepending the scope-appropriate prefix. + * + * @param global whether to use the global prefix + * @param name the JNDI name of the resource + * + * @return the JNDI resource name with the prefix appended + * + * @see #DEFAULT_GLOBAL_RESOURCE_PREFIX + * @see #DEFAULT_RESOURCE_PREFIX + */ + protected static String resolveJndiName(String name, boolean global) { + return (global ? DEFAULT_GLOBAL_RESOURCE_PREFIX : DEFAULT_RESOURCE_PREFIX) + name; + } + + private String getStringAttribute(MBeanServer server, ObjectName objectName, String attributeName) { + try { + return (String) server.getAttribute(objectName, attributeName); + } catch (Exception e) { + logger.error("Error getting attribute '" + attributeName + "' from '" + objectName + "'", e); + return null; + } + } + + /** + * Returns the Server's global naming context + * + * @return the global JNDI context + */ + protected javax.naming.Context getGlobalNamingContext() { + + javax.naming.Context globalContext = null; + MBeanServer mBeanServer = getMBeanServer(); + if (mBeanServer != null) { + try { + ObjectName name = new ObjectName("Catalina:type=Server"); + Server server = (Server) mBeanServer.getAttribute(name, "managedResource"); + // getGlobalNamingContext() was added to Server interface in Tomcat 7.0.11 + if (server instanceof StandardServer) { + globalContext = ((StandardServer) server).getGlobalNamingContext(); + } + } catch (Exception e) { + logger.error("There was an error getting globalContext through JMX server:", e); + } + } + + return globalContext; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/RuntimeInfoAccessorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/RuntimeInfoAccessorBean.java index becd7d705c..a4774c0cf8 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/RuntimeInfoAccessorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/RuntimeInfoAccessorBean.java @@ -1,75 +1,75 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans; - -import com.googlecode.psiprobe.model.jmx.RuntimeInformation; -import com.googlecode.psiprobe.tools.JmxTools; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.modeler.Registry; - -import javax.management.MBeanServer; -import javax.management.ObjectName; - -/** - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class RuntimeInfoAccessorBean { - - private Log logger = LogFactory.getLog(RuntimeInfoAccessorBean.class); - - public RuntimeInformation getRuntimeInformation() throws Exception { - MBeanServer mBeanServer = new Registry().getMBeanServer(); - RuntimeInformation ri = new RuntimeInformation(); - - try { - ObjectName runtimeOName = new ObjectName("java.lang:type=Runtime"); - ri.setStartTime(JmxTools.getLongAttr(mBeanServer, runtimeOName, "StartTime")); - ri.setUptime(JmxTools.getLongAttr(mBeanServer, runtimeOName, "Uptime")); - ri.setVmVendor(JmxTools.getStringAttr(mBeanServer, runtimeOName, "VmVendor")); - - ObjectName osOName = new ObjectName("java.lang:type=OperatingSystem"); - ri.setOsName(JmxTools.getStringAttr(mBeanServer, osOName, "Name")); - ri.setOsVersion(JmxTools.getStringAttr(mBeanServer, osOName, "Version")); - - if (!ri.getVmVendor().startsWith("IBM Corporation")) { - ri.setTotalPhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, - "TotalPhysicalMemorySize")); - ri.setCommittedVirtualMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, - "CommittedVirtualMemorySize")); - ri.setFreePhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, - "FreePhysicalMemorySize")); - ri.setFreeSwapSpaceSize(JmxTools.getLongAttr(mBeanServer, osOName, "FreeSwapSpaceSize")); - ri.setTotalSwapSpaceSize(JmxTools.getLongAttr(mBeanServer, osOName, "TotalSwapSpaceSize")); - ri.setProcessCpuTime(JmxTools.getLongAttr(mBeanServer, osOName, "ProcessCpuTime")); - ri.setAvailableProcessors(Runtime.getRuntime().availableProcessors()); - } else { - ri.setTotalPhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, - "TotalPhysicalMemory")); - } - - if (JmxTools.hasAttribute(mBeanServer, osOName, "OpenFileDescriptorCount") - && JmxTools.hasAttribute(mBeanServer, osOName, "MaxFileDescriptorCount")) { - - ri.setOpenFDCount(JmxTools.getLongAttr(mBeanServer, osOName, "OpenFileDescriptorCount")); - ri.setMaxFDCount(JmxTools.getLongAttr(mBeanServer, osOName, "MaxFileDescriptorCount")); - } - - return ri; - } catch (Exception e) { - logger.debug("OS information is unavailable"); - return null; - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans; + +import com.googlecode.psiprobe.model.jmx.RuntimeInformation; +import com.googlecode.psiprobe.tools.JmxTools; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.modeler.Registry; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +/** + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class RuntimeInfoAccessorBean { + + private Log logger = LogFactory.getLog(RuntimeInfoAccessorBean.class); + + public RuntimeInformation getRuntimeInformation() throws Exception { + MBeanServer mBeanServer = new Registry().getMBeanServer(); + RuntimeInformation ri = new RuntimeInformation(); + + try { + ObjectName runtimeOName = new ObjectName("java.lang:type=Runtime"); + ri.setStartTime(JmxTools.getLongAttr(mBeanServer, runtimeOName, "StartTime")); + ri.setUptime(JmxTools.getLongAttr(mBeanServer, runtimeOName, "Uptime")); + ri.setVmVendor(JmxTools.getStringAttr(mBeanServer, runtimeOName, "VmVendor")); + + ObjectName osOName = new ObjectName("java.lang:type=OperatingSystem"); + ri.setOsName(JmxTools.getStringAttr(mBeanServer, osOName, "Name")); + ri.setOsVersion(JmxTools.getStringAttr(mBeanServer, osOName, "Version")); + + if (!ri.getVmVendor().startsWith("IBM Corporation")) { + ri.setTotalPhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, + "TotalPhysicalMemorySize")); + ri.setCommittedVirtualMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, + "CommittedVirtualMemorySize")); + ri.setFreePhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, + "FreePhysicalMemorySize")); + ri.setFreeSwapSpaceSize(JmxTools.getLongAttr(mBeanServer, osOName, "FreeSwapSpaceSize")); + ri.setTotalSwapSpaceSize(JmxTools.getLongAttr(mBeanServer, osOName, "TotalSwapSpaceSize")); + ri.setProcessCpuTime(JmxTools.getLongAttr(mBeanServer, osOName, "ProcessCpuTime")); + ri.setAvailableProcessors(Runtime.getRuntime().availableProcessors()); + } else { + ri.setTotalPhysicalMemorySize(JmxTools.getLongAttr(mBeanServer, osOName, + "TotalPhysicalMemory")); + } + + if (JmxTools.hasAttribute(mBeanServer, osOName, "OpenFileDescriptorCount") + && JmxTools.hasAttribute(mBeanServer, osOName, "MaxFileDescriptorCount")) { + + ri.setOpenFDCount(JmxTools.getLongAttr(mBeanServer, osOName, "OpenFileDescriptorCount")); + ri.setMaxFDCount(JmxTools.getLongAttr(mBeanServer, osOName, "MaxFileDescriptorCount")); + } + + return ri; + } catch (Exception e) { + logger.debug("OS information is unavailable"); + return null; + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AbstractStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AbstractStatsCollectorBean.java index 7acc235788..f2cb8927a5 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AbstractStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AbstractStatsCollectorBean.java @@ -1,174 +1,174 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.Utils; -import com.googlecode.psiprobe.beans.stats.listeners.StatsCollectionEvent; -import com.googlecode.psiprobe.beans.stats.listeners.StatsCollectionListener; -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.data.xy.XYDataItem; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -/** - * - * @author Vlad Ilyushchenko - * @author Andy Shapoval - * @author Mark Lewis - */ -public abstract class AbstractStatsCollectorBean { - - private StatsCollection statsCollection; - private int maxSeries = 240; - private List listeners; - private Map previousData = new TreeMap(); - - public StatsCollection getStatsCollection() { - return statsCollection; - } - - public void setStatsCollection(StatsCollection statsCollection) { - this.statsCollection = statsCollection; - } - - public int getMaxSeries() { - return maxSeries; - } - - public void setMaxSeries(int maxSeries) { - this.maxSeries = maxSeries; - } - - public List getListeners() { - return listeners; - } - - public void setListeners(List listeners) { - this.listeners = listeners; - } - - public abstract void collect() throws Exception; - - protected long buildDeltaStats(String name, long value) throws InterruptedException { - return buildDeltaStats(name, value, System.currentTimeMillis()); - } - - protected long buildDeltaStats(String name, long value, long time) throws InterruptedException { - long delta = 0; - if (statsCollection != null) { - long previousValue = Utils.toLong((Long) previousData.get(name), 0); - delta = value - previousValue; - delta = delta > 0 ? delta : 0; - buildAbsoluteStats(name, delta, time); - previousData.put(name, new Long(value)); - } - return delta; - } - - protected void buildAbsoluteStats(String name, long value) throws InterruptedException { - buildAbsoluteStats(name, value, System.currentTimeMillis()); - } - - - protected void buildAbsoluteStats(String name, long value, long time) throws InterruptedException { - List stats = statsCollection.getStats(name); - if (stats == null) { - stats = statsCollection.newStats(name, maxSeries); - } else { - XYDataItem data = new XYDataItem(time, value); - statsCollection.lockForUpdate(); - try { - stats.add(data); - houseKeepStats(stats); - } finally { - statsCollection.releaseLock(); - } - if (listeners != null) { - StatsCollectionEvent event = new StatsCollectionEvent(name, data); - for (Iterator it = listeners.iterator(); it.hasNext();) { - Object o = it.next(); - if (o instanceof StatsCollectionListener) { - StatsCollectionListener listener = (StatsCollectionListener) o; - if (listener.isEnabled()) { - listener.statsCollected(event); - } - } - } - } - } - } - - private class Entry { - long time; - long value; - } - - /** - * If there is a value indicating the accumulated amount of time spent on something it is possible - * to build a series of values representing the percentage of time spent on doing something. For - * example: - * - *

- * at point T1 the system has spent A milliseconds performing tasks at point T2 the system has - * spent B milliseconds performing tasks - *

- * - *

- * so between in a timeframe T2-T1 the system spent B-A milliseconds being busy. Thus (B - A)/(T2 - * - T1) * 100 is the percentage of all time the system spent being busy. - *

- * - * @param name - * @param value time in milliseconds - * @param time - * @throws InterruptedException - */ - protected void buildTimePercentageStats(String name, long value, long time) - throws InterruptedException { - - Entry entry = (Entry) previousData.get(name); - if (entry == null) { - entry = new Entry(); - entry.value = value; - entry.time = time; - previousData.put(name, entry); - } else { - double valueDelta = value - entry.value; - double timeDelta = time - entry.time; - double statValue = valueDelta * 100 / timeDelta; - statsCollection.lockForUpdate(); - try { - List stats = statsCollection.getStats(name); - if (stats == null) { - stats = statsCollection.newStats(name, maxSeries); - } - stats.add(stats.size(), new XYDataItem(time, statValue)); - houseKeepStats(stats); - } finally { - statsCollection.releaseLock(); - } - } - } - - protected void resetStats(String name) { - statsCollection.resetStats(name); - } - - private void houseKeepStats(List stats) { - while (stats.size() > maxSeries) { - stats.remove(0); - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.Utils; +import com.googlecode.psiprobe.beans.stats.listeners.StatsCollectionEvent; +import com.googlecode.psiprobe.beans.stats.listeners.StatsCollectionListener; +import com.googlecode.psiprobe.model.stats.StatsCollection; + +import org.jfree.data.xy.XYDataItem; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * + * @author Vlad Ilyushchenko + * @author Andy Shapoval + * @author Mark Lewis + */ +public abstract class AbstractStatsCollectorBean { + + private StatsCollection statsCollection; + private int maxSeries = 240; + private List listeners; + private Map previousData = new TreeMap(); + + public StatsCollection getStatsCollection() { + return statsCollection; + } + + public void setStatsCollection(StatsCollection statsCollection) { + this.statsCollection = statsCollection; + } + + public int getMaxSeries() { + return maxSeries; + } + + public void setMaxSeries(int maxSeries) { + this.maxSeries = maxSeries; + } + + public List getListeners() { + return listeners; + } + + public void setListeners(List listeners) { + this.listeners = listeners; + } + + public abstract void collect() throws Exception; + + protected long buildDeltaStats(String name, long value) throws InterruptedException { + return buildDeltaStats(name, value, System.currentTimeMillis()); + } + + protected long buildDeltaStats(String name, long value, long time) throws InterruptedException { + long delta = 0; + if (statsCollection != null) { + long previousValue = Utils.toLong((Long) previousData.get(name), 0); + delta = value - previousValue; + delta = delta > 0 ? delta : 0; + buildAbsoluteStats(name, delta, time); + previousData.put(name, new Long(value)); + } + return delta; + } + + protected void buildAbsoluteStats(String name, long value) throws InterruptedException { + buildAbsoluteStats(name, value, System.currentTimeMillis()); + } + + + protected void buildAbsoluteStats(String name, long value, long time) throws InterruptedException { + List stats = statsCollection.getStats(name); + if (stats == null) { + stats = statsCollection.newStats(name, maxSeries); + } else { + XYDataItem data = new XYDataItem(time, value); + statsCollection.lockForUpdate(); + try { + stats.add(data); + houseKeepStats(stats); + } finally { + statsCollection.releaseLock(); + } + if (listeners != null) { + StatsCollectionEvent event = new StatsCollectionEvent(name, data); + for (Iterator it = listeners.iterator(); it.hasNext();) { + Object o = it.next(); + if (o instanceof StatsCollectionListener) { + StatsCollectionListener listener = (StatsCollectionListener) o; + if (listener.isEnabled()) { + listener.statsCollected(event); + } + } + } + } + } + } + + private class Entry { + long time; + long value; + } + + /** + * If there is a value indicating the accumulated amount of time spent on something it is possible + * to build a series of values representing the percentage of time spent on doing something. For + * example: + * + *

+ * at point T1 the system has spent A milliseconds performing tasks at point T2 the system has + * spent B milliseconds performing tasks + *

+ * + *

+ * so between in a timeframe T2-T1 the system spent B-A milliseconds being busy. Thus (B - A)/(T2 + * - T1) * 100 is the percentage of all time the system spent being busy. + *

+ * + * @param name + * @param value time in milliseconds + * @param time + * @throws InterruptedException + */ + protected void buildTimePercentageStats(String name, long value, long time) + throws InterruptedException { + + Entry entry = (Entry) previousData.get(name); + if (entry == null) { + entry = new Entry(); + entry.value = value; + entry.time = time; + previousData.put(name, entry); + } else { + double valueDelta = value - entry.value; + double timeDelta = time - entry.time; + double statValue = valueDelta * 100 / timeDelta; + statsCollection.lockForUpdate(); + try { + List stats = statsCollection.getStats(name); + if (stats == null) { + stats = statsCollection.newStats(name, maxSeries); + } + stats.add(stats.size(), new XYDataItem(time, statValue)); + houseKeepStats(stats); + } finally { + statsCollection.releaseLock(); + } + } + } + + protected void resetStats(String name) { + statsCollection.resetStats(name); + } + + private void houseKeepStats(List stats) { + while (stats.size() > maxSeries) { + stats.remove(0); + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AppStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AppStatsCollectorBean.java index 9c9bd4f7c8..3dba23059a 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AppStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/AppStatsCollectorBean.java @@ -1,159 +1,159 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.TomcatContainer; -import com.googlecode.psiprobe.beans.ContainerWrapperBean; -import com.googlecode.psiprobe.model.Application; -import com.googlecode.psiprobe.tools.ApplicationUtils; - -import org.apache.catalina.Context; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.context.ServletContextAware; - -import java.util.Iterator; -import java.util.List; - -import javax.servlet.ServletContext; - -/** - * Collects application statistics - * - * @author Andy Shapoval - * @author Mark Lewis - */ -public class AppStatsCollectorBean extends AbstractStatsCollectorBean implements - ServletContextAware { - - private Log logger = LogFactory.getLog(AppStatsCollectorBean.class); - - private ContainerWrapperBean containerWrapper; - private ServletContext servletContext; - private boolean selfIgnored; - - public ContainerWrapperBean getContainerWrapper() { - return containerWrapper; - } - - public void setContainerWrapper(ContainerWrapperBean containerWrapper) { - this.containerWrapper = containerWrapper; - } - - public boolean isSelfIgnored() { - return selfIgnored; - } - - public void setSelfIgnored(boolean selfIgnored) { - this.selfIgnored = selfIgnored; - } - - protected ServletContext getServletContext() { - return servletContext; - } - - public void setServletContext(ServletContext servletContext) { - this.servletContext = servletContext; - } - - public void collect() throws Exception { - - long currentTime = System.currentTimeMillis(); - - if (containerWrapper == null) { - logger.error("Cannot collect application stats. Container wrapper is not set."); - } else { - TomcatContainer tomcatContainer = getContainerWrapper().getTomcatContainer(); - - // check if the containerWtapper has been initialized - if (tomcatContainer != null) { - long totalReqDelta = 0; - long totalErrDelta = 0; - long totalAvgProcTime = 0; - int participatingAppCount = 0; - - List contexts = tomcatContainer.findContexts(); - for (Iterator i = contexts.iterator(); i.hasNext();) { - Context ctx = (Context) i.next(); - - if (ctx != null && ctx.getName() != null) { - Application app = new Application(); - ApplicationUtils.collectApplicationServletStats(ctx, app); - - String appName = "".equals(ctx.getName()) ? "/" : ctx.getName(); - - long reqDelta = - buildDeltaStats("app.requests." + appName, app.getRequestCount(), currentTime); - long errDelta = buildDeltaStats("app.errors." + appName, app.getErrorCount()); - long procTimeDelta = - buildDeltaStats("app.proc_time." + appName, app.getProcessingTime(), currentTime); - - long avgProcTime = reqDelta == 0 ? 0 : procTimeDelta / reqDelta; - buildAbsoluteStats("app.avg_proc_time." + appName, avgProcTime, currentTime); - - /* - * make sure applications that did not serve any requests do not participate in average - * response time equasion thus diluting the value - */ - if (reqDelta > 0) { - if (!excludeFromTotal(ctx)) { - totalReqDelta += reqDelta; - totalErrDelta += errDelta; - totalAvgProcTime += avgProcTime; - participatingAppCount++; - } - } - } - } - // build totals for all applications - buildAbsoluteStats("total.requests", totalReqDelta, currentTime); - buildAbsoluteStats("total.errors", totalErrDelta, currentTime); - buildAbsoluteStats("total.avg_proc_time", participatingAppCount == 0 ? 0 : totalAvgProcTime - / participatingAppCount, currentTime); - } - logger.debug("app stats collected in " + (System.currentTimeMillis() - currentTime) + "ms."); - } - } - - private boolean excludeFromTotal(Context ctx) { - return isSelfIgnored() && getServletContext().equals(ctx.getServletContext()); - } - - public void reset() { - if (containerWrapper == null) { - logger.error("Cannot reset application stats. Container wrapper is not set."); - } else { - TomcatContainer tomcatContainer = getContainerWrapper().getTomcatContainer(); - if (tomcatContainer != null) { - List contexts = tomcatContainer.findContexts(); - for (Iterator i = contexts.iterator(); i.hasNext();) { - Context ctx = (Context) i.next(); - - if (ctx != null && ctx.getName() != null) { - String appName = "".equals(ctx.getName()) ? "/" : ctx.getName(); - reset(appName); - } - } - } - } - resetStats("total.requests"); - resetStats("total.errors"); - resetStats("total.avg_proc_time"); - } - - public void reset(String appName) { - resetStats("app.requests." + appName); - resetStats("app.proc_time." + appName); - resetStats("app.errors." + appName); - resetStats("app.avg_proc_time." + appName); - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.TomcatContainer; +import com.googlecode.psiprobe.beans.ContainerWrapperBean; +import com.googlecode.psiprobe.model.Application; +import com.googlecode.psiprobe.tools.ApplicationUtils; + +import org.apache.catalina.Context; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.context.ServletContextAware; + +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletContext; + +/** + * Collects application statistics + * + * @author Andy Shapoval + * @author Mark Lewis + */ +public class AppStatsCollectorBean extends AbstractStatsCollectorBean implements + ServletContextAware { + + private Log logger = LogFactory.getLog(AppStatsCollectorBean.class); + + private ContainerWrapperBean containerWrapper; + private ServletContext servletContext; + private boolean selfIgnored; + + public ContainerWrapperBean getContainerWrapper() { + return containerWrapper; + } + + public void setContainerWrapper(ContainerWrapperBean containerWrapper) { + this.containerWrapper = containerWrapper; + } + + public boolean isSelfIgnored() { + return selfIgnored; + } + + public void setSelfIgnored(boolean selfIgnored) { + this.selfIgnored = selfIgnored; + } + + protected ServletContext getServletContext() { + return servletContext; + } + + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + public void collect() throws Exception { + + long currentTime = System.currentTimeMillis(); + + if (containerWrapper == null) { + logger.error("Cannot collect application stats. Container wrapper is not set."); + } else { + TomcatContainer tomcatContainer = getContainerWrapper().getTomcatContainer(); + + // check if the containerWtapper has been initialized + if (tomcatContainer != null) { + long totalReqDelta = 0; + long totalErrDelta = 0; + long totalAvgProcTime = 0; + int participatingAppCount = 0; + + List contexts = tomcatContainer.findContexts(); + for (Iterator i = contexts.iterator(); i.hasNext();) { + Context ctx = (Context) i.next(); + + if (ctx != null && ctx.getName() != null) { + Application app = new Application(); + ApplicationUtils.collectApplicationServletStats(ctx, app); + + String appName = "".equals(ctx.getName()) ? "/" : ctx.getName(); + + long reqDelta = + buildDeltaStats("app.requests." + appName, app.getRequestCount(), currentTime); + long errDelta = buildDeltaStats("app.errors." + appName, app.getErrorCount()); + long procTimeDelta = + buildDeltaStats("app.proc_time." + appName, app.getProcessingTime(), currentTime); + + long avgProcTime = reqDelta == 0 ? 0 : procTimeDelta / reqDelta; + buildAbsoluteStats("app.avg_proc_time." + appName, avgProcTime, currentTime); + + /* + * make sure applications that did not serve any requests do not participate in average + * response time equasion thus diluting the value + */ + if (reqDelta > 0) { + if (!excludeFromTotal(ctx)) { + totalReqDelta += reqDelta; + totalErrDelta += errDelta; + totalAvgProcTime += avgProcTime; + participatingAppCount++; + } + } + } + } + // build totals for all applications + buildAbsoluteStats("total.requests", totalReqDelta, currentTime); + buildAbsoluteStats("total.errors", totalErrDelta, currentTime); + buildAbsoluteStats("total.avg_proc_time", participatingAppCount == 0 ? 0 : totalAvgProcTime + / participatingAppCount, currentTime); + } + logger.debug("app stats collected in " + (System.currentTimeMillis() - currentTime) + "ms."); + } + } + + private boolean excludeFromTotal(Context ctx) { + return isSelfIgnored() && getServletContext().equals(ctx.getServletContext()); + } + + public void reset() { + if (containerWrapper == null) { + logger.error("Cannot reset application stats. Container wrapper is not set."); + } else { + TomcatContainer tomcatContainer = getContainerWrapper().getTomcatContainer(); + if (tomcatContainer != null) { + List contexts = tomcatContainer.findContexts(); + for (Iterator i = contexts.iterator(); i.hasNext();) { + Context ctx = (Context) i.next(); + + if (ctx != null && ctx.getName() != null) { + String appName = "".equals(ctx.getName()) ? "/" : ctx.getName(); + reset(appName); + } + } + } + } + resetStats("total.requests"); + resetStats("total.errors"); + resetStats("total.avg_proc_time"); + } + + public void reset(String appName) { + resetStats("app.requests." + appName); + resetStats("app.proc_time." + appName); + resetStats("app.errors." + appName); + resetStats("app.avg_proc_time." + appName); + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ClusterStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ClusterStatsCollectorBean.java index 3ac3fafe4b..2c7ba12200 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ClusterStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ClusterStatsCollectorBean.java @@ -1,57 +1,57 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.TomcatContainer; -import com.googlecode.psiprobe.beans.ClusterWrapperBean; -import com.googlecode.psiprobe.beans.ContainerWrapperBean; -import com.googlecode.psiprobe.model.jmx.Cluster; - -/** - * - * @author Vlad Ilyushchenko - */ -public class ClusterStatsCollectorBean extends AbstractStatsCollectorBean { - private ContainerWrapperBean containerWrapper; - private ClusterWrapperBean clusterWrapper; - - public ContainerWrapperBean getContainerWrapper() { - return containerWrapper; - } - - public void setContainerWrapper(ContainerWrapperBean containerWrapper) { - this.containerWrapper = containerWrapper; - } - - public ClusterWrapperBean getClusterWrapper() { - return clusterWrapper; - } - - public void setClusterWrapper(ClusterWrapperBean clusterWrapper) { - this.clusterWrapper = clusterWrapper; - } - - public void collect() throws Exception { - // Job can be called before the servlet finished intialisation. Make sure - // we dont get an NPE. - TomcatContainer container = containerWrapper.getTomcatContainer(); - if (container != null) { - Cluster cluster = - clusterWrapper.getCluster(container.getName(), container.getHostName(), false); - if (cluster != null) { - buildDeltaStats("cluster.received", cluster.getTotalReceivedBytes()); - buildDeltaStats("cluster.sent", cluster.getSenderTotalBytes()); - buildDeltaStats("cluster.req.received", cluster.getNrOfMsgsReceived()); - buildDeltaStats("cluster.req.sent", cluster.getSenderNrOfRequests()); - } - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.TomcatContainer; +import com.googlecode.psiprobe.beans.ClusterWrapperBean; +import com.googlecode.psiprobe.beans.ContainerWrapperBean; +import com.googlecode.psiprobe.model.jmx.Cluster; + +/** + * + * @author Vlad Ilyushchenko + */ +public class ClusterStatsCollectorBean extends AbstractStatsCollectorBean { + private ContainerWrapperBean containerWrapper; + private ClusterWrapperBean clusterWrapper; + + public ContainerWrapperBean getContainerWrapper() { + return containerWrapper; + } + + public void setContainerWrapper(ContainerWrapperBean containerWrapper) { + this.containerWrapper = containerWrapper; + } + + public ClusterWrapperBean getClusterWrapper() { + return clusterWrapper; + } + + public void setClusterWrapper(ClusterWrapperBean clusterWrapper) { + this.clusterWrapper = clusterWrapper; + } + + public void collect() throws Exception { + // Job can be called before the servlet finished intialisation. Make sure + // we dont get an NPE. + TomcatContainer container = containerWrapper.getTomcatContainer(); + if (container != null) { + Cluster cluster = + clusterWrapper.getCluster(container.getName(), container.getHostName(), false); + if (cluster != null) { + buildDeltaStats("cluster.received", cluster.getTotalReceivedBytes()); + buildDeltaStats("cluster.sent", cluster.getSenderTotalBytes()); + buildDeltaStats("cluster.req.received", cluster.getNrOfMsgsReceived()); + buildDeltaStats("cluster.req.sent", cluster.getSenderNrOfRequests()); + } + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ConnectorStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ConnectorStatsCollectorBean.java index f274365009..36ed47b0a0 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ConnectorStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/ConnectorStatsCollectorBean.java @@ -1,66 +1,66 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.beans.ContainerListenerBean; -import com.googlecode.psiprobe.model.Connector; - -import java.util.Iterator; -import java.util.List; - -/** - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class ConnectorStatsCollectorBean extends AbstractStatsCollectorBean { - - private ContainerListenerBean listenerBean; - - public ContainerListenerBean getListenerBean() { - return listenerBean; - } - - public void setListenerBean(ContainerListenerBean listenerBean) { - this.listenerBean = listenerBean; - } - - public void collect() throws Exception { - List connectors = listenerBean.getConnectors(false); - for (Iterator it = connectors.iterator(); it.hasNext();) { - Connector connector = (Connector) it.next(); - String statName = "stat.connector." + connector.getName(); - buildDeltaStats(statName + ".requests", connector.getRequestCount()); - buildDeltaStats(statName + ".errors", connector.getErrorCount()); - buildDeltaStats(statName + ".sent", connector.getBytesSent()); - buildDeltaStats(statName + ".received", connector.getBytesReceived()); - buildDeltaStats(statName + ".proc_time", connector.getProcessingTime()); - } - } - - public void reset() throws Exception { - List connectors = listenerBean.getConnectors(false); - for (Iterator it = connectors.iterator(); it.hasNext();) { - Connector connector = (Connector) it.next(); - reset(connector.getName()); - } - } - - public void reset(String connectorName) { - String statName = "stat.connector." + connectorName; - resetStats(statName + ".requests"); - resetStats(statName + ".errors"); - resetStats(statName + ".sent"); - resetStats(statName + ".received"); - resetStats(statName + ".proc_time"); - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.beans.ContainerListenerBean; +import com.googlecode.psiprobe.model.Connector; + +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class ConnectorStatsCollectorBean extends AbstractStatsCollectorBean { + + private ContainerListenerBean listenerBean; + + public ContainerListenerBean getListenerBean() { + return listenerBean; + } + + public void setListenerBean(ContainerListenerBean listenerBean) { + this.listenerBean = listenerBean; + } + + public void collect() throws Exception { + List connectors = listenerBean.getConnectors(false); + for (Iterator it = connectors.iterator(); it.hasNext();) { + Connector connector = (Connector) it.next(); + String statName = "stat.connector." + connector.getName(); + buildDeltaStats(statName + ".requests", connector.getRequestCount()); + buildDeltaStats(statName + ".errors", connector.getErrorCount()); + buildDeltaStats(statName + ".sent", connector.getBytesSent()); + buildDeltaStats(statName + ".received", connector.getBytesReceived()); + buildDeltaStats(statName + ".proc_time", connector.getProcessingTime()); + } + } + + public void reset() throws Exception { + List connectors = listenerBean.getConnectors(false); + for (Iterator it = connectors.iterator(); it.hasNext();) { + Connector connector = (Connector) it.next(); + reset(connector.getName()); + } + } + + public void reset(String connectorName) { + String statName = "stat.connector." + connectorName; + resetStats(statName + ".requests"); + resetStats(statName + ".errors"); + resetStats(statName + ".sent"); + resetStats(statName + ".received"); + resetStats(statName + ".proc_time"); + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/JvmMemoryStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/JvmMemoryStatsCollectorBean.java index 432b2fcff1..4499462efe 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/JvmMemoryStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/JvmMemoryStatsCollectorBean.java @@ -1,42 +1,42 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.beans.JvmMemoryInfoAccessorBean; -import com.googlecode.psiprobe.model.jmx.MemoryPool; - -import java.util.Iterator; -import java.util.List; - -/** - * - * @author Vlad Ilyushchenko - */ -public class JvmMemoryStatsCollectorBean extends AbstractStatsCollectorBean { - private JvmMemoryInfoAccessorBean jvmMemoryInfoAccessor; - - public JvmMemoryInfoAccessorBean getJvmMemoryInfoAccessor() { - return jvmMemoryInfoAccessor; - } - - public void setJvmMemoryInfoAccessor(JvmMemoryInfoAccessorBean jvmMemoryInfoAccessor) { - this.jvmMemoryInfoAccessor = jvmMemoryInfoAccessor; - } - - public void collect() throws Exception { - List pools = jvmMemoryInfoAccessor.getPools(); - long time = System.currentTimeMillis(); - for (Iterator it = pools.iterator(); it.hasNext();) { - MemoryPool pool = (MemoryPool) it.next(); - buildAbsoluteStats("memory.pool." + pool.getName(), pool.getUsed(), time); - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.beans.JvmMemoryInfoAccessorBean; +import com.googlecode.psiprobe.model.jmx.MemoryPool; + +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Vlad Ilyushchenko + */ +public class JvmMemoryStatsCollectorBean extends AbstractStatsCollectorBean { + private JvmMemoryInfoAccessorBean jvmMemoryInfoAccessor; + + public JvmMemoryInfoAccessorBean getJvmMemoryInfoAccessor() { + return jvmMemoryInfoAccessor; + } + + public void setJvmMemoryInfoAccessor(JvmMemoryInfoAccessorBean jvmMemoryInfoAccessor) { + this.jvmMemoryInfoAccessor = jvmMemoryInfoAccessor; + } + + public void collect() throws Exception { + List pools = jvmMemoryInfoAccessor.getPools(); + long time = System.currentTimeMillis(); + for (Iterator it = pools.iterator(); it.hasNext();) { + MemoryPool pool = (MemoryPool) it.next(); + buildAbsoluteStats("memory.pool." + pool.getName(), pool.getUsed(), time); + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/RuntimeStatsCollectorBean.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/RuntimeStatsCollectorBean.java index 21144a9eb1..8afae62194 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/RuntimeStatsCollectorBean.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/collectors/RuntimeStatsCollectorBean.java @@ -1,50 +1,50 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.collectors; - -import com.googlecode.psiprobe.beans.RuntimeInfoAccessorBean; -import com.googlecode.psiprobe.model.jmx.RuntimeInformation; - -/** - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class RuntimeStatsCollectorBean extends AbstractStatsCollectorBean { - private RuntimeInfoAccessorBean runtimeInfoAccessorBean; - - public RuntimeInfoAccessorBean getRuntimeInfoAccessorBean() { - return runtimeInfoAccessorBean; - } - - public void setRuntimeInfoAccessorBean(RuntimeInfoAccessorBean runtimeInfoAccessorBean) { - this.runtimeInfoAccessorBean = runtimeInfoAccessorBean; - } - - public void collect() throws Exception { - RuntimeInformation ri = runtimeInfoAccessorBean.getRuntimeInformation(); - if (ri != null) { - long time = System.currentTimeMillis(); - buildAbsoluteStats("os.memory.committed", ri.getCommittedVirtualMemorySize() / 1024, time); - buildAbsoluteStats("os.memory.physical", - (ri.getTotalPhysicalMemorySize() - ri.getFreePhysicalMemorySize()) / 1024, time); - buildAbsoluteStats("os.memory.swap", - (ri.getTotalSwapSpaceSize() - ri.getFreeSwapSpaceSize()) / 1024, time); - - buildAbsoluteStats("os.fd.open", ri.getOpenFDCount(), time); - buildAbsoluteStats("os.fd.max", ri.getMaxFDCount(), time); - // convert from nanoseconds so times use the same units - long processCpuTimeMs = ri.getProcessCpuTime() / 1000000; - // divide by the number of processors to reflect shared load (<= 100%) - buildTimePercentageStats("os.cpu", processCpuTimeMs / ri.getAvailableProcessors(), time); - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.collectors; + +import com.googlecode.psiprobe.beans.RuntimeInfoAccessorBean; +import com.googlecode.psiprobe.model.jmx.RuntimeInformation; + +/** + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class RuntimeStatsCollectorBean extends AbstractStatsCollectorBean { + private RuntimeInfoAccessorBean runtimeInfoAccessorBean; + + public RuntimeInfoAccessorBean getRuntimeInfoAccessorBean() { + return runtimeInfoAccessorBean; + } + + public void setRuntimeInfoAccessorBean(RuntimeInfoAccessorBean runtimeInfoAccessorBean) { + this.runtimeInfoAccessorBean = runtimeInfoAccessorBean; + } + + public void collect() throws Exception { + RuntimeInformation ri = runtimeInfoAccessorBean.getRuntimeInformation(); + if (ri != null) { + long time = System.currentTimeMillis(); + buildAbsoluteStats("os.memory.committed", ri.getCommittedVirtualMemorySize() / 1024, time); + buildAbsoluteStats("os.memory.physical", + (ri.getTotalPhysicalMemorySize() - ri.getFreePhysicalMemorySize()) / 1024, time); + buildAbsoluteStats("os.memory.swap", + (ri.getTotalSwapSpaceSize() - ri.getFreeSwapSpaceSize()) / 1024, time); + + buildAbsoluteStats("os.fd.open", ri.getOpenFDCount(), time); + buildAbsoluteStats("os.fd.max", ri.getMaxFDCount(), time); + // convert from nanoseconds so times use the same units + long processCpuTimeMs = ri.getProcessCpuTime() / 1000000; + // divide by the number of processors to reflect shared load (<= 100%) + buildTimePercentageStats("os.cpu", processCpuTimeMs / ri.getAvailableProcessors(), time); + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/AbstractSeriesProvider.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/AbstractSeriesProvider.java index ca98e9b208..05466c50e1 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/AbstractSeriesProvider.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/AbstractSeriesProvider.java @@ -1,40 +1,40 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.providers; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jfree.data.xy.XYDataItem; -import org.jfree.data.xy.XYSeries; - -import java.util.List; - -/** - * - * @author Vlad Ilyushchenko - * @author Andy Shapoval - */ -public abstract class AbstractSeriesProvider implements SeriesProvider { - - protected Log logger = LogFactory.getLog(getClass()); - - protected XYSeries toSeries(String legend, List stats) { - XYSeries xySeries = new XYSeries(legend, true, false); - synchronized (stats) { - for (int i = 0; i < stats.size(); i++) { - XYDataItem item = (XYDataItem) stats.get(i); - xySeries.addOrUpdate(item.getX(), item.getY()); - } - } - return xySeries; - } - -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.providers; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYSeries; + +import java.util.List; + +/** + * + * @author Vlad Ilyushchenko + * @author Andy Shapoval + */ +public abstract class AbstractSeriesProvider implements SeriesProvider { + + protected Log logger = LogFactory.getLog(getClass()); + + protected XYSeries toSeries(String legend, List stats) { + XYSeries xySeries = new XYSeries(legend, true, false); + synchronized (stats) { + for (int i = 0; i < stats.size(); i++) { + XYDataItem item = (XYDataItem) stats.get(i); + xySeries.addOrUpdate(item.getX(), item.getY()); + } + } + return xySeries; + } + +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/ConnectorSeriesProvider.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/ConnectorSeriesProvider.java index 8e9695b2d6..d3db07b626 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/ConnectorSeriesProvider.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/ConnectorSeriesProvider.java @@ -1,47 +1,47 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.providers; - -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.data.xy.DefaultTableXYDataset; -import org.springframework.web.bind.ServletRequestUtils; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -/** - * - * @author Vlad Ilyushchenko - */ -public class ConnectorSeriesProvider extends AbstractSeriesProvider { - - public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, - HttpServletRequest request) { - - // get Connector name from the request - String connectorName = ServletRequestUtils.getStringParameter(request, "cn", null); - - // type of statistic to be displayed - String statType = ServletRequestUtils.getStringParameter(request, "st", null); - - // Series legend - String series1Legend = ServletRequestUtils.getStringParameter(request, "sl", ""); - - if (connectorName != null && statType != null) { - List l = statsCollection.getStats("stat.connector." + connectorName + "." + statType); - if (l != null) { - dataset.addSeries(toSeries(series1Legend, l)); - } - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.providers; + +import com.googlecode.psiprobe.model.stats.StatsCollection; + +import org.jfree.data.xy.DefaultTableXYDataset; +import org.springframework.web.bind.ServletRequestUtils; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author Vlad Ilyushchenko + */ +public class ConnectorSeriesProvider extends AbstractSeriesProvider { + + public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, + HttpServletRequest request) { + + // get Connector name from the request + String connectorName = ServletRequestUtils.getStringParameter(request, "cn", null); + + // type of statistic to be displayed + String statType = ServletRequestUtils.getStringParameter(request, "st", null); + + // Series legend + String series1Legend = ServletRequestUtils.getStringParameter(request, "sl", ""); + + if (connectorName != null && statType != null) { + List l = statsCollection.getStats("stat.connector." + connectorName + "." + statType); + if (l != null) { + dataset.addSeries(toSeries(series1Legend, l)); + } + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/MultipleSeriesProvider.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/MultipleSeriesProvider.java index 205b091eb6..a4827f59c3 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/MultipleSeriesProvider.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/MultipleSeriesProvider.java @@ -1,160 +1,160 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.providers; - -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.data.xy.DefaultTableXYDataset; -import org.jfree.data.xy.XYDataItem; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -/** - * Retrieves stats series with names that start with the statNamePrefix. Either all matching series - * or only "top" N ones can be retrieved. Determines top series by comparing max moving avg values. - * Derrives legend entries from series names by removing the statNamePrefix. Ignores series param - * (sp) and legend (s...l) request parameters. - * - * @author Andy Shapoval - */ -public class MultipleSeriesProvider extends AbstractSeriesProvider { - private String statNamePrefix; - private int top = 0; - private int movingAvgFrame = 0; - - public String getStatNamePrefix() { - return statNamePrefix; - } - - /** - * @param statNamePrefix - only series with names that start with statNamePrefix are retrieved. - */ - public void setStatNamePrefix(String statNamePrefix) { - this.statNamePrefix = statNamePrefix; - } - - public int getTop() { - return top; - } - - /** - * @param top - the number of top series to retrieve. If this value is greater than 0, only this - * many series with the greatest max moving avg values are retrieved. - */ - public void setTop(int top) { - this.top = top; - } - - public int getMovingAvgFrame() { - return movingAvgFrame; - } - - /** - * @param movingAvgFrame - if this value is greater than 0, a moving avg value is calculated for - * every series using every Nth value, where N % movingAvgFrame == 0. Top series are - * identified based on a max moving avg value of each series. If the movingAvgFrame equals - * to 0, top series are determined based on a simple avg of all series values. - */ - public void setMovingAvgFrame(int movingAvgFrame) { - this.movingAvgFrame = movingAvgFrame; - } - - public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, - HttpServletRequest request) { - - Map statMap = statsCollection.getStatsByPrefix(statNamePrefix); - boolean useTop = getTop() > 0 && getTop() < statMap.size(); - List seriesList = new ArrayList(); - - for (Iterator i = statMap.entrySet().iterator(); i.hasNext();) { - Series ser = new Series((Map.Entry) i.next()); - if (useTop) { - ser.calculateAvg(); - } - seriesList.add(ser); - } - - if (useTop) { - // sorting stats by the avg value to identify the top series - Collections.sort(seriesList, new Comparator() { - public int compare(Object o1, Object o2) { - Series s1 = (Series) o1; - Series s2 = (Series) o2; - return s1.avg == s2.avg ? s1.key.compareTo(s2.key) : (s1.avg > s2.avg ? -1 : 1); - } - }); - - // keeping only the top series in the list - for (ListIterator i = seriesList.listIterator(getTop()); i.hasNext();) { - i.next(); - i.remove(); - } - } - - // sorting the remaining series by name - Collections.sort(seriesList, new Comparator() { - public int compare(Object o1, Object o2) { - return (((Series) o1).key).compareTo(((Series) o2).key); - } - }); - - for (Iterator i = seriesList.iterator(); i.hasNext();) { - Series ser = (Series) i.next(); - dataset.addSeries(toSeries(ser.key, ser.stats)); - } - } - - // a helper class that holds series and calculates an avg value - private class Series { - final String key; - final List stats; - double avg = 0; - - Series(Map.Entry en) { - key = ((String) en.getKey()).substring(statNamePrefix.length()); - stats = (List) en.getValue(); - } - - // calculating an avg value that is used for identifying the top series - void calculateAvg() { - long sum = 0; - int count = 1; - - synchronized (stats) { - boolean useMovingAvg = getMovingAvgFrame() > 0 && getMovingAvgFrame() < stats.size(); - - for (Iterator i = stats.iterator(); i.hasNext();) { - XYDataItem xy = (XYDataItem) i.next(); - sum += xy.getY().longValue(); - - if ((useMovingAvg && count % getMovingAvgFrame() == 0) || !i.hasNext()) { - double a = (double) sum / count; - if (a > avg) { - avg = a; - } - sum = 0; - count = 1; - } else { - count++; - } - } - } - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.providers; + +import com.googlecode.psiprobe.model.stats.StatsCollection; + +import org.jfree.data.xy.DefaultTableXYDataset; +import org.jfree.data.xy.XYDataItem; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +/** + * Retrieves stats series with names that start with the statNamePrefix. Either all matching series + * or only "top" N ones can be retrieved. Determines top series by comparing max moving avg values. + * Derrives legend entries from series names by removing the statNamePrefix. Ignores series param + * (sp) and legend (s...l) request parameters. + * + * @author Andy Shapoval + */ +public class MultipleSeriesProvider extends AbstractSeriesProvider { + private String statNamePrefix; + private int top = 0; + private int movingAvgFrame = 0; + + public String getStatNamePrefix() { + return statNamePrefix; + } + + /** + * @param statNamePrefix - only series with names that start with statNamePrefix are retrieved. + */ + public void setStatNamePrefix(String statNamePrefix) { + this.statNamePrefix = statNamePrefix; + } + + public int getTop() { + return top; + } + + /** + * @param top - the number of top series to retrieve. If this value is greater than 0, only this + * many series with the greatest max moving avg values are retrieved. + */ + public void setTop(int top) { + this.top = top; + } + + public int getMovingAvgFrame() { + return movingAvgFrame; + } + + /** + * @param movingAvgFrame - if this value is greater than 0, a moving avg value is calculated for + * every series using every Nth value, where N % movingAvgFrame == 0. Top series are + * identified based on a max moving avg value of each series. If the movingAvgFrame equals + * to 0, top series are determined based on a simple avg of all series values. + */ + public void setMovingAvgFrame(int movingAvgFrame) { + this.movingAvgFrame = movingAvgFrame; + } + + public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, + HttpServletRequest request) { + + Map statMap = statsCollection.getStatsByPrefix(statNamePrefix); + boolean useTop = getTop() > 0 && getTop() < statMap.size(); + List seriesList = new ArrayList(); + + for (Iterator i = statMap.entrySet().iterator(); i.hasNext();) { + Series ser = new Series((Map.Entry) i.next()); + if (useTop) { + ser.calculateAvg(); + } + seriesList.add(ser); + } + + if (useTop) { + // sorting stats by the avg value to identify the top series + Collections.sort(seriesList, new Comparator() { + public int compare(Object o1, Object o2) { + Series s1 = (Series) o1; + Series s2 = (Series) o2; + return s1.avg == s2.avg ? s1.key.compareTo(s2.key) : (s1.avg > s2.avg ? -1 : 1); + } + }); + + // keeping only the top series in the list + for (ListIterator i = seriesList.listIterator(getTop()); i.hasNext();) { + i.next(); + i.remove(); + } + } + + // sorting the remaining series by name + Collections.sort(seriesList, new Comparator() { + public int compare(Object o1, Object o2) { + return (((Series) o1).key).compareTo(((Series) o2).key); + } + }); + + for (Iterator i = seriesList.iterator(); i.hasNext();) { + Series ser = (Series) i.next(); + dataset.addSeries(toSeries(ser.key, ser.stats)); + } + } + + // a helper class that holds series and calculates an avg value + private class Series { + final String key; + final List stats; + double avg = 0; + + Series(Map.Entry en) { + key = ((String) en.getKey()).substring(statNamePrefix.length()); + stats = (List) en.getValue(); + } + + // calculating an avg value that is used for identifying the top series + void calculateAvg() { + long sum = 0; + int count = 1; + + synchronized (stats) { + boolean useMovingAvg = getMovingAvgFrame() > 0 && getMovingAvgFrame() < stats.size(); + + for (Iterator i = stats.iterator(); i.hasNext();) { + XYDataItem xy = (XYDataItem) i.next(); + sum += xy.getY().longValue(); + + if ((useMovingAvg && count % getMovingAvgFrame() == 0) || !i.hasNext()) { + double a = (double) sum / count; + if (a > avg) { + avg = a; + } + sum = 0; + count = 1; + } else { + count++; + } + } + } + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/SeriesProvider.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/SeriesProvider.java index 72ac2894cc..6d04e35e30 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/SeriesProvider.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/SeriesProvider.java @@ -1,28 +1,28 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.providers; - -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.data.xy.DefaultTableXYDataset; - -import javax.servlet.http.HttpServletRequest; - -/** - * Classes implementing this interface can be wired up with RenderChartController to provide Series - * data based on StatsCollection instance. - * - * @author Vlad Ilyushchenko - */ -public interface SeriesProvider { - void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, - HttpServletRequest request); -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.providers; + +import com.googlecode.psiprobe.model.stats.StatsCollection; + +import org.jfree.data.xy.DefaultTableXYDataset; + +import javax.servlet.http.HttpServletRequest; + +/** + * Classes implementing this interface can be wired up with RenderChartController to provide Series + * data based on StatsCollection instance. + * + * @author Vlad Ilyushchenko + */ +public interface SeriesProvider { + void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, + HttpServletRequest request); +} diff --git a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/StandardSeriesProvider.java b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/StandardSeriesProvider.java index b8cedc3ea8..eaca25bfa3 100644 --- a/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/StandardSeriesProvider.java +++ b/core/src/main/java/com/googlecode/psiprobe/beans/stats/providers/StandardSeriesProvider.java @@ -1,56 +1,56 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.beans.stats.providers; - -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.data.xy.DefaultTableXYDataset; -import org.springframework.web.bind.ServletRequestUtils; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -/** - * - * @author Vlad Ilyushchenko - */ -public class StandardSeriesProvider extends AbstractSeriesProvider { - - private List statNames = new ArrayList(2); - - public List getStatNames() { - return statNames; - } - - public void setStatNames(List statNames) { - this.statNames = statNames; - } - - public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, - HttpServletRequest request) { - - String seriesParam = ServletRequestUtils.getStringParameter(request, "sp", null); - for (int i = 0; i < statNames.size(); i++) { - String statName = (String) statNames.get(i); - if (seriesParam != null) { - statName = MessageFormat.format(statName, new Object[] {seriesParam}); - } - List l = statsCollection.getStats(statName); - if (l != null) { - dataset.addSeries(toSeries( - ServletRequestUtils.getStringParameter(request, "s" + (i + 1) + "l", "series" + i), l)); - } - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.beans.stats.providers; + +import com.googlecode.psiprobe.model.stats.StatsCollection; + +import org.jfree.data.xy.DefaultTableXYDataset; +import org.springframework.web.bind.ServletRequestUtils; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author Vlad Ilyushchenko + */ +public class StandardSeriesProvider extends AbstractSeriesProvider { + + private List statNames = new ArrayList(2); + + public List getStatNames() { + return statNames; + } + + public void setStatNames(List statNames) { + this.statNames = statNames; + } + + public void populate(DefaultTableXYDataset dataset, StatsCollection statsCollection, + HttpServletRequest request) { + + String seriesParam = ServletRequestUtils.getStringParameter(request, "sp", null); + for (int i = 0; i < statNames.size(); i++) { + String statName = (String) statNames.get(i); + if (seriesParam != null) { + statName = MessageFormat.format(statName, new Object[] {seriesParam}); + } + List l = statsCollection.getStats(statName); + if (l != null) { + dataset.addSeries(toSeries( + ServletRequestUtils.getStringParameter(request, "s" + (i + 1) + "l", "series" + i), l)); + } + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/BeanToXmlController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/BeanToXmlController.java index 25cf922be9..223d3fa52f 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/BeanToXmlController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/BeanToXmlController.java @@ -1,57 +1,57 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import com.googlecode.psiprobe.model.TransportableModel; - -import com.thoughtworks.xstream.XStream; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.AbstractController; -import org.springframework.web.servlet.mvc.Controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Vlad Ilyushchenko - */ -public class BeanToXmlController extends AbstractController { - - private String xmlMarker = ".oxml"; - - public String getXmlMarker() { - return xmlMarker; - } - - public void setXmlMarker(String xmlMarker) { - this.xmlMarker = xmlMarker; - } - - protected ModelAndView handleRequestInternal(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - String path = request.getServletPath(); - String internalPath = path.replaceAll(xmlMarker, ""); - - Controller controller = (Controller) getApplicationContext().getBean(internalPath); - if (controller != null) { - ModelAndView modelAndView = controller.handleRequest(request, response); - if (modelAndView.getModel() != null) { - TransportableModel tm = new TransportableModel(); - tm.putAll(modelAndView.getModel()); - XStream x = new XStream(); - x.toXML(tm, response.getWriter()); - } - } - return null; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.controllers; + +import com.googlecode.psiprobe.model.TransportableModel; + +import com.thoughtworks.xstream.XStream; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.AbstractController; +import org.springframework.web.servlet.mvc.Controller; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Vlad Ilyushchenko + */ +public class BeanToXmlController extends AbstractController { + + private String xmlMarker = ".oxml"; + + public String getXmlMarker() { + return xmlMarker; + } + + public void setXmlMarker(String xmlMarker) { + this.xmlMarker = xmlMarker; + } + + protected ModelAndView handleRequestInternal(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String path = request.getServletPath(); + String internalPath = path.replaceAll(xmlMarker, ""); + + Controller controller = (Controller) getApplicationContext().getBean(internalPath); + if (controller != null) { + ModelAndView modelAndView = controller.handleRequest(request, response); + if (modelAndView.getModel() != null) { + TransportableModel tm = new TransportableModel(); + tm.putAll(modelAndView.getModel()); + XStream x = new XStream(); + x.toXML(tm, response.getWriter()); + } + } + return null; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/ContextHandlerController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/ContextHandlerController.java index 8f939350b2..d775de0ad5 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/ContextHandlerController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/ContextHandlerController.java @@ -1,58 +1,58 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import org.apache.catalina.Context; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Base class for all controllers requiring "webapp" request parameter. - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public abstract class ContextHandlerController extends TomcatContainerController { - - protected ModelAndView handleRequestInternal(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - String contextName = ServletRequestUtils.getStringParameter(request, "webapp", null); - Context context = null; - if (contextName != null) { - contextName = getContainerWrapper().getTomcatContainer().formatContextName(contextName); - context = getContainerWrapper().getTomcatContainer().findContext(contextName); - } - - if (context != null || isContextOptional()) { - return handleContext(contextName, context, request, response); - } else { - if (contextName != null) { - request.setAttribute( - "errorMessage", - getMessageSourceAccessor().getMessage("probe.src.contextDoesntExist", - new Object[] {contextName})); - } - - return new ModelAndView("errors/paramerror"); - } - } - - protected boolean isContextOptional() { - return false; - } - - protected abstract ModelAndView handleContext(String contextName, Context context, - HttpServletRequest request, HttpServletResponse response) throws Exception; -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.controllers; + +import org.apache.catalina.Context; +import org.springframework.web.bind.ServletRequestUtils; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Base class for all controllers requiring "webapp" request parameter. + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public abstract class ContextHandlerController extends TomcatContainerController { + + protected ModelAndView handleRequestInternal(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String contextName = ServletRequestUtils.getStringParameter(request, "webapp", null); + Context context = null; + if (contextName != null) { + contextName = getContainerWrapper().getTomcatContainer().formatContextName(contextName); + context = getContainerWrapper().getTomcatContainer().findContext(contextName); + } + + if (context != null || isContextOptional()) { + return handleContext(contextName, context, request, response); + } else { + if (contextName != null) { + request.setAttribute( + "errorMessage", + getMessageSourceAccessor().getMessage("probe.src.contextDoesntExist", + new Object[] {contextName})); + } + + return new ModelAndView("errors/paramerror"); + } + } + + protected boolean isContextOptional() { + return false; + } + + protected abstract ModelAndView handleContext(String contextName, Context context, + HttpServletRequest request, HttpServletResponse response) throws Exception; +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/DecoratorController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/DecoratorController.java index ae409d1a84..f037ef441f 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/DecoratorController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/DecoratorController.java @@ -1,96 +1,96 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import com.googlecode.psiprobe.UptimeListener; -import com.googlecode.psiprobe.Utils; - -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.ParameterizableViewController; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Properties; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Vlad Ilyushchenko - */ -public class DecoratorController extends ParameterizableViewController { - - private String messagesBasename; - - public String getMessagesBasename() { - return messagesBasename; - } - - public void setMessagesBasename(String messagesBasename) { - this.messagesBasename = messagesBasename; - } - - protected ModelAndView handleRequestInternal(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - request.setAttribute("hostname", InetAddress.getLocalHost().getHostName()); - } catch (UnknownHostException e) { - request.setAttribute("hostname", "unknown"); - } - - Properties version = (Properties) getApplicationContext().getBean("version"); - request.setAttribute("version", version.getProperty("probe.version")); - - Object uptimeStart = getServletContext().getAttribute(UptimeListener.START_TIME_KEY); - if (uptimeStart != null && uptimeStart instanceof Long) { - long l = ((Long) uptimeStart).longValue(); - long uptime = System.currentTimeMillis() - l; - long uptime_days = uptime / (1000 * 60 * 60 * 24); - - uptime = uptime % (1000 * 60 * 60 * 24); - long uptime_hours = uptime / (1000 * 60 * 60); - - uptime = uptime % (1000 * 60 * 60); - long uptime_mins = uptime / (1000 * 60); - - request.setAttribute("uptime_days", new Long(uptime_days)); - request.setAttribute("uptime_hours", new Long(uptime_hours)); - request.setAttribute("uptime_mins", new Long(uptime_mins)); - } - - // - // Work out the language of the interface by matching resource files that we have - // to the request locale. - // - List fileNames = getMessageFileNamesForLocale(request.getLocale()); - String lang = "en"; - for (Iterator it = fileNames.iterator(); it.hasNext();) { - String f = (String) it.next(); - if (getServletContext().getResource(f + ".properties") != null) { - lang = f.substring(messagesBasename.length() + 1); - break; - } - } - - request.setAttribute("lang", lang); - - return super.handleRequestInternal(request, response); - } - - private List getMessageFileNamesForLocale(Locale locale) { - return Utils.getNamesForLocale(messagesBasename, locale); - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.controllers; + +import com.googlecode.psiprobe.UptimeListener; +import com.googlecode.psiprobe.Utils; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.ParameterizableViewController; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Vlad Ilyushchenko + */ +public class DecoratorController extends ParameterizableViewController { + + private String messagesBasename; + + public String getMessagesBasename() { + return messagesBasename; + } + + public void setMessagesBasename(String messagesBasename) { + this.messagesBasename = messagesBasename; + } + + protected ModelAndView handleRequestInternal(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + try { + request.setAttribute("hostname", InetAddress.getLocalHost().getHostName()); + } catch (UnknownHostException e) { + request.setAttribute("hostname", "unknown"); + } + + Properties version = (Properties) getApplicationContext().getBean("version"); + request.setAttribute("version", version.getProperty("probe.version")); + + Object uptimeStart = getServletContext().getAttribute(UptimeListener.START_TIME_KEY); + if (uptimeStart != null && uptimeStart instanceof Long) { + long l = ((Long) uptimeStart).longValue(); + long uptime = System.currentTimeMillis() - l; + long uptime_days = uptime / (1000 * 60 * 60 * 24); + + uptime = uptime % (1000 * 60 * 60 * 24); + long uptime_hours = uptime / (1000 * 60 * 60); + + uptime = uptime % (1000 * 60 * 60); + long uptime_mins = uptime / (1000 * 60); + + request.setAttribute("uptime_days", new Long(uptime_days)); + request.setAttribute("uptime_hours", new Long(uptime_hours)); + request.setAttribute("uptime_mins", new Long(uptime_mins)); + } + + // + // Work out the language of the interface by matching resource files that we have + // to the request locale. + // + List fileNames = getMessageFileNamesForLocale(request.getLocale()); + String lang = "en"; + for (Iterator it = fileNames.iterator(); it.hasNext();) { + String f = (String) it.next(); + if (getServletContext().getResource(f + ".properties") != null) { + lang = f.substring(messagesBasename.length() + 1); + break; + } + } + + request.setAttribute("lang", lang); + + return super.handleRequestInternal(request, response); + } + + private List getMessageFileNamesForLocale(Locale locale) { + return Utils.getNamesForLocale(messagesBasename, locale); + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/ErrorHandlerController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/ErrorHandlerController.java index 8535e2b3cd..7b537e3132 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/ErrorHandlerController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/ErrorHandlerController.java @@ -1,64 +1,64 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.AbstractController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * The ErrorHandlerController will show two different views depending on whether the failed request - * was AJAX or not. - * - * @author Vlad Ilyushchenko. - */ -public class ErrorHandlerController extends AbstractController { - private String viewName; - private String ajaxViewName; - private String ajaxExtension = ".ajax"; - - public String getViewName() { - return viewName; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } - - public String getAjaxViewName() { - return ajaxViewName; - } - - public void setAjaxViewName(String ajaxViewName) { - this.ajaxViewName = ajaxViewName; - } - - public String getAjaxExtension() { - return ajaxExtension; - } - - public void setAjaxExtension(String ajaxExtension) { - this.ajaxExtension = ajaxExtension; - } - - protected ModelAndView handleRequestInternal(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - String originalURI = (String) request.getAttribute("javax.servlet.error.request_uri"); - if (originalURI != null && originalURI.endsWith(ajaxExtension)) { - return new ModelAndView(ajaxViewName); - } else { - return new ModelAndView(viewName); - } - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.controllers; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.AbstractController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * The ErrorHandlerController will show two different views depending on whether the failed request + * was AJAX or not. + * + * @author Vlad Ilyushchenko. + */ +public class ErrorHandlerController extends AbstractController { + private String viewName; + private String ajaxViewName; + private String ajaxExtension = ".ajax"; + + public String getViewName() { + return viewName; + } + + public void setViewName(String viewName) { + this.viewName = viewName; + } + + public String getAjaxViewName() { + return ajaxViewName; + } + + public void setAjaxViewName(String ajaxViewName) { + this.ajaxViewName = ajaxViewName; + } + + public String getAjaxExtension() { + return ajaxExtension; + } + + public void setAjaxExtension(String ajaxExtension) { + this.ajaxExtension = ajaxExtension; + } + + protected ModelAndView handleRequestInternal(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String originalURI = (String) request.getAttribute("javax.servlet.error.request_uri"); + if (originalURI != null && originalURI.endsWith(ajaxExtension)) { + return new ModelAndView(ajaxViewName); + } else { + return new ModelAndView(viewName); + } + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/RememberVisibilityController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/RememberVisibilityController.java index 204d706703..8bb555ca8a 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/RememberVisibilityController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/RememberVisibilityController.java @@ -1,49 +1,49 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import com.googlecode.psiprobe.jsp.Functions; - -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.AbstractController; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Vlad Ilyushchenko - * @author Mark Lewis - */ -public class RememberVisibilityController extends AbstractController { - - private final SimpleDateFormat sdf = new SimpleDateFormat("E, d-MMM-yyyy HH:mm:ss zz"); - - protected ModelAndView handleRequestInternal(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - String cookieName = ServletRequestUtils.getStringParameter(request, "cn"); - String state = ServletRequestUtils.getStringParameter(request, "state"); - if (cookieName != null && state != null) { - cookieName = Functions.safeCookieName(cookieName); - // expire the cookis at the current date + 10years (roughly, nevermind leap years) - response.addHeader( - "Set-Cookie", - cookieName + "=" + state + "; Expires=" - + sdf.format(new Date(System.currentTimeMillis() + 315360000000L))); - } - return null; - } -} +/* + * Licensed under the GPL License. You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +package com.googlecode.psiprobe.controllers; + +import com.googlecode.psiprobe.jsp.Functions; + +import org.springframework.web.bind.ServletRequestUtils; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.AbstractController; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Vlad Ilyushchenko + * @author Mark Lewis + */ +public class RememberVisibilityController extends AbstractController { + + private final SimpleDateFormat sdf = new SimpleDateFormat("E, d-MMM-yyyy HH:mm:ss zz"); + + protected ModelAndView handleRequestInternal(HttpServletRequest request, + HttpServletResponse response) throws Exception { + + String cookieName = ServletRequestUtils.getStringParameter(request, "cn"); + String state = ServletRequestUtils.getStringParameter(request, "state"); + if (cookieName != null && state != null) { + cookieName = Functions.safeCookieName(cookieName); + // expire the cookis at the current date + 10years (roughly, nevermind leap years) + response.addHeader( + "Set-Cookie", + cookieName + "=" + state + "; Expires=" + + sdf.format(new Date(System.currentTimeMillis() + 315360000000L))); + } + return null; + } +} diff --git a/core/src/main/java/com/googlecode/psiprobe/controllers/RenderChartController.java b/core/src/main/java/com/googlecode/psiprobe/controllers/RenderChartController.java index 2d3496b0a0..6b061d578b 100644 --- a/core/src/main/java/com/googlecode/psiprobe/controllers/RenderChartController.java +++ b/core/src/main/java/com/googlecode/psiprobe/controllers/RenderChartController.java @@ -1,182 +1,182 @@ -/* - * Licensed under the GPL License. You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ -package com.googlecode.psiprobe.controllers; - -import com.googlecode.psiprobe.Utils; -import com.googlecode.psiprobe.beans.stats.providers.SeriesProvider; -import com.googlecode.psiprobe.model.stats.StatsCollection; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartUtilities; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.axis.DateAxis; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.renderer.xy.XYAreaRenderer; -import org.jfree.chart.renderer.xy.XYLine3DRenderer; -import org.jfree.data.xy.DefaultTableXYDataset; -import org.jfree.ui.RectangleInsets; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.AbstractController; - -import java.awt.BasicStroke; -import java.awt.Color; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Plots data from "statsCollection" bean. The data is converted to XYSeries using SeriesProvider, - * name of which would be passed as a request parameter. The servlet can only plot up to 9 series. - * It is customizable using these request parameters: - *