All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.weaverplatform.sp4rql.model.scope.ScopeQuery Maven / Gradle / Ivy

package com.weaverplatform.sp4rql.model.scope;

import com.weaverplatform.sp4rql.error.ParseException;
import com.weaverplatform.sp4rql.model.expression.ExpressionArgument;
import com.weaverplatform.sp4rql.model.expression.ExpressionUnit;
import com.weaverplatform.sp4rql.model.restriction.ValuesRestriction;
import com.weaverplatform.sp4rql.model.token.ReferenceToken;
import com.weaverplatform.sp4rql.model.token.VariableToken;
import com.weaverplatform.util.IndentStringBuilder;

import java.util.*;

public class ScopeQuery extends ScopeSimple {

  public enum Type { ASK, CONSTRUCT, DESCRIBE, SELECT }

  private Type queryType;
  private String baseIri;
  private HashMap prefixMap = new HashMap<>();
  private ArrayList grouping = new ArrayList<>();
  private HashMap groupingToSelect = new HashMap<>();
  private Integer limit = null;
  private Integer offset = null;
  private ArrayList order = new ArrayList<>();
  private HashSet desc = new HashSet<>();
  private ValuesRestriction postValues = null;

  // Contains the graphs the restrictions without a graph selector should be matched to
  private HashSet defaultGraphMerge =  new HashSet<>();

  // Limits the graphs the restrictions with a graph selector can match to
  private HashSet namedGraphSelection =  new HashSet<>();

  private boolean distinct = false;

  private boolean reduced = false;

  private ArrayList selections = new ArrayList<>();


  private HashMap selectionDetails = new HashMap<>();

  private boolean selectAll = false;

  public ScopeQuery() {
    super(null);
    this.setAlias("main");
  }

  public ScopeQuery(Sp4rqlScope superScope) {
    super(superScope);
  }

  public void setQueryType(Type type) {
    this.queryType = type;
  }

  public Type getQueryType() {
    return queryType;
  }

  public void registerBase(String iri) {
    if(baseIri != null) {
      throw new ParseException("A base iri is defined more then once");
    }
    baseIri = iri;
  }

  public String getBaseIri() {
    return baseIri;
  }

  public void registerPrefix(String prefix, String iri) {
    boolean allowOverride = true;
    if(!allowOverride && prefixMap.containsKey(prefix)) {
      if(prefix.isEmpty()) {
        throw new ParseException("The empty prefix is defined more then once");
      } else {
        throw new ParseException(String.format("The prefix %s is defined more then once", prefix));
      }
    }
    prefixMap.put(prefix, iri);
  }

  public HashMap getPrefixMap() {
    return prefixMap;
  }

  public void addGrouping(ExpressionArgument expression) {
    grouping.add(expression);
  }

  public void addGrouping(ExpressionArgument expression, VariableToken token) {
    addGrouping(expression);
    groupingToSelect.put(expression, token);
  }

  public ArrayList getGrouping() {
    return grouping;
  }

  public VariableToken getGroupingSelect(ExpressionArgument expression) {
    return groupingToSelect.get(expression);
  }

  public void addDefaultGraph(ReferenceToken token) {
    defaultGraphMerge.add(token);
  }

  public HashSet getDefaultGraphMerge() {
    return defaultGraphMerge;
  }

  public HashSet getNamedGraphSelection() {
    return namedGraphSelection;
  }

  public void addNamedGraph(ReferenceToken token) {
    namedGraphSelection.add(token);
  }

  public void setDistinct() {
    distinct = true;
  }

  public boolean isDistinct() {
    return distinct;
  }

  public void setReduced() {
    reduced = true;
  }

  public boolean isReduced() {
    return reduced;
  }

  public void addSelection(VariableToken token) {
    selections.add(token);
    selectionDetails.put(token, null);
  }

  public void addSelection(VariableToken token, ExpressionUnit expression) {
    selections.add(token);
    selectionDetails.put(token, expression);
  }

  public void setSelectAll() {
    selectAll = true;
  }

  public boolean isSelectAll() {
    return selectAll;
  }

  public List getSelectVariables() {
    return selections;
  }

  // Return null if there is no expression
  public ExpressionUnit getSelectExpression(VariableToken token) {
    return selectionDetails.get(token);
  }

  // If one select contains an aggregate operator the query result should be aggregated
  // and all selects (with the exception of those in the group by list) should aggregate
  public boolean isAggregate() {
    for(ExpressionArgument expression : selectionDetails.values()) {
      if(expression != null && expression instanceof ExpressionUnit && ((ExpressionUnit) expression).isAggregate()) {
        return true;
      }
    }
    return false;
  }

  public void setLimit(int limit) {
    this.limit = limit;
  }

  public Integer getLimit() {
    return limit;
  }

  public void setOffset(int offset) {
    this.offset = offset;
  }

  public Integer getOffset() {
    return offset;
  }

  public void addOrderBy(ExpressionArgument token, boolean desc) {
    this.order.add(token);
    if(desc) {
      this.desc.add(token);
    }
  }

  public ArrayList getOrder() {
    return order;
  }

  public boolean isOrderDesc(ExpressionArgument token) {
    return desc.contains(token);
  }

  public void addPostValuesRestriction(ValuesRestriction restriction) {
    this.postValues = restriction;
  }

  public ValuesRestriction getPostValuesRestriction() {
    return postValues;
  }

  @Override
  public HashSet getExposedVariables() {
    HashSet set = new HashSet<>();
    for(VariableToken token : super.getExposedVariables()) {
      if(isSelectAll() || getSelectVariables().contains(token)) {
        set.add(token);
      }
    }
    for(VariableToken token : selections) {
      set.add(token);
    }
    return set;
  }

  public HashSet getSimpleExposedVariables() {
    return super.getExposedVariables();
  }

  @Override
  public void buildString(IndentStringBuilder builder) {
    if(baseIri != null) {
      builder.append("BASE ");
      builder.append(baseIri);
      builder.newline();
    }
    for(String prefix : prefixMap.keySet()) {
      String iriFragment = prefixMap.get(prefix);
      builder.append("PREFIX ");
      builder.append(prefix);
      builder.append(": ");
      builder.append(iriFragment);
      builder.newline();
    }
    builder.append(queryType.name());
    builder.append(" ");
    if(queryType == Type.SELECT) {
      if(isSelectAll()) {
        builder.append("*");
      } else {
        for (VariableToken token : selections) {
          if(selectionDetails.get(token) != null) {
            selectionDetails.get(token).buildString(builder);
            builder.append(" AS ");
          }
          token.buildString(builder);
          builder.append(" ");
        }
      }
      builder.retract();
    }
    builder.newline();
    for(ReferenceToken token : defaultGraphMerge) {
      builder.append("FROM ");
      token.buildString(builder);
      builder.newline();
    }
    for(ReferenceToken token : namedGraphSelection) {
      builder.append("FROM NAMED ");
      token.buildString(builder);
      builder.newline();
    }
    builder.appendLine("WHERE {", 1);
    super.buildString(builder);
    builder.newline(-1);
    builder.appendLine("}");
    if(!grouping.isEmpty()) {
      builder.append("GROUP BY ");
      Iterator iterator = grouping.iterator();
      while(iterator.hasNext()) {
        ExpressionArgument expression = iterator.next();
        expression.buildString(builder);
        VariableToken token = getGroupingSelect(expression);
        if(token != null) {
          builder.append(" ");
          token.buildString(builder);
        }
        if(iterator.hasNext()) {
          builder.append(" ");
        }
      }
    }
    if(postValues != null) {
      postValues.buildString(builder);
    }
    builder.retract();
  }

  @Override
  public String toString() {
    return getAlias();
  }

  public String buildString() {
    IndentStringBuilder builder = new IndentStringBuilder();
    this.buildString(builder);
    return builder.toString();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy