Package org.apache.marmotta.ldclient.provider.mediawiki

Source Code of org.apache.marmotta.ldclient.provider.mediawiki.MediawikiProvider

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.marmotta.ldclient.provider.mediawiki;

import org.apache.marmotta.commons.sesame.model.Namespaces;
import org.apache.marmotta.ldclient.api.endpoint.Endpoint;
import org.apache.marmotta.ldclient.exception.DataRetrievalException;
import org.apache.marmotta.ldclient.services.provider.AbstractHttpProvider;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.ElementFilter;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
import org.jdom2.xpath.XPathFactory;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* MediawikiProvider allows direct triplification of Mediawiki Articles and Categories.
* <p/>
* For real flexible Endpoint/Provider configuration see
* {@link #buildEndpointUrl(String, Endpoint)}
*
* @see <a href="http://www.mediawiki.org/wiki/API:Main_page">Mediawiki API</a>
* @see #buildEndpointUrl(String, Endpoint)
* @author Jakob Frank <jakob.frank@salzburgresearch.at>
*
*/
public class MediawikiProvider extends AbstractHttpProvider {

    public static final String   PROVIDER_NAME        = "MediaWiki Provider";
    private static Logger        log                  = LoggerFactory.getLogger(MediawikiProvider.class);

    private static final Pattern COLON_PREFIX_PATTERN = Pattern.compile("^[^:]*:");
    private static final Pattern REDIRECT_PATTERN     = Pattern.compile("^#REDIRECT\\s+\\[\\[([^#\\]]*)(#.*)?\\]\\]",
            Pattern.CASE_INSENSITIVE);
    private static final int     MAX_TITLES_PER_QUERY = 50;


    private static enum Context {
        META, META_CONTINUED, CONTENT, LINKS, CATEGORIES, SUBCATEGORIES, SUPERCATEGORIES, PAGES, REDIRECT,
        CATEGORYMEMBERS_PAGES, CATEGORYMEMBERS_SUBCATS, SITE, NO_CONTEXT;
        private static final String paramName = "context";

        public static Context fromUrl(String url) {
            try {
                for (String param : url.split("[?&]")) {
                    if (param.startsWith(paramName + "=")) return valueOf(param.substring(paramName.length() + 1));
                }
            } catch (Exception w) {
            }
            return NO_CONTEXT;
        }

        public String urlParam() {
            return paramName + "=" + this.toString();
        }
    }

    @Override
    public String getName() {
        return PROVIDER_NAME;
    }

    @Override
    public String[] listMimeTypes() {
        return new String[] { "text/xml" };
    }

    @Override
    public List<String> buildRequestUrl(String resource, Endpoint endpoint) throws DataRetrievalException {

        String _t = parseParams(resource).get("title");
        if (_t == null) {
            final String u = resource.replaceAll("\\?.*", "");
            _t = u.substring(u.lastIndexOf('/') + 1);
        }
        final String pageTitle = _t;
        final String apiUrl = buildEndpointUrl(resource, endpoint);
        if (pageTitle != null && !pageTitle.equals("")) {
            final HashMap<String, String> params = new LinkedHashMap<String, String>();

            params.putAll(getDefaultParams("info", null));
            params.putAll(getDefaultParams("revisions", null));
            params.putAll(getDefaultParams("categories", null));
            params.putAll(getDefaultParams("links", null));

            final String metaUrl = buildApiPropQueryUrl(apiUrl, pageTitle, "info|revisions|categories|links", params,
                    Context.META);

            params.clear();
            params.putAll(getDefaultParams("info", null));
            params.putAll(getDefaultParams("revisions", null));

            params.put("rvdir", "older");
            params.put("rvprop", "ids|timestamp|content");
            params.put("inprop", "url|preload");
            final String contentUrl = buildApiPropQueryUrl(apiUrl, pageTitle, "info|revisions", params, Context.CONTENT);

            final List<String> urls = Arrays.asList(metaUrl, contentUrl);
            if (log.isTraceEnabled()) {
                log.trace("CACHE {}", resource);
                for (String u : urls) {
                    log.trace("RESOLVE {}", urlDecode(u).replaceFirst(".*=xml&", ""));
                }
            }
            return urls;
        } else {
            // This seems like the Wiki
            Map<String, String> params = new LinkedHashMap<String, String>();
            params.put("action", "query");
            params.put("meta", "siteinfo");
            params.put("siprop", "general");

            final String siteUrl = buildApiRequestUrl(apiUrl, params, Context.SITE);
            if (log.isTraceEnabled()) {
                log.trace("CACHE {}", resource);
                log.trace("RESOLVE {}", siteUrl);
            }
            return Collections.singletonList(siteUrl);
        }
    }

    /**
     * Build the endpoint url based on
     * <ol>
     * <li>the URI of the resource
     * <li>the {@link Endpoint#getUriPattern()}
     * <li>the {@link Endpoint#getEndpointUrl()}
     * </ol>
     * <p/>
     * Iff the uriPattern <em>entirely</em> (not only a prefix) matches the resourceUri, the apiUrl
     * is build as <code>apiURL = resourceUri.replaceAll(uriPattern, endpointUrl)</code>; else it's
     * just <code>endpointUrl</code>
     *
     *
     * @param resource the resource to retrieve
     * @param endpoint the endpoint to use
     * @return the url to the Mediawiki API for this resouces
     */
    protected String buildEndpointUrl(String resource, Endpoint endpoint) {
        final Pattern pattern = endpoint.getUriPatternCompiled();
        if (pattern != null) {
            final Matcher matcher = pattern.matcher(resource);
            if (matcher.matches()) return matcher.replaceFirst(endpoint.getEndpointUrl());
        }
        return endpoint.getEndpointUrl();
    }

    @Override
    public List<String> parseResponse(String resource, String requestUrl, Repository repository, InputStream in, String contentType)
            throws DataRetrievalException {
        try {
            log.trace("PARSE {}", urlDecode(requestUrl).replaceFirst(".*=xml&", ""));

            parseParams(requestUrl);
            final Context context = Context.fromUrl(requestUrl);
            final Document doc = new SAXBuilder(XMLReaders.NONVALIDATING).build(in);

            ArrayList<String> followUp = new ArrayList<String>();
            final RepositoryConnection con = repository.getConnection();
            final ValueFactory valueFactory = con.getValueFactory();

            switch (context) {
                case SITE:
                    followUp.addAll(parseSiteMeta(resource, requestUrl, doc, repository));
                    break;
                case META:
                case META_CONTINUED:
                    // For Articles: Retrieve article info (sioc:WikiArticle)
                    // Follow-Up: resolve titles: links, categories
                    // For Categories: Retrieve as skos:Concept/sioc:Category
                    followUp.addAll(parseArticleMeta(resource, requestUrl, doc, context, repository));
                    break;
                case CONTENT:
                    followUp.addAll(parseRevision(valueFactory.createURI(resource), requestUrl, con, valueFactory, queryElement(doc, "/api/query/pages/page[1]/revisions"),
                            context));
                    break;
                /* Links from an Article */
                case REDIRECT:
                case LINKS:
                case CATEGORIES:
                /* Links from a Category */
                case SUPERCATEGORIES:
                case SUBCATEGORIES:
                case PAGES:
                    followUp.addAll(addLinks(resource, requestUrl, doc, context, repository));
                    break;
                default:
                    log.error("Unhandled MediawikiProvider.Context: {}", context);
                    break;
            }

            if (log.isTraceEnabled()) {
                for (String f : followUp) {
                    log.trace("FOLLOW {}", urlDecode(f).replaceFirst(".*=xml&", ""));
                }
            }
            return followUp;

            // throw new DataRetrievalException("Invalid response from Mediawiki-API.");
        } catch (RepositoryException e) {
            throw new DataRetrievalException("repository error while parsing XML response", e);
        } catch (IOException e) {
            throw new DataRetrievalException("I/O error while parsing HTML response", e);
        } catch (JDOMException e) {
            throw new DataRetrievalException("could not parse XML response. It is not in proper XML format", e);
        }
    }

    protected List<String> parseSiteMeta(String resource, String requestUrl, Document doc, Repository repository) throws RepositoryException {
        final Element general = queryElement(doc, "/api/query/general");
        if (general != null) {
            final String title = general.getAttributeValue("sitename");
            final String server = general.getAttributeValue("server");
            final String homepage = general.getAttributeValue("base");

            final RepositoryConnection con = repository.getConnection();
            final ValueFactory valueFactory = con.getValueFactory();
            final Resource subject = valueFactory.createURI(resource);

            if (title != null) {
                addLiteralTriple(subject, Namespaces.NS_DC_TERMS + "title", title, null, con, valueFactory);
            }
            if (server != null) {
                if (server.matches("^https?://")) {
                    addTriple(subject, Namespaces.NS_SIOC + "has_host", server, con, valueFactory);
                } else if (server.startsWith("//")) {
                    addTriple(subject, Namespaces.NS_SIOC + "has_host", "http:" + server, con, valueFactory);
                } else {
                    log.warn("Found invalid host {} for wiki {}, ignoring", server, resource);
                }
            }
            if (homepage != null) {
                addTriple(subject, Namespaces.NS_FOAF + "homepage", homepage, con, valueFactory);
            }
            addTypeTriple(subject, Namespaces.NS_SIOC_TYPES + "Wiki", con, valueFactory);
        }

        return Collections.emptyList();
    }

    protected List<String> addLinks(String resource, String requestUrl, Document doc, Context context, Repository repository)
            throws RepositoryException {
        final String predicate;
        switch (context) {
            case LINKS:
                predicate = Namespaces.NS_SIOC + "links_to";
                break;
            case CATEGORIES:
                predicate = Namespaces.NS_SIOC + "topic";
                break;
            case REDIRECT:
                predicate = Namespaces.NS_DC_TERMS + "isReplacedBy";
                break;
            case SUBCATEGORIES:
                predicate = Namespaces.NS_SKOS + "narrower";
                break;
            case SUPERCATEGORIES:
                predicate = Namespaces.NS_SKOS + "broader";
                break;
            case PAGES:
                predicate = Namespaces.NS_SIOC + "topic"; /* INVERSE !!! */
                break;
            default:
                return Collections.emptyList();
        }

        final RepositoryConnection con = repository.getConnection();
        final ValueFactory valueFactory = con.getValueFactory();
        final Resource subject = valueFactory.createURI(resource);

        for (Element page : queryElements(doc, "/api/query/pages/page")) {
            if (page.getAttributeValue("missing") != null) {
                continue;
            }

            final String url = page.getAttributeValue("fullurl");
            if (url != null) {
                if (context == Context.PAGES) {
                    addTriple(valueFactory.createURI(url), predicate, resource, con, valueFactory);
                } else {
                    addTriple(subject, predicate, url, con, valueFactory);
                }
            }
        }
        return Collections.emptyList();
    }

    protected List<String> parseArticleMeta(String resource, String requestUrl, Document doc, Context context,
                                            Repository repository) throws RepositoryException {
        ArrayList<String> followUp = new ArrayList<String>();

        Element page = queryElement(doc, "/api/query/pages/page[1]");
        if (page != null) {
            if (page.getAttributeValue("missing") != null) return Collections.emptyList();

            final RepositoryConnection con = repository.getConnection();
            final ValueFactory valueFactory = con.getValueFactory();
            final URI subject = valueFactory.createURI(resource);

            final String title = page.getAttributeValue("title");
            final String pageId = page.getAttributeValue("pageid");
            final String namespace = page.getAttributeValue("ns");
            final String ident = namespace + ":" + pageId;

            final String wiki = page.getAttributeValue("fullurl");
            if (wiki != null) {
                String wikiUrl = wiki.replaceFirst("(?i:" + Pattern.quote(title.replaceAll(" ", "_")) + ")$", "");
                addTriple(subject, Namespaces.NS_SIOC + "has_container", wikiUrl, con, valueFactory);
            }

            if (context == Context.META) {
                if ("0".equals(namespace)) {
                    addTypeTriple(subject, Namespaces.NS_SIOC_TYPES + "WikiArticle", con, valueFactory);
                    addLiteralTriple(subject, Namespaces.NS_DC_TERMS + "title", title, null, con, valueFactory);
                } else if ("14".equals(namespace)) {
                    // Category is a subType of skoc:Concept
                    addTypeTriple(subject, Namespaces.NS_SIOC_TYPES + "Category", con, valueFactory);
                    Matcher m = COLON_PREFIX_PATTERN.matcher(title);
                    if (m.find()) {
                        addLiteralTriple(subject, Namespaces.NS_SKOS + "prefLabel", m.replaceFirst(""), null, con,
                                valueFactory);
                        addLiteralTriple(subject, Namespaces.NS_SKOS + "altLabel", title, null, con,
                                valueFactory);
                    } else {
                        addLiteralTriple(subject, Namespaces.NS_SKOS + "prefLabel", title, null, con,
                                valueFactory);
                    }

                    // In a category, we also want sub-categories and contained pages
                    final Map<String, String> cmParams = getDefaultParams("categorymembers", null);
                    cmParams.put("cmtitle", title);
                    followUp.add(buildApiListQueryUrl(requestUrl, "categorymembers", cmParams, Context.META));
                }

                addLiteralTriple(subject, Namespaces.NS_DC_TERMS + "identifier", ident, Namespaces.NS_XSD + "string", con, valueFactory);
                addLiteralTriple(subject, Namespaces.NS_DC_TERMS + "modified", page.getAttributeValue("touched"), Namespaces.NS_XSD
                        + "dateTime", con, valueFactory);
                followUp.addAll(parseRevision(subject, requestUrl, con, valueFactory, page.getChild("revisions"), Context.META));
                if (page.getAttributeValue("fullurl") != null && !resource.equals(page.getAttributeValue("fullurl"))) {
                    addTriple(subject, Namespaces.NS_OWL + "sameAs", page.getAttributeValue("fullurl"), con, valueFactory);
                }
            }

            List<Element> pagings = queryElements(doc, "/api/query-continue/*");
            for (int i = 0; i < pagings.size(); i++) {
                Element e = pagings.get(i);
                if (!"revisions".equals(e.getName())) {
                    followUp.add(buildApiPropQueryUrl(requestUrl, title, e.getName(), getDefaultParams(e.getName(), e),
                            Context.META_CONTINUED));
                }
            }

            // Parse categories of this article, and resolve them in a followUp request
            final Element cats = page.getChild("categories");
            if (cats != null) {
                final List<Element> cls = cats.getChildren("cl");
                if (cls.size() > 0) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < cls.size(); i++) {
                        sb.append(cls.get(i).getAttributeValue("title")).append("|");
                        if ((i + 1) % MAX_TITLES_PER_QUERY == 0) {
                            final String titles = sb.substring(0, sb.length() - 1);
                            if ("0".equals(namespace)) {
                                followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.CATEGORIES));
                            } else if ("14".equals(namespace)) {
                                followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.SUPERCATEGORIES));
                            }
                            sb = new StringBuilder();
                        }
                    }
                    if (sb.length() > 0) {
                        final String titles = sb.substring(0, sb.length() - 1);
                        if ("0".equals(namespace)) {
                            followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.CATEGORIES));
                        } else if ("14".equals(namespace)) {
                            followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.SUPERCATEGORIES));
                        }
                    }
                }
            }

            // Parse (page)links of this article, and resolve them in a followUp request
            final Element links = page.getChild("links");
            if (links != null) {
                final List<Element> pls = links.getChildren("pl");
                if (pls.size() > 0) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < pls.size(); i++) {
                        sb.append(pls.get(i).getAttributeValue("title")).append("|");
                        if ((i + 1) % MAX_TITLES_PER_QUERY == 0) {
                            final String titles = sb.substring(0, sb.length() - 1);
                            followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.LINKS));
                            sb = new StringBuilder();
                        }
                    }
                    if (sb.length() > 0) {
                        final String titles = sb.substring(0, sb.length() - 1);
                        followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.LINKS));
                    }
                }
            }

        }
        Element catmembers = queryElement(doc, "/api/query/categorymembers");
        if (catmembers != null) {
            final List<Element> cms = catmembers.getChildren("cm");
            if (cms.size() > 0) {
                StringBuilder pt = new StringBuilder(), ct = new StringBuilder();
                int ptC = 0, ctC = 0;
                for (int i = 0; i < cms.size(); i++) {
                    final Element cm = cms.get(i);
                    final String type = cm.getAttributeValue("type");
                    final String title = cm.getAttributeValue("title");
                    if ("page".equals(type)) {
                        pt.append(title).append("|");
                        ptC++;
                    } else if ("subcat".equals(type)) {
                        ct.append(title).append("|");
                        ctC++;
                    } else if (type == null) {
                        // attribute type is available from Mediawiki 1.18+, use this as fallback.
                        final String ns = cm.getAttributeValue("ns");
                        if ("0".equals(ns)) {
                            pt.append(title).append("|");
                            ptC++;
                        } else if ("14".equals(ns)) {
                            ct.append(title).append("|");
                            ctC++;
                        }
                    }
                    if (ptC > MAX_TITLES_PER_QUERY) {
                        final String titles = pt.substring(0, pt.length() - 1);
                        followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.PAGES));
                        ptC = 0;
                        pt = new StringBuilder();
                    }
                    if (ctC > MAX_TITLES_PER_QUERY) {
                        final String titles = ct.substring(0, ct.length() - 1);
                        followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.SUBCATEGORIES));
                        ctC = 0;
                        ct = new StringBuilder();
                    }
                }
                if (ptC > 50) {
                    final String titles = pt.substring(0, pt.length() - 1);
                    followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.PAGES));
                }
                if (ctC > 50) {
                    final String titles = ct.substring(0, ct.length() - 1);
                    followUp.add(buildApiPropQueryUrl(requestUrl, titles, "info", getDefaultParams("info", null), Context.SUBCATEGORIES));
                }

            }
            Element cmContinue = queryElement(doc, "/api/query-continue/categorymembers");
            if (cmContinue != null) {
                final Map<String, String> cmParams = getDefaultParams(cmContinue.getName(), cmContinue);
                cmParams.put("cmtitle", parseParams(requestUrl).get("cmtitle"));
                followUp.add(buildApiListQueryUrl(requestUrl, cmContinue.getName(), cmParams, Context.META_CONTINUED));
            }
        }
        return followUp;
    }

    protected List<String> parseRevision(URI resource, String requestUrl, RepositoryConnection con, ValueFactory valueFactory,
                                         Element revisions, Context context) throws RepositoryException {
        List<String> followUp = Collections.emptyList();
        if (revisions == null) return followUp;
        final Element rev = revisions.getChild("rev");
        if (rev == null) return followUp;
        final Resource subject = resource;

        if (context == Context.META && "0".equals(rev.getAttributeValue("parentid"))) {
            // This is the first revision, so we use the creation date
            addLiteralTriple(subject, Namespaces.NS_DC_TERMS + "created", rev.getAttributeValue("timestamp"), Namespaces.NS_XSD + "dateTime", con,
                    valueFactory);
        }
        if (context == Context.CONTENT && rev.getValue() != null && rev.getValue().trim().length() > 0) {
            final String content = rev.getValue().trim();
            final Matcher m = REDIRECT_PATTERN.matcher(content);
            if (((Element) revisions.getParent()).getAttribute("redirect") != null && m.find()) {
                followUp = Collections.singletonList(buildApiPropQueryUrl(requestUrl, m.group(1), "info", getDefaultParams("info", null),
                        Context.REDIRECT));
            } else {
                addLiteralTriple(subject, Namespaces.NS_RSS_CONTENT + "encoded", content, Namespaces.NS_XSD + "string", con, valueFactory);
            }
        }
        return followUp;
    }

    private String buildApiListQueryUrl(String url, String list, Map<String, String> extraArgs, Context context) {
        HashMap<String, String> params = new LinkedHashMap<String, String>();
        params.put("action", "query");
        params.put("list", list);

        params.putAll(extraArgs);

        return buildApiRequestUrl(url, params, context);
    }

    private String buildApiPropQueryUrl(String url, String titleQuery, String prop, Map<String, String> extraArgs, Context context) {
        HashMap<String, String> params = new LinkedHashMap<String, String>();
        params.put("action", "query");
        params.put("titles", titleQuery);
        params.put("prop", prop);

        params.putAll(extraArgs);

        return buildApiRequestUrl(url, params, context);
    }

    private String buildApiRequestUrl(String url, Map<String, String> params, Context context) {
        StringBuilder sb = new StringBuilder(url.replaceAll("\\?.*", ""));
        sb.append("?format=xml");

        for (String param : params.keySet()) {
            sb.append("&").append(urlEncode(param));
            sb.append("=").append(urlEncode(params.get(param)));
        }
        if (context != null && context != Context.NO_CONTEXT) {
            sb.append("&").append(context.urlParam());
        }

        return sb.toString();
    }

    private Map<String, String> getDefaultParams(String prop, Element queryContinue) {
        HashMap<String, String> params = new LinkedHashMap<String, String>();
        final String limit = "max";

        if ("info".equals(prop)) {
            params.put("inprop", "url");
        } else if ("revisions".equals(prop)) {
            // Revision info: first revision for creation
            params.put("rvdir", "newer");
            params.put("rvlimit", "1");
            params.put("rvprop", "ids|timestamp");
        } else if ("categories".equals(prop)) {
            params.put("cllimit", limit);
            // Categories: only visible cats
            params.put("clshow", "!hidden");
        } else if ("links".equals(prop)) {
            params.put("pllimit", limit);
            // Links: only links to same
            params.put("plnamespace", "0");
        } else if ("categorymembers".equals(prop)) {
            params.put("cmlimit", limit);
            params.put("cmprop", "title|type");
        }

        if (queryContinue != null && queryContinue.getName().equals(prop) && queryContinue.getAttributes().size() == 1) {
            final Attribute a = queryContinue.getAttributes().get(0);
            params.put(a.getName(), a.getValue());
        }

        return params;
    }

    private String urlEncode(String string) {
        try {
            return URLEncoder.encode(string, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return string;
        }
    }

    private String urlDecode(String string) {
        try {
            return URLDecoder.decode(string, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return string;
        }
    }

    protected Map<String, String> parseParams(String requestUrl) {
        if (requestUrl.indexOf('?') < 0) return Collections.emptyMap();
        final String queryString = requestUrl.substring(requestUrl.indexOf('?') + 1);
        HashMap<String, String> params = new LinkedHashMap<String, String>();
        for (String param : queryString.split("&")) {
            final String kv[] = param.split("=");
            if (kv.length == 2) {
                params.put(urlDecode(kv[0]), urlDecode(kv[1]));
            } else if (kv.length == 1) {
                params.put(urlDecode(kv[0]), Boolean.TRUE.toString());
            }
        }
        return params;

    }

    private void addTriple(Resource subject, String predicate, String object, RepositoryConnection con, ValueFactory valueFactory)
            throws RepositoryException {
        if (predicate == null || object == null) return;
        final URI predUri = valueFactory.createURI(predicate);
        final URI objUri = valueFactory.createURI(object);

        Statement stmt = valueFactory.createStatement(subject, predUri, objUri);
        con.add(stmt);

    }

    private void addLiteralTriple(Resource subject, String predicate, String label, String datatype, RepositoryConnection con,
                                  ValueFactory valueFactory) throws RepositoryException {
        if (predicate == null || label == null) return;
        final URI predUri = valueFactory.createURI(predicate);

        final Literal lit;
        if (datatype != null) {
            final URI dType = valueFactory.createURI(datatype);
            lit = valueFactory.createLiteral(label, dType);
        } else {
            lit = valueFactory.createLiteral(label);
        }

        Statement stmt = valueFactory.createStatement(subject, predUri, lit);
        con.add(stmt);

    }

    private void addTypeTriple(Resource subject, String type, RepositoryConnection con, ValueFactory valueFactory) throws RepositoryException {
        if (type == null) return;
        final URI predUri = valueFactory.createURI(Namespaces.NS_RDF + "type");
        final URI rdfType = valueFactory.createURI(type);

        Statement stmt = valueFactory.createStatement(subject, predUri, rdfType);
        con.add(stmt);

    }

    protected Element queryElement(Document n, String query) {
        return XPathFactory.instance().compile(query, new ElementFilter()).evaluateFirst(n);
    }
    protected Element queryElement(Element n, String query) {
        return XPathFactory.instance().compile(query, new ElementFilter()).evaluateFirst(n);
    }

    protected List<Element> queryElements(Document n, String query) {
        return XPathFactory.instance().compile(query, new ElementFilter()).evaluate(n);
    }

    protected List<Element> queryElements(Element n, String query) {
        return XPathFactory.instance().compile(query, new ElementFilter()).evaluate(n);
    }

}
TOP

Related Classes of org.apache.marmotta.ldclient.provider.mediawiki.MediawikiProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.