OSDN Git Service

Alter save thread logic so that if an error happens, a message box is produced rather...
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / xml / XMLNoteRepair.java
1 /*
2  * This file is part of NeverNote 
3  * Copyright 2009 Randy Baumgarte
4  * 
5  * This file may be licensed under the terms of of the
6  * GNU General Public License Version 2 (the ``GPL'').
7  *
8  * Software distributed under the License is distributed
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
10  * express or implied. See the GPL for the specific language
11  * governing rights and limitations.
12  *
13  * You should have received a copy of the GPL along with this
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html
15  * or write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18 */
19 package cx.fbn.nevernote.xml;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.StringReader;
24
25 import javax.xml.parsers.ParserConfigurationException;
26 import javax.xml.parsers.SAXParser;
27 import javax.xml.parsers.SAXParserFactory;
28
29 import org.xml.sax.InputSource;
30 import org.xml.sax.SAXException;
31 import org.xml.sax.SAXParseException;
32
33 import cx.fbn.nevernote.Global;
34
35 public class XMLNoteRepair {
36         public boolean saveInvalidXML;
37         
38         public String parse(String xmlData, boolean validate) {
39                 saveInvalidXML = false;
40                 InputSource is = new InputSource();
41                 is.setCharacterStream(new StringReader(xmlData));
42                 XMLNoteRepairHandler handler = new XMLNoteRepairHandler();
43                 
44                 // Replace DTD with local copy in case we are not connected
45                 File dtdFile = Global.getFileManager().getXMLDirFile("enml2.dtd");
46                 String dtd = dtdFile.toURI().toString();
47                 xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \'http://xml.evernote.com/pub/enml2.dtd'>", 
48                                 "<!DOCTYPE en-note SYSTEM \"" +dtd +"\">");
49                 xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">", 
50                                 "<!DOCTYPE en-note SYSTEM \"" +dtd +"\">");
51                 
52                 handler.setXml(xmlData);
53                 is.setCharacterStream(new StringReader(handler.getXml()));
54         
55                 boolean fixed = false;
56                 int i=0;
57                 int max = 10;
58                 if (validate)
59                         max = 10000;
60                 while (!fixed && i<max) {
61                         try {
62                                 i++;
63                                 SAXParserFactory factory = SAXParserFactory.newInstance();
64                                 factory.setValidating(validate);
65                                 SAXParser parser = factory.newSAXParser();
66                                 parser.parse(is, handler);
67                                 fixed = true;
68                         } catch (EnmlException e) { 
69                                 String message = e.getMessage();
70                                 saveInvalidXML = true;
71                                 //System.out.println("ENML Exception: " +message);
72                                 boolean found = false;
73                                 int endAttribute = message.indexOf(" must be declared for element type ");
74                                 if (message.startsWith("Attribute ") && endAttribute > -1) {
75                                         String attribute = message.substring(11, endAttribute-1);
76                                         String element = message.substring(message.indexOf("\"", endAttribute+3));
77                                         element = element.replace("\"", "");
78                                         element = element.substring(0,element.length()-1);
79                                         Global.addInvalidAttribute(element, attribute);
80                                         handler.stripAttribute(attribute, e.getLineNumber(), e.getColumnNumber());
81                                         is.setCharacterStream(new StringReader(handler.getXml()));
82                                         found = true;
83                                 }
84                                 int endElement = message.indexOf(" must be declared.");
85                                 if (message.startsWith("Element type") && endElement > -1) {
86                                         String element = message.substring(14,endElement-1);
87                                         Global.addInvalidElement(element);
88                                         handler.renameElement(element, e.getLineNumber(), e.getColumnNumber());
89                                         is.setCharacterStream(new StringReader(handler.getXml()));
90                                         found = true;
91                                 }
92                                 if (!found)
93                                         System.err.println("New enml validation error: " +e.getMessage() +" Line:" +e.getLineNumber() +" Column:" +e.getColumnNumber());
94                         } catch (SAXParseException e) {
95                                 System.err.println("SAXParse Exception - Attempt #"+i +" "+e.getMessage());
96                                 handler.repair(e.getLineNumber(), e.getColumnNumber());
97                                 is.setCharacterStream(new StringReader(handler.getXml()));
98                                 if (validate) {
99                                         System.err.println("Error validating ENML2 DTD");
100                                         return null;
101                                 }
102                         } catch (SAXException e) {
103                                 System.err.append("SAXException");
104                                 e.printStackTrace();
105                         } catch (ParserConfigurationException e) {
106                                 System.err.println("Parser Config Error");
107                                 e.printStackTrace();
108                         } catch (IOException e) {
109                                 System.err.println("IO Exception");
110                                 e.printStackTrace();
111                         }
112                 }
113                 if (!fixed)
114                         return null;
115                 else {
116                         // Replace DTD with online copy
117                         xmlData = handler.getXml();
118                         xmlData = xmlData.replace("<!DOCTYPE en-note SYSTEM \"" +dtd +"\">", "<!DOCTYPE en-note SYSTEM \'http://xml.evernote.com/pub/enml2.dtd'>");
119                         return xmlData;                 
120                 }
121         }
122 }