private void parseInternal()

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();
        }
    }