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