Use consistent class design

Update all classes so that inner classes are always last. Also
ensure that utility classes are always final and have a private
constructor and make exceptions final whenever possible.

Issue: SPR-16968
This commit is contained in:
Phillip Webb
2018-06-20 19:44:39 -07:00
committed by Juergen Hoeller
parent 0ad0f341bd
commit eeebd51f57
128 changed files with 656 additions and 455 deletions

View File

@@ -29,7 +29,7 @@ import org.springframework.lang.Nullable;
public class ExpressionException extends RuntimeException {
@Nullable
protected String expressionString;
protected final String expressionString;
protected int position; // -1 if not known; should be known in all reasonable cases
@@ -40,6 +40,8 @@ public class ExpressionException extends RuntimeException {
*/
public ExpressionException(String message) {
super(message);
this.expressionString = null;
this.position = 0;
}
/**
@@ -49,6 +51,8 @@ public class ExpressionException extends RuntimeException {
*/
public ExpressionException(String message, Throwable cause) {
super(message, cause);
this.expressionString = null;
this.position = 0;
}
/**
@@ -81,6 +85,7 @@ public class ExpressionException extends RuntimeException {
*/
public ExpressionException(int position, String message) {
super(message);
this.expressionString = null;
this.position = position;
}
@@ -92,6 +97,7 @@ public class ExpressionException extends RuntimeException {
*/
public ExpressionException(int position, String message, Throwable cause) {
super(message, cause);
this.expressionString = null;
this.position = position;
}

View File

@@ -1009,6 +1009,21 @@ public class CodeFlow implements Opcodes {
}
}
public static final String toBoxedDescriptor(String primitiveDescriptor) {
switch (primitiveDescriptor.charAt(0)) {
case 'I': return "Ljava/lang/Integer";
case 'J': return "Ljava/lang/Long";
case 'F': return "Ljava/lang/Float";
case 'D': return "Ljava/lang/Double";
case 'B': return "Ljava/lang/Byte";
case 'C': return "Ljava/lang/Character";
case 'S': return "Ljava/lang/Short";
case 'Z': return "Ljava/lang/Boolean";
default:
throw new IllegalArgumentException("Unexpected non primitive descriptor "+primitiveDescriptor);
}
}
/**
* Interface used to generate fields.
@@ -1029,19 +1044,5 @@ public class CodeFlow implements Opcodes {
void generateCode(MethodVisitor mv, CodeFlow codeflow);
}
public static String toBoxedDescriptor(String primitiveDescriptor) {
switch (primitiveDescriptor.charAt(0)) {
case 'I': return "Ljava/lang/Integer";
case 'J': return "Ljava/lang/Long";
case 'F': return "Ljava/lang/Float";
case 'D': return "Ljava/lang/Double";
case 'B': return "Ljava/lang/Byte";
case 'C': return "Ljava/lang/Character";
case 'S': return "Ljava/lang/Short";
case 'Z': return "Ljava/lang/Boolean";
default:
throw new IllegalArgumentException("Unexpected non primitive descriptor "+primitiveDescriptor);
}
}
}

View File

@@ -41,7 +41,7 @@ import org.springframework.util.ObjectUtils;
public abstract class Operator extends SpelNodeImpl {
private final String operatorName;
// The descriptors of the runtime operand values are used if the discovered declared
// descriptors are not providing enough information (for example a generic type
// whose accessors seem to only be returning 'Object' - the actual descriptors may
@@ -104,8 +104,8 @@ public abstract class Operator extends SpelNodeImpl {
return (dc.areNumbers && dc.areCompatible);
}
/**
* Numeric comparison operators share very similar generated code, only differing in
/**
* Numeric comparison operators share very similar generated code, only differing in
* two comparison instructions.
*/
protected void generateComparisonCode(MethodVisitor mv, CodeFlow cf, int compInstruction1, int compInstruction2) {
@@ -113,20 +113,20 @@ public abstract class Operator extends SpelNodeImpl {
SpelNodeImpl right = getRightOperand();
String leftDesc = left.exitTypeDescriptor;
String rightDesc = right.exitTypeDescriptor;
boolean unboxLeft = !CodeFlow.isPrimitive(leftDesc);
boolean unboxRight = !CodeFlow.isPrimitive(rightDesc);
DescriptorComparison dc = DescriptorComparison.checkNumericCompatibility(
leftDesc, rightDesc, this.leftActualDescriptor, this.rightActualDescriptor);
char targetType = dc.compatibleType; // CodeFlow.toPrimitiveTargetDesc(leftDesc);
cf.enterCompilationScope();
left.generateCode(mv, cf);
cf.exitCompilationScope();
if (unboxLeft) {
CodeFlow.insertUnboxInsns(mv, targetType, leftDesc);
}
cf.enterCompilationScope();
right.generateCode(mv, cf);
cf.exitCompilationScope();
@@ -142,11 +142,11 @@ public abstract class Operator extends SpelNodeImpl {
mv.visitJumpInsn(compInstruction1, elseTarget);
}
else if (targetType == 'F') {
mv.visitInsn(FCMPG);
mv.visitInsn(FCMPG);
mv.visitJumpInsn(compInstruction1, elseTarget);
}
else if (targetType == 'J') {
mv.visitInsn(LCMP);
mv.visitInsn(LCMP);
mv.visitJumpInsn(compInstruction1, elseTarget);
}
else if (targetType == 'I') {
@@ -231,13 +231,13 @@ public abstract class Operator extends SpelNodeImpl {
return false;
}
/**
* A descriptor comparison encapsulates the result of comparing descriptor
* for two operands and describes at what level they are compatible.
*/
protected static class DescriptorComparison {
protected static final class DescriptorComparison {
static final DescriptorComparison NOT_NUMBERS = new DescriptorComparison(false, false, ' ');
@@ -254,7 +254,7 @@ public abstract class Operator extends SpelNodeImpl {
this.areCompatible = areCompatible;
this.compatibleType = compatibleType;
}
/**
* Return an object that indicates whether the input descriptors are compatible.
* <p>A declared descriptor is what could statically be determined (e.g. from looking
@@ -278,7 +278,7 @@ public abstract class Operator extends SpelNodeImpl {
boolean leftNumeric = CodeFlow.isPrimitiveOrUnboxableSupportedNumberOrBoolean(ld);
boolean rightNumeric = CodeFlow.isPrimitiveOrUnboxableSupportedNumberOrBoolean(rd);
// If the declared descriptors aren't providing the information, try the actual descriptors
if (!leftNumeric && !ObjectUtils.nullSafeEquals(ld, leftActualDescriptor)) {
ld = leftActualDescriptor;
@@ -288,7 +288,7 @@ public abstract class Operator extends SpelNodeImpl {
rd = rightActualDescriptor;
rightNumeric = CodeFlow.isPrimitiveOrUnboxableSupportedNumberOrBoolean(rd);
}
if (leftNumeric && rightNumeric) {
if (CodeFlow.areBoxingCompatible(ld, rd)) {
return new DescriptorComparison(true, true, CodeFlow.toPrimitiveTargetDesc(ld));
@@ -299,7 +299,7 @@ public abstract class Operator extends SpelNodeImpl {
}
else {
return DescriptorComparison.NOT_NUMBERS;
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -64,7 +64,7 @@ import org.springframework.util.ReflectionUtils;
* @author Andy Clement
* @since 4.1
*/
public class SpelCompiler implements Opcodes {
public final class SpelCompiler implements Opcodes {
private static final Log logger = LogFactory.getLog(SpelCompiler.class);

View File

@@ -24,7 +24,7 @@ import org.springframework.expression.TypedValue;
* @author Andy Clement
* @since 3.0
*/
public class BooleanTypedValue extends TypedValue {
public final class BooleanTypedValue extends TypedValue {
/**
* True.

View File

@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
* @see #forInstanceMethodInvocation()
* @see DataBindingPropertyAccessor
*/
public class DataBindingMethodResolver extends ReflectiveMethodResolver {
public final class DataBindingMethodResolver extends ReflectiveMethodResolver {
private DataBindingMethodResolver() {
super();

View File

@@ -37,7 +37,7 @@ import java.lang.reflect.Method;
* @see StandardEvaluationContext
* @see ReflectivePropertyAccessor
*/
public class DataBindingPropertyAccessor extends ReflectivePropertyAccessor {
public final class DataBindingPropertyAccessor extends ReflectivePropertyAccessor {
/**
* Create a new property accessor for reading and possibly also writing.

View File

@@ -86,7 +86,7 @@ import org.springframework.lang.Nullable;
* @see StandardTypeConverter
* @see DataBindingPropertyAccessor
*/
public class SimpleEvaluationContext implements EvaluationContext {
public final class SimpleEvaluationContext implements EvaluationContext {
private static final TypeLocator typeNotFoundTypeLocator = typeName -> {
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);