Package org.restlet.ext.rdf.internal.n3

Source Code of org.restlet.ext.rdf.internal.n3.RdfN3Reader

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.ext.rdf.internal.n3;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.restlet.data.Reference;
import org.restlet.ext.rdf.Graph;
import org.restlet.ext.rdf.GraphHandler;
import org.restlet.ext.rdf.Literal;
import org.restlet.ext.rdf.internal.RdfConstants;
import org.restlet.ext.rdf.internal.turtle.BlankNodeToken;
import org.restlet.ext.rdf.internal.turtle.Context;
import org.restlet.ext.rdf.internal.turtle.LexicalUnit;
import org.restlet.ext.rdf.internal.turtle.ListToken;
import org.restlet.ext.rdf.internal.turtle.RdfTurtleReader;
import org.restlet.ext.rdf.internal.turtle.StringToken;
import org.restlet.ext.rdf.internal.turtle.Token;
import org.restlet.ext.rdf.internal.turtle.UriToken;
import org.restlet.representation.Representation;

/**
* Handler of RDF content according to the N3 notation.
*
* @author Thierry Boileau
*/
public class RdfN3Reader extends RdfTurtleReader {

    /**
     * Constructor.
     *
     * @param rdfRepresentation
     *            The representation to read.
     * @param graphHandler
     *            The graph handler invoked during the parsing.
     * @throws IOException
     */
    public RdfN3Reader(Representation rdfN3Representation,
            GraphHandler graphHandler) throws IOException {
        super(rdfN3Representation, graphHandler);
    }

    @Override
    protected void generateLinks(List<LexicalUnit> lexicalUnits) {
        Object currentSubject = null;
        Reference currentPredicate = null;
        Object currentObject = null;
        int nbTokens = 0;
        boolean swapSubjectObject = false;
        // Stores the list of parsed subjects.
        List<Object> subjects = new ArrayList<Object>();

        for (int i = 0; i < lexicalUnits.size(); i++) {
            LexicalUnit lexicalUnit = lexicalUnits.get(i);

            nbTokens++;
            switch (nbTokens) {
            case 1:
                if (",".equals(lexicalUnit.getValue())) {
                    nbTokens++;
                } else if (";".equals(lexicalUnit.getValue())) {
                    if (!subjects.isEmpty()) {
                        currentSubject = subjects.get(subjects.size() - 1);
                    }
                } else {
                    if ("!".equalsIgnoreCase(lexicalUnit.getValue())) {
                        currentObject = new BlankNodeToken(newBlankNodeId())
                                .resolve();
                        currentPredicate = getPredicate(lexicalUnits.get(++i));
                        this.link(currentSubject, currentPredicate,
                                currentObject);
                        currentSubject = currentObject;
                        nbTokens = 1;
                    } else if ("^".equalsIgnoreCase(lexicalUnit.getValue())) {
                        currentObject = currentSubject;
                        currentPredicate = getPredicate(lexicalUnits.get(++i));
                        currentSubject = new BlankNodeToken(newBlankNodeId())
                                .resolve();
                        this.link(currentSubject, currentPredicate,
                                currentObject);
                        nbTokens = 1;
                    } else {
                        currentSubject = lexicalUnit.resolve();
                        subjects.add(currentSubject);
                    }
                }
                break;
            case 2:
                if ("is".equalsIgnoreCase(lexicalUnit.getValue())) {
                    nbTokens--;
                    swapSubjectObject = true;
                } else if ("has".equalsIgnoreCase(lexicalUnit.getValue())) {
                    nbTokens--;
                } else if ("=".equalsIgnoreCase(lexicalUnit.getValue())) {
                    currentPredicate = RdfConstants.PREDICATE_SAME;
                } else if ("=>".equalsIgnoreCase(lexicalUnit.getValue())) {
                    currentPredicate = RdfConstants.PREDICATE_IMPLIES;
                } else if ("<=".equalsIgnoreCase(lexicalUnit.getValue())) {
                    swapSubjectObject = true;
                    currentPredicate = RdfConstants.PREDICATE_IMPLIES;
                } else if ("a".equalsIgnoreCase(lexicalUnit.getValue())) {
                    currentPredicate = RdfConstants.PREDICATE_TYPE;
                } else if ("!".equalsIgnoreCase(lexicalUnit.getValue())) {
                    currentObject = new BlankNodeToken(newBlankNodeId())
                            .resolve();
                    currentPredicate = getPredicate(lexicalUnits.get(++i));
                    this.link(currentSubject, currentPredicate, currentObject);
                    currentSubject = currentObject;
                    nbTokens = 1;
                } else if ("^".equalsIgnoreCase(lexicalUnit.getValue())) {
                    currentObject = currentSubject;
                    currentPredicate = getPredicate(lexicalUnits.get(++i));
                    currentSubject = new BlankNodeToken(newBlankNodeId())
                            .resolve();
                    this.link(currentSubject, currentPredicate, currentObject);
                    nbTokens = 1;
                } else {
                    currentPredicate = getPredicate(lexicalUnit);
                }
                break;
            case 3:
                if ("of".equalsIgnoreCase(lexicalUnit.getValue())) {
                    nbTokens--;
                } else {
                    // take care of the "path" shorthands.
                    int j = i + 1;
                    if (j < lexicalUnits.size() && isPath(lexicalUnits.get(j))) {
                        if ("!"
                                .equalsIgnoreCase(lexicalUnits.get(j)
                                        .getValue())) {
                            // Create a new BlankNode which is the object of the
                            // current link.
                            currentObject = new BlankNodeToken(newBlankNodeId())
                                    .resolve();
                            this.link(currentSubject, currentPredicate,
                                    currentObject);

                            // Interpret the "!" path
                            currentPredicate = getPredicate(lexicalUnits
                                    .get(j + 1));
                            this.link(lexicalUnit.resolve(), currentPredicate,
                                    currentObject);
                            currentSubject = currentObject;
                            nbTokens = 0;
                            i += 2;
                        } else if ("^".equalsIgnoreCase(lexicalUnits.get(j)
                                .getValue())) {
                            // Create a new BlankNode which is the object of the
                            // current link.
                            currentObject = new BlankNodeToken(newBlankNodeId())
                                    .resolve();
                            this.link(currentSubject, currentPredicate,
                                    currentObject);

                            // Interpret the "^" path
                            currentSubject = currentObject;
                            currentPredicate = getPredicate(lexicalUnits
                                    .get(j + 1));
                            currentObject = lexicalUnit.resolve();
                            this.link(currentSubject, currentPredicate,
                                    currentObject);
                            nbTokens = 0;
                            i += 2;
                        }
                    } else {
                        if (swapSubjectObject) {
                            currentObject = currentSubject;
                            currentSubject = lexicalUnit.resolve();
                            this.link(currentSubject, currentPredicate,
                                    currentObject);
                            currentSubject = currentObject;
                        } else {
                            currentObject = lexicalUnit.resolve();
                            this.link(currentSubject, currentPredicate,
                                    currentObject);
                        }
                        nbTokens = 0;
                        swapSubjectObject = false;
                    }
                }
                break;
            default:
                break;
            }
        }
    }

    /**
     * Returns the given lexical unit as a predicate.
     *
     * @param lexicalUnit
     *            The lexical unit to get as a predicate.
     * @return A RDF URI reference of the predicate.
     */
    private Reference getPredicate(LexicalUnit lexicalUnit) {
        Reference result = null;
        Object p = lexicalUnit.resolve();
        if (p instanceof Reference) {
            result = (Reference) p;
        } else if (p instanceof String) {
            result = new Reference((String) p);
        }

        return result;
    }

    @Override
    protected boolean isDelimiter(int c) {
        return isWhiteSpace(c) || c == '^' || c == '!' || c == '=' || c == '<'
                || c == '"' || c == '{' || c == '}' || c == '[' || c == ']'
                || c == '(' || c == ')' || c == '.' || c == ';' || c == ','
                || c == '@';
    }

    /**
     * Returns true if the given lexical unit is a "path" shorthand.
     *
     * @param lexicalUnit
     *            The lexical unit to analyse.
     * @return True if the given lexical unit is a "path" shorthand.
     */
    protected boolean isPath(LexicalUnit lexicalUnit) {
        return "!".equals(lexicalUnit.getValue())
                || "^".equals(lexicalUnit.getValue());
    }

    /**
     * Callback method used when a link is parsed or written.
     *
     * @param source
     *            The source or subject of the link.
     * @param typeRef
     *            The type reference of the link.
     * @param target
     *            The target or object of the link.
     */
    @Override
    protected void link(Object source, Reference typeRef, Object target) {
        if (source instanceof Reference) {
            if (target instanceof Reference) {
                getGraphHandler().link((Reference) source, typeRef,
                        (Reference) target);
            } else if (target instanceof Literal) {
                getGraphHandler().link((Reference) source, typeRef,
                        (Literal) target);
            } else {
                org.restlet.Context
                        .getCurrentLogger()
                        .warning(
                                "The N3 document contains an object which is neither a Reference nor a literal: "
                                        + target);
                org.restlet.Context.getCurrentLogger().warning(
                        getParsingMessage());
            }
        } else if (source instanceof Graph) {
            if (target instanceof Reference) {
                getGraphHandler().link((Graph) source, typeRef,
                        (Reference) target);
            } else if (target instanceof Literal) {
                getGraphHandler().link((Graph) source, typeRef,
                        (Literal) target);
            } else {
                org.restlet.Context
                        .getCurrentLogger()
                        .warning(
                                "The N3 document contains an object which is neither a Reference nor a literal: "
                                        + target);
                org.restlet.Context.getCurrentLogger().warning(
                        getParsingMessage());
            }
        }
    }

    @Override
    protected void parseBlankNode(BlankNodeToken blankNode) throws IOException {
        step();
        do {
            consumeWhiteSpaces();
            switch (getChar()) {
            case '(':
                blankNode.getLexicalUnits().add(
                        new ListToken(this, getContext()));
                break;
            case '<':
                if (step() == '=') {
                    blankNode.getLexicalUnits().add(new Token("<="));
                    step();
                    discard();
                } else {
                    stepBack();
                    blankNode.getLexicalUnits().add(
                            new UriToken(this, getContext()));
                }
                break;
            case '_':
                blankNode.getLexicalUnits().add(
                        new BlankNodeToken(parseToken()));
                break;
            case '"':
                blankNode.getLexicalUnits().add(
                        new StringToken(this, getContext()));
                break;
            case '[':
                blankNode.getLexicalUnits().add(
                        new BlankNodeToken(this, getContext()));
                break;
            case '!':
                blankNode.getLexicalUnits().add(new Token("!"));
                step();
                discard();
                break;
            case '^':
                blankNode.getLexicalUnits().add(new Token("^"));
                step();
                discard();
                break;
            case '=':
                if (step() == '>') {
                    blankNode.getLexicalUnits().add(new Token("=>"));
                    step();
                    discard();
                } else {
                    blankNode.getLexicalUnits().add(new Token("="));
                    discard();
                }
                break;
            case '@':
                // Remove the leading '@' character.
                step();
                discard();
                blankNode.getLexicalUnits().add(new Token(this, getContext()));
                discard();
                break;
            case ';':
                step();
                discard();
                blankNode.getLexicalUnits().add(new Token(";"));
                break;
            case ',':
                step();
                discard();
                blankNode.getLexicalUnits().add(new Token(","));
                break;
            case '#':
                parseComment();
                break;
            case '{':
                blankNode.getLexicalUnits().add(
                        new FormulaToken(this, getContext()));
                break;
            case ']':
                break;
            default:
                if (!isEndOfFile(getChar())) {
                    blankNode.getLexicalUnits().add(
                            new Token(this, getContext()));
                }
                break;
            }
        } while (!isEndOfFile(getChar()) && getChar() != ']');
        if (getChar() == ']') {
            // Set the cursor at the right of the list token.
            step();
        }

    }

    /**
     * Parses the given formula token.
     *
     * @param formulaToken
     *            The formula token to parse.
     * @throws IOException
     */
    protected void parseFormula(FormulaToken formulaToken) throws IOException {
        step();
        do {
            parseStatement(new Context());
        } while (!isEndOfFile(getChar()) && getChar() != '}');
        if (getChar() == '}') {
            // Set the cursor at the right of the formula token.
            step();
        }
    }

    @Override
    protected void parseList(ListToken listToken) throws IOException {
        step();
        do {
            consumeWhiteSpaces();
            switch (getChar()) {
            case '(':
                listToken.getLexicalUnits().add(
                        new ListToken(this, getContext()));
                break;
            case '<':
                if (step() == '=') {
                    listToken.getLexicalUnits().add(new Token("<="));
                    step();
                    discard();
                } else {
                    stepBack();
                    listToken.getLexicalUnits().add(
                            new UriToken(this, getContext()));
                }
                break;
            case '_':
                listToken.getLexicalUnits().add(
                        new BlankNodeToken(this.parseToken()));
                break;
            case '"':
                listToken.getLexicalUnits().add(
                        new StringToken(this, getContext()));
                break;
            case '[':
                listToken.getLexicalUnits().add(
                        new BlankNodeToken(this, getContext()));
                break;
            case '{':
                listToken.getLexicalUnits().add(
                        new FormulaToken(this, getContext()));
                break;
            case ')':
                break;
            default:
                if (!isEndOfFile(getChar())) {
                    listToken.getLexicalUnits().add(
                            new Token(this, getContext()));
                }
                break;
            }
        } while (!isEndOfFile(getChar()) && getChar() != ')');
        if (getChar() == ')') {
            // Set the cursor at the right of the list token.
            step();
        }
    }

    @Override
    protected void parseStatement(Context context) throws IOException {
        List<LexicalUnit> lexicalUnits = new ArrayList<LexicalUnit>();
        do {
            consumeWhiteSpaces();
            switch (getChar()) {
            case '(':
                lexicalUnits.add(new ListToken(this, context));
                break;
            case '<':
                if (step() == '=') {
                    lexicalUnits.add(new Token("<="));
                    step();
                    discard();
                } else {
                    stepBack();
                    lexicalUnits.add(new UriToken(this, context));
                }
                break;
            case '_':
                lexicalUnits.add(new BlankNodeToken(parseToken()));
                break;
            case '"':
                lexicalUnits.add(new StringToken(this, context));
                break;
            case '[':
                lexicalUnits.add(new BlankNodeToken(this, context));
                break;
            case '!':
                lexicalUnits.add(new Token("!"));
                step();
                discard();
                break;
            case '^':
                lexicalUnits.add(new Token("^"));
                step();
                discard();
                break;
            case '=':
                if (step() == '>') {
                    lexicalUnits.add(new Token("=>"));
                    step();
                    discard();
                } else {
                    lexicalUnits.add(new Token("="));
                    discard();
                }
                break;
            case '@':
                // Remove the leading '@' character.
                step();
                discard();
                lexicalUnits.add(new Token(this, context));
                discard();
                break;
            case ';':
                step();
                discard();
                lexicalUnits.add(new Token(";"));
                break;
            case ',':
                step();
                discard();
                lexicalUnits.add(new Token(","));
                break;
            case '{':
                lexicalUnits.add(new FormulaToken(this, context));
                break;
            case '#':
                parseComment();
                break;
            case '.':
                break;
            default:
                if (!isEndOfFile(getChar())) {
                    lexicalUnits.add(new Token(this, context));
                }
                break;
            }
        } while (!isEndOfFile(getChar()) && getChar() != '.'
                && getChar() != '}');

        // Generate the links
        generateLinks(lexicalUnits);
    }

}
TOP

Related Classes of org.restlet.ext.rdf.internal.n3.RdfN3Reader

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.