in src/main/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReader.java [195:337]
private void parseInternal(final InputStream bufferedInput, final ContentCreator creator, final URL xmlLocation)
throws XmlPullParserException, IOException, RepositoryException {
final StringBuilder contentBuffer = new StringBuilder();
// Mark the beginning of the stream. We assume that if there's an XSL processing
// instruction,
// it will occur in the first gulp - which makes sense, as processing
// instructions must be
// specified before the root element of an XML file.
bufferedInput.mark(bufferedInput.available());
// set the parser input, use null encoding to force detection with
// <?xml?>
this.xmlParser.setInput(bufferedInput, null);
NodeDescription.SHARED.clear();
PropertyDescription.SHARED.clear();
FileDescription.SHARED.clear();
NodeDescription currentNode = null;
PropertyDescription currentProperty = null;
String currentElement;
int eventType = this.xmlParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.PROCESSING_INSTRUCTION) {
ProcessingInstruction pi = new ProcessingInstruction(this.xmlParser.getText());
// Look for a reference to an XSL stylesheet
if (pi.getName().equals(XML_STYLESHEET_PROCESSING_INSTRUCTION) && xmlLocation != null) {
// Rewind the input stream to the beginning, so that it can be transformed with
// XSL
bufferedInput.reset();
// Pipe the XML input through the XSL transformer
XslTransformerStream transformerStream = new XslTransformerStream(bufferedInput,
pi.getAttribute(HREF_ATTRIBUTE), xmlLocation);
// Start the transformer thread
transformerStream.startTransform();
// Re-run the XML parser, now with the transformed XML
parseInternal(transformerStream, creator, xmlLocation);
transformerStream.close();
return;
}
}
if (eventType == XmlPullParser.START_TAG) {
currentElement = this.xmlParser.getName();
if (ELEM_PROPERTY.equals(currentElement)) {
currentNode = NodeDescription.create(currentNode, creator);
currentProperty = PropertyDescription.SHARED;
} else if (ELEM_NODE.equals(currentElement)) {
NodeDescription.create(currentNode, creator);
currentNode = NodeDescription.SHARED;
} else if (ELEM_FILE_NAME.equals(currentElement)
&& ELEM_FILE_NAMESPACE.equals(this.xmlParser.getNamespace())) {
if (xmlLocation != null) {
int attributeCount = this.xmlParser.getAttributeCount();
if (attributeCount < 2 || attributeCount > 3) {
throw new IOException(
"File element must have these attributes: url, mimeType and lastModified: "
+ xmlLocation);
}
try {
AttributeMap attributes = AttributeMap.getInstance();
attributes.setValues(xmlParser);
FileDescription.SHARED.setBaseLocation(xmlLocation);
FileDescription.SHARED.setValues(attributes);
attributes.clear();
} catch (ParseException e) {
IOException ioe = new IOException("Error parsing file description: " + xmlLocation);
ioe.initCause(e);
throw ioe;
}
FileDescription.SHARED.create(creator);
FileDescription.SHARED.clear();
} else {
logger.warn("file element encountered when xml location isn't known. skipping.");
}
}
} else if (eventType == XmlPullParser.END_TAG) {
String qName = this.xmlParser.getName();
String content = contentBuffer.toString().trim();
contentBuffer.delete(0, contentBuffer.length());
if (ELEM_PROPERTY.equals(qName)) {
if (currentProperty != null) {
if (currentProperty.getName() == null) {
throw new IOException(String.format("XML file does not seem to contain valid content xml. Expected %s element for property in : %s", ELEM_NAME, xmlLocation));
}
currentProperty = PropertyDescription.create(currentProperty, creator);
}
} else if (ELEM_NAME.equals(qName)) {
if (currentProperty != null) {
currentProperty.setName(content);
} else if (currentNode != null) {
currentNode.setName(content);
} else {
throw new IOException(String.format(INVALID_XML_UNEXPECTED_ELEMENT, qName, xmlLocation));
}
} else if (ELEM_VALUE.equals(qName)) {
if (currentProperty == null) {
throw new IOException(String.format(INVALID_XML_UNEXPECTED_ELEMENT, qName, xmlLocation));
}
currentProperty.addValue(content);
} else if (ELEM_VALUES.equals(qName)) {
if (currentProperty == null) {
throw new IOException(String.format(INVALID_XML_UNEXPECTED_ELEMENT, qName, xmlLocation));
}
currentProperty.setMultiValue(true);
} else if (ELEM_TYPE.equals(qName)) {
if (currentProperty == null) {
throw new IOException(String.format(INVALID_XML_UNEXPECTED_ELEMENT, qName, xmlLocation));
}
currentProperty.setType(content);
} else if (ELEM_NODE.equals(qName)) {
currentNode = NodeDescription.create(currentNode, creator);
creator.finishNode();
} else if (ELEM_PRIMARY_NODE_TYPE.equals(qName)) {
if (currentNode == null) {
throw new IOException(String.format(INVALID_XML_ELEMENT_NOT_ALLOWED, qName, xmlLocation));
}
currentNode.setPrimaryNodeType(content);
} else if (ELEM_MIXIN_NODE_TYPE.equals(qName)) {
if (currentNode == null) {
throw new IOException(String.format(INVALID_XML_ELEMENT_NOT_ALLOWED, qName, xmlLocation));
}
currentNode.addMixinType(content);
}
} else if (eventType == XmlPullParser.TEXT || eventType == XmlPullParser.CDSECT) {
contentBuffer.append(this.xmlParser.getText());
}
eventType = this.xmlParser.nextToken();
}
}