Package org.openrdf.query.parser.sparql

Source Code of org.openrdf.query.parser.sparql.BlankNodeVarProcessor$BlankNodeToVarConverter

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.query.parser.sparql;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.parser.sparql.ast.ASTBasicGraphPattern;
import org.openrdf.query.parser.sparql.ast.ASTBlankNode;
import org.openrdf.query.parser.sparql.ast.ASTBlankNodePropertyList;
import org.openrdf.query.parser.sparql.ast.ASTCollection;
import org.openrdf.query.parser.sparql.ast.ASTQueryContainer;
import org.openrdf.query.parser.sparql.ast.ASTVar;
import org.openrdf.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants;
import org.openrdf.query.parser.sparql.ast.VisitorException;

/**
* Processes blank nodes in the query body, replacing them with variables while
* retaining scope.
*
* @author Arjohn Kampman
*/
class BlankNodeVarProcessor extends ASTVisitorBase {

  public static void process(ASTQueryContainer qc)
    throws MalformedQueryException
  {
    try {
      qc.jjtAccept(new BlankNodeToVarConverter(), null);
    }
    catch (VisitorException e) {
      throw new MalformedQueryException(e);
    }
  }

  /*-------------------------------------*
   * Inner class BlankNodeToVarConverter *
   *-------------------------------------*/

  private static class BlankNodeToVarConverter extends ASTVisitorBase {

    private int anonVarNo = 1;

    private Map<String, String> conversionMap = new HashMap<String, String>();

    private Set<String> usedBNodeIDs = new HashSet<String>();

    private String createAnonVarName() {
      return "-anon-" + anonVarNo++;
    }

    @Override
    public Object visit(ASTBasicGraphPattern node, Object data)
      throws VisitorException
    {
      // The same Blank node ID cannot be used across Graph Patterns
      usedBNodeIDs.addAll(conversionMap.keySet());

      // Blank nodes are scope to Basic Graph Patterns
      conversionMap.clear();

      return super.visit(node, data);
    }

    @Override
    public Object visit(ASTBlankNode node, Object data)
      throws VisitorException
    {
      String bnodeID = node.getID();
      String varName = findVarName(bnodeID);

      if (varName == null) {
        varName = createAnonVarName();

        if (bnodeID != null) {
          conversionMap.put(bnodeID, varName);
        }
      }

      ASTVar varNode = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR);
      varNode.setName(varName);
      varNode.setAnonymous(true);

      node.jjtReplaceWith(varNode);

      return super.visit(node, data);
    }

    private String findVarName(String bnodeID)
      throws VisitorException
    {
      if (bnodeID == null) {
        return null;
      }
      String varName = conversionMap.get(bnodeID);
      if (varName == null && usedBNodeIDs.contains(bnodeID)) {
        throw new VisitorException("BNodeID already used in another scope: " + bnodeID);
      }
      return varName;
    }

    @Override
    public Object visit(ASTBlankNodePropertyList node, Object data)
      throws VisitorException
    {
      node.setVarName(createAnonVarName());
      return super.visit(node, data);
    }

    @Override
    public Object visit(ASTCollection node, Object data)
      throws VisitorException
    {
      node.setVarName(createAnonVarName());
      return super.visit(node, data);
    }
  }
}
TOP

Related Classes of org.openrdf.query.parser.sparql.BlankNodeVarProcessor$BlankNodeToVarConverter

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.