View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.edl.service.impl;
18  
19  
20  import junit.framework.AssertionFailedError;
21  import org.apache.log4j.Logger;
22  import org.junit.Test;
23  import org.kuali.rice.core.exception.RiceRuntimeException;
24  import org.kuali.rice.kew.edl.bo.EDocLiteStyle;
25  import org.kuali.rice.kew.edl.dao.EDocLiteDAO;
26  import org.kuali.rice.kew.edl.service.StyleService;
27  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
28  import org.kuali.rice.kew.service.KEWServiceLocator;
29  import org.kuali.rice.kew.test.KEWTestCase;
30  import org.kuali.rice.kew.test.TestUtilities;
31  
32  import javax.xml.transform.Templates;
33  import javax.xml.transform.TransformerConfigurationException;
34  import javax.xml.transform.TransformerException;
35  import javax.xml.transform.stream.StreamResult;
36  import javax.xml.transform.stream.StreamSource;
37  import java.io.*;
38  
39  
40  /**
41   * Tests StyleServiceImpl
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  public class StyleServiceImplTest extends KEWTestCase {
45      private static final Logger LOG = Logger.getLogger(StyleServiceImplTest.class);
46  
47  	@Test public void testLoadXML() throws FileNotFoundException {
48          loadXmlFile("style.xml");
49  
50          StyleService styleService = KEWServiceLocator.getStyleService();
51          assertNotNull("Style 'an_arbitrary_style' not found", styleService.getStyle("an_arbitrary_style"));
52  
53          assertTrue("Style not found among all styles", styleService.getStyleNames().contains("an_arbitrary_style"));
54  
55          EDocLiteStyle style = styleService.getStyle("an_arbitrary_style");
56          assertNotNull("'an_arbitrary_style' style not found", style);
57          assertEquals("an_arbitrary_style", style.getName());
58          assertNotNull(style.getActiveInd());
59          assertTrue(style.getActiveInd().booleanValue());
60          assertNotNull(style.getXmlContent());
61      }
62  
63  
64  	/**
65  	 * Tests automatic import of styles from files based on configuration properties.
66  	 * See edl.style.widgets in common-config-defualts.xml, edl.style.gidgets in kew-test-config.xml
67  	 */
68      @Test public void testLoadingFromConfiguredFile() {
69          StyleService styleService = KEWServiceLocator.getStyleService();
70          EDocLiteDAO dao = (EDocLiteDAO)KEWServiceLocator.getService("enEDocLiteDAO");
71  
72          String notThereStyle = "gidgets";
73          String isThereStyle = "widgets";
74  
75          // first verify that the database doesn't contain these styles already
76          assertNull(dao.getEDocLiteStyle(notThereStyle));
77          assertNull(dao.getEDocLiteStyle(isThereStyle));
78  
79          // test loading an incorrectly configured style
80          try {
81              // the configured location for the gidgets style doesn't contain a file
82              styleService.getStyle(notThereStyle);
83              fail("should have thrown " + RiceRuntimeException.class.getSimpleName());
84          } catch (RiceRuntimeException e) {
85              LOG.info("^^^ CAUGHT EXPECTED EXCEPTION ^^^");
86          } catch (Exception e) {
87              fail("Wrong exception type '" + e.getClass() + "', should have been '" + RiceRuntimeException.class.getCanonicalName() + "'");
88          }
89  
90          styleService.getStyle("widgets");
91          // should succeed in loading it's style into the database
92      }
93  
94      @Test public void testInclusions() throws FileNotFoundException, TransformerConfigurationException, TransformerException {
95          loadXmlFile("style.xml");
96  
97          StyleService styleService = KEWServiceLocator.getStyleService();
98  
99          // ignoring the duplicate definition via inclusion test as the behavior seems
100         // unspecified
101         // XML.com claims it is an "error": http://www.xml.com/pub/a/2000/11/01/xslt/index.html
102         // XLST 1.0 spec doesn't seem to specify anything regarding this: http://www.w3.org/TR/xslt
103         // Michael Kay's XSLT Programmer's Reference states "...it is implementation-defined
104         // whether an XSLT processor will report duplicate declarations as an error , so
105         // the behavior may vary from on product to another
106         // (although it is not clear to me whether he is speaking specifically of identical
107         // literal definitions introduced by re-inclusion of the same exact stylesheet twice, or
108         // "logical" duplication of template match criteria)
109         /*Templates t = styleService.getStyleAsTranslet("test_includer");
110         StringWriter w = new StringWriter();
111         StreamResult result = new StreamResult(w);
112         try {
113             t.newTransformer().transform(new StreamSource(new StringReader("<a/>")), result);
114             System.err.println(w.toString());
115             fail("Exception not thrown on ambiguous template defs");
116         } catch (Exception e) {
117             // expected
118         }*/
119 
120         Writer w = new StringWriter();
121         StreamResult result = new StreamResult(w);
122         Templates t = styleService.getStyleAsTranslet("test_includer2");
123         t.newTransformer().transform(new StreamSource(new StringReader("<a/>")), result);
124         assertEquals("oneoneoneoneone", w.toString());
125 
126         w = new StringWriter();
127         result = new StreamResult(w);
128         t.newTransformer().transform(new StreamSource(new StringReader("<b/>")), result);
129         assertEquals("22222", w.toString());
130 
131         w = new StringWriter();
132         result = new StreamResult(w);
133         t = styleService.getStyleAsTranslet("test_importer");
134         t.newTransformer().transform(new StreamSource(new StringReader("<a/>")), result);
135         assertEquals("aaaaa", w.toString());
136 
137         w = new StringWriter();
138         result = new StreamResult(w);
139         t.newTransformer().transform(new StreamSource(new StringReader("<b/>")), result);
140         assertEquals("BBBBB", w.toString());
141 
142         w = new StringWriter();
143         result = new StreamResult(w);
144         t.newTransformer().transform(new StreamSource(new StringReader("<c/>")), result);
145         assertEquals("CCCCC", w.toString());
146     }
147 
148     @Test public void testLoadBadDefinition() throws FileNotFoundException {
149         StyleService styleService = KEWServiceLocator.getStyleService();
150         try {
151             styleService.loadXml(TestUtilities.loadResource(getClass(), "badstyle.xml"), null);
152             fail("BadDefinition was successfully parsed.");
153         } catch (RuntimeException re) {
154             // should probably use type system to detect type of error, not just message string...
155             // maybe we need general parsing or "semantic" validation exception
156             assertTrue("Wrong exception occurred: " + re, re.getMessage().contains("Style 'style' element must contain a 'xsl:stylesheet' child element"));
157         }
158     }
159 
160     @Test public void testStoreStyle() {
161         StyleService styleService = KEWServiceLocator.getStyleService();
162         String styleXml = "<style></style>";
163         try {
164             styleService.saveStyle(new ByteArrayInputStream(styleXml.getBytes()));
165             throw new AssertionFailedError("Storing style with no name succeeded");
166         } catch (WorkflowServiceErrorException wsee) {
167             // expected due to lack of name
168         }
169         styleXml = "<style name=\"test\"></style>";
170         try {
171             styleService.saveStyle(new ByteArrayInputStream(styleXml.getBytes()));
172             throw new AssertionFailedError("Storing style with no xsl:stylesheet element succeeded");
173         } catch (WorkflowServiceErrorException wsee) {
174             // expected due to lack of stylesheet content
175         }
176         styleXml = "<style name=\"test\"><xsl:stylesheet></xsl:stylesheet></style>";
177         styleService.saveStyle(new ByteArrayInputStream(styleXml.getBytes()));
178         EDocLiteStyle style = styleService.getStyle("test");
179         assertNotNull(style);
180         assertEquals("test", style.getName());
181         assertNotNull(style);
182         assertNotNull(style.getXmlContent());
183     }
184 
185     /**
186      * Tests the caching of "styles" in StyleServiceImpl.
187      *
188      * The style cache is really a cache of java.xml.transform.Templates objects which represent
189      * the "compiled" stylesheets.
190      */
191     @Test public void testStyleCaching() throws Exception {
192         loadXmlFile("style.xml");
193 
194         // try to grab the templates out of the cache, it shouldn't be cached yet
195         Templates cachedTemplates = new StyleServiceImpl().fetchTemplatesFromCache("an_arbitrary_style");
196         assertNull("The default style template should not be cached yet.", cachedTemplates);
197 
198         // fetch the Templates object from the service
199         Templates templates = KEWServiceLocator.getStyleService().getStyleAsTranslet("an_arbitrary_style");
200         assertNotNull("Templates should not be null.", templates);
201         templates = KEWServiceLocator.getStyleService().getStyleAsTranslet("an_arbitrary_style");
202         assertNotNull("Templates should not be null.", templates);
203 
204         // the Templates should now be cached
205         cachedTemplates = new StyleServiceImpl().fetchTemplatesFromCache("an_arbitrary_style");
206         assertNotNull("Templates should now be cached.", cachedTemplates);
207 
208         // the cached Templates should be the same as the Templates we fetched from the service
209         assertEquals("Templates should be the same.", templates, cachedTemplates);
210 
211         // now re-import the style and the templates should no longer be cached
212         loadXmlFile("style.xml");
213         cachedTemplates = new StyleServiceImpl().fetchTemplatesFromCache("an_arbitrary_style");
214         assertNull("After re-import, the Default style Templates should no longer be cached.", cachedTemplates);
215 
216         // re-fetch the templates from the service and verify they are in the cache
217         Templates newTemplates = KEWServiceLocator.getStyleService().getStyleAsTranslet("an_arbitrary_style");
218         assertNotNull("Templates should not be null.", templates);
219         newTemplates = KEWServiceLocator.getStyleService().getStyleAsTranslet("an_arbitrary_style");
220         assertNotNull("Templates should not be null.", templates);
221 
222         cachedTemplates = new StyleServiceImpl().fetchTemplatesFromCache("an_arbitrary_style");
223         assertNotNull("Templates should now be cached.", cachedTemplates);
224 
225         // lastly, check that the newly cached templates are not the same as the original templates
226         assertFalse("Old Templates should be different from new Templates.", templates.equals(newTemplates));
227 
228     }
229 }