com.blazebit.persistence.parser.expression.PathExpression Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 - 2024 Blazebit.
*
* Licensed 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 com.blazebit.persistence.parser.expression;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Christian Beikov
* @author Moritz Becker
* @since 1.0.0
*/
public class PathExpression extends AbstractExpression implements Expression {
private List pathProperties;
private PathReference pathReference;
private boolean usedInCollectionFunction = false;
private boolean collectionQualifiedPath;
public PathExpression() {
this(new ArrayList(), false);
}
public PathExpression(PathElementExpression pathElementExpression) {
this(list(pathElementExpression), false);
}
public PathExpression(List pathProperties) {
this(pathProperties, false);
}
public PathExpression(List pathProperties, boolean isCollectionKeyPath) {
this.pathProperties = pathProperties;
this.collectionQualifiedPath = isCollectionKeyPath;
}
public PathExpression(List pathProperties, PathReference pathReference, boolean usedInCollectionFunction, boolean collectionQualifiedPath) {
this.pathProperties = pathProperties;
this.pathReference = pathReference;
this.usedInCollectionFunction = usedInCollectionFunction;
this.collectionQualifiedPath = collectionQualifiedPath;
}
private static List list(PathElementExpression elementExpression) {
List list = new ArrayList<>(1);
list.add(elementExpression);
return list;
}
@Override
public Expression copy(ExpressionCopyContext copyContext) {
if (pathProperties.size() == 1 && pathProperties.get(0) instanceof PropertyExpression) {
Expression expression = copyContext.getExpressionForAlias(pathProperties.get(0).toString());
if (expression != null) {
return expression;
}
}
int size = pathProperties.size();
List newPathProperties = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
newPathProperties.add(pathProperties.get(i).copy(copyContext));
}
return new PathExpression(newPathProperties, copyContext.isCopyResolved() ? pathReference : null, usedInCollectionFunction, collectionQualifiedPath);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public T accept(ResultVisitor visitor) {
return visitor.visit(this);
}
public List getExpressions() {
return pathProperties;
}
public void setExpressions(List expressions) {
this.pathProperties = expressions;
}
public PathReference getPathReference() {
return pathReference;
}
public void setPathReference(PathReference pathReference) {
this.pathReference = pathReference;
}
public BaseNode getBaseNode() {
if (pathReference == null) {
return null;
}
return pathReference.getBaseNode();
}
public String getField() {
if (pathReference == null) {
return null;
}
return pathReference.getField();
}
public boolean isUsedInCollectionFunction() {
return usedInCollectionFunction;
}
public void setUsedInCollectionFunction(boolean collectionValued) {
this.usedInCollectionFunction = collectionValued;
}
public String getPath() {
return toString();
}
public boolean isCollectionQualifiedPath() {
return collectionQualifiedPath;
}
public void setCollectionQualifiedPath(boolean collectionQualifiedPath) {
this.collectionQualifiedPath = collectionQualifiedPath;
}
public PathExpression withoutFirst() {
int size = pathProperties.size();
if (size == 0) {
return this;
}
List list = new ArrayList<>(size - 1);
for (int i = 1; i < size; i++) {
list.add(pathProperties.get(i));
}
return new PathExpression(list);
}
/*
* The following equals and hashCode implementation makes it possible that expressions which have different path properties but
* reference the same object, are equal.
*/
@Override
public int hashCode() {
int hash = 3;
if (this.pathReference != null) {
hash = 31 * hash + this.pathReference.hashCode();
} else {
hash = 31 * hash + (this.pathProperties != null ? this.pathProperties.hashCode() : 0);
}
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
final PathExpression other = (PathExpression) obj;
if (this.pathReference != null || other.pathReference != null) {
if (this.pathReference == null) {
// First try to match with path properties
if (this.pathProperties == other.pathProperties || this.pathProperties != null && this.pathProperties.equals(other.pathProperties)) {
return true;
}
// If that doesn't work out, try to match paths
return this.getPath().equals(other.getPath());
} else if (other.pathReference == null) {
// First try to match with path properties
if (other.pathProperties == this.pathProperties || other.pathProperties != null && other.pathProperties.equals(this.pathProperties)) {
return true;
}
// If that doesn't work out, try to match paths
return this.getPath().equals(other.getPath());
} else {
if (this.pathReference == other.pathReference) {
return true;
}
return this.pathReference.equals(other.pathReference);
}
} else {
if (this.pathProperties != other.pathProperties && (this.pathProperties == null || !this.pathProperties.equals(other.pathProperties))) {
return false;
}
}
return true;
}
}