1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.helger.schematron.pure.bound;
18
19 import javax.annotation.Nonnull;
20 import javax.annotation.Nullable;
21 import javax.annotation.concurrent.Immutable;
22 import javax.xml.xpath.XPathFunctionResolver;
23 import javax.xml.xpath.XPathVariableResolver;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.xml.sax.EntityResolver;
28
29 import com.helger.commons.ValueEnforcer;
30 import com.helger.commons.annotation.OverrideOnDemand;
31 import com.helger.commons.equals.EqualsHelper;
32 import com.helger.commons.hashcode.HashCodeGenerator;
33 import com.helger.commons.hashcode.IHashCodeGenerator;
34 import com.helger.commons.io.resource.IReadableResource;
35 import com.helger.commons.string.ToStringGenerator;
36 import com.helger.schematron.SchematronDebug;
37 import com.helger.schematron.SchematronException;
38 import com.helger.schematron.pure.binding.IPSQueryBinding;
39 import com.helger.schematron.pure.binding.PSQueryBindingRegistry;
40 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
41 import com.helger.schematron.pure.exchange.PSReader;
42 import com.helger.schematron.pure.model.PSSchema;
43 import com.helger.schematron.pure.preprocess.PSPreprocessor;
44 import com.helger.schematron.pure.preprocess.SchematronPreprocessException;
45 import com.helger.xml.microdom.serialize.MicroWriter;
46
47
48
49
50
51
52
53
54 @Immutable
55 public class PSBoundSchemaCacheKey
56 {
57 private static final Logger s_aLogger = LoggerFactory.getLogger (PSBoundSchemaCacheKey.class);
58
59 private final IReadableResource m_aResource;
60 private final String m_sPhase;
61 private final IPSErrorHandler m_aErrorHandler;
62 private final XPathVariableResolver m_aVariableResolver;
63 private final XPathFunctionResolver m_aFunctionResolver;
64 private final EntityResolver m_aEntityResolver;
65
66 private transient int m_nHashCode = IHashCodeGenerator.ILLEGAL_HASHCODE;
67
68 public PSBoundSchemaCacheKey (@Nonnull final IReadableResource aResource,
69 @Nullable final String sPhase,
70 @Nullable final IPSErrorHandler aErrorHandler,
71 @Nullable final XPathVariableResolver aVariableResolver,
72 @Nullable final XPathFunctionResolver aFunctionResolver,
73 @Nullable final EntityResolver aEntityResolver)
74 {
75 ValueEnforcer.notNull (aResource, "Resource");
76
77 m_aResource = aResource;
78 m_sPhase = sPhase;
79 m_aErrorHandler = aErrorHandler;
80 m_aVariableResolver = aVariableResolver;
81 m_aFunctionResolver = aFunctionResolver;
82 m_aEntityResolver = aEntityResolver;
83 }
84
85
86
87
88 @Nonnull
89 public final IReadableResource getResource ()
90 {
91 return m_aResource;
92 }
93
94
95
96
97 @Nullable
98 public final String getPhase ()
99 {
100 return m_sPhase;
101 }
102
103
104
105
106
107 @Nullable
108 public final IPSErrorHandler getErrorHandler ()
109 {
110 return m_aErrorHandler;
111 }
112
113
114
115
116 @Nullable
117 public final XPathVariableResolver getVariableResolver ()
118 {
119 return m_aVariableResolver;
120 }
121
122
123
124
125 @Nullable
126 public final XPathFunctionResolver getFunctionResolver ()
127 {
128 return m_aFunctionResolver;
129 }
130
131
132
133
134 @Nullable
135 public final EntityResolver getEntityResolver ()
136 {
137 return m_aEntityResolver;
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 @Nonnull
154 @OverrideOnDemand
155 public PSSchema readSchema (@Nonnull final IReadableResource aResource,
156 @Nullable final IPSErrorHandler aErrorHandler,
157 @Nullable final EntityResolver aEntityResolver) throws SchematronException
158 {
159 return new PSReader (aResource, aErrorHandler, aEntityResolver).readSchema ();
160 }
161
162
163
164
165
166
167
168
169
170
171 @Nonnull
172 @OverrideOnDemand
173 public IPSQueryBinding getQueryBinding (@Nonnull final PSSchema aSchema) throws SchematronException
174 {
175 return PSQueryBindingRegistry.getQueryBindingOfNameOrThrow (aSchema.getQueryBinding ());
176 }
177
178
179
180
181
182
183
184
185
186
187 @Nonnull
188 @OverrideOnDemand
189 public PSPreprocessor createPreprocessor (@Nonnull final IPSQueryBinding aQueryBinding)
190 {
191 final PSPreprocessor aPreprocessor = PSPreprocessor.createPreprocessorWithoutInformationLoss (aQueryBinding);
192 return aPreprocessor;
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206 @Nonnull
207 @OverrideOnDemand
208 public PSSchema createPreprocessedSchema (@Nonnull final PSSchema aSchema,
209 @Nonnull final IPSQueryBinding aQueryBinding) throws SchematronException
210 {
211 final PSPreprocessor aPreprocessor = createPreprocessor (aQueryBinding);
212 final PSSchema aPreprocessedSchema = aPreprocessor.getAsPreprocessedSchema (aSchema);
213 if (aPreprocessedSchema == null)
214 throw new SchematronPreprocessException ("Failed to preprocess schema " +
215 aSchema +
216 " with query binding " +
217 aQueryBinding);
218 if (SchematronDebug.isShowPreprocessedSchematron ())
219 s_aLogger.info ("Preprocessed Schematron:\n" +
220 MicroWriter.getNodeAsString (aPreprocessedSchema.getAsMicroElement ()));
221 return aPreprocessedSchema;
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 @Nonnull
243 public IPSBoundSchema createBoundSchema () throws SchematronException
244 {
245
246 final PSSchema aSchema = readSchema (getResource (), getErrorHandler (), getEntityResolver ());
247
248
249 final IPSQueryBinding aQueryBinding = getQueryBinding (aSchema);
250
251
252 final PSSchema aPreprocessedSchema = createPreprocessedSchema (aSchema, aQueryBinding);
253
254
255 return aQueryBinding.bind (aPreprocessedSchema,
256 getPhase (),
257 getErrorHandler (),
258 getVariableResolver (),
259 getFunctionResolver ());
260 }
261
262 @Override
263 public boolean equals (final Object o)
264 {
265 if (o == this)
266 return true;
267 if (o == null || !getClass ().equals (o.getClass ()))
268 return false;
269 final PSBoundSchemaCacheKey rhs = (PSBoundSchemaCacheKey) o;
270 return m_aResource.equals (rhs.m_aResource) &&
271 EqualsHelper.equals (m_sPhase, rhs.m_sPhase) &&
272 EqualsHelper.equals (m_aVariableResolver, rhs.m_aVariableResolver) &&
273 EqualsHelper.equals (m_aFunctionResolver, rhs.m_aFunctionResolver);
274 }
275
276 @Override
277 public int hashCode ()
278 {
279 int ret = m_nHashCode;
280 if (ret == IHashCodeGenerator.ILLEGAL_HASHCODE)
281 ret = m_nHashCode = new HashCodeGenerator (this).append (m_aResource)
282 .append (m_sPhase)
283 .append (m_aVariableResolver)
284 .append (m_aFunctionResolver)
285 .getHashCode ();
286 return ret;
287 }
288
289 @Override
290 public String toString ()
291 {
292 return new ToStringGenerator (this).append ("resource", m_aResource)
293 .append ("phase", m_sPhase)
294 .appendIfNotNull ("errorHandler", m_aErrorHandler)
295 .appendIfNotNull ("variableResolver", m_aVariableResolver)
296 .appendIfNotNull ("functionResolver", m_aFunctionResolver)
297 .getToString ();
298 }
299 }