Skip to content

Commit 5da2096

Browse files
committed
Validate XML document against schema
1 parent 749e5bd commit 5da2096

File tree

1 file changed

+76
-52
lines changed
  • src/main/java/com/coniferproductions/sevenator

1 file changed

+76
-52
lines changed

src/main/java/com/coniferproductions/sevenator/App.java

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@
1414
import java.util.List;
1515
import java.util.ArrayList;
1616
import java.nio.ByteOrder;
17-
import java.util.logging.Level;
1817

1918
import javafx.application.Application;
2019
import javafx.application.Platform;
2120
import javafx.collections.FXCollections;
2221
import javafx.collections.ObservableList;
23-
import javafx.fxml.FXMLLoader;
2422
import javafx.scene.Scene;
2523
import javafx.scene.control.*;
2624
import javafx.scene.layout.BorderPane;
@@ -31,15 +29,12 @@
3129
import javafx.stage.Stage;
3230

3331
import static java.lang.System.Logger.Level.*;
34-
import static java.util.logging.Level.SEVERE;
3532

36-
import org.apache.batik.swing.JSVGCanvas;
3733
import org.apache.batik.transcoder.TranscoderException;
3834
import org.apache.batik.transcoder.TranscoderInput;
3935
import org.apache.batik.transcoder.TranscoderOutput;
4036
import org.apache.batik.transcoder.image.ImageTranscoder;
4137

42-
import javafx.embed.swing.SwingNode;
4338
import javafx.embed.swing.SwingFXUtils;
4439
import javafx.scene.image.Image;
4540
import javafx.scene.image.ImageView;
@@ -48,9 +43,15 @@
4843
import org.xml.sax.SAXException;
4944
import org.xml.sax.SAXParseException;
5045

46+
import javax.xml.XMLConstants;
5147
import javax.xml.parsers.DocumentBuilder;
5248
import javax.xml.parsers.DocumentBuilderFactory;
5349
import javax.xml.parsers.ParserConfigurationException;
50+
import javax.xml.transform.dom.DOMSource;
51+
import javax.xml.validation.Schema;
52+
import javax.xml.validation.SchemaFactory;
53+
import javax.xml.validation.SchemaFactoryConfigurationError;
54+
import javax.xml.validation.Validator;
5455

5556
public class App extends Application {
5657
public static final String LOGGER_NAME = "com.coniferproductions.sevenator";
@@ -141,6 +142,74 @@ String getFileExtension(String filename) {
141142
return "";
142143
}
143144

145+
private void loadSyxFile(Path path) throws IOException, ParseException {
146+
List<UInt8> data = new ArrayList<>();
147+
byte[] contents = Files.readAllBytes(path);
148+
data = UInt8.listFromByteArray(contents);
149+
150+
Message message = Message.parse(data);
151+
logger.log(DEBUG, "data length = " + data.size());
152+
153+
Header header = Header.parse(message.getPayload());
154+
logger.log(DEBUG, header);
155+
156+
List<UInt8> payload = message.getPayload();
157+
List<UInt8> cartridgeData = payload.subList(header.getDataSize(), payload.size() - 1);
158+
159+
cartridge = Cartridge.parse(cartridgeData);
160+
}
161+
162+
private void loadXmlDocument(Path path) throws ParserConfigurationException, IOException, SAXException {
163+
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
164+
documentBuilderFactory.setNamespaceAware(true); // required for validation
165+
documentBuilderFactory.setValidating(true);
166+
documentBuilderFactory.setIgnoringElementContentWhitespace(true);
167+
168+
// Prepare the documentBuilderFactory for handling schemas
169+
final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
170+
documentBuilderFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI);
171+
172+
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
173+
174+
builder.setErrorHandler(new ErrorHandler() {
175+
@Override
176+
public void warning(SAXParseException exception) throws SAXException {
177+
logger.log(WARNING, exception.getMessage());
178+
}
179+
180+
@Override
181+
public void error(SAXParseException exception) throws SAXException {
182+
logger.log(ERROR, exception.getMessage());
183+
}
184+
185+
@Override
186+
public void fatalError(SAXParseException exception) throws SAXException {
187+
logger.log(ERROR, exception.getMessage());
188+
}
189+
});
190+
Document document = builder.parse(Files.newInputStream(path));
191+
192+
// Load the schema for validation
193+
Schema schema = null;
194+
try {
195+
String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
196+
SchemaFactory schemaFactory = SchemaFactory.newInstance(language);
197+
schema = schemaFactory.newSchema(
198+
new File(
199+
Paths.get(System.getProperty("user.home") + "/tmp/", "cartridge.xsd").toString()));
200+
201+
Validator validator = schema.newValidator();
202+
validator.validate(new DOMSource(document));
203+
logger.log(INFO, path.toString() + " validated successfully");
204+
205+
document.getDocumentElement().normalize();
206+
cartridge = new Cartridge(document);
207+
208+
} catch (SchemaFactoryConfigurationError sfce) {
209+
logger.log(ERROR, sfce.getMessage());
210+
}
211+
}
212+
144213
private Menu makeFileMenu(Stage stage) {
145214
FileChooser fileChooser = new FileChooser();
146215
fileChooser.getExtensionFilters().addAll(
@@ -161,21 +230,8 @@ private Menu makeFileMenu(Stage stage) {
161230
String filename = path.getFileName().toString();
162231
String extension = getFileExtension(filename); // name is from chooser, won't be null
163232
if (extension.equals("syx")) {
164-
List<UInt8> data = new ArrayList<>();
165233
try {
166-
byte[] contents = Files.readAllBytes(path);
167-
data = UInt8.listFromByteArray(contents);
168-
169-
Message message = Message.parse(data);
170-
logger.log(DEBUG, "data length = " + data.size());
171-
172-
Header header = Header.parse(message.getPayload());
173-
logger.log(DEBUG, header);
174-
175-
List<UInt8> payload = message.getPayload();
176-
List<UInt8> cartridgeData = payload.subList(header.getDataSize(), payload.size() - 1);
177-
178-
cartridge = Cartridge.parse(cartridgeData);
234+
loadSyxFile(path);
179235
populateVoiceList();
180236
} catch (IOException ioe) {
181237
System.err.println("Error reading file: " + ioe.getLocalizedMessage());
@@ -184,46 +240,14 @@ private Menu makeFileMenu(Stage stage) {
184240
System.exit(1);
185241
}
186242
} else if (extension.equals("xml")) {
187-
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
188-
factory.setNamespaceAware(true); // required for validation
189-
factory.setValidating(true);
190-
191-
// Prepare the factory for handling schemas
192-
final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
193-
final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
194-
factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
195-
196-
factory.setIgnoringElementContentWhitespace(true);
197-
198243
try {
199-
DocumentBuilder builder = factory.newDocumentBuilder();
200-
201-
builder.setErrorHandler(new ErrorHandler() {
202-
@Override
203-
public void warning(SAXParseException exception) throws SAXException {
204-
logger.log(WARNING, exception.getMessage());
205-
}
206-
207-
@Override
208-
public void error(SAXParseException exception) throws SAXException {
209-
logger.log(ERROR, exception.getMessage());
210-
}
211-
212-
@Override
213-
public void fatalError(SAXParseException exception) throws SAXException {
214-
logger.log(ERROR, exception.getMessage());
215-
}
216-
});
217-
Document document = builder.parse(Files.newInputStream(path));
218-
document.getDocumentElement().normalize();
219-
cartridge = new Cartridge(document);
244+
loadXmlDocument(path);
220245

221246
} catch (ParserConfigurationException | IOException ex) {
222247
throw new RuntimeException(ex);
223248
} catch (SAXException ex) {
224249
throw new RuntimeException(ex);
225250
}
226-
227251
}
228252
});
229253

0 commit comments

Comments
 (0)