001/**
002 * Copyright (C) 2007-2011, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 * 
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 *
019 */
020package org.dllearner.confparser;
021
022import org.apache.jena.vocabulary.OWL;
023import org.apache.jena.vocabulary.RDF;
024import org.apache.jena.vocabulary.RDFS;
025import joptsimple.internal.Strings;
026import org.apache.commons.collections15.CollectionUtils;
027import org.dllearner.cli.ConfFileOption;
028
029import java.util.*;
030import java.util.regex.Matcher;
031import java.util.regex.Pattern;
032
033/**
034 * Performs post processing of conf files based on special parsing directives.
035 * 
036 * @author Jens Lehmann
037 *
038 */
039public class PostProcessor {
040
041        List<ConfFileOption> confOptions;
042        Map<String, ConfFileOption> directives;
043        
044        // a set of properties which contain URIs
045//      static final Set<String> uriProperties = Sets.newHashSet(
046//                      "positiveExamples", 
047//                      "negativeExamples", 
048//                      "startClass", 
049//                      "classToDescribe",
050//                      "entityToDescribe",
051//                      "propertyToDescribe"
052//                      );
053
054        public PostProcessor(List<ConfFileOption> confOptions, Map<String, ConfFileOption> directives) {
055                this.confOptions = confOptions;
056                this.directives = directives;
057        }
058        
059        private static String replaceAllMap (String pre, Map<String,String> repMap, String post, String in) {
060                List<String> keys = new ArrayList<>(repMap.keySet());
061                Collections.sort(keys, (o1, o2) -> o1.length() - o2.length());
062                CollectionUtils.transform(keys, input -> Pattern.quote(input));
063                Matcher m = Pattern.compile(pre + "(" + Strings.join(keys, "|") + ")" + post).matcher(in);
064                m.reset();
065                if (m.find()) {
066                        StringBuffer sb = new StringBuffer();
067                        do {
068                                m.appendReplacement(sb, repMap.get(m.group(1)));
069                        } while (m.find());
070                        return m.appendTail(sb).toString();
071                }
072                return in;
073                }
074        
075        /**
076         * Applies all special directives by modifying the conf options.
077         */
078        public void applyAll() {
079                //apply base URI directive
080                
081                
082                // apply prefix directive
083                ConfFileOption prefixOption = directives.get("prefixes");
084                Map<String,String> prefixes = new TreeMap<>();
085                
086                prefixes.put("owl", OWL.NS);
087                prefixes.put("rdfs", RDFS.getURI());
088                prefixes.put("rdf", RDF.getURI());
089                
090                if(prefixOption != null) {
091                        prefixes.putAll((Map<String,String>) prefixOption.getValueObject());
092                }
093                         
094                // loop through all options and replaces prefixes
095                for(ConfFileOption option : confOptions) {
096                        Object valueObject = option.getValue();
097//                      if(uriProperties.contains(option.getPropertyName())){
098//                              System.out.println(option);
099//                      }
100                        
101
102                        if(valueObject instanceof String){
103                                valueObject = replaceAllMap("", prefixes, ":", (String) valueObject);
104                        } else if(valueObject instanceof Map) {
105                                valueObject = processStringMap(prefixes, (Map)valueObject);
106                        } else if(valueObject instanceof Collection){
107                                processStringCollection(prefixes, (Collection<?>) valueObject);
108                        } else if(valueObject instanceof Boolean || valueObject instanceof Integer || valueObject instanceof Double || valueObject instanceof Long) {
109                                // nothing needs to be done for booleans
110                        } else {
111                                throw new Error("Unknown conf option type " + valueObject.getClass());
112                        }
113
114                        option.setValueObject(valueObject);
115                }
116    }
117
118    private Map processStringMap(Map<String, String> prefixes, Map inputMap) {
119
120        Map newMap = new HashMap();
121
122        /** This does the values */
123        for (Object keyObject : inputMap.keySet()) {
124            Object key = keyObject;
125            Object value = inputMap.get(key);
126
127            if (keyObject instanceof String) {
128                // replace prefixes in the key
129                key = replaceAllMap("", prefixes, ":", (String) keyObject);
130                // if the value is a string, we also replace prefixes there
131                if (value instanceof String) {
132                        value = replaceAllMap("", prefixes, ":", (String) value);
133                }
134            }
135            newMap.put(key, value);
136        }
137
138       return newMap;
139
140    }
141
142    @SuppressWarnings("unchecked")
143        private void processStringCollection(final Map<String, String> prefixes, Collection valueObject) {
144        CollectionUtils.transform(valueObject, input -> {
145                if (input instanceof String) {
146                        return replaceAllMap("", prefixes, ":", (String) input);
147                }
148                return input;
149        });
150    }
151}