212 lines
6.6 KiB
Java
212 lines
6.6 KiB
Java
/******************************************************************************
|
|
* Copyright (c) 2002 - 2011 IBM Corporation.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial API and implementation
|
|
*****************************************************************************/
|
|
package com.ibm.wala.cast.js.html.nu_validator;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.LineNumberReader;
|
|
import java.io.Reader;
|
|
import java.io.StringReader;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.AbstractMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.Stack;
|
|
|
|
import org.xml.sax.Attributes;
|
|
import org.xml.sax.ContentHandler;
|
|
import org.xml.sax.InputSource;
|
|
import org.xml.sax.Locator;
|
|
import org.xml.sax.SAXException;
|
|
|
|
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
|
import com.ibm.wala.cast.js.html.IHtmlParser;
|
|
import com.ibm.wala.cast.js.html.ITag;
|
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
|
import com.ibm.wala.cast.tree.impl.LineNumberPosition;
|
|
import com.ibm.wala.util.collections.Pair;
|
|
|
|
import nu.validator.htmlparser.common.XmlViolationPolicy;
|
|
import nu.validator.htmlparser.sax.HtmlParser;
|
|
|
|
public class NuValidatorHtmlParser implements IHtmlParser {
|
|
|
|
@Override
|
|
public void parse(final URL url, final Reader reader, final IHtmlCallback handler, final String fileName) {
|
|
URL xx = null;
|
|
try {
|
|
xx = new URL("file://" + fileName);
|
|
} catch (MalformedURLException e1) {
|
|
e1.printStackTrace();
|
|
}
|
|
final URL localFileName = xx;
|
|
|
|
HtmlParser parser = new HtmlParser();
|
|
parser.setXmlPolicy(XmlViolationPolicy.ALLOW);
|
|
parser.setContentHandler(new ContentHandler() {
|
|
private Locator locator;
|
|
private Stack<ITag> tags = new Stack<>();
|
|
|
|
private int countLines(char[] ch, int start, int length) {
|
|
LineNumberReader r = new LineNumberReader(new StringReader (new String(ch, start, length)));
|
|
try {
|
|
while (r.read() > -1);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("cannot read from string", e);
|
|
}
|
|
return r.getLineNumber();
|
|
}
|
|
|
|
@Override
|
|
public void setDocumentLocator(Locator locator) {
|
|
this.locator = locator;
|
|
}
|
|
|
|
@Override
|
|
public void startElement(String uri, final String localName, String qName, final Attributes atts) throws SAXException {
|
|
final Position line = new LineNumberPosition(url, localFileName, locator.getLineNumber());
|
|
tags.push(new ITag() {
|
|
|
|
@Override
|
|
public String getName() {
|
|
return localName;
|
|
}
|
|
|
|
@Override
|
|
public Pair<String,Position> getAttributeByName(String name) {
|
|
if (atts.getValue(name) != null) {
|
|
return Pair.make(atts.getValue(name), line);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Map<String, Pair<String,Position>> getAllAttributes() {
|
|
return new AbstractMap<String,Pair<String,Position>>() {
|
|
private Set<Map.Entry<String,Pair<String,Position>>> es = null;
|
|
|
|
@Override
|
|
public Set<java.util.Map.Entry<String, Pair<String,Position>>> entrySet() {
|
|
if (es == null) {
|
|
es = new HashSet<>();
|
|
for(int i = 0; i < atts.getLength(); i++) {
|
|
final int index = i;
|
|
es.add(new Map.Entry<String,Pair<String,Position>>() {
|
|
|
|
@Override
|
|
public String getKey() {
|
|
return atts.getLocalName(index).toLowerCase();
|
|
}
|
|
|
|
@Override
|
|
public Pair<String,Position> getValue() {
|
|
if (atts.getValue(index) != null) {
|
|
return Pair.make(atts.getValue(index), line);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Pair<String,Position> setValue(Pair<String,Position> value) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return es;
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public Position getElementPosition() {
|
|
return line;
|
|
}
|
|
|
|
@Override
|
|
public Position getContentPosition() {
|
|
return line;
|
|
}
|
|
});
|
|
|
|
handler.handleStartTag(tags.peek());
|
|
}
|
|
|
|
@Override
|
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
|
handler.handleEndTag(tags.pop());
|
|
}
|
|
|
|
@Override
|
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
|
handler.handleText(new LineNumberPosition(url, localFileName, locator.getLineNumber() - countLines(ch, start, length)), new String(ch, start, length));
|
|
}
|
|
|
|
@Override
|
|
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
|
handler.handleText(new LineNumberPosition(url, localFileName, locator.getLineNumber()), new String(ch, start, length));
|
|
}
|
|
|
|
@Override
|
|
public void startDocument() throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void endDocument() throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void endPrefixMapping(String prefix) throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void processingInstruction(String target, String data) throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void skippedEntity(String name) throws SAXException {
|
|
// do nothing
|
|
}
|
|
|
|
});
|
|
|
|
try {
|
|
parser.parse(new InputSource(new InputStream() {
|
|
@Override
|
|
public int read() throws IOException {
|
|
int v;
|
|
do {
|
|
v = reader.read();
|
|
} while (v == '\r');
|
|
return v;
|
|
}
|
|
}));
|
|
} catch (IOException e) {
|
|
assert false : e.toString();
|
|
} catch (SAXException e) {
|
|
assert false : e.toString();
|
|
}
|
|
}
|
|
}
|