001: /* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.channels;
007:
008: import java.sql.SQLException;
009: import java.util.Map;
010:
011: import javax.xml.parsers.DocumentBuilderFactory;
012: import javax.xml.parsers.ParserConfigurationException;
013:
014: import org.jasig.portal.ChannelRuntimeData;
015: import org.jasig.portal.ChannelStaticData;
016: import org.jasig.portal.PortalEvent;
017: import org.jasig.portal.PortalException;
018: import org.w3c.dom.Document;
019: import org.xml.sax.Attributes;
020: import org.xml.sax.ContentHandler;
021: import org.xml.sax.Locator;
022: import org.xml.sax.SAXException;
023:
024: import junit.framework.TestCase;
025:
026: /**
027: * Testcase for CGenericXSLT.
028: * We test basics like making the ChannelStaticData and ChannelRuntimeData
029: * available to subclasses, spot check proper response to exceptions, and test
030: * some edge behaviors with null return values.
031: * We notably do not currently test but should test applying a valid XSLT to
032: * valid XML with valid parameters.
033: * @version $Revision: 35694 $ $Date: 2005-04-30 12:41:36 -0700 (Sat, 30 Apr 2005) $
034: */
035: public class CAbstractXsltTest extends TestCase {
036:
037: // TODO: test the case where everything is working as expected.
038:
039: protected void setUp() throws Exception {
040: super .setUp();
041: }
042:
043: protected void tearDown() throws Exception {
044: super .tearDown();
045: }
046:
047: /**
048: * Test that CAbstractXSLT exposes to its subclasses the runtime data it receives.
049: */
050: public void testGetRuntimeData() {
051:
052: MockXSLTChannel instance = new MockXSLTChannel();
053: assertNull(instance.getRuntimeData());
054:
055: ChannelRuntimeData runtimeDataA = new ChannelRuntimeData();
056: instance.setRuntimeData(runtimeDataA);
057: assertSame(runtimeDataA, instance.getRuntimeData());
058:
059: ChannelRuntimeData runtimeDataB = new ChannelRuntimeData();
060: instance.setRuntimeData(runtimeDataB);
061:
062: }
063:
064: /**
065: * Test that CAbstractXSLT exposes to its subclasses the static data it receives.
066: */
067: public void testGetStaticData() {
068: MockXSLTChannel instance = new MockXSLTChannel();
069:
070: assertNull(instance.getStaticData());
071:
072: ChannelStaticData sd = new ChannelStaticData();
073: instance.setStaticData(sd);
074: assertSame(sd, instance.getStaticData());
075: }
076:
077: /**
078: * Test that when we try to renderXML on an implementation that returns a
079: * null Document for getXml, we throw IllegalStateException.
080: * @throws PortalException
081: */
082: public void testRenderXMLNullDocument() throws PortalException {
083: try {
084: MockXSLTChannel instance = new MockXSLTChannel();
085: instance.setStaticData(new ChannelStaticData());
086: instance.setRuntimeData(new ChannelRuntimeData());
087: instance.renderXML(new DummyContentHandler());
088: } catch (IllegalStateException ise) {
089: // expected
090: return;
091: }
092: fail("Expected to fail with IllegalStateException because our XML was null.");
093: }
094:
095: /**
096: * Test that when getXml() throws a RuntimeException that exception
097: * is thrown by renderXML().
098: * @throws PortalException
099: */
100: public void testRenderXMLGetXmlThrowsRuntimeException()
101: throws PortalException {
102: RuntimeException runtimeException = new RuntimeException();
103:
104: MockXSLTChannel mock = new MockXSLTChannel();
105: mock.setStaticData(new ChannelStaticData());
106: mock.setRuntimeData(new ChannelRuntimeData());
107: mock.setThrownFromGetXml(runtimeException);
108:
109: try {
110: mock.renderXML(new DummyContentHandler());
111: } catch (RuntimeException rte) {
112: assertSame(runtimeException, rte);
113: // good, expected throw behavior.
114: return;
115: }
116: }
117:
118: /**
119: * Test that when getXstlUri() throws a PortalException that exception
120: * is thrown by renderXML().
121: * @throws ParserConfigurationException
122: */
123: public void testRenderXMLGetXsltUriThrowsPortalException()
124: throws ParserConfigurationException {
125: PortalException portalException = new PortalException();
126:
127: MockXSLTChannel mock = new MockXSLTChannel();
128: mock.setStaticData(new ChannelStaticData());
129: mock.setRuntimeData(new ChannelRuntimeData());
130: Document blankDoc = DocumentBuilderFactory.newInstance()
131: .newDocumentBuilder().newDocument();
132: mock.setDocument(blankDoc);
133: mock.setThrownFromGetXsltUri(portalException);
134:
135: try {
136: mock.renderXML(new DummyContentHandler());
137: } catch (PortalException pe) {
138: assertSame(portalException, pe);
139: // good, expected throw behavior.
140: return;
141: }
142: fail("Should have thrown the PortalException that getXsltUri() threw.");
143: }
144:
145: /**
146: * Test that when getStylesheetParams() throws SQLException
147: * the renderXML() implementation properly wraps that exception into a
148: * PortalException in conformance with the IChannel API.
149: * @throws ParserConfigurationException
150: */
151: public void testRenderXMLGetStylesheetParamsThrowsSqlException()
152: throws ParserConfigurationException {
153: SQLException sqlException = new SQLException();
154:
155: MockXSLTChannel mock = new MockXSLTChannel();
156: mock.setStaticData(new ChannelStaticData());
157: mock.setRuntimeData(new ChannelRuntimeData());
158: Document blankDoc = DocumentBuilderFactory.newInstance()
159: .newDocumentBuilder().newDocument();
160: mock.setDocument(blankDoc);
161: mock.setXsltUriString("anxslt.xsl");
162: mock.setThrownFromGetStylesheetParams(sqlException);
163:
164: try {
165: mock.renderXML(new DummyContentHandler());
166: } catch (PortalException pe) {
167: assertSame(sqlException, pe.getCause());
168: // good, expected throw behavior.
169: return;
170: }
171: fail("Should have thrown a PortalException wrapping the SqlException that getStylesheetParams() threw.");
172: }
173:
174: /**
175: * A Mock implementation of CAbstractXSLT that provides configuration points
176: * for scripting the template method return values or exception throw behavior.
177: */
178: private class MockXSLTChannel extends CAbstractXslt {
179:
180: /**
181: * The Document that getXml() will return when thrownFromGetXml
182: * is null.
183: */
184: private Document document;
185:
186: /**
187: * When not null, the Exception that will be thrown from getXml().
188: */
189: private Exception thrownFromGetXml;
190:
191: /**
192: * The String that getXsltUri() will return when thrownFromGetXsltUri is null.
193: */
194: private String xsltUriString;
195:
196: /**
197: * When not null, the Exception that will be thrown from
198: * getXsltUri().
199: */
200: private Exception thrownFromGetXsltUri;
201:
202: /**
203: * The Map that getStylesheetParams() will return except when
204: * thrownFromGetStylesheetParams is not null.
205: */
206: private Map stylesheetParamMap;
207:
208: /**
209: * When not null, the Exception that getStylesheetParams() will throw.
210: */
211: private Exception thrownFromGetStylesheetParams;
212:
213: protected Document getXml() throws Exception {
214: /*
215: * This mock implementation responds to this method call in the
216: * configured way. If we have an Exception to throw we throw it,
217: * otherwise we return the configured return value.
218: */
219: if (this .thrownFromGetXml != null) {
220: throw this .thrownFromGetXml;
221: }
222:
223: return this .document;
224: }
225:
226: protected String getXsltUri() throws Exception {
227: /*
228: * This mock implementation responds to this method call in the
229: * configured way. If we have an Exception to throw we throw it,
230: * otherwise we return the configured return value.
231: */
232: if (this .thrownFromGetXsltUri != null) {
233: throw this .thrownFromGetXsltUri;
234: }
235:
236: return this .xsltUriString;
237: }
238:
239: protected Map getStylesheetParams() throws Exception {
240: /*
241: * This mock implementation responds to this method call in the
242: * configured way. If we have an Exception to throw we throw it,
243: * otherwise we return the configured return value.
244: */
245:
246: if (this .thrownFromGetStylesheetParams != null) {
247: throw this .thrownFromGetStylesheetParams;
248: }
249:
250: return this .stylesheetParamMap;
251: }
252:
253: public void receiveEvent(PortalEvent ev) {
254: // do nothing
255: }
256:
257: /**
258: * Get the Document we will return on getXml() when we do not throw.
259: * @return the Document we will return on getXml() when we do not throw.
260: */
261: Document getDocument() {
262: return this .document;
263: }
264:
265: /**
266: * Set the Document we will return for getXml() where we do not throw.
267: * @param document Document we will return on getXml() where we do not throw.
268: */
269: void setDocument(Document document) {
270: this .document = document;
271: }
272:
273: /**
274: * Get the Map we should return on invocation of getStylesheetParams() where
275: * we do not throw.
276: * @return the Map we will return on getStylesheetParams() when we do not throw.
277: */
278: Map getStylesheetParamMap() {
279: return this .stylesheetParamMap;
280: }
281:
282: /**
283: * Set the Map we will return on invocation of getStylesheetParams() in the case
284: * where we do not throw.
285: * @param stylesheetParamMap Map we should return on getStylesheetParams().
286: */
287: void setStylesheetParamMap(Map stylesheetParamMap) {
288: this .stylesheetParamMap = stylesheetParamMap;
289: }
290:
291: /**
292: * Get the Throwable that we will throw on invocation of getStylesheetParams(),
293: * or null if we will not throw.
294: * @return the Throwable we will throw on getStylesheetParams(), or null if we will not throw.
295: */
296: Throwable getThrownFromGetStylesheetParams() {
297: return this .thrownFromGetStylesheetParams;
298: }
299:
300: /**
301: * Set the Throwable we should throw on invocation of getStylesheetParams().
302: * Set to null to configure not to throw on invocation of getStylesheetParams().
303: * @param thrownFromGetStylesheetParams Exception to throw, or null not to throw.
304: */
305: void setThrownFromGetStylesheetParams(
306: Exception thrownFromGetStylesheetParams) {
307: this .thrownFromGetStylesheetParams = thrownFromGetStylesheetParams;
308: }
309:
310: /**
311: * Get the Throwable we will throw on invocations of getXml(), or null if
312: * we will not throw.
313: * @return the Exception we will throw on getXml() or null if we will not throw.
314: */
315: Exception getThrownFromGetXml() {
316: return this .thrownFromGetXml;
317: }
318:
319: /**
320: * Set the Throwable we will throw on invocations of getXml().
321: * Set to null to configure not to throw on invocations of
322: * getXml() and instead return our document.
323: * @param thrownFromGetXml Exception to throw or null to not throw.
324: */
325: void setThrownFromGetXml(Exception thrownFromGetXml) {
326: this .thrownFromGetXml = thrownFromGetXml;
327: }
328:
329: /**
330: * Get the Throwable that we will throw on invocation of getXsltUri(), or
331: * null if we will not throw.
332: * @return the Throwable we will throw, or null if we will not throw.
333: */
334: Throwable getThrownFromGetXsltUri() {
335: return this .thrownFromGetXsltUri;
336: }
337:
338: /**
339: * Set the Throwable that we will throw on getXsltUri() invocations.
340: * When set to null, we will not throw but will instead return the String
341: * we are configured to return. When set to a non-null, we will throw
342: * rather than return the String.
343: * @param thrownFromGetXsltUri a Exception or null indicating do not throw.
344: */
345: void setThrownFromGetXsltUri(Exception thrownFromGetXsltUri) {
346: this .thrownFromGetXsltUri = thrownFromGetXsltUri;
347: }
348:
349: /**
350: * Get the String that we will return on getXsltUri() invocations
351: * when we do not throw anything.
352: * @return Returns the String we will return on getXsltUri() invocations.
353: */
354: String getXsltUriString() {
355: return this .xsltUriString;
356: }
357:
358: /**
359: * Set the String that this Mock Object will return for invocations of
360: * getXsltUri(). This setting will be overridden when we are configured to
361: * throw a Throwable on getXsltUri() invocation.
362: * @param xsltUriString The String we should return when we do not throw.
363: */
364: void setXsltUriString(String xsltUriString) {
365: this .xsltUriString = xsltUriString;
366: }
367: }
368:
369: /**
370: * A totally uninteresting stub ContentHandler that we use to test renderXML
371: * exception handling behavior.
372: */
373: private static class DummyContentHandler implements ContentHandler {
374:
375: public void setDocumentLocator(Locator locator) {
376: // do nothing
377: }
378:
379: public void startDocument() throws SAXException {
380: // do nothing
381: }
382:
383: public void endDocument() throws SAXException {
384: // do nothing
385: }
386:
387: public void startPrefixMapping(String prefix, String uri)
388: throws SAXException {
389: // do nothing
390: }
391:
392: public void endPrefixMapping(String prefix) throws SAXException {
393: // do nothing
394: }
395:
396: public void startElement(String namespaceURI, String localName,
397: String qName, Attributes atts) throws SAXException {
398: // do nothing
399: }
400:
401: public void endElement(String namespaceURI, String localName,
402: String qName) throws SAXException {
403: // do nothing
404: }
405:
406: public void characters(char[] ch, int start, int length)
407: throws SAXException {
408: // do nothing
409: }
410:
411: public void ignorableWhitespace(char[] ch, int start, int length)
412: throws SAXException {
413: // do nothing
414: }
415:
416: public void processingInstruction(String target, String data)
417: throws SAXException {
418: // do nothing
419: }
420:
421: public void skippedEntity(String name) throws SAXException {
422: // do nothing
423: }
424: }
425:
426: }
|