Skip to content

Commit 93e959d

Browse files
committed
[Java] Improve error messages when parsing a non-SBE schema XML file.
1 parent 612318f commit 93e959d

File tree

1 file changed

+48
-29
lines changed

1 file changed

+48
-29
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class XmlSchemaParser
6161
"/*[local-name() = 'messageSchema']";
6262

6363
static final String MESSAGE_XPATH_EXPR =
64-
"//*[local-name() = 'message']";
64+
"/*[local-name() = 'messageSchema']/*[local-name() = 'message']";
6565

6666
/**
6767
* Validate the document against a given schema. Errors will be written to {@link java.lang.System#err}.
@@ -141,6 +141,11 @@ public static MessageSchema parse(final InputSource is, final ParserOptions opti
141141
errorHandler.checkIfShouldExit();
142142

143143
final Node schemaNode = (Node)xPath.compile(MESSAGE_SCHEMA_XPATH_EXPR).evaluate(document, XPathConstants.NODE);
144+
if (null == schemaNode)
145+
{
146+
throw new IllegalStateException("messageSchema element not found in document, schema is not valid for SBE");
147+
}
148+
144149
final MessageSchema messageSchema = new MessageSchema(schemaNode, typeByNameMap, messageByIdMap);
145150
errorHandler.checkIfShouldExit();
146151

@@ -167,9 +172,9 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti
167172
/**
168173
* Scan XML for all types (encodedDataType, compositeType, enumType, and setType) and save in map.
169174
*
170-
* @param document for the XML parsing
171-
* @param xPath for XPath expression reuse
172-
* @return {@link java.util.Map} of name {@link java.lang.String} to Type
175+
* @param document for the XML parsing.
176+
* @param xPath for XPath expression reuse.
177+
* @return {@link java.util.Map} of name {@link java.lang.String} to {@link Type}.
173178
* @throws Exception on parsing error.
174179
*/
175180
public static Map<String, Type> findTypes(final Document document, final XPath xPath) throws Exception
@@ -206,10 +211,10 @@ public static Map<String, Type> findTypes(final Document document, final XPath x
206211
/**
207212
* Scan XML for all message definitions and save in map.
208213
*
209-
* @param document for the XML parsing
210-
* @param xPath for XPath expression reuse
211-
* @param typeByNameMap to use for Type objects
212-
* @return {@link java.util.Map} of schemaId to Message
214+
* @param document for the XML parsing.
215+
* @param xPath for XPath expression reuse.
216+
* @param typeByNameMap to use for Type objects.
217+
* @return {@link java.util.Map} of schemaId to {@link Message}.
213218
* @throws Exception on parsing error.
214219
*/
215220
public static Map<Long, Message> findMessages(
@@ -221,6 +226,11 @@ public static Map<Long, Message> findMessages(
221226
forEach((NodeList)xPath.compile(MESSAGE_XPATH_EXPR).evaluate(document, XPathConstants.NODESET),
222227
(node) -> addMessageWithIdCheck(distinctNames, messageByIdMap, new Message(node, typeByNameMap), node));
223228

229+
if (messageByIdMap.isEmpty())
230+
{
231+
handleWarning(document.getDocumentElement(), "no messages found in document");
232+
}
233+
224234
return messageByIdMap;
225235
}
226236

@@ -233,8 +243,7 @@ public static Map<Long, Message> findMessages(
233243
public static void handleError(final Node node, final String msg)
234244
{
235245
final ErrorHandler handler = (ErrorHandler)node.getOwnerDocument().getUserData(ERROR_HANDLER_KEY);
236-
237-
if (handler == null)
246+
if (null == handler)
238247
{
239248
throw new IllegalStateException("ERROR: " + formatLocationInfo(node) + msg);
240249
}
@@ -253,8 +262,7 @@ public static void handleError(final Node node, final String msg)
253262
public static void handleWarning(final Node node, final String msg)
254263
{
255264
final ErrorHandler handler = (ErrorHandler)node.getOwnerDocument().getUserData(ERROR_HANDLER_KEY);
256-
257-
if (handler == null)
265+
if (null == handler)
258266
{
259267
throw new IllegalStateException("WARNING: " + formatLocationInfo(node) + msg);
260268
}
@@ -267,13 +275,19 @@ public static void handleWarning(final Node node, final String msg)
267275
/**
268276
* Helper function that throws an exception when the attribute is not set.
269277
*
270-
* @param elementNode that should have the attribute
271-
* @param attrName that is to be looked up
272-
* @return value of the attribute
273-
* @throws IllegalArgumentException if the attribute is not present
278+
* @param elementNode that should have the attribute.
279+
* @param attrName that is to be looked up.
280+
* @return value of the attribute.
281+
* @throws IllegalStateException if the attribute is not present.
274282
*/
275283
public static String getAttributeValue(final Node elementNode, final String attrName)
276284
{
285+
if (null == elementNode)
286+
{
287+
throw new IllegalStateException(
288+
"element node is null when looking for attribute: " + attrName);
289+
}
290+
277291
final NamedNodeMap attributes = elementNode.getAttributes();
278292
if (null == attributes)
279293
{
@@ -282,7 +296,7 @@ public static String getAttributeValue(final Node elementNode, final String attr
282296
}
283297

284298
final Node attrNode = attributes.getNamedItemNS(null, attrName);
285-
if (attrNode == null || "".equals(attrNode.getNodeValue()))
299+
if (null == attrNode || "".equals(attrNode.getNodeValue()))
286300
{
287301
throw new IllegalStateException(
288302
"element '" + elementNode.getNodeName() + "' has empty or missing attribute: " + attrName);
@@ -294,22 +308,27 @@ public static String getAttributeValue(final Node elementNode, final String attr
294308
/**
295309
* Helper function that uses a default value when value not set.
296310
*
297-
* @param elementNode that should have the attribute
298-
* @param attrName that is to be looked up
299-
* @param defValue String to return if not set
300-
* @return value of the attribute or defValue
311+
* @param elementNode that should have the attribute.
312+
* @param attrName that is to be looked up.
313+
* @param defValue value to return if not set.
314+
* @return value of the attribute or defValue.
301315
*/
302316
public static String getAttributeValue(final Node elementNode, final String attrName, final String defValue)
303317
{
318+
if (null == elementNode)
319+
{
320+
throw new IllegalStateException(
321+
"element node is null when looking for attribute: " + attrName);
322+
}
323+
304324
final NamedNodeMap attributes = elementNode.getAttributes();
305-
if (attributes == null)
325+
if (null == attributes)
306326
{
307327
return defValue;
308328
}
309329

310330
final Node attrNode = attributes.getNamedItemNS(null, attrName);
311-
312-
if (attrNode == null)
331+
if (null == attrNode)
313332
{
314333
return defValue;
315334
}
@@ -320,9 +339,9 @@ public static String getAttributeValue(final Node elementNode, final String attr
320339
/**
321340
* Helper function that hides the null return from {@link org.w3c.dom.NamedNodeMap#getNamedItem(String)}.
322341
*
323-
* @param elementNode that could be null
324-
* @param attrName that is to be looked up
325-
* @return null or value of the attribute
342+
* @param elementNode that could be null.
343+
* @param attrName that is to be looked up.
344+
* @return null or value of the attribute.
326345
*/
327346
public static String getAttributeValueOrNull(final Node elementNode, final String attrName)
328347
{
@@ -343,8 +362,8 @@ public static String getAttributeValueOrNull(final Node elementNode, final Strin
343362
/**
344363
* Helper function to convert a schema byteOrderName into a {@link ByteOrder}.
345364
*
346-
* @param byteOrderName specified as a FIX SBE string
347-
* @return ByteOrder representation
365+
* @param byteOrderName specified as a FIX SBE string.
366+
* @return ByteOrder representation.
348367
*/
349368
public static ByteOrder getByteOrder(final String byteOrderName)
350369
{

0 commit comments

Comments
 (0)