blob: e6afa100b244edc3731f71ee850d577965f525c9 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Generated by javadoc (17) -->
<title>ResolverUtil (Apache Log4j Core 2.23.1 API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="declaration: package: org.apache.logging.log4j.core.config.plugins.util, class: ResolverUtil">
<meta name="generator" content="javadoc/ClassWriterImpl">
<link rel="stylesheet" type="text/css" href="../../../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../../../script-dir/jquery-ui.min.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../../../jquery-ui.overrides.css" title="Style">
<script type="text/javascript" src="../../../../../../../../script.js"></script>
<script type="text/javascript" src="../../../../../../../../script-dir/jquery-3.6.1.min.js"></script>
<script type="text/javascript" src="../../../../../../../../script-dir/jquery-ui.min.js"></script>
</head>
<body class="class-declaration-page">
<script type="text/javascript">var evenRowColor = "even-row-color";
var oddRowColor = "odd-row-color";
var tableTab = "table-tab";
var activeTableTab = "active-table-tab";
var pathtoroot = "../../../../../../../../";
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<div class="flex-box">
<header role="banner" class="flex-header">
<nav role="navigation">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="top-nav" id="navbar-top">
<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
<li><a href="../../../../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="nav-bar-cell1-rev">Class</li>
<li><a href="class-use/ResolverUtil.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../../../help-doc.html#class">Help</a></li>
</ul>
</div>
<div class="sub-nav">
<div>
<ul class="sub-nav-list">
<li>Summary:&nbsp;</li>
<li><a href="#nested-class-summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-summary">Method</a></li>
</ul>
<ul class="sub-nav-list">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-detail">Method</a></li>
</ul>
</div>
<div class="nav-list-search"><label for="search-input">SEARCH:</label>
<input type="text" id="search-input" value="search" disabled="disabled">
<input type="reset" id="reset-button" value="reset" disabled="disabled">
</div>
</div>
<!-- ========= END OF TOP NAVBAR ========= -->
<span class="skip-nav" id="skip-navbar-top"></span></nav>
</header>
<div class="flex-content">
<main role="main">
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="sub-title"><span class="package-label-in-type">Package</span>&nbsp;<a href="package-summary.html">org.apache.logging.log4j.core.config.plugins.util</a></div>
<h1 title="Class ResolverUtil" class="title">Class ResolverUtil</h1>
</div>
<div class="inheritance" title="Inheritance Tree"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html" title="class or interface in java.lang" class="external-link">java.lang.Object</a>
<div class="inheritance">org.apache.logging.log4j.core.config.plugins.util.ResolverUtil</div>
</div>
<section class="class-description" id="class-description">
<hr>
<div class="type-signature"><span class="modifiers">public class </span><span class="element-name type-name-label">ResolverUtil</span>
<span class="extends-implements">extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></span></div>
<div class="block"><p>
ResolverUtil is used to locate classes that are available in the/a class path and meet arbitrary conditions. The two
most common conditions are that a class implements/extends another class, or that is it annotated with a specific
annotation. However, through the use of the <a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util"><code>ResolverUtil.Test</code></a> class it is possible to search using arbitrary conditions.
</p>
<p>
A ClassLoader is used to locate all locations (directories and jar files) in the class path that contain classes
within certain packages, and then to load those classes and check them. By default the ClassLoader returned by
<code>Thread.currentThread().getContextClassLoader()</code> is used, but this can be overridden by calling
<a href="#setClassLoader(java.lang.ClassLoader)"><code>setClassLoader(ClassLoader)</code></a> prior to invoking any of the <code>find()</code> methods.
</p>
<p>
General searches are initiated by calling the <a href="#find(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String...)"><code>find(ResolverUtil.Test, String...)</code></a> method and supplying a
package name and a Test instance. This will cause the named package <b>and all sub-packages</b> to be scanned for
classes that meet the test. There are also utility methods for the common use cases of scanning multiple packages for
extensions of particular classes, or classes annotated with a specific annotation.
</p>
<p>
The standard usage pattern for the ResolverUtil class is as follows:
</p>
<pre>
ResolverUtil resolver = new ResolverUtil();
resolver.findInPackage(new CustomTest(), pkg1);
resolver.find(new CustomTest(), pkg1);
resolver.find(new CustomTest(), pkg1, pkg2);
Set&lt;Class&lt;?&gt;&gt; beans = resolver.getClasses();
</pre>
<p>
This class was copied and modified from Stripes - http://stripes.mc4j.org/confluence/display/stripes/Home
</p></div>
</section>
<section class="summary">
<ul class="summary-list">
<!-- ======== NESTED CLASS SUMMARY ======== -->
<li>
<section class="nested-class-summary" id="nested-class-summary">
<h2>Nested Class Summary</h2>
<div class="caption"><span>Nested Classes</span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Class</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color"><code>static interface&nbsp;</code></div>
<div class="col-second even-row-color"><code><a href="ResolverUtil.Test.html" class="type-name-link" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a></code></div>
<div class="col-last even-row-color">
<div class="block">A simple interface that specifies how to test classes to determine if they are to be included in the results
produced by the ResolverUtil.</div>
</div>
</div>
</section>
</li>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<li>
<section class="constructor-summary" id="constructor-summary">
<h2>Constructor Summary</h2>
<div class="caption"><span>Constructors</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Constructor</div>
<div class="table-header col-last">Description</div>
<div class="col-constructor-name even-row-color"><code><a href="#%3Cinit%3E()" class="member-name-link">ResolverUtil</a>()</code></div>
<div class="col-last even-row-color">&nbsp;</div>
</div>
</section>
</li>
<!-- ========== METHOD SUMMARY =========== -->
<li>
<section class="method-summary" id="method-summary">
<h2>Method Summary</h2>
<div id="method-summary-table">
<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab2" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab2', 3)" class="table-tab">Instance Methods</button><button id="method-summary-table-tab4" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab4', 3)" class="table-tab">Concrete Methods</button></div>
<div id="method-summary-table.tabpanel" role="tabpanel">
<div class="summary-table three-column-summary" aria-labelledby="method-summary-table-tab0">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>protected void</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#addIfMatching(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String)" class="member-name-link">addIfMatching</a><wbr>(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;fqn)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Add the class designated by the fully qualified class name provided to the set of resolved classes if and only if
it is approved by the Test supplied.</div>
</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#find(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String...)" class="member-name-link">find</a><wbr>(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>...&nbsp;packageNames)</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Attempts to discover classes that pass the test.</div>
</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#findInPackage(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String)" class="member-name-link">findInPackage</a><wbr>(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;packageName)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Scans for classes starting at the package provided and descending into subpackages.</div>
</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;?&gt;&gt;</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#getClasses()" class="member-name-link">getClasses</a>()</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Provides access to the classes discovered so far.</div>
</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html" title="class or interface in java.lang" class="external-link">ClassLoader</a></code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#getClassLoader()" class="member-name-link">getClassLoader</a>()</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Returns the ClassLoader that will be used for scanning for classes.</div>
</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/net/URI.html" title="class or interface in java.net" class="external-link">URI</a>&gt;</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#getResources()" class="member-name-link">getResources</a>()</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Returns the matching resources.</div>
</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#setClassLoader(java.lang.ClassLoader)" class="member-name-link">setClassLoader</a><wbr>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html" title="class or interface in java.lang" class="external-link">ClassLoader</a>&nbsp;aClassloader)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Sets an explicit ClassLoader that should be used when scanning for classes.</div>
</div>
</div>
</div>
</div>
<div class="inherited-list">
<h3 id="methods-inherited-from-class-java.lang.Object">Methods inherited from class&nbsp;java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></h3>
<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone--" title="class or interface in java.lang" class="external-link">clone</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-" title="class or interface in java.lang" class="external-link">equals</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#finalize--" title="class or interface in java.lang" class="external-link">finalize</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--" title="class or interface in java.lang" class="external-link">getClass</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--" title="class or interface in java.lang" class="external-link">hashCode</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notify--" title="class or interface in java.lang" class="external-link">notify</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notifyAll--" title="class or interface in java.lang" class="external-link">notifyAll</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--" title="class or interface in java.lang" class="external-link">toString</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait--" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait-long-" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait-long-int-" title="class or interface in java.lang" class="external-link">wait</a></code></div>
</section>
</li>
</ul>
</section>
<section class="details">
<ul class="details-list">
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<li>
<section class="constructor-details" id="constructor-detail">
<h2>Constructor Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="&lt;init&gt;()">
<h3>ResolverUtil</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name">ResolverUtil</span>()</div>
</section>
</li>
</ul>
</section>
</li>
<!-- ============ METHOD DETAIL ========== -->
<li>
<section class="method-details" id="method-detail">
<h2>Method Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="getClasses()">
<h3>getClasses</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;?&gt;&gt;</span>&nbsp;<span class="element-name">getClasses</span>()</div>
<div class="block">Provides access to the classes discovered so far. If no calls have been made to any of the <code>find()</code>
methods, this set will be empty.</div>
<dl class="notes">
<dt>Returns:</dt>
<dd>the set of classes that have been discovered.</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="getResources()">
<h3>getResources</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/net/URI.html" title="class or interface in java.net" class="external-link">URI</a>&gt;</span>&nbsp;<span class="element-name">getResources</span>()</div>
<div class="block">Returns the matching resources.</div>
<dl class="notes">
<dt>Returns:</dt>
<dd>A Set of URIs that match the criteria.</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="getClassLoader()">
<h3>getClassLoader</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html" title="class or interface in java.lang" class="external-link">ClassLoader</a></span>&nbsp;<span class="element-name">getClassLoader</span>()</div>
<div class="block">Returns the ClassLoader that will be used for scanning for classes. If no explicit ClassLoader has been set by
the calling, the context class loader will be used.</div>
<dl class="notes">
<dt>Returns:</dt>
<dd>the ClassLoader that will be used to scan for classes</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="setClassLoader(java.lang.ClassLoader)">
<h3>setClassLoader</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name">setClassLoader</span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html" title="class or interface in java.lang" class="external-link">ClassLoader</a>&nbsp;aClassloader)</span></div>
<div class="block">Sets an explicit ClassLoader that should be used when scanning for classes. If none is set then the context
ClassLoader will be used.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>aClassloader</code> - a ClassLoader to use when scanning for classes</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="find(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String...)">
<h3>find</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name">find</span><wbr><span class="parameters">(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>...&nbsp;packageNames)</span></div>
<div class="block">Attempts to discover classes that pass the test. Accumulated classes can be accessed by calling
<a href="#getClasses()"><code>getClasses()</code></a>.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>test</code> - the test to determine matching classes</dd>
<dd><code>packageNames</code> - one or more package names to scan (including subpackages) for classes</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="findInPackage(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String)">
<h3>findInPackage</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name">findInPackage</span><wbr><span class="parameters">(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;packageName)</span></div>
<div class="block">Scans for classes starting at the package provided and descending into subpackages. Each class is offered up to
the Test as it is discovered, and if the Test returns true the class is retained. Accumulated classes can be
fetched by calling <a href="#getClasses()"><code>getClasses()</code></a>.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>test</code> - an instance of <a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util"><code>ResolverUtil.Test</code></a> that will be used to filter classes</dd>
<dd><code>packageName</code> - the name of the package from which to start scanning for classes, e.g. <code>net.sourceforge.stripes</code></dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="addIfMatching(org.apache.logging.log4j.core.config.plugins.util.ResolverUtil.Test,java.lang.String)">
<h3>addIfMatching</h3>
<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name">addIfMatching</span><wbr><span class="parameters">(<a href="ResolverUtil.Test.html" title="interface in org.apache.logging.log4j.core.config.plugins.util">ResolverUtil.Test</a>&nbsp;test,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;fqn)</span></div>
<div class="block">Add the class designated by the fully qualified class name provided to the set of resolved classes if and only if
it is approved by the Test supplied.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>test</code> - the test used to determine if the class matches</dd>
<dd><code>fqn</code> - the fully qualified name of a class</dd>
</dl>
</section>
</li>
</ul>
</section>
</li>
</ul>
</section>
<!-- ========= END OF CLASS DATA ========= -->
</main>
<footer role="contentinfo">
<hr>
<p class="legal-copy"><small><p align="center"> Copyright &copy; 1999-2024 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All Rights Reserved.<br/> Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo, and the Apache Log4j logo are trademarks of The Apache Software Foundation. </p></small></p>
</footer>
</div>
</div>
</body>
</html>