You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2017/10/10 06:46:15 UTC

[isis] branch master updated: ISIS-1465: adds section describing the structure of the helloworld app

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c25bae  ISIS-1465: adds section describing the structure of the helloworld app
5c25bae is described below

commit 5c25bae685c732ccec0602ba8dfb6d86b83b6ea9
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Oct 10 07:46:05 2017 +0100

    ISIS-1465: adds section describing the structure of the helloworld app
---
 .../src/main/asciidoc/guides/htg.adoc              |   1 -
 ...ugfun_getting-started_helloworld-archetype.adoc | 244 ++++++++++++++++++++-
 2 files changed, 242 insertions(+), 3 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/htg.adoc b/adocs/documentation/src/main/asciidoc/guides/htg.adoc
index 64f6e32..e9ada3d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/htg.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/htg.adoc
@@ -4,7 +4,6 @@
 :_basedir: ../../
 :_imagesdir: images/
 :numbered:
-:generate_pdf:
 :toc: right
 
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_helloworld-archetype.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_helloworld-archetype.adoc
index 69a15bf..8e47941 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_helloworld-archetype.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_helloworld-archetype.adoc
@@ -63,6 +63,245 @@ where `myapp` is the `artifactId` entered above.
 
 
 
+[[__ugfun_getting-started_helloworld-archetype_structure-of-the-app]]
+== Structure of the App
+
+As noted above, the application generated by the helloworld archetype is deliberately simplified, with everything contained within a single Maven module.
+
+Under `src/main/java` we have:
+
+[monotree]
+----
+> domainapp/
+>> application/
+>>> HelloWorldAppManifest.java
+>>> isis.properties
+>> dom/
+>>> HelloWorldModule.java
+>>> impl/
+>>>> HelloWorldObject.java
+>>>> HelloWorldObject.layout.xml
+>>>> HelloWorldObject.png
+>>>> HelloWorldObjects.java
+>> app/
+>>> HelloWorldApplication.java
+>>> welcome.html
+----
+
+For simplicity, all the Java source files generated by the archetype are placed in a `domainapp` top-level package.
+
+[TIP]
+====
+While it's more conventional to use the inverse domain name for package (eg `com.mycompany.myapp`, that's only really appropriate for library code that will be released for reuse by multiple applications in different orgnisations (eg open source).
+
+For internal application though this is less of a concern; indeed, avoiding using the domain name means that if the company is taken over then nothing needs be changed.
+
+Of course, just are free to move the classes to a different package if you wish.
+====
+
+In `domainapp.application` package is `HelloWorldAppManifest`, which implements the `AppManifest` interface defined by the Apache Isis applib.
+The class is only small, so is worth showing here in its entirety:
+
+[source,java]
+----
+public class HelloWorldAppManifest extends AppManifestAbstract {
+    public static final Builder BUILDER = Builder
+            .forModules(HelloWorldModule.class)
+            .withConfigurationPropertiesFile(HelloWorldAppManifest.class, "isis.properties")
+            .withAuthMechanism("shiro");
+
+    public HelloWorldAppManifest() {
+        super(BUILDER);
+    }
+}
+----
+
+Rather than implement `AppManifest` directly, `HelloWorldAppManifest` uses the builder provided by the convenience `AppManifestAbstract`); as you'll find when you work on bigger applications, it's common to have variations around the app manifest, so the builder makes it easy to create these variations without lots of boilerplate.
+
+For now, we see that (using the builder) the app manifest defines three things:
+
+* a list of modules - there's just one, `HelloWorldModule` for this class
+* the location of a configuration file, `isis.properties`, read in as a resource from the classpath
+* specifying an authentication/authorisation mechanism, in this case Apache Shiro integration.
+
+In Apache Isis a module is simply an empty class, which is used simply to obtain a package name.
+The framework uses classpath scanning to find certain classes; rather than scan the entire classpath it limits its search to the package(s) obtained from the modules.
+
+The packages are scanned to identify three types of classes:
+
+* all entities.
++
+These are entities that are annotated with `@javax.jdo.annotations.PersistenceCapable`.
+These are passed through to the JDO (DataNucleus) object store, in order to create database mappings from the entities to relational tables
+
+In the helloworld application, the only entity is `HelloWorldObject`.
+
+* all domain services
++
+These are classes that are annotated with the framework's `@DomainService` annotation.
+Depending on their nature, services are used to build up the menu, or are available to call programmatically, eg repositories.
+The framework instantiates an instance of each and will automatically inject the services into other domain objects and services.
+
++
+In the helloworld application, the only domain service  is `HelloWorldObjects`.
+This appears in the menu, and also acts as a repository for the `HelloWorldObject` entity.
+
+* all fixture scripts
++
+These are classes that extend from the applib `FixtureScript` class, and are used to setup the database when running in prototype mode (against an in-memory database.
++
+The helloworld application doesn't provide any examples of these.
+
+The app manifest also identifies the `isis.properties` file (in the same package as `HelloWorldAppManifest`) as containing various configuration options.
+The helloworld application uses these for settings that are unlikely to change and so are loaded as a static resource from the classpath.
+
+You'll find that there's another file called `isis.properties` that's in `WEB-INF/isis.properties`.
+This also provides configuration options (the framework simply combines them) but those in `WEB-INF/isis.properties` are restricted to settings that are likely to change from environment to environment, most notably JDBC URL connection strings.
+Separating these out makes it easy to reconfigure the application to run against different databases in different environments (dev, test, production etc).
+
+Finally, the app manifest identifies Apache Shiro for authentication and authorisation.
+Shiro in turn is configured using the `WEB-INF/shiro.ini` file.
+
+[TIP]
+====
+The security integration provided by Apache Isis and Shiro is quite sophisticated; to get started though you can just login using:
+
+* username: `sven`
+* password: `pass`
+====
+
+In the `domainapp.dom` module ("dom" stands for "domain object model") is the `HelloWorldModule`:
+
+[source,java]
+----
+package domainapp.dom;
+public final class HelloWorldModule {
+    private HelloWorldModule(){}
+}
+----
+
+As already explained, this is simply used by the app manifest to identify "domainapp.dom" as the package to scan to locate entities (`HelloWorldObject`), services (`HelloWorldObjects`) and fixture scripts (none provided).
+
+In the `domainapp.dom.impl` we have the classes that actually comprise our domain object.
+These are a little large to list here in their entirety, but it's worth calling out:
+
+* `HelloWorldObject`:
+
+** is annotated with a bunch of JDO annotations, `@PersistenceCapable` being the most important.
++
+This annotation is what identifies the class as an entity, so that Apache Isis passes through to JDO/DataNucleus during bootstrapping (to create the ORM mappings).
+
+** is also annotated with Isis' own `@DomainObject`.
++
+This isn't mandatory, but since entities are the real building blocks on which Isis applications are built, it's very common to use this annotation.
+
+** also uses various Project Lombok annotations to remove boilerplate.
+
+* `HelloWorldObject.layout.xml` defines the layout of the properties and actions of the `HelloWorldObject` (this class doesn't have any collections).
+
+* `HelloWorldObject.png` is used as an icon for any instances of the domain object shown in the (Wicket) viewer
+
+* `HelloWorldObjects` is a domain service by virtue of the fact that it is annotated with Isis' `@DomainService`.
+
+This acts as both a menu (the `@DomainService#nature` attribute) and also a repository to find/create instances of `HelloWorldObject`.
+
+Finally, in the `domainapp.webapp` we have `HelloWorldApplication`.
+This is required to bootstrap the Wicket viewer (it is configured in `WEB-INF/web.xml`).
+Internally it uses Google Guice to configure various static resources served up by Wicket:
+
+[source,java]
+----
+public class HelloWorldApplication extends IsisWicketApplication {
+    ...
+    @Override
+    protected Module newIsisWicketModule() {
+        final Module isisDefaults = super.newIsisWicketModule();
+        final Module overrides = new AbstractModule() {
+            @Override
+            protected void configure() {
+                ...
+            }
+        };
+        return Modules.override(isisDefaults).with(overrides);
+    }
+}
+----
+
+The `configure()` method is the place to change the name of the application for example, or to change the initial about and welcome messages.
+The text of the welcome page shown by the Wicket viewer can be found in `welcome.html`, loaded from the classpath and in the same package as `HelloWorldApplication`.
+
+Under `src/main/webapp` we have various resources that are used to configure the webapp, or that are served up by the running webapp:
+
+[monotree]
+----
+> about/
+>> index.html
+> css/
+>> application.css
+> scripts/
+>> application.js
+> swagger-ui/
+> WEB-INF/
+>> isis.properties
+>> logging.properties
+>> shiro.ini
+>> web.xml
+----
+
+Most important of these is `WEB-INF/web.xml`, which bootstraps both the Wicket viewer and the Restful Objects viewer (the REST API derived from the domain object model).
+
+The `about/index.html` is the page shown at the root of the package, providing links to either the Wicket viewer or to Swagger.
+In a production application this is usually replaced with a page that does an HTTP 302 redirect to the Wicket viewer.
+
+In `css/application.css` you can use to customise CSS, typically to highlight certain fields or states.
+The pages generated by the Wicket viewer have plenty of CSS classes to target.
+You can also implement the `cssClass()` method in each domain object to provide additional CSS classes to target.
+
+Similarly, in `scripts/application.js` you have the option to add arbitrary Javascript.
+JQuery is available by default.
+
+In `swagger-ui` is a copy of the Swagger 2.x UI classes, preconfigured to run against the REST API exposed by the Restful Objects viewer.
+This can be useful for developing custom applications, and is accessible from the initial page (served up by `about/index.html`).
+
+Finally in `WEB-INF` we have the standard `web.xml` (already briefly discussed) along with several other files:
+
+* `isis.properties` contains further configuration settings for Apache Isis itself.
++
+(As already discsussed), these are in addition to the configuration files found in the `isis.properties` that lives alongside the `HelloWorldAppManifest` class.
+Those in the WEB-INF/isis.properties file are those that are likely to change when running the application in different environments.
+
+* `logging.properties` configures log4j.
++
+The framework is configured to use slf4j running against log4j.
+
+* `shiro.ini` configures Apache Shiro, used for security (authentication and authorisation)
+
+* `web.xml` configures the Wicket viewer and Restful Objects viewer.
+It also sets up various filters for serving up static resources with caching HTTP headers.
+
+Under `src/test/java` we have:
+
+[monotree]
+----
+> domainapp
+>> dom
+>>> impl
+>>>> HelloWorldObjectTest_delete.java
+>>>> HelloWorldObjectTest_updateName.java
+----
+
+These are very simple unit tests of `HelloWorldObject`.
+They use JMock as the mocking library (with some minor extensions provided by Apache Isis itself).
+
+Finally, at the root directory we of course have the `pom.xml`.
+Some notable points:
+
+* since this module generates a WAR file, the `pom.xml` uses `<packaging>war</packaging>`
+
+* maven mixins are used to remove boilerplate configuration of standard plugins (resources, compile, jar etc), for the DataNucleus enhancer, for surefire (tests), and for running the application using jetty plugin
+
+Now you know your way around the code generated by the archetype, lets see how to run it.
+
 [[__ugfun_getting-started_helloworld-archetype_running-the-app]]
 == Running the App
 
@@ -253,10 +492,10 @@ The REST API implemented by Apache Isis is specified in the link:http://www.rest
 
 
 [[__ugfun_getting-started_helloworld-archetype_experimenting]]
-== Experimenting
+== Experimenting with the App
 
 Once you are familiar with the generated app, try modifying it.
-There is plenty of guidance on this site; start with this guide (fundamentals) and then look at the other guides available the main xref:../../documentation.adoc#[documentation] page.
+There is plenty more guidance on this site; start with this guide (fundamentals) and then look at the other guides available the main xref:../../documentation.adoc#[documentation] page.
 
 If you use IntelliJ IDEA or Eclipse, do also install the xref:../dg/dg.adoc#__dg_ide_intellij_live-templates[live templates (for IntelliJ)] / xref:../dg/dg.adoc#__dg_ide_eclipse_editor-templates[editor templates (for Eclipse)]; these will help you follow the Apache Isis naming conventions.
 
@@ -272,3 +511,4 @@ Instead, we suggest that you start with the xref:ugfun.adoc#_ugfun_getting-start
 Although a little more complex, it provides more structure and tests, all of which will help you as your application grows.
 
 
+

-- 
To stop receiving notification emails like this one, please contact
['"commits@isis.apache.org" <co...@isis.apache.org>'].