/*
* This file is part of NixNote
* Copyright 2009 Randy Baumgarte
*
* This file may be licensed under the terms of of the
* GNU General Public License Version 2 (the ``GPL'').
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the GPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the GPL along with this
* program. If not, go to http://www.gnu.org/licenses/gpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package cx.fbn.nevernote.xml;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import cx.fbn.nevernote.Global;
public class XMLNoteRepair {
public boolean saveInvalidXML;
public String parse(String xmlData, boolean validate) {
saveInvalidXML = false;
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlData));
XMLNoteRepairHandler handler = new XMLNoteRepairHandler();
// Replace DTD with local copy in case we are not connected
File dtdFile = Global.getFileManager().getXMLDirFile("enml2.dtd");
String dtd = dtdFile.toURI().toString();
xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \'http://xml.evernote.com/pub/enml2.dtd'>",
"<!DOCTYPE en-note SYSTEM \"" +dtd +"\">");
xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">",
"<!DOCTYPE en-note SYSTEM \"" +dtd +"\">");
handler.setXml(xmlData);
is.setCharacterStream(new StringReader(handler.getXml()));
boolean fixed = false;
int i=0;
int max = 10;
if (validate)
max = 10000;
while (!fixed && i<max) {
try {
i++;
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(validate);
SAXParser parser = factory.newSAXParser();
parser.parse(is, handler);
fixed = true;
} catch (EnmlException e) {
String message = e.getMessage();
saveInvalidXML = true;
//System.out.println("ENML Exception: " +message);
boolean found = false;
int endAttribute = message.indexOf(" must be declared for element type ");
if (message.startsWith("Attribute ") && endAttribute > -1) {
String attribute = message.substring(11, endAttribute-1);
String element = message.substring(message.indexOf("\"", endAttribute+3));
element = element.replace("\"", "");
element = element.substring(0,element.length()-1);
Global.addInvalidAttribute(element, attribute);
handler.stripAttribute(attribute, e.getLineNumber(), e.getColumnNumber());
is.setCharacterStream(new StringReader(handler.getXml()));
found = true;
}
int endElement = message.indexOf(" must be declared.");
if (message.startsWith("Element type") && endElement > -1) {
String element = message.substring(14,endElement-1);
Global.addInvalidElement(element);
handler.renameElement(element, e.getLineNumber(), e.getColumnNumber());
is.setCharacterStream(new StringReader(handler.getXml()));
found = true;
}
if (!found)
System.err.println("New enml validation error: " +e.getMessage() +" Line:" +e.getLineNumber() +" Column:" +e.getColumnNumber());
} catch (SAXParseException e) {
System.err.println("SAXParse Exception - Attempt #"+i +" "+e.getMessage());
handler.repair(e.getLineNumber(), e.getColumnNumber());
is.setCharacterStream(new StringReader(handler.getXml()));
if (validate) {
System.err.println("Error validating ENML2 DTD");
return null;
}
} catch (SAXException e) {
System.err.append("SAXException");
e.printStackTrace();
} catch (ParserConfigurationException e) {
System.err.println("Parser Config Error");
e.printStackTrace();
} catch (IOException e) {
System.err.println("IO Exception");
e.printStackTrace();
}
}
if (!fixed)
return null;
else {
// Replace DTD with online copy
xmlData = handler.getXml();
xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \"" +dtd +"\">", "<!DOCTYPE en-note SYSTEM \'http://xml.evernote.com/pub/enml2.dtd'>");
return xmlData;
}
}
}