1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.helger.schematron.xslt;
18
19 import java.io.File;
20
21 import javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23 import javax.annotation.concurrent.NotThreadSafe;
24 import javax.xml.transform.Templates;
25 import javax.xml.transform.Transformer;
26 import javax.xml.transform.TransformerConfigurationException;
27 import javax.xml.transform.dom.DOMResult;
28
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31 import org.w3c.dom.Document;
32
33 import com.helger.commons.ValueEnforcer;
34 import com.helger.commons.io.file.FilenameHelper;
35 import com.helger.commons.io.file.SimpleFileIO;
36 import com.helger.commons.io.resource.ClassPathResource;
37 import com.helger.commons.io.resource.IReadableResource;
38 import com.helger.schematron.saxon.SchematronTransformerFactory;
39 import com.helger.schematron.xslt.SCHTransformerCustomizer.EStep;
40 import com.helger.xml.serialize.write.XMLWriter;
41 import com.helger.xml.serialize.write.XMLWriterSettings;
42 import com.helger.xml.transform.TransformSourceFactory;
43 import com.helger.xml.transform.XMLTransformerFactory;
44
45
46
47
48
49
50
51
52 @NotThreadSafe
53 final class SchematronProviderXSLTFromSCH implements ISchematronXSLTBasedProvider
54 {
55 private static final Logger s_aLogger = LoggerFactory.getLogger (SchematronProviderXSLTFromSCH.class);
56
57
58
59
60 private static final String SCHEMATRON_DIRECTORY_XSLT2 = "schematron/20100414-xslt2/";
61
62
63
64
65 private static final String XSLT2_STEP1 = SCHEMATRON_DIRECTORY_XSLT2 + "iso_dsdl_include.xsl";
66
67
68
69
70 private static final String XSLT2_STEP2 = SCHEMATRON_DIRECTORY_XSLT2 + "iso_abstract_expand.xsl";
71
72
73
74
75 private static final String XSLT2_STEP3 = SCHEMATRON_DIRECTORY_XSLT2 + "iso_svrl_for_xslt2.xsl";
76
77
78
79
80 private static final boolean SAVE_INTERMEDIATE_FILES = false;
81
82 private static Templates s_aStep1;
83 private static Templates s_aStep2;
84 private static Templates s_aStep3;
85
86 private final IReadableResource m_aSchematronResource;
87 private Document m_aSchematronXSLTDoc;
88 private Templates m_aSchematronXSLTTemplates;
89
90
91
92
93
94
95
96
97
98
99 public SchematronProviderXSLTFromSCH (@Nonnull final IReadableResource aSchematronResource,
100 @Nonnull final SCHTransformerCustomizer aTransformerCustomizer)
101 {
102 m_aSchematronResource = ValueEnforcer.notNull (aSchematronResource, "SchematronResource");
103 ValueEnforcer.notNull (aTransformerCustomizer, "TransformerCustomizer");
104
105 try
106 {
107
108 if (s_aStep1 == null)
109 s_aStep1 = XMLTransformerFactory.newTemplates (SchematronTransformerFactory.getDefaultSaxonFirst (),
110 new ClassPathResource (XSLT2_STEP1));
111 if (s_aStep2 == null)
112 s_aStep2 = XMLTransformerFactory.newTemplates (SchematronTransformerFactory.getDefaultSaxonFirst (),
113 new ClassPathResource (XSLT2_STEP2));
114 if (s_aStep3 == null)
115 s_aStep3 = XMLTransformerFactory.newTemplates (SchematronTransformerFactory.getDefaultSaxonFirst (),
116 new ClassPathResource (XSLT2_STEP3));
117
118
119 final DOMResult aResult1 = new DOMResult ();
120 final Transformer aTransformer1 = s_aStep1.newTransformer ();
121 aTransformerCustomizer.customize (EStep.SCH2XSLT_1, aTransformer1);
122 aTransformer1.transform (TransformSourceFactory.create (aSchematronResource), aResult1);
123
124
125 final DOMResult aResult2 = new DOMResult ();
126 final Transformer aTransformer2 = s_aStep2.newTransformer ();
127 aTransformerCustomizer.customize (EStep.SCH2XSLT_2, aTransformer2);
128 aTransformer2.transform (TransformSourceFactory.create (aResult1.getNode ()), aResult2);
129
130 if (SAVE_INTERMEDIATE_FILES)
131 {
132 final String sXML = XMLWriter.getXMLString (aResult2.getNode ());
133 SimpleFileIO.writeFile (new File ("test-minified",
134 FilenameHelper.getWithoutPath (aSchematronResource.getPath ()) +
135 ".min-xslt.sch"),
136 sXML,
137 XMLWriterSettings.DEFAULT_XML_CHARSET_OBJ);
138 }
139
140
141 final DOMResult aResult3 = new DOMResult ();
142 final Transformer aTransformer3 = s_aStep3.newTransformer ();
143 aTransformerCustomizer.customize (EStep.SCH2XSLT_3, aTransformer3);
144 aTransformer3.transform (TransformSourceFactory.create (aResult2.getNode ()), aResult3);
145
146
147
148 m_aSchematronXSLTDoc = (Document) aResult3.getNode ();
149
150 if (SAVE_INTERMEDIATE_FILES)
151 {
152 final String sXML = XMLWriter.getXMLString (m_aSchematronXSLTDoc);
153 SimpleFileIO.writeFile (new File ("test-final",
154 FilenameHelper.getWithoutPath (aSchematronResource.getPath ()) + ".xslt"),
155 sXML,
156 XMLWriterSettings.DEFAULT_XML_CHARSET_OBJ);
157 }
158
159
160 m_aSchematronXSLTTemplates = XMLTransformerFactory.newTemplates (SchematronTransformerFactory.getDefaultSaxonFirst (),
161 TransformSourceFactory.create (m_aSchematronXSLTDoc));
162 }
163 catch (final Throwable t)
164 {
165 s_aLogger.error ("Schematron preprocessor error", t);
166 }
167 }
168
169 @Nonnull
170 public IReadableResource getSchematronResource ()
171 {
172 return m_aSchematronResource;
173 }
174
175 public boolean isValidSchematron ()
176 {
177 return m_aSchematronXSLTTemplates != null;
178 }
179
180 @Nullable
181 public Document getXSLTDocument ()
182 {
183 return m_aSchematronXSLTDoc;
184 }
185
186 @Nullable
187 public Transformer getXSLTTransformer () throws TransformerConfigurationException
188 {
189 return m_aSchematronXSLTTemplates == null ? null : m_aSchematronXSLTTemplates.newTransformer ();
190 }
191 }