Skip to content

Commit 78f4b79

Browse files
committed
bug(#282): Made StrictXML lazy
1 parent 392045f commit 78f4b79

2 files changed

Lines changed: 58 additions & 39 deletions

File tree

src/main/java/com/jcabi/xml/StrictXML.java

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
import javax.xml.validation.SchemaFactory;
4444
import javax.xml.validation.Validator;
4545
import lombok.EqualsAndHashCode;
46+
import org.cactoos.Scalar;
47+
import org.cactoos.scalar.Sticky;
48+
import org.cactoos.scalar.Unchecked;
4649
import org.w3c.dom.Node;
4750
import org.w3c.dom.ls.LSResourceResolver;
4851
import org.xml.sax.SAXException;
@@ -64,7 +67,7 @@ public final class StrictXML implements XML {
6467
/**
6568
* Original XML document.
6669
*/
67-
private final transient XML origin;
70+
private final transient Unchecked<XML> origin;
6871

6972
/**
7073
* Public ctor.
@@ -90,7 +93,7 @@ public StrictXML(final XML xml, final LSResourceResolver resolver) {
9093
* @param val Custom validator
9194
*/
9295
public StrictXML(final XML xml, final Validator val) {
93-
this(xml, StrictXML.validate(xml, val));
96+
this(xml, () -> StrictXML.validate(xml, val));
9497
}
9598

9699
/**
@@ -99,36 +102,48 @@ public StrictXML(final XML xml, final Validator val) {
99102
* @param schema XSD schema
100103
*/
101104
public StrictXML(final XML xml, final XML schema) {
102-
this(xml, StrictXML.check(xml, schema));
105+
this(xml, () -> StrictXML.check(xml, schema));
103106
}
104107

105108
/**
106109
* Private ctor.
107110
* @param xml XML Document
108-
* @param errors XML Document errors
111+
* @param errs XML Document errors function
109112
*/
110-
@SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors")
111113
private StrictXML(
112114
final XML xml,
113-
final Collection<SAXParseException> errors
115+
final Scalar<Collection<SAXParseException>> errs
114116
) {
115-
if (!errors.isEmpty()) {
116-
Logger.warn(
117-
StrictXML.class,
118-
"%d XML validation error(s):\n %s\n%s",
119-
errors.size(),
120-
StrictXML.join(StrictXML.print(errors), "\n "),
121-
xml
122-
);
123-
throw new IllegalArgumentException(
124-
String.format(
125-
"%d error(s) in XML document: %s",
126-
errors.size(),
127-
StrictXML.join(StrictXML.print(errors), ";")
128-
)
129-
);
130-
}
131-
this.origin = xml;
117+
this(
118+
() -> {
119+
final Collection<SAXParseException> errors = errs.value();
120+
if (!errors.isEmpty()) {
121+
Logger.warn(
122+
StrictXML.class,
123+
"%d XML validation error(s):\n %s\n%s",
124+
errors.size(),
125+
StrictXML.join(StrictXML.print(errors), "\n "),
126+
xml
127+
);
128+
throw new IllegalArgumentException(
129+
String.format(
130+
"%d error(s) in XML document: %s",
131+
errors.size(),
132+
StrictXML.join(StrictXML.print(errors), ";")
133+
)
134+
);
135+
}
136+
return xml;
137+
}
138+
);
139+
}
140+
141+
/**
142+
* Default ctor.
143+
* @param xml XML supplier
144+
*/
145+
private StrictXML(final Scalar<XML> xml) {
146+
this.origin = new Unchecked<>(new Sticky<>(xml));
132147
}
133148

134149
@Override
@@ -138,22 +153,22 @@ public String toString() {
138153

139154
@Override
140155
public List<String> xpath(final String query) {
141-
return this.origin.xpath(query);
156+
return this.origin.value().xpath(query);
142157
}
143158

144159
@Override
145160
public List<XML> nodes(final String query) {
146-
return this.origin.nodes(query);
161+
return this.origin.value().nodes(query);
147162
}
148163

149164
@Override
150165
public XML registerNs(final String prefix, final Object uri) {
151-
return this.origin.registerNs(prefix, uri);
166+
return this.origin.value().registerNs(prefix, uri);
152167
}
153168

154169
@Override
155170
public XML merge(final NamespaceContext context) {
156-
return this.origin.merge(context);
171+
return this.origin.value().merge(context);
157172
}
158173

159174
/**
@@ -164,27 +179,27 @@ public XML merge(final NamespaceContext context) {
164179
*/
165180
@Deprecated
166181
public Node node() {
167-
return this.origin.deepCopy();
182+
return this.origin.value().deepCopy();
168183
}
169184

170185
@Override
171186
public Node inner() {
172-
return this.origin.inner();
187+
return this.origin.value().inner();
173188
}
174189

175190
@Override
176191
public Node deepCopy() {
177-
return this.origin.deepCopy();
192+
return this.origin.value().deepCopy();
178193
}
179194

180195
@Override
181196
public Collection<SAXParseException> validate() {
182-
return this.origin.validate();
197+
return this.origin.value().validate();
183198
}
184199

185200
@Override
186201
public Collection<SAXParseException> validate(final XML xsd) {
187-
return this.origin.validate(xsd);
202+
return this.origin.value().validate(xsd);
188203
}
189204

190205
/**

src/test/java/com/jcabi/xml/StrictXMLTest.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,16 @@ void passesValidXmlThrough() {
9494
void rejectsInvalidXmlThrough() {
9595
Assertions.assertThrows(
9696
IllegalArgumentException.class,
97-
() -> new StrictXML(
97+
new StrictXML(
9898
new XMLDocument("<root>not an integer</root>"),
9999
new XMLDocument(
100100
StringUtils.join(
101101
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' >",
102102
"<xs:element name='root' type='xs:integer'/></xs:schema>"
103103
)
104104
)
105-
)
105+
)::inner,
106+
"An exception should have been thrown if XML does not match to XSD schema"
106107
);
107108
}
108109

@@ -127,7 +128,8 @@ void rejectsInvalidXmlUsingXsiSchemaLocation() {
127128
new XMLDocument(
128129
this.getClass().getResource("xsi-schemalocation-invalid.xml")
129130
)
130-
)
131+
).inner(),
132+
"An exception should have been thrown if schema location is invalid"
131133
);
132134
}
133135

@@ -244,7 +246,7 @@ void lookupXsdsFromClasspath() {
244246
void rejectXmlWhenXsdIsNotAvailableOnClasspath() {
245247
Assertions.assertThrows(
246248
IllegalArgumentException.class,
247-
() -> new StrictXML(
249+
new StrictXML(
248250
new XMLDocument(
249251
StringUtils.join(
250252
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
@@ -263,17 +265,19 @@ void rejectXmlWhenXsdIsNotAvailableOnClasspath() {
263265
"</payment>"
264266
)
265267
)
266-
)
268+
)::inner,
269+
"An exception should have been thrown if XSD is not available on classpath"
267270
);
268271
}
269272

270273
@Test
271274
void handlesXmlWithoutSchemaLocation() {
272275
Assertions.assertThrows(
273276
IllegalArgumentException.class,
274-
() -> new StrictXML(
277+
new StrictXML(
275278
new XMLDocument("<a></a>")
276-
)
279+
)::inner,
280+
"An exception should have been thrown if XML does not contain a schema location"
277281
);
278282
}
279283
}

0 commit comments

Comments
 (0)