This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new cc1c154 REST refactoring.
cc1c154 is described below
commit cc1c1547770190a0fda82502ac4f7a4fe9f22049
Author: JamesBognar <[email protected]>
AuthorDate: Mon Feb 1 11:13:02 2021 -0500
REST refactoring.
---
.../java/org/apache/juneau/cp/FileFinder_Test.java | 7 +-
.../cp/{FileFinder.java => BasicFileFinder.java} | 165 +++--------
.../java/org/apache/juneau/cp/BeanFactory.java | 23 ++
.../main/java/org/apache/juneau/cp/FileFinder.java | 305 ++-------------------
.../org/apache/juneau/cp/FileFinderBuilder.java | 54 ++--
.../org/apache/juneau/internal/ClassUtils.java | 14 +
.../java/org/apache/juneau/rest/Swagger_Test.java | 2 +-
.../org/apache/juneau/rest/BasicFileFinder.java | 53 ----
.../apache/juneau/rest/BasicSwaggerProvider.java | 2 +-
.../java/org/apache/juneau/rest/RestContext.java | 10 +-
.../java/org/apache/juneau/rest/StaticFiles.java | 4 +-
.../apache/juneau/rest/SwaggerProviderBuilder.java | 7 +-
12 files changed, 143 insertions(+), 503 deletions(-)
diff --git
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
index 10bbef2..ffe720f 100644
---
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
+++
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
@@ -654,16 +654,17 @@ public class FileFinder_Test {
@Test
public void e03_subclassing() throws Exception {
- E03b x = E03b
+ FileFinder x = E03b
.create()
.dir(".")
.caching(100_000_000)
- .build(E03b.class);
+ .implClass(E03b.class)
+ .build();
assertObject(x).isType(E03b.class);
}
public static class E03a extends FileFinderBuilder {}
- public static class E03b extends FileFinder {
+ public static class E03b extends BasicFileFinder {
public static E03a create() {
return new E03a();
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
similarity index 68%
copy from
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
copy to
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
index 75f941f..e065401 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
@@ -28,60 +28,14 @@ import org.apache.juneau.collections.*;
import org.apache.juneau.internal.*;
/**
- * Utility class for finding regular or localized files on the classpath and
file system.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jc>// Constructor a file source that looks for files in the "files"
working directory, then in the
- * // package "foo.bar", then in the package "foo.bar.files", then in the
package "files".</jc>
- * FileFinder <jv>finder</jv> = FileFinder
- * .<jsm>create</jsm>()
- * .dir(<js>"files"</js>)
- * .cp(foo.bar.MyClass.<jk>class</jk>,<jk>null</jk>,<jk>true</jk>)
- *
.cp(foo.bar.MyClass.<jk>class</jk>,<js>"files"</js>,<jk>true</jk>)
- *
.cp(foo.bar.MyClass.<jk>class</jk>,<js>"/files"</js>,<jk>true</jk>)
- * .cache(1_000_000l) <jc>// Cache files less than 1MB in
size.</jc>
- *
.ignore(Pattern.<jsm>compile</jsm>(<js>"(?i)(.*\\.(class|properties))|(package.html)"</js>))
<jc>// Ignore certain files.</jc>
- * .build();
- *
- * <jc>// Find a normal file.</jc>
- * InputStream <jv>is1</jv> =
<jv>finder</jv>.getStream(<js>"text.txt"</js>);
- *
- * <jc>// Find a localized file called "text_ja_JP.txt".</jc>
- * InputStream <jv>is2</jv> =
<jv>finder</jv>.getStream(<js>"text.txt"</js>, Locale.<jsf>JAPAN</jsf>);
- * </p>
- *
- * <p>
- * If the <c>locale</c> is specified, then we look for resources whose name
matches that locale.
- * For example, if looking for the resource <js>"MyResource.txt"</js> for the
Japanese locale, we will look for
- * files in the following order:
- * <ol>
- * <li><js>"MyResource_ja_JP.txt"</js>
- * <li><js>"MyResource_ja.txt"</js>
- * <li><js>"MyResource.txt"</js>
- * </ol>
- *
- * <p>
- * This class can be subclassed to provide specific preconfigured instances
using no-arg constructors.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
- * <jk>public</jk> MyFileFinder() {
- * <jk>super</jk>(
- * <jk>new</jk> FileFinderBuilder()
- * .dir(<js>"/files"</js>)
- * );
- * }
- * }
- * </p>
+ * Basic implementation of a {@link FileFinder}.
*
* <p>
* Specialized behavior can be implemented by overridding the {@link
#find(String, Locale)} method.
*
* <h5 class='section'>Example:</h5>
* <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
+ * <jk>public class</jk> MyFileFinder <jk>extends</jk> BasicFileFinder {
* <ja>@Override</ja>
* <jk>protected</jk> Optional<InputStream> find(String
<jv>name</jv>, Locale <jv>locale</jv>) <jk>throws</jk> IOException {
* <jc>// Do special handling or just call
super.find().</jc>
@@ -89,26 +43,9 @@ import org.apache.juneau.internal.*;
* }
* }
* </p>
- *
- * <p>
- * The {@link FileFinderBuilder#build(Class)} method is provided for
instantiated subclasses of {@link FileFinder}.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
- * <jk>public</jk> MyFileFinder(FileFinderBuilder
<jv>builder</jv>) {
- * <jk>super</jk>(builder);
- * }
- * }
- *
- * <jc>// Instantiate subclass.</jc>
- * MyFileFinder <jv>finder</jv> =
FileFinder.<jsm>create</jsm>().build(MyFileFinder.<jk>class</jk>);
- * </p>
*/
-public class FileFinder {
+public class BasicFileFinder implements FileFinder {
- /** Represents no file finder */
- public static class Null extends FileFinder {}
private static final ResourceBundle.Control RB_CONTROL =
ResourceBundle.Control.getControl(Control.FORMAT_DEFAULT);
@@ -121,20 +58,11 @@ public class FileFinder {
private final int hashCode;
/**
- * Instantiate a new builder.
- *
- * @return A new builder.
- */
- public static FileFinderBuilder create() {
- return new FileFinderBuilder();
- }
-
- /**
* Builder-based constructor.
*
* @param builder The builder object.
*/
- public FileFinder(FileFinderBuilder builder) {
+ public BasicFileFinder(FileFinderBuilder builder) {
this.roots = builder.roots.toArray(new
LocalDir[builder.roots.size()]);
this.cachingLimit = builder.cachingLimit;
this.include = builder.include.toArray(new
Pattern[builder.include.size()]);
@@ -148,7 +76,7 @@ public class FileFinder {
* <p>
* Can be used when providing a subclass that overrides the {@link
#find(String, Locale)} method.
*/
- public FileFinder() {
+ protected BasicFileFinder() {
this.roots = new LocalDir[0];
this.cachingLimit = -1;
this.include = new Pattern[0];
@@ -156,6 +84,34 @@ public class FileFinder {
this.hashCode = HashCode.of(getClass(), roots, cachingLimit,
getIncludePatterns(), getExcludePatterns());
}
+
//-----------------------------------------------------------------------------------------------------------------
+ // FileFinder methods
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Override /* FileFinder */
+ public final Optional<InputStream> getStream(String name, Locale
locale) throws IOException {
+ return find(name, locale);
+ }
+
+ @Override /* FileFinder */
+ public final Optional<InputStream> getStream(String name) throws
IOException {
+ return find(name, null);
+ }
+
+ @Override /* FileFinder */
+ public final Optional<String> getString(String name) throws IOException
{
+ return Optional.ofNullable(IOUtils.read(find(name,
null).orElse(null), IOUtils.UTF8));
+ }
+
+ @Override /* FileFinder */
+ public Optional<String> getString(String name, Locale locale) throws
IOException {
+ return Optional.ofNullable(IOUtils.read(find(name,
locale).orElse(null), IOUtils.UTF8));
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // Implementation methods
+
//-----------------------------------------------------------------------------------------------------------------
+
/**
* The main implementation method for finding files.
*
@@ -212,58 +168,7 @@ public class FileFinder {
return Optional.of(lf.read());
}
-
- /**
- * Returns the contents of the resource with the specified name.
- *
- * @param name The resource name.
- * See {@link Class#getResource(String)} for format.
- * @param locale
- * The locale of the resource to retrieve.
- * <br>If <jk>null</jk>, won't look for localized file names.
- * @return The resolved resource contents, or <jk>null</jk> if the
resource was not found.
- * @throws IOException Thrown by underlying stream.
- */
- public final Optional<InputStream> getStream(String name, Locale
locale) throws IOException {
- return find(name, locale);
- }
-
- /**
- * Returns the file with the specified name.
- *
- * @param name The file name.
- * @return An input stream to the file if it exists, or <jk>null</jk>
if it does not.
- * @throws IOException If file could not be read.
- */
- public final Optional<InputStream> getStream(String name) throws
IOException {
- return find(name, null);
- }
-
- /**
- * Returns the file with the specified name as a string.
- *
- * @param name The file name.
- * @return The contents of the file as a string. Assumes UTF-8
encoding.
- * @throws IOException If file could not be read.
- */
- public final Optional<String> getString(String name) throws IOException
{
- return Optional.ofNullable(IOUtils.read(find(name,
null).orElse(null), IOUtils.UTF8));
- }
-
- /**
- * Returns the file with the specified name as a string.
- *
- * @param name The file name.
- * @param locale
- * The locale of the resource to retrieve.
- * <br>If <jk>null</jk>, won't look for localized file names.
- * @return The contents of the file as a string. Assumes UTF-8
encoding.
- * @throws IOException If file could not be read.
- */
- public Optional<String> getString(String name, Locale locale) throws
IOException {
- return Optional.ofNullable(IOUtils.read(find(name,
locale).orElse(null), IOUtils.UTF8));
- }
-
+
/**
* Returns the candidate file names for the specified file name in the
specified locale.
*
@@ -391,7 +296,7 @@ public class FileFinder {
@Override /* Object */
public boolean equals(Object o) {
- return o instanceof FileFinder && eq(this, (FileFinder)o,
(x,y)->eq(x.hashCode, y.hashCode) && eq(x.getClass(), y.getClass()) &&
eq(x.roots, y.roots) && eq(x.cachingLimit, y.cachingLimit) &&
eq(x.getIncludePatterns(), y.getIncludePatterns()) &&
eq(x.getExcludePatterns(), y.getExcludePatterns()));
+ return o instanceof BasicFileFinder && eq(this,
(BasicFileFinder)o, (x,y)->eq(x.hashCode, y.hashCode) && eq(x.getClass(),
y.getClass()) && eq(x.roots, y.roots) && eq(x.cachingLimit, y.cachingLimit) &&
eq(x.getIncludePatterns(), y.getIncludePatterns()) &&
eq(x.getExcludePatterns(), y.getExcludePatterns()));
}
@Override
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
index e0b2bd7..d26a135 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanFactory.java
@@ -141,6 +141,29 @@ public class BeanFactory {
}
/**
+ * Same as {@link #addBean(Class, Object)} but also adds subtypes of
the bean.
+ *
+ * @param <T> The class to associate this bean with.
+ * @param c The class to associate this bean with.
+ * @param t The bean.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public <T> BeanFactory addBeans(Class<T> c, T t) {
+ if (t == null)
+ beanMap.remove(c);
+ else {
+ addBean(c, t);
+ Class<T> c2 = (Class<T>)t.getClass();
+ while (c2 != c) {
+ addBean(c2, t);
+ c2 = (Class<T>) c2.getSuperclass();
+ }
+ }
+ return this;
+ }
+
+ /**
* Adds a bean supplier of the specified type to this factory.
*
* @param <T> The class to associate this bean with.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
index 75f941f..7b32d5d 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
@@ -12,20 +12,8 @@
//
***************************************************************************************************************************
package org.apache.juneau.cp;
-import static org.apache.juneau.internal.FileUtils.*;
-import static org.apache.juneau.internal.StringUtils.*;
-import static org.apache.juneau.internal.ObjectUtils.*;
-import static java.util.Arrays.*;
-import static java.util.stream.Collectors.*;
-
import java.io.*;
import java.util.*;
-import java.util.ResourceBundle.*;
-import java.util.concurrent.*;
-import java.util.regex.*;
-
-import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
/**
* Utility class for finding regular or localized files on the classpath and
file system.
@@ -62,63 +50,33 @@ import org.apache.juneau.internal.*;
* </ol>
*
* <p>
- * This class can be subclassed to provide specific preconfigured instances
using no-arg constructors.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
- * <jk>public</jk> MyFileFinder() {
- * <jk>super</jk>(
- * <jk>new</jk> FileFinderBuilder()
- * .dir(<js>"/files"</js>)
- * );
- * }
- * }
- * </p>
- *
- * <p>
- * Specialized behavior can be implemented by overridding the {@link
#find(String, Locale)} method.
+ * The default implementation of this interface is {@link BasicFileFinder}.
+ * The {@link FileFinderBuilder#implClass(Class)} method is provided for
instantiating other instances.
*
* <h5 class='section'>Example:</h5>
* <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
- * <ja>@Override</ja>
- * <jk>protected</jk> Optional<InputStream> find(String
<jv>name</jv>, Locale <jv>locale</jv>) <jk>throws</jk> IOException {
- * <jc>// Do special handling or just call
super.find().</jc>
- * <jk>return super</jk>.find(<jv>name</jv>,
<jv>locale</jv>);
- * }
- * }
- * </p>
- *
- * <p>
- * The {@link FileFinderBuilder#build(Class)} method is provided for
instantiated subclasses of {@link FileFinder}.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode w800'>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
+ * <jk>public class</jk> MyFileFinder <jk>extends</jk> BasicFileFinder {
* <jk>public</jk> MyFileFinder(FileFinderBuilder
<jv>builder</jv>) {
* <jk>super</jk>(builder);
* }
* }
*
* <jc>// Instantiate subclass.</jc>
- * MyFileFinder <jv>finder</jv> =
FileFinder.<jsm>create</jsm>().build(MyFileFinder.<jk>class</jk>);
+ * FileFinder <jv>myFinder</jv> =
FileFinder.<jsm>create</jsm>().implClass(MyFileFinder.<jk>class</jk>).build();
* </p>
+ *
+ * <p>
+ * Subclasses must provide a public constructor that takes in any of the
following arguments:
+ * <ul>
+ * <li>{@link FileFinderBuilder} - The builder object.
+ * <li>Any beans present in the registered {@link
FileFinderBuilder#beanFactory(BeanFactory) bean factory}.
+ * <li>Any {@link Optional} beans optionally present in the registered
{@link FileFinderBuilder#beanFactory(BeanFactory) bean factory}.
+ * </ul>
*/
-public class FileFinder {
+public interface FileFinder {
/** Represents no file finder */
- public static class Null extends FileFinder {}
-
- private static final ResourceBundle.Control RB_CONTROL =
ResourceBundle.Control.getControl(Control.FORMAT_DEFAULT);
-
- private final Map<String,LocalFile> files = new ConcurrentHashMap<>();
- private final Map<Locale,Map<String,LocalFile>> localizedFiles = new
ConcurrentHashMap<>();
-
- private final LocalDir[] roots;
- private final long cachingLimit;
- private final Pattern[] include, exclude;
- private final int hashCode;
+ public abstract class Null implements FileFinder {}
/**
* Instantiate a new builder.
@@ -130,90 +88,6 @@ public class FileFinder {
}
/**
- * Builder-based constructor.
- *
- * @param builder The builder object.
- */
- public FileFinder(FileFinderBuilder builder) {
- this.roots = builder.roots.toArray(new
LocalDir[builder.roots.size()]);
- this.cachingLimit = builder.cachingLimit;
- this.include = builder.include.toArray(new
Pattern[builder.include.size()]);
- this.exclude = builder.exclude.toArray(new
Pattern[builder.exclude.size()]);
- this.hashCode = HashCode.of(getClass(), roots, cachingLimit,
getIncludePatterns(), getExcludePatterns());
- }
-
- /**
- * Default constructor.
- *
- * <p>
- * Can be used when providing a subclass that overrides the {@link
#find(String, Locale)} method.
- */
- public FileFinder() {
- this.roots = new LocalDir[0];
- this.cachingLimit = -1;
- this.include = new Pattern[0];
- this.exclude = new Pattern[0];
- this.hashCode = HashCode.of(getClass(), roots, cachingLimit,
getIncludePatterns(), getExcludePatterns());
- }
-
- /**
- * The main implementation method for finding files.
- *
- * <p>
- * Subclasses can override this method to provide their own handling.
- *
- * @param name The resource name.
- * See {@link Class#getResource(String)} for format.
- * @param locale
- * The locale of the resource to retrieve.
- * <br>If <jk>null</jk>, won't look for localized file names.
- * @return The resolved resource contents, or <jk>null</jk> if the
resource was not found.
- * @throws IOException Thrown by underlying stream.
- */
- protected Optional<InputStream> find(String name, Locale locale) throws
IOException {
- name = StringUtils.trimSlashesAndSpaces(name);
-
- if (isInvalidPath(name))
- return Optional.empty();
-
- if (locale != null)
- localizedFiles.putIfAbsent(locale, new
ConcurrentHashMap<>());
-
- Map<String,LocalFile> fileCache = locale == null ? files :
localizedFiles.get(locale);
-
- LocalFile lf = fileCache.get(name);
-
- if (lf == null) {
- List<String> candidateFileNames =
getCandidateFileNames(name, locale);
- paths: for (LocalDir root : roots) {
- for (String cfn : candidateFileNames) {
- lf = root.resolve(cfn);
- if (lf != null)
- break paths;
- }
- }
-
- if (lf != null && isIgnoredFile(lf.getName()))
- lf = null;
-
- if (lf != null) {
- fileCache.put(name, lf);
-
- if (cachingLimit >= 0) {
- long size = lf.size();
- if (size > 0 && size <= cachingLimit)
- lf.cache();
- }
- }
- }
-
- if (lf == null)
- return Optional.empty();
-
- return Optional.of(lf.read());
- }
-
- /**
* Returns the contents of the resource with the specified name.
*
* @param name The resource name.
@@ -224,9 +98,7 @@ public class FileFinder {
* @return The resolved resource contents, or <jk>null</jk> if the
resource was not found.
* @throws IOException Thrown by underlying stream.
*/
- public final Optional<InputStream> getStream(String name, Locale
locale) throws IOException {
- return find(name, locale);
- }
+ public Optional<InputStream> getStream(String name, Locale locale)
throws IOException;
/**
* Returns the file with the specified name.
@@ -235,9 +107,7 @@ public class FileFinder {
* @return An input stream to the file if it exists, or <jk>null</jk>
if it does not.
* @throws IOException If file could not be read.
*/
- public final Optional<InputStream> getStream(String name) throws
IOException {
- return find(name, null);
- }
+ public Optional<InputStream> getStream(String name) throws IOException;
/**
* Returns the file with the specified name as a string.
@@ -246,9 +116,7 @@ public class FileFinder {
* @return The contents of the file as a string. Assumes UTF-8
encoding.
* @throws IOException If file could not be read.
*/
- public final Optional<String> getString(String name) throws IOException
{
- return Optional.ofNullable(IOUtils.read(find(name,
null).orElse(null), IOUtils.UTF8));
- }
+ public Optional<String> getString(String name) throws IOException;
/**
* Returns the file with the specified name as a string.
@@ -260,142 +128,5 @@ public class FileFinder {
* @return The contents of the file as a string. Assumes UTF-8
encoding.
* @throws IOException If file could not be read.
*/
- public Optional<String> getString(String name, Locale locale) throws
IOException {
- return Optional.ofNullable(IOUtils.read(find(name,
locale).orElse(null), IOUtils.UTF8));
- }
-
- /**
- * Returns the candidate file names for the specified file name in the
specified locale.
- *
- * <p>
- * For example, if looking for the <js>"MyResource.txt"</js> file in
the Japanese locale, the iterator will return
- * names in the following order:
- * <ol>
- * <li><js>"MyResource_ja_JP.txt"</js>
- * <li><js>"MyResource_ja.txt"</js>
- * <li><js>"MyResource.txt"</js>
- * </ol>
- *
- * <p>
- * If the locale is <jk>null</jk>, then it will only return
<js>"MyResource.txt"</js>.
- *
- * @param fileName The name of the file to get candidate file names on.
- * @param locale
- * The locale.
- * <br>If <jk>null</jk>, won't look for localized file names.
- * @return An iterator of file names to look at.
- */
- protected List<String> getCandidateFileNames(final String fileName,
final Locale locale) {
-
- if (locale == null)
- return Collections.singletonList(fileName);
-
- List<String> list = new ArrayList<>();
- String baseName = getBaseName(fileName);
- String ext = getExtension(fileName);
-
- for (Locale l : getCandidateLocales(locale)) {
- String ls = l.toString();
- if (ls.isEmpty())
- list.add(fileName);
- else {
- list.add(baseName + "_" + ls + (ext.isEmpty() ?
"" : ('.' + ext)));
- list.add(ls.replace('_', '/') + '/' + fileName);
- }
- }
-
- return list;
- }
-
- /**
- * Returns the candidate locales for the specified locale.
- *
- * <p>
- * For example, if <c>locale</c> is <js>"ja_JP"</js>, then this method
will return:
- * <ol>
- * <li><js>"ja_JP"</js>
- * <li><js>"ja"</js>
- * <li><js>""</js>
- * </ol>
- *
- * @param locale The locale to get the list of candidate locales for.
- * @return The list of candidate locales.
- */
- protected List<Locale> getCandidateLocales(Locale locale) {
- return RB_CONTROL.getCandidateLocales("", locale);
- }
-
- /**
- * Checks for path malformations such as use of <js>".."</js> which can
be used to open up security holes.
- *
- * <p>
- * Default implementation returns <jk>true</jk> if the path is any of
the following:
- * <ul>
- * <li>Is blank or <jk>null</jk>.
- * <li>Contains <js>".."</js> (to prevent traversing out of
working directory).
- * <li>Contains <js>"%"</js> (to prevent URI trickery).
- * </ul>
- *
- * @param path The path to check.
- * @return <jk>true</jk> if the path is invalid.
- */
- protected boolean isInvalidPath(String path) {
- return isEmpty(path) || path.contains("..") ||
path.contains("%");
- }
-
- /**
- * Returns <jk>true</jk> if the file should be ignored based on file
name.
- *
- * @param name The name to check.
- * @return <jk>true</jk> if the file should be ignored.
- */
- protected boolean isIgnoredFile(String name) {
- for (Pattern p : exclude)
- if (p.matcher(name).matches())
- return true;
- for (Pattern p : include)
- if (p.matcher(name).matches())
- return false;
- return true;
- }
-
- private List<String> getIncludePatterns() {
- return
asList(include).stream().map(x->x.pattern()).collect(toList());
- }
-
- private List<String> getExcludePatterns() {
- return
asList(include).stream().map(x->x.pattern()).collect(toList());
- }
-
- /**
- * Returns the settings in this finder as a serializable map for
debugging purposes.
- *
- * @return The settings in this finder as a serializable map
- */
- public OMap toMap() {
- return OMap
- .create()
- .a("class", getClass().getSimpleName())
- .a("roots", roots)
- .a("cachingLimit", cachingLimit)
- .a("include", getIncludePatterns())
- .a("exclude", getExcludePatterns())
- .a("hashCode", hashCode)
- ;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- @Override /* Object */
- public boolean equals(Object o) {
- return o instanceof FileFinder && eq(this, (FileFinder)o,
(x,y)->eq(x.hashCode, y.hashCode) && eq(x.getClass(), y.getClass()) &&
eq(x.roots, y.roots) && eq(x.cachingLimit, y.cachingLimit) &&
eq(x.getIncludePatterns(), y.getIncludePatterns()) &&
eq(x.getExcludePatterns(), y.getExcludePatterns()));
- }
-
- @Override
- public String toString() {
- return toMap().toString();
- }
+ public Optional<String> getString(String name, Locale locale) throws
IOException;
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinderBuilder.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinderBuilder.java
index 84df5c5..e539519 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinderBuilder.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinderBuilder.java
@@ -13,6 +13,7 @@
package org.apache.juneau.cp;
import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.internal.ClassUtils.*;
import java.nio.file.*;
import java.util.*;
@@ -22,7 +23,6 @@ import java.util.stream.*;
import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.internal.*;
-import org.apache.juneau.reflect.*;
/**
* Builder for {@link FileFinder} objects.
@@ -32,6 +32,8 @@ public class FileFinderBuilder {
final Set<LocalDir> roots = new LinkedHashSet<>();
long cachingLimit = -1;
List<Pattern> include = AList.of(Pattern.compile(".*")), exclude =
AList.create();
+ private Class<? extends FileFinder> implClass;
+ private BeanFactory beanFactory;
/**
* Create a new {@link FileFinder} using this builder.
@@ -39,23 +41,12 @@ public class FileFinderBuilder {
* @return A new {@link FileFinder}
*/
public FileFinder build() {
- return new FileFinder(this);
- }
-
- /**
- * Create a new {@link FileFinder} subclass using this builder.
- *
- * <p>
- * Subclass must have a public constructor that takes in a single
{@link FileFinderBuilder} object.
- *
- * @param c The subclass of {@link FileFinder} to instantiate.
- * @param <T> The subclass of {@link FileFinder} to instantiate.
- *
- * @return A new {@link FileFinder}
- * @throws ExecutableException Thrown from constructor.
- */
- public <T extends FileFinder> T build(Class<T> c) throws
ExecutableException {
- return ClassInfo.of(c).getPublicConstructor(this).invoke(this);
+ try {
+ Class<? extends FileFinder> ic = isConcrete(implClass)
? implClass : BasicFileFinder.class;
+ return
BeanFactory.of(beanFactory).addBeans(FileFinderBuilder.class,
this).createBean(ic);
+ } catch (ExecutableException e) {
+ throw new RuntimeException(e.getCause().getMessage(),
e.getCause());
+ }
}
/**
@@ -140,6 +131,33 @@ public class FileFinderBuilder {
return this;
}
+ /**
+ * Specifies the bean factory to use for instantiating the {@link
FileFinder} object.
+ *
+ * <p>
+ * Can be used to instantiate {@link FileFinder} implementations with
injected constructor argument beans.
+ *
+ * @param value The new value for this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public FileFinderBuilder beanFactory(BeanFactory value) {
+ this.beanFactory = value;
+ return this;
+ }
+
+ /**
+ * Specifies a subclass of {@link FileFinder} to create when the {@link
#build()} method is called.
+ *
+ * @param value The new value for this setting.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public FileFinderBuilder implClass(Class<? extends FileFinder> value) {
+ this.implClass = value;
+ return this;
+ }
+
// <FluentSetters>
// </FluentSetters>
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index d892956..4fc916e 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -322,6 +322,20 @@ public final class ClassUtils {
return null;
}
+ /**
+ * Returns <jk>true</jk> if this class is not <jk>null</jk> and isn't
abstract or an interface.
+ *
+ * @param c The class to check.
+ * @return <jk>true</jk> if this class is not <jk>null</jk> and isn't
abstract or an interface.
+ */
+ public static boolean isConcrete(Class<?> c) {
+ if (c == null)
+ return false;
+ ClassInfo ci = ClassInfo.of(c);
+ if (ci.isAbstract())
+ return false;
+ return true;
+ }
/**
* Returns the class name for the specified object.
diff --git
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
index 21f9bef..fc9246c 100644
---
a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
+++
b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
@@ -57,7 +57,7 @@ public class Swagger_Test {
return ip.getSwagger(rc, req.getLocale());
}
- public static class TestClasspathFileFinder extends FileFinder {
+ public static class TestClasspathFileFinder extends BasicFileFinder {
public TestClasspathFileFinder() {
super(FileFinder.create().cp(Swagger_Test.class, null,
false));
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicFileFinder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicFileFinder.java
deleted file mode 100644
index 961ad48..0000000
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicFileFinder.java
+++ /dev/null
@@ -1,53 +0,0 @@
-//
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file *
-// * distributed with this work for additional information regarding copyright
ownership. The ASF licenses this file *
-// * to you 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.apache.juneau.rest;
-
-import org.apache.juneau.cp.*;
-
-/**
- * Basic implementation of a file finder used for finding files for REST
resource classes.
- *
- * <p>
- * This implementation has the following attributes:
- * <ul>
- * <li>Looks for files in the following locations:
- * <li><js>"static"</js> working subdirectory.
- * <li><js>"htdocs"</js> working subdirectory.
- * <li><js>"htdocs"</js> subpackage from this class and all parent
classes.
- * <li><js>"htdocs"</js> root package from this class and all
parent classes.
- * </li>
- * <li>Caches any files smaller than 1MB into memory.
- * <li>Ignores any <js>".class"</js> or <js>".properties"</js> files found.
- * </ul>
- *
- * @seealso {@link RestContext#REST_fileFinder}
- */
-public class BasicFileFinder extends FileFinder {
-
- /**
- * Constructor.
- *
- * @param context The context of the REST resource this finder belongs
to.
- */
- public BasicFileFinder(RestContext context) {
- super(FileFinder
- .create()
- .dir("static")
- .dir("htdocs")
- .cp(context.getResourceClass(), "htdocs", true)
- .cp(context.getResourceClass(), "/htdocs", true)
- .caching(1_000_000)
- .exclude("(?i).*\\.(class|properties)")
- );
- }
-}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProvider.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProvider.java
index 9e410cd..39bc1c3 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProvider.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicSwaggerProvider.java
@@ -23,7 +23,7 @@ import org.apache.juneau.svl.*;
/**
* Basic implementation of a {@link SwaggerProvider}.
- *
+ *
* TODO
*/
public class BasicSwaggerProvider implements SwaggerProvider {
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 47d70d2..f74c4a4 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -1463,7 +1463,7 @@ public class RestContext extends BeanContext {
* <p class='bcode w800'>
* <jc>// Create a file finder that looks for files in the /files
working subdirectory, but overrides the find()
* // method for special handling of special cases.</jc>
- * <jk>public class</jk> MyFileFinder <jk>extends</jk> FileFinder {
+ * <jk>public class</jk> MyFileFinder <jk>extends</jk>
BasicFileFinder {
*
* <jk>public</jk> MyFileFinder() {
* <jk>super</jk>(
@@ -1526,7 +1526,7 @@ public class RestContext extends BeanContext {
* <li><b>ID:</b> {@link
org.apache.juneau.rest.RestContext#REST_fileFinderDefault
REST_fileFinderDefault}
* <li><b>Name:</b> <js>"RestContext.fileFinderDefault.o"</js>
* <li><b>Data type:</b> {@link org.apache.juneau.cp.FileFinder}
- * <li><b>Default:</b> {@link
org.apache.juneau.rest.BasicFileFinder}
+ * <li><b>Default:</b> {@link
org.apache.juneau.cp.BasicFileFinder}
* <li><b>Session property:</b> <jk>false</jk>
* <li><b>Methods:</b>
* <ul>
@@ -3695,7 +3695,7 @@ public class RestContext extends BeanContext {
x = beanFactory.getBean(FileFinder.class).orElse(null);
if (x == null)
- x = getInstanceProperty(REST_fileFinderDefault,
FileFinder.class, null, beanFactory);
+ x = getInstanceProperty(REST_fileFinderDefault,
BasicFileFinder.class, null, beanFactory);
if (x == null)
x = createFileFinderBuilder(resource,
beanFactory).build();
@@ -3761,7 +3761,7 @@ public class RestContext extends BeanContext {
* <ul>
* <li>{@link RestContext}
* <li>{@link BeanFactory}
- * <li>{@link FileFinder}
+ * <li>{@link BasicFileFinder}
* <li>Any {@doc RestInjection injected beans}.
* </ul>
* <li>Resolves it via the bean factory registered in this context.
@@ -3859,7 +3859,7 @@ public class RestContext extends BeanContext {
* <ul>
* <li>{@link RestContext}
* <li>{@link BeanFactory}
- * <li>{@link FileFinder}
+ * <li>{@link BasicFileFinder}
* <li>Any {@doc RestInjection injected beans}.
* </ul>
* <li>Resolves it via the bean factory registered in this context.
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/StaticFiles.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/StaticFiles.java
index 64aac5e..639b275 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/StaticFiles.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/StaticFiles.java
@@ -32,10 +32,10 @@ import org.apache.juneau.internal.*;
* API for retrieving localized static files from either the classpath or file
system.
*
* <p>
- * Provides the same functionality as {@link FileFinder} but adds support for
returning files as {@link BasicHttpResource}
+ * Provides the same functionality as {@link BasicFileFinder} but adds support
for returning files as {@link BasicHttpResource}
* objects with arbitrary headers.
*/
-public class StaticFiles extends FileFinder {
+public class StaticFiles extends BasicFileFinder {
/** Represents no static files */
public static final class Null extends StaticFiles {}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerProviderBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerProviderBuilder.java
index 7c48002..faae720 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerProviderBuilder.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerProviderBuilder.java
@@ -13,6 +13,7 @@
package org.apache.juneau.rest;
import static org.apache.juneau.rest.HttpRuntimeException.*;
+import static org.apache.juneau.internal.ClassUtils.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.http.exception.*;
@@ -35,7 +36,7 @@ public class SwaggerProviderBuilder {
/**
* Creates a new {@link SwaggerProvider} object from this builder.
- *
+ *
* <p>
* Instantiates an instance of the {@link #implClass(Class)
implementation class} or
* else {@link BasicSwaggerProvider} if implementation class was not
specified.
@@ -44,8 +45,8 @@ public class SwaggerProviderBuilder {
*/
public SwaggerProvider build() {
try {
- Class<? extends SwaggerProvider> ic = (implClass ==
null || implClass == SwaggerProvider.class) ? BasicSwaggerProvider.class :
implClass;
- return
BeanFactory.of(beanFactory).addBean(SwaggerProviderBuilder.class,
this).createBean(ic);
+ Class<? extends SwaggerProvider> ic =
isConcrete(implClass) ? implClass : BasicSwaggerProvider.class;
+ return
BeanFactory.of(beanFactory).addBeans(SwaggerProviderBuilder.class,
this).createBean(ic);
} catch (Exception e) {
throw toHttpException(e, InternalServerError.class);
}