001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jmeter.monitor.parser;
018:
019: // import java.util.List;
020: import java.util.Stack;
021:
022: import org.xml.sax.Attributes;
023: import org.xml.sax.SAXException;
024: import org.xml.sax.helpers.DefaultHandler;
025:
026: import org.apache.jmeter.monitor.model.ObjectFactory;
027: import org.apache.jmeter.monitor.model.Connector;
028: import org.apache.jmeter.monitor.model.Jvm;
029: import org.apache.jmeter.monitor.model.Memory;
030: import org.apache.jmeter.monitor.model.RequestInfo;
031: import org.apache.jmeter.monitor.model.Status;
032: import org.apache.jmeter.monitor.model.StatusImpl;
033: import org.apache.jmeter.monitor.model.ThreadInfo;
034: import org.apache.jmeter.monitor.model.Worker;
035: import org.apache.jmeter.monitor.model.Workers;
036: import org.apache.jmeter.monitor.model.WorkersImpl;
037:
038: public class MonitorHandler extends DefaultHandler {
039: // private boolean startDoc = false;
040: // private boolean endDoc = false;
041: private Stack stacktree = new Stack();
042:
043: private ObjectFactory factory = null;
044:
045: private Status status = null;
046:
047: private Jvm jvm = null;
048:
049: private Memory memory = null;
050:
051: private Connector connector = null;
052:
053: private ThreadInfo threadinfo = null;
054:
055: private RequestInfo requestinfo = null;
056:
057: private Worker worker = null;
058:
059: private Workers workers = null;
060:
061: // private List workerslist = null;
062:
063: /**
064: *
065: */
066: public MonitorHandler() {
067: super ();
068: }
069:
070: /**
071: * Set the ObjectFactory used to create new
072: *
073: * @param factory
074: */
075: public void setObjectFactory(ObjectFactory factory) {
076: this .factory = factory;
077: }
078:
079: public void startDocument() throws SAXException {
080: // this.startDoc = true;
081: }
082:
083: public void endDocument() throws SAXException {
084: // this.startDoc = false;
085: // this.endDoc = true;
086: }
087:
088: /**
089: * Receive notification of the start of an element.
090: *
091: * <p>
092: * By default, do nothing. Application writers may override this method in a
093: * subclass to take specific actions at the start of each element (such as
094: * allocating a new tree node or writing output to a file).
095: * </p>
096: *
097: * @param uri
098: * @param localName
099: * The element type name.
100: * @param qName
101: * @param attributes
102: * The specified or defaulted attributes.
103: * @exception org.xml.sax.SAXException
104: * Any SAX exception, possibly wrapping another exception.
105: * @see org.xml.sax.ContentHandler#startElement
106: */
107: public void startElement(String uri, String localName,
108: String qName, Attributes attributes) throws SAXException {
109: if (qName.equals(Constants.STATUS)) {
110: status = factory.createStatus();
111: stacktree.push(status);
112: } else if (qName.equals(Constants.JVM)) {
113: jvm = factory.createJvm();
114: if (stacktree.peek() instanceof Status) {
115: status.setJvm(jvm);
116: stacktree.push(jvm);
117: }
118: } else if (qName.equals(Constants.MEMORY)) {
119: memory = factory.createMemory();
120: if (stacktree.peek() instanceof Jvm) {
121: stacktree.push(memory);
122: if (attributes != null) {
123: for (int idx = 0; idx < attributes.getLength(); idx++) {
124: String attr = attributes.getQName(idx);
125: if (attr.equals(Constants.MEMORY_FREE)) {
126: memory.setFree(parseLong(attributes
127: .getValue(idx)));
128: } else if (attr.equals(Constants.MEMORY_TOTAL)) {
129: memory.setTotal(parseLong(attributes
130: .getValue(idx)));
131: } else if (attr.equals(Constants.MEMORY_MAX)) {
132: memory.setMax(parseLong(attributes
133: .getValue(idx)));
134: }
135: }
136: }
137: jvm.setMemory(memory);
138: }
139: } else if (qName.equals(Constants.CONNECTOR)) {
140: connector = factory.createConnector();
141: if (stacktree.peek() instanceof Status
142: || stacktree.peek() instanceof Connector) {
143: ((StatusImpl) status).addConnector(connector);
144: stacktree.push(connector);
145: if (attributes != null) {
146: for (int idx = 0; idx < attributes.getLength(); idx++) {
147: String attr = attributes.getQName(idx);
148: if (attr.equals(Constants.ATTRIBUTE_NAME)) {
149: connector.setName(attributes.getValue(idx));
150: }
151: }
152: }
153: }
154: } else if (qName.equals(Constants.THREADINFO)) {
155: threadinfo = factory.createThreadInfo();
156: if (stacktree.peek() instanceof Connector) {
157: stacktree.push(threadinfo);
158: connector.setThreadInfo(threadinfo);
159: if (attributes != null) {
160: for (int idx = 0; idx < attributes.getLength(); idx++) {
161: String attr = attributes.getQName(idx);
162: if (attr.equals(Constants.MAXTHREADS)) {
163: threadinfo
164: .setMaxThreads(parseInt(attributes
165: .getValue(idx)));
166: } else if (attr
167: .equals(Constants.MINSPARETHREADS)) {
168: threadinfo
169: .setMinSpareThreads(parseInt(attributes
170: .getValue(idx)));
171: } else if (attr
172: .equals(Constants.MAXSPARETHREADS)) {
173: threadinfo
174: .setMaxSpareThreads(parseInt(attributes
175: .getValue(idx)));
176: } else if (attr
177: .equals(Constants.CURRENTTHREADCOUNT)) {
178: threadinfo
179: .setCurrentThreadCount(parseInt(attributes
180: .getValue(idx)));
181: } else if (attr
182: .equals(Constants.CURRENTBUSYTHREADS)) {
183: threadinfo
184: .setCurrentThreadsBusy(parseInt(attributes
185: .getValue(idx)));
186: }
187: }
188: }
189: }
190: } else if (qName.equals(Constants.REQUESTINFO)) {
191: requestinfo = factory.createRequestInfo();
192: if (stacktree.peek() instanceof Connector) {
193: stacktree.push(requestinfo);
194: connector.setRequestInfo(requestinfo);
195: if (attributes != null) {
196: for (int idx = 0; idx < attributes.getLength(); idx++) {
197: String attr = attributes.getQName(idx);
198: if (attr.equals(Constants.MAXTIME)) {
199: requestinfo.setMaxTime(parseInt(attributes
200: .getValue(idx)));
201: } else if (attr
202: .equals(Constants.PROCESSINGTIME)) {
203: requestinfo
204: .setProcessingTime(parseInt(attributes
205: .getValue(idx)));
206: } else if (attr.equals(Constants.REQUESTCOUNT)) {
207: requestinfo
208: .setRequestCount(parseInt(attributes
209: .getValue(idx)));
210: } else if (attr.equals(Constants.ERRORCOUNT)) {
211: requestinfo
212: .setErrorCount(parseInt(attributes
213: .getValue(idx)));
214: } else if (attr.equals(Constants.BYTESRECEIVED)) {
215: requestinfo
216: .setBytesReceived(parseLong(attributes
217: .getValue(idx)));
218: } else if (attr.equals(Constants.BYTESSENT)) {
219: requestinfo
220: .setBytesSent(parseLong(attributes
221: .getValue(idx)));
222: }
223: }
224: }
225: }
226: } else if (qName.equals(Constants.WORKERS)) {
227: workers = factory.createWorkers();
228: if (stacktree.peek() instanceof Connector) {
229: connector.setWorkers(workers);
230: stacktree.push(workers);
231: }
232: } else if (qName.equals(Constants.WORKER)) {
233: worker = factory.createWorker();
234: if (stacktree.peek() instanceof Workers
235: || stacktree.peek() instanceof Worker) {
236: stacktree.push(worker);
237: ((WorkersImpl) workers).addWorker(worker);
238: if (attributes != null) {
239: for (int idx = 0; idx < attributes.getLength(); idx++) {
240: String attr = attributes.getQName(idx);
241: if (attr.equals(Constants.STAGE)) {
242: worker.setStage(attributes.getValue(idx));
243: } else if (attr
244: .equals(Constants.REQUESTPROCESSINGTIME)) {
245: worker
246: .setRequestProcessingTime(parseInt(attributes
247: .getValue(idx)));
248: } else if (attr
249: .equals(Constants.REQUESTBYTESSENT)) {
250: worker
251: .setRequestBytesSent(parseLong(attributes
252: .getValue(idx)));
253: } else if (attr
254: .equals(Constants.REQUESTBYTESRECEIVED)) {
255: worker
256: .setRequestBytesReceived(parseLong(attributes
257: .getValue(idx)));
258: } else if (attr.equals(Constants.REMOTEADDR)) {
259: worker.setRemoteAddr(attributes
260: .getValue(idx));
261: } else if (attr.equals(Constants.VIRTUALHOST)) {
262: worker.setVirtualHost(attributes
263: .getValue(idx));
264: } else if (attr.equals(Constants.METHOD)) {
265: worker.setMethod(attributes.getValue(idx));
266: } else if (attr.equals(Constants.CURRENTURI)) {
267: worker.setCurrentUri(attributes
268: .getValue(idx));
269: } else if (attr
270: .equals(Constants.CURRENTQUERYSTRING)) {
271: worker.setCurrentQueryString(attributes
272: .getValue(idx));
273: } else if (attr.equals(Constants.PROTOCOL)) {
274: worker
275: .setProtocol(attributes
276: .getValue(idx));
277: }
278: }
279: }
280: }
281: }
282: }
283:
284: /**
285: * Receive notification of the end of an element.
286: *
287: * <p>
288: * By default, do nothing. Application writers may override this method in a
289: * subclass to take specific actions at the end of each element (such as
290: * finalising a tree node or writing output to a file).
291: * </p>
292: *
293: * @param uri
294: * @param localName
295: * The element type name.
296: * @param qName
297: * The specified or defaulted attributes.
298: * @exception org.xml.sax.SAXException
299: * Any SAX exception, possibly wrapping another exception.
300: * @see org.xml.sax.ContentHandler#endElement
301: */
302: public void endElement(String uri, String localName, String qName)
303: throws SAXException {
304: if (qName.equals(Constants.STATUS)) {
305: if (stacktree.peek() instanceof Status) {
306: stacktree.pop();
307: }
308: } else if (qName.equals(Constants.JVM)) {
309: if (stacktree.peek() instanceof Jvm) {
310: stacktree.pop();
311: }
312: } else if (qName.equals(Constants.MEMORY)) {
313: if (stacktree.peek() instanceof Memory) {
314: stacktree.pop();
315: }
316: } else if (qName.equals(Constants.CONNECTOR)) {
317: if (stacktree.peek() instanceof Connector
318: || stacktree.peek() instanceof Connector) {
319: stacktree.pop();
320: }
321: } else if (qName.equals(Constants.THREADINFO)) {
322: if (stacktree.peek() instanceof ThreadInfo) {
323: stacktree.pop();
324: }
325: } else if (qName.equals(Constants.REQUESTINFO)) {
326: if (stacktree.peek() instanceof RequestInfo) {
327: stacktree.pop();
328: }
329: } else if (qName.equals(Constants.WORKERS)) {
330: if (stacktree.peek() instanceof Workers) {
331: stacktree.pop();
332: }
333: } else if (qName.equals(Constants.WORKER)) {
334: if (stacktree.peek() instanceof Worker
335: || stacktree.peek() instanceof Worker) {
336: stacktree.pop();
337: }
338: }
339: }
340:
341: /**
342: * Receive notification of character data inside an element.
343: *
344: * <p>
345: * By default, do nothing. Application writers may override this method to
346: * take specific actions for each chunk of character data (such as adding
347: * the data to a node or buffer, or printing it to a file).
348: * </p>
349: *
350: * @param ch
351: * The characters.
352: * @param start
353: * The start position in the character array.
354: * @param length
355: * The number of characters to use from the character array.
356: * @exception org.xml.sax.SAXException
357: * Any SAX exception, possibly wrapping another exception.
358: * @see org.xml.sax.ContentHandler#characters
359: */
360: public void characters(char ch[], int start, int length)
361: throws SAXException {
362: }
363:
364: /**
365: * Convienance method for parsing long. If the string was not a number, the
366: * method returns zero.
367: *
368: * @param data
369: * @return the value as a long
370: */
371: public long parseLong(String data) {
372: long val = 0;
373: if (data.length() > 0) {
374: try {
375: val = Long.parseLong(data);
376: } catch (NumberFormatException e) {
377: val = 0;
378: }
379: }
380: return val;
381: }
382:
383: /**
384: * Convienance method for parsing integers.
385: *
386: * @param data
387: * @return the value as an integer
388: */
389: public int parseInt(String data) {
390: int val = 0;
391: if (data.length() > 0) {
392: try {
393: val = Integer.parseInt(data);
394: } catch (NumberFormatException e) {
395: val = 0;
396: }
397: }
398: return val;
399: }
400:
401: /**
402: * method returns the status object.
403: *
404: * @return the status
405: */
406: public Status getContents() {
407: return this.status;
408: }
409: }
|