// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.tagtransform.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.openstreetmap.osmosis.tagtransform.Matcher;
import org.openstreetmap.osmosis.tagtransform.Output;
import org.openstreetmap.osmosis.tagtransform.TTEntityType;
import org.openstreetmap.osmosis.tagtransform.Translation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class TransformLoader {
private static final Logger LOG = Logger.getLogger(TransformLoader.class.getName());
public List<Translation> load(String configFile) {
List<Translation> translations = new ArrayList<Translation>();
File file = new File(configFile);
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
NodeList translationElements = doc.getDocumentElement().getElementsByTagName("translation");
for (int i = 0; i < translationElements.getLength(); i++) {
Translation t = parseTranslation((Element) translationElements.item(i));
if (t != null) {
translations.add(t);
}
}
} catch (Exception e) {
throw new TransformLoadException("Failed to load transform", e);
}
return translations;
}
private Translation parseTranslation(Element element) {
String name = "";
String description = "";
Matcher matcher = null;
Matcher finder = null;
List<Output> output = new ArrayList<Output>();
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
if (!(children.item(i) instanceof Element)) {
continue;
}
Element child = (Element) children.item(i);
String nodeName = child.getNodeName();
if (nodeName.equals("name")) {
name = child.getTextContent();
} else if (nodeName.equals("description")) {
description = child.getTextContent();
} else if (nodeName.equals("match")) {
matcher = parseMatcher(child);
} else if (nodeName.equals("find")) {
finder = parseMatcher(child);
} else if (nodeName.equals("output")) {
NodeList outputs = child.getChildNodes();
for (int j = 0; j < outputs.getLength(); j++) {
if (!(outputs.item(j) instanceof Element)) {
continue;
}
Output o = parseOutput((Element) outputs.item(j));
if (o != null) {
output.add(o);
}
}
}
}
if (matcher != null) {
LOG.info("New translation: " + name);
return new TranslationImpl(name, description, matcher, finder, output);
} else {
return null;
}
}
private Output parseOutput(Element child) {
String name = child.getNodeName();
if (name.equals("copy-all")) {
return new CopyAll();
} else if (name.equals("copy-unmatched")) {
return new CopyUnmatched();
} else if (name.equals("copy-matched")) {
return new CopyMatched();
} else if (name.equals("tag")) {
String k = child.getAttribute("k");
String v = child.getAttribute("v");
String m = child.getAttribute("from_match");
return new TagOutput(k, v, m);
}
return null;
}
private Matcher parseMatcher(Element matcher) {
String name = matcher.getNodeName();
if (name.equals("match") || name.equals("find")) {
NodeList children = matcher.getChildNodes();
List<Matcher> matchers = new ArrayList<Matcher>();
String uname = null;
int uid = 0;
for (int i = 0; i < children.getLength(); i++) {
if (!(children.item(i) instanceof Element)) {
continue;
}
Element child = (Element) children.item(i);
Matcher m = parseMatcher(child);
if (m != null) {
matchers.add(m);
}
}
TTEntityType type = getType(matcher.getAttribute("type"));
if (matcher.getAttribute("user") != "") {
uname = matcher.getAttribute("user");
}
if (matcher.getAttribute("uid") != "") {
uid = Integer.parseInt(matcher.getAttribute("uid"));
}
String mode;
if (name.equals("find")) {
mode = "or";
} else {
mode = matcher.getAttribute("mode");
}
if (mode == null || mode.equals("") || mode.equals("and")) {
return new AndMatcher(matchers, type, uname, uid);
} else if (mode.equals("or")) {
return new OrMatcher(matchers, type, uname, uid);
}
} else if (name.equals("tag")) {
String k = matcher.getAttribute("k");
String v = matcher.getAttribute("v");
String id = matcher.getAttribute("match_id");
return new TagMatcher(id, k, v);
} else if (name.equals("notag")) {
String k = matcher.getAttribute("k");
String v = matcher.getAttribute("v");
return new NoTagMatcher(k, v);
}
return null;
}
private TTEntityType getType(String type) {
if (type == null || type.isEmpty() || type.equals("all")) {
return null;
}
if (type.equals("node")) {
return TTEntityType.NODE;
}
if (type.equals("way")) {
return TTEntityType.WAY;
}
if (type.equals("relation")) {
return TTEntityType.RELATION;
}
if (type.equals("bound")) {
return TTEntityType.BOUND;
}
return null;
}
}