TAMAYA-209: Regenerate new asf-site with newly merged contents.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/commit/40dff215 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/tree/40dff215 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/diff/40dff215 Branch: refs/heads/asf-site Commit: 40dff215d1177a03eff40d7ac7233f0030042d16 Parents: 4f4912e Author: Phil Ottlinger <pottlin...@apache.org> Authored: Mon Dec 19 22:57:27 2016 +0100 Committer: Phil Ottlinger <pottlin...@apache.org> Committed: Mon Dec 19 22:57:27 2016 +0100 ---------------------------------------------------------------------- about.html | 187 +++ api.html | 1117 +++++++++++++++++ archive.html | 193 +++ blog/2013/first-post.html | 171 +++ blog/2013/fourth-post.html | 164 +++ blog/2013/second-post.html | 148 +++ blog/2013/third-post.html | 164 +++ blog/2016/first-post.html | 200 +++ blog/2016/fourth-post.html | 191 +++ blog/2016/second-post.html | 175 +++ blog/2016/third-post.html | 191 +++ community.html | 293 +++++ core.html | 573 +++++++++ css/asciidoctor.css | 512 ++++++++ css/base.css | 52 + css/bootstrap.min.css | 7 + css/prettify.css | 1 + development/community.html | 320 +++++ development/possible-contributions.html | 504 ++++++++ development/source.html | 203 ++++ development/team.html | 318 +++++ devguide.html | 412 +++++++ documentation/api.html | 1141 ++++++++++++++++++ documentation/core.html | 600 +++++++++ documentation/extensions.html | 398 ++++++ documentation/extensions/mod_builder.html | 262 ++++ documentation/extensions/mod_camel.html | 314 +++++ documentation/extensions/mod_cdi.html | 447 +++++++ .../extensions/mod_classloader_support.html | 283 +++++ documentation/extensions/mod_collections.html | 470 ++++++++ documentation/extensions/mod_consul.html | 249 ++++ documentation/extensions/mod_environment.html | 219 ++++ documentation/extensions/mod_etcd.html | 385 ++++++ documentation/extensions/mod_events.html | 508 ++++++++ documentation/extensions/mod_filter.html | 305 +++++ documentation/extensions/mod_formats.html | 466 +++++++ documentation/extensions/mod_functions.html | 342 ++++++ documentation/extensions/mod_injection.html | 704 +++++++++++ documentation/extensions/mod_jodatime.html | 227 ++++ documentation/extensions/mod_json.html | 241 ++++ documentation/extensions/mod_management.html | 301 +++++ .../extensions/mod_metamodel-staged.html | 256 ++++ documentation/extensions/mod_model.html | 796 ++++++++++++ .../extensions/mod_mutable_config.html | 509 ++++++++ documentation/extensions/mod_optional.html | 229 ++++ documentation/extensions/mod_osgi.html | 319 +++++ documentation/extensions/mod_remote.html | 292 +++++ documentation/extensions/mod_resolver.html | 317 +++++ documentation/extensions/mod_resources.html | 341 ++++++ documentation/extensions/mod_server.html | 586 +++++++++ documentation/extensions/mod_spi-support.html | 248 ++++ documentation/extensions/mod_spring.html | 335 +++++ documentation/extensions/mod_usagetracker.html | 368 ++++++ documentation/extensions/mod_validation.html | 303 +++++ documentation/extensions/mod_yaml.html | 292 +++++ documentation/quickstart.html | 402 ++++++ documentation/usecases.html | 1077 +++++++++++++++++ download.html | 274 +++++ examples.html | 240 ++++ extensions.html | 371 ++++++ extensions/mod_builder.html | 235 ++++ extensions/mod_camel.html | 287 +++++ extensions/mod_cdi.html | 420 +++++++ extensions/mod_classloader_support.html | 256 ++++ extensions/mod_collections.html | 443 +++++++ extensions/mod_consul.html | 222 ++++ extensions/mod_environment.html | 192 +++ extensions/mod_etcd.html | 358 ++++++ extensions/mod_events.html | 481 ++++++++ extensions/mod_filter.html | 278 +++++ extensions/mod_formats.html | 439 +++++++ extensions/mod_functions.html | 315 +++++ extensions/mod_injection.html | 677 +++++++++++ extensions/mod_jodatime.html | 200 +++ extensions/mod_json.html | 214 ++++ extensions/mod_management.html | 274 +++++ extensions/mod_metamodel-staged.html | 229 ++++ extensions/mod_model.html | 769 ++++++++++++ extensions/mod_mutable_config.html | 482 ++++++++ extensions/mod_optional.html | 202 ++++ extensions/mod_osgi.html | 292 +++++ extensions/mod_remote.html | 265 ++++ extensions/mod_resolver.html | 290 +++++ extensions/mod_resources.html | 314 +++++ extensions/mod_server.html | 559 +++++++++ extensions/mod_spi-support.html | 221 ++++ extensions/mod_spring.html | 308 +++++ extensions/mod_yaml.html | 265 ++++ favicon.ico | Bin 0 -> 15086 bytes favicons/android-chrome-144x144.png | Bin 0 -> 21238 bytes favicons/android-chrome-192x192.png | Bin 0 -> 34004 bytes favicons/android-chrome-36x36.png | Bin 0 -> 2361 bytes favicons/android-chrome-48x48.png | Bin 0 -> 3627 bytes favicons/android-chrome-72x72.png | Bin 0 -> 6836 bytes favicons/android-chrome-96x96.png | Bin 0 -> 10837 bytes favicons/apple-touch-icon-114x114.png | Bin 0 -> 13188 bytes favicons/apple-touch-icon-120x120.png | Bin 0 -> 14440 bytes favicons/apple-touch-icon-144x144.png | Bin 0 -> 19621 bytes favicons/apple-touch-icon-152x152.png | Bin 0 -> 21329 bytes favicons/apple-touch-icon-180x180.png | Bin 0 -> 28243 bytes favicons/apple-touch-icon-57x57.png | Bin 0 -> 4357 bytes favicons/apple-touch-icon-60x60.png | Bin 0 -> 4710 bytes favicons/apple-touch-icon-72x72.png | Bin 0 -> 6328 bytes favicons/apple-touch-icon-76x76.png | Bin 0 -> 6854 bytes favicons/apple-touch-icon-precomposed.png | Bin 0 -> 31150 bytes favicons/apple-touch-icon.png | Bin 0 -> 28243 bytes favicons/browserconfig.xml | 12 + favicons/favicon-16x16.png | Bin 0 -> 1922 bytes favicons/favicon-194x194.png | Bin 0 -> 31800 bytes favicons/favicon-32x32.png | Bin 0 -> 2932 bytes favicons/favicon-96x96.png | Bin 0 -> 10679 bytes favicons/favicon.ico | Bin 0 -> 15086 bytes favicons/manifest.json | 41 + favicons/mstile-144x144.png | Bin 0 -> 2499 bytes favicons/mstile-150x150.png | Bin 0 -> 2397 bytes favicons/mstile-310x150.png | Bin 0 -> 2638 bytes favicons/mstile-310x310.png | Bin 0 -> 5949 bytes favicons/mstile-70x70.png | Bin 0 -> 1731 bytes feed.xml | 115 ++ fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes fonts/glyphicons-halflings-regular.svg | 229 ++++ fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes highleveldesign.html | 444 +++++++ history.html | 205 ++++ index.html | 269 +++++ js/bootstrap.min.js | 6 + js/html5shiv.min.js | 4 + js/jquery-1.11.1.min.js | 4 + js/prettify.js | 30 + logos/egg-logo2.png | Bin 0 -> 7241 bytes quickstart.html | 375 ++++++ release-guide.html | 558 +++++++++ sitemap.xml | 154 +++ source.html | 176 +++ start.html | 199 +++ usecases.html | 1050 ++++++++++++++++ 137 files changed, 34871 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/40dff215/about.html ---------------------------------------------------------------------- diff --git a/about.html b/about.html new file mode 100644 index 0000000..e46a6d2 --- /dev/null +++ b/about.html @@ -0,0 +1,187 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset="utf-8"/> + <title>About</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content=""/> + <meta name="author" content=""/> + <meta name="keywords" content=""/> + <meta name="generator" content="'JBake '+'${version}"/> + + <!-- Le styles --> + <link href="css/bootstrap.min.css" rel="stylesheet"/> + <link href="css/asciidoctor.css" rel="stylesheet"/> + <link href="css/base.css" rel="stylesheet"/> + <link href="css/prettify.css" rel="stylesheet"/> + + <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="js/html5shiv.min.js"></script> + <![endif]--> + + <!-- Fav and touch icons from ASF --> + <link rel="shortcut icon" href="favicon.ico"/> + <link rel="apple-touch-icon" sizes="57x57" href="favicons/apple-touch-icon-57x57.png"/> + <link rel="apple-touch-icon" sizes="60x60" href="favicons/apple-touch-icon-60x60.png"/> + <link rel="apple-touch-icon" sizes="72x72" href="favicons/apple-touch-icon-72x72.png"/> + <link rel="apple-touch-icon" sizes="76x76" href="favicons/apple-touch-icon-76x76.png"/> + <link rel="apple-touch-icon" sizes="114x114" href="favicons/apple-touch-icon-114x114.png"/> + <link rel="apple-touch-icon" sizes="120x120" href="favicons/apple-touch-icon-120x120.png"/> + <link rel="apple-touch-icon" sizes="144x144" href="favicons/apple-touch-icon-144x144.png"/> + <link rel="apple-touch-icon" sizes="152x152" href="favicons/apple-touch-icon-152x152.png"/> + <link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon-180x180.png"/> + <link rel="icon" type="image/png" href="favicons/favicon-32x32.png" sizes="32x32"/> + <link rel="icon" type="image/png" href="favicons/favicon-194x194.png" sizes="194x194"/> + <link rel="icon" type="image/png" href="favicons/favicon-96x96.png" sizes="96x96"/> + <link rel="icon" type="image/png" href="favicons/android-chrome-192x192.png" sizes="192x192"/> + <link rel="icon" type="image/png" href="favicons/favicon-16x16.png" sizes="16x16"/> + <link rel="manifest" href="favicons/manifest.json"/> + <link rel="shortcut icon" href="favicons/favicon.ico"/> + <meta name="msapplication-TileColor" content="#603cba"/> + <meta name="msapplication-TileImage" content="favicons/mstile-144x144.png"/> + <meta name="msapplication-config" content="favicons/browserconfig.xml"/> + <meta name="theme-color" content="#303284"/> + </head> + <body onload="prettyPrint()"> + <div id="wrap"> + <div> + + <!-- Fixed navbar --> + <div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="index.html">Apache Tamaya (incubating)</a> + </div> + <div class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li><a href="start.html">Tamaya in 5 minutes</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="documentation/usecases.html">Use Cases and Requirements</a></li> + <li><a href="documentation/quickstart.html">Quickstart</a></li> + <li><a href="documentation/api.html">API</a></li> + <li><a href="documentation/core.html">Core</a></li> + <li><a href="documentation/extensions.html">Extension Guide</a></li> + <li class="divider"></li> + <li><a href="apidocs/index.html">Javadoc ${tamaya_version} (external)</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Development <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="development/source.html">Sources</a></li> + <li><a href="development/community.html">Community</a></li> + <li><a href="development/team.html">Project Team</a></li> + <li><a href="devguide.html">Development Guide</a></li> + <li><a href="release-guide.html">Release Guide</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Releases <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="download.html">Download</a></li> + <li><a href="history.html">Release History</a></li> + </ul> + </li> +<!-- Example: + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link</a></li> + </ul> + </li> +--> + <li><a href="sitemap.xml">Sitemap</a></li> + <li><a href="feed.xml">Subscribe</a></li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + + </div> + <div class="container"> + + <div class="page-header"> + <h1>About</h1> + </div> + + <p><em>2016-12-18</em></p> + + <p> +Tamaya provides a flexible and powerful Configuration Solution for Java developers using Java SE as well as for more complex usage scenarios like Cloud or Java EE. It provides a modern type-safe property based Configuration API combined with a powerful environment model and a flexible SPI. + +Rationale +Configuration is one of the most prominent cross-cutting concerns similar to logging. Most of us already have been writing similar code again and again in each of our projects. Sometimes in a similar way but mostly always slightly different, but certainly with high coupling to your configuration backends. Given your code is reused or integrated some how, or deployed by some customers, struggling starts: not supported backends, different policies, missing combination and validation mechanisms and so on. Tamaya solves all this by defining a common API and backend SPI. Your code is decoupled from the configuration backend. There is no difference if your code is deployed on your dev box or in a clustered Docker environment in production, it stays the same! + +Features +Unified Configuration API +Pluggable Configuration Backends +Enforceable Configuration Policies +Configuration Validation and Documentation +Seemless Enterprise Integration + +Quickstart +Using Apache Tamaya is simple: + +Add org.apache.tamaya:tamaya-core:0.2-incubating to your dependencies. +Add your config to META-INF/javaconfiguration.properties +Access your configuration by ConfigurationProvider.getConfiguration() and use it. +Look at the extension modules to customize your setup! +Enjoy! +</p> + + <hr /> + </div> + </div> + <div> + <div id="push"></div> + + <div id="footer"> + <div class="container"> + <p class="muted credit">© 2014-2016 Apache Software Foundation | Mixed with <a href="http://getbootstrap.com/">Bootstrap v3.1.1</a> + | Baked with <a href="http://jbake.org">JBake <span>v2.5.0</span></a> + at <span>2016-12-19</span> + </p> + <p> + <b>Disclaimer</b> + Apache Tamaya (incubating) is an effort undergoing + incubation at + The Apache Software Foundation (ASF), sponsored by + the name of Apache Incubator. Incubation is required of + all newly accepted projects until a further review indicates + that the infrastructure, communications, and decision making + process have stabilized in a manner consistent with other + successful ASF projects. While incubation status is not + necessarily a reflection of the completeness or stability of + the code, it does indicate that the project has yet to + be fully endorsed by the ASF.<br /> + <a href="http://incubator.apache.org/guides/website.html" style="border:0px;" target="_target"><img class="incubator-logo" src="logos/egg-logo2.png"/></a> + </p> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="js/jquery-1.11.1.min.js"></script> + <script src="js/bootstrap.min.js"></script> + <script src="js/prettify.js"></script> + + </div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/40dff215/api.html ---------------------------------------------------------------------- diff --git a/api.html b/api.html new file mode 100644 index 0000000..8c0a872 --- /dev/null +++ b/api.html @@ -0,0 +1,1117 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset="utf-8"/> + <title>Tamaya Incubator</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content=""/> + <meta name="author" content=""/> + <meta name="keywords" content=""/> + <meta name="generator" content="'JBake '+'${version}"/> + + <!-- Le styles --> + <link href="css/bootstrap.min.css" rel="stylesheet"/> + <link href="css/asciidoctor.css" rel="stylesheet"/> + <link href="css/base.css" rel="stylesheet"/> + <link href="css/prettify.css" rel="stylesheet"/> + + <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="js/html5shiv.min.js"></script> + <![endif]--> + + <!-- Fav and touch icons from ASF --> + <link rel="shortcut icon" href="favicon.ico"/> + <link rel="apple-touch-icon" sizes="57x57" href="favicons/apple-touch-icon-57x57.png"/> + <link rel="apple-touch-icon" sizes="60x60" href="favicons/apple-touch-icon-60x60.png"/> + <link rel="apple-touch-icon" sizes="72x72" href="favicons/apple-touch-icon-72x72.png"/> + <link rel="apple-touch-icon" sizes="76x76" href="favicons/apple-touch-icon-76x76.png"/> + <link rel="apple-touch-icon" sizes="114x114" href="favicons/apple-touch-icon-114x114.png"/> + <link rel="apple-touch-icon" sizes="120x120" href="favicons/apple-touch-icon-120x120.png"/> + <link rel="apple-touch-icon" sizes="144x144" href="favicons/apple-touch-icon-144x144.png"/> + <link rel="apple-touch-icon" sizes="152x152" href="favicons/apple-touch-icon-152x152.png"/> + <link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon-180x180.png"/> + <link rel="icon" type="image/png" href="favicons/favicon-32x32.png" sizes="32x32"/> + <link rel="icon" type="image/png" href="favicons/favicon-194x194.png" sizes="194x194"/> + <link rel="icon" type="image/png" href="favicons/favicon-96x96.png" sizes="96x96"/> + <link rel="icon" type="image/png" href="favicons/android-chrome-192x192.png" sizes="192x192"/> + <link rel="icon" type="image/png" href="favicons/favicon-16x16.png" sizes="16x16"/> + <link rel="manifest" href="favicons/manifest.json"/> + <link rel="shortcut icon" href="favicons/favicon.ico"/> + <meta name="msapplication-TileColor" content="#603cba"/> + <meta name="msapplication-TileImage" content="favicons/mstile-144x144.png"/> + <meta name="msapplication-config" content="favicons/browserconfig.xml"/> + <meta name="theme-color" content="#303284"/> + </head> + <body onload="prettyPrint()"> + <div id="wrap"> + <div> + + <!-- Fixed navbar --> + <div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="">Apache Tamaya (incubating)</a> + </div> + <div class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li><a href="index.html">Home</a></li> + <li><a href="quickstart.html">Quickstart</a></li> + <li><a href="index.html">Documentation</a></li> + <li><a href="/apidocs/index.html">API</a></li> + <li><a href="index.html">Development</a></li> + <li><a href="index.html">Releases</a></li> + <li><a href="about.html">About</a></li> + <li><a href="sitemap.xml">Sitemap</a></li> + <li><a href="feed.xml">Subscribe</a></li> +<!-- + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link</a></li> + </ul> + </li> +--> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + + </div> + <div class="container"> + + <div class="page-header"> + <h1></h1> + </div> + + <p><em>2016-11-28</em></p> + + <p><div class="sect1"> +<h2 id="CoreDesign">Apache Tamaya: API</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Though Tamaya is a very powerful and flexible solution there are basically only a few simple core concepts required +that are the base of all the other mechanisms. As a starting point we recommend you read the corresponding +l<a href="HighLevelDesign.html">High Level Design Documentation</a></p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="API">The Tamaya API</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The API provides the artifacts as described in the <a href="HighLevelDesign.html">High Level Design Documentation</a>, which are:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>A simple but complete SE <strong>API</strong> for accessing key/value based <em>Configuration</em>:</p> +<div class="ulist"> +<ul> +<li> +<p>Configuration hereby models configuration, the main interface of Tamaya. Configuration provides</p> +<div class="ulist"> +<ul> +<li> +<p>access to literal key/value pairs.</p> +</li> +<li> +<p>functional extension points (with, query) using a unary ConfigOperator or +a function ConfigurationQuery<T>.</p> +</li> +</ul> +</div> +</li> +<li> +<p>ConfigurationProvider provides with getConfiguration() the static entry point for accessing configuration.</p> +</li> +<li> +<p>ConfigException defines a runtime exception for usage by the configuration system.</p> +</li> +<li> +<p>TypeLiteral provides a possibility to type safely define the target type to be returned by a registered +PropertyProvider.</p> +</li> +<li> +<p>PropertyConverter, which defines conversion of configuration values (String) into any required target type.</p> +</li> +</ul> +</div> +</li> +<li> +<p>Additionally the <strong>SPI</strong> provides:</p> +<div class="ulist"> +<ul> +<li> +<p><em>PropertySource:</em> is the the SPI for adding configuration data. A PropertySource hereby</p> +<div class="ulist"> +<ul> +<li> +<p>is designed as a minimalistic interface that be implemented by any kind of data provider (local or remote)</p> +</li> +<li> +<p>provides single access for key/value pairs in raw format as String key/values only (getPropertyValue).</p> +</li> +<li> +<p>can optionally support scanning of its provided values, implementing getProperties().</p> +</li> +</ul> +</div> +</li> +<li> +<p><em>PropertySourceProvider:</em> allows to register multiple property sources dynamically, e.g. all config files found in +file system folder..</p> +</li> +<li> +<p>ConfigurationProviderSpi defines the SPI that is used as a backing bean for the ConfigurationProvider +singleton.</p> +</li> +<li> +<p>PropertyFilter, which allows filtering of property values prior getting returned to the caller.</p> +</li> +<li> +<p>PropertyValueCombinationPolicy optionally can be registered to change the way how different key/value +pairs are combined to build up the final Configuration passed over to the filters registered.</p> +</li> +<li> +<p>ConfigurationContext, which provides a container for all the artifacts needed to build up a Configuration. +For example a context contains the property sources, property filters, converters and combination policy used. +Also the ordering of the property sources is defined by the context. A context instance given a +Configuration can be created by calling ConfigurationProvider.createConfiguration(context);.</p> +</li> +<li> +<p>Similarly a ConfigurationContext can be created using a ConfigurationContextBuilder. This builder can be +obtained calling ConfigurationProvider.getConfigurationContextBuilder();.</p> +</li> +<li> +<p>ServiceContext, which provides access to the components loaded, depending on the current runtime stack.</p> +</li> +<li> +<p>ServiceContextManager provides static access to the ServiceContext loaded.</p> +</li> +</ul> +</div> +</li> +</ul> +</div> +<div class="paragraph"> +<p>This is also reflected in the main packages of the API:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>org.apache.tamaya contains the main API abstractions used by users.</p> +</li> +<li> +<p>org.apache.tamaya.spi contains the SPI interfaces to be implemented by implementations and the ServiceContext +mechanism.</p> +</li> +</ul> +</div> +<div class="sect2"> +<h3 id="APIKeyValues">Key/Value Pairs</h3> +<div class="paragraph"> +<p>Basically configuration is a very generic concept. Therefore it should be modelled in a generic way. The most simple +and most commonly used approach are simple literal key/value pairs. So the core building block of {name} are key/value pairs. +You can think of a common .properties file, e.g.</p> +</div> +<div class="listingblock"> +<div class="title">A simple properties file</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-properties" data-lang="properties">a.b.c=cVal +a.b.c.1=cVal1 +a.b.c.2=cVal2 +a=aVal +a.b=abVal +a.b2=abVal</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Now you can use java.util.Properties to read this file and access the corresponding properties, e.g.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-properties" data-lang="properties">Properties props = new Properties(); +props.readProperties(...); +String val = props.getProperty("a.b.c"); +val = props.getProperty("a.b.c.1"); +...</code></pre> +</div> +</div> +<div class="sect3"> +<h4 id="_why_using_strings_only">Why Using Strings Only</h4> +<div class="paragraph"> +<p>There are good reason to keep of non String-values as core storage representation of configuration. Mostly +there are several huge advantages:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Strings are simple to understand</p> +</li> +<li> +<p>Strings are human readable and therefore easy to prove for correctness</p> +</li> +<li> +<p>Strings can easily be used within different language, different VMs, files or network communications.</p> +</li> +<li> +<p>Strings can easily be compared and manipulated</p> +</li> +<li> +<p>Strings can easily be searched, indexed and cached</p> +</li> +<li> +<p>It is very easy to provide Strings as configuration, which gives much flexibility for providing configuration in +production as well in testing.</p> +</li> +<li> +<p>and more…​</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>On the other side there are also disadvantages:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Strings are inherently not type safe, they do not provide validation out of the box for special types, such as +numbers, dates etc.</p> +</li> +<li> +<p>In many cases you want to access configuration in a typesafe way avoiding conversion to the target types explicitly +throughout your code.</p> +</li> +<li> +<p>Strings are neither hierarchical nor multi-valued, so mapping hierarchical and collection structures requires some +extra efforts.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Nevertheless most of these advantages can be mitigated easily, hereby still keeping all the benefits from above:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>Adding type safe adapters on top of String allow to add any type easily, that can be directly mapped out of Strings. +This includes all common base types such as numbers, dates, time, but also timezones, formatting patterns and more.</p> +</li> +<li> +<p>Also multi-valued, complex and collection types can be defined as a corresponding PropertyAdapter knows how to +parse and create the target instance required.</p> +</li> +<li> +<p>String s also can be used as references pointing to other locations and formats, where configuration is +accessible.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>[[API Configuration]] +=== Configuration</p> +</div> +<div class="paragraph"> +<p>Configuration is the main API provided by Tamaya. It allows reading of single property values or the whole +property map, but also supports type safe access:</p> +</div> +<div class="listingblock"> +<div class="title">Interface Configuration</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public interface Configuration{ + String get(String key); + String getOrDefault(String key, String value); + <T> T get(String key, Class<T> type); + <T> T getOrDefault(String key, Class<T> type, T defaultValue); + <T> T get(String key, TypeLiteral<T> type); + <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue); + Map<String,String> getProperties(); + + // extension points + Configuration with(ConfigOperator operator); + <T> T query(ConfigQuery<T> query); + + ConfigurationContext getContext(); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby</p> +</div> +<div class="ulist"> +<ul> +<li> +<p><T> T get(String, Class<T>) provides type safe accessors for all basic wrapper types of the JDK.</p> +</li> +<li> +<p>with, query provide the extension points for adding additional functionality.</p> +</li> +<li> +<p>getProperties() provides access to all key/values, whereas entries from non scannable property sources may not +be included.</p> +</li> +<li> +<p>getOrDefault allows to pass default values as needed, returned if the requested value evaluated to null.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>The class TypeLiteral is basically similar to the same class provided with CDI:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class TypeLiteral<T> implements Serializable { + + [...] + + protected TypeLiteral(Type type) { + this.type = type; + } + + protected TypeLiteral() { } + + public static <L> TypeLiteral<L> of(Type type){...} + public static <L> TypeLiteral<L> of(Class<L> type){...} + + public final Type getType() {...} + public final Class<T> getRawType() {...} + + public static Type getGenericInterfaceTypeParameter(Class<?> clazz, Class<?> interfaceType){...} + public static Type getTypeParameter(Class<?> clazz, Class<?> interfaceType){...} + + [...] +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Instances of Configuration can be accessed from the ConfigurationProvider singleton:</p> +</div> +<div class="listingblock"> +<div class="title">Accessing Configuration</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Configuration config = ConfigurationProvider.getConfiguration();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby the singleton is backed up by an instance of ConfigurationProviderSpi.</p> +</div> +</div> +<div class="sect3"> +<h4 id="PropertyConverter">Property Type Conversion</h4> +<div class="paragraph"> +<p>As illustrated in the previous section, Configuration also to access non String types. Nevertheless internally +all properties are strictly modelled as pure Strings only, so non String types must be derived by converting the +configured String values into the required target type. This is achieved with the help of PropertyConverters:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public interface PropertyConverter<T>{ + T convert(String value, ConversionContext context); + //X TODO Collection<String> getSupportedFormats(); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The ConversionContext contains additional meta-information for the accessed key, inclusing the key’a name and +additional metadata.</p> +</div> +<div class="paragraph"> +<p>PropertyConverter instances can be implemented and registered by default using the ServiceLoader. Hereby +a configuration String value is passed to all registered converters for a type in order of their annotated @Priority +value. The first non-null result of a converter is then returned as the current configuration value.</p> +</div> +<div class="paragraph"> +<p>Access to converters is provided by the current ConfigurationContext, which is accessible from +the ConfigurationProvider singleton.</p> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="ExtensionPoints">Extension Points</h3> +<div class="paragraph"> +<p>We are well aware of the fact that this library will not be able to cover all kinds of use cases. Therefore +we have added functional extension mechanisms to Configuration that were used in other areas of the Java eco-system +as well:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>with(ConfigOperator operator) allows to pass arbitrary unary functions that take and return instances of +Configuration. Operators can be used to cover use cases such as filtering, configuration views, security +interception and more.</p> +</li> +<li> +<p>query(ConfigQuery query) allows to apply a function returning any kind of result based on a +Configuration instance. Queries are used for accessing/deriving any kind of data based on of a Configuration +instance, e.g. accessing a Set<String> of root keys present.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>Both interfaces hereby are functional interfaces. Because of backward compatibility with Java 7 we did not use +UnaryOperator and Function from the java.util.function package. Nevertheless usage is similar, so you can +use Lambdas and method references in Java 8:</p> +</div> +<div class="listingblock"> +<div class="title">Applying a ConfigurationQuery using a method reference</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigSecurity securityContext = ConfigurationProvider.getConfiguration().query(ConfigSecurity::targetSecurityContext);</code></pre> +</div> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<div class="title">Note</div> +</td> +<td class="content"> +ConfigSecurity is an arbitrary class only for demonstration purposes. +</td> +</tr> +</table> +</div> +<div class="paragraph"> +<p>Operator calls basically look similar:</p> +</div> +<div class="listingblock"> +<div class="title">Applying a ConfigurationOperator using a lambda expression:</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Configuration secured = ConfigurationProvider.getConfiguration() + .with((config) -> + config.get("foo")!=null?; + FooFilter.apply(config): + config);</code></pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="ConfigException">ConfigException</h3> +<div class="paragraph"> +<p>The class ConfigException models the base <strong>runtime</strong> exception used by the configuration system.</p> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="SPI">SPI</h2> +<div class="sectionbody"> +<div class="sect2"> +<h3 id="PropertySource">Interface PropertySource</h3> +<div class="paragraph"> +<p>We have seen that constraining configuration aspects to simple literal key/value pairs provides us with an easy to +understand, generic, flexible, yet expendable mechanism. Looking at the Java language features a java.util.Map<String, +String> and java.util.Properties basically model these aspects out of the box.</p> +</div> +<div class="paragraph"> +<p>Though there are advantages in using these types as a model, there are some severe drawbacks, notably implementation +of these types is far not trivial and the collection API offers additional functionality not useful when aiming +for modelling simple property sources.</p> +</div> +<div class="paragraph"> +<p>To render an implementation of a custom PropertySource as convenient as possible only the following methods were +identified to be necessary:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public interface PropertySource{ + int getOrdinal(); + String getName(); + String get(String key); + boolean isScannable(); + Map<String, String> getProperties(); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>get looks similar to the methods on Map. It may return null in case no such entry is available.</p> +</li> +<li> +<p>getProperties allows to extract all property data to a Map<String,String>. Other methods like containsKey, +keySet as well as streaming operations then can be applied on the returned Map instance.</p> +</li> +<li> +<p>But not in all scenarios a property source may be scannable, e.g. when looking up keys is very inefficient, it +may not make sense to iterator over all keys to collect the corresponding properties. +This can be evaluated by calling isScannable(). If a PropertySource is defined as non scannable accesses to +getProperties() may not return all key/value pairs that would be available when accessed directly using the +String get(String) method.</p> +</li> +<li> +<p>getOrdinal() defines the ordinal of the PropertySource. Property sources are managed in an ordered chain, where +property sources with higher ordinals override the ones with lower ordinals. If ordinal are the same, the natural +ordering of the fulloy qualified class names of the property source implementations are used. The reason for +not using @Priority annotations is that property sources can define dynamically their ordinals, e.g. based on +a property contained with the configuration itself.</p> +</li> +<li> +<p>Finally getName() returns a (unique) name that identifies the PropertySource within the current +ConfigurationContext.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>This interface can be implemented by any kind of logic. It could be a simple in memory map, a distributed configuration +provided by a data grid, a database, the JNDI tree or other resources. Or it can be a combination of multiple +property sources with additional combination/aggregation rules in place.</p> +</div> +<div class="paragraph"> +<p>PropertySources are by default registered using the Java ServiceLoader or the mechanism provided by the current + active ServiceContext.</p> +</div> +</div> +<div class="sect2"> +<h3 id="PropertySourceProvider">Interface PropertySourceProvider</h3> +<div class="paragraph"> +<p>Instances of this type can be used to register multiple instances of PropertySource.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">// @FunctionalInterface in Java 8 +public interface PropertySourceProvider{ + Collection<PropertySource> getPropertySources(); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>This allows to evaluate the property sources to be read/that are available dynamically. All property sources +are read out and added to the current chain of PropertySource instances within the current ConfigurationContext, +refer also to <a id="ConfigurationContext"></a>.</p> +</div> +<div class="paragraph"> +<p>PropertySourceProviders are by default registered using the Java ServiceLoader or the mechanism provided by the +current active ServiceContext.</p> +</div> +</div> +<div class="sect2"> +<h3 id="PropertyFilter">Interface PropertyFilter</h3> +<div class="paragraph"> +<p>Also PropertyFilters can be added to a Configuration. They are evaluated before a Configuration instance is +passed to the user. Filters can hereby used for multiple purposes, such as</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>resolving placeholders</p> +</li> +<li> +<p>masking sensitive entries, such as passwords</p> +</li> +<li> +<p>constraining visibility based on the current active user</p> +</li> +<li> +<p>…​</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>PropertyFilters are by default registered using the Java ServiceLoader or the mechanism provided by the current +active ServiceContext. Similar to property sources they are managed in an ordered filter chain, based on the +applied @Priority annotations.</p> +</div> +<div class="paragraph"> +<p>A PropertyFilter is defined as follows:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">// Functional Interface +public interface PropertyFilter{ + String filterProperty(String value, FilterContext context); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>returning null will remove the key from the final result</p> +</li> +<li> +<p>non null values are used as the current value of the key. Nevertheless for resolving multi-step dependencies +filter evaluation has to be continued as long as filters are still changing some of the values to be returned. +To prevent possible endless loops after a defined number of loops evaluation is stopped.</p> +</li> +<li> +<p>FilterContext provides additional metdata, inclusing the key accessed, which is useful in many use cases.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>This method is called each time a single entry is accessed, and for each property in a full properties result.</p> +</div> +<div class="sect3"> +<h4 id="PropertyValueCombinationPolicy">Interface PropertyValueCombinationPolicy</h4> +<div class="paragraph"> +<p>This interface can be implemented optional. It can be used to adapt the way how property key/value pairs are combined to +build up the final Configuration to be passed over to the PropertyFilters. The default implementation is just +overriding all values read before with the new value read. Nevertheless for collections and other use cases it is +often useful to have alternate combination policies in place, e.g. for combining values from previous sources with the +new value. Finally looking at the method’s signature it may be surprising to find a Map for the value. The basic +value hereby is defined by currentValue.get(key). Nevertheless the Map may also contain additional meta entries, +which may be considered by the policy implementation.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">// FunctionalInterface +public interface PropertyValueCombinationPolicy{ + + PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = + new PropertyValueCombinationPolicy(){ + @Override + public Map<String,String> collect(Map<String,String> currentValue, String key, + PropertySource propertySource) { + PropertyValue value = propertySource.get(key); + return value!=null?value.getConfigEntries():currentValue; + } + }; + + String collect(Map<String,String> currentValue currentValue, String key, + PropertySource propertySource); + +}</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="ConfigurationContext">The Configuration Context</h4> +<div class="paragraph"> +<p>A Configuration is created from a ConfigurationContext, which is +accessible from Configuration.getContext():</p> +</div> +<div class="listingblock"> +<div class="title">Accessing the current ConfigurationContext</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationContext context = ConfigurationProvider.getConfiguration().getContext();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The ConfigurationContext provides access to the internal artifacts that determine the final Configuration and +also defines the ordering of the property sources, filters and converters contained:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>PropertySources registered (including the PropertySources provided from PropertySourceProvider instances).</p> +</li> +<li> +<p>PropertyFilters registered, which filter values before they are returned to the client</p> +</li> +<li> +<p>PropertyConverter instances that provide conversion functionality for converting String values to any other types.</p> +</li> +<li> +<p>the current PropertyValueCombinationPolicy that determines how property values from different PropertySources are +combined to the final property value returned to the client.</p> +</li> +</ul> +</div> +</div> +<div class="sect3"> +<h4 id="Mutability">Changing the current Configuration Context</h4> +<div class="paragraph"> +<p>A ConfigurationContext is not mutable once it is created. In many cases mutability is also not needed. Nevertheless +there are use cases where the current ConfigurationContext (and +consequently Configuration) must be adapted:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>New configuration files where detected in a folder observed by Tamaya.</p> +</li> +<li> +<p>Remote configuration, e.g. stored in a database or alternate ways has been updated and the current system must +be adapted to these changes.</p> +</li> +<li> +<p>The overall configuration context is manually setup by the application logic.</p> +</li> +<li> +<p>Within unit testing alternate configuration setup should be setup to meet the configuration requirements of the +tests executed.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>In such cases the ConfigurationContext must be changed, meaning it must be possible:</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>to add or remove PropertySource instances</p> +</li> +<li> +<p>to add or remove PropertyFilter instances</p> +</li> +<li> +<p>to add or remove PropertyConverter instances</p> +</li> +<li> +<p>to redefine the current PropertyValueCombinationPolicy instances.</p> +</li> +</ul> +</div> +<div class="paragraph"> +<p>This can be achieved by obtaining an instance of ConfigurationContextBuilder. Instances of this builder can be +accessed either</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>calling ConfigurationContext.toBuilder(), hereby returning a builder instance preinitialized with the values from the +current ConfigurationContext.</p> +</li> +<li> +<p>calling ConfigurationProvider.getConfigurationContextBuilder().</p> +</li> +</ul> +</div> +<div class="listingblock"> +<div class="title">Accessing a ConfigurationContextBuilder</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationContextBuilder preinitializedContextBuilder = ConfigurationProvider.getConfiguration().getContext().toBuilder(); +ConfigurationContextBuilder emptyContextBuilder = ConfigurationProvider.getConfigurationContextBuilder();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>With such a builder a new ConfigurationContext can be created and then applied:</p> +</div> +<div class="listingblock"> +<div class="title">Creating and applying a new ConfigurationContext</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationContext context = ConfigurationProvider.getConfiguration().getContext() + .toBuilder(); + .addPropertySources(new MyPropertySource()) + .addPropertyFilter(new MyFilter()) + .build();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby the builder provides several methods for adding, removing of property sources and also operations +for programmatically change the property sourcepriorities, e.g.</p> +</div> +<div class="listingblock"> +<div class="title">Chain manipulation using ConfigurationContextBuilder</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">PropertySource propertySource = builder.getPropertySource("sourceId"); + +// changing the priority of a property source. The ordinal value hereby is not considered. +// Instead the position of the property source within the chain is changed. +builder.decreasePriority(propertySource); + +// Alternately a comparator expression can be passed to establish the defined ordering... +builder.sortPropertyFilters(MyFilterComparator::compare);</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Finally if the new context is ready a new configuration can be created, or the context is applied to the +current configuration.</p> +</div> +<div class="listingblock"> +<div class="title">Creating and applying a new ConfigurationContext</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationContext context = builder.build(); + +// Creates a new matching Configuration instance +Configuration newConfig = ConfigurationProvider.createConfiguration(context); + +// Apply the new context to replace the current configuration: +ConfigurationProvider.setConfigurationContext(context);</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby ConfigurationProvider.setConfigurationContext(context) can throw an UnsupportedOperationException. +This can be checked by calling the method boolean ConfigurationProvider.isConfigurationContextSettable().</p> +</div> +</div> +<div class="sect3"> +<h4 id="ConfigurationProviderSpi">Implementing and Managing Configuration</h4> +<div class="paragraph"> +<p>One of the most important SPI in Tamaya if the ConfigurationProviderSpi interface, which is backing up the +ConfigurationProvider singleton. Implementing this class allows</p> +</div> +<div class="ulist"> +<ul> +<li> +<p>to fully determine the implementation class for Configuration</p> +</li> +<li> +<p>to manage the current ConfigurationContext in the scope and granularity required.</p> +</li> +<li> +<p>to provide access to the right Configuration/ConfigurationContext based on the current runtime context.</p> +</li> +<li> +<p>Performing changes as set with the current ConfigurationContextBuilder.</p> +</li> +</ul> +</div> +</div> +</div> +</div> +</div> +<h1 id="_interface_configurationcontextbuilder" class="sect0">Interface ConfigurationContextBuilder</h1> +<div class="paragraph"> +<p>Unresolved directive in <stdin> - include::temp-properties-files-for-site/attributes.adoc[]</p> +</div> +<div class="sect1"> +<h2 id="BuilderCore">Interface ConfigurationContextBuilder</h2> +<div class="sectionbody"> +<div class="sect2"> +<h3 id="_overview">Overview</h3> +<div class="paragraph"> +<p>The Tamaya builder module provides a generic (one time) builder for creating Configuration instances, +e.g. as follows:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationBuilder builder = new ConfigurationBuilder(); +// do something +Configuration config = builder.build();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Basically the builder allows to create configuration instances completely independent of the current configuration +setup. This gives you full control on the Configuration setup.</p> +</div> +</div> +<div class="sect2"> +<h3 id="_supported_functionality">Supported Functionality</h3> +<div class="paragraph"> +<p>The builder allows you to add PropertySource instances:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder(); +builder.addPropertySources(sourceOne, sourceTwo, sourceThree +Configuration config = ConfigurationProvider.createConfiguration(builder.build());</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Hereby the ordering of the propertysources is not changed, regardless of the ordinals provided +by the property sources. This allows alternate ordering policies easily being implemented because +creating a configuration based on a configuration context is already implemented and provided by the core +API.</p> +</div> +<div class="paragraph"> +<p>Similarly you can add filters:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">builder.addPropertyFilters(new MyConfigFilter());</code></pre> +</div> +</div> +<div class="paragraph"> +<p>…​or PropertySourceProvider instances:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">builder.addPropertySourceProvider(new MyPropertySourceProvider());</code></pre> +</div> +</div> +<div class="sect3"> +<h4 id="ServiceContext">The ServiceContext</h4> +<div class="paragraph"> +<p>The ServiceContext is also a very important SPI, which allows to define how components are loaded in Tamaya. +The ServiceContext hereby defines access methods to obtain components, whereas itself it is available from the +ServiceContextManager singleton:</p> +</div> +<div class="listingblock"> +<div class="title">Accessing the ServiceContext</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ServiceContext serviceContext = ServiceContextManager.getServiceContext(); + +public interface ServiceContext{ + int ordinal(); + <T> T getService(Class<T> serviceType); + <T> List<T> getServices(Class<T> serviceType); +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>With the ServiceContext a component can be accessed in two different ways:</p> +</div> +<div class="olist arabic"> +<ol class="arabic"> +<li> +<p>access as as a single property. Hereby the registered instances (if multiple) are sorted by priority and then finally +the most significant instance is returned only.</p> +</li> +<li> +<p>access all items given its type. This will return (by default) all instances loadedable from the current +runtime context, ordered by priority, hereby the most significant components added first.</p> +</li> +</ol> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_examples">Examples</h2> +<div class="sectionbody"> +<div class="sect2"> +<h3 id="_accessing_configuration">Accessing Configuration</h3> +<div class="paragraph"> +<p><em>Configuration</em> is obtained from the ConfigurationProvider singleton:</p> +</div> +<div class="listingblock"> +<div class="title">Accessing Configuration</div> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Configuration config = ConfigurationProvider.getConfiguration();</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Many users in a SE context will probably only work with <em>Configuration</em>, since it offers all functionality +needed for basic configuration with a very lean memory and runtime footprint. In Java 7 access to the keys is +very similar to <strong>Map<String,String></strong>, whereas in Java 8 additionally usage of <em>Optional</em> is supported:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Configuration config = ConfigurationProvider.getConfiguration(); +String myKey = config.get("myKey"); // may return null +int myLimit = config.get("all.size.limit", int.class);</code></pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_environment_and_system_properties">Environment and System Properties</h3> +<div class="paragraph"> +<p>By default environment and system properties are included into the <em>Configuration</em>. So we can access the current +<em>PROMPT</em> environment variable as follows:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">String prompt = ConfigurationProvider.getConfiguration().get("PROMPT");</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Similary the system properties are directly applied to the <em>Configuration</em>. So if we pass the following system +property to our JVM:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">java ... -Duse.my.system.answer=yes</code></pre> +</div> +</div> +<div class="paragraph"> +<p>we can access it as follows:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java">boolean useMySystem = ConfigurationProvider.getConfiguration().get("use.my.system.answer", boolean.class);</code></pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_adding_a_custom_configuration">Adding a Custom Configuration</h3> +<div class="paragraph"> +<p>Adding a classpath based configuration is simply as well: just implement an according <em>PropertySource</em>. With the +<em>tamaya-spi-support</em> module you just have to perform a few steps:</p> +</div> +<div class="olist arabic"> +<ol class="arabic"> +<li> +<p>Define a PropertySource as follows:</p> +</li> +</ol> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-java" data-lang="java"> public class MyPropertySource extends PropertiesResourcePropertySource{ + + public MyPropertySource(){ + super(ClassLoader.getSystemClassLoader().getResource("META-INF/cfg/myconfig.properties"), DEFAULT_ORDINAL); + } + }</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Then register MyPropertySource using the ServiceLoader by adding the following file:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-listing" data-lang="listing">META-INF/services/org.apache.tamaya.spi.PropertySource</code></pre> +</div> +</div> +<div class="paragraph"> +<p>…​containing the following line:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="prettyprint highlight"><code class="language-listing" data-lang="listing">com.mypackage.MyPropertySource</code></pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="APIImpl">API Implementation</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The API is implemented by the Tamaya _Core_module. Refer to the <a href="Core.html">Core documentation</a> for +further details.</p> +</div> +</div> +</div></p> + + <hr /> + </div> + </div> + <div> + <div id="push"></div> + + <div id="footer"> + <div class="container"> + <p class="muted credit">© 2014-2016 Apache Software Foundation | Mixed with <a href="http://getbootstrap.com/">Bootstrap v3.1.1</a> + | Baked with <a href="http://jbake.org">JBake <span>v2.5.0</span></a> + at <span>2016-12-12</span> + </p> + <p> + <b>Disclaimer</b> + Apache Tamaya (incubating) is an effort undergoing + incubation at + The Apache Software Foundation (ASF), sponsored by + the name of Apache Incubator. Incubation is required of + all newly accepted projects until a further review indicates + that the infrastructure, communications, and decision making + process have stabilized in a manner consistent with other + successful ASF projects. While incubation status is not + necessarily a reflection of the completeness or stability of + the code, it does indicate that the project has yet to + be fully endorsed by the ASF.<br /> + <a href="http://incubator.apache.org/guides/website.html" style="border:0px;" target="_target"><img class="incubator-logo" src="logos/egg-logo2.png"/></a> + </p> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="js/jquery-1.11.1.min.js"></script> + <script src="js/bootstrap.min.js"></script> + <script src="js/prettify.js"></script> + + </div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/40dff215/archive.html ---------------------------------------------------------------------- diff --git a/archive.html b/archive.html new file mode 100644 index 0000000..4d2c5e8 --- /dev/null +++ b/archive.html @@ -0,0 +1,193 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset="utf-8"/> + <title>Tamaya Incubator</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content=""/> + <meta name="author" content=""/> + <meta name="keywords" content=""/> + <meta name="generator" content="'JBake '+'${version}"/> + + <!-- Le styles --> + <link href="css/bootstrap.min.css" rel="stylesheet"/> + <link href="css/asciidoctor.css" rel="stylesheet"/> + <link href="css/base.css" rel="stylesheet"/> + <link href="css/prettify.css" rel="stylesheet"/> + + <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="js/html5shiv.min.js"></script> + <![endif]--> + + <!-- Fav and touch icons from ASF --> + <link rel="shortcut icon" href="favicon.ico"/> + <link rel="apple-touch-icon" sizes="57x57" href="favicons/apple-touch-icon-57x57.png"/> + <link rel="apple-touch-icon" sizes="60x60" href="favicons/apple-touch-icon-60x60.png"/> + <link rel="apple-touch-icon" sizes="72x72" href="favicons/apple-touch-icon-72x72.png"/> + <link rel="apple-touch-icon" sizes="76x76" href="favicons/apple-touch-icon-76x76.png"/> + <link rel="apple-touch-icon" sizes="114x114" href="favicons/apple-touch-icon-114x114.png"/> + <link rel="apple-touch-icon" sizes="120x120" href="favicons/apple-touch-icon-120x120.png"/> + <link rel="apple-touch-icon" sizes="144x144" href="favicons/apple-touch-icon-144x144.png"/> + <link rel="apple-touch-icon" sizes="152x152" href="favicons/apple-touch-icon-152x152.png"/> + <link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon-180x180.png"/> + <link rel="icon" type="image/png" href="favicons/favicon-32x32.png" sizes="32x32"/> + <link rel="icon" type="image/png" href="favicons/favicon-194x194.png" sizes="194x194"/> + <link rel="icon" type="image/png" href="favicons/favicon-96x96.png" sizes="96x96"/> + <link rel="icon" type="image/png" href="favicons/android-chrome-192x192.png" sizes="192x192"/> + <link rel="icon" type="image/png" href="favicons/favicon-16x16.png" sizes="16x16"/> + <link rel="manifest" href="favicons/manifest.json"/> + <link rel="shortcut icon" href="favicons/favicon.ico"/> + <meta name="msapplication-TileColor" content="#603cba"/> + <meta name="msapplication-TileImage" content="favicons/mstile-144x144.png"/> + <meta name="msapplication-config" content="favicons/browserconfig.xml"/> + <meta name="theme-color" content="#303284"/> + </head> + <body onload="prettyPrint()"> + <div id="wrap"> + <div> + + <!-- Fixed navbar --> + <div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="index.html">Apache Tamaya (incubating)</a> + </div> + <div class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li><a href="start.html">Tamaya in 5 minutes</a></li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="documentation/usecases.html">Use Cases and Requirements</a></li> + <li><a href="documentation/quickstart.html">Quickstart</a></li> + <li><a href="documentation/api.html">API</a></li> + <li><a href="documentation/core.html">Core</a></li> + <li><a href="documentation/extensions.html">Extension Guide</a></li> + <li class="divider"></li> + <li><a href="apidocs/index.html">Javadoc {tamaya_version} (external)</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Development <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="development/source.html">Sources</a></li> + <li><a href="development/community.html">Community</a></li> + <li><a href="development/team.html">Project Team</a></li> + <li><a target="_blank" href="https://builds.apache.org/view/S-Z/view/Tamaya/">CI / ASF Jenkins</a></li> + <li><a target="_blank" href="https://issues.apache.org/jira/browse/TAMAYA">Issues / ASF Jira</a></li> + <li><a href="devguide.html">Development Guide</a></li> + <li><a href="release-guide.html">Release Guide</a></li> + <li class="divider"></li> + <li><a href="development/possible-contributions.html">Possible Contributions</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Releases <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="download.html">Download</a></li> + <li><a href="history.html">Release History</a></li> + </ul> + </li> +<!-- Example: + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link</a></li> + </ul> + </li> +--> + <li><a href="sitemap.xml">Sitemap</a></li> + <li><a href="feed.xml">Subscribe</a></li> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + + </div> + <div class="container"> + <div class="page-header"> + <h1>Blog Archive</h1> + </div> + + + <h3>Dezember 2016</h3> + + <h4>19 - <a href="blog/2016/fourth-post.html">Fourth Post</a></h4> + + + + + <h3>November 2016</h3> + + <h4>04 - <a href="blog/2016/first-post.html">Hello world</a></h4> + + + + + <h3>September 2013</h3> + + <h4>26 - <a href="blog/2016/third-post.html">Third Post</a></h4> + + + + + <h3>August 2013</h3> + + <h4>25 - <a href="blog/2016/second-post.html">Second Post</a></h4> + + + + </div> + </div> + + <div> + <div id="push"></div> + + <div id="footer"> + <div class="container"> + <p class="muted credit">© 2014-2016 Apache Software Foundation | Mixed with <a href="http://getbootstrap.com/">Bootstrap v3.1.1</a> + | Baked with <a href="http://jbake.org">JBake <span>v2.5.0</span></a> + at <span>2016-12-19</span> + </p> + <p> + <b>Disclaimer</b> + Apache Tamaya (incubating) is an effort undergoing + incubation at + The Apache Software Foundation (ASF), sponsored by + the name of Apache Incubator. Incubation is required of + all newly accepted projects until a further review indicates + that the infrastructure, communications, and decision making + process have stabilized in a manner consistent with other + successful ASF projects. While incubation status is not + necessarily a reflection of the completeness or stability of + the code, it does indicate that the project has yet to + be fully endorsed by the ASF.<br /> + <a href="http://incubator.apache.org/guides/website.html" style="border:0px;" target="_target"><img class="incubator-logo" src="logos/egg-logo2.png"/></a> + </p> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="js/jquery-1.11.1.min.js"></script> + <script src="js/bootstrap.min.js"></script> + <script src="js/prettify.js"></script> + + </div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/40dff215/blog/2013/first-post.html ---------------------------------------------------------------------- diff --git a/blog/2013/first-post.html b/blog/2013/first-post.html new file mode 100644 index 0000000..8bdbdba --- /dev/null +++ b/blog/2013/first-post.html @@ -0,0 +1,171 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset="utf-8"/> + <title>First Post</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content=""/> + <meta name="author" content=""/> + <meta name="keywords" content=""/> + <meta name="generator" content="'JBake '+'${version}"/> + + <!-- Le styles --> + <link href="../../css/bootstrap.min.css" rel="stylesheet"/> + <link href="../../css/asciidoctor.css" rel="stylesheet"/> + <link href="../../css/base.css" rel="stylesheet"/> + <link href="../../css/prettify.css" rel="stylesheet"/> + + <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> + <!--[if lt IE 9]> + <script src="../../js/html5shiv.min.js"></script> + <![endif]--> + + <!-- Fav and touch icons from ASF --> + <link rel="shortcut icon" href="../../favicon.ico"/> + <link rel="apple-touch-icon" sizes="57x57" href="../../favicons/apple-touch-icon-57x57.png"/> + <link rel="apple-touch-icon" sizes="60x60" href="../../favicons/apple-touch-icon-60x60.png"/> + <link rel="apple-touch-icon" sizes="72x72" href="../../favicons/apple-touch-icon-72x72.png"/> + <link rel="apple-touch-icon" sizes="76x76" href="../../favicons/apple-touch-icon-76x76.png"/> + <link rel="apple-touch-icon" sizes="114x114" href="../../favicons/apple-touch-icon-114x114.png"/> + <link rel="apple-touch-icon" sizes="120x120" href="../../favicons/apple-touch-icon-120x120.png"/> + <link rel="apple-touch-icon" sizes="144x144" href="../../favicons/apple-touch-icon-144x144.png"/> + <link rel="apple-touch-icon" sizes="152x152" href="../../favicons/apple-touch-icon-152x152.png"/> + <link rel="apple-touch-icon" sizes="180x180" href="../../favicons/apple-touch-icon-180x180.png"/> + <link rel="icon" type="image/png" href="../../favicons/favicon-32x32.png" sizes="32x32"/> + <link rel="icon" type="image/png" href="../../favicons/favicon-194x194.png" sizes="194x194"/> + <link rel="icon" type="image/png" href="../../favicons/favicon-96x96.png" sizes="96x96"/> + <link rel="icon" type="image/png" href="../../favicons/android-chrome-192x192.png" sizes="192x192"/> + <link rel="icon" type="image/png" href="../../favicons/favicon-16x16.png" sizes="16x16"/> + <link rel="manifest" href="../../favicons/manifest.json"/> + <link rel="shortcut icon" href="../../favicons/favicon.ico"/> + <meta name="msapplication-TileColor" content="#603cba"/> + <meta name="msapplication-TileImage" content="../../favicons/mstile-144x144.png"/> + <meta name="msapplication-config" content="../../favicons/browserconfig.xml"/> + <meta name="theme-color" content="#303284"/> + </head> + <body onload="prettyPrint()"> + <div id="wrap"> + <div> + + <!-- Fixed navbar --> + <div class="navbar navbar-default navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="../../">Apache Tamaya (incubating)</a> + </div> + <div class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li><a href="../../index.html">Home</a></li> + <li><a href="../../quickstart.html">Quickstart</a></li> + <li><a href="../../index.html">Documentation</a></li> + <li><a href="../..//apidocs/index.html">API</a></li> + <li><a href="../../index.html">Development</a></li> + <li><a href="../../index.html">Releases</a></li> + <li><a href="../../about.html">About</a></li> + <li><a href="../../sitemap.xml">Sitemap</a></li> + <li><a href="../../feed.xml">Subscribe</a></li> +<!-- + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a href="#">Action</a></li> + <li><a href="#">Another action</a></li> + <li><a href="#">Something else here</a></li> + <li class="divider"></li> + <li class="dropdown-header">Nav header</li> + <li><a href="#">Separated link</a></li> + <li><a href="#">One more separated link</a></li> + </ul> + </li> +--> + </ul> + </div><!--/.nav-collapse --> + </div> + </div> + + </div> + <div class="container"> + + <div class="page-header"> + <h1>First Post</h1> + </div> + + <p><em>2013-07-24</em></p> + + <p> +<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vel diam purus. Curabitur ut nisi lacus.</p> + +<ul> +<li><a href="http://example.org">http://example.org</a></li> +<li><a href="http://example.org">Example.org</a></li> +</ul> + +<p>Nam id nisl quam. Donec a lorem sit amet libero pretium vulputate vel ut purus. Suspendisse leo arcu, +mattis et imperdiet luctus, pulvinar vitae mi. Quisque fermentum sollicitudin feugiat. Mauris nec leo +ligula. Vestibulum tristique odio ut risus ultricies a hendrerit quam iaculis. Duis tempor elit sit amet +ligula vehicula et iaculis sem placerat. Fusce dictum, metus at volutpat lacinia, elit massa auctor risus, +id auctor arcu enim eu augue. Donec ultrices turpis in mi imperdiet ac venenatis sapien sodales.</p> + +<pre class="prettyprint"> +<code> +package org.jbake; + +public class Oven { + public static void main(String[] args) { + System.out.print("Baking!"); + } +} +</code> +</pre> + +<p>In consequat imperdiet nunc quis bibendum. Nulla semper, erat quis ornare tristique, lectus massa posuere +libero, ut vehicula lectus nunc ut lorem. Aliquam erat volutpat.</p> +</p> + + <hr /> + </div> + </div> + <div> + <div id="push"></div> + + <div id="footer"> + <div class="container"> + <p class="muted credit">© 2014-2016 Apache Software Foundation | Mixed with <a href="http://getbootstrap.com/">Bootstrap v3.1.1</a> + | Baked with <a href="http://jbake.org">JBake <span>v2.5.0</span></a> + at <span>2016-11-02</span> + </p> + <p> + <b>Disclaimer</b> + Apache Tamaya (incubating) is an effort undergoing + incubation at + The Apache Software Foundation (ASF), sponsored by + the name of Apache Incubator. Incubation is required of + all newly accepted projects until a further review indicates + that the infrastructure, communications, and decision making + process have stabilized in a manner consistent with other + successful ASF projects. While incubation status is not + necessarily a reflection of the completeness or stability of + the code, it does indicate that the project has yet to + be fully endorsed by the ASF.<br /> + <a href="http://incubator.apache.org/guides/website.html" style="border:0px;" target="_target"><img class="incubator-logo" src="../../logos/egg-logo2.png"/></a> + </p> + </div> + </div> + + <!-- Le javascript + ================================================== --> + <!-- Placed at the end of the document so the pages load faster --> + <script src="../../js/jquery-1.11.1.min.js"></script> + <script src="../../js/bootstrap.min.js"></script> + <script src="../../js/prettify.js"></script> + + </div> + </body> +</html>