diff --git a/src/main/java/org/springframework/data/gemfire/config/AbstractRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/AbstractRegionParser.java index 7ab3d2b5..77e8926d 100644 --- a/src/main/java/org/springframework/data/gemfire/config/AbstractRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/AbstractRegionParser.java @@ -73,8 +73,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { super.doParse(element, builder); builder.setAbstract(isRegionTemplate(element)); - boolean subRegion = isSubRegion(element); - doParseRegion(element, parserContext, builder, subRegion); + doParseRegion(element, parserContext, builder, isSubRegion(element)); } protected abstract void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, @@ -117,7 +116,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { // Factory will enable gateway if it is not set and hub-id is set. if (StringUtils.hasText(enableGateway)) { if (GemfireUtils.isGemfireVersion7OrAbove()) { - log.warn("'enable-gateway' is deprecated since Gemfire 7.0"); + log.warn("'enable-gateway' has been deprecated since Gemfire 7.0"); } } @@ -125,11 +124,11 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { if (StringUtils.hasText(hubId)) { if (GemfireUtils.isGemfireVersion7OrAbove()) { - log.warn("'hub-id' is deprecated since Gemfire 7.0"); + log.warn("'hub-id' has been deprecated since Gemfire 7.0"); } if (!CollectionUtils.isEmpty(DomUtils.getChildElementsByTagName(element, "gateway-sender"))) { - parserContext.getReaderContext().error("It is invalid to specify both 'hub-id' and 'gateway-sender'", - element); + parserContext.getReaderContext().error("specifying both 'hub-id' and 'gateway-sender' is invalid", + element); } } 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 a3096015..30dca6ad 100644 --- a/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java +++ b/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java @@ -20,6 +20,8 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; @@ -49,36 +51,61 @@ abstract class ParsingUtils { private static final Log log = LogFactory.getLog(ParsingUtils.class); - static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName, - String propertyName, Object defaultValue) { - String attr = element.getAttribute(attributeName); - if (StringUtils.hasText(attr)) { - builder.addPropertyValue(propertyName, attr); - } else { - if (defaultValue != null) { - builder.addPropertyValue(propertyName, defaultValue); - } + static void setPropertyReference(Element element, BeanDefinitionBuilder builder, String attributeName, + String propertyName) { + + String attributeValue = element.getAttribute(attributeName); + + if (StringUtils.hasText(attributeValue)) { + builder.addPropertyReference(propertyName, attributeValue); } } - + + @SuppressWarnings("unused") + static void setPropertyReference(Element element, BeanDefinitionBuilder builder, String attributeName) { + setPropertyReference(element, builder, attributeName, Conventions.attributeNameToPropertyName(attributeName)); + } + + static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName, + String propertyName, Object defaultValue) { + + String attributeValue = element.getAttribute(attributeName); + + if (StringUtils.hasText(attributeValue)) { + builder.addPropertyValue(propertyName, attributeValue); + } + else if (defaultValue != null) { + builder.addPropertyValue(propertyName, defaultValue); + } + } + static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName, String propertyName) { - setPropertyValue(element, builder, attributeName, propertyName,null); + setPropertyValue(element, builder, attributeName, propertyName, null); } - static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName) { setPropertyValue(element, builder, attributeName, Conventions.attributeNameToPropertyName(attributeName)); } - static void setPropertyReference(Element element, BeanDefinitionBuilder builder, String attrName, - String propertyName) { - String attr = element.getAttribute(attrName); - if (StringUtils.hasText(attr)) { - builder.addPropertyReference(propertyName, attr); + static void setPropertyValue(BeanDefinitionBuilder builder, BeanDefinition source, String propertyName, + boolean withDependsOn) { + + PropertyValue propertyValue = source.getPropertyValues().getPropertyValue(propertyName); + + if (propertyValue != null) { + builder.addPropertyValue(propertyValue.getName(), propertyValue.getValue()); + + if (withDependsOn && propertyValue.getValue() instanceof RuntimeBeanReference) { + builder.addDependsOn(((RuntimeBeanReference) propertyValue.getValue()).getBeanName()); + } } } + static void setPropertyValue(BeanDefinitionBuilder builder, BeanDefinition source, String propertyName) { + setPropertyValue(builder, source, propertyName, false); + } + /** * Utility method handling parsing of nested definition of the type: * @@ -125,12 +152,8 @@ abstract class ParsingUtils { static Object parseRefOrNestedCustomElement(ParserContext parserContext, Element element, BeanDefinitionBuilder builder) { Object beanRef = ParsingUtils.getBeanReference(parserContext, element, "bean"); - if (beanRef != null) { - return beanRef; - } - else { - return parserContext.getDelegate().parseCustomElement(element, builder.getBeanDefinition()); - } + return (beanRef != null ? beanRef : parserContext.getDelegate().parseCustomElement( + element, builder.getBeanDefinition())); } static Object parseRefOrSingleNestedBeanDeclaration(ParserContext parserContext, Element element, @@ -297,10 +320,6 @@ abstract class ParsingUtils { static void parseOptionalRegionAttributes(ParserContext parserContext, Element element, BeanDefinitionBuilder regionAttributesBuilder) { - if (!("partitioned-region".equals(element.getLocalName()))) { - setPropertyValue(element, regionAttributesBuilder, "persistent", "persistBackup"); - } - setPropertyValue(element, regionAttributesBuilder, "cloning-enabled"); setPropertyValue(element, regionAttributesBuilder, "concurrency-level"); setPropertyValue(element, regionAttributesBuilder, "disk-synchronous"); @@ -325,11 +344,11 @@ abstract class ParsingUtils { String concurrencyChecksEnabled = element.getAttribute("concurrency-checks-enabled"); if (StringUtils.hasText(concurrencyChecksEnabled)) { - if (!GemfireUtils.isGemfireVersion7OrAbove()) { - log.warn("Setting 'concurrency-checks-enabled' is only available in Gemfire 7.0 or above"); + if (GemfireUtils.isGemfireVersion7OrAbove()) { + ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "concurrency-checks-enabled"); } else { - ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "concurrency-checks-enabled"); + log.warn("Setting 'concurrency-checks-enabled' is only available in Gemfire 7.0 or above!"); } } } diff --git a/src/main/java/org/springframework/data/gemfire/config/PartitionedRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/PartitionedRegionParser.java index 32b5a26e..0c0074b6 100644 --- a/src/main/java/org/springframework/data/gemfire/config/PartitionedRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/PartitionedRegionParser.java @@ -58,7 +58,7 @@ class PartitionedRegionParser extends AbstractRegionParser { BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( RegionAttributesFactoryBean.class); - super.doParseCommonRegionConfiguration(element, parserContext, regionBuilder, regionAttributesBuilder, subRegion); + doParseCommonRegionConfiguration(element, parserContext, regionBuilder, regionAttributesBuilder, subRegion); regionBuilder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition()); diff --git a/src/main/java/org/springframework/data/gemfire/config/ReplicatedRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/ReplicatedRegionParser.java index 11b21a6a..83115245 100644 --- a/src/main/java/org/springframework/data/gemfire/config/ReplicatedRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/ReplicatedRegionParser.java @@ -47,7 +47,7 @@ class ReplicatedRegionParser extends AbstractRegionParser { BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( RegionAttributesFactoryBean.class); - super.doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesBuilder, subRegion); + doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesBuilder, subRegion); builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition()); } diff --git a/src/test/java/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest.java new file mode 100644 index 00000000..8490f2a5 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest.java @@ -0,0 +1,112 @@ +/* + * 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.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import javax.annotation.Resource; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; +import org.springframework.data.gemfire.test.support.FileSystemUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.DiskStore; +import com.gemstone.gemfire.cache.EntryOperation; +import com.gemstone.gemfire.cache.EvictionAction; +import com.gemstone.gemfire.cache.EvictionAlgorithm; +import com.gemstone.gemfire.cache.PartitionResolver; +import com.gemstone.gemfire.cache.Region; + +/** + * The PersistentPartitionRegionTemplateTest class is a test suite of test cases testing the functionality of + * Spring Data GemFire's Region templates with a 'persistent', PARTITION Region configuration. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.PartitionedRegionFactoryBean + * @see com.gemstone.gemfire.cache.Region + * @link https://jira.spring.io/browse/SGF-384 + * @since 1.6.0 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(initializers = GemfireTestApplicationContextInitializer.class) +@SuppressWarnings("unused") +public class TemplatePersistentPartitionRegionNamespaceTest { + + @Autowired + private DiskStore exampleDataStore; + + @Resource(name = "Example") + private Region example; + + @After + public void tearDown() { + for (File diskDirectory : exampleDataStore.getDiskDirs()) { + FileSystemUtils.deleteRecursive(FileSystemUtils.getRootRelativeToWorkingDirectoryOrPath( + diskDirectory.getAbsoluteFile())); + } + } + + @Test + public void testExampleTemplatedPersistentPartitionRegion() { + assertNotNull("The '/Example' PARTITION Region was not properly configured and initialized!", example); + assertEquals("Example", example.getName()); + assertEquals("/Example", example.getFullPath()); + assertNotNull(example.getAttributes()); + assertEquals(DataPolicy.PERSISTENT_PARTITION, example.getAttributes().getDataPolicy()); + assertNotNull(example.getAttributes().getEvictionAttributes()); + assertEquals(EvictionAlgorithm.LRU_HEAP, example.getAttributes().getEvictionAttributes().getAlgorithm()); + assertEquals(EvictionAction.OVERFLOW_TO_DISK, example.getAttributes().getEvictionAttributes().getAction()); + assertNotNull(example.getAttributes().getPartitionAttributes()); + assertEquals(1, example.getAttributes().getPartitionAttributes().getRedundantCopies()); + assertEquals(163, example.getAttributes().getPartitionAttributes().getTotalNumBuckets()); + assertNotNull(example.getAttributes().getPartitionAttributes().getPartitionResolver()); + assertEquals("TestPartitionResolver", example.getAttributes().getPartitionAttributes().getPartitionResolver().getName()); + } + + public static final class TestPartitionResolver implements PartitionResolver { + + private String name; + + @Override + public Object getRoutingObject(final EntryOperation kvEntryOperation) { + throw new UnsupportedOperationException("Not Implemented!"); + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public void close() { + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests.java b/src/test/java/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests.java index 17b47f0c..4895b34c 100644 --- a/src/test/java/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests.java @@ -101,6 +101,9 @@ public class TemplateRegionsNamespaceTests { @Resource(name = "/TemplateBasedReplicateRegion/TemplateBasedReplicateSubRegion") private Region templateBasedReplicateSubRegion; + @Resource(name = "TemplateBasedReplicateRegionNoOverrides") + private Region templateBasedReplicateRegionNoOverrides; + @Resource(name = "TemplateBasedPartitionRegion") private Region templateBasedPartitionRegion; @@ -234,7 +237,7 @@ public class TemplateRegionsNamespaceTests { protected void assertDefaultRegionAttributes(final Region region) { assertNotNull("The Region must not be null!", region); - assertNotNull(String.format("The Region (%1$s) must have 'RegionAttributes' defined!", + assertNotNull(String.format("Region (%1$s) must have 'RegionAttributes' defined!", region.getFullPath()), region.getAttributes()); assertNull(region.getAttributes().getCustomEntryIdleTimeout()); assertNull(region.getAttributes().getCustomEntryTimeToLive()); @@ -249,7 +252,7 @@ public class TemplateRegionsNamespaceTests { protected void assertDefaultSubscriptionAttributes(final SubscriptionAttributes subscriptionAttributes) { assumeNotNull(subscriptionAttributes); - assertSubscriptionAttributes(subscriptionAttributes, InterestPolicy.CACHE_CONTENT); + assertSubscriptionAttributes(subscriptionAttributes, InterestPolicy.DEFAULT); } protected void assertSubscriptionAttributes(final SubscriptionAttributes subscriptionAttributes, @@ -317,7 +320,7 @@ public class TemplateRegionsNamespaceTests { assertEmpty(nonTemplateBasedReplicateRegion.getAttributes().getAsyncEventQueueIds()); assertEmpty(nonTemplateBasedReplicateRegion.getAttributes().getCacheListeners()); assertCacheLoader(nonTemplateBasedReplicateRegion, "ABC"); - assertNull(nonTemplateBasedReplicateRegion.getAttributes().getCacheWriter()); + assertCacheWriter(nonTemplateBasedReplicateRegion, "DEF"); assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getCloningEnabled()); assertTrue(nonTemplateBasedReplicateRegion.getAttributes().getConcurrencyChecksEnabled()); assertEquals(12, nonTemplateBasedReplicateRegion.getAttributes().getConcurrencyLevel()); @@ -350,9 +353,9 @@ public class TemplateRegionsNamespaceTests { assertEmpty(templateBasedReplicateRegion.getAttributes().getAsyncEventQueueIds()); assertCacheListeners(templateBasedReplicateRegion, "XYZ"); assertCacheLoader(templateBasedReplicateRegion, "dbLoader"); - assertNull(templateBasedReplicateRegion.getAttributes().getCacheWriter()); + assertCacheWriter(templateBasedReplicateRegion, "dbWriter"); assertTrue(templateBasedReplicateRegion.getAttributes().getCloningEnabled()); - assertFalse(templateBasedReplicateRegion.getAttributes().getConcurrencyChecksEnabled()); + assertTrue(templateBasedReplicateRegion.getAttributes().getConcurrencyChecksEnabled()); assertEquals(24, templateBasedReplicateRegion.getAttributes().getConcurrencyLevel()); assertEquals(DataPolicy.REPLICATE, templateBasedReplicateRegion.getAttributes().getDataPolicy()); assertFalse(templateBasedReplicateRegion.getAttributes().isDiskSynchronous()); @@ -385,7 +388,7 @@ public class TemplateRegionsNamespaceTests { assertRegionMetaData(templateBasedReplicateSubRegion, "TemplateBasedReplicateSubRegion", "/TemplateBasedReplicateRegion/TemplateBasedReplicateSubRegion"); assertDefaultRegionAttributes(templateBasedReplicateSubRegion); - assertAsyncEventQueues(templateBasedReplicateSubRegion, "TestAsyncEventQueue"); + assertEmpty(templateBasedReplicateSubRegion.getAttributes().getAsyncEventQueueIds()); assertCacheListeners(templateBasedReplicateSubRegion, "testListener"); assertCacheLoader(templateBasedReplicateSubRegion, "A"); assertCacheWriter(templateBasedReplicateSubRegion, "B"); @@ -401,7 +404,7 @@ public class TemplateRegionsNamespaceTests { ExpirationAction.DESTROY, 600); assertExpirationAttributes(templateBasedReplicateSubRegion.getAttributes().getEntryTimeToLive(), ExpirationAction.DESTROY, 600); - assertGatewaySenders(templateBasedReplicateSubRegion, "TestGatewaySender"); + assertEmpty(templateBasedReplicateSubRegion.getAttributes().getGatewaySenderIds()); assertTrue(templateBasedReplicateSubRegion.getAttributes().getIgnoreJTA()); assertFalse(templateBasedReplicateSubRegion.getAttributes().getIndexMaintenanceSynchronous()); assertEquals(51, templateBasedReplicateSubRegion.getAttributes().getInitialCapacity()); @@ -417,6 +420,43 @@ public class TemplateRegionsNamespaceTests { assertEquals(String.class, templateBasedReplicateSubRegion.getAttributes().getValueConstraint()); } + @Test + public void testTemplateBasedReplicateRegionNoOverrides() { + assertRegionMetaData(templateBasedReplicateRegionNoOverrides, "TemplateBasedReplicateRegionNoOverrides"); + assertDefaultRegionAttributes(templateBasedReplicateRegionNoOverrides); + assertEmpty(templateBasedReplicateRegionNoOverrides.getAttributes().getAsyncEventQueueIds()); + assertCacheListeners(templateBasedReplicateRegionNoOverrides, "XYZ"); + assertNull(templateBasedReplicateRegionNoOverrides.getAttributes().getCacheLoader()); + assertNull(templateBasedReplicateRegionNoOverrides.getAttributes().getCacheWriter()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getCloningEnabled()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getConcurrencyChecksEnabled()); + assertEquals(24, templateBasedReplicateRegionNoOverrides.getAttributes().getConcurrencyLevel()); + assertEquals(DataPolicy.PERSISTENT_REPLICATE, templateBasedReplicateRegionNoOverrides.getAttributes().getDataPolicy()); + assertFalse(templateBasedReplicateRegionNoOverrides.getAttributes().isDiskSynchronous()); + assertFalse(templateBasedReplicateRegionNoOverrides.getAttributes().getEnableAsyncConflation()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getEnableSubscriptionConflation()); + assertEvictionAttributes(templateBasedReplicateRegionNoOverrides.getAttributes().getEvictionAttributes(), + EvictionAction.OVERFLOW_TO_DISK, EvictionAlgorithm.LRU_ENTRY, 2024, null); + assertExpirationAttributes(templateBasedReplicateRegionNoOverrides.getAttributes().getEntryIdleTimeout(), + ExpirationAction.DESTROY, 600); + assertExpirationAttributes(templateBasedReplicateRegionNoOverrides.getAttributes().getEntryTimeToLive(), + ExpirationAction.INVALIDATE, 300); + assertEmpty(templateBasedReplicateRegionNoOverrides.getAttributes().getGatewaySenderIds()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getIgnoreJTA()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getIndexMaintenanceSynchronous()); + assertEquals(51, templateBasedReplicateRegionNoOverrides.getAttributes().getInitialCapacity()); + assertEquals(String.class, templateBasedReplicateRegionNoOverrides.getAttributes().getKeyConstraint()); + assertEquals(0.85f, templateBasedReplicateRegionNoOverrides.getAttributes().getLoadFactor(), 0.0f); + assertFalse(templateBasedReplicateRegionNoOverrides.getAttributes().isLockGrantor()); + assertDefaultMembershipAttributes(templateBasedReplicateRegionNoOverrides.getAttributes().getMembershipAttributes()); + assertNull(templateBasedReplicateRegionNoOverrides.getAttributes().getPartitionAttributes()); + assertEquals(Scope.DISTRIBUTED_ACK, templateBasedReplicateRegionNoOverrides.getAttributes().getScope()); + assertTrue(templateBasedReplicateRegionNoOverrides.getAttributes().getStatisticsEnabled()); + assertSubscriptionAttributes(templateBasedReplicateRegionNoOverrides.getAttributes().getSubscriptionAttributes(), + InterestPolicy.CACHE_CONTENT); + assertEquals(Object.class, templateBasedReplicateRegionNoOverrides.getAttributes().getValueConstraint()); + } + @Test public void testTemplateBasedPartitionRegion() { assertRegionMetaData(templateBasedPartitionRegion, "TemplateBasedPartitionRegion"); diff --git a/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java new file mode 100644 index 00000000..523b30a6 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java @@ -0,0 +1,108 @@ +/* + * 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.test.support; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.gemstone.gemfire.management.internal.cli.util.spring.Assert; + +/** + * The FileSystemUtils class is a utility class encapsulating functionality to process file system directories + * and files collectively. + * + * @author John Blum + * @see java.io.File + * @see java.io.FileFilter + * @see org.springframework.data.gemfire.test.support.FileUtils + * @see org.springframework.data.gemfire.test.support.IOUtils + * @since 1.5.0 + */ +@SuppressWarnings("unused") +public abstract class FileSystemUtils extends FileUtils { + + public static final File JAVA_HOME = new File(System.getProperty("java.home")); + public static final File USER_HOME = new File(System.getProperty("user.home")); + public static final File WORKING_DIRECTORY = new File(System.getProperty("user.dir")); + + public static boolean deleteRecursive(final File path) { + assert path != null; + + boolean success = true; + + if (path.isDirectory()) { + for (File file : safeListFiles(path)) { + success &= deleteRecursive(file); + } + } + + return (path.delete() && success); + } + + public static File getRootRelativeToWorkingDirectoryOrPath(final File path) { + File localPath = path; + + if (isDirectory(localPath)) { + while (localPath != null && !WORKING_DIRECTORY.equals(localPath.getParentFile())) { + localPath = localPath.getParentFile(); + } + } + + return (localPath != null ? localPath : path); + } + + public static File[] listFiles(final File directory, final FileFilter fileFilter) { + Assert.isTrue(directory != null && directory.isDirectory(), String.format( + "The File (%1$s) does not refer to a valid directory!", directory)); + + List results = new ArrayList(); + + for (File file : safeListFiles(directory, fileFilter)) { + if (file.isDirectory()) { + results.addAll(Arrays.asList(listFiles(file, fileFilter))); + } + else { + results.add(file); + } + } + + return results.toArray(new File[results.size()]); + } + + private static File[] safeListFiles(final File directory) { + return safeListFiles(directory, AllFiles.INSTANCE); + } + + private static File[] safeListFiles(final File directory, final FileFilter fileFilter) { + File[] files = (directory != null ? directory.listFiles(fileFilter) : new File[0]); + return (files != null ? files : new File[0]); + } + + public static final class AllFiles implements FileFilter { + + public static final AllFiles INSTANCE = new AllFiles(); + + @Override + public boolean accept(final File pathname) { + return true; + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java new file mode 100644 index 00000000..de1c970f --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.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.test.support; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.springframework.util.Assert; + +import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils; + +/** + * The FileUtils class is a utility class for processing files, working with java.io.File objects. + * + * @author John Blum + * @see java.io.File + * @see java.io.FileReader + * @see java.io.FileWriter + * @see org.springframework.data.gemfire.test.support.IOUtils + * @since 1.5.0 + */ +@SuppressWarnings("unused") +public abstract class FileUtils extends IOUtils { + + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + public static boolean isDirectory(final File path) { + return (path != null && path.isDirectory()); + } + + public static boolean isFile(final File path) { + return (path != null && path.isFile()); + } + + // TODO refactor and perhaps replace with org.springframework.util.FileCopyUtils.copyToString(:Reader) + public static String read(final File file) throws IOException { + Assert.isTrue(file != null && file.isFile(), String.format( + "The File reference (%1$s) from which to read the contents is not a valid file!", file)); + + assert file != null; + + BufferedReader fileReader = new BufferedReader(new FileReader(file)); + + try { + StringBuilder buffer = new StringBuilder(); + + for (String line = fileReader.readLine(); line != null; line = fileReader.readLine()) { + buffer.append(line); + buffer.append(LINE_SEPARATOR); + } + + return buffer.toString().trim(); + } + finally { + close(fileReader); + } + } + + // TODO refactor and perhaps replace with org.springframework.util.FileCopyUtils.copy(:String, :Writer) + public static void write(final File file, final String contents) throws IOException { + Assert.notNull(file, "The File to write to must not be null!"); + Assert.isTrue(StringUtils.hasText(contents), "The 'contents' of the file cannot be null or empty!"); + + BufferedWriter fileWriter = null; + + try { + fileWriter = new BufferedWriter(new FileWriter(file)); + fileWriter.write(contents); + fileWriter.flush(); + } + finally { + IOUtils.close(fileWriter); + } + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest-context.xml b/src/test/resources/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest-context.xml new file mode 100644 index 00000000..c00bb4eb --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/TemplatePersistentPartitionRegionNamespaceTest-context.xml @@ -0,0 +1,36 @@ + + + + + TemplatePersistentPartitionRegionNamespaceTest + warning + 0 + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests-context.xml b/src/test/resources/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests-context.xml index 83fd9fc6..377ad5d6 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/TemplateRegionsNamespaceTests-context.xml @@ -20,7 +20,8 @@ - + @@ -28,7 +29,6 @@ parallel="false" dispatcher-threads="8"/> - @@ -41,8 +41,8 @@ - @@ -51,16 +51,14 @@ - - - - + + @@ -73,6 +71,9 @@ + + + + + + @@ -88,20 +92,27 @@ - + + + + + + - + + @@ -114,10 +125,8 @@ - - - +