Weiterer Teil Umstellung webdevSupport von sitenode type auf legacy free application.
git-svn-id: https://svn.libreccm.org/ccm/trunk@1514 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
6232654cda
commit
9cc5a910f9
|
|
@ -24,9 +24,10 @@ import com.arsdigita.util.Lockable;
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common interface implemented by all Bebop
|
* The common interface implemented by all Bebop components.
|
||||||
* components. During its lifetime, a component receives the following
|
*
|
||||||
* calls from the containing page.
|
* During its lifetime, a component receives the following calls
|
||||||
|
* from the containing page.
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> During initialization/creation of the containing page:
|
* <li> During initialization/creation of the containing page:
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ package com.arsdigita.bebop;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common interface that is implemented by all
|
* The common interface that is implemented by all Bebop containers.
|
||||||
* Bebop containers. The Container interface extends the Component
|
*
|
||||||
* interface. A container is simply a component that contains other
|
* The Container interface extends the Component interface. A container is
|
||||||
* components.
|
* simply a component that contains other components.
|
||||||
*
|
*
|
||||||
* @author David Lutterkort
|
* @author David Lutterkort
|
||||||
* @author Uday Mathur
|
* @author Uday Mathur
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <P>The top-level container for all Bebop components and
|
* <p>The top-level container for all Bebop components and containers. </p>
|
||||||
* containers. </P>
|
*
|
||||||
* <UL>
|
* <UL>
|
||||||
* <LI>Holds references to the components of a page.</LI>
|
* <LI>Holds references to the components of a page.</LI>
|
||||||
* <LI>Provides methods for servicing requests and for notifying
|
* <LI>Provides methods for servicing requests and for notifying
|
||||||
|
|
@ -249,6 +249,7 @@ public class Page extends BlockStylable implements Container {
|
||||||
// request will be kept
|
// request will be kept
|
||||||
m_currentTitle = new RequestLocal() {
|
m_currentTitle = new RequestLocal() {
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Object initialValue(PageState state) {
|
protected Object initialValue(PageState state) {
|
||||||
return m_title.firePrintEvent(state);
|
return m_title.firePrintEvent(state);
|
||||||
}
|
}
|
||||||
|
|
@ -400,6 +401,7 @@ public class Page extends BlockStylable implements Container {
|
||||||
return m_panel.size();
|
return m_panel.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Iterator children() {
|
public Iterator children() {
|
||||||
return Collections.singletonList(m_panel).iterator();
|
return Collections.singletonList(m_panel).iterator();
|
||||||
}
|
}
|
||||||
|
|
@ -498,29 +500,6 @@ public class Page extends BlockStylable implements Container {
|
||||||
return m_errorDisplay;
|
return m_errorDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Sets a stylesheet that should be used in HTML output. To use
|
|
||||||
// * a CSS stylesheet, call something like
|
|
||||||
// * <code>setStyleSheet("style.css", "text/css")</code>.
|
|
||||||
// * <p>
|
|
||||||
// * These values will ultimately wind up in a <tt><link></tt> tag in
|
|
||||||
// * the head of the HTML page.
|
|
||||||
// * <p>
|
|
||||||
// * Note that the stylesheet set with this call has nothing to do with the
|
|
||||||
// * XSLT stylesheet (transformer) that is applied to the XML generated
|
|
||||||
// * from this page.
|
|
||||||
// *
|
|
||||||
// * @param styleSheetURI the location of the stylesheet
|
|
||||||
// * @param styleSheetType the MIME type of the stylesheet, usually
|
|
||||||
// * <tt>text/css</tt>
|
|
||||||
// * @pre ! isLocked()
|
|
||||||
// * @deprecated Use {@link #addClientStylesheet addClientStylesheet}
|
|
||||||
// * instead. Will be removed on 2001-05-31.
|
|
||||||
// */
|
|
||||||
// public void setStyleSheet(String styleSheetURI, String styleSheetType) {
|
|
||||||
// Assert.isUnlocked(this);
|
|
||||||
// addClientStylesheet(styleSheetURI, styleSheetType);
|
|
||||||
// }
|
|
||||||
/**
|
/**
|
||||||
* Adds a client-side stylesheet that should be used in HTML
|
* Adds a client-side stylesheet that should be used in HTML
|
||||||
* output. Arbitrarily many client-side stylesheets can be added with
|
* output. Arbitrarily many client-side stylesheets can be added with
|
||||||
|
|
@ -532,7 +511,7 @@ public class Page extends BlockStylable implements Container {
|
||||||
*
|
*
|
||||||
* <p> Note that the stylesheet set with this call has nothing to do with
|
* <p> Note that the stylesheet set with this call has nothing to do with
|
||||||
* the XSLT stylesheet (transformer) that is applied to the XML generated
|
* the XSLT stylesheet (transformer) that is applied to the XML generated
|
||||||
* from this page.
|
* from this page!
|
||||||
*
|
*
|
||||||
* @param styleSheetURI the location of the stylesheet
|
* @param styleSheetURI the location of the stylesheet
|
||||||
* @param mimeType the MIME type of the stylesheet, usually
|
* @param mimeType the MIME type of the stylesheet, usually
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,20 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A common servlet to provide a generic URL-to-Bebop-Page map based dispatch
|
||||||
|
* pattern.
|
||||||
|
* It provides methods to setup a url - page map. The doService method uses
|
||||||
|
* the request's URL to determine the page to display and forwards to the
|
||||||
|
* presentation manager for the Page handling.
|
||||||
|
*
|
||||||
|
* This class is a servlet based version of BebopMapDispatcher and associated
|
||||||
|
* classes and is generally used in the same way by legacy free applications.
|
||||||
|
*
|
||||||
|
* Subclasses usually overwrite the doService method to create Page objects
|
||||||
|
* and use this.put method to construct the mapping.
|
||||||
|
*
|
||||||
|
* Subclasses may overwrite the doService method to add additional functionality,
|
||||||
|
* e.g. permission checking.
|
||||||
*
|
*
|
||||||
* @author Justin Ross <jross@redhat.com>
|
* @author Justin Ross <jross@redhat.com>
|
||||||
* @author chris gilbert - allow BebopApplicationServlet pages to disable
|
* @author chris gilbert - allow BebopApplicationServlet pages to disable
|
||||||
|
|
@ -53,12 +67,18 @@ public class BebopApplicationServlet extends BaseApplicationServlet {
|
||||||
private static final Logger s_log = Logger.getLogger
|
private static final Logger s_log = Logger.getLogger
|
||||||
(BebopApplicationServlet.class);
|
(BebopApplicationServlet.class);
|
||||||
|
|
||||||
// String pathInfo => Page page
|
/** URL (pathinfo) -> Page object mapping. Based on it (and the http
|
||||||
|
* request url) the doService method to selects a page to display */
|
||||||
private final Map m_pages = new HashMap();
|
private final Map m_pages = new HashMap();
|
||||||
// Set of pathinfo
|
// Set of pathinfo
|
||||||
private final Set m_clientCacheDisabledPages = new HashSet();
|
private final Set m_clientCacheDisabledPages = new HashSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Initializer uses parent class's initializer to setup the servlet request /
|
||||||
|
* response and application context. Usually a user of this class will NOT
|
||||||
|
* overwrite this method but the user extension point doInit() to perform
|
||||||
|
* local initialization tasks, in case of this servlet typically to setup
|
||||||
|
* the page-url mapping using the provided mapping methods of this class.
|
||||||
*
|
*
|
||||||
* @throws ServletException
|
* @throws ServletException
|
||||||
*/
|
*/
|
||||||
|
|
@ -68,15 +88,29 @@ public class BebopApplicationServlet extends BaseApplicationServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* User extension point, overwrite this method to setup a URL - page mapping
|
||||||
*
|
*
|
||||||
* @param pathInfo
|
* @throws ServletException
|
||||||
* @param page
|
*/
|
||||||
|
@Override
|
||||||
|
public void doInit() throws ServletException {
|
||||||
|
// nothing here
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds one Url-Page mapping to the internal mapping table.
|
||||||
|
*
|
||||||
|
* @param pathInfo url stub for a page to display
|
||||||
|
* @param page Page object to display
|
||||||
*/
|
*/
|
||||||
protected final void put(final String pathInfo,
|
protected final void put(final String pathInfo,
|
||||||
final Page page) {
|
final Page page) {
|
||||||
Assert.exists(pathInfo, String.class);
|
Assert.exists(pathInfo, String.class);
|
||||||
Assert.exists(page, Page.class);
|
Assert.exists(page, Page.class);
|
||||||
Assert.isTrue(pathInfo.startsWith("/"), "path starts with '/'");
|
// Current Implementation requires pathInfo to start with a leading '/'
|
||||||
|
// SUN Servlet API specifies: "PathInfo *may be empty* or will start
|
||||||
|
// with a '/' character."
|
||||||
|
Assert.isTrue(pathInfo.startsWith("/"), "path starts not with '/'");
|
||||||
|
|
||||||
m_pages.put(pathInfo, page);
|
m_pages.put(pathInfo, page);
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +128,9 @@ public class BebopApplicationServlet extends BaseApplicationServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Main processing unit searches in the page map for the request's url
|
||||||
|
* and forwards the page to display to the appropriate presentation
|
||||||
|
* manager to serve the page.
|
||||||
*
|
*
|
||||||
* @param sreq
|
* @param sreq
|
||||||
* @param sresp
|
* @param sresp
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,13 @@ import org.apache.log4j.Logger;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common base class for a generic URL-to-Bebop-Page dispatching pattern.
|
* Common base class for a generic URL-to-Bebop-Page dispatching pattern. This
|
||||||
|
* class provides methods to setup a url - page map. URL is used as a key to a
|
||||||
|
* dispatcher type class whose dispatch() method will provide the Page handling.
|
||||||
|
*
|
||||||
|
* Dispatching is done by the parent class on a general url - dispatcher class
|
||||||
|
* mapping.
|
||||||
|
*
|
||||||
* This class may be used directly by applications, or it may be subclassed
|
* This class may be used directly by applications, or it may be subclassed
|
||||||
* to be coded with a specific map or to override the map lookup for certain
|
* to be coded with a specific map or to override the map lookup for certain
|
||||||
* sets of URLs.
|
* sets of URLs.
|
||||||
|
|
@ -53,8 +59,8 @@ public class BebopMapDispatcher extends MapDispatcher {
|
||||||
public BebopMapDispatcher() {
|
public BebopMapDispatcher() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
//mount the confirmation page
|
|
||||||
Map m = new HashMap();
|
Map m = new HashMap();
|
||||||
|
//mount the confirmation page
|
||||||
m.put(ConfirmPage.CONFIRM_URL, new ConfirmPage());
|
m.put(ConfirmPage.CONFIRM_URL, new ConfirmPage());
|
||||||
setMap(m);
|
setMap(m);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,14 @@ import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for
|
* Base class for a generic URL-to-Dispatcher mapping dispatch. This class may
|
||||||
* a generic URL-to-Dispatcher mapping dispatch. This class may
|
* be used directly by applications, or it may be subclassed to be coded with
|
||||||
* be used directly by applications, or it may be subclassed to
|
* a specific map or override the map lookup for certain sets of URLs.
|
||||||
* be coded with a specific
|
|
||||||
* map or override the map lookup for certain sets of URLs.
|
|
||||||
* <p>
|
* <p>
|
||||||
* URLs are mapped to Dispatcher objects. When the dispatch method is called,
|
* URLs are mapped to Dispatcher objects. When the dispatch method is called,
|
||||||
* this first looks up the remainingURL (from the request context) in the map and
|
* this first looks up the remainingURL (from the request context) in the map
|
||||||
* dispatches to the target object. Then we call
|
* and dispatches to the target object. Then we call the dispatch method on
|
||||||
* the dispatch method on the target.
|
* the target.
|
||||||
*
|
*
|
||||||
* <p>A configurable "not found" dispatcher is available to handle the case
|
* <p>A configurable "not found" dispatcher is available to handle the case
|
||||||
* where no target is mapped for a URL. By default, this is set to
|
* where no target is mapped for a URL. By default, this is set to
|
||||||
|
|
@ -55,9 +53,9 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||||
* exact mapping. If a not-found handler is specified, it is up to this
|
* exact mapping. If a not-found handler is specified, it is up to this
|
||||||
* specified dispatcher to set the status code appropriately.
|
* specified dispatcher to set the status code appropriately.
|
||||||
*
|
*
|
||||||
* <p>Note that any URLs that do not have a file extension will
|
* <p>Note that any URLs that do not have a file extension will automatically
|
||||||
* automatically be required to have a trailing slash. Your relative
|
* be required to have a trailing slash. Your relative links MUST COMPENSATE
|
||||||
* links must compensate for this.
|
* for this.
|
||||||
*
|
*
|
||||||
* <p>Example: Assume we set up a map dispatcher as follows:
|
* <p>Example: Assume we set up a map dispatcher as follows:
|
||||||
* <pre>
|
* <pre>
|
||||||
|
|
@ -100,8 +98,9 @@ public class MapDispatcher implements Dispatcher {
|
||||||
private static final Logger s_log =
|
private static final Logger s_log =
|
||||||
Logger.getLogger(MapDispatcher.class.getName());
|
Logger.getLogger(MapDispatcher.class.getName());
|
||||||
|
|
||||||
/* Creates MapDispatcher with empty URL mapped to "/".
|
/**
|
||||||
**/
|
* Constructor creates MapDispatcher with empty URL mapped to "/".
|
||||||
|
*/
|
||||||
public MapDispatcher() {
|
public MapDispatcher() {
|
||||||
m_notFoundHandler = JSPApplicationDispatcher.getInstance();
|
m_notFoundHandler = JSPApplicationDispatcher.getInstance();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -454,27 +454,29 @@ public class CoreLoader extends PackageLoader {
|
||||||
|
|
||||||
private void loadWebDev() {
|
private void loadWebDev() {
|
||||||
// Add the package type to the database
|
// Add the package type to the database
|
||||||
/*
|
|
||||||
PackageType packType = PackageType.create
|
|
||||||
("webdev-support", "WebDeveloper Support", "WebDeveloper Supports",
|
|
||||||
"http://arsdigita.com/webdev-support");
|
|
||||||
|
|
||||||
// Add the node and the package instance on that node.
|
/* LEGACY COMPATIBLE application type */
|
||||||
SiteNode node = SiteNode.createSiteNode("ds");
|
|
||||||
// Specify the URL stub for this package instance.
|
|
||||||
node.mountPackage(packType.createInstance("webdev-support"));
|
|
||||||
|
|
||||||
// Map the package type to a dispatcher class
|
|
||||||
packType.setDispatcherClass("com.arsdigita.webdevsupport.Dispatcher");
|
|
||||||
*/
|
|
||||||
ApplicationType webDevType = ApplicationType
|
ApplicationType webDevType = ApplicationType
|
||||||
.createApplicationType("webdev-support",
|
.createApplicationType("webdev-support",
|
||||||
"WebDeveloper Support",
|
"WebDeveloper Support",
|
||||||
WebDevSupport.BASE_DATA_OBJECT_TYPE);
|
WebDevSupport.BASE_DATA_OBJECT_TYPE);
|
||||||
webDevType.setDispatcherClass("com.arsdigita.webdevsupport.Dispatcher");
|
webDevType.setDispatcherClass("com.arsdigita.webdevsupport.Dispatcher");
|
||||||
|
|
||||||
|
/* LEGACY FREE application type */
|
||||||
|
// ApplicationType webDevType =
|
||||||
|
// new ApplicationType("WebDev Support",
|
||||||
|
// WebDevSupport.BASE_DATA_OBJECT_TYPE );
|
||||||
|
|
||||||
|
|
||||||
|
/* Legacy free / compatible INDEPENDENT application properties */
|
||||||
webDevType.setDescription("WebDeveloper Support application");
|
webDevType.setDescription("WebDeveloper Support application");
|
||||||
webDevType.save();
|
webDevType.save();
|
||||||
|
|
||||||
|
|
||||||
|
// create application instance as a legacy free or legacy comp. app.
|
||||||
|
// Whether a legacy compatible or a legacy free application is
|
||||||
|
// created depends on the type of ApplicationType above. No need to
|
||||||
|
// modify anything here
|
||||||
Application webDev = Application.createApplication(webDevType,
|
Application webDev = Application.createApplication(webDevType,
|
||||||
"ds",
|
"ds",
|
||||||
"WebDeveloper Support",
|
"WebDeveloper Support",
|
||||||
|
|
@ -482,9 +484,6 @@ public class CoreLoader extends PackageLoader {
|
||||||
webDev.setDescription("The default WEB developer service instance.");
|
webDev.setDescription("The default WEB developer service instance.");
|
||||||
webDev.save();
|
webDev.save();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Application loadAdminApp() {
|
private Application loadAdminApp() {
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,17 @@ public abstract class BaseServlet extends HttpServlet {
|
||||||
|
|
||||||
private static Logger s_log = Logger.getLogger(BaseServlet.class);
|
private static Logger s_log = Logger.getLogger(BaseServlet.class);
|
||||||
|
|
||||||
/**
|
/** The name of the request attribute used to store the originally
|
||||||
* The name of the request attribute used to store the originally
|
* requested URL. */
|
||||||
* requested URL.
|
|
||||||
*/
|
|
||||||
public static final String REQUEST_URL_ATTRIBUTE =
|
public static final String REQUEST_URL_ATTRIBUTE =
|
||||||
BaseServlet.class.getName() + ".request_url";
|
BaseServlet.class.getName() + ".request_url";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializer uses parent class's initializer to setup the servlet request /
|
||||||
|
* response and application context. Usually a user of this class will not
|
||||||
|
* overwrite this method but the user extension point doInit to perform
|
||||||
|
* local initialization tasks.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init(final ServletConfig sconfig) throws ServletException {
|
public void init(final ServletConfig sconfig) throws ServletException {
|
||||||
if (s_log.isInfoEnabled()) {
|
if (s_log.isInfoEnabled()) {
|
||||||
|
|
|
||||||
|
|
@ -64,15 +64,18 @@ import com.arsdigita.web.URL;
|
||||||
import com.arsdigita.webdevsupport.log4j.CategoryPanel;
|
import com.arsdigita.webdevsupport.log4j.CategoryPanel;
|
||||||
import com.arsdigita.webdevsupport.config.ConfigList;
|
import com.arsdigita.webdevsupport.config.ConfigList;
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -83,22 +86,23 @@ import org.apache.log4j.Logger;
|
||||||
*
|
*
|
||||||
* @author Joseph A. Bank (jbank@alum.mit.edu)
|
* @author Joseph A. Bank (jbank@alum.mit.edu)
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
**/
|
* @version $Id: Dispatcher.java 1460 2007-03-02 14:36:38Z sskracic $
|
||||||
|
*/
|
||||||
public class Dispatcher extends BebopMapDispatcher {
|
public class Dispatcher extends BebopMapDispatcher {
|
||||||
|
|
||||||
private static final Logger s_log =
|
private static final Logger s_log =
|
||||||
Logger.getLogger(Dispatcher.class.getName());
|
Logger.getLogger(Dispatcher.class.getName());
|
||||||
|
|
||||||
public static final String APP_NAME = "ds";
|
public static final String APP_NAME = "ds";
|
||||||
|
|
||||||
public static final String versionId =
|
|
||||||
"$Id: Dispatcher.java 1460 2007-03-02 14:36:38Z sskracic $" +
|
|
||||||
" by $Author: sskracic $, " +
|
|
||||||
"$DateTime: 2004/08/16 18:10:38 $";
|
|
||||||
|
|
||||||
private static boolean s_showDSPages = false;
|
private static boolean s_showDSPages = false;
|
||||||
|
|
||||||
private final static String CACHE_TABLE_URL = "cache-table";
|
private final static String CACHE_TABLE_URL = "cache-table";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor builds the various Developer Support Pages and creates the
|
||||||
|
* corresponding URL - Page mapping.
|
||||||
|
*/
|
||||||
public Dispatcher() {
|
public Dispatcher() {
|
||||||
super();
|
super();
|
||||||
Map m = new HashMap();
|
Map m = new HashMap();
|
||||||
|
|
@ -115,20 +119,35 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
m.put("config", buildConfigPage());
|
m.put("config", buildConfigPage());
|
||||||
m.put(CACHE_TABLE_URL, buildCacheTablePage());
|
m.put(CACHE_TABLE_URL, buildCacheTablePage());
|
||||||
|
|
||||||
/** The rest of the URLs go here with more
|
/* The rest of the URLs go here with more
|
||||||
* m_put statements.
|
* m_put statements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Make the created map operational */
|
||||||
setMap(m);
|
setMap(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrites parent's dispatch method to add permission checking. If
|
||||||
|
* required permissions are granted dispatching is delegatged to parent.
|
||||||
|
* @param req
|
||||||
|
* @param resp
|
||||||
|
* @param ctx
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ServletException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void dispatch(HttpServletRequest req,
|
public void dispatch(HttpServletRequest req,
|
||||||
HttpServletResponse resp,
|
HttpServletResponse resp,
|
||||||
RequestContext ctx)
|
RequestContext ctx)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
|
/* Determine access priviledge, only logged in users may access DS */
|
||||||
Party party = Kernel.getContext().getParty();
|
Party party = Kernel.getContext().getParty();
|
||||||
if (party == null) {
|
if (party == null) {
|
||||||
throw new LoginSignal(req);
|
throw new LoginSignal(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
SiteNode node = ((SiteNodeRequestContext)ctx).getSiteNode();
|
SiteNode node = ((SiteNodeRequestContext)ctx).getSiteNode();
|
||||||
PermissionDescriptor admin = new PermissionDescriptor
|
PermissionDescriptor admin = new PermissionDescriptor
|
||||||
(PrivilegeDescriptor.ADMIN, node, party);
|
(PrivilegeDescriptor.ADMIN, node, party);
|
||||||
|
|
@ -144,6 +163,10 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return index Page object
|
||||||
|
*/
|
||||||
private Page buildIndexPage() {
|
private Page buildIndexPage() {
|
||||||
Page p = PageFactory.buildPage(APP_NAME, "Web Developer Support");
|
Page p = PageFactory.buildPage(APP_NAME, "Web Developer Support");
|
||||||
|
|
||||||
|
|
@ -154,8 +177,10 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
links.add(new Link("Cache Table Browser", CACHE_TABLE_URL));
|
links.add(new Link("Cache Table Browser", CACHE_TABLE_URL));
|
||||||
|
|
||||||
ActionLink enable = new ActionLink("Enable request logging") {
|
ActionLink enable = new ActionLink("Enable request logging") {
|
||||||
|
@Override
|
||||||
public boolean isVisible(PageState state) {
|
public boolean isVisible(PageState state) {
|
||||||
return !DeveloperSupport.containsListener(WebDevSupportListener.getInstance())
|
return !DeveloperSupport.containsListener(
|
||||||
|
WebDevSupportListener.getInstance())
|
||||||
&& super.isVisible(state);
|
&& super.isVisible(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -171,11 +196,14 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
|
|
||||||
|
|
||||||
ActionLink disable = new ActionLink("Disable request logging") {
|
ActionLink disable = new ActionLink("Disable request logging") {
|
||||||
|
@Override
|
||||||
public boolean isVisible(PageState state) {
|
public boolean isVisible(PageState state) {
|
||||||
return DeveloperSupport.containsListener(WebDevSupportListener.getInstance())
|
return DeveloperSupport.containsListener(
|
||||||
|
WebDevSupportListener.getInstance())
|
||||||
&& super.isVisible(state);
|
&& super.isVisible(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
disable.addActionListener(new ActionListener() {
|
disable.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
DeveloperSupport.removeListener(WebDevSupportListener.getInstance());
|
DeveloperSupport.removeListener(WebDevSupportListener.getInstance());
|
||||||
|
|
@ -225,6 +253,10 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return log4j Page object
|
||||||
|
*/
|
||||||
private Page buildLog4jPage() {
|
private Page buildLog4jPage() {
|
||||||
Page p = PageFactory.buildPage(APP_NAME, "Log4j Logger Adjuster");
|
Page p = PageFactory.buildPage(APP_NAME, "Log4j Logger Adjuster");
|
||||||
p.add(new CategoryPanel());
|
p.add(new CategoryPanel());
|
||||||
|
|
@ -232,6 +264,10 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return config Page object
|
||||||
|
*/
|
||||||
private Page buildConfigPage() {
|
private Page buildConfigPage() {
|
||||||
Page p = PageFactory.buildPage(APP_NAME, "Registry Config");
|
Page p = PageFactory.buildPage(APP_NAME, "Registry Config");
|
||||||
p.add(new ConfigList());
|
p.add(new ConfigList());
|
||||||
|
|
@ -247,6 +283,11 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ParameterModel m_request_id = new IntegerParameter("request_id");
|
private ParameterModel m_request_id = new IntegerParameter("request_id");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return info Page object
|
||||||
|
*/
|
||||||
private Page buildInfoPage() {
|
private Page buildInfoPage() {
|
||||||
Page p = PageFactory.buildPage(APP_NAME, "Request Information");
|
Page p = PageFactory.buildPage(APP_NAME, "Request Information");
|
||||||
p.addGlobalStateParam(m_request_id);
|
p.addGlobalStateParam(m_request_id);
|
||||||
|
|
@ -258,6 +299,12 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
|
|
||||||
private ParameterModel m_query_id = new IntegerParameter("query_id");
|
private ParameterModel m_query_id = new IntegerParameter("query_id");
|
||||||
private ParameterModel m_query_request_id = new IntegerParameter("request_id");
|
private ParameterModel m_query_request_id = new IntegerParameter("request_id");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return queryInfo Page object
|
||||||
|
*/
|
||||||
private Page buildQueryInfoPage() {
|
private Page buildQueryInfoPage() {
|
||||||
Page p = PageFactory.buildPage(APP_NAME, "Query Information");
|
Page p = PageFactory.buildPage(APP_NAME, "Query Information");
|
||||||
p.addGlobalStateParam(m_query_request_id);
|
p.addGlobalStateParam(m_query_request_id);
|
||||||
|
|
@ -268,6 +315,7 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestLocal m_scoreboard = new RequestLocal() {
|
private RequestLocal m_scoreboard = new RequestLocal() {
|
||||||
|
@Override
|
||||||
protected Object initialValue(PageState state) {
|
protected Object initialValue(PageState state) {
|
||||||
// queryInfo.getID() => {textRepeats, queryRepeats}
|
// queryInfo.getID() => {textRepeats, queryRepeats}
|
||||||
return new HashMap();
|
return new HashMap();
|
||||||
|
|
@ -561,10 +609,24 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
class RequestInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
class RequestInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
public RequestInfoComponent() {
|
public RequestInfoComponent() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void generateXML(PageState state, Element parent) {
|
public void generateXML(PageState state, Element parent) {
|
||||||
Integer request_id = (Integer)state.getValue(m_request_id);
|
Integer request_id = (Integer)state.getValue(m_request_id);
|
||||||
RequestInfo ri =
|
RequestInfo ri =
|
||||||
|
|
@ -671,10 +733,24 @@ public class Dispatcher extends BebopMapDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class
|
||||||
|
*/
|
||||||
class QueryInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
class QueryInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
public QueryInfoComponent() {
|
public QueryInfoComponent() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void generateXML(PageState state, Element parent) {
|
public void generateXML(PageState state, Element parent) {
|
||||||
Integer request_id = (Integer)state.getValue(m_query_request_id);
|
Integer request_id = (Integer)state.getValue(m_query_request_id);
|
||||||
Integer query_id = (Integer)state.getValue(m_query_id);
|
Integer query_id = (Integer)state.getValue(m_query_id);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ import com.arsdigita.bebop.parameters.IntegerParameter;
|
||||||
*
|
*
|
||||||
* @author Daniel Berrange (berrange@redhat.com)
|
* @author Daniel Berrange (berrange@redhat.com)
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
**/
|
*/
|
||||||
public class QueryLog implements com.arsdigita.dispatcher.Dispatcher {
|
public class QueryLog implements com.arsdigita.dispatcher.Dispatcher {
|
||||||
private static final Logger s_log =
|
private static final Logger s_log =
|
||||||
Logger.getLogger(QueryLog.class.getName());
|
Logger.getLogger(QueryLog.class.getName());
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class WebDevSupport extends Application {
|
||||||
public static final String BASE_DATA_OBJECT_TYPE =
|
public static final String BASE_DATA_OBJECT_TYPE =
|
||||||
"com.arsdigita.webdevsupport.WebDevSupport";
|
"com.arsdigita.webdevsupport.WebDevSupport";
|
||||||
|
|
||||||
public WebDevSupport(DataObject obj) {
|
public WebDevSupport(final DataObject obj) {
|
||||||
super(obj);
|
super(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,5 +66,10 @@ public class WebDevSupport extends Application {
|
||||||
return BASE_DATA_OBJECT_TYPE;
|
return BASE_DATA_OBJECT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getServletPath() {
|
||||||
|
return "/webdevsupport";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,876 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Peter Boy <pb@zes.uni-bremen.de> All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.arsdigita.webdevsupport;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.ActionLink;
|
||||||
|
import com.arsdigita.bebop.BoxPanel;
|
||||||
|
import com.arsdigita.bebop.ColumnPanel;
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.bebop.Container;
|
||||||
|
import com.arsdigita.bebop.ControlLink;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.Link;
|
||||||
|
import com.arsdigita.bebop.ListPanel;
|
||||||
|
import com.arsdigita.bebop.Page;
|
||||||
|
import com.arsdigita.bebop.PageFactory;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.RequestLocal;
|
||||||
|
import com.arsdigita.bebop.Table;
|
||||||
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
|
import com.arsdigita.bebop.event.ActionListener;
|
||||||
|
import com.arsdigita.bebop.event.TableActionAdapter;
|
||||||
|
import com.arsdigita.bebop.event.TableActionEvent;
|
||||||
|
import com.arsdigita.bebop.parameters.IntegerParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.ParameterModel;
|
||||||
|
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
|
||||||
|
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
|
||||||
|
import com.arsdigita.bebop.table.TableModel;
|
||||||
|
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||||
|
import com.arsdigita.developersupport.DeveloperSupport;
|
||||||
|
import com.arsdigita.dispatcher.AccessDeniedException;
|
||||||
|
import com.arsdigita.dispatcher.DispatcherHelper;
|
||||||
|
import com.arsdigita.kernel.Kernel;
|
||||||
|
import com.arsdigita.kernel.Party;
|
||||||
|
import com.arsdigita.kernel.permissions.PermissionDescriptor;
|
||||||
|
import com.arsdigita.kernel.permissions.PermissionService;
|
||||||
|
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
||||||
|
import com.arsdigita.templating.PresentationManager;
|
||||||
|
import com.arsdigita.templating.Templating;
|
||||||
|
import com.arsdigita.util.Assert;
|
||||||
|
import com.arsdigita.util.StringUtils;
|
||||||
|
import com.arsdigita.web.Application;
|
||||||
|
import com.arsdigita.web.BaseApplicationServlet;
|
||||||
|
import com.arsdigita.web.LoginSignal;
|
||||||
|
import com.arsdigita.web.ParameterMap;
|
||||||
|
import com.arsdigita.web.RedirectSignal;
|
||||||
|
import com.arsdigita.web.URL;
|
||||||
|
import com.arsdigita.webdevsupport.config.ConfigList;
|
||||||
|
import com.arsdigita.webdevsupport.log4j.CategoryPanel;
|
||||||
|
import com.arsdigita.xml.Document;
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Developer Support Application Servlet class, central entry point to
|
||||||
|
* create and process the applications UI.
|
||||||
|
*
|
||||||
|
* We should have subclassed BebopApplicationServlet but couldn't overwrite
|
||||||
|
* doService() method to add permission checking. So we use our own page
|
||||||
|
* mapping. The general logic is the same as for BebopApplicationServlet.
|
||||||
|
* {@see com.arsdigita.bebop.page.BebopApplicationServlet}
|
||||||
|
*
|
||||||
|
* @author pb
|
||||||
|
*/
|
||||||
|
public class WebDevSupportServlet extends BaseApplicationServlet {
|
||||||
|
|
||||||
|
private static final Logger s_log =
|
||||||
|
Logger.getLogger(Dispatcher.class.getName());
|
||||||
|
|
||||||
|
public static final String APP_NAME = "ds";
|
||||||
|
|
||||||
|
private static boolean s_showDSPages = false;
|
||||||
|
/** URL (pathinfo) -> Page object mapping. Based on it (and the http
|
||||||
|
* request url) the doService method to selects a page to display */
|
||||||
|
private final Map m_pages = new HashMap();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User extension point, overwrite this method to setup a URL - page mapping
|
||||||
|
*
|
||||||
|
* @throws ServletException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doInit() throws ServletException {
|
||||||
|
|
||||||
|
addPage("/", buildIndexPage()); // index page at address ~/ds
|
||||||
|
// addPage("/index.jsp", buildIndexPage()); // index page at address ~/ds
|
||||||
|
|
||||||
|
addPage("/log4j", buildLog4jPage()); // Logger Adjuster at addr. ~/ds/log4j
|
||||||
|
addPage("/config", buildConfigPage()); // config browser @ ~/ds/config
|
||||||
|
// cache table browser @ ~/ds/cache-table
|
||||||
|
addPage("/cache-table", buildCacheTablePage());
|
||||||
|
|
||||||
|
// XXXX!!
|
||||||
|
// QueryLog is a class of its own in webdevsupport, based upon dispatcher.Disp
|
||||||
|
// and prints out all queries in a request
|
||||||
|
// put("query-log", new QueryLog());
|
||||||
|
|
||||||
|
addPage("/request-info", buildInfoPage());
|
||||||
|
addPage("/query-info", buildQueryInfoPage());
|
||||||
|
addPage("/query-plan", buildQueryPlanPage());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Central service method, checks for required permission, determines the
|
||||||
|
* requested page and passes the page object to PresentationManager.
|
||||||
|
*/
|
||||||
|
public final void doService(HttpServletRequest sreq,
|
||||||
|
HttpServletResponse sresp,
|
||||||
|
Application app)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
// /////// Some preparational steps ///////////////
|
||||||
|
|
||||||
|
/* Determine access privilege: only logged in users may access DS */
|
||||||
|
Party party = Kernel.getContext().getParty();
|
||||||
|
if (party == null) {
|
||||||
|
throw new LoginSignal(sreq);
|
||||||
|
}
|
||||||
|
/* Determine access privilege: Admin privileges must be granted */
|
||||||
|
PermissionDescriptor admin = new PermissionDescriptor
|
||||||
|
(PrivilegeDescriptor.ADMIN, app, party);
|
||||||
|
if (!PermissionService.checkPermission(admin)) {
|
||||||
|
throw new AccessDeniedException("User is not an administrator");
|
||||||
|
}
|
||||||
|
/* Want ds to always show the latest stuff... */
|
||||||
|
DispatcherHelper.cacheDisable(sresp);
|
||||||
|
|
||||||
|
|
||||||
|
// /////// Everything OK here - DO IT ///////////////
|
||||||
|
|
||||||
|
String pathInfo = sreq.getPathInfo();
|
||||||
|
Assert.exists(pathInfo, "String pathInfo");
|
||||||
|
if (pathInfo.length() > 1 && pathInfo.endsWith("/")) {
|
||||||
|
/* NOTE: ServletAPI specifies, pathInfo may be empty or will
|
||||||
|
* start with a '/' character. It currently carries a
|
||||||
|
* trailing '/' if a "virtual" page, i.e. not a real jsp, but
|
||||||
|
* result of a servlet mapping. But Application requires url
|
||||||
|
* NOT to end with a trailing '/' for legacy free applications. */
|
||||||
|
pathInfo = pathInfo.substring(0, pathInfo.length()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Page page = (Page) m_pages.get(pathInfo);
|
||||||
|
|
||||||
|
if (page != null) {
|
||||||
|
|
||||||
|
final Document doc = page.buildDocument(sreq, sresp);
|
||||||
|
|
||||||
|
PresentationManager pm = Templating.getPresentationManager();
|
||||||
|
pm.servePage(doc, sreq, sresp);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sresp.sendError(404, "No such page for path " + pathInfo);
|
||||||
|
// throw new IllegalStateException("No such page for path " + pathInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds one Url-Page mapping to the internal mapping table.
|
||||||
|
*
|
||||||
|
* @param pathInfo url stub for a page to display
|
||||||
|
* @param page Page object to display
|
||||||
|
*/
|
||||||
|
private void addPage(final String pathInfo, final Page page) {
|
||||||
|
|
||||||
|
Assert.exists(pathInfo, String.class);
|
||||||
|
Assert.exists(page, Page.class);
|
||||||
|
// Current Implementation requires pathInfo to start with a leading '/'
|
||||||
|
// SUN Servlet API specifies: "PathInfo *may be empty* or will start
|
||||||
|
// with a '/' character."
|
||||||
|
Assert.isTrue(pathInfo.startsWith("/"), "path starts not with '/'");
|
||||||
|
|
||||||
|
m_pages.put(pathInfo, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return index Page object
|
||||||
|
*/
|
||||||
|
private Page buildIndexPage() {
|
||||||
|
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Web Developer Support");
|
||||||
|
|
||||||
|
BoxPanel links = new BoxPanel(BoxPanel.VERTICAL);
|
||||||
|
|
||||||
|
links.add(new Link("Log4j Logger Adjuster", "/ds/log4j"));
|
||||||
|
links.add(new Link("Config Browser", "/ds/config"));
|
||||||
|
links.add(new Link("Cache Table Browser", "/ds/cache-table"));
|
||||||
|
|
||||||
|
ActionLink enable = new ActionLink("Enable request logging") {
|
||||||
|
@Override
|
||||||
|
public boolean isVisible(PageState state) {
|
||||||
|
return !DeveloperSupport.containsListener(
|
||||||
|
WebDevSupportListener.getInstance())
|
||||||
|
&& super.isVisible(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
enable.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
DeveloperSupport.addListener(WebDevSupportListener.getInstance());
|
||||||
|
throw new RedirectSignal(URL.request(e.getPageState().getRequest(),
|
||||||
|
null), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
links.add(enable);
|
||||||
|
|
||||||
|
ActionLink disable = new ActionLink("Disable request logging") {
|
||||||
|
@Override
|
||||||
|
public boolean isVisible(PageState state) {
|
||||||
|
return DeveloperSupport.containsListener(
|
||||||
|
WebDevSupportListener.getInstance())
|
||||||
|
&& super.isVisible(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disable.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
DeveloperSupport.removeListener(WebDevSupportListener.getInstance());
|
||||||
|
WebDevSupportListener.getInstance().clearRequestHistory();
|
||||||
|
throw new RedirectSignal(URL.request(e.getPageState().getRequest(),
|
||||||
|
null), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
links.add(disable);
|
||||||
|
|
||||||
|
BoxPanel logs = new BoxPanel(BoxPanel.VERTICAL) {
|
||||||
|
@Override
|
||||||
|
public boolean isVisible(PageState state) {
|
||||||
|
return DeveloperSupport
|
||||||
|
.containsListener(WebDevSupportListener.getInstance())
|
||||||
|
&& super.isVisible(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
logs.add(new Label("") {
|
||||||
|
@Override
|
||||||
|
public String getLabel(PageState ps) {
|
||||||
|
return "Currently storing the last " +
|
||||||
|
WebDevSupportListener.getInstance().getMaxRequests() +
|
||||||
|
" requests";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Label toggle = new Label("") {
|
||||||
|
@Override
|
||||||
|
public String getLabel(PageState ps) {
|
||||||
|
return s_showDSPages ? "Hide hits to developer support" :
|
||||||
|
"Show hits to developer support";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ControlLink cl = new ControlLink(toggle) {
|
||||||
|
@Override
|
||||||
|
public void respond(PageState s) {
|
||||||
|
s_showDSPages = !s_showDSPages;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setControlEvent(PageState s) {
|
||||||
|
s.setControlEvent(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
logs.add(cl);
|
||||||
|
logs.add(new Label("<h3>Available Request Information</h3>", false));
|
||||||
|
logs.add(makeRequestTable());
|
||||||
|
|
||||||
|
p.add(links);
|
||||||
|
p.add(logs);
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return log4j Page object
|
||||||
|
*/
|
||||||
|
private Page buildLog4jPage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Log4j Logger Adjuster");
|
||||||
|
p.add(new CategoryPanel());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return config Page object
|
||||||
|
*/
|
||||||
|
private Page buildConfigPage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Registry Config");
|
||||||
|
p.add(new ConfigList());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Page buildCacheTablePage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Cache Table Browser");
|
||||||
|
p.add(new CacheTableBrowser());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ParameterModel m_request_id = new IntegerParameter("request_id");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return info Page object
|
||||||
|
*/
|
||||||
|
private Page buildInfoPage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Request Information");
|
||||||
|
p.addGlobalStateParam(m_request_id);
|
||||||
|
// p.add(new RequestInfoComponent());
|
||||||
|
p.add(makeDatabaseRequestComponent());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParameterModel m_query_id = new IntegerParameter("query_id");
|
||||||
|
private ParameterModel m_query_request_id = new IntegerParameter("request_id");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return queryInfo Page object
|
||||||
|
*/
|
||||||
|
private Page buildQueryInfoPage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Query Information");
|
||||||
|
p.addGlobalStateParam(m_query_request_id);
|
||||||
|
p.addGlobalStateParam(m_query_id);
|
||||||
|
p.add(new QueryInfoComponent());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private RequestLocal m_scoreboard = new RequestLocal() {
|
||||||
|
@Override
|
||||||
|
protected Object initialValue(PageState state) {
|
||||||
|
// queryInfo.getID() => {textRepeats, queryRepeats}
|
||||||
|
return new HashMap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used below in makeDatabaseRequestComponent to generate a query
|
||||||
|
// scoreboard.
|
||||||
|
private void incrementScore(final PageState state, final QueryInfo key,
|
||||||
|
final int index) {
|
||||||
|
Map map = (Map) m_scoreboard.get(state);
|
||||||
|
|
||||||
|
Integer[] row = (Integer[]) map.get(new Integer(key.getID()));
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
row = new Integer[] { new Integer(0), new Integer(0) };
|
||||||
|
map.put(new Integer(key.getID()), row);
|
||||||
|
}
|
||||||
|
|
||||||
|
row[index] = new Integer(row[index].intValue() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Component makeDatabaseRequestComponent() {
|
||||||
|
final String[] headers =
|
||||||
|
{ "ID", "Duration (execution)", "Conn", "Command", "Exception" };
|
||||||
|
|
||||||
|
TableModelBuilder b = new AbstractTableModelBuilder() {
|
||||||
|
public TableModel makeModel(Table t, final PageState s) {
|
||||||
|
Integer request_id = (Integer)s.getValue(m_request_id);
|
||||||
|
RequestInfo ri =
|
||||||
|
WebDevSupportListener.getInstance().getRequest(request_id.intValue());
|
||||||
|
final Iterator iter = (ri == null) ? new ArrayList().iterator() :
|
||||||
|
ri.getQueries();
|
||||||
|
|
||||||
|
return new TableModel() {
|
||||||
|
private HashMap seenQueryAndValues = new HashMap();
|
||||||
|
private HashMap seenQuery = new HashMap();
|
||||||
|
private boolean duplicateQueryAndValues = false;
|
||||||
|
private boolean duplicateQuery = false;
|
||||||
|
private QueryInfo current = null;
|
||||||
|
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nextRow() {
|
||||||
|
if (iter.hasNext()) {
|
||||||
|
current = (QueryInfo) iter.next();
|
||||||
|
|
||||||
|
duplicateQueryAndValues =
|
||||||
|
seenQueryAndValues.containsKey(current);
|
||||||
|
duplicateQuery =
|
||||||
|
seenQuery.containsKey(current.getQuery());
|
||||||
|
|
||||||
|
if (!duplicateQueryAndValues) {
|
||||||
|
seenQueryAndValues.put(current, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!duplicateQuery) {
|
||||||
|
seenQuery.put(current.getQuery(), current);
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementScore
|
||||||
|
(s, (QueryInfo) seenQueryAndValues.get(current),
|
||||||
|
0);
|
||||||
|
incrementScore
|
||||||
|
(s, (QueryInfo) seenQuery.get(current.getQuery()),
|
||||||
|
1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getElementAt(int columnIndex) {
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 0: {
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
result.append(current.getID());
|
||||||
|
|
||||||
|
if (duplicateQueryAndValues) {
|
||||||
|
result.append(
|
||||||
|
" duplicates #" +
|
||||||
|
((QueryInfo)seenQueryAndValues.get(
|
||||||
|
current)).getID()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicateQuery) {
|
||||||
|
result.append(
|
||||||
|
" duplicates text of #" +
|
||||||
|
((QueryInfo)seenQuery.get(
|
||||||
|
current.getQuery())).getID()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
case 1: return (current.isClosed() ?
|
||||||
|
current.getTotalTime() + " ms" :
|
||||||
|
"unknown")
|
||||||
|
+ "<br/> (" + current.getTime() + " ms)";
|
||||||
|
case 2: return current.getConnectionID();
|
||||||
|
case 3: return "<blockquote><pre>" +
|
||||||
|
current.getQuery() +
|
||||||
|
"</pre><br>BINDS: " +
|
||||||
|
current.getBindvars() +
|
||||||
|
"</blockquote>";
|
||||||
|
case 4: return current.getSQLE();
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getKeyAt(int columnIndex) {
|
||||||
|
return new Integer(current.getID());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Table table = new Table(b, headers);
|
||||||
|
table.setBorder("1");
|
||||||
|
table.getColumn(1).setCellRenderer(new NonEscapedTableCellRenderer(false));
|
||||||
|
table.getColumn(3).setCellRenderer(new NonEscapedTableCellRenderer());
|
||||||
|
table.getColumn(0).setCellRenderer(new
|
||||||
|
DefaultTableCellRenderer(true));
|
||||||
|
table.addTableActionListener(new TableActionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void cellSelected(TableActionEvent e) {
|
||||||
|
PageState s = e.getPageState();
|
||||||
|
Integer request_id = (Integer) s.getValue(m_query_request_id);
|
||||||
|
|
||||||
|
final ParameterMap params = new ParameterMap();
|
||||||
|
|
||||||
|
params.setParameter("request_id", request_id);
|
||||||
|
params.setParameter("query_id", e.getRowKey());
|
||||||
|
|
||||||
|
if (e.getColumn().intValue() == 0) {
|
||||||
|
throw new RedirectSignal(URL.getDispatcherPath() +
|
||||||
|
"/ds/query-info" + params, true);
|
||||||
|
} else {
|
||||||
|
throw new RedirectSignal(URL.getDispatcherPath() +
|
||||||
|
"/ds/query-log" + params, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Label l = new Label("None");
|
||||||
|
l.setFontWeight(Label.ITALIC);
|
||||||
|
l.setStyleAttr("padding-left: 3em");
|
||||||
|
table.setEmptyView(l);
|
||||||
|
table.setWidth("100%");
|
||||||
|
|
||||||
|
BoxPanel panel = new BoxPanel(BoxPanel.VERTICAL);
|
||||||
|
panel.add(table);
|
||||||
|
|
||||||
|
TableModelBuilder scoreBuilder = new AbstractTableModelBuilder() {
|
||||||
|
public TableModel makeModel(Table t, final PageState state) {
|
||||||
|
return new TableModel() {
|
||||||
|
Map map = (Map) m_scoreboard.get(state);
|
||||||
|
Iterator iter = map.keySet().iterator();
|
||||||
|
Integer key;
|
||||||
|
Integer[] row;
|
||||||
|
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nextRow() {
|
||||||
|
if (iter.hasNext()) {
|
||||||
|
key = (Integer) iter.next();
|
||||||
|
row = (Integer[]) map.get(key);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getElementAt(int column) {
|
||||||
|
switch (column) {
|
||||||
|
case 0:
|
||||||
|
return key;
|
||||||
|
case 1:
|
||||||
|
return row[0];
|
||||||
|
case 2:
|
||||||
|
return row[1];
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getKeyAt(int column) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final String[] scoreHeaders = {"ID", "Duplicates", "Text-Duplicates"};
|
||||||
|
|
||||||
|
Table scoreTable = new Table(scoreBuilder, scoreHeaders);
|
||||||
|
panel.add(scoreTable);
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Table makeRequestTable() {
|
||||||
|
final String[] headers = { "Time", "Duration", "Queries", "IP",
|
||||||
|
"Request", "Extra" };
|
||||||
|
|
||||||
|
TableModelBuilder b = new AbstractTableModelBuilder() {
|
||||||
|
public TableModel makeModel(Table t, PageState s) {
|
||||||
|
return new TableModel() {
|
||||||
|
ListIterator iter =
|
||||||
|
WebDevSupportListener.getInstance().getRequestsReverse();
|
||||||
|
private RequestInfo current = null;
|
||||||
|
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nextRow() {
|
||||||
|
while (iter.hasPrevious()) {
|
||||||
|
current = (RequestInfo) iter.previous();
|
||||||
|
boolean isdevsupp = current.isDevSupportRequest();
|
||||||
|
if (s_showDSPages || !isdevsupp) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static final int MAXSTR = 35;
|
||||||
|
public Object getElementAt(int columnIndex) {
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 0: return current.getTime();
|
||||||
|
case 1: return current.getDuration();
|
||||||
|
case 2: return current.getNumQueries()+"";
|
||||||
|
case 3: return current.getIP();
|
||||||
|
case 4: {
|
||||||
|
String req = current.getRequest();
|
||||||
|
if (req.length() > MAXSTR) {
|
||||||
|
return req.substring(0, MAXSTR)+"...";
|
||||||
|
} else {
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
return "[query log]";
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getKeyAt(int columnIndex) {
|
||||||
|
return new Integer(current.getID());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Table result = new Table(b, headers);
|
||||||
|
result.getColumn(4).setCellRenderer(new
|
||||||
|
DefaultTableCellRenderer(true));
|
||||||
|
result.getColumn(5).setCellRenderer(new
|
||||||
|
DefaultTableCellRenderer(true));
|
||||||
|
result.addTableActionListener(new TableActionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void cellSelected(TableActionEvent e) {
|
||||||
|
final ParameterMap params = new ParameterMap();
|
||||||
|
params.setParameter("request_id", e.getRowKey());
|
||||||
|
|
||||||
|
if (e.getColumn().intValue() == 4) {
|
||||||
|
throw new RedirectSignal(URL.getDispatcherPath() +
|
||||||
|
"/ds/request-info" + params, true);
|
||||||
|
} else if (e.getColumn().intValue() == 5) {
|
||||||
|
throw new RedirectSignal(URL.getDispatcherPath() +
|
||||||
|
"/ds/query-log" + params, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Label l = new Label("None");
|
||||||
|
l.setFontWeight(Label.ITALIC);
|
||||||
|
l.setStyleAttr("padding-left: 3em");
|
||||||
|
result.setEmptyView(l);
|
||||||
|
result.setWidth("100%");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dashes(int depth) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
while (depth-- > 0) sb.append("--");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ParameterModel m_query_p_id = new IntegerParameter("query_id");
|
||||||
|
private ParameterModel m_query_p_request_id =
|
||||||
|
new IntegerParameter("request_id");
|
||||||
|
|
||||||
|
private Page buildQueryPlanPage() {
|
||||||
|
Page p = PageFactory.buildPage(APP_NAME, "Query Execution Plan");
|
||||||
|
p.addGlobalStateParam(m_query_p_request_id);
|
||||||
|
p.addGlobalStateParam(m_query_p_id);
|
||||||
|
p.add(new QueryPlanComponent());
|
||||||
|
p.lock();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RequestInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public RequestInfoComponent() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void generateXML(PageState state, Element parent) {
|
||||||
|
Integer request_id = (Integer)state.getValue(m_request_id);
|
||||||
|
RequestInfo ri =
|
||||||
|
WebDevSupportListener.getInstance().getRequest(request_id.intValue());
|
||||||
|
if (ri != null) {
|
||||||
|
Container param_list;
|
||||||
|
Container form_list;
|
||||||
|
Container comment_list;
|
||||||
|
Container headers_list;
|
||||||
|
Container stages_list;
|
||||||
|
BoxPanel bp = new BoxPanel();
|
||||||
|
bp.add(new Label("<h3>Parameters</h3>", false));
|
||||||
|
bp.add(param_list = new ColumnPanel(2));
|
||||||
|
param_list.add(new Label("Request Start Time:"));
|
||||||
|
param_list.add(new Label(ri.getTime()));
|
||||||
|
param_list.add(new Label("Request Completion Time: "));
|
||||||
|
param_list.add(new Label(ri.getEndTime()));
|
||||||
|
param_list.add(new Label("Request Duration: "));
|
||||||
|
param_list.add(new Label(ri.getDuration()));
|
||||||
|
param_list.add(new Label("IP: "));
|
||||||
|
param_list.add(new Label(ri.getIP()));
|
||||||
|
param_list.add(new Label("Method: "));
|
||||||
|
param_list.add(new Label(ri.getMethod()));
|
||||||
|
param_list.add(new Label("URL: "));
|
||||||
|
param_list.add(new Label(ri.getURL()));
|
||||||
|
param_list.add(new Label("Query: "));
|
||||||
|
param_list.add(new Label(StringUtils.quoteHtml( ri.getQuery())));
|
||||||
|
param_list.add(new Label("Request Parameters: "));
|
||||||
|
param_list.add(form_list = new ColumnPanel(2));
|
||||||
|
Iterator iter = ri.getParameterNames();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
String param = (String)iter.next();
|
||||||
|
form_list.add(new Label(param + ":"));
|
||||||
|
form_list.add(new Label(ri.getParameter(param)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bp.add(new Label("<h3>Headers</h3>", false));
|
||||||
|
bp.add(headers_list = new ColumnPanel(2));
|
||||||
|
iter = ri.headerKeys();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
String header = (String)iter.next();
|
||||||
|
headers_list.add(new Label(header +": "));
|
||||||
|
headers_list.add(new Label(ri.getHeader(header)));
|
||||||
|
}
|
||||||
|
//Doesn't appear to be possible to get the output headers
|
||||||
|
//bp.add(new Label("Output Headers"));
|
||||||
|
if (ri.numComments() > 0) {
|
||||||
|
bp.add(new Label("<h3>Comments</h3>", false));
|
||||||
|
bp.add(comment_list = new ListPanel(false));
|
||||||
|
iter = ri.getComments();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
comment_list.add(new Label((String)iter.next()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ri.numStages() > 0) {
|
||||||
|
bp.add(new Label("<h3>Stages</h3>", false));
|
||||||
|
bp.add(stages_list = new ColumnPanel(4));
|
||||||
|
iter = ri.getStages();
|
||||||
|
stages_list.add(new Label("Stage"));
|
||||||
|
stages_list.add(new Label("Time"));
|
||||||
|
stages_list.add(new Label("Queries"));
|
||||||
|
stages_list.add(new Label("Processing"));
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
StageInfo si = (StageInfo)iter.next();
|
||||||
|
String leaf = si.leaf() ? "*" : "";
|
||||||
|
int numqueries = si.numQueries();
|
||||||
|
long time = si.time();
|
||||||
|
stages_list.add(new Label(dashes(si.depth()) + si.getName()));
|
||||||
|
stages_list.add(new Label(time + " ms" + leaf));
|
||||||
|
if (numqueries != 0) {
|
||||||
|
long queryTime = si.queryTime(ri.getQueries());
|
||||||
|
long non_queryTime = time-queryTime;
|
||||||
|
stages_list.add(new Label(queryTime + " ms" + leaf +
|
||||||
|
" ("+numqueries+" queries)"));
|
||||||
|
stages_list.add(new Label(non_queryTime + " ms" + leaf));
|
||||||
|
} else {
|
||||||
|
stages_list.add(new Label(""));
|
||||||
|
stages_list.add(new Label(time + " ms"+ leaf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bp.add(new Label("<h3>Database Requests</h3>", false));
|
||||||
|
int query_count = 0;
|
||||||
|
long total_time = 0;
|
||||||
|
long total_execute = 0;
|
||||||
|
int unclosed_count = 0;
|
||||||
|
iter = ri.getQueries();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
QueryInfo qi = (QueryInfo)iter.next();
|
||||||
|
query_count++;
|
||||||
|
total_execute += qi.getTime();
|
||||||
|
total_time += qi.getTotalTime();
|
||||||
|
if (!qi.isClosed()) {
|
||||||
|
unclosed_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bp.add(new Label("Total Queries: " + query_count +
|
||||||
|
(unclosed_count > 0 ? " (" + unclosed_count +
|
||||||
|
" unclosed)" : "")));
|
||||||
|
bp.add(new Label("Total Time: " + total_time +
|
||||||
|
" ms (execution: " + total_execute + " ms)"));
|
||||||
|
bp.generateXML(state, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class
|
||||||
|
*/
|
||||||
|
class QueryInfoComponent extends com.arsdigita.bebop.SimpleComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public QueryInfoComponent() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void generateXML(PageState state, Element parent) {
|
||||||
|
Integer request_id = (Integer)state.getValue(m_query_request_id);
|
||||||
|
Integer query_id = (Integer)state.getValue(m_query_id);
|
||||||
|
RequestInfo ri =
|
||||||
|
WebDevSupportListener.getInstance().getRequest(request_id.intValue());
|
||||||
|
if (ri != null) {
|
||||||
|
QueryInfo qi = ri.getQuery(query_id.intValue());
|
||||||
|
if (qi != null) {
|
||||||
|
ListPanel info_list;
|
||||||
|
BoxPanel bp = new BoxPanel();
|
||||||
|
bp.add(info_list = new ListPanel(false));
|
||||||
|
info_list.add(new Label("Total query duration: " +
|
||||||
|
qi.getTotalTime() + " ms"));
|
||||||
|
info_list.add(new Label("Query execution time: " +
|
||||||
|
qi.getTime() + " ms"));
|
||||||
|
info_list.add(new Label("Statement closed: " +
|
||||||
|
qi.isClosed()));
|
||||||
|
info_list.add(new Label("Connection ID: " +
|
||||||
|
qi.getConnectionID()));
|
||||||
|
info_list.add(new Label("Type: " +
|
||||||
|
qi.getType()));
|
||||||
|
info_list.add(new Label("Query: <br/><pre>" +
|
||||||
|
StringUtils.quoteHtml(
|
||||||
|
qi.getQuery() ) + "</pre>", false));
|
||||||
|
info_list.add(new Label("Bindvars: " +
|
||||||
|
qi.getBindvars()));
|
||||||
|
|
||||||
|
Link l = new Link ("Query Execution Plan",
|
||||||
|
"../query-plan/");
|
||||||
|
l.setVar("request_id", request_id.toString());
|
||||||
|
l.setVar("query_id", query_id.toString());
|
||||||
|
info_list.add(l);
|
||||||
|
|
||||||
|
|
||||||
|
info_list.add(new Label("Exception: " +
|
||||||
|
qi.getSQLE()));
|
||||||
|
info_list.add(new Label("StackTrace: <br/><pre>" +
|
||||||
|
StringUtils.quoteHtml(qi.getStackTrace()) +
|
||||||
|
"</pre>", false));
|
||||||
|
bp.generateXML(state, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We need NonEscapedTableCellRenderer
|
||||||
|
// Currently part of (thisPackage) Dispatcher.java
|
||||||
|
// When the class will we deleted we must copy first!
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -83,6 +83,11 @@
|
||||||
<servlet-class>com.arsdigita.versioning.VersioningServlet</servlet-class>
|
<servlet-class>com.arsdigita.versioning.VersioningServlet</servlet-class>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>webdevsupport</servlet-name>
|
||||||
|
<servlet-class>com.arsdigita.webdevsupport.WebDevSupportServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>oid-redirect</servlet-name>
|
<servlet-name>oid-redirect</servlet-name>
|
||||||
<servlet-class>com.arsdigita.web.OIDRedirectServlet</servlet-class>
|
<servlet-class>com.arsdigita.web.OIDRedirectServlet</servlet-class>
|
||||||
|
|
@ -176,6 +181,11 @@
|
||||||
<url-pattern>/versioning/*</url-pattern>
|
<url-pattern>/versioning/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>webdevsupport</servlet-name>
|
||||||
|
<url-pattern>/webdevsupport/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>oid-redirect</servlet-name>
|
<servlet-name>oid-redirect</servlet-name>
|
||||||
<url-pattern>/redirect/*</url-pattern>
|
<url-pattern>/redirect/*</url-pattern>
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,10 @@ public class ForumServlet extends BebopApplicationServlet
|
||||||
@Override
|
@Override
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
super.init();
|
super.init();
|
||||||
s_log.debug("creating forum page");
|
|
||||||
|
|
||||||
|
s_log.debug("creating forum page");
|
||||||
final Page forum = ForumPageFactory.getPage(ForumPageFactory.FORUM_PAGE);
|
final Page forum = ForumPageFactory.getPage(ForumPageFactory.FORUM_PAGE);
|
||||||
|
|
||||||
s_log.debug("creating thread page");
|
s_log.debug("creating thread page");
|
||||||
final Page thread = ForumPageFactory.getPage(ForumPageFactory.THREAD_PAGE);
|
final Page thread = ForumPageFactory.getPage(ForumPageFactory.THREAD_PAGE);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,11 @@
|
||||||
<servlet-class>com.arsdigita.versioning.VersioningServlet</servlet-class>
|
<servlet-class>com.arsdigita.versioning.VersioningServlet</servlet-class>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>webdevsupport</servlet-name>
|
||||||
|
<servlet-class>com.arsdigita.webdevsupport.WebDevSupportServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>oid-redirect</servlet-name>
|
<servlet-name>oid-redirect</servlet-name>
|
||||||
<servlet-class>com.arsdigita.web.OIDRedirectServlet</servlet-class>
|
<servlet-class>com.arsdigita.web.OIDRedirectServlet</servlet-class>
|
||||||
|
|
@ -439,6 +444,11 @@
|
||||||
<url-pattern>/versioning/*</url-pattern>
|
<url-pattern>/versioning/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>webdevsupport</servlet-name>
|
||||||
|
<url-pattern>/webdevsupport/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>oid-redirect</servlet-name>
|
<servlet-name>oid-redirect</servlet-name>
|
||||||
<url-pattern>/redirect/*</url-pattern>
|
<url-pattern>/redirect/*</url-pattern>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue