View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.common.content.transformer;
20  
21  import java.io.IOException;
22  import java.util.Arrays;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import javax.xml.transform.sax.TransformerHandler;
27  
28  import org.jdom2.Content;
29  import org.jdom2.DefaultJDOMFactory;
30  import org.jdom2.Document;
31  import org.jdom2.JDOMFactory;
32  import org.jdom2.Text;
33  import org.jdom2.transform.JDOMResult;
34  import org.mycore.common.MCRCache;
35  import org.mycore.common.MCRConstants;
36  import org.mycore.common.config.MCRConfigurationException;
37  import org.mycore.common.content.MCRContent;
38  import org.mycore.common.content.MCRJDOMContent;
39  import org.xml.sax.SAXException;
40  import org.xml.sax.XMLReader;
41  
42  /**
43   * Transforms XML content using a static XSL stylesheet.
44   * The stylesheet is configured via
45   * 
46   * MCR.ContentTransformer.{ID}.Stylesheet
47   * 
48   * Resulting MCRContent holds XML.
49   * Use {@link MCRXSLTransformer} if you want to produce non XML output.
50   * @author Thomas Scheffler (yagee)
51   *
52   */
53  public class MCRXSL2XMLTransformer extends MCRXSLTransformer {
54  
55      private static MCRCache<String, MCRXSL2XMLTransformer> INSTANCE_CACHE = new MCRCache<>(100,
56          "MCRXSLTransformer instance cache");
57  
58      public MCRXSL2XMLTransformer() {
59          super();
60      }
61  
62      public MCRXSL2XMLTransformer(String... stylesheets) {
63          super(stylesheets);
64      }
65  
66      public static MCRXSL2XMLTransformer getInstance(String... stylesheets) {
67          String key = stylesheets.length == 1 ? stylesheets[0] : Arrays.toString(stylesheets);
68          MCRXSL2XMLTransformer instance = INSTANCE_CACHE.get(key);
69          if (instance == null) {
70              instance = new MCRXSL2XMLTransformer(stylesheets);
71              INSTANCE_CACHE.put(key, instance);
72          }
73          return instance;
74      }
75  
76      @Override
77      protected MCRContent getTransformedContent(MCRContent source, XMLReader reader,
78          TransformerHandler transformerHandler) throws IOException, SAXException {
79          JDOMResult result = new JDOMResult();
80          transformerHandler.setResult(result);
81          // Parse the source XML, and send the parse events to the
82          // TransformerHandler.
83          reader.parse(source.getInputSource());
84          Document resultDoc = getDocument(result);
85          if (resultDoc == null) {
86              throw new MCRConfigurationException("Stylesheets " + Arrays.asList(templateSources)
87                  + " does not return any content for " + source.getSystemId());
88          }
89          return new MCRJDOMContent(resultDoc);
90      }
91  
92      private Document getDocument(JDOMResult result) {
93          Document resultDoc = result.getDocument();
94          if (resultDoc == null) {
95              //Sometimes a transformation produces whitespace strings
96              //JDOM would produce a empty document if it detects those
97              //So we remove them, if they exists.
98              List<Content> transformResult = result.getResult();
99              int origSize = transformResult.size();
100             Iterator<Content> iterator = transformResult.iterator();
101             while (iterator.hasNext()) {
102                 Content content = iterator.next();
103                 if (content instanceof Text) {
104                     String trimmedText = ((Text) content).getTextTrim();
105                     if (trimmedText.length() == 0) {
106                         iterator.remove();
107                     }
108                 }
109             }
110             if (transformResult.size() < origSize) {
111                 JDOMFactory f = result.getFactory();
112                 if (f == null) {
113                     f = new DefaultJDOMFactory();
114                 }
115                 resultDoc = f.document(null);
116                 resultDoc.setContent(transformResult);
117             }
118         }
119         return resultDoc;
120     }
121 
122     @Override
123     protected String getDefaultExtension() {
124         return "xml";
125     }
126 
127     @Override
128     public String getEncoding() {
129         return MCRConstants.DEFAULT_ENCODING;
130     }
131 
132 }