Improved sloppy parser exception handling
This commit is contained in:
parent
2bf3860cbc
commit
e7c3276541
3 changed files with 205 additions and 174 deletions
|
@ -7,6 +7,7 @@ Changelog
|
||||||
- Fixed perpetually green "Update" button
|
- Fixed perpetually green "Update" button
|
||||||
- Added --global-panic commandline arg to show mod devs typoed find tags
|
- Added --global-panic commandline arg to show mod devs typoed find tags
|
||||||
- Added commandline tips in readme_modders.txt
|
- Added commandline tips in readme_modders.txt
|
||||||
|
- Fixed sloppy parser Validate error about things not allowed at root
|
||||||
|
|
||||||
1.2:
|
1.2:
|
||||||
- Added a commandline interface
|
- Added a commandline interface
|
||||||
|
|
|
@ -824,7 +824,7 @@ public class ModUtilities {
|
||||||
xmlValid = false;
|
xmlValid = false;
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
log.error( "Error while validating mod xml.", e );
|
log.error( "Error while validating mod xml with the strict parser.", e );
|
||||||
messages.add( new ReportMessage(
|
messages.add( new ReportMessage(
|
||||||
ReportMessage.EXCEPTION,
|
ReportMessage.EXCEPTION,
|
||||||
"An error occurred. See log for details."
|
"An error occurred. See log for details."
|
||||||
|
@ -846,6 +846,9 @@ public class ModUtilities {
|
||||||
List<ReportMessage> messages = new ArrayList<ReportMessage>();
|
List<ReportMessage> messages = new ArrayList<ReportMessage>();
|
||||||
boolean xmlValid = true;
|
boolean xmlValid = true;
|
||||||
|
|
||||||
|
// Meh, the parser's gonna make its own wrapper with declarations anyway.
|
||||||
|
//text = "<wrapper xmlns:mod='mod' xmlns:mod-append='mod-append' xmlns:mod-overwrite='mod-overwrite'>"+ text +"</wrapper>";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SloppyXMLParser parser = new SloppyXMLParser();
|
SloppyXMLParser parser = new SloppyXMLParser();
|
||||||
parser.build( text );
|
parser.build( text );
|
||||||
|
@ -876,6 +879,7 @@ public class ModUtilities {
|
||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
log.error( "Error while validating mod xml with the sloppy parser.", e );
|
||||||
messages.add( new ReportMessage(
|
messages.add( new ReportMessage(
|
||||||
ReportMessage.EXCEPTION,
|
ReportMessage.EXCEPTION,
|
||||||
"An error occurred. See log for details."
|
"An error occurred. See log for details."
|
||||||
|
@ -883,6 +887,13 @@ public class ModUtilities {
|
||||||
}
|
}
|
||||||
xmlValid = false;
|
xmlValid = false;
|
||||||
}
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
log.error( "Error while validating mod xml with the sloppy parser.", e );
|
||||||
|
messages.add( new ReportMessage(
|
||||||
|
ReportMessage.EXCEPTION,
|
||||||
|
"An error occurred. See log for details."
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
return new Report( messages, xmlValid );
|
return new Report( messages, xmlValid );
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.jdom2.Content;
|
||||||
import org.jdom2.DefaultJDOMFactory;
|
import org.jdom2.DefaultJDOMFactory;
|
||||||
import org.jdom2.Document;
|
import org.jdom2.Document;
|
||||||
import org.jdom2.Element;
|
import org.jdom2.Element;
|
||||||
|
import org.jdom2.IllegalAddException;
|
||||||
import org.jdom2.JDOMFactory;
|
import org.jdom2.JDOMFactory;
|
||||||
import org.jdom2.Namespace;
|
import org.jdom2.Namespace;
|
||||||
import org.jdom2.Parent;
|
import org.jdom2.Parent;
|
||||||
|
@ -115,198 +116,216 @@ public class SloppyXMLParser {
|
||||||
String tmp = null;
|
String tmp = null;
|
||||||
Matcher m = declPtn.matcher( s );
|
Matcher m = declPtn.matcher( s );
|
||||||
|
|
||||||
while ( pos > lastPos && pos < sLen ) {
|
try {
|
||||||
m.region( pos, sLen );
|
while ( pos > lastPos && pos < sLen ) {
|
||||||
boolean matchedChunk = false;
|
m.region( pos, sLen );
|
||||||
|
boolean matchedChunk = false;
|
||||||
for ( Pattern chunkPtn : chunkPtns ) {
|
|
||||||
m.usePattern( chunkPtn );
|
for ( Pattern chunkPtn : chunkPtns ) {
|
||||||
if ( !m.lookingAt() ) continue;
|
m.usePattern( chunkPtn );
|
||||||
|
if ( !m.lookingAt() ) continue;
|
||||||
if ( chunkPtn == declPtn ) {
|
|
||||||
// Don't care.
|
if ( chunkPtn == declPtn ) {
|
||||||
addLineAndCol( lastLineAndCol, m.group(0) );
|
// Don't care.
|
||||||
}
|
addLineAndCol( lastLineAndCol, m.group(0) );
|
||||||
else if ( chunkPtn == emptyCommentPtn ) {
|
|
||||||
String whitespace = m.group( 1 );
|
|
||||||
if ( whitespace.length() > 0 )
|
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
|
||||||
|
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
|
||||||
}
|
|
||||||
else if ( chunkPtn == commentPtn ) {
|
|
||||||
String whitespace = m.group( 1 );
|
|
||||||
if ( whitespace.length() > 0 )
|
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
|
||||||
|
|
||||||
tmp = m.group( 2 );
|
|
||||||
if ( tmp.length() == 0 ) {
|
|
||||||
factory.addContent( parentNode, factory.comment( "" ) );
|
|
||||||
}
|
}
|
||||||
else {
|
else if ( chunkPtn == emptyCommentPtn ) {
|
||||||
Matcher splicedMatcher = Pattern.compile( "(\\s*)<!--" ).matcher( tmp );
|
String whitespace = m.group( 1 );
|
||||||
int commentStart = 0;
|
if ( whitespace.length() > 0 )
|
||||||
while ( splicedMatcher.find() ) {
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
if ( splicedMatcher.start() - commentStart > 0 ) {
|
|
||||||
String splicedChunk = tmp.substring( commentStart, splicedMatcher.start() );
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
splicedChunk = splicedChunk.replaceAll( "^-+|(?<=-)-+|-+$", "" );
|
}
|
||||||
if ( splicedChunk.startsWith( " " ) ) splicedChunk += " ";
|
else if ( chunkPtn == commentPtn ) {
|
||||||
Comment commentNode = factory.comment( splicedChunk );
|
String whitespace = m.group( 1 );
|
||||||
|
if ( whitespace.length() > 0 )
|
||||||
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
|
|
||||||
|
tmp = m.group( 2 );
|
||||||
|
if ( tmp.length() == 0 ) {
|
||||||
|
factory.addContent( parentNode, factory.comment( "" ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Matcher splicedMatcher = Pattern.compile( "(\\s*)<!--" ).matcher( tmp );
|
||||||
|
int commentStart = 0;
|
||||||
|
while ( splicedMatcher.find() ) {
|
||||||
|
if ( splicedMatcher.start() - commentStart > 0 ) {
|
||||||
|
String splicedChunk = tmp.substring( commentStart, splicedMatcher.start() );
|
||||||
|
splicedChunk = splicedChunk.replaceAll( "^-+|(?<=-)-+|-+$", "" );
|
||||||
|
if ( splicedChunk.startsWith( " " ) ) splicedChunk += " ";
|
||||||
|
Comment commentNode = factory.comment( splicedChunk );
|
||||||
|
factory.addContent( parentNode, commentNode );
|
||||||
|
}
|
||||||
|
if ( splicedMatcher.group(1).length() > 0 ) {
|
||||||
|
// Whitespace between comments.
|
||||||
|
factory.addContent( parentNode, factory.text( splicedMatcher.group(1) ) );
|
||||||
|
}
|
||||||
|
commentStart = splicedMatcher.end();
|
||||||
|
}
|
||||||
|
if ( commentStart < tmp.length() ) {
|
||||||
|
String finalChunk = tmp.substring( commentStart );
|
||||||
|
finalChunk = finalChunk.replaceAll( "^-+|(?<=-)-+|-+$", "" );
|
||||||
|
Comment commentNode = factory.comment( finalChunk );
|
||||||
factory.addContent( parentNode, commentNode );
|
factory.addContent( parentNode, commentNode );
|
||||||
}
|
}
|
||||||
if ( splicedMatcher.group(1).length() > 0 ) {
|
|
||||||
// Whitespace between comments.
|
|
||||||
factory.addContent( parentNode, factory.text( splicedMatcher.group(1) ) );
|
|
||||||
}
|
|
||||||
commentStart = splicedMatcher.end();
|
|
||||||
}
|
}
|
||||||
if ( commentStart < tmp.length() ) {
|
|
||||||
String finalChunk = tmp.substring( commentStart );
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
finalChunk = finalChunk.replaceAll( "^-+|(?<=-)-+|-+$", "" );
|
}
|
||||||
Comment commentNode = factory.comment( finalChunk );
|
else if ( chunkPtn == emptyCDATAPtn ) {
|
||||||
factory.addContent( parentNode, commentNode );
|
String whitespace = m.group( 1 );
|
||||||
|
if ( whitespace.length() > 0 )
|
||||||
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
|
|
||||||
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
|
}
|
||||||
|
else if ( chunkPtn == cdataPtn ) {
|
||||||
|
String whitespace = m.group( 1 );
|
||||||
|
if ( whitespace.length() > 0 )
|
||||||
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
|
|
||||||
|
CDATA cdataNode = factory.cdata( m.group(2) );
|
||||||
|
factory.addContent( parentNode, cdataNode );
|
||||||
|
|
||||||
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
|
}
|
||||||
|
else if ( chunkPtn == sTagPtn ) {
|
||||||
|
String whitespace = m.group( 1 );
|
||||||
|
if ( whitespace.length() > 0 )
|
||||||
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
|
|
||||||
|
String nodePrefix = m.group( 2 ); // Might be null.
|
||||||
|
String nodeName = m.group( 3 );
|
||||||
|
String attrString = m.group( 4 );
|
||||||
|
boolean selfClosing = ( m.group( 5 ).length() > 0 );
|
||||||
|
|
||||||
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
|
|
||||||
|
Element tagNode;
|
||||||
|
if ( nodePrefix != null ) {
|
||||||
|
Namespace nodeNS = Namespace.getNamespace( nodePrefix, nodePrefix ); // URI? *shrug*
|
||||||
|
factory.addNamespaceDeclaration( rootNode, nodeNS );
|
||||||
|
tagNode = factory.element( lastLineAndCol[0]+1, lastLineAndCol[1]+1+1, nodeName, nodeNS );
|
||||||
|
} else {
|
||||||
|
tagNode = factory.element( lastLineAndCol[0]+1, lastLineAndCol[1]+1+1, nodeName );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if ( attrString.length() > 0 ) {
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
Matcher am = attrPtn.matcher( attrString );
|
||||||
}
|
while ( am.lookingAt() ) {
|
||||||
else if ( chunkPtn == emptyCDATAPtn ) {
|
String attrPrefix = am.group( 1 ); // Might be null.
|
||||||
String whitespace = m.group( 1 );
|
String attrName = am.group( 2 );
|
||||||
if ( whitespace.length() > 0 )
|
String attrValue = am.group( 3 );
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
attrValue = attrValue.substring( 1, attrValue.length()-1 );
|
||||||
|
attrValue = unescape( attrValue );
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
|
||||||
}
|
if ( attrPrefix != null ) {
|
||||||
else if ( chunkPtn == cdataPtn ) {
|
if ( attrPrefix.equals( "xmlns" ) ) {
|
||||||
String whitespace = m.group( 1 );
|
// This is a pseudo attribute declaring a namespace prefix.
|
||||||
if ( whitespace.length() > 0 )
|
// Move it to the root node.
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
Namespace attrNS = Namespace.getNamespace( attrName, attrName ); // URI? *shrug*
|
||||||
|
factory.addNamespaceDeclaration( rootNode, attrNS );
|
||||||
CDATA cdataNode = factory.cdata( m.group(2) );
|
}
|
||||||
factory.addContent( parentNode, cdataNode );
|
else {
|
||||||
|
Namespace attrNS = Namespace.getNamespace( attrPrefix, attrPrefix ); // URI? *shrug*
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
factory.addNamespaceDeclaration( rootNode, attrNS );
|
||||||
}
|
Attribute attrObj = factory.attribute( attrName, attrValue, AttributeType.UNDECLARED, attrNS );
|
||||||
else if ( chunkPtn == sTagPtn ) {
|
factory.setAttribute( tagNode, attrObj );
|
||||||
String whitespace = m.group( 1 );
|
}
|
||||||
if ( whitespace.length() > 0 )
|
} else if ( attrName.equals("xmlns") ) {
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
// New default namespace URI within this node.
|
||||||
|
Namespace attrNS = Namespace.getNamespace( attrValue );
|
||||||
String nodePrefix = m.group( 2 ); // Might be null.
|
factory.addNamespaceDeclaration( tagNode, attrNS );
|
||||||
String nodeName = m.group( 3 );
|
} else {
|
||||||
String attrString = m.group( 4 );
|
// Normal attribute.
|
||||||
boolean selfClosing = ( m.group( 5 ).length() > 0 );
|
Attribute attrObj = factory.attribute( attrName, attrValue, AttributeType.UNDECLARED, Namespace.NO_NAMESPACE );
|
||||||
|
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
|
||||||
|
|
||||||
Element tagNode;
|
|
||||||
if ( nodePrefix != null ) {
|
|
||||||
Namespace nodeNS = Namespace.getNamespace( nodePrefix, nodePrefix ); // URI? *shrug*
|
|
||||||
factory.addNamespaceDeclaration( rootNode, nodeNS );
|
|
||||||
tagNode = factory.element( lastLineAndCol[0]+1, lastLineAndCol[1]+1+1, nodeName, nodeNS );
|
|
||||||
} else {
|
|
||||||
tagNode = factory.element( lastLineAndCol[0]+1, lastLineAndCol[1]+1+1, nodeName );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( attrString.length() > 0 ) {
|
|
||||||
Matcher am = attrPtn.matcher( attrString );
|
|
||||||
while ( am.lookingAt() ) {
|
|
||||||
String attrPrefix = am.group( 1 ); // Might be null.
|
|
||||||
String attrName = am.group( 2 );
|
|
||||||
String attrValue = am.group( 3 );
|
|
||||||
attrValue = attrValue.substring( 1, attrValue.length()-1 );
|
|
||||||
attrValue = unescape( attrValue );
|
|
||||||
|
|
||||||
if ( attrPrefix != null ) {
|
|
||||||
if ( attrPrefix.equals( "xmlns" ) ) {
|
|
||||||
// This is a pseudo attribute declaring a namespace prefix.
|
|
||||||
// Move it to the root node.
|
|
||||||
Namespace attrNS = Namespace.getNamespace( attrName, attrName ); // URI? *shrug*
|
|
||||||
factory.addNamespaceDeclaration( rootNode, attrNS );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Namespace attrNS = Namespace.getNamespace( attrPrefix, attrPrefix ); // URI? *shrug*
|
|
||||||
factory.addNamespaceDeclaration( rootNode, attrNS );
|
|
||||||
Attribute attrObj = factory.attribute( attrName, attrValue, AttributeType.UNDECLARED, attrNS );
|
|
||||||
factory.setAttribute( tagNode, attrObj );
|
factory.setAttribute( tagNode, attrObj );
|
||||||
}
|
}
|
||||||
} else if ( attrName.equals("xmlns") ) {
|
am.region( am.end(), am.regionEnd() );
|
||||||
// New default namespace URI within this node.
|
}
|
||||||
Namespace attrNS = Namespace.getNamespace( attrValue );
|
if ( am.regionStart() < attrString.length() ) {
|
||||||
factory.addNamespaceDeclaration( tagNode, attrNS );
|
int nonspacePos = findNextNonspace( s, pos );
|
||||||
} else {
|
int errorPos = ( (nonspacePos != -1) ? nonspacePos : pos );
|
||||||
// Normal attribute.
|
|
||||||
Attribute attrObj = factory.attribute( attrName, attrValue, AttributeType.UNDECLARED, Namespace.NO_NAMESPACE );
|
int[] lineAndCol = getLineAndCol( s, errorPos );
|
||||||
factory.setAttribute( tagNode, attrObj );
|
int lineNum = lineAndCol[0];
|
||||||
|
int colNum = lineAndCol[1];
|
||||||
|
|
||||||
|
SAXParseException cause = new SAXParseException( String.format( "At line %d, column %d: Strange attributes.", lineNum, colNum ), null, null, lineNum, colNum);
|
||||||
|
throw new JDOMParseException( String.format( "Error on line %d: %s", lineNum, cause.getMessage() ), cause );
|
||||||
}
|
}
|
||||||
am.region( am.end(), am.regionEnd() );
|
|
||||||
}
|
|
||||||
if ( am.regionStart() < attrString.length() ) {
|
|
||||||
int nonspacePos = findNextNonspace( s, pos );
|
|
||||||
int errorPos = ( (nonspacePos != -1) ? nonspacePos : pos );
|
|
||||||
|
|
||||||
int[] lineAndCol = getLineAndCol( s, errorPos );
|
|
||||||
int lineNum = lineAndCol[0];
|
|
||||||
int colNum = lineAndCol[1];
|
|
||||||
|
|
||||||
SAXParseException cause = new SAXParseException( String.format( "At line %d, column %d: Strange attributes.", lineNum, colNum ), null, null, lineNum, colNum);
|
|
||||||
throw new JDOMParseException( String.format( "Error on line %d: %s", lineNum, cause.getMessage() ), cause );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory.addContent( parentNode, tagNode );
|
||||||
|
if ( !selfClosing ) parentNode = tagNode;
|
||||||
}
|
}
|
||||||
|
else if ( chunkPtn == eTagPtn ) {
|
||||||
factory.addContent( parentNode, tagNode );
|
String interimText = m.group( 1 );
|
||||||
if ( !selfClosing ) parentNode = tagNode;
|
interimText = unescape( interimText );
|
||||||
|
|
||||||
|
factory.addContent( parentNode, factory.text( interimText ) );
|
||||||
|
parentNode = parentNode.getParent();
|
||||||
|
|
||||||
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
|
}
|
||||||
|
else if ( chunkPtn == endSpacePtn ) {
|
||||||
|
// This is the end of the document.
|
||||||
|
}
|
||||||
|
else if ( chunkPtn == strayCharsPtn ) {
|
||||||
|
// Non-space junk between an end tag and a start tag.
|
||||||
|
|
||||||
|
String whitespace = m.group( 1 );
|
||||||
|
if ( whitespace.length() > 0 )
|
||||||
|
factory.addContent( parentNode, factory.text( whitespace ) );
|
||||||
|
|
||||||
|
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
matchedChunk = true;
|
||||||
|
lastPos = pos;
|
||||||
|
pos = m.end();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if ( chunkPtn == eTagPtn ) {
|
|
||||||
String interimText = m.group( 1 );
|
if ( !matchedChunk ) {
|
||||||
interimText = unescape( interimText );
|
int nonspacePos = findNextNonspace( s, pos );
|
||||||
|
int errorPos = ( (nonspacePos != -1) ? nonspacePos : pos );
|
||||||
factory.addContent( parentNode, factory.text( interimText ) );
|
|
||||||
parentNode = parentNode.getParent();
|
int[] lineAndCol = getLineAndCol( s, errorPos );
|
||||||
|
int lineNum = lineAndCol[0];
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
int colNum = lineAndCol[1];
|
||||||
|
|
||||||
|
SAXParseException cause = new SAXParseException( String.format( "At line %d, column %d: Unexpected characters.", lineNum, colNum ), null, null, lineNum, colNum);
|
||||||
|
throw new JDOMParseException( String.format( "Error on line %d: %s", lineNum, cause.getMessage() ), cause );
|
||||||
}
|
}
|
||||||
else if ( chunkPtn == endSpacePtn ) {
|
}
|
||||||
// This is the end of the document.
|
|
||||||
|
if ( rootNode.getChildren().size() == 1 ) {
|
||||||
|
// No need for the wrapper, promote its only child to root.
|
||||||
|
|
||||||
|
Element newRoot = rootNode.getChildren().get( 0 );
|
||||||
|
newRoot.detach();
|
||||||
|
for ( Namespace ns : rootNode.getAdditionalNamespaces() ) {
|
||||||
|
factory.addNamespaceDeclaration( newRoot, ns );
|
||||||
}
|
}
|
||||||
else if ( chunkPtn == strayCharsPtn ) {
|
factory.setRoot( doc, newRoot );
|
||||||
// Non-space junk between an end tag and a start tag.
|
|
||||||
|
|
||||||
String whitespace = m.group( 1 );
|
|
||||||
if ( whitespace.length() > 0 )
|
|
||||||
factory.addContent( parentNode, factory.text( whitespace ) );
|
|
||||||
|
|
||||||
addLineAndCol( lastLineAndCol, s, m.start(), m.end() );
|
|
||||||
}
|
|
||||||
|
|
||||||
matchedChunk = true;
|
|
||||||
lastPos = pos;
|
|
||||||
pos = m.end();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !matchedChunk ) {
|
|
||||||
int nonspacePos = findNextNonspace( s, pos );
|
|
||||||
int errorPos = ( (nonspacePos != -1) ? nonspacePos : pos );
|
|
||||||
|
|
||||||
int[] lineAndCol = getLineAndCol( s, errorPos );
|
|
||||||
int lineNum = lineAndCol[0];
|
|
||||||
int colNum = lineAndCol[1];
|
|
||||||
|
|
||||||
SAXParseException cause = new SAXParseException( String.format( "At line %d, column %d: Unexpected characters.", lineNum, colNum ), null, null, lineNum, colNum);
|
|
||||||
throw new JDOMParseException( String.format( "Error on line %d: %s", lineNum, cause.getMessage() ), cause );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch( IllegalAddException e ) {
|
||||||
|
int nonspacePos = findNextNonspace( s, pos );
|
||||||
|
int errorPos = ( (nonspacePos != -1) ? nonspacePos : pos );
|
||||||
|
|
||||||
if ( rootNode.getChildren().size() == 1 ) {
|
int[] lineAndCol = getLineAndCol( s, errorPos );
|
||||||
// No need for the wrapper, promote its only child to root.
|
int lineNum = lineAndCol[0];
|
||||||
|
int colNum = lineAndCol[1];
|
||||||
|
|
||||||
Element newRoot = rootNode.getChildren().get( 0 );
|
String hint = "";
|
||||||
newRoot.detach();
|
if ( e.getMessage() != null && e.getMessage().indexOf( "not allowed at the document root" ) != -1 ) {
|
||||||
for ( Namespace ns : rootNode.getAdditionalNamespaces() ) {
|
hint = " (There's likely an extraneous closing tag before this point.)";
|
||||||
factory.addNamespaceDeclaration( newRoot, ns );
|
|
||||||
}
|
}
|
||||||
factory.setRoot( doc, newRoot );
|
SAXParseException cause = new SAXParseException( String.format( "At line %d, column %d: %s%s", lineNum, colNum, e.getMessage(), hint ), null, null, lineNum, colNum, e);
|
||||||
|
throw new JDOMParseException( String.format( "Error on line %d: %s", lineNum, cause.getMessage() ), cause );
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue