From 433d152c98fdc5fa05bb1c11b98ba8360fac6125 Mon Sep 17 00:00:00 2001 From: John Blum Date: Thu, 9 Jul 2020 11:56:21 -0700 Subject: [PATCH] Add enumeration of supported Resource prefixes (e.g. classpath:). Additionally, the enum defines operations on the Resource prefixes for convenience. Resolves gh-92. --- .../geode/core/io/support/ResourcePrefix.java | 120 ++++++++++++++++++ .../io/support/ResourcePrefixUnitTests.java | 70 ++++++++++ 2 files changed, 190 insertions(+) create mode 100644 spring-geode/src/main/java/org/springframework/geode/core/io/support/ResourcePrefix.java create mode 100644 spring-geode/src/test/java/org/springframework/geode/core/io/support/ResourcePrefixUnitTests.java diff --git a/spring-geode/src/main/java/org/springframework/geode/core/io/support/ResourcePrefix.java b/spring-geode/src/main/java/org/springframework/geode/core/io/support/ResourcePrefix.java new file mode 100644 index 00000000..a18a8b3d --- /dev/null +++ b/spring-geode/src/main/java/org/springframework/geode/core/io/support/ResourcePrefix.java @@ -0,0 +1,120 @@ +/* + * Copyright 2020 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 + * + * https://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.geode.core.io.support; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * An enumeration of {@link Resource} {@link String prefixes} recognized by the Spring Framework. + * + * @author John Blum + * @see org.springframework.core.io.Resource + * @since 1.3.1 + */ +public enum ResourcePrefix { + + CLASSPATH_URL_PREFIX(ResourceLoader.CLASSPATH_URL_PREFIX), + FILESYSTEM_URL_PREFIX("file:"), + HTTP_URL_PREFIX("http:"); + + public static final String RESOURCE_PATH_SEPARATOR = "/"; + + /** + * Factory method used to try and find a {@link ResourcePrefix} enumerated value + * matching the given {@link String prefix}. + * + * @param prefix {@link String} with the name of the prefix. + * @return a {@link ResourcePrefix} matching the given {@link String prefix} by name, or {@literal null} + * if the {@link String prefix} does not match any {@link ResourcePrefix} enumerated value. + */ + public static @Nullable ResourcePrefix from(@Nullable String prefix) { + + if (StringUtils.hasText(prefix)) { + + prefix = prefix.trim().toLowerCase(); + + for (ResourcePrefix resourcePrefix : values()) { + if (resourcePrefix.toString().equals(prefix)) { + return resourcePrefix; + } + } + } + + return null; + } + + private final String prefix; + + /** + * Constructs a new instance of {@link ResourcePrefix} initialized with the named {@link String prefix}. + * + * @param prefix {@link String name} of the prefix. + * @throws IllegalArgumentException if the {@link String prefix} is not specified. + */ + ResourcePrefix(String prefix) { + Assert.hasText(prefix, "Resource prefix must be specified"); + this.prefix = prefix; + } + + /** + * Gets the network protocol that this {@link ResourcePrefix} represents. + * + * @return the network protocol that this {@link ResourcePrefix} represents. + */ + public String getProtocol() { + + StringBuilder buffer = new StringBuilder(); + + for (char character : this.prefix.toCharArray()) { + if (Character.isAlphabetic(character)) { + buffer.append(character); + } + } + + return buffer.toString(); + } + + /** + * Gets the {@link String pattern} or template used to construct a {@link java.net.URL} prefix + * from this {@link ResourcePrefix}. + * + * @return the {@link String pattern} or template used to construct a {@link java.net.URL} prefix + * from this {@link ResourcePrefix}. + * @see #toUrlPrefix() + */ + protected String getUrlPrefixPattern() { + return this.equals(CLASSPATH_URL_PREFIX) ? "%s" : "%1$s%2$s%2$s"; + } + + @Override + public String toString() { + return this.prefix; + } + + /** + * Gets the {@link ResourcePrefix} as a prefix use in a {@link java.net.URL}. + * + * @return the {@link java.net.URL} prefix. + * @see #getUrlPrefixPattern() + */ + public String toUrlPrefix() { + return String.format(getUrlPrefixPattern(), toString(), RESOURCE_PATH_SEPARATOR); + } +} diff --git a/spring-geode/src/test/java/org/springframework/geode/core/io/support/ResourcePrefixUnitTests.java b/spring-geode/src/test/java/org/springframework/geode/core/io/support/ResourcePrefixUnitTests.java new file mode 100644 index 00000000..ebcdad7a --- /dev/null +++ b/spring-geode/src/test/java/org/springframework/geode/core/io/support/ResourcePrefixUnitTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020 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 + * + * https://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.geode.core.io.support; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import org.springframework.core.io.ResourceLoader; + +/** + * Unit Tests for {@link ResourcePrefix}. + * + * @author John Blum + * @see org.junit.Test + * @since 1.3.1 + */ +public class ResourcePrefixUnitTests { + + @Test + public void fromReturnsResourcePrefix() { + + assertThat(ResourcePrefix.from(ResourceLoader.CLASSPATH_URL_PREFIX)) + .isEqualTo(ResourcePrefix.CLASSPATH_URL_PREFIX); + + for (ResourcePrefix prefix : ResourcePrefix.values()) { + assertThat(ResourcePrefix.from(prefix.toString())).isEqualTo(prefix); + } + } + + @Test + public void fromInvalidPrefixReturnsNull() { + + assertThat(ResourcePrefix.from("ftp:")).isNull(); + assertThat(ResourcePrefix.from("scp:")).isNull(); + assertThat(ResourcePrefix.from("smtp:")).isNull(); + assertThat(ResourcePrefix.from(" ")).isNull(); + assertThat(ResourcePrefix.from("")).isNull(); + assertThat(ResourcePrefix.from(null)).isNull(); + } + + @Test + public void getProtocolIsCorrect() { + + assertThat(ResourcePrefix.CLASSPATH_URL_PREFIX.getProtocol()).isEqualTo("classpath"); + assertThat(ResourcePrefix.FILESYSTEM_URL_PREFIX.getProtocol()).isEqualTo("file"); + assertThat(ResourcePrefix.HTTP_URL_PREFIX.getProtocol()).isEqualTo("http"); + } + + @Test + public void toUrlPrefix() { + + assertThat(ResourcePrefix.CLASSPATH_URL_PREFIX.toUrlPrefix()).isEqualTo("classpath:"); + assertThat(ResourcePrefix.FILESYSTEM_URL_PREFIX.toUrlPrefix()).isEqualTo("file://"); + assertThat(ResourcePrefix.HTTP_URL_PREFIX.toUrlPrefix()).isEqualTo("http://"); + } +}