http://git-wip-us.apache.org/repos/asf/polygene-website/blob/bb9c9971/content/java/2017/tools.html ---------------------------------------------------------------------- diff --git a/content/java/2017/tools.html b/content/java/2017/tools.html new file mode 100644 index 0000000..1dc04de --- /dev/null +++ b/content/java/2017/tools.html @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Tools</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /><link rel="home" href="index.html" title="" /><link rel="up" href="index.html" title="" /><link rel="prev" href="extension-reindexer.html" title="Reindexer" /><link rel="next" href="glossary.html" title="Glossary " /> + + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> + <meta name="description" content=""> + <meta name="author" content=""> + <link rel="icon" href="../../favicon.ico"> + + <title>Starter Template for Bootstrap</title> + + <!-- Bootstrap core CSS --> + <link href="bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"> + + <!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> + <link href="css/ie10-viewport-bug-workaround.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="css/polygene-ng.css" rel="stylesheet"> + + <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> + <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> + <script src="js/ie-emulation-modes-warning.js"></script> + + <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + +<!-- favicon --> + +<link rel="shortcut icon" href="http://polygene.apache.org/favicon.ico" type="image/vnd.microsoft.icon" /> +<link rel="icon" href="http://polygene.apache.org/favicon.ico" type="image/x-icon" /> + +<!-- style --> + +<link href="css/shCore.css" rel="stylesheet" type="text/css" /> +<link href="css/shCoreEclipse.css" rel="stylesheet" type="text/css" /> +<link href="css/shThemeEclipse.css" rel="stylesheet" type="text/css" /> +<!--<link href="css/polygene.css" rel="stylesheet" type="text/css" />--> + +<!-- Syntax Highlighter --> + +<script type="text/javascript" src="js/shCore.js"></script> +<script type="text/javascript" src="js/shBrushJava.js"></script> +<script type="text/javascript" src="js/shBrushScala.js"></script> +<script type="text/javascript" src="js/shBrushJScript.js"></script> +<script type="text/javascript" src="js/shBrushBash.js"></script> +<script type="text/javascript" src="js/shBrushPlain.js"></script> +<script type="text/javascript" src="js/shBrushXml.js"></script> +<script type="text/javascript" src="js/shBrushGroovy.js"></script> +<script type="text/javascript" src="js/shBrushPython.js"></script> +<script type="text/javascript" src="js/shBrushRuby.js"></script> +<script type="text/javascript" src="js/shBrushCSharp.js"></script> + +<script type="text/javascript"> + SyntaxHighlighter.defaults['tab-size'] = 4; + SyntaxHighlighter.defaults['gutter'] = false; + SyntaxHighlighter.defaults['toolbar'] = false; + SyntaxHighlighter.all() +</script> + +<!-- JQuery --> + +<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script> + +<!-- Image Scaler --> + +<script type="text/javascript" src="js/imagescaler.js"></script> + +<!-- Table Styler --> + +<script type="text/javascript" src="js/tablestyler.js"></script> + +<!-- Apache Polygene WebSite Progressive Enhancement --> + +<link href="css/progressive-enhancement.css" rel="stylesheet" type="text/css" /> +<script type="text/javascript" src="js/jquery.scrollTo-1.4.2.js"></script> +<script type="text/javascript" src="js/progressive-enhancement.js"></script> + +<!-- Analytics --> + <script type="text/javascript"> + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-62007352-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); + </script> + + </head><body><div xmlns="" xmlns:exsl="http://exslt.org/common" class="logo"><a href="index.html"><img src="images/logo-standard.png" /></a></div><nav xmlns="" xmlns:exsl="http://exslt.org/common" class="navbar navbar-inverse navbar-fixed-top"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="#">Apache<br />Polygene + </a></div><div id="navbar" class="collapse navbar-collapse"><span class="nav navbar-nav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><a href="index.html#home">Polygeneâ¢</a></span></dt><dt><span class="section"><a href="intro.html">Introduction</a></span></dt><dt><span class="section"><a href="tutorials.html">Tutorials</a></span></dt><dt><span class="section"><a href="javadocs.html">Javadoc</a></span></dt><dt><span class="section"><a href="samples.html">Samples</a></span></dt><dt><span class="section"><a href="core.html">Core</a></span></dt><dt><span class="section"><a href="libraries.html">Libraries</a></span></dt><dt><span class="section"><a href="extensions.html">Extensions</a></span></dt><dt><span class="section"><span xmlns="" href="tools.html">Tools</span></span></dt><dt><span class="section"><a href="glossary.html">Glossary </a></span></dt></dl></div></span></div></div></nav><div xmlns="" xmlns:exsl="http://exslt .org/common" class="sidenav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><span xmlns="" href="tools.html#_overview_8">Overview</span></span></dt></dl></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title"><a id="tools"></a>Tools</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_overview_8"></a>Overview</h3></div></div></div><p>The Polygene⢠SDK comes with usefull development tools. Theses tools can come in +handy when assembled into your <a class="xref" href="glossary.html#def-application">Application</a> in development +<a class="xref" href="glossary.html#def-application-mode">Application Mode</a>.</p><p>The tools are available in the <code class="literal">tools/</code> directory of the Polygene⢠SDK.</p></div></div><footer xmlns="" xmlns:exsl="http://exslt.org/common" class="footer"><div class="container"><p class="text-muted">Copyright © 2017 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/" target="_blank">Apache License, Version 2.0</a>. + Apache Polygene, Polygene, Apache, the Apache feather logo, and the Apache Polygene project logo are + trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners. + </p></div></footer><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common">window.jQuery || document.write('<script src="js/jquery-1.6.4.min.js"></script>')</script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="bootstrap-3.3.7/js/bootstrap.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="js/ie10-viewport-bug-workaround.js"></script></body></html> \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/polygene-website/blob/bb9c9971/content/java/2017/tut-composites.html ---------------------------------------------------------------------- diff --git a/content/java/2017/tut-composites.html b/content/java/2017/tut-composites.html new file mode 100644 index 0000000..386c3fb --- /dev/null +++ b/content/java/2017/tut-composites.html @@ -0,0 +1,985 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Transient Composites Tutorial</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /><link rel="home" href="index.html" title="" /><link rel="up" href="tutorials.html" title="Tutorials" /><link rel="prev" href="howto-assemble-application.html" title="Assemble an Application" /><link rel="next" href="tut-services.html" title="Services Composites Tutorial" /> + + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> + <meta name="description" content=""> + <meta name="author" content=""> + <link rel="icon" href="../../favicon.ico"> + + <title>Starter Template for Bootstrap</title> + + <!-- Bootstrap core CSS --> + <link href="bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"> + + <!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> + <link href="css/ie10-viewport-bug-workaround.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="css/polygene-ng.css" rel="stylesheet"> + + <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> + <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> + <script src="js/ie-emulation-modes-warning.js"></script> + + <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + +<!-- favicon --> + +<link rel="shortcut icon" href="http://polygene.apache.org/favicon.ico" type="image/vnd.microsoft.icon" /> +<link rel="icon" href="http://polygene.apache.org/favicon.ico" type="image/x-icon" /> + +<!-- style --> + +<link href="css/shCore.css" rel="stylesheet" type="text/css" /> +<link href="css/shCoreEclipse.css" rel="stylesheet" type="text/css" /> +<link href="css/shThemeEclipse.css" rel="stylesheet" type="text/css" /> +<!--<link href="css/polygene.css" rel="stylesheet" type="text/css" />--> + +<!-- Syntax Highlighter --> + +<script type="text/javascript" src="js/shCore.js"></script> +<script type="text/javascript" src="js/shBrushJava.js"></script> +<script type="text/javascript" src="js/shBrushScala.js"></script> +<script type="text/javascript" src="js/shBrushJScript.js"></script> +<script type="text/javascript" src="js/shBrushBash.js"></script> +<script type="text/javascript" src="js/shBrushPlain.js"></script> +<script type="text/javascript" src="js/shBrushXml.js"></script> +<script type="text/javascript" src="js/shBrushGroovy.js"></script> +<script type="text/javascript" src="js/shBrushPython.js"></script> +<script type="text/javascript" src="js/shBrushRuby.js"></script> +<script type="text/javascript" src="js/shBrushCSharp.js"></script> + +<script type="text/javascript"> + SyntaxHighlighter.defaults['tab-size'] = 4; + SyntaxHighlighter.defaults['gutter'] = false; + SyntaxHighlighter.defaults['toolbar'] = false; + SyntaxHighlighter.all() +</script> + +<!-- JQuery --> + +<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script> + +<!-- Image Scaler --> + +<script type="text/javascript" src="js/imagescaler.js"></script> + +<!-- Table Styler --> + +<script type="text/javascript" src="js/tablestyler.js"></script> + +<!-- Apache Polygene WebSite Progressive Enhancement --> + +<link href="css/progressive-enhancement.css" rel="stylesheet" type="text/css" /> +<script type="text/javascript" src="js/jquery.scrollTo-1.4.2.js"></script> +<script type="text/javascript" src="js/progressive-enhancement.js"></script> + +<!-- Analytics --> + <script type="text/javascript"> + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-62007352-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); + </script> + + </head><body><div xmlns="" xmlns:exsl="http://exslt.org/common" class="logo"><a href="index.html"><img src="images/logo-standard.png" /></a></div><nav xmlns="" xmlns:exsl="http://exslt.org/common" class="navbar navbar-inverse navbar-fixed-top"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="#">Apache<br />Polygene + </a></div><div id="navbar" class="collapse navbar-collapse"><span class="nav navbar-nav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><a href="index.html#home">Polygeneâ¢</a></span></dt><dt><span class="section"><a href="intro.html">Introduction</a></span></dt><dt><span class="section"><span xmlns="" href="tutorials.html">Tutorials</span></span></dt><dt><span class="section"><a href="javadocs.html">Javadoc</a></span></dt><dt><span class="section"><a href="samples.html">Samples</a></span></dt><dt><span class="section"><a href="core.html">Core</a></span></dt><dt><span class="section"><a href="libraries.html">Libraries</a></span></dt><dt><span class="section"><a href="extensions.html">Extensions</a></span></dt><dt><span class="section"><a href="tools.html">Tools</a></span></dt><dt><span class="section"><a href="glossary.html">Glossary </a></span></dt></dl></div></span></div></div></nav><div xmlns="" xmlns:exsl="http://exslt .org/common" class="sidenav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><a href="tutorials.html#_overview">Overview</a></span></dt><dt><span class="section"><a href="two-minutes-intro.html">Polygene⢠in 2 minutes</a></span></dt><dt><span class="section"><a href="ten-minutes-intro.html">Polygene⢠in 10 minutes</a></span></dt><dt><span class="section"><a href="thirty-minutes-intro.html">Polygene⢠in 30 minutes</a></span></dt><dt><span class="section"><a href="howto-depend-on-polygene.html">Depend on Polygeneâ¢</a></span></dt><dt><span class="section"><a href="howto-assemble-application.html">Assemble an Application</a></span></dt><dt><span class="section"><span xmlns="" href="tut-composites.html">Transient Composites Tutorial</span></span></dt><dt><span class="section"><a href="tut-services.html">Services Composites Tutorial</a></span></dt><dt><span class="section"><a href="howto-contextual-fragments.html">Use contextual frag ments</a></span></dt><dt><span class="section"><a href="howto-leverage-properties.html">Leverage Properties</a></span></dt><dt><span class="section"><a href="howto-create-constraint.html">Create a Constraint</a></span></dt><dt><span class="section"><a href="howto-create-concern.html">Create a Concern</a></span></dt><dt><span class="section"><a href="howto-create-sideeffect.html">Create a SideEffect</a></span></dt><dt><span class="section"><a href="howto-create-entity.html">Create an Entity</a></span></dt><dt><span class="section"><a href="howto-configure-service.html">Configure a Service</a></span></dt><dt><span class="section"><a href="howto-invocation-annotation.html">Use @Invocation</a></span></dt><dt><span class="section"><a href="build-system.html">Polygene⢠Build System</a></span></dt><dt><span class="section"><a href="community-docs.html">Polygene⢠Documentation</a></span></dt><dt><span class="section"><a href="releasing-apache.html">Releasing Polygeneâ¢</a></span></dt>< /dl></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="tut-composites"></a>Transient Composites Tutorial</h3></div></div></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>Theses tutorials are based on actual code found in the <code class="literal">tutorials/</code> directory of the +<a class="ulink" href="https://polygene.apache.org/download.html" target="_top">Polygene⢠SDK sources</a>. You should start your favorite editor and find the code related to +this tutorial, run it and play with it.</p></div><p>Throughout this set of tutorials it will be shown how to create and work with Composites, which +is the basic element in Polygeneâ¢. We will refactor one HelloWorld class to take advantage of the various +features in Polygeneâ¢. These refactorings will make it easier to reuse parts of the class, +and introduce new features without having to change existing code. We will also look +at some of the existing classes, or Fragments, available in Polygene⢠that you can reuse +so that you donât have to write everything yourself.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step1" title="Step 1 - Interface Refactoring">Step 1 - Interface Refactoring</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step2" title="Step 2 - Creating a Transient Composite">Step 2 - Creating a Transient Composite</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step3" title="Step 3 - Mixins">Step 3 - Mixins</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step4" title="Step 4 - Concerns">Step 4 - Concerns</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step5" title="Step 5 - Constraints">Step 5 - Constraints</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step6" title="Step 6 - SideEffects">Step 6 - SideEffects</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step7" title="Step 7 - Properties">Step 7 - Properties</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step8" title="Step 8 - Generic Mixins">Step 8 - Generic Mixins</a> +</li><li class="listitem"> +<a class="xref" href="tut-composites.html#tut-composites-step9" title="Step 9 - Private and Abstract Mixins">Step 9 - Private and Abstract Mixins</a> +</li></ul></div><p>Each tutorial step in this series starts with the result from the previous tutorial, so you can +always look at the next tutorial step for guidance on what to do.</p><p>At the bottom of each tutorial step, the is Solutions section, which list the files you should have come to if you +have followed the instructions.</p><p>If you want to reproduce whatâs explained in this tutorial, remember to depend on the Core Runtime artifact that depends +on Core API, Core SPI, and Core Bootstrap:</p><div class="table"><a id="idm1046"></a><p class="title"><strong>Table 5. Artifact</strong></p><div class="table-contents"><table summary="Artifact" border="1"><colgroup><col class="col_1" /><col class="col_2" /><col class="col_3" /></colgroup><thead><tr><th align="left" valign="top">Group ID</th><th align="left" valign="top">Artifact ID</th><th align="left" valign="top">Version</th></tr></thead><tbody><tr><td align="left" valign="top"><p>org.apache.polygene.core</p></td><td align="left" valign="top"><p>org.apache.polygene.core.runtime</p></td><td align="left" valign="top"><p>0</p></td></tr></tbody></table></div></div><br class="table-break" /><p>See the <a class="xref" href="howto-depend-on-polygene.html" title="Depend on Polygeneâ¢">Depend on Polygeneâ¢</a> tutorial for details.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step1"></a>Step 1 - Interface Refactoring</h4></div></div>< /div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_initial_hello_world"></a>Initial Hello World</h5></div></div></div><p>This whole tutorial describes how to step-by-step modify a typical HelloWorld "application" into a full-fledged Polygene⢠+Composite Oriented application. Here is the initial code of HelloWorld.</p><pre class="programlisting brush: java"> +/** + * Initial HelloWorld implementation. Everything is mixed up + * into one class, and no interface is used. + */ +public class HelloWorld +{ + String phrase; + String name; + + public String getPhrase() + { + return phrase; + } + + public void setPhrase( String phrase ) + throws IllegalArgumentException + { + if( phrase == null ) + { + throw new IllegalArgumentException( "Phrase may not be null " ); + } + + this.phrase = phrase; + } + + public String getName() + { + return name; + } + + public void setName( String name ) + throws IllegalArgumentException + { + if( name == null ) + { + throw new IllegalArgumentException( "Name may not be null " ); + } + + this.name = name; + } + + public String say() + { + return phrase + " " + name; + } +} +</pre></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_interface_refactoring"></a>Interface refactoring</h5></div></div></div><p>In this step we start with a basic Java class, which when invoked will concatenate the two properties "phrase" +and "name". If invoked with the properties set to "Hello" and "World" respectively it will hence return "Hello World".</p><p>Polygene⢠relies heavily on the use of interfaces. This makes it possible for an object to externally implement a number of +interfaces which internally is backed by a number of Mixins, some of which you may have written yourself, and some of +which may have been reused. This also makes it easy to introduce Modifiers (aka "interceptors", aka "advice"), which +are Fragments which execute before and/or after the method on the Mixin is invoked.</p><p>The first task is therefore to refactor the code so that the method is implemented from an interface instead. We should +then also separate the state into one interface and the behaviour into another. This will make things easier for us +later when state and behaviour becomes implemented by separate Mixins.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Refactor the class into interface and implementation. +</li><li class="listitem"> +Refactor the interface so that it extends one interface called HelloWorldBehaviour with behaviour and one called HelloWorldState with state (get/set methods). +</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_2"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p><span class="strong"><strong>HelloWorld.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface aggregates the behaviour and state + * of the HelloWorld sub-interfaces. To a client + * this is the same as before though, since it only + * has to deal with this interface instead of the + * two sub-interfaces. + */ +public interface HelloWorld + extends HelloWorldBehaviour, HelloWorldState +{ +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + * The exceptions will be thrown by Polygene automatically if + * null is sent in as values. The parameters would have to be declared + * as @Optional if null is allowed. + */ +public interface HelloWorldState +{ + void setPhrase( String phrase ) + throws IllegalArgumentException; + + String getPhrase(); + + void setName( String name ) + throws IllegalArgumentException; + + String getName(); +} +</pre><p><span class="strong"><strong>HelloWorldBehaviour.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the behaviour + * of the HelloWorld object. + */ +public interface HelloWorldBehaviour +{ + String say(); +} +</pre><p><span class="strong"><strong>HelloWorldMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * interface. The behaviour and state is mixed. + */ +public class HelloWorldMixin + implements HelloWorld +{ + String phrase; + String name; + + @Override + public String say() + { + return getPhrase() + " " + getName(); + } + + @Override + public void setPhrase( String phrase ) + throws IllegalArgumentException + { + if( phrase == null ) + { + throw new IllegalArgumentException( "Phrase may not be null" ); + } + + this.phrase = phrase; + } + + @Override + public String getPhrase() + { + return phrase; + } + + @Override + public void setName( String name ) + throws IllegalArgumentException + { + if( name == null ) + { + throw new IllegalArgumentException( "Name may not be null" ); + } + + this.name = name; + } + + @Override + public String getName() + { + return name; + } +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step2" title="Step 2 - Creating a Transient Composite">Step 2 - Creating a Transient Composite</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step2"></a>Step 2 - Creating a Transient Composite</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step1" title="Step 1 - Interface Refactoring">Step 1 - Interface Refactoring</a>.</p><p>In this step we will create a TransientComposite interface that ties all pieces together. The TransientComposite +interface is a regular Java interface which extends the interfaces you want to expose from your domain model, and which +uses various annotations to declare what Fragments to include. Fragments include Mixins, Concerns, SideEffects and +Constraints. In this tutorial we will only use Mixins. When a TransientComposite is instantiated at runtime the +framework will inspect the interface to determine what the TransientComposite instance should look like in terms of +used Fragments.</p><p>In Polygene⢠all method parameters are considered mandatory unless marked as @Optional. Therefore you can remove the null +checks in the Mixin. If a null value is passed in an exception will be thrown by Polygeneâ¢.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Create an interface that extends the domain interface <code class="literal">HelloWorld</code> and <code class="literal">org.apache.polygene.api.composite.TransientComposite</code>. +</li><li class="listitem"> +Add a @Mixins annotation to it with the name of the Mixin as argument. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_3"></a>Solution</h5></div></div></div><p>These ones remain unchanged:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorld.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldBehaviour.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldState.java</code> +</li></ul></div><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares all the Fragments of the HelloWorld composite. + * <p> + * Currently it only declares one Mixin. + * </p> + */ +@Mixins( HelloWorldMixin.class ) +public interface HelloWorldComposite + extends HelloWorld, TransientComposite +{ +} +</pre><p><span class="strong"><strong>HelloWorldMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * interface. The behaviour and state is mixed. + */ +public class HelloWorldMixin + implements HelloWorld +{ + String phrase; + String name; + + @Override + public String say() + { + return getPhrase() + " " + getName(); + } + + @Override + public void setPhrase( String phrase ) + throws IllegalArgumentException + { + if( phrase == null ) + { + throw new IllegalArgumentException( "Phrase may not be null" ); + } + + this.phrase = phrase; + } + + @Override + public String getPhrase() + { + return phrase; + } + + @Override + public void setName( String name ) + throws IllegalArgumentException + { + if( name == null ) + { + throw new IllegalArgumentException( "Name may not be null" ); + } + + this.name = name; + } + + @Override + public String getName() + { + return name; + } +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step3" title="Step 3 - Mixins">Step 3 - Mixins</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step3"></a>Step 3 - Mixins</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step2" title="Step 2 - Creating a Transient Composite">Step 2 - Creating a Transient Composite</a>.</p><p>In this step we refactor the Mixin from the previous steps into two, one which serves the behaviour interface and +one which serves the state interface. This makes it possible to reuse the interfaces independently and also makes it +easier to exchange one interface implementation with another. This also allows us to specify the new Mixins as default +implementations of the interfaces by adding @Mixins annotations on them.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Refactor the Mixin into one which implement the behaviour interface and one which implements the state interface. Use the @This injection annotation to allow the behaviour to access the state. +</li><li class="listitem"> +Add a @Mixins annotations on the behaviour and state interfaces which declare the Mixins as default implementations. +</li><li class="listitem"> +Remove the @Mixins annotation from the TransientComposite interface. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_4"></a>Solution</h5></div></div></div><p>Only <span class="strong"><strong>HelloWorld.java</strong></span> remains unchanged.</p><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares all the Fragments + * of the HelloWorld composite. + * <p> + * The Mixins annotation has been moved to the respective sub-interfaces. + * The sub-interfaces therefore declare themselves what mixin implementation + * is preferred. This interface could still have its own Mixins annotation + * with overrides of those defaults however. + * </p> + */ +public interface HelloWorldComposite + extends HelloWorld, TransientComposite +{ +} +</pre><p><span class="strong"><strong>HelloWorldBehaviour.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the behaviour of the HelloWorld object. + * <p> + * It declares what Mixin to use as default implementation. + * </p> + */ +@Mixins( HelloWorldBehaviourMixin.class ) +public interface HelloWorldBehaviour +{ + String say(); +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld behaviour interface. + * <p> + * It uses a @This Dependency Injection + * annotation to access the state of the Composite. The field + * will be automatically injected when the Composite + * is instantiated. Injections of resources or references + * can be provided either to fields, constructor parameters or method parameters. + * </p> + */ +public class HelloWorldBehaviourMixin + implements HelloWorldBehaviour +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.getPhrase() + " " + state.getName(); + } +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + * The exceptions will be thrown by Polygene automatically if + * null is sent in as values. The parameters would have to be declared + * as @Optional if null is allowed. + */ +@Mixins( HelloWorldStateMixin.class ) +public interface HelloWorldState +{ + void setPhrase( String phrase ) + throws IllegalArgumentException; + + String getPhrase(); + + void setName( String name ) + throws IllegalArgumentException; + + String getName(); +} +</pre><p><span class="strong"><strong>HelloWorldStateMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * state interface. + */ +public class HelloWorldStateMixin + implements HelloWorldState +{ + String phrase; + String name; + + @Override + public String getPhrase() + { + return phrase; + } + + @Override + public void setPhrase( String phrase ) + { + this.phrase = phrase; + } + + @Override + public String getName() + { + return name; + } + + @Override + public void setName( String name ) + { + this.name = name; + } +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step4" title="Step 4 - Concerns">Step 4 - Concerns</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step4"></a>Step 4 - Concerns</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step3" title="Step 3 - Mixins">Step 3 - Mixins</a>.</p><p>In this step we refactor the mixin from the previous steps so that the result of the say() method is modified to be +prefixed with "Simon says:". To do this we need to implement a Concern for the say() method. Concerns are a type of +Modifier which modify the behaviour of the methods in Mixins. They do this by intercepting the invocation of the +TransientComposite. This allows them to change the invocation parameters, return their own values or throw their own +exceptions, and do other things which directly affect the invocation of the method.</p><p>Concerns should not perform any side-effects, such as updating state in another TransientComposite, Mixin or similar. +Any side-effects are done in SideEffects, which is another type of Modifier, which are allowed to perform side-effects +but, in contrast to Concerns, cannot change the parameters or in any other way change the result of the invocation.</p><p>Concerns are implemented in one of two ways: either create a class which directly implements the interface whose +methods should be modified, or create a generic Modifier by implementing the InvocationHandler interface (or subclass +GenericConcern which does this for you). Add an @ConcernFor dependency injection, as a field, constructor parameter +or method parameter, which has the same type as the interface the Concern implements. When the TransientComposite is +invoked the Concern will be called, allowing it to perform itâs work. If the call should proceed, then invoke the +method again on the injected object. The preferred way to do all of this is to subclass ConcernOf which does all of +this for you.</p><p>Concerns are applied by adding an @Concerns annotation on the TransientComposite, the domain interface, or the Mixin +implementation. Any of these works, and where to put it is a matter of design choice.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Create a typed concern, implement the HelloWorldBehaviour and let it modify the result of the base method by prefix the result with "Simon says:". +</li><li class="listitem"> +Add an @Concerns annotation on the HelloWorldBehaviourMixin which references the Concern class. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_5"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p>These ones remain unchanged:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorld.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldBehavior.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldComposite.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldState.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldStateMixin.java</code> +</li></ul></div><p><span class="strong"><strong>HelloWorldBehaviourMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * behaviour interface. + * <p> + * It uses a @This Dependency Injection + * annotation to access the state of the Composite. The field + * will be automatically injected when the Composite + * is instantiated. Injections of resources or references + * can be provided either to fields, constructor parameters or method parameters. + * </p> + */ +@Concerns( HelloWorldBehaviourConcern.class ) +public class HelloWorldBehaviourMixin + implements HelloWorldBehaviour +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.getPhrase() + " " + state.getName(); + } +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourConcern.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is a concern that modifies the mixin behaviour. + */ +public class HelloWorldBehaviourConcern + extends ConcernOf<HelloWorldBehaviour> + implements HelloWorldBehaviour +{ + @Override + public String say() + { + return "Simon says:" + next.say(); + } +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step5" title="Step 5 - Constraints">Step 5 - Constraints</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step5"></a>Step 5 - Constraints</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step4" title="Step 4 - Concerns">Step 4 - Concerns</a>.</p><p>In this step we will look at how to use Constraints. When we pass parameters to methods in regular Java code the only +restriction we can make is to denote a type. Any other constraints on the input value, such as whether the parameter is +optional, integer ranges, string regular expressions, and so on, cannot be expressed, and so we have to put this into +Javadoc, and then manually add these checks in the implementation class.</p><p>In Polygene⢠there is the option to use Constraints, which are further restrictions on the parameters. This is implemented +by having an annotation that describes what the Constraint does, and then an implementation class that checks whether a +specific value fulfills the Constraint or not.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The previous steps had a dependency to the <a class="xref" href="core-api.html" title="Core API"> Core API</a> only. The constraints youâve used in this step, +introduce a new dependency to the <a class="xref" href="library-constraints.html" title="Constraints">Constraints Library</a>, where all the constraint related classes reside. So +update your classpath settings accordingly.</p></div><p>There are a number of pre-written constraints in Polygene⢠which you can use. The null check of the original HelloWorld +version is already handled by default since Polygene⢠considers method parameters to be mandatory if not explicitly marked +with the @Optional annotation. So, instead of doing that check we will add other checks that are useful to make, such +as ensuring that the passed in string is not empty.</p><p>The only thing you have to do is add the annotation @NotEmpty to the method parameters you want to constrain in this +way. The annotation has a default implementation declared in it by using the @Constraints annotation. You can either +just use this, which is the common case, or override it by declaring your own @Constraints annotation in the +TransientComposite type.</p><p>You can add as many Constraint annotations you want to a parameter. All of them will be checked whenever a method is +called.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Add @NotEmpty to the state parameters. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_6"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p>These ones remain unchanged:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorld.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldComposite.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldStateMixin.java</code> +</li></ul></div><p><span class="strong"><strong>HelloWorldBehaviour.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the behaviour + * of the HelloWorld object. + * <p> + * It declares what Mixin to use as default implementation, and also the extra + * concern to be applied. + * </p> + */ +@Concerns( HelloWorldBehaviourConcern.class ) +@Mixins( HelloWorldBehaviourMixin.class ) +public interface HelloWorldBehaviour +{ + String say(); +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * behaviour interface. + * <p> + * It uses a @This DependencyModel Injection + * annotation to access the state of the Composite. The field + * will be automatically injected when the Composite + * is instantiated. Injections of resources or references + * can be provided either to fields, constructor parameters or method parameters. + * </p> + */ +public class HelloWorldBehaviourMixin + implements HelloWorldBehaviour +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.getPhrase() + " " + state.getName(); + } +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourConcern.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Concern validates the parameters + * to the HelloWorldState interface. + */ +public class HelloWorldBehaviourConcern + extends ConcernOf<HelloWorldBehaviour> + implements HelloWorldBehaviour +{ + @Override + public String say() + { + return "Simon says:" + next.say(); + } +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + * <p> + * The parameters are declared as @NotEmpty, so the client cannot pass in empty strings + * as values. + * </p> + */ +@Mixins( HelloWorldStateMixin.class ) +public interface HelloWorldState +{ + void setPhrase( @NotEmpty String phrase ) + throws IllegalArgumentException; + + String getPhrase(); + + void setName( @NotEmpty String name ) + throws IllegalArgumentException; + + String getName(); +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step6" title="Step 6 - SideEffects">Step 6 - SideEffects</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step6"></a>Step 6 - SideEffects</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step5" title="Step 5 - Constraints">Step 5 - Constraints</a>.</p><p>The current say() method has a Concern that modifies its value. What if we instead want the value to be intact, but log +that value to System.out? That would be considered a side-effect of the say() method, and should hence not be done in a +Concern. It would be better to implement this in a SideEffect. SideEffects are executed after the Mixin and all Concerns +for a method are done, which means that the final result has been computed. A SideEffect can access this result value, +and then use that for further computation, but it should not change the value or throw an exception.</p><p>SideEffects can be either typed or generic, just like Concerns. In the typed case we are interested in specifying +SideEffects for one or more particular methods, whereas in the generic case the SideEffect is not really relying on what +method is being invoked. Both are useful in different scenarios.</p><p>The easiest way to implement a typed SideEffect is to subclass the SideEffectOf class. This gives you access to the +result of the real method invocation by using the "next" field, which has the same type as the interface of the method +you want the code to be a side-effect of. Note that calling "next" does not actually do anything, it only returns the +value (or throws the exception, if one was thrown from the original method) that has already been computed. Similarly, +since the method is already done, you can return anything from the SideEffect method. The framework will simply throw it +away, and also ignore any exceptions that you throw in your code.</p><p>To declare that the SideEffect should be used you add the @SideEffects annotation to either the TransientComposite type, +the Mixin type, or the Mixin implementation. Either works.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Create the SideEffect class that logs the result of say() to System.out. +</li><li class="listitem"> +Add a @SideEffects annotation with the SideEffect to the HelloWorldComposite interface. +</li><li class="listitem"> +Remove the Concern from the previous step. +</li><li class="listitem"> +Move the HelloWorldStateMixin from the HelloWorldState to the HelloWorldComposite interface. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_7"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p>These ones remain unchanged:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorld.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldBehaviourMixin.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldStateMixin.java</code> +</li></ul></div><p><span class="strong"><strong>HelloWorldBehaviour.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the behaviour + * of the HelloWorld object. + */ +public interface HelloWorldBehaviour +{ + String say(); +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourSideEffect.java</strong></span></p><pre class="programlisting brush: java"> +/** + * As a side-effect of calling say, output the result. + */ +public class HelloWorldBehaviourSideEffect + extends SideEffectOf<HelloWorldBehaviour> + implements HelloWorldBehaviour +{ + @Override + public String say() + { + System.out.println( result.say() ); + return null; + } +} +</pre><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares transitively + * all the Fragments of the HelloWorld composite. + * <p> + * It declares that the HelloWorldBehaviourSideEffect should be applied. + * </p> + */ +@Mixins( { HelloWorldBehaviourMixin.class, HelloWorldStateMixin.class } ) +@SideEffects( HelloWorldBehaviourSideEffect.class ) +public interface HelloWorldComposite + extends HelloWorld, TransientComposite +{ +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + * <p> + * The parameters are declared as @NotEmpty, so the client cannot pass in empty strings + * as values. + * </p> + */ +public interface HelloWorldState +{ + void setPhrase( @NotEmpty String phrase ) + throws IllegalArgumentException; + + String getPhrase(); + + void setName( @NotEmpty String name ) + throws IllegalArgumentException; + + String getName(); +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step7" title="Step 7 - Properties">Step 7 - Properties</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step7"></a>Step 7 - Properties</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step6" title="Step 6 - SideEffects">Step 6 - SideEffects</a>.</p><p>One of the goals of Polygene⢠is to give you domain modeling tools that allow you to more concisely use domain concepts in +code. One of the things we do rather often is model Properties of objects as getters and setters. But this is a very +weak model, and does not give you any access to metadata about the property, and also makes common tasks like UI binding +non-trivial. There is also a lot of repetition of code, which is unnecessary. Using JavaBeans conventions one typically +have to have code in five places for one property, whereas in Polygene⢠the same thing can be achieved with one line of code.</p><p>But lets start out easy. To declare a property you have to make a method in a mixin type that returns a value of the +type Property, and which does not take any parameters. Hereâs a simple example:</p><pre class="programlisting brush: java">Property<String> name();</pre><p>This declares a Property of type String with the name "name". The Property interface has methods "get" and "set" to +access and mutate the value, respectively.</p><p>For now you will be responsible for implementing these methods, but later on these will be handled automatically, thus +reducing Properties to one-liners!</p><p>In the Mixin implementation of the interface with the Property declaration you should have an injection of the Property, +which is created for you by Polygeneâ¢. The injection can be done in a field like this:</p><pre class="programlisting brush: java">@State Property<String> name;</pre><p>The State dependency injection annotation means that Polygene⢠will inject the Property for you. The field has the name +"name", which matches the name in the interface, and therefore that Property is injected. You can then implement the +method trivially by just returning the "name" field.</p><p>Properties can have Constraints just like method parameters. Simply set them on the Property method instead, and they +will be applied just as before when you call "set".</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Remove JavaBeans properties from HelloWorldState. +</li><li class="listitem"> +Remove HelloWorld and add the HelloWorldState and HelloWorldBehavior to the HelloWorldComposite interface. +</li><li class="listitem"> +Remove the HelloWorldBehaviourSideEffect. +</li><li class="listitem"> +Update the behaviour mixin to use the state interface accordingly. +</li><li class="listitem"> +Add Property methods with the correct type and the @NotEmpty annotation. +</li><li class="listitem"> +Update the state mixin to inject and return the properties as described above. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_8"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p>Only <code class="literal">HelloWorldBehavior.java</code> remains unchanged.</p><p>Theses ones are deleted:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorld.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldConcern.java</code> +</li></ul></div><p><span class="strong"><strong>HelloWorldBehaviourMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * behaviour interface. + * <p> + * This version access the state using Polygene Properties. + * </p> + */ +public class HelloWorldBehaviourMixin + implements HelloWorldBehaviour +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.phrase().get() + " " + state.name().get(); + } +} +</pre><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares transitively + * all the Fragments of the HelloWorld composite. + */ +@Mixins( { HelloWorldBehaviourMixin.class, HelloWorldStateMixin.class } ) +public interface HelloWorldComposite + extends HelloWorldBehaviour, HelloWorldState, TransientComposite +{ +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + * <p> + * The state is now declared using Properties. The @NotEmpty annotation is applied to the + * method instead, and has the same meaning as before. + * </p> + */ +public interface HelloWorldState +{ + @NotEmpty + Property<String> phrase(); + + @NotEmpty + Property<String> name(); +} +</pre><p><span class="strong"><strong>HelloWorldStateMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * state interface. + */ +public class HelloWorldStateMixin + implements HelloWorldState +{ + @State + private Property<String> phrase; + @State + private Property<String> name; + + @Override + public Property<String> phrase() + { + return phrase; + } + + @Override + public Property<String> name() + { + return name; + } +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step8" title="Step 8 - Generic Mixins">Step 8 - Generic Mixins</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step8"></a>Step 8 - Generic Mixins</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step7" title="Step 7 - Properties">Step 7 - Properties</a>.</p><p>In this step we will look at how to use generic Fragments. So far all Fragments, i.e. the Concerns, SideEffects, +and Mixins, have directly implemented the domain interface. But sometimes it is useful to be able to provide a generic +implementation of an interface. An example of this is the HelloWorldState interface. Since it only handles properties, +and the old version used the JavaBean rules for naming getters and setters we could create a mixin that handles +invocations of such methods automatically for us by storing the properties in a map and use the methods to look them up.</p><p>Implementing a generic Fragment is done by creating a class that implements the interface +java.lang.proxy.InvocationHandler. This has a single "invoke" method which is passed the object that was invoked (the +TransientComposite in this case), the method, and the arguments. The Fragment is then allowed to implement the method +any way it wants.</p><p>Since interfaces with only Properties is such a common case Polygene⢠already has a generic Mixin that implements the +Properties management described above, but for the builtin Property type instead of the getter/setter variant. The +class is aptly named PropertyMixin.</p><p>While we could use it, for now we will implement it ourselves to get a feel for how generic Mixins work.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Remove the HelloWorldStateMixin +</li><li class="listitem"> +Add a GenericPropertyMixin, and have it implement InvocationHandler +</li><li class="listitem"> +Inject "@State StateHolder state" in the mixin. The StateHolder interface will give you access to the Properties for the TransientComposite which Polygene⢠manages for you +</li><li class="listitem"> +On call to invoke(), delegate to the StateHolder interface to get the Property for the invoked method +</li><li class="listitem"> +Add an @AppliesTo annotation to the Mixin and implement the AppliesToFilter with a rule that matches only methods that return Property values. +</li><li class="listitem"> +Add the mixin to the TransientComposite. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_9"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts;</p><p>These ones remain unchanged:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<code class="literal">HelloWorldBehaviour.java</code> +</li><li class="listitem"> +<code class="literal">HelloWorldState.java</code> +</li></ul></div><p><span class="strong"><strong>GenericPropertyMixin.java</strong></span></p><pre class="programlisting brush: java">@AppliesTo( { GenericPropertyMixin.PropertyFilter.class } ) +public class GenericPropertyMixin + implements InvocationHandler +{ + @State + private StateHolder state; + + @Override + public Object invoke( Object proxy, Method method, Object[] args ) + throws Throwable + { + return state.propertyFor( method ); + } + + public static class PropertyFilter + implements AppliesToFilter + { + @Override + public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> modifierClass ) + { + return Property.class.isAssignableFrom( method.getReturnType() ); + } + } +} +</pre><p><span class="strong"><strong>HelloWorldBehaviourMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the HelloWorld + * behaviour interface. + */ +public class HelloWorldBehaviourMixin + implements HelloWorldBehaviour +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.phrase().get() + " " + state.name().get(); + } +} +</pre><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares transitively + * all the Fragments of the HelloWorld composite. + * <p> + * All standard declarations have been moved to + * the StandardAbstractEntityComposite so we don't have to repeat + * them in all Composites. + * </p> + */ +@Mixins( { HelloWorldBehaviourMixin.class, GenericPropertyMixin.class } ) +public interface HelloWorldComposite + extends HelloWorldBehaviour, HelloWorldState, TransientComposite +{ +} +</pre><p>Next step is <a class="xref" href="tut-composites.html#tut-composites-step9" title="Step 9 - Private and Abstract Mixins">Step 9 - Private and Abstract Mixins</a></p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-composites-step9"></a>Step 9 - Private and Abstract Mixins</h4></div></div></div><p>Previous step was <a class="xref" href="tut-composites.html#tut-composites-step8" title="Step 8 - Generic Mixins">Step 8 - Generic Mixins</a>.</p><p>Now weâre going to turn around and see how we can reduce the code needed to implement the HelloWorld example. We will +also look at how to hide the Properties from the client code, since Properties are often considered to be implementation +details that should not be exposed to clients.</p><p>The first thing we will do is remove the behaviour interface, and move the say() method to the TransientComposite type. +This forces the mixin to implement the TransientComposite type, which would normally mean that it would have to +implement all methods, including those found in the TransientComposite interface. However, since we are only really +interested in implementing the say() method we will mark this by declaring that the Mixin "implements" the +TransientComposite type, but is also "abstract". This, using pure Java semantics, makes it possible to avoid having to +implement all methods. Polygene⢠will during the initialization phase detect that the Mixin only handles the say() method, +and therefore only map it to that specific method. In order to instantiate the Mixin it will generate a subclass which +implements the remaining methods in the TransientComposite type, as no-ops. These will never be called however, and is +there purely for the purpose of being able to instantiate the Mixin. The Mixin is considered to be an Abstract Fragment.</p><p>To hide the state from the client we need to use what is called Private Mixins. A Private Mixin is any mixin that is +referenced by another Mixin by using the @This injection, but which is not included in the TransientComposite type. As +long as there is a Mixin implementation declared for the interface specified by the @This injection it will work, since +Polygene⢠can know how to implement the interface. But since it is not extended by the TransientComposite type there is no +way for a user of the TransientComposite to access it. That Mixin becomes an implementation detail. This can be used +either for encapsulation purposes, or for referencing utility mixins that help the rest of the code implement some +interface, but which itself should not be exposed.</p><p>Since the state is now hidden the initialization of the TransientComposite is a bit more tricky. Instead of just +instantiating it you have to create a TransientBuilder first, then set the state using .prototypeFor(), and then call +newInstance(). This ensures that the state can be set during construction, but not at any later point, other than +through publicly exposed methods.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Move the say() method into the TransientComposite interface. +</li><li class="listitem"> +Remove the behaviour interface. +</li><li class="listitem"> +Remove the HelloWorldBehaviourMixin, create a HelloWorldMixin and let the HelloWorldMixin implement the TransientComposite directly. +</li><li class="listitem"> +Mark the HelloWorldMixin as abstract and implement only the say() method. +</li><li class="listitem"> +Remove the HelloWorldState from the TransientComposite "extends" declaration. +</li><li class="listitem"> +Remove the GenericPropertyMixin. The Property methods will be implemented by the standard PropertyMixin declared in the TransientComposite interface instead. +</li></ul></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="_solution_10"></a>Solution</h5></div></div></div><p>If you have successfully completed the task, you should end up with the following artifacts only;</p><p><span class="strong"><strong>HelloWorldComposite.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This Composite interface declares transitively all the Fragments of the HelloWorld composite. + * <p> + * The Fragments are all abstract, so it's ok to + * put the domain methods here. Otherwise the Fragments + * would have to implement all methods, including those in Composite. + * </p> + */ +@Mixins( { HelloWorldMixin.class } ) +public interface HelloWorldComposite + extends TransientComposite +{ + String say(); +} +</pre><p><span class="strong"><strong>HelloWorldMixin.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This is the implementation of the say() method. The mixin + * is abstract so it doesn't have to implement all methods + * from the Composite interface. + */ +public abstract class HelloWorldMixin + implements HelloWorldComposite +{ + @This + HelloWorldState state; + + @Override + public String say() + { + return state.phrase().get() + " " + state.name().get(); + } +} +</pre><p><span class="strong"><strong>HelloWorldState.java</strong></span></p><pre class="programlisting brush: java"> +/** + * This interface contains only the state + * of the HelloWorld object. + */ +public interface HelloWorldState +{ + @NotEmpty + Property<String> phrase(); + + @NotEmpty + Property<String> name(); +} +</pre></div></div></div><footer xmlns="" xmlns:exsl="http://exslt.org/common" class="footer"><div class="container"><p class="text-muted">Copyright © 2017 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/" target="_blank">Apache License, Version 2.0</a>. + Apache Polygene, Polygene, Apache, the Apache feather logo, and the Apache Polygene project logo are + trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners. + </p></div></footer><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common">window.jQuery || document.write('<script src="js/jquery-1.6.4.min.js"></script>')</script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="bootstrap-3.3.7/js/bootstrap.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="js/ie10-viewport-bug-workaround.js"></script></body></html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/polygene-website/blob/bb9c9971/content/java/2017/tut-services.html ---------------------------------------------------------------------- diff --git a/content/java/2017/tut-services.html b/content/java/2017/tut-services.html new file mode 100644 index 0000000..ea2ed27 --- /dev/null +++ b/content/java/2017/tut-services.html @@ -0,0 +1,173 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Services Composites Tutorial</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /><link rel="home" href="index.html" title="" /><link rel="up" href="tutorials.html" title="Tutorials" /><link rel="prev" href="tut-composites.html" title="Transient Composites Tutorial" /><link rel="next" href="howto-contextual-fragments.html" title="Use contextual fragments" /> + + + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> + <meta name="description" content=""> + <meta name="author" content=""> + <link rel="icon" href="../../favicon.ico"> + + <title>Starter Template for Bootstrap</title> + + <!-- Bootstrap core CSS --> + <link href="bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"> + + <!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> + <link href="css/ie10-viewport-bug-workaround.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="css/polygene-ng.css" rel="stylesheet"> + + <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> + <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> + <script src="js/ie-emulation-modes-warning.js"></script> + + <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + +<!-- favicon --> + +<link rel="shortcut icon" href="http://polygene.apache.org/favicon.ico" type="image/vnd.microsoft.icon" /> +<link rel="icon" href="http://polygene.apache.org/favicon.ico" type="image/x-icon" /> + +<!-- style --> + +<link href="css/shCore.css" rel="stylesheet" type="text/css" /> +<link href="css/shCoreEclipse.css" rel="stylesheet" type="text/css" /> +<link href="css/shThemeEclipse.css" rel="stylesheet" type="text/css" /> +<!--<link href="css/polygene.css" rel="stylesheet" type="text/css" />--> + +<!-- Syntax Highlighter --> + +<script type="text/javascript" src="js/shCore.js"></script> +<script type="text/javascript" src="js/shBrushJava.js"></script> +<script type="text/javascript" src="js/shBrushScala.js"></script> +<script type="text/javascript" src="js/shBrushJScript.js"></script> +<script type="text/javascript" src="js/shBrushBash.js"></script> +<script type="text/javascript" src="js/shBrushPlain.js"></script> +<script type="text/javascript" src="js/shBrushXml.js"></script> +<script type="text/javascript" src="js/shBrushGroovy.js"></script> +<script type="text/javascript" src="js/shBrushPython.js"></script> +<script type="text/javascript" src="js/shBrushRuby.js"></script> +<script type="text/javascript" src="js/shBrushCSharp.js"></script> + +<script type="text/javascript"> + SyntaxHighlighter.defaults['tab-size'] = 4; + SyntaxHighlighter.defaults['gutter'] = false; + SyntaxHighlighter.defaults['toolbar'] = false; + SyntaxHighlighter.all() +</script> + +<!-- JQuery --> + +<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script> + +<!-- Image Scaler --> + +<script type="text/javascript" src="js/imagescaler.js"></script> + +<!-- Table Styler --> + +<script type="text/javascript" src="js/tablestyler.js"></script> + +<!-- Apache Polygene WebSite Progressive Enhancement --> + +<link href="css/progressive-enhancement.css" rel="stylesheet" type="text/css" /> +<script type="text/javascript" src="js/jquery.scrollTo-1.4.2.js"></script> +<script type="text/javascript" src="js/progressive-enhancement.js"></script> + +<!-- Analytics --> + <script type="text/javascript"> + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-62007352-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); + </script> + + </head><body><div xmlns="" xmlns:exsl="http://exslt.org/common" class="logo"><a href="index.html"><img src="images/logo-standard.png" /></a></div><nav xmlns="" xmlns:exsl="http://exslt.org/common" class="navbar navbar-inverse navbar-fixed-top"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="#">Apache<br />Polygene + </a></div><div id="navbar" class="collapse navbar-collapse"><span class="nav navbar-nav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><a href="index.html#home">Polygeneâ¢</a></span></dt><dt><span class="section"><a href="intro.html">Introduction</a></span></dt><dt><span class="section"><span xmlns="" href="tutorials.html">Tutorials</span></span></dt><dt><span class="section"><a href="javadocs.html">Javadoc</a></span></dt><dt><span class="section"><a href="samples.html">Samples</a></span></dt><dt><span class="section"><a href="core.html">Core</a></span></dt><dt><span class="section"><a href="libraries.html">Libraries</a></span></dt><dt><span class="section"><a href="extensions.html">Extensions</a></span></dt><dt><span class="section"><a href="tools.html">Tools</a></span></dt><dt><span class="section"><a href="glossary.html">Glossary </a></span></dt></dl></div></span></div></div></nav><div xmlns="" xmlns:exsl="http://exslt .org/common" class="sidenav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl class="toc"><dt><span class="section"><a href="tutorials.html#_overview">Overview</a></span></dt><dt><span class="section"><a href="two-minutes-intro.html">Polygene⢠in 2 minutes</a></span></dt><dt><span class="section"><a href="ten-minutes-intro.html">Polygene⢠in 10 minutes</a></span></dt><dt><span class="section"><a href="thirty-minutes-intro.html">Polygene⢠in 30 minutes</a></span></dt><dt><span class="section"><a href="howto-depend-on-polygene.html">Depend on Polygeneâ¢</a></span></dt><dt><span class="section"><a href="howto-assemble-application.html">Assemble an Application</a></span></dt><dt><span class="section"><a href="tut-composites.html">Transient Composites Tutorial</a></span></dt><dt><span class="section"><span xmlns="" href="tut-services.html">Services Composites Tutorial</span></span></dt><dt><span class="section"><a href="howto-contextual-fragments.html">Use contextual frag ments</a></span></dt><dt><span class="section"><a href="howto-leverage-properties.html">Leverage Properties</a></span></dt><dt><span class="section"><a href="howto-create-constraint.html">Create a Constraint</a></span></dt><dt><span class="section"><a href="howto-create-concern.html">Create a Concern</a></span></dt><dt><span class="section"><a href="howto-create-sideeffect.html">Create a SideEffect</a></span></dt><dt><span class="section"><a href="howto-create-entity.html">Create an Entity</a></span></dt><dt><span class="section"><a href="howto-configure-service.html">Configure a Service</a></span></dt><dt><span class="section"><a href="howto-invocation-annotation.html">Use @Invocation</a></span></dt><dt><span class="section"><a href="build-system.html">Polygene⢠Build System</a></span></dt><dt><span class="section"><a href="community-docs.html">Polygene⢠Documentation</a></span></dt><dt><span class="section"><a href="releasing-apache.html">Releasing Polygeneâ¢</a></span></dt>< /dl></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="tut-services"></a>Services Composites Tutorial</h3></div></div></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>Theses tutorials are based on actual code found in the <code class="literal">tutorials/</code> directory of the +<a class="ulink" href="http://polygene.apache.org/download.html" target="_top">Polygene⢠SDK sources</a>. You should start your favorite editor and find the code related to +this tutorial, run it and play with it.</p></div><p>In this other set of tutorials it will be shown how to create and work with Service Composites, which are composites +that extends from the ServiceComposite class. We will refactor one a very simple Library where you can borrow and +return books to take advantage of the various features in Polygeneâ¢. These refactorings will benefit from automatic Service +activation and Configuration Entities management.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +<a class="xref" href="tut-services.html#tut-services-step1" title="Step 1 - Creating a ServiceComposite">Step 1 - Creating a ServiceComposite</a> +</li><li class="listitem"> +<a class="xref" href="tut-services.html#tut-services-step2" title="Step 2 - Hooking into the Service Activation">Step 2 - Hooking into the Service Activation</a> +</li><li class="listitem"> +<a class="xref" href="tut-services.html#tut-services-step3" title="Step 3 - Reading the Service Configuration">Step 3 - Reading the Service Configuration</a> +</li></ul></div><p>Each tutorial step in this series starts with the result from the previous tutorial, so you can +always look at the next tutorial step for guidance on what to do.</p><p>At the bottom of each tutorial step, the is Solutions section, which list the files you should have come to if you +have followed the instructions.</p><p>If you want to reproduce whatâs explained in this tutorial, remember to depend on the Core Runtime artifact that depends +on Core API, Core SPI, and Core Bootstrap:</p><div class="table"><a id="idm1455"></a><p class="title"><strong>Table 6. Artifact</strong></p><div class="table-contents"><table summary="Artifact" border="1"><colgroup><col class="col_1" /><col class="col_2" /><col class="col_3" /></colgroup><thead><tr><th align="left" valign="top">Group ID</th><th align="left" valign="top">Artifact ID</th><th align="left" valign="top">Version</th></tr></thead><tbody><tr><td align="left" valign="top"><p>org.apache.polygene.core</p></td><td align="left" valign="top"><p>org.apache.polygene.core.runtime</p></td><td align="left" valign="top"><p>0</p></td></tr></tbody></table></div></div><br class="table-break" /><p>See the <a class="xref" href="howto-depend-on-polygene.html" title="Depend on Polygeneâ¢">Depend on Polygeneâ¢</a> tutorial for details.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-services-step1"></a>Step 1 - Creating a ServiceComposite</h4></div></d iv></div><p>In this tutorial we start with basic Java classes, to simulate a very simple Library where you can borrow +and return books.</p><p>Polygene⢠relies heavily on the use of interfaces. This makes it possible for an object +to externally implement a number of interfaces which internally is backed by a number +of Mixins, some of which you may have written yourself, and some of which may have been +reused. This is also true for services, which we are to cover in this tutorial.</p><p>The first task is therefore to refactor the code so that the methods are implemented from an +interface instead, and to essentially make the identical "application" into a Polygene⢠application. +We also want the Book to be a ValueComposite.</p><p>Steps for this tutorial:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Make the Book into a ValueComposite. +</li><li class="listitem"> +Make the Library an interface with the same methods. We call this a MixinType. +</li><li class="listitem"> +Create a LibraryMixin class, which implements the Library interface. +</li><li class="listitem"> +Create a LibraryService that binds the LibraryMixin. +</li><li class="listitem"> +The LibraryMixin will need to be injected with the ValueBuilderFactory in the @Structure scope. +</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-services-step2"></a>Step 2 - Hooking into the Service Activation</h4></div></div></div><p>Services can be "activated" and "passivated". Applications can be notified of this occurring +by Polygene⢠runtime by assembling them with an Activator.</p><p>Activators methods are called around "activation" and "passivation": beforeActivation, +afterActivation, beforeActivation, afterPassivation. The +ActivatorAdapter class help you keeping your code short when you only need one or two hooks.</p><p>To showcase how this works, we refactor the code to create a number of copies of the books, to be lend out +upon call to the borrowBook method, which will return null if no copy is available. The book +copies are created in the activate method.</p><p>Steps to do:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Add a createInitialData method to Library. +</li><li class="listitem"> +In the implementation, create a couple of books of each title and store each copy in a HashMap<String,ArrayList<Book>>. +</li><li class="listitem"> +Write an Activator<ServiceReference<Library>> class extending ActivatorAdapter. +</li><li class="listitem"> +Override the afterActivation method, use the ServiceReference to get a handle on the Library and call its createInitialData method. +</li><li class="listitem"> +Add the @Activators annotation to the LibraryService declaring the new LibraryActivator. +</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="tut-services-step3"></a>Step 3 - Reading the Service Configuration</h4></div></div></div><p>Services typically have configuration. Configurations are directly supported in Polygeneâ¢. A +ConfigurationComposite is a subtype of EntityComposite. That is because +configurations are stored in EntityStores, can be modified in runtime by client code and has +the same semantics as regular entities.</p><p>Polygene⢠also handles the bootstrapping of configuration for the services. If the ConfigurationComposite is +not found in the configured entity store, then Polygene⢠will automatically locate a properties file for each +service instance, read those properties into a ConfigurationComposite instance, save that to the +entity store and provide the values to the service. The properties file must be with the same name as +the service instance with the extension "properties" in the same package as the service.</p><p>For this exercise, create a LibraryConfiguration that contains "titles", "authors" and "copies". +The first two are a string with a comma separated list, and the "copies" is just an Integer with how many +copies are made of each title.</p><p>Steps to do.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> +Create a LibraryConfiguration interface that extends ConfigurationComposite, and has three Property instances named "titles", "authors" and "copies", where the first two are of String type and the last is of Integer type. +</li><li class="listitem"> +Delete the LibraryActivator and remove the @Activators annotation from the LibraryService and the corresponding createInitialData method. +</li><li class="listitem"> +In the LibraryMixin remove the member injection of the ValueBuilderFactory, and instead inject the ValueBuilderFactory in the constructor. +</li><li class="listitem"> +Inject the LibraryConfiguration via the constructor. The injection scope is @This. +</li><li class="listitem"> +Create a resource called LibraryService.properties and place it in the directory <code class="literal">org/apache/polygene/tutorials/services/step4</code> in the classpath (for instance, src/main/resources ). Put something like this in: + titles=Domain Driven Design, Pragmatic Programmer, Extreme Programming Explained + authors=Eric Evans, Andy Hunt, Kent Beck + #Number of copies of each book. + copies=3 +</li><li class="listitem"> +Load initial data from the LibraryConfiguration in the LibraryMixin constructor. +</li></ul></div></div></div><footer xmlns="" xmlns:exsl="http://exslt.org/common" class="footer"><div class="container"><p class="text-muted">Copyright © 2017 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/" target="_blank">Apache License, Version 2.0</a>. + Apache Polygene, Polygene, Apache, the Apache feather logo, and the Apache Polygene project logo are + trademarks of The Apache Software Foundation. + All other marks mentioned may be trademarks or registered trademarks of their respective owners. + </p></div></footer><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common">window.jQuery || document.write('<script src="js/jquery-1.6.4.min.js"></script>')</script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="bootstrap-3.3.7/js/bootstrap.min.js"></script><script xmlns="" xmlns:exsl="http://exslt.org/common" src="js/ie10-viewport-bug-workaround.js"></script></body></html> \ No newline at end of file
