Rename modules.

Rename geode-spring-boot to spring-geode.

Rename geode-spring-boot-autoconfigure to spring-geode-autoconfigure.

Rename geode-spring-boot-starter to spring-geode-starter.

Rename gemfire-spring-boot-starter to spring-gemfire-starter.

Resolves GitHub Issue #6.
This commit is contained in:
John Blum
2018-06-19 18:35:09 -07:00
parent c830817ed3
commit 330dc7fec3
84 changed files with 5 additions and 5 deletions

View File

@@ -0,0 +1,27 @@
/*
* Copyright 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.
* 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 example.app;
/**
* The {@link NonBeanType} class is a non-Spring bean, placeholder reference type for classpath component scanning.
*
* @author John Blum
* @since 1.0.0
*/
public class NonBeanType {
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 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.
* 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 example.app.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.gemfire.mapping.annotation.Region;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/**
* The {@link Author} class is an Abstract Data Type (ADT) modeling a book author.
*
* @author John Blum
* @see lombok
* @see org.springframework.data.annotation.Id
* @see org.springframework.data.gemfire.mapping.annotation.Region
* @since 1.0.0
*/
@Data
@Region("Authors")
@RequiredArgsConstructor(staticName = "newAuthor")
@SuppressWarnings("unused")
public class Author {
@Id
private Long id;
@NonNull
private String name;
public boolean isNew() {
return getId() == null;
}
public Author identifiedBy(Long id) {
setId(id);
return this;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 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.
* 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 example.app.model;
import java.time.LocalDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.gemfire.mapping.annotation.Region;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/**
* The {@link Book} class is an Abstract Data Type (ADT) modeling a book.
*
* @author John Blum
* @see lombok
* @see org.springframework.data.annotation.Id
* @see org.springframework.data.gemfire.mapping.annotation.Region
* @see example.app.model.Author
* @see example.app.model.ISBN
* @since 1.0.0
*/
@Region("Books")
@Data
@RequiredArgsConstructor(staticName = "newBook")
public class Book {
private Author author;
@Id
private ISBN isbn;
private LocalDate publishedDate;
@NonNull
private String title;
public boolean isNew() {
return getIsbn() == null;
}
public Book identifiedBy(ISBN isbn) {
setIsbn(isbn);
return this;
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright 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.
* 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 example.app.model;
import java.util.UUID;
import org.apache.shiro.util.Assert;
/**
* The {@link ISBN} class is a Abstract Data Type (ADT) modeling either a {@link Book} ISBN-10 or ISBN-13 number.
*
* @author John Blum
* @see java.lang.Comparable
* @since 1.0.0
*/
@SuppressWarnings("unused")
public class ISBN implements Comparable<ISBN> {
public static ISBN autoGenerated() {
return of(UUID.randomUUID().toString());
}
public static ISBN of(String number) {
Assert.hasText(number, String.format("Number [%s] is required", number));
return new ISBN(number);
}
private String number;
private ISBN(String number) {
this.number = number;
}
public String getNumber() {
return number;
}
@Override
@SuppressWarnings("all")
public int compareTo(ISBN other) {
return this.getNumber().compareTo(other.getNumber());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ISBN)) {
return false;
}
ISBN that = (ISBN) obj;
return this.getNumber().equals(that.getNumber());
}
@Override
public int hashCode() {
int hashValue = 17;
hashValue = 37 * hashValue + getNumber().hashCode();
return hashValue;
}
@Override
public String toString() {
return getNumber();
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 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.
* 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 example.app.repo;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import example.app.model.Author;
import example.app.model.Book;
import example.app.model.ISBN;
/**
* The {@link BookRepository} interface is a Spring Data {@link CrudRepository} defining basic CRUD
* and simple query data access operations on {@link Book} objects to the backing data store.
*
* @author John Blum
* @see example.app.model.Book
* @see example.app.model.ISBN
* @see org.springframework.data.repository.CrudRepository
* @since 1.0.0
*/
@SuppressWarnings("unused")
public interface BookRepository extends CrudRepository<Book, ISBN> {
List<Book> findByAuthorOrderByAuthorNameAscTitleAsc(Author author);
Book findByIsbn(ISBN isbn);
Book findByTitle(String title);
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 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.
* 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 example.app.service;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import example.app.model.Author;
import example.app.model.Book;
import example.app.model.ISBN;
import example.app.repo.BookRepository;
/**
* The {@link BookService} class is an application {@link Service service} class for managing {@link Book Books}.
*
* @author John Blum
* @see example.app.model.Author
* @see example.app.model.Book
* @see example.app.model.ISBN
* @see example.app.repo.BookRepository
* @see org.springframework.stereotype.Service
* @since 1.0.0
*/
@Service
@SuppressWarnings("unused")
public class BookService {
private final BookRepository bookRepository;
public BookService(@Autowired(required = false) BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
protected BookRepository getBookRepository() {
return Optional.ofNullable(this.bookRepository)
.orElseThrow(() -> newIllegalStateException("BookRepository was not properly configured"));
}
public List<Book> findByAuthor(Author author) {
return getBookRepository().findByAuthorOrderByAuthorNameAscTitleAsc(author);
}
public Book findByIsbn(ISBN isbn) {
return getBookRepository().findByIsbn(isbn);
}
public Book findByTitle(String title) {
return getBookRepository().findByTitle(title);
}
public Book stock(Book book) {
if (book.isNew()) {
book.identifiedBy(ISBN.autoGenerated());
}
return getBookRepository().save(book);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 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.
* 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 example.app.service.support;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import example.app.model.Book;
import example.app.model.ISBN;
import example.app.repo.BookRepository;
import example.app.service.BookService;
/**
* The {@link CachingBookService} class is an implementation and extension of {@link BookService}
* with caching capabilities.
*
* @author John Blum
* @see example.app.model.Book
* @see example.app.model.ISBN
* @see example.app.repo.BookRepository
* @see example.app.service.BookService
* @see org.springframework.cache.annotation.Cacheable
* @see org.springframework.stereotype.Service
* @since 1.0.0
*/
@Service
public class CachingBookService extends BookService {
private final AtomicBoolean cacheMiss = new AtomicBoolean(false);
public CachingBookService(@Autowired(required = false) BookRepository bookRepository) {
super(bookRepository);
}
public boolean isCacheMiss() {
return this.cacheMiss.getAndSet(false);
}
@Override
@Cacheable(value = "CachedBooks")
public Book findByTitle(String title) {
this.cacheMiss.set(true);
return Book.newBook(title).identifiedBy(ISBN.autoGenerated());
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 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.
* 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 example.echo.config;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.GemfireTemplate;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.util.RegionUtils;
/**
* The {@link EchoClientConfiguration} class is a Spring {@link Configuration} class used to configure
* a {@link ClientCache} {@link Region} for echo messages.
*
* @author John Blum
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.client.ClientCache
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.GemfireTemplate
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
* @since 1.0.0
*/
@Configuration
@SuppressWarnings("unused")
public class EchoClientConfiguration {
protected static final String REGION_NAME = "Echo";
@Bean(REGION_NAME)
public ClientRegionFactoryBean<String, String> echoRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<String, String> echoRegion = new ClientRegionFactoryBean<>();
echoRegion.setCache(gemfireCache);
echoRegion.setClose(false);
echoRegion.setShortcut(ClientRegionShortcut.PROXY);
return echoRegion;
}
@Bean
public GemfireTemplate echoTemplate(GemFireCache gemfireCache) {
return new GemfireTemplate(gemfireCache.getRegion(RegionUtils.toRegionPath(REGION_NAME)));
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 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.
* 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 example.echo.config;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.GemfireTemplate;
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
import org.springframework.data.gemfire.util.RegionUtils;
import example.geode.cache.EchoCacheLoader;
/**
* The {@link EchoClientConfiguration} class is a Spring {@link Configuration} class used to configure
* a peer {@link Cache} {@link Region} for echo messages.
*
* @author John Blum
* @see org.apache.geode.cache.Cache
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.GemfireTemplate
* @see org.springframework.data.gemfire.PartitionedRegionFactoryBean
* @see example.geode.cache.EchoCacheLoader
* @since 1.0.0
*/
@Configuration
@SuppressWarnings("unused")
public class EchoServerConfiguration {
@Bean(EchoClientConfiguration.REGION_NAME)
public PartitionedRegionFactoryBean<String, String> echoRegion(GemFireCache gemfireCache) {
PartitionedRegionFactoryBean<String, String> echoRegion = new PartitionedRegionFactoryBean<>();
echoRegion.setCache(gemfireCache);
echoRegion.setCacheLoader(EchoCacheLoader.INSTANCE);
echoRegion.setClose(false);
echoRegion.setPersistent(false);
return echoRegion;
}
@Bean
public GemfireTemplate echoTemplate(GemFireCache gemfireCache) {
return new GemfireTemplate(gemfireCache.getRegion(
RegionUtils.toRegionPath(EchoClientConfiguration.REGION_NAME)));
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 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.
* 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 example.geode.cache;
import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.LoaderHelper;
import org.springframework.geode.cache.support.CacheLoaderSupport;
/**
* The {@link EchoCacheLoader} class is an implementation of {@link CacheLoader} that echos the key as the value.
*
* @author John Blum
* @see org.apache.geode.cache.CacheLoader
* @see org.springframework.geode.cache.support.CacheLoaderSupport
* @since 1.0.0
*/
@SuppressWarnings("unused")
public class EchoCacheLoader implements CacheLoaderSupport<String, String> {
public static final EchoCacheLoader INSTANCE = new EchoCacheLoader();
@Override
public String load(LoaderHelper<String, String> helper) throws CacheLoaderException {
return helper.getKey();
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 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.
* 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 example.geode.query.cq.event;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/**
* The {@link TemperatureReading} class is an Abstract Data Type (ADT) modeling a temperature event,
* tracking the recorded temperature, unit and timestamp of the event.
*
* @author John Blum
* @see java.time.LocalDateTime
* @see lombok
* @see example.geode.query.cq.event.TemperatureUnit
* @since 1.0.0
*/
@Data
@EqualsAndHashCode(of = { "temperature", "temperatureUnit" })
@RequiredArgsConstructor(staticName = "of")
public class TemperatureReading {
@NonNull
private Integer temperature;
private LocalDateTime timestamp = LocalDateTime.now();
private TemperatureUnit temperatureUnit = TemperatureUnit.defaultTemperatureUnit();
public TemperatureReading at(LocalDateTime timestamp) {
setTimestamp(timestamp);
return this;
}
public TemperatureReading in(TemperatureUnit temperatureUnit) {
setTemperatureUnit(temperatureUnit);
return this;
}
@Override
public String toString() {
return String.format("%d %s", getTemperature(), getTemperatureUnit());
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright 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.
* 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 example.geode.query.cq.event;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.apache.geode.cache.query.CqEvent;
import org.springframework.data.gemfire.listener.annotation.ContinuousQuery;
/**
* The {@link TemperatureReadingsContinuousQueriesHandler} class is a POJO containing Apache Geode/Pivotal GemFire
* Continuous Query (CQ) definitions.
*
* @author John Blum
* @see org.apache.geode.cache.query.CqEvent
* @see org.springframework.data.gemfire.listener.annotation.ContinuousQuery
* @since 1.0.0
*/
@SuppressWarnings("unused")
public final class TemperatureReadingsContinuousQueriesHandler {
private final AtomicInteger temperatureReadingsCounter = new AtomicInteger(0);
private final List<TemperatureReading> boilingTemperatureReadings = new CopyOnWriteArrayList<>();
private final List<TemperatureReading> freezingTemperatureReadings = new CopyOnWriteArrayList<>();
public List<TemperatureReading> getBoilingTemperatureReadings() {
return Collections.unmodifiableList(this.boilingTemperatureReadings);
}
public List<Integer> getBoilingTemperatures() {
return getBoilingTemperatureReadings().stream()
.map(TemperatureReading::getTemperature)
.collect(Collectors.toList());
}
public List<TemperatureReading> getFreezingTemperatureReadings() {
return Collections.unmodifiableList(this.freezingTemperatureReadings);
}
public List<Integer> getFreezingTemperatures() {
return getFreezingTemperatureReadings().stream()
.map(TemperatureReading::getTemperature)
.collect(Collectors.toList());
}
public int getTemperatureReadingCount() {
return this.temperatureReadingsCounter.get();
}
@ContinuousQuery(name = "BoilingTemperatures",
query = "SELECT * FROM /TemperatureReadings r WHERE r.temperature >= 212")
public void boilingTemperatures(CqEvent event) {
TemperatureReading temperatureReading = (TemperatureReading) event.getNewValue();
this.boilingTemperatureReadings.add(temperatureReading);
this.temperatureReadingsCounter.incrementAndGet();
}
@ContinuousQuery(name = "FreezingTemperatures",
query = "SELECT * FROM /TemperatureReadings r WHERE r.temperature <= 32")
public void freezingTemperatures(CqEvent event) {
TemperatureReading temperatureReading = (TemperatureReading) event.getNewValue();
this.freezingTemperatureReadings.add(temperatureReading);
this.temperatureReadingsCounter.incrementAndGet();
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 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.
* 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 example.geode.query.cq.event;
import java.util.Locale;
import java.util.Optional;
/**
* The {@link TemperatureUnit} enum is an enumeration of different temperature units
* as defined by International System of Units (SI).
*
* @author John Blum
* @since 1.0.0
*/
@SuppressWarnings("unused")
public enum TemperatureUnit {
CELSIUS("°C"),
FAHRENHEIT("°F"),
KELVIN("K");
public static TemperatureUnit defaultTemperatureUnit() {
return Optional.of(Locale.getDefault())
.map(Locale::getISO3Country)
.filter(Locale.US.getISO3Country()::equalsIgnoreCase)
.map(it -> TemperatureUnit.FAHRENHEIT)
.orElse(TemperatureUnit.CELSIUS);
}
private final String symbol;
TemperatureUnit(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return this.symbol;
}
@Override
public String toString() {
return getSymbol();
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 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.
* 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 example.java.net;
import java.net.URL;
import org.springframework.core.io.ClassPathResource;
/**
* The {@link UrlRevealed} class is a disclosure of Java's {@link URL} class.
*
* @author John Blum
* @see java.net.URL
* @since 1.0.0
*/
public class UrlRevealed {
public static void main(String[] args) throws Exception {
URL url = new URL("jar:file:///www.foo.com/bar/jar.jar!/baz/entry.txt");
System.out.printf("URL [%s] {%n \tfile [%s],%n \tpath [%s],%n \tport [%s],%n \tprotocol [%s],%n \tquery [%s]%n}%n%n",
url, url.getFile(), url.getPath(), url.getPort(), url.getProtocol(), url.getQuery());
System.out.printf("URI [%s]%n", new ClassPathResource("trusted.keystore").getURL().toURI());
}
}