diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java index 2586ef6b427..9a4da458dee 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java @@ -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. @@ -47,7 +47,7 @@ public final class ParserContext { @Nullable private BeanDefinition containingBeanDefinition; - private final Deque containingComponents = new ArrayDeque<>(); + private final Deque containingComponents = new ArrayDeque<>(); public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate) { @@ -96,8 +96,7 @@ public final class ParserContext { @Nullable public CompositeComponentDefinition getContainingComponent() { - return (!this.containingComponents.isEmpty() ? - (CompositeComponentDefinition) this.containingComponents.getLast() : null); + return this.containingComponents.peek(); } public void pushContainingComponent(CompositeComponentDefinition containingComponent) { @@ -105,7 +104,7 @@ public final class ParserContext { } public CompositeComponentDefinition popContainingComponent() { - return (CompositeComponentDefinition) this.containingComponents.pop(); + return this.containingComponents.pop(); } public void popAndRegisterContainingComponent() { diff --git a/spring-context/src/main/java/org/springframework/validation/AbstractErrors.java b/spring-context/src/main/java/org/springframework/validation/AbstractErrors.java index b791889d40e..2a165707699 100644 --- a/spring-context/src/main/java/org/springframework/validation/AbstractErrors.java +++ b/spring-context/src/main/java/org/springframework/validation/AbstractErrors.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -20,9 +20,9 @@ import java.io.Serializable; import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; -import java.util.EmptyStackException; import java.util.LinkedList; import java.util.List; +import java.util.NoSuchElementException; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; @@ -62,12 +62,12 @@ public abstract class AbstractErrors implements Errors, Serializable { } @Override - public void popNestedPath() throws IllegalArgumentException { + public void popNestedPath() throws IllegalStateException { try { String formerNestedPath = this.nestedPathStack.pop(); doSetNestedPath(formerNestedPath); } - catch (EmptyStackException ex) { + catch (NoSuchElementException ex) { throw new IllegalStateException("Cannot pop nested path: no nested path on stack"); } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java b/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java index 4c930b38570..3f244d41427 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java @@ -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. @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.expression.EvaluationContext; @@ -49,6 +50,7 @@ import org.springframework.util.CollectionUtils; * nodes might need. * * @author Andy Clement + * @author Juergen Hoeller * @since 3.0 */ public class ExpressionState { @@ -118,7 +120,12 @@ public class ExpressionState { if (this.contextObjects == null) { this.contextObjects = new ArrayDeque<>(); } - this.contextObjects.pop(); + try { + this.contextObjects.pop(); + } + catch (NoSuchElementException ex) { + throw new IllegalStateException("Cannot pop active context object: stack is empty"); + } } public TypedValue getRootContextObject() { @@ -197,9 +204,7 @@ public class ExpressionState { @Nullable public Object lookupLocalVariable(String name) { - int scopeNumber = initVariableScopes().size() - 1; - for (int i = scopeNumber; i >= 0; i--) { - VariableScope scope = initVariableScopes().get(i); + for (VariableScope scope : initVariableScopes()) { if (scope.definesVariable(name)) { return scope.lookupVariable(name); } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java index dee3a0074a2..0bd8828b98d 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -16,7 +16,6 @@ package org.springframework.expression.spel; -import java.util.EmptyStackException; import java.util.HashMap; import java.util.Map; @@ -36,6 +35,7 @@ import static org.junit.Assert.*; * Tests for the expression state object - some features are not yet exploited in the language (eg nested scopes) * * @author Andy Clement + * @author Juergen Hoeller */ public class ExpressionStateTests extends AbstractExpressionTests { @@ -43,7 +43,7 @@ public class ExpressionStateTests extends AbstractExpressionTests { public void testConstruction() { EvaluationContext context = TestScenarioCreator.getTestEvaluationContext(); ExpressionState state = new ExpressionState(context); - assertEquals(context,state.getEvaluationContext()); + assertEquals(context, state.getEvaluationContext()); } // Local variables are in variable scopes which come and go during evaluation. Normal variables are @@ -58,107 +58,107 @@ public class ExpressionStateTests extends AbstractExpressionTests { state.setLocalVariable("foo",34); value = state.lookupLocalVariable("foo"); - assertEquals(34,value); + assertEquals(34, value); - state.setLocalVariable("foo",null); + state.setLocalVariable("foo", null); value = state.lookupLocalVariable("foo"); - assertEquals(null,value); + assertEquals(null, value); } @Test public void testVariables() { ExpressionState state = getState(); TypedValue typedValue = state.lookupVariable("foo"); - assertEquals(TypedValue.NULL,typedValue); + assertEquals(TypedValue.NULL, typedValue); state.setVariable("foo",34); typedValue = state.lookupVariable("foo"); - assertEquals(34,typedValue.getValue()); - assertEquals(Integer.class,typedValue.getTypeDescriptor().getType()); + assertEquals(34, typedValue.getValue()); + assertEquals(Integer.class, typedValue.getTypeDescriptor().getType()); state.setVariable("foo","abc"); typedValue = state.lookupVariable("foo"); - assertEquals("abc",typedValue.getValue()); - assertEquals(String.class,typedValue.getTypeDescriptor().getType()); + assertEquals("abc", typedValue.getValue()); + assertEquals(String.class, typedValue.getTypeDescriptor().getType()); } @Test public void testNoVariableInteference() { ExpressionState state = getState(); TypedValue typedValue = state.lookupVariable("foo"); - assertEquals(TypedValue.NULL,typedValue); + assertEquals(TypedValue.NULL, typedValue); state.setLocalVariable("foo",34); typedValue = state.lookupVariable("foo"); - assertEquals(TypedValue.NULL,typedValue); + assertEquals(TypedValue.NULL, typedValue); - state.setVariable("goo","hello"); + state.setVariable("goo", "hello"); assertNull(state.lookupLocalVariable("goo")); } @Test public void testLocalVariableNestedScopes() { ExpressionState state = getState(); - assertEquals(null,state.lookupLocalVariable("foo")); + assertEquals(null, state.lookupLocalVariable("foo")); state.setLocalVariable("foo",12); - assertEquals(12,state.lookupLocalVariable("foo")); + assertEquals(12, state.lookupLocalVariable("foo")); state.enterScope(null); - assertEquals(12,state.lookupLocalVariable("foo")); // found in upper scope + assertEquals(12, state.lookupLocalVariable("foo")); // found in upper scope state.setLocalVariable("foo","abc"); - assertEquals("abc",state.lookupLocalVariable("foo")); // found in nested scope + assertEquals("abc", state.lookupLocalVariable("foo")); // found in nested scope state.exitScope(); - assertEquals(12,state.lookupLocalVariable("foo")); // found in nested scope + assertEquals(12, state.lookupLocalVariable("foo")); // found in nested scope } @Test public void testRootContextObject() { ExpressionState state = getState(); - assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass()); + assertEquals(Inventor.class, state.getRootContextObject().getValue().getClass()); // although the root object is being set on the evaluation context, the value in the 'state' remains what it was when constructed ((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null); - assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass()); + assertEquals(Inventor.class, state.getRootContextObject().getValue().getClass()); // assertEquals(null, state.getRootContextObject().getValue()); state = new ExpressionState(new StandardEvaluationContext()); - assertEquals(TypedValue.NULL,state.getRootContextObject()); + assertEquals(TypedValue.NULL, state.getRootContextObject()); - ((StandardEvaluationContext)state.getEvaluationContext()).setRootObject(null); - assertEquals(null,state.getRootContextObject().getValue()); + ((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null); + assertEquals(null, state.getRootContextObject().getValue()); } @Test public void testActiveContextObject() { ExpressionState state = getState(); - assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue()); + assertEquals(state.getRootContextObject().getValue(), state.getActiveContextObject().getValue()); try { state.popActiveContextObject(); fail("stack should be empty..."); } - catch (EmptyStackException ese) { + catch (IllegalStateException ese) { // success } state.pushActiveContextObject(new TypedValue(34)); - assertEquals(34,state.getActiveContextObject().getValue()); + assertEquals(34, state.getActiveContextObject().getValue()); state.pushActiveContextObject(new TypedValue("hello")); - assertEquals("hello",state.getActiveContextObject().getValue()); + assertEquals("hello", state.getActiveContextObject().getValue()); state.popActiveContextObject(); - assertEquals(34,state.getActiveContextObject().getValue()); + assertEquals(34, state.getActiveContextObject().getValue()); state.popActiveContextObject(); - assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue()); + assertEquals(state.getRootContextObject().getValue(), state.getActiveContextObject().getValue()); state = new ExpressionState(new StandardEvaluationContext()); - assertEquals(TypedValue.NULL,state.getActiveContextObject()); + assertEquals(TypedValue.NULL, state.getActiveContextObject()); } @Test @@ -167,14 +167,14 @@ public class ExpressionStateTests extends AbstractExpressionTests { assertNull(state.lookupLocalVariable("foo")); state.enterScope("foo",34); - assertEquals(34,state.lookupLocalVariable("foo")); + assertEquals(34, state.lookupLocalVariable("foo")); state.enterScope(null); - state.setLocalVariable("foo",12); - assertEquals(12,state.lookupLocalVariable("foo")); + state.setLocalVariable("foo", 12); + assertEquals(12, state.lookupLocalVariable("foo")); state.exitScope(); - assertEquals(34,state.lookupLocalVariable("foo")); + assertEquals(34, state.lookupLocalVariable("foo")); state.exitScope(); assertNull(state.lookupLocalVariable("goo")); @@ -187,8 +187,8 @@ public class ExpressionStateTests extends AbstractExpressionTests { // supplied should override root on context ExpressionState state = new ExpressionState(ctx,new TypedValue("i am a string")); TypedValue stateRoot = state.getRootContextObject(); - assertEquals(String.class,stateRoot.getTypeDescriptor().getType()); - assertEquals("i am a string",stateRoot.getValue()); + assertEquals(String.class, stateRoot.getTypeDescriptor().getType()); + assertEquals("i am a string", stateRoot.getValue()); } @Test @@ -198,17 +198,17 @@ public class ExpressionStateTests extends AbstractExpressionTests { assertNull(state.lookupLocalVariable("goo")); Map m = new HashMap<>(); - m.put("foo",34); - m.put("goo","abc"); + m.put("foo", 34); + m.put("goo", "abc"); state.enterScope(m); - assertEquals(34,state.lookupLocalVariable("foo")); - assertEquals("abc",state.lookupLocalVariable("goo")); + assertEquals(34, state.lookupLocalVariable("foo")); + assertEquals("abc", state.lookupLocalVariable("goo")); state.enterScope(null); state.setLocalVariable("foo",12); - assertEquals(12,state.lookupLocalVariable("foo")); - assertEquals("abc",state.lookupLocalVariable("goo")); + assertEquals(12, state.lookupLocalVariable("foo")); + assertEquals("abc", state.lookupLocalVariable("goo")); state.exitScope(); state.exitScope(); @@ -217,7 +217,7 @@ public class ExpressionStateTests extends AbstractExpressionTests { } @Test - public void testOperators() throws Exception { + public void testOperators() { ExpressionState state = getState(); try { state.operate(Operation.ADD,1,2); @@ -225,7 +225,7 @@ public class ExpressionStateTests extends AbstractExpressionTests { } catch (EvaluationException ee) { SpelEvaluationException sEx = (SpelEvaluationException)ee; - assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageCode()); + assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, sEx.getMessageCode()); } try { @@ -234,28 +234,28 @@ public class ExpressionStateTests extends AbstractExpressionTests { } catch (EvaluationException ee) { SpelEvaluationException sEx = (SpelEvaluationException)ee; - assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageCode()); + assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, sEx.getMessageCode()); } } @Test public void testComparator() { ExpressionState state = getState(); - assertEquals(state.getEvaluationContext().getTypeComparator(),state.getTypeComparator()); + assertEquals(state.getEvaluationContext().getTypeComparator(), state.getTypeComparator()); } @Test public void testTypeLocator() throws EvaluationException { ExpressionState state = getState(); assertNotNull(state.getEvaluationContext().getTypeLocator()); - assertEquals(Integer.class,state.findType("java.lang.Integer")); + assertEquals(Integer.class, state.findType("java.lang.Integer")); try { state.findType("someMadeUpName"); fail("Should have failed to find it"); } catch (EvaluationException ee) { SpelEvaluationException sEx = (SpelEvaluationException)ee; - assertEquals(SpelMessage.TYPE_NOT_FOUND,sEx.getMessageCode()); + assertEquals(SpelMessage.TYPE_NOT_FOUND, sEx.getMessageCode()); } } @@ -263,16 +263,16 @@ public class ExpressionStateTests extends AbstractExpressionTests { public void testTypeConversion() throws EvaluationException { ExpressionState state = getState(); String s = (String) state.convertValue(34, TypeDescriptor.valueOf(String.class)); - assertEquals("34",s); + assertEquals("34", s); s = (String)state.convertValue(new TypedValue(34), TypeDescriptor.valueOf(String.class)); - assertEquals("34",s); + assertEquals("34", s); } @Test public void testPropertyAccessors() { ExpressionState state = getState(); - assertEquals(state.getEvaluationContext().getPropertyAccessors(),state.getPropertyAccessors()); + assertEquals(state.getEvaluationContext().getPropertyAccessors(), state.getPropertyAccessors()); } /**