
com.google.code.liquidform.Arithmetics Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of liquidform.jpa Show documentation
Show all versions of liquidform.jpa Show documentation
Provides a Java Domain Specific Language for building type-safe and refactoring proof JPA queries.
The newest version!
/*
* Copyright (C) 2008-2009 the original author or authors
*
* 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.google.code.liquidform;
import com.google.code.liquidform.internal.AliasFactory;
import com.google.code.liquidform.internal.FrameworkObjectFactory;
import com.google.code.liquidform.internal.managedobjects.FrameworkManagedObject;
/**
* Provides support for arithmetic expressions. The method names here should be
* self explanatory. Varargs are used to enable operations with multiple
* operands.
*
*
* The return type of those methods extends {@link Number}. The JSR states that
* "Arithmetic operations use numeric promotion" but this
* implementation, based on generics, falls back to the first common superclass
* (namely {@link Number}) as soon as the arguments are not all of the exact
* same type.
*
* Note that with {@link SubQuery}, the return type is necessarily
* {@link Number}.
*
*/
public class Arithmetics {
private static final String UNARY_PLUS = "+ ";
private static final String UNARY_MINUS = "- ";
private static final String PLUS = " + ";
private static final String MINUS = " - ";
private static final String TIMES = " * ";
private static final String DIVIDE = " / ";
private Arithmetics() {
// utility class
}
// grouping with parentheses
public static N paren(final N arithmeticExpression) {
N grouppedExpression = FrameworkObjectFactory.INSTANCE
.makeNew(arithmeticExpression);
AliasFactory.remember(grouppedExpression, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
return "(" + AliasFactory.safeStringForm(arithmeticExpression)
+ ")";
}
});
return grouppedExpression;
}
// addition
public static N plus(final N operand,
final N... moreOperands) {
N sum = FrameworkObjectFactory.INSTANCE.makeNew(operand);
AliasFactory.remember(sum, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
if (moreOperands.length == 0) {
return UNARY_PLUS + AliasFactory.safeStringForm(operand);
}
return buildChainedOps(PLUS, operand, moreOperands);
}
});
return sum;
}
public static Number plus(final SubQuery extends Number> subQuery,
Number operand) {
return plus(rememberAsDouble(subQuery), operand);
}
public static Number plus(final SubQuery extends Number> subQuery,
final SubQuery extends Number>... moreSubQueries) {
Double subQueryAsNumber = rememberAsDouble(subQuery);
if (moreSubQueries.length == 0) {
return plus(subQueryAsNumber);
}
return plus(subQueryAsNumber,
rememberAllSubQueriesAsNumbers(moreSubQueries));
}
// subtraction
public static N minus(final N operand,
final N... moreOperands) {
N difference = FrameworkObjectFactory.INSTANCE.makeNew(operand);
AliasFactory.remember(difference, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
if (moreOperands.length == 0) {
return UNARY_MINUS + AliasFactory.safeStringForm(operand);
}
return buildChainedOps(MINUS, operand, moreOperands);
}
});
return difference;
}
public static Number minus(final SubQuery extends Number> subQuery,
Number operand) {
return minus(rememberAsDouble(subQuery), operand);
}
public static Number minus(Number operand,
final SubQuery extends Number> subQuery) {
return minus(operand, rememberAsDouble(subQuery));
}
public static Number minus(final SubQuery extends Number> subQuery,
SubQuery extends Number>... moreSubQueries) {
Double subQueryAsNumber = rememberAsDouble(subQuery);
if (moreSubQueries.length == 0) {
return minus(subQueryAsNumber);
}
return minus(subQueryAsNumber,
rememberAllSubQueriesAsNumbers(moreSubQueries));
}
// product
public static N times(final N factor1, final N factor2,
final N... moreFactors) {
N product = FrameworkObjectFactory.INSTANCE.makeNew(factor1);
AliasFactory.remember(product, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
if (moreFactors.length == 0) {
return AliasFactory.safeStringForm(factor1) + TIMES
+ AliasFactory.safeStringForm(factor2);
}
return AliasFactory.safeStringForm(factor1) + TIMES
+ buildChainedOps(TIMES, factor2, moreFactors);
}
});
return product;
}
public static Number times(final SubQuery extends Number> subQuery,
Number factor) {
return times(rememberAsDouble(subQuery), factor);
}
public static Number times(final SubQuery extends Number> subQuery1,
final SubQuery extends Number> subQuery2,
SubQuery extends Number>... moreSubQueries) {
Double subQuery1AsNumber = rememberAsDouble(subQuery1);
if (moreSubQueries.length == 0) {
return times(subQuery1AsNumber, rememberAsDouble(subQuery2));
}
return times(subQuery1AsNumber, rememberAsDouble(subQuery2),
rememberAllSubQueriesAsNumbers(moreSubQueries));
}
// division
public static N divide(final N dividend, final N divisor) {
N quotient = FrameworkObjectFactory.INSTANCE.makeNew(dividend);
AliasFactory.remember(quotient, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
return AliasFactory.safeStringForm(dividend) + DIVIDE
+ AliasFactory.safeStringForm(divisor);
}
});
return quotient;
}
public static Number divide(
final SubQuery extends Number> subQueryDividend, Number divisor) {
return divide(rememberAsDouble(subQueryDividend), divisor);
}
public static Number divide(Number dividend,
final SubQuery extends Number> subQueryDivisor) {
return divide(dividend, rememberAsDouble(subQueryDivisor));
}
public static Number divide(
final SubQuery extends Number> subQueryDividend,
final SubQuery extends Number> subQueryDivisor) {
return divide(rememberAsDouble(subQueryDividend),
rememberAsDouble(subQueryDivisor));
}
private static String buildChainedOps(String operator,
O operand, O... moreOperands) {
StringBuilder sb = new StringBuilder();
sb.append(AliasFactory.safeStringForm(operand));
for (O element : moreOperands) {
sb.append(operator).append(AliasFactory.safeStringForm(element));
}
return sb.toString();
};
private static Double rememberAsDouble(
final SubQuery extends Number> subQuery) {
Double subQueryAsNumber = FrameworkObjectFactory.INSTANCE
.makeNew(Double.class);
AliasFactory.remember(subQueryAsNumber, new FrameworkManagedObject() {
@Override
public String getTargetRepresentation() {
return AliasFactory.safeStringForm(subQuery);
}
});
return subQueryAsNumber;
}
private static Number[] rememberAllSubQueriesAsNumbers(
SubQuery extends Number>... moreSubQueries) {
Number[] result = new Number[moreSubQueries.length];
for (int i = 0; i < moreSubQueries.length; i++) {
result[i] = rememberAsDouble(moreSubQueries[i]);
}
return result;
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy