001: /*
002: * @(#)DefaultMonitor.java
003: *
004: * Copyright (C) 2002-2003 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Part of the GroboUtils package at:
009: * http://groboutils.sourceforge.net
010: *
011: * Permission is hereby granted, free of charge, to any person obtaining a
012: * copy of this software and associated documentation files (the "Software"),
013: * to deal in the Software without restriction, including without limitation
014: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
015: * and/or sell copies of the Software, and to permit persons to whom the
016: * Software is furnished to do so, subject to the following conditions:
017: *
018: * The above copyright notice and this permission notice shall be included in
019: * all copies or substantial portions of the Software.
020: *
021: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
022: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
024: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
025: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
026: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
027: * DEALINGS IN THE SOFTWARE.
028: */
029: package net.sourceforge.groboutils.autodoc.v1.testserver;
030:
031: import java.util.Hashtable;
032:
033: import org.apache.log4j.Logger;
034:
035: /**
036: * This implemenation of <tt>Monitor</tt> uses a Hashtable to store the
037: * test data.
038: *
039: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
040: * @since March 17, 2002
041: * @version $Date: 2003/05/27 13:30:16 $
042: */
043: public class DefaultMonitor implements Monitor {
044: private static final Logger LOG = Logger
045: .getLogger(DefaultMonitor.class);
046:
047: private Hashtable testData = new Hashtable();
048: private TestDataFactory dataFactory;
049: private Server server;
050:
051: /**
052: * Constructor for a Monitor requiring a reference to the Server which will
053: * receive the completed <tt>TestData</tt> structures, and a reference to
054: * a factory for creating new <tt>TestData</tt> instances for the particular
055: * framework this Monitor belongs to.
056: *
057: * @param s the server to receive completed <tt>TestData</tt> entities.
058: * This cannot be <tt>null</tt>.
059: * @param f the factory in charge of creating new <tt>TestData</tt>
060: * entities. This cannot be <tt>null</tt>.
061: * @exception IllegalArgumentException if <tt>s</tt> or <tt>f</tt> is
062: * <tt>null</tt>.
063: */
064: public DefaultMonitor(Server s, TestDataFactory f) {
065: if (s == null || f == null) {
066: throw new IllegalArgumentException("no null arguments");
067: }
068: this .server = s;
069: this .dataFactory = f;
070: }
071:
072: /**
073: * Adds a new <tt>TestData</tt> instance related to the given
074: * <tt>TestInfo</tt>. If there already is a <tt>TestData</tt> for the
075: * given <tt>TestInfo</tt>, then an exception is thrown.
076: *
077: * @param info the unique test identifier to create a new <tt>TestData</tt>
078: * instance for.
079: * @exception IllegalStateException if <tt>info</tt> is already
080: * been added without having been sent.
081: * @exception IllegalArgumentException if <tt>info</tt> is <tt>null</tt>.
082: */
083: public void addTestData(TestInfo info) {
084: assertNotNull(info);
085: synchronized (this .testData) {
086: if (this .testData.containsKey(info)) {
087: throw new IllegalStateException("Test " + info
088: + " has already been registered.");
089: }
090: LOG.debug("**** Monitor " + this + " adding test " + info);
091: TestData td = createTestData(info);
092: this .testData.put(info, td);
093: }
094: }
095:
096: /**
097: * Retrieves the data associated with the given <tt>TestInfo</tt>, as was
098: * created through {@link #addTestData( TestInfo )}. If the <tt>info</tt>
099: * was never passed to the add method, then an exception is thrown.
100: *
101: * @param info the unique test identifier
102: * @exception IllegalStateException if <tt>info</tt> has not been added,
103: * or has been removed through the send call.
104: * @exception IllegalArgumentException if <tt>info</tt> is <tt>null</tt>.
105: */
106: public TestData getTestData(TestInfo info) {
107: assertNotNull(info);
108: synchronized (this .testData) {
109: TestData td = (TestData) this .testData.get(info);
110: assertNotNull(td);
111: return td;
112: }
113: }
114:
115: /**
116: * Sends the <tt>TestData</tt> associated with <tt>info</tt> to the
117: * inner server, and removes the data from the inner cache. If the
118: * <tt>info</tt> has not been added, then an exception is thrown.
119: *
120: * @param info the unique test identifier
121: * @exception IllegalStateException if <tt>info</tt> has not been added,
122: * or has been removed through the send call.
123: * @exception IllegalArgumentException if <tt>info</tt> is <tt>null</tt>.
124: */
125: public void sendTestData(TestInfo info) {
126: assertNotNull(info);
127: TestData td;
128: synchronized (this .testData) {
129: td = (TestData) this .testData.remove(info);
130: }
131: LOG.debug("**** Monitor " + this + " removing test " + info);
132: sendTestDataToServer(td);
133: }
134:
135: /**
136: * Creates a new TestData instance for the info object through the
137: * factory. This is guaranteed to never return <tt>null</tt>.
138: *
139: * @param info the unique test identifier
140: * @exception IllegalStateException if the factory returns <tt>null</tt>.
141: */
142: protected TestData createTestData(TestInfo info) {
143: TestData td = this .dataFactory.createTestData(info);
144: if (td == null) {
145: throw new IllegalStateException("factory returned null");
146: }
147: return td;
148: }
149:
150: /**
151: * Retrieves the registered TestData instance for the info. This
152: * may return <tt>null</tt>.
153: *
154: * @param info the unique test identifier
155: */
156: protected TestData retrieveTestData(TestInfo info) {
157: TestData td = (TestData) this .testData.get(info);
158: return td;
159: }
160:
161: /**
162: * Sends off the test data to the server.
163: */
164: protected void sendTestDataToServer(TestData td) {
165: assertNotNull(td);
166: this .server.addTestData(td);
167: }
168:
169: /**
170: * Ensures that <tt>info</tt> is not <tt>null</tt>.
171: */
172: protected void assertNotNull(TestInfo info) {
173: if (info == null) {
174: throw new IllegalArgumentException("TestInfo was null");
175: }
176: }
177:
178: /**
179: * Ensures that <tt>td</tt> is not <tt>null</tt>.
180: */
181: protected void assertNotNull(TestData td) {
182: if (td == null) {
183: throw new IllegalStateException("Test is not registered.");
184: }
185: }
186: }
|