diff --git a/src/main/java/org/springframework/data/gemfire/ExpirationActionType.java b/src/main/java/org/springframework/data/gemfire/ExpirationActionType.java new file mode 100644 index 00000000..db6b7953 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/ExpirationActionType.java @@ -0,0 +1,94 @@ +/* + * Copyright 2010-2013 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 org.springframework.data.gemfire; + +import com.gemstone.gemfire.cache.ExpirationAction; + +/** + * The ExpirationActionType enum is a enumeration of GemFire Expiration Actions on expired Cache Region entries. + * + * @author John Blum + * @see com.gemstone.gemfire.cache.ExpirationAction + * @since 1.6.0 + */ +@SuppressWarnings("unused") +public enum ExpirationActionType { + DESTROY(ExpirationAction.DESTROY), + INVALIDATE(ExpirationAction.INVALIDATE), + LOCAL_DESTROY(ExpirationAction.LOCAL_DESTROY), + LOCAL_INVALIDATE(ExpirationAction.LOCAL_INVALIDATE); + + private final ExpirationAction expirationAction; + + /** + * Constructs an instance of the ExpirationActionType enum initialized with the corresponding GemFire + * ExpirationAction value. + * + * @param expirationAction the GemFire ExpirationAction value. + * @see com.gemstone.gemfire.cache.ExpirationAction + */ + ExpirationActionType(final ExpirationAction expirationAction) { + this.expirationAction = expirationAction; + } + + /** + * Returns the corresponding SDG ExpirationActionType enumerated value given a GemFire ExpirationAction. + * + * @param expirationAction the GemFire ExpirationAction instance used to determine the ExpirationActionType. + * @return a ExpirationActionType enumerated value given a GemFire ExpirationAction. + * @see com.gemstone.gemfire.cache.ExpirationAction + * @see #getExpirationAction() + */ + public static ExpirationActionType valueOf(final ExpirationAction expirationAction) { + for (ExpirationActionType expirationActionType : values()) { + if (expirationActionType.getExpirationAction().equals(expirationAction)) { + return expirationActionType; + } + } + + return null; + } + + /** + * Returns an ExpirationActionType for the given String value describing the enumerated value. + * + * @param value a String value describing the desired ExpirationActionType that is returned. + * @return an ExpirationActionType for the given String. + * @see java.lang.Enum#name() + * @see java.lang.String#equalsIgnoreCase(String) + */ + public static ExpirationActionType valueOfIgnoreCase(final String value) { + for (ExpirationActionType expirationActionType : values()) { + if (expirationActionType.name().equalsIgnoreCase(value)) { + return expirationActionType; + } + } + + return null; + } + + /** + * Gets the corresponding GemFire ExpirationAction for this enumerated value. + * + * @return a GemFire ExpirationAction instance corresponding to this enumerated value. + * @see com.gemstone.gemfire.cache.ExpirationAction + */ + public ExpirationAction getExpirationAction() { + return expirationAction; + } + +} diff --git a/src/main/java/org/springframework/data/gemfire/ExpirationActionTypeConverter.java b/src/main/java/org/springframework/data/gemfire/ExpirationActionTypeConverter.java new file mode 100644 index 00000000..b95609c6 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/ExpirationActionTypeConverter.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2013 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 org.springframework.data.gemfire; + +import java.beans.PropertyEditorSupport; + +import org.springframework.core.convert.converter.Converter; + +/** + * The ExpirationActionTypeConverter class is a Spring Converter used to convert a String value into + * a corresponding ExpirationActionType enumerated value. + * + * @author John Blum + * @see java.beans.PropertyEditorSupport + * @see org.springframework.core.convert.converter.Converter + * @see org.springframework.data.gemfire.ExpirationActionType + * @since 1.6.0 + */ +public class ExpirationActionTypeConverter extends PropertyEditorSupport implements Converter { + + /* non-Javadoc */ + private ExpirationActionType assertConverted(final String source, final ExpirationActionType expirationActionType) { + if (expirationActionType == null) { + throw new IllegalArgumentException(String.format("Source (%1$s) is not a valid ExpirationActionType!", + source)); + } + + return expirationActionType; + } + + /** + * Sets the ExpirationActionType by parsing a given String. May raise a java.lang.IllegalArgumentException + * if either the String is badly formatted or the text cannot be expressed as a ExpirationActionType. + * + * @param text the String value to express as (convert to) a ExpirationActionType. + * @throws java.lang.IllegalArgumentException if the String value does not represent a valid ExpirationActionType. + * @see #convert(String) + * @see #setValue(Object) + */ + @Override + public void setAsText(final String text) throws IllegalArgumentException { + setValue(convert(text)); + } + + /** + * Converts the given String value into an appropriate ExpirationActionType. + * + * @param source the String value to convert into an ExpirationActionType. + * @return an ExpirationActionType for the given String value. + * @throws java.lang.IllegalArgumentException if the String value does not represent a valid ExpirationActionType. + * @see org.springframework.data.gemfire.ExpirationActionType#valueOfIgnoreCase(String) + */ + @Override + public ExpirationActionType convert(final String source) { + return assertConverted(source, ExpirationActionType.valueOfIgnoreCase(source)); + } + +} diff --git a/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java b/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java index 3c6cb109..0061448f 100644 --- a/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java +++ b/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java @@ -27,6 +27,8 @@ import org.springframework.beans.factory.xml.ParserContext; import org.springframework.core.Conventions; import org.springframework.data.gemfire.EvictionAttributesFactoryBean; import org.springframework.data.gemfire.EvictionType; +import org.springframework.data.gemfire.ExpirationActionType; +import org.springframework.data.gemfire.ExpirationActionTypeConverter; import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.SubscriptionAttributesFactoryBean; import org.springframework.data.gemfire.SubscriptionType; @@ -290,6 +292,7 @@ abstract class ParsingUtils { // turn on statistics regionAttributesBuilder.addPropertyValue("statisticsEnabled", Boolean.TRUE); } + return result; } @@ -380,24 +383,13 @@ abstract class ParsingUtils { if (expirationElement != null) { String timeoutAttribute = expirationElement.getAttribute("timeout"); - String expirationTimeout = (StringUtils.hasText(timeoutAttribute) ? timeoutAttribute : null); + String expirationTimeout = (StringUtils.hasText(timeoutAttribute) ? timeoutAttribute : "0"); String actionAttribute = StringUtils.trimAllWhitespace(expirationElement.getAttribute("action")); - ExpirationAction expirationAction; - // TODO refactor this using an Enum and ExpirationActionConverter! - if ("DESTROY".equalsIgnoreCase(actionAttribute)) { - expirationAction = ExpirationAction.DESTROY; - } - else if ("LOCAL_DESTROY".equalsIgnoreCase(actionAttribute)) { - expirationAction = ExpirationAction.LOCAL_DESTROY; - } - else if ("LOCAL_INVALIDATE".equalsIgnoreCase(actionAttribute)) { - expirationAction = ExpirationAction.LOCAL_INVALIDATE; - } - else { - expirationAction = ExpirationAction.INVALIDATE; - } + ExpirationActionType expirationActionType = new ExpirationActionTypeConverter().convert(actionAttribute); + ExpirationAction expirationAction = (expirationActionType != null + ? expirationActionType.getExpirationAction() : ExpirationAction.INVALIDATE); BeanDefinitionBuilder expirationAttributes = BeanDefinitionBuilder.genericBeanDefinition( ExpirationAttributes.class); diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd index 3a47dc58..94d5baad 100644 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd @@ -1553,43 +1553,18 @@ Defines a template for creating multiple GemFire Local Regions that all share a - - - - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeConverterTest.java b/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeConverterTest.java new file mode 100644 index 00000000..671dfae3 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeConverterTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2013 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 org.springframework.data.gemfire; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Test; + +/** + * The ExpirationActionTypeConverterTest class is a test suite of test cases testing the contract and functionality + * of the ExpirationActionTypeConverter class. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.ExpirationActionTypeConverter + * @since 1.6.0 + */ +public class ExpirationActionTypeConverterTest { + + private final ExpirationActionTypeConverter converter = new ExpirationActionTypeConverter(); + + @After + public void tearDown() { + converter.setValue(null); + } + + @Test + public void testConvert() { + assertEquals(ExpirationActionType.DESTROY, converter.convert("destroy")); + assertEquals(ExpirationActionType.INVALIDATE, converter.convert("InvalidAte")); + assertEquals(ExpirationActionType.LOCAL_DESTROY, converter.convert("LOCAL_dEsTrOy")); + assertEquals(ExpirationActionType.LOCAL_INVALIDATE, converter.convert("Local_Invalidate")); + } + + @Test(expected = IllegalArgumentException.class) + public void testConvertThrowsIllegalArgumentException() { + try { + converter.convert("blow_up"); + } + catch (IllegalArgumentException expected) { + assertEquals("Source (blow_up) is not a valid ExpirationActionType!", expected.getMessage()); + throw expected; + } + } + + @Test + public void testSetAsText() { + converter.setAsText("InValidAte"); + assertEquals(ExpirationActionType.INVALIDATE, converter.getValue()); + converter.setAsText("Local_Destroy"); + assertEquals(ExpirationActionType.LOCAL_DESTROY, converter.getValue()); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetAsTextThrowsIllegalArgumentException() { + try { + converter.setAsText("destruction"); + } + catch (IllegalArgumentException expected) { + assertEquals("Source (destruction) is not a valid ExpirationActionType!", expected.getMessage()); + throw expected; + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeTest.java b/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeTest.java new file mode 100644 index 00000000..681624e8 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/ExpirationActionTypeTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2013 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 org.springframework.data.gemfire; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import com.gemstone.gemfire.cache.ExpirationAction; + +/** + * The ExpirationActionTypeTest class is a test suite of test cases testing the contract and functionality + * of the ExpirationActionType enum. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.ExpirationActionType + * @since 1.6.0 + */ +public class ExpirationActionTypeTest { + + @Test + public void testValueOf() { + assertEquals(ExpirationActionType.DESTROY, ExpirationActionType.valueOf(ExpirationAction.DESTROY)); + assertEquals(ExpirationActionType.INVALIDATE, ExpirationActionType.valueOf(ExpirationAction.INVALIDATE)); + assertEquals(ExpirationActionType.LOCAL_DESTROY, ExpirationActionType.valueOf(ExpirationAction.LOCAL_DESTROY)); + assertEquals(ExpirationActionType.LOCAL_INVALIDATE, ExpirationActionType.valueOf(ExpirationAction.LOCAL_INVALIDATE)); + + } + + @Test + public void testValueOfExpirationActionOrdinalValues() { + try { + for (int ordinal = 0; ordinal < Integer.MAX_VALUE; ordinal++) { + assertNotNull(ExpirationActionType.valueOf(ExpirationAction.fromOrdinal(ordinal))); + } + } + catch (ArrayIndexOutOfBoundsException ignore) { + } + } + + @Test + public void testValueOfIgnoreCase() { + assertEquals(ExpirationActionType.DESTROY, ExpirationActionType.valueOfIgnoreCase("destroy")); + assertEquals(ExpirationActionType.INVALIDATE, ExpirationActionType.valueOfIgnoreCase("Invalidate")); + assertEquals(ExpirationActionType.LOCAL_DESTROY, ExpirationActionType.valueOfIgnoreCase("LOCAL_DESTROY")); + assertEquals(ExpirationActionType.LOCAL_INVALIDATE, ExpirationActionType.valueOfIgnoreCase("Local_Invalidate")); + } + + @Test + public void testValueOfIgnoreCaseWithInvalidStringValues() { + assertNull(ExpirationActionType.valueOfIgnoreCase("Invalid")); + assertNull(ExpirationActionType.valueOfIgnoreCase("local destroy")); + } + +}