You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by bu...@apache.org on 2015/01/02 13:14:36 UTC
svn commit: r934776 - in /websites/staging/isis/trunk: cgi-bin/ content/
content/intro/tutorials/step-by-step-petclinic.html
Author: buildbot
Date: Fri Jan 2 12:14:36 2015
New Revision: 934776
Log:
Staging update by buildbot for isis
Modified:
websites/staging/isis/trunk/cgi-bin/ (props changed)
websites/staging/isis/trunk/content/ (props changed)
websites/staging/isis/trunk/content/intro/tutorials/step-by-step-petclinic.html
Propchange: websites/staging/isis/trunk/cgi-bin/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Fri Jan 2 12:14:36 2015
@@ -1 +1 @@
-1649008
+1649009
Propchange: websites/staging/isis/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Fri Jan 2 12:14:36 2015
@@ -1 +1 @@
-1649008
+1649009
Modified: websites/staging/isis/trunk/content/intro/tutorials/step-by-step-petclinic.html
==============================================================================
--- websites/staging/isis/trunk/content/intro/tutorials/step-by-step-petclinic.html (original)
+++ websites/staging/isis/trunk/content/intro/tutorials/step-by-step-petclinic.html Fri Jan 2 12:14:36 2015
@@ -786,7 +786,7 @@ git checkout <a href="https://github.com
<div class="note">
-git checkout [xxx](https://github.com/danhaywood/isis-app-petclinic/commit/xxx)
+git checkout [6f92a8ee8e76696d005da2a8b7a746444d017546](https://github.com/danhaywood/isis-app-petclinic/commit/6f92a8ee8e76696d005da2a8b7a746444d017546)
</div>
@@ -801,532 +801,12 @@ git checkout [xxx](https://github.com/da
-
-6364d75fe7930e9184b19eae396ce1a7
-
-
-
-The remainder of the tutorial provides guidance on building a domain application. We'd rather you build your own app, but if you're not feeling inspired, you could have a go at building our "petclinic" app. Here's the design:
-
-
-
-In case you're interested, the above diagram was built using [yuml.me][http://yuml.me]; the DSL that defines this diagram is:
-
-
-632694ea02e98d2525e3c95dcb1d0d1d
-
-
-
-
-
-
-
-
-210ceda1ce4bc865fb97197f7eb13bb7
-
-
-
-Most domain objects in Apache Isis applications are persistent entities. In the simpleapp archetype the `SimpleObject` is an example. We can start developing our app by refactoring that class:
-
-
-
-dcecd86fdc9659789b687ae81b71e297
-
-
-
-
-df434499c20a1fb68f0c4c3662b482d6
-
-
-
-Domain services often act as factories or repositories to entities; more generally can be used to "bridge across" to other domains/bounded contexts. Most are application-scoped, but they can also be request-scoped if required.
-
-In the simpleapp archetype the `SimpleObjects` service is a factory/repository for the original `SimpleObject` entity. For our app it therefore makes sense to refactor that class into our own first service:
-
-
-
-cd47e1fbe5e74777fa28ce5e3f756396
-
-
-
-
-b9c2cb709acc7f26e3bd52ecf7125370
-
-
-
-Fixture scripts are used to setup the app into a known state. They are great for demo's and as a time-saver when implementing a feature, and they can also be reused in automated integration tests. We usually also have a fixture script to zap all the (non-reference) data (or some logical subset of the data)
-
-
-
-e8f8af5c541d3ded640d5c50dae3cd59
-
-
-
-
-3e8949570b7979c5f10b6786cca81869
-
-
-
-Most business functionality is implemented using actions... basically a `public` method accepting domain classes and primitives as its parameter types. The action can return a domain entity, or a collection of entities, or a primitive/String/value, or void. If a domain entity is returned then that object is rendered immediately; if a collection is returned then the Wicket viewer renders a table. Such collections are sometimes called "standalone" collections.
-
-
-
-1da34f5b78c333430a0cce9a1d5bb653
-
-
-
-
-7b4347168de97955ade722fe148c3d8f
-
-
-
-As well as exposing the Wicket viewer, Isis also exposes a REST API (an implementation of the [Restful Objects spec](http://restfulobjects.org)). All of the functionality of the domain object model is available through this REST API.
-
-
-
-768dee12f202c4441e3befebf2fe3e31
-
-
-
-
-151b82c7d2d0933000878c353cf8ec2e
-
-
-
-The semantics of an action (whether it is safe/query only, whether it is idempotent, whether it is neither) can be specified for each action; if not specified then Isis assumes non-idempotent. In the Wicket viewer this matters in that only query-only actions can be bookmarked or used as contributed properties/collections. In the RESTful viewer this matters in that it determines the HTTP verb (GET, PUT or POST) that is used to invoke the action.
-
-
-
-42e0f7788c347eeb3694a7c397244747
-
-
-
-
-14a8cb3b5c63f75307e11787758fb667
-
-
-
-Domain entities have state: either values (primitives, strings) or references to other entities. In this section we explore adding some value properties
-
-
-
-e66c2dc044ad81d9558921f68cdd8fa0
-
-
-
-
-62ef364d315cbad8c2c53cbb6c806312
-
-
-
-Domain entities can also reference other domain entities. These references may be either scalar (single-valued) or vector (multi-valued). In this section we focus on scalar reference properties.
-
-
-
-5fc9438953bf860551607fd6368f46f2
-
-
-
-
-6dc5e281d59d7a5572ba4fbff30a67a6
-
-
-
-Quick detour: often we want to set up defaults to go with choices. Sensible defaults for action parameters can really improve the usability of the app.
-
-
-
-3b7b3efed8fd040d988c56a0e1c0dd03
-
-
-
-
-50ab4d214505ad962a7c72711c5bcc86
-
-
-
-Returning back to references, Isis also supports vector (multi-valued) references to another object instances... in other words collections. We sometimes called these "parented" collections (to distinguish from a "standalone" collection as returned from an action)
-
-
-
-b1c516ca9e5131bb12a9fe4fe87f3996
-
-
-
-
-7f4a9d9aec2c02bd5d46b09441b0b508
-
-
-
-The Wicket UI doesn't allow collections to be modified (added to/removed from). However, we can easily write actions to accomplish the same. Moreover, these actions can provide some additional business logic. For example: it probably shouldn't be possible to add an object twice into a collection, so it should not be presented in the list of choices/autoComplete; conversely, only those objects in the collection should be offered as choices to be removed.
-
-
-
-9c9eeefb0a57c113a47c00b97a0918be
-
-
-
-
-d458956d12a9fc5d57a1b657f41fc736
-
-
-
-(In 1.8.0-SNAPSHOT), CSS classes can be associated with any class member (property, collection, action). But for actions in particular:
-- the bootstrap "btn" CSS classes can be used using [@CssClass](http://isis.apache.org/reference/recognized-annotations/CssClass.html) annotation
-- the [Font Awesome](http://fortawesome.github.io/Font-Awesome/icons/) icons can be used using the [@CssClassFa](http://isis.apache.org/reference/recognized-annotations/CssClassFa-deprecated.html) annotation
-
-It's also possible to use Font Awesome icons for the [domain object icon](http://isis.apache.org/how-tos/how-to-01-070-How-to-specify-the-icon-for-a-domain-entity.html).
-
-So:
-- for some of the actions of your domain services or entities, annotate using `@CssClass` or `@CssClassFa`.
-
-
-
-
-
-cad1af2f4641f21137b61bfda3c5ee6b
-
-
-
-Up to this point we've been using annotations (`@MemberOrder`, `@MemberGroupLayout`, `@Named`, `@PropertyLayout`, `@ParameterLayout`, `@CssClass` and `@CssClassFa` and so on) for UI hints. However, the feedback loop is not good: it requires us stopping the app, editing the code, recompiling and running again. So instead, all these UI hints (and more) can be specified dynamically, using a corresponding `.layout.json` file. If edited while the app is running, it will be reloaded automatically (in IntelliJ, use Run>Reload Changed Classes):
-
-
-
-7a9ac31ce5adbca4b6ff5c5594b9f1fb
-
-
-
-
-e119e604b10f160356406770fb4e4d71
-
-
-
-Apache Isis excels for domains where there are complex business rules to enforce. The UI tries not to constrain the user from navigating around freely, however the domain objects nevertheless ensure that they cannot change into an invalid state. Such rules can be enforced either declaratively (using annotations) or imperatively (using code). The objects can do this in one of three ways:
-
-
-
-7667b4055e6e472c860e9c661f72b4fd
-
-
-Or, more pithily: "see it, use it, do it"
-
-
-
-
-39914e708a5f125e544125f15c385f6f
-
-
-
-
-
-35eaa4fdc10696d0266b53e692c6d5bb
-
-
-
-
-28e9d8e8a367f67c5cbbb74475da5cc2
-
-
-
-
-
-28306d5233835e66c76d2668c5994e67
-
-
-
-
-d504f6a01d6faaac7efa41e5d5b0b98c
-
-
-
-
-
-5e2654d58330caecc4307e1ac9fe2730
-
-
-
-
-7b782805b6b9b74538f495fad7a0a4dc
-
-
-
-The Wicket UI will automatically invoke the "home page" action, if available. This is a no-arg action of one of the domain services, that can return either an object (eg representing the current user) or a standalone action.
-
-
-
-6107be802a639d73c0309ce256d50f6d
-
-
-
-
-7ad3e1cfd135d1289d984bb3975d6a07
-
-
-
-To ensure testability, there should be no dependencies on system time, for example usage of `LocalDate.now()`. Instead the domain objects should delegate to the provided `ClockService`.
-
-
-
-e93da4f14c65e9a826297ac534c3fa87
-
-
-
-
-690233360a7add3dda729c1620ff12af
-
-
-
-One of Isis' most powerful features is the ability for the UI to combine functionality from domain services into the representation of an entity. The effect is similar to traits or mix-ins in other languages, however the "mixing in" is done at runtime, within the Isis metamodel. In Isis' terminology, we say that the domain service action is contributed to the entity.
-
-Any action of a domain service that has a domain entity type as one of its parameter types will (by default) be contributed. If the service action takes more than one argument, or does not have safe semantics, then it will be contributed as an entity action. If the service action has precisely one parameter type (that of the entity) and has safe semantics then it will be contributed either as a collection or as a property (dependent on whether it returns a collection of a scalar).
-
-Why are contributions so useful? Because the service action will match not on the entity type, but also on any of the entity's supertypes (all the way up to `java.lang.Object`). That means that you can apply the [dependency inversion principle](http://en.wikipedia.org/wiki/Dependency_inversion_principle) to ensure that the modules of your application have acyclic dependencies; but in the UI it can still appear as if there are bidirectional dependencies between those modules. The lack of bidirectional dependencies can help save your app degrading into a [big ball of mud](http://en.wikipedia.org/wiki/Big_ball_of_mud).
-
-Finally, note that the layout of contributed actions/collections/properties can be specified using the `.layout.json` file (and it is highly recommended that you do so).
-
-
-
-
-7d4dba4341c8320d7101fb64ca607359
-
-
-
-
-
-1c05f14ee8f22d60d9a4a763ace1ee55
-
-
-
-
-8a6769efeafbb090cd22640fcf4d5183
-
-
-
-
-
-9614d710b08379bd216f0f9860e56044
-
-
-
-
-ec3dc80b0f5ce579415294eb9e704b9e
-
-
-
-
-
-0f15fad26c4b2fa65b9aa8decce30eed
-
-
-
-
-e09ec84f6644e3e0c7b03928ec9bd4dd
-
-
-
-Another way in which Apache Isis helps you keep your application nicely modularized is through its event bus. Each action invocation, or property modification, can be used to generate a succession of events that allows subscribers to veto the interaction (the see it/use it/do it rules) or, if the action is allowed, to perform work prior to the execution of the action or after the execution of the action.
-
-Under the covers Isis uses the [Guava event bus](https://code.google.com/p/guava-libraries/wiki/EventBusExplained) and subscribers (always domain services) subscribe by writing methods annotated with `@com.google.common.eventbus.Subscribe` annotation.
-
-By default the events generated are `ActionInteractionEvent.Default` (for actions) and `PropertyInteractionEvent.Default` (for properties). Subclasses of these can be specified using the [@ActionInteraction](http://isis.apache.org/reference/recognized-annotations/ActionInteraction.html) or [@PropertyInteraction](http://isis.apache.org/reference/recognized-annotations/PropertyInteraction.html).
-
-Using the guidance in [these docs](http://isis.apache.org/reference/services/event-bus-service.html):
-
-
-
-b986a66cd2cd068d9b089d39ab1170b4
-
-
-Bulk actions are actions that can be invoked on a collection of actions, that is on collections returned by invoking an action. Actions are specified as being bulk actions using the [@Bulk](http://isis.apache.org/reference/recognized-annotations/Bulk.html) annotation. Note that currently (1.8.0-SNAPSHOT) only no-arg actions can be specified as bulk actions.
-
-
-
-ad47a6cc531c309b0e97845f6755bede
-
-
-The similar [ScratchPad](http://isis.apache.org/reference/services/scratchpad.html) (request-scoped) domain service is a good way to share information between bulk action invocations:
-
-
-
-e279e03a45a3aecf237b12a010adafca
-
-
-
-
-5a30cbad7faca18df50c1742deb24b15
-
-
-
-The [QueryResultsCache](http://isis.apache.org/reference/services/query-results-cache.html) (request-scoped) domain service allows arbitrary objects to be cached for the duration of a request.
-
-This can be helpful for "naive" code which would normally make the same query within a loop.
-
-
-
-bb9c303931d786451dea0f6306b309ac
-
-
-
-
-ee70cd70b57cf1e0b065102ac0c0e776
-
-
-
-Each element in the Wicket viewer (entity form, properties, collections, action button etc) is a component, each created by a internal API (`ComponentFactory`, described [here](http://isis.apache.org/components/viewers/wicket/customizing-the-viewer.html)). For collections there can be multiple views, and the Wicket viewer provides a view selector drop down (top right of each collection panel).
-
-Moreover, we can add additional views. In this section we'll explore some of these, already provided through [Isis addons](http://www.isisaddons.org/).
-
-
-
-
-9d07244d6baab0051637b774c9d4eedf
-
-
-
-The [Excel download add-on](https://github.com/isisaddons/isis-wicket-excel) allows the collection to be downloaded as an Excel spreadsheet (`.xlsx`).
-
-
-
-5ab74a9c990f11c07a962478106ff3dc
-
-
-
-
-bf79ef9f99ddb7f0bd62bd83d7dafe4d
-
-
-
-The [Fullcalendar2 download add-on](https://github.com/isisaddons/isis-wicket-fullcalendar2) allows entities to be rendered in a full-page calendar.
-
-
-
-4ae50459d4bedd73d025a7c1fb672866
-
-
-
-
-6952e98c49fa08622940edde8241db08
-
-
-
-The [Gmap3 download add-on](https://github.com/isisaddons/isis-wicket-gmap3) allows entities that implement certain APIs to be rendered in a full-page gmap3.
-
-
-
-7395e76d0257f5f3cb9d1205fba1bd11
-
-
-
-
-432886d7499d664b98c13b41dc3c63bf
-
-
-
-In addition to providing Wicket viewer extensions, [Isis addons](http://www.isisaddons.org/) also has a large number of modules. These address such cross-cutting concerns as security, command (profiling), auditing and publishing.
-
-
-
-af3bdd37ce5a5d583b114f6134efc897
-
-
-
-
-8229c0cd6ba408b2286112f56ea15518
-
-
-
-In most cases users can accomplish the business operations they need by invoking actions directly on domain entities. For some high-volume or specialized uses cases, though, there may be a requirement to bring together data or functionality that spans several entities.
-
-Also, if using Isis' REST API then the REST client may be a native application (on a smartphone or tablet, say) that is deployed by a third party. In these cases exposing the entities directly would be inadvisable because a refactoring of the domain entity would change the REST API and probably break that REST client.
-
-To support these use cases, Isis therefore allows you to write a [view model](http://isis.apache.org/reference/recognized-annotations/ViewModel.html), either by annotating the class with [@ViewModel](http://isis.apache.org/reference/recognized-annotations/ViewModel.html) or (for more control) by implementing the `ViewModel` interface.
-
-
-
-5d531ffe129009da4a379c9004a81f22
-
-
-
-
-676ce6f0eaac8ed78054908ee18ee6f0
-
-
-
-Up to this point we've been introducing the features of Isis and building out our domain application, but with little regard to testing. Time to fix that.
-
-
-
-a5690de81ca27957ffe4648db552fd59
-
-
-
-Unit testing domain entities and domain services is easy; just use JUnit and mocking libraries to mock out interactions with domain services.
-
-[Mockito](https://code.google.com/p/mockito/) seems to be the current favourite among Java developers for mocking libraries, but if you use JMock then you'll find we provide a `JUnitRuleMockery2` class and a number of other utility classes, documented [here](http://isis.apache.org/core/unittestsupport.html).
-
-
-
-451483acc0a860d2e5c11d23c789a3ce
-
-
-
-
-a70299784affb7ea091129c45225bb82
-
-
-
-Although unit tests are easy to write and fast to execute, integration tests are more valuable: they test interactions of the system from the outside-in, simulating the way in which the end-users use the application.
-
-Earlier on in the tutorial we commented out the `myapp-integtests` module. Let's commented it back in. In the parent `pom.xml`:
-
-
-
-47b6922a7d6cc7e717c1b15312a36eac
-
-
-
-change to:
-
-
-
-219291bc01c4eaf50ad00782b7166d71
-
-
-
-There will probably be some compile issues to fix up once you've done this; comment out all code that doesn't compile.
-
-Isis has great support for writing [integration tests](http://isis.apache.org/core/integtestsupport.html); well-written integration tests should leverage fixture scripts and use the [wrapper factory](http://isis.apache.org/reference/services/wrapper-factory.html) service.
-
-
-
-7ac57cbde657119463bc4a965b068d14
-
-
-
-
-2ca66b388f86cefae9d1daedf62c2ae2
-
-
-
-The REST API generated by Isis conforms to the Restful Objects specification. Isis 1.8.0-SNAPSHOT provides experimental support to allow the representations to be customized.
-
-
-
-a0cd8d7883be580f77fdd49d2817d181
-
-
-d29f126d473d19422b62da09f6d72cab
-
-
-
-
-
-
-a4f7ecb3c9b97933489368883e3d2986
+<div class="note">
+git checkout [xxx](https://github.com/danhaywood/isis-app-petclinic/commit/xxx)
+</div>
-If you have an external database available, then update the `pom.xml` for the classpath and update the JDBC properties in `WEB-INF\persistor.properties` to point to your database.
-->