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 d33b11ae..023a37ff 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, @@ -118,7 +117,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"); } } @@ -126,11 +125,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 7f42a734..002f77a0 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; @@ -28,7 +30,6 @@ import org.springframework.core.Conventions; import org.springframework.data.gemfire.EvictionAttributesFactoryBean; import org.springframework.data.gemfire.ExpirationAttributesFactoryBean; import org.springframework.data.gemfire.GemfireUtils; -import org.springframework.data.gemfire.InterestPolicyType; import org.springframework.data.gemfire.SubscriptionAttributesFactoryBean; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; @@ -37,7 +38,6 @@ import org.w3c.dom.Element; import com.gemstone.gemfire.cache.LossAction; import com.gemstone.gemfire.cache.MembershipAttributes; import com.gemstone.gemfire.cache.ResumptionAction; -import com.gemstone.gemfire.cache.Scope; /** * Utilities used by the Spring Data GemFire XML Namespace parsers. @@ -51,8 +51,23 @@ 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) { + 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); @@ -64,8 +79,8 @@ abstract class ParsingUtils { } } - static void setPropertyValue(Element element, BeanDefinitionBuilder builder, - String attributeName, String propertyName) { + static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName, + String propertyName) { setPropertyValue(element, builder, attributeName, propertyName, null); } @@ -73,16 +88,24 @@ abstract class ParsingUtils { setPropertyValue(element, builder, attributeName, Conventions.attributeNameToPropertyName(attributeName)); } - static void setPropertyReference(Element element, BeanDefinitionBuilder builder, - String attributeName, String propertyName) { + static void setPropertyValue(BeanDefinitionBuilder builder, BeanDefinition source, String propertyName, + boolean withDependsOn) { - String attributeValue = element.getAttribute(attributeName); + PropertyValue propertyValue = source.getPropertyValues().getPropertyValue(propertyName); - if (StringUtils.hasText(attributeValue)) { - builder.addPropertyReference(propertyName, attributeValue); + 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: * @@ -126,7 +149,8 @@ abstract class ParsingUtils { static Object parseRefOrNestedCustomElement(ParserContext parserContext, Element element, BeanDefinitionBuilder builder) { Object beanRef = ParsingUtils.getBeanReference(parserContext, element, "bean"); - return (beanRef != null ? beanRef : parserContext.getDelegate().parseCustomElement(element, builder.getBeanDefinition())); + return (beanRef != null ? beanRef : parserContext.getDelegate().parseCustomElement( + element, builder.getBeanDefinition())); } static Object parseRefOrSingleNestedBeanDeclaration(ParserContext parserContext, Element element, @@ -287,10 +311,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"); @@ -309,11 +329,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 32e03d5d..1d6d71f7 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().getCompressor()); assertNull(region.getAttributes().getCustomEntryIdleTimeout()); @@ -250,7 +253,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, @@ -318,7 +321,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()); @@ -351,9 +354,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()); @@ -386,7 +389,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"); @@ -402,7 +405,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()); @@ -418,6 +421,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 index fb3791d4..523b30a6 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java @@ -30,18 +30,44 @@ import com.gemstone.gemfire.management.internal.cli.util.spring.Assert; * * @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 IOUtils { +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)); @@ -60,9 +86,23 @@ public abstract class FileSystemUtils extends IOUtils { 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 index 386c16d9..de1c970f 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java @@ -32,6 +32,8 @@ import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils; * * @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 */ @@ -40,7 +42,15 @@ public abstract class FileUtils extends IOUtils { public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - // TODO refactor and perhaps replace with org.springframework.util.FileCopytUtils.copyToString(:Reader) + 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)); @@ -64,7 +74,7 @@ public abstract class FileUtils extends IOUtils { } } - // TODO refactor and perhaps replace with org.springframework.util.FileCopytUtils.copy(:String, :Writer) + // 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!"); 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 fc8b6ec3..a59a15fa 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="true" dispatcher-threads="8"/> - @@ -41,8 +41,8 @@ - @@ -51,16 +51,14 @@ - - - - + + @@ -73,6 +71,9 @@ + + + + + + @@ -88,20 +92,27 @@ - + + + + + + - + + @@ -114,10 +125,8 @@ - - - +