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.OverridingMethodsMustInvokeSuper;
22
23 import org.w3c.dom.Node;
24
25 import com.helger.commons.ValueEnforcer;
26 import com.helger.commons.annotation.OverrideOnDemand;
27 import com.helger.commons.annotation.ReturnsMutableCopy;
28 import com.helger.commons.collection.ext.CommonsArrayList;
29 import com.helger.commons.collection.ext.ICommonsList;
30 import com.helger.commons.state.EValidity;
31 import com.helger.commons.string.ToStringGenerator;
32 import com.helger.schematron.CSchematron;
33 import com.helger.schematron.pure.binding.IPSQueryBinding;
34 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
35 import com.helger.schematron.pure.errorhandler.LoggingPSErrorHandler;
36 import com.helger.schematron.pure.model.IPSElement;
37 import com.helger.schematron.pure.model.PSActive;
38 import com.helger.schematron.pure.model.PSPattern;
39 import com.helger.schematron.pure.model.PSPhase;
40 import com.helger.schematron.pure.model.PSSchema;
41 import com.helger.schematron.pure.validation.AbstractPSPartialValidationHandler;
42 import com.helger.schematron.pure.validation.PSValidationHandlerBreakOnFirstError;
43 import com.helger.schematron.pure.validation.SchematronValidationException;
44 import com.helger.xml.namespace.MapBasedNamespaceContext;
45
46
47
48
49
50
51
52 public abstract class AbstractPSBoundSchema implements IPSBoundSchema
53 {
54 private final IPSQueryBinding m_aQueryBinding;
55 private final PSSchema m_aOrigSchema;
56 private final IPSErrorHandler m_aErrorHandler;
57 private final boolean m_bDefaultErrorHandler;
58 private final MapBasedNamespaceContext m_aNamespaceContext;
59 private final String m_sPhase;
60 private final PSPhase m_aPhase;
61 private final ICommonsList <PSPattern> m_aPatterns = new CommonsArrayList <> ();
62
63 public AbstractPSBoundSchema (@Nonnull final IPSQueryBinding aQueryBinding,
64 @Nonnull final PSSchema aOrigSchema,
65 @Nullable final String sPhase,
66 @Nullable final IPSErrorHandler aCustomErrorHandler)
67 {
68 ValueEnforcer.notNull (aQueryBinding, "QueryBinding");
69 ValueEnforcer.notNull (aOrigSchema, "OrigSchema");
70
71 m_aQueryBinding = aQueryBinding;
72 m_aOrigSchema = aOrigSchema;
73 m_aErrorHandler = aCustomErrorHandler != null ? aCustomErrorHandler : new LoggingPSErrorHandler ();
74 m_bDefaultErrorHandler = aCustomErrorHandler == null;
75
76
77 m_aNamespaceContext = aOrigSchema.getAsNamespaceContext ();
78
79
80 String sRealPhase = sPhase != null ? sPhase : CSchematron.PHASE_DEFAULT;
81 if (sRealPhase.equals (CSchematron.PHASE_DEFAULT))
82 {
83 sRealPhase = aOrigSchema.getDefaultPhase ();
84 if (sRealPhase == null)
85 sRealPhase = CSchematron.PHASE_ALL;
86 }
87 if (!sRealPhase.equals (CSchematron.PHASE_ALL))
88 {
89 m_aPhase = aOrigSchema.getPhaseOfID (sRealPhase);
90 if (m_aPhase == null)
91 warn (aOrigSchema, "Failed to resolve phase with ID '" + sRealPhase + "' - default to all patterns");
92 }
93 else
94 m_aPhase = null;
95 m_sPhase = sRealPhase;
96
97
98 if (m_aPhase == null)
99 {
100
101 m_aPatterns.addAll (aOrigSchema.getAllPatterns ());
102 }
103 else
104 {
105
106 for (final PSActive aActive : m_aPhase.getAllActives ())
107 {
108 final String sActivePatternID = aActive.getPattern ();
109 final PSPattern aPattern = aOrigSchema.getPatternOfID (sActivePatternID);
110 if (aPattern == null)
111 {
112 warn (aOrigSchema,
113 "Failed to resolve pattern with ID '" +
114 sActivePatternID +
115 "' - ignoring this pattern in phase '" +
116 sRealPhase +
117 "'");
118 }
119 else
120 {
121
122 m_aPatterns.add (aPattern);
123 }
124 }
125 }
126 if (m_aPatterns.isEmpty ())
127 if (m_aPhase == null)
128 error (aOrigSchema, "No patterns found in schema!");
129 else
130 error (aOrigSchema, "No patterns found in schema for phase '" + m_aPhase.getID () + "!");
131 }
132
133 @Nonnull
134 protected IPSErrorHandler getErrorHandler ()
135 {
136 return m_aErrorHandler;
137 }
138
139 protected boolean isDefaultErrorHandler ()
140 {
141 return m_bDefaultErrorHandler;
142 }
143
144 @OverridingMethodsMustInvokeSuper
145 protected void warn (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMsg)
146 {
147 getErrorHandler ().warn (m_aOrigSchema.getResource (), aSourceElement, sMsg);
148 }
149
150 @OverridingMethodsMustInvokeSuper
151 protected void error (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMsg)
152 {
153 error (aSourceElement, sMsg, (Throwable) null);
154 }
155
156 @OverridingMethodsMustInvokeSuper
157 protected void error (@Nonnull final IPSElement aSourceElement,
158 @Nonnull final String sMsg,
159 @Nullable final Throwable t)
160 {
161 getErrorHandler ().error (m_aOrigSchema.getResource (), aSourceElement, sMsg, t);
162 }
163
164 @Nonnull
165 public final IPSQueryBinding getQueryBinding ()
166 {
167 return m_aQueryBinding;
168 }
169
170 @Nonnull
171 public final PSSchema getOriginalSchema ()
172 {
173 return m_aOrigSchema;
174 }
175
176 @Nonnull
177 public final MapBasedNamespaceContext getNamespaceContext ()
178 {
179 return m_aNamespaceContext;
180 }
181
182 @Nonnull
183 public final String getPhaseID ()
184 {
185 return m_sPhase;
186 }
187
188 @Nullable
189 public final PSPhase getPhase ()
190 {
191 return m_aPhase;
192 }
193
194 public final boolean isPhaseSpecified ()
195 {
196 return m_aPhase != null;
197 }
198
199 @Nonnull
200 @ReturnsMutableCopy
201 public final ICommonsList <PSPattern> getAllRelevantPatterns ()
202 {
203 return m_aPatterns.getClone ();
204 }
205
206
207
208
209
210
211
212 @Nonnull
213 @OverrideOnDemand
214 protected AbstractPSPartialValidationHandler createPartialValidationHandler ()
215 {
216 return new PSValidationHandlerBreakOnFirstError ();
217 }
218
219 @Nonnull
220 public EValidity validatePartially (@Nonnull final Node aNode) throws SchematronValidationException
221 {
222 final AbstractPSPartialValidationHandler aValidationHandler = createPartialValidationHandler ();
223 validate (aNode, aValidationHandler);
224 return aValidationHandler.getValidity ();
225 }
226
227 @Override
228 public String toString ()
229 {
230 return new ToStringGenerator (this).append ("queryBinding", m_aQueryBinding)
231 .append ("origSchema", m_aOrigSchema)
232 .appendIfNotNull ("errorHandler", m_aErrorHandler)
233 .append ("namespaceContext", m_aNamespaceContext)
234 .appendIfNotNull ("phase", m_sPhase)
235 .appendIfNotNull ("phase", m_aPhase)
236 .append ("patterns", m_aPatterns)
237 .toString ();
238 }
239 }