Search in sources :

Example 11 with DOMException

use of com.gargoylesoftware.css.dom.DOMException in project LoboEvolution by LoboEvolution.

the class XPathExpressionImpl method evaluate.

/**
 * {@inheritDoc}
 */
@Override
public Object evaluate(Node contextNode, short type, Object result) throws XPathException, DOMException {
    // If the XPathEvaluator was determined by "casting" the document
    if (m_doc != null) {
        // Check that the context node is owned by the same document
        if (!Objects.equals(contextNode, m_doc) && !contextNode.getOwnerDocument().equals(m_doc)) {
            String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_WRONG_DOCUMENT, null);
            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, fmsg);
        }
        // Check that the context node is an acceptable node type
        int nodeType = contextNode.getNodeType();
        switch(nodeType) {
            case NodeType.DOCUMENT_NODE:
            case NodeType.ELEMENT_NODE:
            case NodeType.ATTRIBUTE_NODE:
            case NodeType.TEXT_NODE:
            case NodeType.CDATA_SECTION_NODE:
            case NodeType.COMMENT_NODE:
            case NodeType.PROCESSING_INSTRUCTION_NODE:
                break;
            default:
                String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_WRONG_NODETYPE, null);
                throw new UnsupportedOperationException(fmsg);
        }
    }
    if (!XPathResultImpl.isValidType(type)) {
        String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_INVALID_XPATH_TYPE, new Object[] { (int) type });
        throw new XPathException(XPathException.TYPE_ERR, fmsg);
    }
    XPathContext xpathSupport = new XPathContext(false);
    XObject xobj = null;
    return new XPathResultImpl(type, xobj, contextNode, m_xpath);
}
Also used : DOMException(com.gargoylesoftware.css.dom.DOMException) XPathException(org.loboevolution.html.xpath.XPathException) XPathContext(org.apache.xpath.XPathContext) XObject(org.apache.xpath.objects.XObject)

Example 12 with DOMException

use of com.gargoylesoftware.css.dom.DOMException in project LoboEvolution by LoboEvolution.

the class HtmlParser method parseToken.

/**
 * Parses text followed by one element.
 *
 * @param parent
 * @param reader
 * @param stopTags    If tags in this set are encountered, the method throws
 *                    StopException.
 * @return
 * @throws IOException
 * @throws StopException
 * @throws SAXException
 */
private int parseToken(final Node parent, final LineNumberReader reader, final Set<HTMLTag> stopTags, final LinkedList<String> ancestors) throws IOException, StopException, SAXException {
    final Document doc = this.document;
    final HTMLDocumentImpl htmlDoc = (HTMLDocumentImpl) doc;
    final StringBuilder textSb = this.readUpToTagBegin(reader);
    if (textSb == null) {
        return TOKEN_EOD;
    }
    if (textSb.length() > 0) {
        // int textLine = reader.getLineNumber();
        final StringBuilder decText = entityDecode(textSb);
        final String text = decText.toString();
        if (text.trim().length() > 0) {
            final Node textNode = doc.createTextNode(decText.toString());
            try {
                safeAppendChild(parent, textNode);
            } catch (final DOMException de) {
                if ((parent.getNodeType() != NodeType.DOCUMENT_NODE) || (de.getCode() != DOMException.HIERARCHY_REQUEST_ERR)) {
                    logger.log(Level.WARNING, "parseToken(): Unable to append child to " + parent + ".", de);
                }
            }
        }
    }
    if (this.justReadTagBegin) {
        String tag = this.readTag(parent, reader);
        if (tag == null) {
            return TOKEN_EOD;
        }
        String normalTag = tag.toUpperCase();
        try {
            if (tag.startsWith("!")) {
                if ("!--".equals(tag)) {
                    final StringBuilder comment = this.passEndOfComment(reader);
                    final StringBuilder decText = entityDecode(comment);
                    safeAppendChild(parent, doc.createComment(decText.toString()));
                    return TOKEN_COMMENT;
                } else if ("!DOCTYPE".equals(tag)) {
                    final String doctypeStr = this.parseEndOfTag(reader);
                    String qName = null;
                    String publicId = null;
                    String systemId = null;
                    if (doctypeStr.contains("PUBLIC")) {
                        final Matcher doctypeMatcher = doctypePattern.matcher(doctypeStr);
                        if (doctypeMatcher.matches()) {
                            qName = doctypeMatcher.group(1);
                            publicId = doctypeMatcher.group(2);
                            systemId = doctypeMatcher.group(3);
                        }
                    } else {
                        qName = doctypeStr.replace(">", "");
                    }
                    final DocumentTypeImpl doctype = new DocumentTypeImpl(qName, publicId, systemId);
                    htmlDoc.setDoctype(doctype);
                    needRoot = false;
                    return TOKEN_BAD;
                } else {
                    passEndOfTag(reader);
                    return TOKEN_BAD;
                }
            } else if (tag.startsWith("/")) {
                tag = tag.substring(1);
                normalTag = normalTag.substring(1);
                this.passEndOfTag(reader);
                return TOKEN_END_ELEMENT;
            } else if (tag.startsWith("?")) {
                tag = tag.substring(1);
                final StringBuilder data = readProcessingInstruction(reader);
                safeAppendChild(parent, doc.createProcessingInstruction(tag, data.toString()));
                return TOKEN_FULL_ELEMENT;
            } else {
                final int localIndex = normalTag.indexOf(':');
                final boolean tagHasPrefix = localIndex > 0;
                final String localName = tagHasPrefix ? normalTag.substring(localIndex + 1) : normalTag;
                Element element = doc.createElement(localName);
                element.setUserData(MODIFYING_KEY, Boolean.TRUE, null);
                try {
                    if (!this.justReadTagEnd) {
                        while (this.readAttribute(reader, element)) {
                        // EMPTY LOOP
                        }
                    }
                    if (stopTags != null && stopTags.contains(HTMLTag.get(normalTag))) {
                        // After MODIFYING_KEY is set.
                        throw new StopException(element);
                    }
                    // Add element to parent before children are added.
                    // This is necessary for incremental rendering.
                    safeAppendChild(parent, element);
                    if (!this.justReadEmptyElement) {
                        ElementInfo einfo = HTMLEntities.ELEMENT_INFOS.get(HTMLTag.get(localName.toUpperCase()));
                        int endTagType = einfo == null ? ElementInfo.END_ELEMENT_REQUIRED : einfo.getEndElementType();
                        if (endTagType != ElementInfo.END_ELEMENT_FORBIDDEN) {
                            boolean childrenOk = einfo == null || einfo.isChildElementOk();
                            Set<HTMLTag> newStopSet = einfo == null ? null : einfo.getStopTags();
                            if (newStopSet == null) {
                                if (endTagType == ElementInfo.END_ELEMENT_OPTIONAL) {
                                    newStopSet = Collections.singleton(HTMLTag.get(normalTag));
                                }
                            }
                            if (stopTags != null) {
                                if (newStopSet != null) {
                                    final Set<HTMLTag> newStopSet2 = new HashSet<>();
                                    newStopSet2.addAll(stopTags);
                                    newStopSet2.addAll(newStopSet);
                                    newStopSet = newStopSet2;
                                } else {
                                    newStopSet = endTagType == ElementInfo.END_ELEMENT_REQUIRED ? null : stopTags;
                                }
                            }
                            ancestors.addFirst(normalTag);
                            try {
                                for (; ; ) {
                                    try {
                                        int token;
                                        if ((einfo != null) && einfo.isNoScriptElement()) {
                                            final UserAgentContext ucontext = this.ucontext;
                                            if ((ucontext == null) || ucontext.isScriptingEnabled()) {
                                                token = this.parseForEndTag(parent, reader, tag, false, shouldDecodeEntities(einfo));
                                            } else {
                                                token = this.parseToken(element, reader, newStopSet, ancestors);
                                            }
                                        } else {
                                            token = childrenOk ? this.parseToken(element, reader, newStopSet, ancestors) : this.parseForEndTag(element, reader, tag, true, shouldDecodeEntities(einfo));
                                        }
                                        if (token == TOKEN_END_ELEMENT) {
                                            final String normalLastTag = this.normalLastTag;
                                            if (normalTag.equalsIgnoreCase(normalLastTag)) {
                                                return TOKEN_FULL_ELEMENT;
                                            } else {
                                                final ElementInfo closeTagInfo = HTMLEntities.ELEMENT_INFOS.get(HTMLTag.get(normalLastTag.toUpperCase()));
                                                if ((closeTagInfo == null) || (closeTagInfo.getEndElementType() != ElementInfo.END_ELEMENT_FORBIDDEN)) {
                                                    // TODO: Rather inefficient algorithm, but it's
                                                    // probably executed infrequently?
                                                    final Iterator<String> i = ancestors.iterator();
                                                    if (i.hasNext()) {
                                                        i.next();
                                                        while (i.hasNext()) {
                                                            final String normalAncestorTag = i.next();
                                                            if (normalLastTag.equals(normalAncestorTag)) {
                                                                normalTag = normalLastTag;
                                                                return TOKEN_END_ELEMENT;
                                                            }
                                                        }
                                                    }
                                                }
                                            // TODO: Working here
                                            }
                                        } else if (token == TOKEN_EOD) {
                                            return TOKEN_EOD;
                                        }
                                    } catch (final StopException se) {
                                        // newElement does not have a parent.
                                        final Element newElement = se.getElement();
                                        tag = newElement.getTagName();
                                        normalTag = tag.toUpperCase();
                                        if (stopTags != null && stopTags.contains(HTMLTag.get(normalTag))) {
                                            throw se;
                                        }
                                        einfo = HTMLEntities.ELEMENT_INFOS.get(HTMLTag.get(normalTag.toUpperCase()));
                                        endTagType = einfo == null ? ElementInfo.END_ELEMENT_REQUIRED : einfo.getEndElementType();
                                        childrenOk = einfo == null || einfo.isChildElementOk();
                                        newStopSet = einfo == null ? null : einfo.getStopTags();
                                        if (newStopSet == null) {
                                            if (endTagType == ElementInfo.END_ELEMENT_OPTIONAL) {
                                                newStopSet = Collections.singleton(HTMLTag.get(normalTag));
                                            }
                                        }
                                        if (stopTags != null && newStopSet != null) {
                                            final Set<HTMLTag> newStopSet2 = new HashSet<>();
                                            newStopSet2.addAll(stopTags);
                                            newStopSet2.addAll(newStopSet);
                                            newStopSet = newStopSet2;
                                        }
                                        ancestors.removeFirst();
                                        ancestors.addFirst(normalTag);
                                        // Switch element
                                        element.setUserData(MODIFYING_KEY, Boolean.FALSE, null);
                                        // newElement should have been suspended.
                                        element = newElement;
                                        // Add to parent
                                        safeAppendChild(parent, element);
                                        if (this.justReadEmptyElement) {
                                            return TOKEN_BEGIN_ELEMENT;
                                        }
                                    }
                                }
                            } finally {
                                ancestors.removeFirst();
                            }
                        }
                    }
                    return TOKEN_BEGIN_ELEMENT;
                } finally {
                    // This can inform elements to continue with notifications.
                    // It can also cause Javascript to be loaded / processed.
                    // Update: Elements now use Document.addJob() to delay processing
                    element.setUserData(MODIFYING_KEY, Boolean.FALSE, null);
                }
            }
        } finally {
            this.normalLastTag = normalTag;
        }
    } else {
        this.normalLastTag = null;
        return TOKEN_TEXT;
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) UserAgentContext(org.loboevolution.http.UserAgentContext) Matcher(java.util.regex.Matcher) ElementInfo(org.loboevolution.info.ElementInfo) Node(org.loboevolution.html.node.Node) Element(org.loboevolution.html.node.Element) DocumentTypeImpl(org.loboevolution.html.dom.domimpl.DocumentTypeImpl) Document(org.loboevolution.html.node.Document) HTMLDocumentImpl(org.loboevolution.html.dom.domimpl.HTMLDocumentImpl) DOMException(com.gargoylesoftware.css.dom.DOMException) HTMLTag(org.loboevolution.html.HTMLTag) HashSet(java.util.HashSet)

Example 13 with DOMException

use of com.gargoylesoftware.css.dom.DOMException in project LoboEvolution by LoboEvolution.

the class CSSStyleSheetImpl method deleteRule.

/**
 * {@inheritDoc}
 */
@Override
public void deleteRule(int index) {
    try {
        cssStyleSheet.deleteRule(index);
        this.cssRuleList.addStyleRule(cssStyleSheet.getCssRules());
    } catch (Exception e) {
        throw new DOMException(DOMException.INDEX_SIZE_ERR, e.getMessage());
    }
}
Also used : DOMException(com.gargoylesoftware.css.dom.DOMException) DOMException(com.gargoylesoftware.css.dom.DOMException)

Example 14 with DOMException

use of com.gargoylesoftware.css.dom.DOMException in project LoboEvolution by LoboEvolution.

the class DOMImplementationTest method testCreateDocumentType.

@Test
public void testCreateDocumentType() {
    DocumentType doctype = domImpl.createDocumentType("html", null, null);
    assertEquals("<!DOCTYPE html>", doctype.toString());
    // 
    doctype = domImpl.createDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", null);
    assertEquals("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\">", doctype.toString());
    // 
    doctype = domImpl.createDocumentType("html", null, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
    assertEquals("<!DOCTYPE html SYSTEM \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">", doctype.toString());
    // 
    doctype = domImpl.createDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
    assertEquals("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">", doctype.toString());
    // 
    try {
        domImpl.createDocumentType("html><html><injection/", null, null);
        fail("Must throw exception.");
    } catch (DOMException e) {
        assertEquals(DOMException.INVALID_CHARACTER_ERR, e.getCode());
    }
    // 
    doctype = domImpl.createDocumentType("html", "\"><injection foo=\"", null);
    assertEquals("<!DOCTYPE html PUBLIC \"&quot;&gt;&lt;injection foo=&quot;\">", doctype.toString());
    // 
    doctype = domImpl.createDocumentType("html", null, "\"><injection foo=\"");
    assertEquals("<!DOCTYPE html SYSTEM \"&quot;&gt;&lt;injection foo=&quot;\">", doctype.toString());
}
Also used : DOMException(com.gargoylesoftware.css.dom.DOMException) DocumentType(org.loboevolution.html.node.DocumentType) Test(org.junit.Test) LoboUnitTest(org.loboevolution.driver.LoboUnitTest)

Example 15 with DOMException

use of com.gargoylesoftware.css.dom.DOMException in project LoboEvolution by LoboEvolution.

the class HTMLDocumentTest method testAppendChildTwoDoctypesError.

@Test
public void testAppendChildTwoDoctypesError() throws DOMException {
    UserAgentContext context = new UserAgentContext(true);
    context.setUserAgentEnabled(false);
    Document document = new DOMImplementationImpl(context).createDocument(null, null, null);
    document.appendChild(document.getImplementation().createDocumentType("foo", null, null));
    try {
        document.appendChild(document.getImplementation().createDocumentType("bar", null, null));
        fail("Must throw exception.");
    } catch (DOMException e) {
        assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
    }
}
Also used : DOMException(com.gargoylesoftware.css.dom.DOMException) UserAgentContext(org.loboevolution.http.UserAgentContext) Test(org.junit.Test) LoboUnitTest(org.loboevolution.driver.LoboUnitTest)

Aggregations

DOMException (com.gargoylesoftware.css.dom.DOMException)31 Test (org.junit.Test)12 LoboUnitTest (org.loboevolution.driver.LoboUnitTest)12 HTMLElement (org.loboevolution.html.dom.HTMLElement)8 HTMLLinkElement (org.loboevolution.html.dom.HTMLLinkElement)8 Document (org.loboevolution.html.node.Document)8 NodeListImpl (org.loboevolution.html.dom.nodeimpl.NodeListImpl)6 Selector (com.gargoylesoftware.css.parser.selector.Selector)4 SelectorList (com.gargoylesoftware.css.parser.selector.SelectorList)4 Node (org.loboevolution.html.node.Node)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 HTMLBodyElement (org.loboevolution.html.dom.HTMLBodyElement)2 ElementFilter (org.loboevolution.html.dom.filter.ElementFilter)2 DocumentType (org.loboevolution.html.node.DocumentType)2 UserAgentContext (org.loboevolution.http.UserAgentContext)2 CSSStyleDeclarationImpl (com.gargoylesoftware.css.dom.CSSStyleDeclarationImpl)1 CSSOMParser (com.gargoylesoftware.css.parser.CSSOMParser)1 CSS3Parser (com.gargoylesoftware.css.parser.javacc.CSS3Parser)1