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.InputStream;
20 import java.util.Locale;
21 import java.util.Map;
22
23 import javax.annotation.Nonnull;
24 import javax.annotation.Nullable;
25 import javax.annotation.concurrent.NotThreadSafe;
26 import javax.xml.transform.ErrorListener;
27 import javax.xml.transform.Source;
28 import javax.xml.transform.Transformer;
29 import javax.xml.transform.TransformerException;
30 import javax.xml.transform.URIResolver;
31 import javax.xml.transform.dom.DOMResult;
32
33 import org.oclc.purl.dsdl.svrl.SchematronOutputType;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Node;
38
39 import com.helger.commons.ValueEnforcer;
40 import com.helger.commons.annotation.ReturnsMutableCopy;
41 import com.helger.commons.collection.CollectionHelper;
42 import com.helger.commons.io.IHasInputStream;
43 import com.helger.commons.io.resource.IReadableResource;
44 import com.helger.commons.io.stream.StreamHelper;
45 import com.helger.commons.lang.GenericReflection;
46 import com.helger.commons.state.EValidity;
47 import com.helger.commons.string.ToStringGenerator;
48 import com.helger.commons.xml.XMLFactory;
49 import com.helger.commons.xml.serialize.write.XMLWriter;
50 import com.helger.commons.xml.transform.LoggingTransformErrorListener;
51 import com.helger.commons.xml.transform.TransformSourceFactory;
52 import com.helger.schematron.AbstractSchematronResource;
53 import com.helger.schematron.svrl.SVRLReader;
54 import com.helger.schematron.xslt.validator.ISchematronXSLTValidator;
55 import com.helger.schematron.xslt.validator.SchematronXSLTValidatorDefault;
56
57
58
59
60
61
62
63
64
65 @NotThreadSafe
66 public abstract class AbstractSchematronXSLTBasedResource <IMPLTYPE extends AbstractSchematronXSLTBasedResource <IMPLTYPE>> extends AbstractSchematronResource
67 {
68 private static final Logger s_aLogger = LoggerFactory.getLogger (AbstractSchematronXSLTBasedResource.class);
69
70 protected ErrorListener m_aCustomErrorListener;
71 protected URIResolver m_aCustomURIResolver;
72 protected Map <String, ?> m_aCustomParameters;
73 private ISchematronXSLTValidator m_aXSLTValidator = new SchematronXSLTValidatorDefault ();
74
75 public AbstractSchematronXSLTBasedResource (@Nonnull final IReadableResource aSCHResource)
76 {
77 super (aSCHResource);
78 }
79
80 @Nonnull
81 protected final IMPLTYPE thisAsT ()
82 {
83
84 return GenericReflection.<AbstractSchematronXSLTBasedResource <IMPLTYPE>, IMPLTYPE> uncheckedCast (this);
85 }
86
87 @Nullable
88 public ErrorListener getErrorListener ()
89 {
90 return m_aCustomErrorListener;
91 }
92
93 @Nonnull
94 public IMPLTYPE setErrorListener (@Nullable final ErrorListener aCustomErrorListener)
95 {
96 m_aCustomErrorListener = aCustomErrorListener;
97 return thisAsT ();
98 }
99
100 @Nullable
101 public URIResolver getURIResolver ()
102 {
103 return m_aCustomURIResolver;
104 }
105
106 @Nonnull
107 public IMPLTYPE setURIResolver (@Nullable final URIResolver aCustomURIResolver)
108 {
109 m_aCustomURIResolver = aCustomURIResolver;
110 return thisAsT ();
111 }
112
113 public boolean hasParameters ()
114 {
115 return CollectionHelper.isNotEmpty (m_aCustomParameters);
116 }
117
118 @Nonnull
119 @ReturnsMutableCopy
120 public Map <String, ?> getParameters ()
121 {
122 return CollectionHelper.newOrderedMap (m_aCustomParameters);
123 }
124
125 @Nonnull
126 public IMPLTYPE setParameters (@Nullable final Map <String, ?> aCustomParameters)
127 {
128 m_aCustomParameters = CollectionHelper.newOrderedMap (aCustomParameters);
129 return thisAsT ();
130 }
131
132
133
134
135
136 @Nullable
137 public abstract ISchematronXSLTBasedProvider getXSLTProvider ();
138
139
140
141
142 @Nonnull
143 public ISchematronXSLTValidator getXSLTValidator ()
144 {
145 return m_aXSLTValidator;
146 }
147
148 @Nonnull
149 public IMPLTYPE setXSLTValidator (@Nonnull final ISchematronXSLTValidator aXSLTValidator)
150 {
151 ValueEnforcer.notNull (aXSLTValidator, "XSLTValidator");
152 m_aXSLTValidator = aXSLTValidator;
153 return thisAsT ();
154 }
155
156 public final boolean isValidSchematron ()
157 {
158 final ISchematronXSLTBasedProvider aXSLTProvider = getXSLTProvider ();
159 return aXSLTProvider != null && aXSLTProvider.isValidSchematron ();
160 }
161
162 @Nonnull
163 public EValidity getSchematronValidity (@Nonnull final IHasInputStream aXMLResource) throws Exception
164 {
165 ValueEnforcer.notNull (aXMLResource, "XMLResource");
166
167 final InputStream aIS = aXMLResource.getInputStream ();
168 if (aIS == null)
169 {
170
171 s_aLogger.warn ("XML resource " + aXMLResource + " does not exist!");
172 return EValidity.INVALID;
173 }
174
175 try
176 {
177
178 return getSchematronValidity (TransformSourceFactory.create (aIS));
179 }
180 finally
181 {
182
183 StreamHelper.close (aIS);
184 }
185 }
186
187 @Nonnull
188 public EValidity getSchematronValidity (@Nonnull final Source aXMLSource) throws Exception
189 {
190
191 final SchematronOutputType aSO = applySchematronValidationToSVRL (aXMLSource);
192 if (aSO == null)
193 return EValidity.INVALID;
194
195
196 return m_aXSLTValidator.getSchematronValidity (aSO);
197 }
198
199 @Nullable
200 public Document applySchematronValidation (@Nonnull final IHasInputStream aXMLResource) throws Exception
201 {
202 ValueEnforcer.notNull (aXMLResource, "XMLResource");
203
204 final InputStream aIS = aXMLResource.getInputStream ();
205 if (aIS == null)
206 {
207
208 s_aLogger.warn ("XML resource " + aXMLResource + " does not exist!");
209 return null;
210 }
211
212 try
213 {
214 return applySchematronValidation (TransformSourceFactory.create (aIS));
215 }
216 finally
217 {
218 StreamHelper.close (aIS);
219 }
220 }
221
222 @Nullable
223 public Document applySchematronValidation (@Nonnull final Node aXMLResource) throws Exception
224 {
225 ValueEnforcer.notNull (aXMLResource, "XMLResource");
226
227 return applySchematronValidation (TransformSourceFactory.create (aXMLResource));
228 }
229
230 @Nullable
231 public final Document applySchematronValidation (@Nonnull final Source aXMLSource) throws TransformerException
232 {
233 ValueEnforcer.notNull (aXMLSource, "XMLSource");
234
235 final ISchematronXSLTBasedProvider aXSLTProvider = getXSLTProvider ();
236 if (aXSLTProvider == null || !aXSLTProvider.isValidSchematron ())
237 {
238
239 return null;
240 }
241
242
243 final Document ret = XMLFactory.newDocument ();
244
245
246
247 final Transformer aTransformer = aXSLTProvider.getXSLTTransformer ();
248
249
250
251 if (m_aCustomErrorListener != null)
252 aTransformer.setErrorListener (m_aCustomErrorListener);
253 else
254 aTransformer.setErrorListener (new LoggingTransformErrorListener (Locale.US));
255
256
257 if (m_aCustomURIResolver != null)
258 aTransformer.setURIResolver (m_aCustomURIResolver);
259
260
261 if (m_aCustomParameters != null)
262 for (final Map.Entry <String, ?> aEntry : m_aCustomParameters.entrySet ())
263 aTransformer.setParameter (aEntry.getKey (), aEntry.getValue ());
264
265
266 if (false)
267 System.out.println (XMLWriter.getXMLString (aXSLTProvider.getXSLTDocument ()));
268
269
270 aTransformer.transform (aXMLSource, new DOMResult (ret));
271
272
273 if (false)
274 System.out.println (XMLWriter.getXMLString (ret));
275
276 return ret;
277 }
278
279 @Nullable
280 public SchematronOutputType applySchematronValidationToSVRL (@Nonnull final IHasInputStream aXMLResource) throws Exception
281 {
282 final Document aDoc = applySchematronValidation (aXMLResource);
283 return aDoc == null ? null : SVRLReader.readXML (aDoc);
284 }
285
286 @Nullable
287 public SchematronOutputType applySchematronValidationToSVRL (@Nonnull final Source aXMLSource) throws Exception
288 {
289 final Document aDoc = applySchematronValidation (aXMLSource);
290 return aDoc == null ? null : SVRLReader.readXML (aDoc);
291 }
292
293 @Nullable
294 public SchematronOutputType applySchematronValidationToSVRL (@Nonnull final Node aXMLSource) throws Exception
295 {
296 final Document aDoc = applySchematronValidation (aXMLSource);
297 return aDoc == null ? null : SVRLReader.readXML (aDoc);
298 }
299
300 @Override
301 public String toString ()
302 {
303 return ToStringGenerator.getDerived (super.toString ()).append ("XSLTValidator", m_aXSLTValidator).toString ();
304 }
305 }