sascha@765: package de.intevation.flys.importer; sascha@765: sascha@765: import org.w3c.dom.Document; sascha@765: import org.w3c.dom.NodeList; sascha@765: import org.w3c.dom.Element; sascha@765: sascha@765: import javax.xml.xpath.XPathConstants; sascha@765: sascha@765: import java.util.Map; sascha@765: import java.util.HashMap; sascha@765: import java.util.List; sascha@765: import java.util.ArrayList; sascha@765: sascha@765: import java.util.regex.Pattern; sascha@765: import java.util.regex.Matcher; sascha@765: sascha@765: import org.apache.log4j.Logger; sascha@765: sascha@765: import de.intevation.artifacts.common.utils.XMLUtils; sascha@765: sascha@765: public class AnnotationClassifier sascha@765: { sascha@765: private static Logger log = Logger.getLogger(Importer.class); sascha@765: sascha@765: public static final String TYPES_XPATH = sascha@766: "/annotation/types/type"; sascha@765: sascha@765: public static final String FILE_PATTERNS_XPATH = sascha@766: "/annotation/patterns/file"; sascha@765: sascha@765: public static final String DESCRIPTION_PATTERNS_XPATH = sascha@766: "/annotation/patterns/line"; sascha@765: sascha@765: sascha@765: public static class Pair { sascha@765: sascha@765: protected Pattern pattern; sascha@765: protected ImportAnnotationType annType; sascha@765: sascha@765: public Pair(Pattern pattern, ImportAnnotationType annType) { sascha@765: this.pattern = pattern; sascha@765: this.annType = annType; sascha@765: } sascha@765: sascha@765: public ImportAnnotationType match(String s) { sascha@765: Matcher m = pattern.matcher(s); sascha@765: return m.matches() ? annType : null; sascha@765: } sascha@765: } // class Pair sascha@765: sascha@765: sascha@765: protected Map types; sascha@765: protected List filePatterns; sascha@765: protected List descPatterns; sascha@765: sascha@765: protected ImportAnnotationType defaultType; sascha@765: sascha@765: public AnnotationClassifier() { sascha@765: } sascha@765: sascha@765: public AnnotationClassifier(Document rules) { sascha@765: types = new HashMap(); sascha@765: filePatterns = new ArrayList(); sascha@765: descPatterns = new ArrayList(); sascha@765: sascha@765: buildRules(rules); sascha@765: } sascha@765: sascha@765: protected void buildRules(Document rules) { sascha@765: buildTypes(rules); sascha@765: buildFilePatterns(rules); sascha@765: buildDescriptionPatterns(rules); sascha@765: } sascha@765: sascha@765: protected void buildTypes(Document rules) { sascha@765: sascha@765: NodeList typeList = (NodeList)XMLUtils.xpath( sascha@765: rules, sascha@765: TYPES_XPATH, sascha@765: XPathConstants.NODESET, sascha@765: null); sascha@765: sascha@765: if (typeList == null) { sascha@765: log.info("no rules found."); sascha@765: return; sascha@765: } sascha@765: sascha@765: for (int i = 0, N = typeList.getLength(); i < N; ++i) { sascha@765: Element typeElement = (Element)typeList.item(i); sascha@765: String name = typeElement.getAttribute("name"); sascha@765: if (name.length() == 0) { sascha@765: log.warn("rule has no name"); sascha@765: continue; sascha@765: } sascha@765: sascha@765: ImportAnnotationType aic = new ImportAnnotationType(name); sascha@765: sascha@765: types.put(name, aic); sascha@765: sascha@765: if (typeElement.getAttribute("default").equals("true")) { sascha@765: defaultType = aic; sascha@765: } sascha@765: } sascha@765: } sascha@765: sascha@765: protected void buildFilePatterns(Document rules) { sascha@765: sascha@765: NodeList patternList = (NodeList)XMLUtils.xpath( sascha@765: rules, sascha@765: FILE_PATTERNS_XPATH, sascha@765: XPathConstants.NODESET, sascha@765: null); sascha@765: sascha@765: if (patternList == null) { sascha@765: log.info("no file patterns found."); sascha@765: return; sascha@765: } sascha@765: sascha@765: for (int i = 0, N = patternList.getLength(); i < N; ++i) { sascha@765: Element element = (Element)patternList.item(i); sascha@765: Pair pair = buildPair(element); sascha@765: if (pair != null) { sascha@765: filePatterns.add(pair); sascha@765: } sascha@771: } sascha@765: } sascha@765: sascha@765: protected void buildDescriptionPatterns(Document rules) { sascha@765: sascha@765: NodeList patternList = (NodeList)XMLUtils.xpath( sascha@765: rules, sascha@765: DESCRIPTION_PATTERNS_XPATH, sascha@765: XPathConstants.NODESET, sascha@765: null); sascha@765: sascha@765: if (patternList == null) { sascha@765: log.info("no line patterns found."); sascha@765: return; sascha@765: } sascha@765: sascha@765: for (int i = 0, N = patternList.getLength(); i < N; ++i) { sascha@765: Element element = (Element)patternList.item(i); sascha@765: Pair pair = buildPair(element); sascha@765: if (pair != null) { sascha@765: descPatterns.add(pair); sascha@765: } sascha@771: } sascha@765: } sascha@765: sascha@765: protected Pair buildPair(Element element) { sascha@765: String pattern = element.getAttribute("pattern"); sascha@765: String type = element.getAttribute("type"); sascha@765: sascha@765: if (pattern.length() == 0) { sascha@765: log.warn("pattern has no 'pattern' attribute."); sascha@765: return null; sascha@765: } sascha@765: sascha@765: if (type.length() == 0) { sascha@765: log.warn("pattern has no 'type' attribute."); sascha@765: return null; sascha@765: } sascha@765: sascha@765: ImportAnnotationType annType = types.get(type); sascha@765: sascha@765: if (annType == null) { sascha@765: log.warn("pattern has unknown type '" + type + "'"); sascha@765: return null; sascha@765: } sascha@765: sascha@765: Pattern p; sascha@765: sascha@765: try { sascha@765: p = Pattern.compile(pattern, sascha@765: Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE); sascha@765: } sascha@765: catch (IllegalArgumentException iae) { sascha@765: log.warn("pattern '" + pattern + "' is invalid.", iae); sascha@765: return null; sascha@765: } sascha@765: sascha@765: return new Pair(p, annType); sascha@765: } sascha@765: sascha@765: public ImportAnnotationType getDefaultType() { sascha@765: return defaultType; sascha@765: } sascha@765: sascha@765: public ImportAnnotationType classifyFile(String filename) { sascha@765: return classifyFile(filename, null); sascha@765: } sascha@765: sascha@765: public ImportAnnotationType classifyFile( sascha@765: String filename, sascha@765: ImportAnnotationType def sascha@765: ) { sascha@765: if (filename.toLowerCase().endsWith(".km")) { sascha@765: filename = filename.substring(0, filename.length()-3); sascha@765: } sascha@765: sascha@765: for (Pair pair: filePatterns) { sascha@765: ImportAnnotationType annType = pair.match(filename); sascha@765: if (annType != null) { sascha@765: return annType; sascha@765: } sascha@765: } sascha@765: sascha@765: return def; sascha@765: } sascha@765: sascha@765: public ImportAnnotationType classifyDescription(String description) { sascha@765: return classifyDescription(description, null); sascha@765: } sascha@765: sascha@765: public ImportAnnotationType classifyDescription( sascha@765: String description, sascha@765: ImportAnnotationType def sascha@765: ) { sascha@765: for (Pair pair: descPatterns) { sascha@765: ImportAnnotationType annType = pair.match(description); sascha@765: if (annType != null) { sascha@765: return annType; sascha@765: } sascha@765: } sascha@765: sascha@765: return def; sascha@765: } sascha@765: } sascha@765: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :