blob: 671f2417568b68e5b4484c00ce6b6cd2fe5f223f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.openjpa.persistence.query;
import java.util.LinkedList;
/**
* An abstract path is formed by two parts : the first part is a parent path.
* The second part can be an attribute or an operation (e.g. KEY() or VALUE())
* or a join type operation. Based on the exact nature of the second part,
* concrete derivation of this class combines the two constituent parts to
* arrive at complete path name.
* For example, a navigation path adds the two part with a navigation '.'
* operator, while a OperatorPath will combine the parts as KEY(parent).
*
* The constituent parts are immutable and supplied at construction. Hence
* concrete implementations know what exact type they are dealing with, but
* this receiver maintains it state as more generic type to accommodate
* concrete types to cast/interpret these state variables.
*
* @author Pinaki Poddar
*
*/
abstract class AbstractPath extends ExpressionImpl implements
PathExpression {
private static final long serialVersionUID = 1L;
protected final AbstractPath _parent;
protected final Object _part2;
protected final PathOperator _operator;
protected final QueryDefinitionImpl _owner;
protected AbstractPath(QueryDefinitionImpl owner, AbstractPath parent,
PathOperator op, Object part2) {
_owner = owner;
_parent = parent;
_part2 = part2;
_operator = op;
}
// ------------------------------------------------------------------------
// Path related functions.
// ------------------------------------------------------------------------
final QueryDefinitionImpl getOwner() {
return _owner;
}
/**
* Gets the parent from which this receiver has been derived. Can be null
* for a root path.
*/
public AbstractPath getParent() {
return _parent;
}
/**
* Gets operator that derived this receiver from its parent.
*/
public PathOperator getOperator() {
return _operator;
}
/**
* Gets the last segment of this path.
* Concrete implementation should return a covariant type.
*/
public Object getLastSegment() {
return _part2;
}
// -----------------------------------------------------------------------
// Implementation of PathExpression
// -----------------------------------------------------------------------
@Override
public Aggregate avg() {
return new AverageExpression(this);
}
@Override
public Aggregate count() {
return new CountExpression(this);
}
@Override
public Predicate isEmpty() {
return new IsEmptyExpression(this);
}
@Override
public Aggregate max() {
return new MaxExpression(this);
}
@Override
public Aggregate min() {
return new MinExpression(this);
}
@Override
public Expression size() {
return new SizeExpression(this);
}
@Override
public Aggregate sum() {
return new SumExpression(this);
}
@Override
public Expression type() {
return new TypeExpression(this);
}
LinkedList<AbstractPath> split() {
return _split(this, new LinkedList<>());
}
private LinkedList<AbstractPath> _split(AbstractPath path,
LinkedList<AbstractPath> list) {
if (path == null)
return list;
_split(path.getParent(), list);
list.add(path);
return list;
}
}