/*
* Copyright (c) 2008-2019 Emmanuel Dupuy.
* This project is distributed under the GPLv3 license.
* This is a Copyleft license that gives the user the right to use,
* copy and modify the code freely for non-commercial purposes.
*/
package org.jd.gui.util.xml;
import org.jd.gui.util.exception.ExceptionUtil;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
public abstract class AbstractXmlPathFinder {
protected HashMap<String, HashSet<String>> tagNameToPaths = new HashMap<>();
protected StringBuilder sb = new StringBuilder(200);
public AbstractXmlPathFinder(Collection<String> paths) {
for (String path : paths) {
if ((path != null) && (path.length() > 0)) {
// Normalize path
path = '/' + path;
int lastIndex = path.lastIndexOf('/');
String lastTagName = path.substring(lastIndex+1);
// Add tag names to map
HashSet<String> setOfPaths = tagNameToPaths.get(lastTagName);
if (setOfPaths == null) {
tagNameToPaths.put(lastTagName, setOfPaths = new HashSet<>());
}
setOfPaths.add(path);
}
}
}
public void find(String text) {
sb.setLength(0);
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(text));
String tagName = "";
int offset = 0;
while (reader.hasNext()) {
reader.next();
switch (reader.getEventType())
{
case XMLStreamReader.START_ELEMENT:
sb.append('/').append(tagName = reader.getLocalName());
offset = reader.getLocation().getCharacterOffset();
break;
case XMLStreamReader.END_ELEMENT:
sb.setLength(sb.length() - reader.getLocalName().length() - 1);
break;
case XMLStreamReader.CHARACTERS:
HashSet<String> setOfPaths = tagNameToPaths.get(tagName);
if (setOfPaths != null) {
String path = sb.toString();
if (setOfPaths.contains(path)) {
// Search start offset
while (offset > 0) {
if (text.charAt(offset) == '>') {
break;
} else {
offset--;
}
}
handle(path.substring(1), reader.getText(), offset+1);
}
}
break;
}
}
} catch (XMLStreamException e) {
assert ExceptionUtil.printStackTrace(e);
}
}
public abstract void handle(String path, String text, int position);
}