001: package com.jamonapi;
002:
003: import java.util.*;
004: import com.jamonapi.utils.*;
005:
006: /** MonitorConverter is a utility class used by MonitorComposite to convert Monitor data to various formats. **/
007:
008: public class MonitorConverter extends java.lang.Object implements
009: MonitorReportInterface {
010: private ResultSetUtils utils = ResultSetUtils.createInstance(); // Generic conversion class.
011: private MonitorComposite rootComposite;
012: private static String JAMON_ADMIN_PAGE_DEFAULT = "JAMonAdmin.jsp";
013: private String JAMonAdminPage = JAMON_ADMIN_PAGE_DEFAULT;
014: private static String[][] EMPTY_ARRAY = { { "" } };
015:
016: private ArrayList rowsList = new ArrayList();
017:
018: // used for initial sizing of the ArrayList that holds the data returned by MonitorComposite
019: static private int TYPICAL_NUM_CHILDREN = 30;
020:
021: /** Constructor that takes the MonitorComposite object that the Converter methods will be called against. **/
022: protected MonitorConverter(MonitorComposite rootComposite) {
023: this .rootComposite = rootComposite;
024: }
025:
026: /** Constructor that takes the MonitorComposite object that the Converter methods will be called against. **/
027: protected MonitorConverter(MonitorComposite rootComposite,
028: String JAMonAdminPage) {
029: this .rootComposite = rootComposite;
030: this .JAMonAdminPage = JAMonAdminPage;
031: }
032:
033: /** Return an html table in String format that is sorted by the passed column in ascending or descending order **/
034: public String getReport(int sortCol, String sortOrder)
035: throws Exception {
036: return new MonitorReport(sortCol, sortOrder).getReport();
037: }
038:
039: /** Return an html table in String format in the default sort order **/
040: public String getReport() throws Exception {
041: return getReport(1, "asc");
042: }
043:
044: /***** start inner class MonitorReport - class that displays the monitor html report *****/
045: private class MonitorReport {
046:
047: private final int sortCol;
048: private final String sortOrder;
049: private final StringBuffer table = new StringBuffer(20000);
050:
051: public MonitorReport(int sortCol, String sortOrder) {
052: this .sortCol = sortCol;
053: this .sortOrder = sortOrder;
054: }
055:
056: public String getReport() throws Exception {
057: addReportHeader();
058: addReportBody();
059:
060: return table.toString();
061: }
062:
063: private void addReportHeader() {
064: table.append("<!-- Begin Report Sect. -->\n");
065: table
066: .append("<table border='0' cellpadding='0' cellspacing='0'>\n");
067: table.append("<tr>\n");
068: table.append("<td>\n");
069: table
070: .append("<table class='layoutmain' border='1' cellpadding='2' cellspacing='0' rules='all'>\n");
071: table.append("<tr class='headtextr' valign='top'>\n");
072:
073: String[] header = MonitorComposite.getHeader();
074: int rows = header.length;
075: String currentHeaderCell = null;
076: String lastHeaderCell = null;
077:
078: for (int i = 0; i < rows; i++) {
079: int sortIndex = i + 1;
080: if (sortIndex == sortCol) { // if this header entry is the one that has been sorted on
081: String newSortOrder = ("asc"
082: .equalsIgnoreCase(sortOrder)) ? "desc"
083: : "asc";
084: currentHeaderCell = "<th><a href='"
085: + JAMonAdminPage + "?sortCol=" + sortIndex
086: + "&sortOrder=" + newSortOrder + "'>"
087: + header[i] + "</a><br><img src='"
088: + sortOrder + ".gif'></th>\n";
089: } else {
090: currentHeaderCell = "<th><a href='"
091: + JAMonAdminPage + "?sortCol=" + sortIndex
092: + "&sortOrder=desc'>" + header[i]
093: + "</a><br></th>\n";
094: }
095:
096: if (i == 0) // repeat the first header at the end so the report is easier to read.
097: lastHeaderCell = currentHeaderCell;
098:
099: table.append(currentHeaderCell);
100: }
101:
102: table.append(lastHeaderCell + "</tr>\n");
103: table.append("<tr class='headtextr'>\n");
104: table.append("<th colspan='13'> </th>\n");
105: table
106: .append("<th colspan='13'>Hits/Avg ms.           (Avg Active/Primary Active/Global Active)</th>\n");
107: table.append("<th> </th>\n</tr>\n");
108:
109: }
110:
111: private void addReportBody() {
112: Object[][] data = getData("", sortCol - 1, sortOrder);
113:
114: int rows = data.length;
115: int cols = data[0].length;
116:
117: for (int i = 0; i < rows; i++) {
118: // note row i=0 is row 1
119: String oddOrEven = (i % 2 == 0) ? "odd" : "even";
120: String monitorLabel = data[i][0].toString();
121:
122: table
123: .append("<tr class='"
124: + oddOrEven
125: + "' onMouseOver='rollOnRow(this, \"Statistics for "
126: + monitorLabel
127: + "\")' onMouseOut='rollOffRow(this)'>\n");
128: String labelEntry = "<th class='headtextc' align='left' nowrap>"
129: + monitorLabel + "</th>\n";
130: table.append(labelEntry);
131:
132: for (int j = 1; j < cols; j++) {
133: table
134: .append("<td nowrap>" + data[i][j]
135: + "</td>\n");
136: }
137:
138: table.append(labelEntry); // repeat the label column to make the report more readable
139: table.append("</tr>\n");
140: }
141:
142: table.append("</table>\n<!-- End Report Sect. -->\n");
143:
144: }
145: }
146:
147: /***** end inner class MonitorReport *****/
148:
149: public String[][] getData() {
150: return getData("");
151: }
152:
153: public String[][] getData(String label) {
154: getCompositeData(label, rootComposite);
155:
156: int rows = rowsList.size();
157:
158: if (rows == 0) {
159: return EMPTY_ARRAY;
160: } else
161: return utils.arrayListToString(rowsList);
162:
163: }
164:
165: public Object[][] getData(String label, int sortCol,
166: String sortOrder) {
167: Object[][] data = getData(label);
168:
169: if (data == EMPTY_ARRAY) // Avoid index out of range exception when monitor has no data
170: return data;
171: else
172: return Misc.sort(data, sortCol, sortOrder);
173: }
174:
175: protected void getData(String label, MinimalMonitor monitor) {
176: if (monitor instanceof MonitorComposite)
177: getCompositeData(label, (MonitorComposite) monitor); // recursive
178: else
179: getLeafData(label, monitor);
180: }
181:
182: protected void getCompositeData(final String localLabel,
183: final MonitorComposite composite) {
184: // inner classes in a method can only access local variables that are defined as final
185: class GetMonitorData implements Command {
186: Map.Entry mapEntry;
187: MinimalMonitor monitor;
188:
189: public void execute(Object value) throws Exception {
190: String label = localLabel;
191: mapEntry = (Map.Entry) value;
192:
193: monitor = (MinimalMonitor) mapEntry.getValue();
194: String key = mapEntry.getKey().toString(); // something like pagesC or homepageL
195: label += composite.getLabelFromKey(key); // pages. or homepage
196:
197: getData(label, monitor); // recursive
198: }
199: }
200:
201: composite.iterateMapEntries(new GetMonitorData());
202: }
203:
204: protected void getLeafData(String label, MinimalMonitor monitor) {
205: ArrayList rowData = new ArrayList(TYPICAL_NUM_CHILDREN);// the arraylist will be created by the called routine.
206: rowData.add(label); // add display label such as "pages.homepage"
207: monitor.getData(rowData); // appends monitor data to the arraylist
208:
209: String[] rowDataArray = new String[0];
210:
211: rowsList.add(rowData.toArray(rowDataArray));
212:
213: }
214:
215: protected static void setJAMonAdminPage(String JAMonAdminPage) {
216: MonitorConverter.JAMON_ADMIN_PAGE_DEFAULT = JAMonAdminPage;
217: }
218:
219: }
|