Skip to content

Commit 825b50e

Browse files
committed
WIP - SAX Parse indices
1 parent cb4682d commit 825b50e

2 files changed

Lines changed: 141 additions & 39 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.databasepreservation.modules.siard.in.path;
2+
3+
import java.nio.file.FileSystems;
4+
import java.nio.file.Path;
5+
import java.util.Map;
6+
import java.util.regex.Matcher;
7+
import java.util.regex.Pattern;
8+
9+
import org.xml.sax.Attributes;
10+
import org.xml.sax.SAXException;
11+
import org.xml.sax.helpers.DefaultHandler;
12+
13+
import com.databasepreservation.modules.siard.constants.SIARDDKConstants;
14+
15+
/**
16+
*
17+
* @author Alexandre Flores <aflores@keep.pt>
18+
*/
19+
public abstract class SIARDDKFileIndexHandler<T, D> extends DefaultHandler {
20+
21+
protected final Map<String, Path> archiveFolderLookupByFolderName;
22+
protected final Map<String, T> xmlFilePathLookupByFolderName;
23+
protected final Map<String, T> xsdFilePathLookupByFolderName;
24+
25+
private final Pattern patternTableFolder = Pattern
26+
.compile("(AVID\\.[A-ZÆØÅ]{2,4}\\.[0-9]*\\.[0-9]*)\\\\Tables\\\\(table[0-9]*)");
27+
private final Pattern patternIndicesFolder = Pattern.compile("AVID\\.[A-ZÆØÅ]{2,4}\\.[0-9]*\\.1\\\\Indices");
28+
29+
protected String currentFileFoN;
30+
protected String currentFileFiN;
31+
protected String currentFileMD5;
32+
private StringBuilder currentElementCharacters;
33+
34+
public SIARDDKFileIndexHandler(Map<String, Path> archiveFolderLookupByFolderName,
35+
Map<String, T> xsdFilePathLookupByFolderName, Map<String, T> xmlFilePathLookupByFolderName) {
36+
this.archiveFolderLookupByFolderName = archiveFolderLookupByFolderName;
37+
this.xsdFilePathLookupByFolderName = xsdFilePathLookupByFolderName;
38+
this.xmlFilePathLookupByFolderName = xmlFilePathLookupByFolderName;
39+
}
40+
41+
@Override
42+
public void startDocument() throws SAXException {
43+
// no op
44+
}
45+
46+
@Override
47+
public void endDocument() throws SAXException {
48+
// no op
49+
}
50+
51+
@Override
52+
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
53+
currentElementCharacters = new StringBuilder();
54+
}
55+
56+
@Override
57+
public void endElement(String uri, String localName, String qName) throws SAXException {
58+
switch (localName) {
59+
case (getFileLocalName()):
60+
endElementFile();
61+
}
62+
}
63+
64+
@Override
65+
public void characters(char ch[], int start, int length) throws SAXException {
66+
currentElementCharacters.append(ch, start, length);
67+
}
68+
69+
private void startElementF(String uri, String localName, String qName, Attributes attributes) {
70+
}
71+
72+
private void endElementFile() throws SAXException {
73+
Matcher matcherTableFolder = patternTableFolder.matcher(currentFileFoN);
74+
if (matcherTableFolder.matches()) {
75+
String folderName = matcherTableFolder.group(2);
76+
Path archivePath = FileSystems.getDefault().getPath(matcherTableFolder.group(1));
77+
archiveFolderLookupByFolderName.put(folderName, archivePath);
78+
if (currentFileFiN.toLowerCase().endsWith(SIARDDKConstants.XML_EXTENSION)) {
79+
if (xmlFilePathLookupByFolderName.containsKey(folderName)) {
80+
throw new SAXException("Inconsistent data in the " + SIARDDKConstants.FILE_INDEX
81+
+ " for table files. Multiple entries for the xml file for folder [" + folderName + "].");
82+
}
83+
xmlFilePathLookupByFolderName.put(folderName, fileInfo);
84+
} else {
85+
if (getFiN(fileInfo).toLowerCase().endsWith(SIARDDKConstants.XSD_EXTENSION)) {
86+
if (xsdFilePathLookupByFolderName.containsKey(folderName)) {
87+
throw new SAXException("Inconsistent data in the " + SIARDDKConstants.FILE_INDEX
88+
+ " for table files. Multiple entries for the xsd file for folder [" + folderName + "].");
89+
}
90+
xsdFilePathLookupByFolderName.put(folderName, fileInfo);
91+
}
92+
}
93+
}
94+
}
95+
96+
abstract String getFileLocalName();
97+
}

dbptk-modules/dbptk-module-siard/src/main/java/com/databasepreservation/modules/siard/in/path/SIARDDKPathImportStrategy.java

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,42 @@
77
*/
88
package com.databasepreservation.modules.siard.in.path;
99

10-
import com.databasepreservation.model.exception.ModuleException;
11-
import com.databasepreservation.modules.siard.common.SIARDArchiveContainer;
12-
import com.databasepreservation.modules.siard.common.path.MetadataPathStrategy;
13-
import com.databasepreservation.modules.siard.constants.SIARDDKConstants;
14-
import com.databasepreservation.modules.siard.in.read.ReadStrategy;
15-
import jakarta.xml.bind.JAXBContext;
16-
import jakarta.xml.bind.JAXBElement;
17-
import jakarta.xml.bind.JAXBException;
18-
import jakarta.xml.bind.Unmarshaller;
19-
import java.util.List;
20-
21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
23-
import org.xml.sax.SAXException;
24-
25-
import javax.xml.XMLConstants;
26-
import javax.xml.transform.stream.StreamSource;
27-
import javax.xml.validation.Schema;
28-
import javax.xml.validation.SchemaFactory;
2910
import java.io.IOException;
3011
import java.io.InputStream;
3112
import java.nio.file.FileSystems;
3213
import java.nio.file.Path;
3314
import java.security.InvalidParameterException;
3415
import java.util.HashMap;
16+
import java.util.List;
3517
import java.util.Map;
3618
import java.util.regex.Matcher;
3719
import java.util.regex.Pattern;
3820

21+
import javax.xml.XMLConstants;
22+
import javax.xml.parsers.ParserConfigurationException;
23+
import javax.xml.parsers.SAXParser;
24+
import javax.xml.parsers.SAXParserFactory;
25+
import javax.xml.transform.stream.StreamSource;
26+
import javax.xml.validation.Schema;
27+
import javax.xml.validation.SchemaFactory;
28+
import javax.xml.validation.ValidatorHandler;
29+
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
import org.xml.sax.InputSource;
33+
import org.xml.sax.SAXException;
34+
import org.xml.sax.XMLReader;
35+
import org.xml.sax.helpers.DefaultHandler;
36+
37+
import com.databasepreservation.model.exception.ModuleException;
38+
import com.databasepreservation.modules.siard.common.SIARDArchiveContainer;
39+
import com.databasepreservation.modules.siard.common.path.MetadataPathStrategy;
40+
import com.databasepreservation.modules.siard.constants.SIARDDKConstants;
41+
import com.databasepreservation.modules.siard.in.read.ReadStrategy;
42+
43+
import jakarta.xml.bind.JAXBContext;
44+
import jakarta.xml.bind.JAXBException;
45+
3946
/**
4047
* @author Thomas Kristensen <tk@bithuset.dk>
4148
*
@@ -45,7 +52,8 @@
4552
* to retrieve md5sums.(The impl. of retrieval of md5sums for the meta
4653
* data files are only implemented to the extend that it is needed. )
4754
*/
48-
public abstract class SIARDDKPathImportStrategy<T, D> implements ContentPathImportStrategy, MetadataPathStrategy {
55+
public abstract class SIARDDKPathImportStrategy<T, D> extends DefaultHandler
56+
implements ContentPathImportStrategy, MetadataPathStrategy {
4957
protected final Logger logger = LoggerFactory.getLogger(ContentPathImportStrategy.class);
5058
protected final String importAsSchema;
5159
protected final SIARDArchiveContainer mainFolder;
@@ -55,16 +63,14 @@ public abstract class SIARDDKPathImportStrategy<T, D> implements ContentPathImpo
5563
protected final Map<String, T> xsdFilePathLookupByFolderName = new HashMap<String, T>();
5664
protected final Map<String, String> folderNameLookupByTableId = new HashMap<String, String>();
5765
protected final Map<String, Path> archiveFolderLookupByFolderName = new HashMap<String, Path>();
58-
59-
private FileIndexXsdInputStreamStrategy fileIndexXsdInputStreamStrategy;
60-
6166
protected final Pattern folderSperatorPattern = Pattern.compile("[\\\\\\/]");
67+
private final Class<D> fileIndexTypeClass;
6268
// protected byte[] fileIndexExpectedMD5Sum; --For some reason, no md5sum is
6369
// required for fileIndex.xml in the standard
6470
protected byte[] tabelIndexExpectedMD5Sum;
6571
protected byte[] archiveIndexExpectedMD5Sum;
6672
protected boolean fileIndexIsParsed;
67-
private final Class<D> fileIndexTypeClass;
73+
private FileIndexXsdInputStreamStrategy fileIndexXsdInputStreamStrategy;
6874

6975
public SIARDDKPathImportStrategy(SIARDArchiveContainer mainFolder, ReadStrategy readStrategy,
7076
MetadataPathStrategy metadataPathStrategy, String importAsSchema,
@@ -91,33 +97,32 @@ public void parseFileIndexMetadata() throws ModuleException {
9197
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
9298
Schema xsdSchema = null;
9399
InputStream xsdStream = fileIndexXsdInputStreamStrategy.getInputStream(this);
100+
ValidatorHandler validatorHandler = null;
94101
try {
95102
xsdSchema = schemaFactory.newSchema(new StreamSource(xsdStream));
103+
validatorHandler = xsdSchema.newValidatorHandler();
104+
validatorHandler.setContentHandler(new SIARDDKFileIndexHandler());
96105
} catch (SAXException e) {
97106
throw new ModuleException()
98107
.withMessage(
99108
"Error reading metadata XSD file: " + metadataPathStrategy.getXsdFilePath(SIARDDKConstants.FILE_INDEX))
100109
.withCause(e);
101110
}
102-
InputStream reader = null;
103-
D xmlFileIndex;
104-
Unmarshaller unmarshaller;
111+
105112
try {
106-
unmarshaller = context.createUnmarshaller();
107-
unmarshaller.setSchema(xsdSchema);
108-
reader = readStrategy.createInputStream(mainFolder,
109-
metadataPathStrategy.getXmlFilePath(SIARDDKConstants.FILE_INDEX));
110-
@SuppressWarnings("unchecked")
111-
JAXBElement<D> jaxbElement = (JAXBElement<D>) unmarshaller.unmarshal(reader);
112-
xmlFileIndex = jaxbElement.getValue();
113-
} catch (JAXBException e) {
114-
throw new ModuleException().withMessage("Error while Unmarshalling JAXB").withCause(e);
113+
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
114+
saxParserFactory.setValidating(false);
115+
saxParserFactory.setNamespaceAware(true);
116+
SAXParser saxParser = saxParserFactory.newSAXParser();
117+
XMLReader xmlReader = saxParser.getXMLReader();
118+
xmlReader.setContentHandler(validatorHandler);
119+
xmlReader.parse(new InputSource(readStrategy.createInputStream(mainFolder,
120+
metadataPathStrategy.getXmlFilePath(SIARDDKConstants.FILE_INDEX))));
121+
} catch (SAXException | ParserConfigurationException | IOException e) {
122+
throw new ModuleException().withMessage("Error while parsing file index").withCause(e);
115123
} finally {
116124
try {
117125
xsdStream.close();
118-
if (reader != null) {
119-
reader.close();
120-
}
121126
} catch (IOException e) {
122127
logger.debug("Could not close xsdStream", e);
123128
}

0 commit comments

Comments
 (0)