blob: 71ff300ae6d8e88c639bb99dc299a43af56e044c [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.criteria;
import java.util.List;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Selection;
import org.apache.openjpa.persistence.util.ReservedWords;
/**
* An item selected in the projection clause of Criteria query.
* Base implementation for all concrete expressions.
*
* @param <X> the type this term evaluates to
*
* @author Pinaki Poddar
*
* @since 2.0.0
*/
abstract class SelectionImpl<X> implements Selection<X>, CriteriaExpression {
private final Class<X> _cls;
private String _alias;
private Boolean _autoAliased;
/**
* Construct with the immutable type represented by this selection term.
*/
public SelectionImpl(Class<X> cls) {
_cls = cls;
}
/**
* Gets the immutable type represented by this selection term.
*/
@Override
public Class<X> getJavaType() {
return _cls;
}
/**
* Gets the alias set of this selection term.
*/
@Override
public String getAlias() {
return _alias;
}
/**
* Sets the alias on this selection term.
* Alias can only be set once.
*/
@Override
public Selection<X> alias(String alias) {
assertValidName(alias);
if (isAliased())
throw new IllegalStateException(this + " has been aliased to [" + _alias
+ ". Can not alias again to " + alias);
_alias = alias;
_autoAliased = false;
return this;
}
/**
* Sets the alias of this expression internally. Only valid if the expression is not aliased explicitly
* by calling {@linkplain #alias(String)}.
*/
void setAutoAlias(String alias) {
if (isAliased())
throw new IllegalStateException(this + " has been aliased. Can not set alias internally");
_alias = alias;
_autoAliased = true;
}
/**
* Affirms if the alias of this expression is assigned automatically.
*/
boolean isAutoAliased() {
return _autoAliased == null ? true : _autoAliased.booleanValue();
}
/**
* Affirms if this expression has been assigned an alias by {@linkplain #alias(String)} method.
* An alias can be assigned also by internal implementation.
* @see #isAutoAliased()
*/
boolean isAliased() {
return Boolean.FALSE.equals(_autoAliased);
}
/**
* Throws IllegalStateException because a selection term, by default, consists of single value.
*/
@Override
public List<Selection<?>> getCompoundSelectionItems() {
throw new IllegalStateException(this + " is not a compound selection");
}
/**
* Returns false because a selection term, by default, consists of single value.
*/
@Override
public boolean isCompoundSelection() {
return false;
}
void assertValidName(String name) {
if (name == null || name.trim().length() == 0)
throw new IllegalArgumentException("empty name is invalid");
if (ReservedWords.isKeyword(name))
throw new IllegalArgumentException("reserved word " + name + " is not valid");
Character ch = ReservedWords.hasSpecialCharacter(name);
if (ch != null)
throw new IllegalArgumentException(name + " contains reserved symbol " + ch);
}
// ------------------------------------------------------------------------------------
// Contract for CriteriaExpression implemented mostly as a no-op for easier derivation.
// ------------------------------------------------------------------------------------
@Override
public StringBuilder asValue(AliasContext q) {
throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as value");
}
@Override
public StringBuilder asVariable(AliasContext q) {
throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as variable");
}
@Override
public StringBuilder asProjection(AliasContext q) {
String as = (isAutoAliased() ? "" : " AS " + getAlias());
return asValue(q).append(as);
}
@Override
public void acceptVisit(CriteriaExpressionVisitor visitor) {
Expressions.acceptVisit(visitor, this, (Expression<?>[])null);
}
}