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

org.eclipse.rdf4j.query.algebra.Group Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
/*******************************************************************************
 * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *******************************************************************************/
package org.eclipse.rdf4j.query.algebra;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import com.google.common.collect.Iterables;

/**
 * A tuple operator that groups tuples that have a specific set of equivalent variable bindings, and that can apply
 * aggregate functions on the grouped results.
 *
 * @author David Huynh
 * @author Arjohn Kampman
 */
public class Group extends UnaryTupleOperator {

	/*-----------*
	 * Variables *
	 *-----------*/

	private Set groupBindings = Set.of();

	private List groupElements = new ArrayList<>();

	/*--------------*
	 * Constructors *
	 *--------------*/

	public Group() {
	}

	public Group(TupleExpr arg) {
		super(arg);
	}

	public Group(TupleExpr arg, Iterable groupBindingNames) {
		this(arg);
		setGroupBindingNames(groupBindingNames);
	}

	public Group(TupleExpr arg, Iterable groupBindingNames, Iterable groupElements) {
		this(arg, groupBindingNames);
		setGroupElements(groupElements);
	}

	/*---------*
	 * Methods *
	 *---------*/

	public Set getGroupBindingNames() {
		return groupBindings;
	}

	public void addGroupBindingName(String bindingName) {
		if (groupBindings.isEmpty()) {
			groupBindings = Set.of(bindingName);
			return;
		} else if (groupBindings.size() == 1) {
			groupBindings = new HashSet<>(groupBindings);
		}
		groupBindings.add(bindingName);
	}

	public void setGroupBindingNames(List bindingNames) {
		if (bindingNames.isEmpty()) {
			groupBindings = Set.of();
		} else if (bindingNames.size() == 1) {
			groupBindings = Set.of(bindingNames.get(0));
		} else {
			groupBindings = new LinkedHashSet<>(bindingNames);
		}
	}

	public void setGroupBindingNames(Iterable bindingNames) {
		groupBindings = new LinkedHashSet<>();
		Iterables.addAll(groupBindings, bindingNames);
	}

	public List getGroupElements() {
		return groupElements;
	}

	public void addGroupElement(GroupElem groupElem) {
		groupElem.setParentNode(this);
		groupElements.add(groupElem);
	}

	public void setGroupElements(Iterable elements) {
		this.groupElements.clear();
		Iterables.addAll(groupElements, elements);
		groupElements.forEach(groupElem -> groupElem.setParentNode(this));
	}

	public Set getAggregateBindingNames() {
		Set bindings = new HashSet<>();

		for (GroupElem binding : groupElements) {
			bindings.add(binding.getName());
		}

		return bindings;
	}

	@Override
	public Set getBindingNames() {
		Set bindingNames = new LinkedHashSet<>(getGroupBindingNames());
		bindingNames.addAll(getAggregateBindingNames());
		return bindingNames;
	}

	@Override
	public Set getAssuredBindingNames() {
		Set bindingNames = new LinkedHashSet<>(getGroupBindingNames());
		bindingNames.retainAll(getArg().getAssuredBindingNames());
		return bindingNames;
	}

	@Override
	public  void visit(QueryModelVisitor visitor) throws X {
		visitor.meet(this);
	}

	@Override
	public  void visitChildren(QueryModelVisitor visitor) throws X {
		super.visitChildren(visitor);

		for (GroupElem ge : groupElements) {
			ge.visit(visitor);
		}
	}

	@Override
	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
		if (replaceNodeInList(groupElements, current, replacement)) {
			return;
		}
		super.replaceChildNode(current, replacement);
	}

	@Override
	public boolean equals(Object other) {
		if (other instanceof Group && super.equals(other)) {
			Group o = (Group) other;
			return groupBindings.equals(o.getGroupBindingNames()) && groupElements.equals(o.getGroupElements());
		}
		return false;
	}

	@Override
	public int hashCode() {
		return super.hashCode() ^ groupBindings.hashCode() ^ groupElements.hashCode();
	}

	@Override
	public Group clone() {
		Group clone = (Group) super.clone();

		clone.groupBindings = new LinkedHashSet<>(getGroupBindingNames());

		clone.groupElements = new ArrayList<>(getGroupElements().size());
		for (GroupElem ge : getGroupElements()) {
			clone.addGroupElement(ge.clone());
		}

		return clone;
	}

	@Override
	public String getSignature() {
		StringBuilder sb = new StringBuilder();
		sb.append(this.getClass().getSimpleName());
		sb.append(" (");

		Set bindingNames = getGroupBindingNames();
		int count = 0;
		for (String name : bindingNames) {
			sb.append(name);
			count++;
			if (count < bindingNames.size()) {
				sb.append(", ");
			}
		}
		sb.append(")");

		return sb.toString();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy