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 2011/03/18 08:47:32 UTC
svn commit: r1082839 [2/4] - in /incubator/isis/trunk: ./
applib/src/docbkx/guide/ core/ core/src/docbkx/guide/
runtimes/dflt/src/docbkx/guide/ src/docbkx/guide/ src/site/apt/
support/quickstart/quickrun/
support/quickstart/viewer-wicket/src/main/webap...
Modified: incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml?rev=1082839&r1=1082838&r2=1082839&view=diff
==============================================================================
--- incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml (original)
+++ incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml Fri Mar 18 07:47:32 2011
@@ -109,12 +109,23 @@
<para>This guide assumes that you have at least the outline of a running
<emphasis>Apache Isis</emphasis> application, for example having run the
- quickstart archetype. If you haven't done this, then please consult the
- core documentation (or the Isis website) to learn how.</para>
+ quickstart archetype. Details of how to run the quickstart archetype can
+ be found in <xref linkend="apx.Archetype" />.</para>
- <para>This guide provides all the specifics of writing a domain object
- according to the conventions of the <emphasis>default</emphasis>
- programming model.</para>
+ <para>This guide has two main objectives:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>to describe the general approach for developing Isis
+ applications solely by writing domain objects</para>
+ </listitem>
+
+ <listitem>
+ <para>to describe the specifics of writing domain objects according
+ to the conventions of the <emphasis>default</emphasis> programming
+ model.</para>
+ </listitem>
+ </itemizedlist>
<para>The core documentation, on the other hand, explains the wider
landscape of what makes up an <emphasis>Isis</emphasis> application,
@@ -129,10 +140,11 @@
<sect1>
<title>Where Next?</title>
- <para>This guide itself is in several parts. The first part is a set of
- chapters is written in the style of recipes/cookbooks, providing a
- "how-to" guide on developing domain objects. This is good reading if you
- are just starting out. The second part provides details on other
+ <para>This guide is in several parts. The first part is intended to
+ explain, from a developers' perspective, what exactly <emphasis>Apache
+ Isis</emphasis> is. The second part has chapters that describe the
+ specifics in the style of recipes/cookbooks, providing a "how-to" guide
+ on developing domain objects. The third part provides details on other
supporting features relevant to writing domain applications. The final
part is a series of appendices that provide details of the programming
model in reference form. You should find this more useful if you've used
@@ -141,7 +153,913 @@
</sect1>
</chapter>
- <part>
+ <part id="prt.UnderstandingApacheIsis">
+ <title>Understanding Apache Isis</title>
+
+ <partintro>
+ <para>The chapters in this part of the guide are intended to help you
+ understand <emphasis>Apache Isis</emphasis> from a developers'
+ perspective:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the principles and patterns that underpin Isis (<xref
+ linkend="chp.PrinciplesAndPatterns" />)</para>
+ </listitem>
+
+ <listitem>
+ <para>a development process to follow (<xref
+ linkend="chp.DevelopmentProcess" />)</para>
+ </listitem>
+ </itemizedlist>
+ </partintro>
+
+ <chapter id="chp.PrinciplesAndPatterns">
+ <title>Apache Isis and Naked Objects</title>
+
+ <abstract>
+ <para>Understanding Apache Isis and the naked objects pattern by way
+ of a series of questions and answers.</para>
+ </abstract>
+
+ <para>The headline feature that distinguishes <emphasis>Apache
+ Isis</emphasis> from other frameworks is its support for the naked
+ objects pattern - the ability to generate a user interface (at runtime)
+ directly from the domain model. However, there's much more to
+ <emphasis>Apache Isis</emphasis> than this.</para>
+
+ <para>This chapter introduces the Apache Isis and the naked objects
+ pattern by way of a series of questions and answers.</para>
+
+ <sect1>
+ <title>Apache Isis implements naked objects pattern... but what is
+ that, exactly?</title>
+
+ <para>Naked objects is an architectural pattern where the idea is to
+ automatically expose a domain model objects directly within a
+ object-oriented user interface... not just their state (properties and
+ collections) but also their behaviour (what we call actions). You can
+ think of it as analogous to an <acronym>ORM</acronym> such as <ulink
+ url="http://hibernate.org">Hibernate</ulink>; but whereas an
+ <acronym>ORM</acronym> reflects the domain model into the persistence
+ layer, naked objects reflects the domain model into the presentation
+ layer.</para>
+
+ <para>Naked Objects (capitals) was a Java framework that implemented
+ the naked objects (lower case) pattern. Since then, we've taken the
+ original framework, along with a number of sister projects developed
+ by the community, into the Apache Incubator. So, what was originally
+ "Naked Objects" is now Apache Isis.</para>
+ </sect1>
+
+ <sect1>
+ <title>What type of applications are best suited to Isis?</title>
+
+ <para>The naked objects pattern requires that your primary
+ consideration is in building an object-oriented domain model, so it's
+ most suitable for enterprise applications that have complex business
+ rules where there's a desire to represented them within such a domain
+ model. The idea - at least during the initial stages - is to build up
+ a domain model quickly, and to get feedback from the domain experts by
+ exploiting the framework's ability to expose that directly domain
+ model within the user interface. A picture tells a thousand
+ words.</para>
+
+ <para>Apache Isis "sweet spot" are those applications that are used
+ internally within the organization, by experienced users who are
+ comfortable with the entities within the domain model, and just need
+ an application that imposes as few constraints as possible on how it
+ is used. These are sometimes called <emphasis>sovereign
+ applications</emphasis>. If you're a developer then your
+ <acronym>IDE</acronym> is probably the sovereign application you use
+ the most, and how often did you use any of its wizards? And if you use
+ telephone banking then you'll also know how frustrating a sovereign
+ application can be that is too invasive in dictating the workflow...
+ that poor person on the other end asks making apologies while she goes
+ exits from one screen and then goes into another to check some detail
+ on a bank account. The generic <acronym>OO</acronym>
+ <acronym>UI</acronym>s generated by naked objects impose no such
+ restrictions, and so are ideal for this sort of application.</para>
+ </sect1>
+
+ <sect1>
+ <title>And are there applications where the OO UIs generated by Isis
+ are less suitable?</title>
+
+ <para>The opposite of a sovereign application (above) is sometimes
+ called a <emphasis>transient application</emphasis>. These are ones
+ used only occasionally or by inexperienced users, typically outside
+ the organization (ie your customers), who don't know or care to know
+ the domain model, and just want to be led through the system to
+ accomplish some well-defined goal. A good example here is a check-in
+ kiosk at an airport... you just want to get on the plane, and be given
+ the opportunity to choose your seat. But you likely won't care which
+ plane, or even plane type, nor who the pilot is; these are unimportant
+ details.</para>
+
+ <para>For this sort of application a generic <acronym>OO</acronym>
+ <acronym>UI</acronym> that exposes lots of the domain is clearly not
+ appropriate. Instead, we want an application that exposes view models
+ rather than entities, and where the <acronym>UI</acronym> can be
+ customized. The view model object is responsible for managing the
+ workflow for the user story, exposing just the subset of the domain
+ that is relevant, and hiding the rest of the domain. We find that
+ these view models can be layered on top of the entities once those
+ entities are understood.</para>
+
+ <para>Using view model objects is necessary but probably not
+ sufficient for transient applications; we also usually need to
+ customize the <acronym>UI</acronym>. <emphasis>Apache Isis</emphasis>
+ has two viewers that allow the UI to be customized, one that provides
+ a set of taglibs, and one that provides a set of <ulink
+ url="http://wicket.apache.org">Apache Wicket</ulink>
+ components.</para>
+
+ <para>Putting both of these techniques together (custom view models
+ and views) means that Apache Isis is suitable for transient
+ applications as well as sovereign applications. However, the former
+ will necessarily take more work as opposed to the latter.</para>
+ </sect1>
+
+ <sect1>
+ <title>What is the typical development process life cycle for
+ applications built with Isis, and how does it compare to traditional
+ application development process?</title>
+
+ <para>The main difference you're likely to encounter is the emphasis
+ on developing the domain model at the same time as identifying and
+ prioritizing user stories, what those practicing domain driven design
+ call a "ubiquitous language" for the team.</para>
+
+ <para>So, rather than let the developers in the team "discover" the
+ domain model as part of story implementation, we'd expect that the
+ domain experts/business analysts have already identified some of the
+ main domain concepts through prototyping or spikes, and these can be
+ used to help communicate the stories to the developers during the
+ planning game. Not every business analyst is going to feel comfortable
+ working with an <acronym>IDE</acronym>, but it works well to pair with
+ a developer. Because an Apache Isis application can be runs just from
+ domain classes, it's possible to develop the app very very quickly.
+ We've found a good technique is to run workshops with the business
+ analyst facilitating the meeting with the domain experts, and the
+ developer acting as "code monkey" to rapidly convert the ideas into an
+ app. Obviously the code isn't production quality, but it allows the
+ team as a whole to go very quickly and experiment with different
+ representations of the model.</para>
+
+ <para>Another alternative is to go a little more slowly, and have the
+ analyst and developer pairing to write production code. The analyst
+ still focuses on identifying and naming the domain concepts and their
+ relationships, while the developer's role (as well as learning about
+ the domain) is to ensure that there's enough rigour and tests around
+ the code that's been written while this is being done. Of course, both
+ approaches to pairing can be used, sometimes spiking ideas, sometimes
+ going straight to writing tested code.</para>
+
+ <para>Of course, while the naked objects pattern means that no
+ <acronym>UI</acronym> code needs to be written in order to elicit
+ feedback, there do still need to be objects in the app for the domain
+ expert to view. Apache Isis has a pluggable runtime/persistence layer,
+ and for prototyping and most of development we recommend using the
+ in-memory object store. To populate this object store for each run we
+ use fixtures, which we usually arrange into a composite pattern to
+ setup data needed for the particular scenario we might be working on.
+ Using Isis in this way means that we spend our time alternating
+ between defining domain classes and writing fixture data. This can be
+ a great benefit because it helps the domain experts - who after all
+ aren't necessarily technical - distinguish between what are classes
+ and what are instances of classes. For example, if I'm writing a
+ library system and we identify there are loanable books and reference
+ books, we need to know whether "loanable book" and "reference book"
+ are different subclasses of a book superclass, or merely different
+ instances of a book class with, say, a loanable property set to true
+ or false. Seeing a running application makes it much easier for the
+ domain expert to make the call.</para>
+
+ <para>In terms of writing tests, there are several options. First,
+ because the domain objects you write are basically pojos that follow
+ some naming conventions, they are very easy to test using standard
+ <acronym>TDD</acronym> tools such as <ulink
+ url="http://junit.org">JUnit</ulink> and <ulink
+ url="http://jmock.org">JMock</ulink>. And if you wanted to, you could
+ test the <acronym>UI</acronym> generated by Isis using <ulink
+ url="http://seleniumhq.org/">Selenium</ulink> and similar; indeed we'd
+ recommend that if you've customized the <acronym>UI</acronym>.</para>
+
+ <para>In addition, though, Isis provides a couple of additional
+ BDD/testing framework integrations. One of these is an integration
+ with <ulink url="http://fitnesse.org">FitNesse</ulink>, and a newer
+ one we've worked on is an integration with <ulink
+ url="http://concordion.org">Concordion</ulink>. In both cases the
+ integrations provide the glue code so you can exercise your domain
+ objects directly. For example, your spec might say "the place order
+ action cannot be invoked if the product is out of stock". All the
+ developer needs to do is to wire the spec to these pre-canned
+ integrations, specifying that the
+ <methodname>placeOrder()</methodname> action should be called on a
+ <classname>Product</classname>.</para>
+
+ <para>Isis also provides a JUnit runner that works by bootstrapping
+ the Isis runtime for each test, and proxying the domain objects with a
+ bit of cglib so that they are interacted with "as if" through the
+ <acronym>UI</acronym>. For example, let's go back to that
+ <methodname>placeOrder()</methodname> action. To prevent this from
+ being called for a <classname>Product</classname> that's out of stock,
+ the developer would write a corresponding
+ <methodname>validatePlaceOrder()</methodname> method. Isis
+ automatically calls this validate method prior to the
+ <methodname>placeOrder()</methodname> method, and uses the return
+ value ("that product is out of stock") as the reason why the action
+ can't be invoked. In the <acronym>UI</acronym>, this business rule is
+ represented by greying out the OK button of the action. In the JUnit
+ runner, this rule is represented by having the cglib proxy throw a
+ validation exception if the test calls
+ <methodname>placeOrder()</methodname> with an out of stock
+ <classname>Product</classname>.</para>
+
+ <para>In terms of deployment, there's several steps involved, probably
+ the most significant being to select the runtime and object store. As
+ noted above, Isis has a pluggable persistence layer; you can use the
+ in-memory object store for developing, but will want to switch to a
+ "real" object store for deployment. The amount of work required here
+ depends on the object store selected; in the case of
+ <acronym>JPA</acronym>/Hibernate support, for example, it amounts to
+ annotating your domain entities with annotations, and writing
+ implementations of some of the repositories to make the relevant
+ <acronym>SQL</acronym> calls.</para>
+ </sect1>
+
+ <sect1>
+ <title>What are the limitations of Apache Isis framework?</title>
+
+ <para>It's certainly true that naked objects pattern implemented by
+ Apache Isis is opinionated, so if you don't agree with all of its
+ opinions then you're going to find it limiting in one way or
+ another.</para>
+
+ <para>The first of these is that everything that the user wants to
+ interact with has to be an object of some sort. As already explained,
+ for sovereign applications, these are likely to be the persisted
+ domain entities, but for a transient application, the object may be a
+ view model to be support a particular workflow, and which may or may
+ not be persisted. Such an approach probably wouldn't be considered
+ much of a limitation, but it's worth contrasting with architectures
+ (eg Spring Web Flow or Struts) where put the responsibility for
+ tracking workflow lives not in an object but instead within some sort
+ of declarative XML markup (or even just in the interplay between
+ controllers and views).</para>
+
+ <para>A slightly more subtle consequence of the above is that
+ integration of different technologies happens through the domain
+ objects, rather than in front of them through application-layer or
+ <acronym>UI</acronym> layer mashups. For example, supposing that we
+ wanted to have an <acronym>SMS</acronym> sent out to confirm a
+ checkout. If you were writing the <acronym>UI</acronym> and
+ application service layer yourself, you might choose to have the
+ application layer make the call to the <acronym>SMS</acronym> service,
+ judging it to be a coordination responsibility. With
+ <emphasis>Isis</emphasis>, though, you don't get the chance to write
+ any application layer code, and so this would be done by having the
+ domain object call out to the <acronym>SMS</acronym> service. The
+ <acronym>SMS</acronym> service would be defined by an interface, and
+ the implementation would be injected into the domain object by the
+ framework. For some reason not everyone is necessarily comfortable
+ about injecting domain services into entities; but it works well for
+ us and we're sticking with it.</para>
+
+ <para>Another area where <emphasis>Isis</emphasis> is going to feel
+ different - and perhaps limiting to some - is that it pushes some
+ responsibilities onto the domain objects that otherwise might sit in
+ other layers. For example, above we discussed that a
+ <methodname>placeOrder()</methodname> action on a
+ <classname>Customer</classname> can have a supporting
+ <methodname>validatePlaceOrder()</methodname> method. It's also
+ possible to have <methodname>disablePlaceOrder()</methodname> method,
+ which if returning non-null will cause the action to be greyed out the
+ action in the <acronym>UI</acronym>. For example, a blacklisted
+ <classname>Customer</classname> might not allow any orders to be
+ placed, and would indicate this through the disable method. Some might
+ consider this as a misplaced presentation concern. However, the
+ <classname>Customer</classname> isn't greying out the
+ <acronym>UI</acronym> itself; the disable method is merely a
+ convention by which the presentation layer can interrogate the
+ entity.</para>
+
+ <para>Something else we hear sometimes about naked objects-style
+ systems is that they are really only suitable for
+ <acronym>CRUD</acronym> style applications. It has to be said that
+ it's a criticism that does irk; because although its true that naked
+ objects frameworks automatically expose object state, they also expose
+ object's behaviour. That is, every public method that is not a
+ property or a collection is taken to be an action and will rendered by
+ the <acronym>UI</acronym> as a button or a link. Indeed, we sometimes
+ like to talk of behaviourally complete domain objects; it's the very
+ antithesis of the anaemic domain model anti-pattern.</para>
+
+ <para>All the above notwithstanding, probably the biggest impediment
+ to going out and using Isis right now is that it's a small community
+ and as such the codebase is still relatively new. But if that is a
+ turn-off, note that you can still use Apache Isis to prototype your
+ domain model, because they are just pojos after all. Indeed, embedding
+ Isis' metamodel for a deployment hosted on some other framework is the
+ objective of the <emphasis>embedded runtime</emphasis> component of
+ Isis</para>
+ </sect1>
+
+ <sect1>
+ <title>How extensive is the application security support provided by
+ Isis?</title>
+
+ <para><emphasis>Apache Isis</emphasis> exposes a pluggable
+ authentication <acronym>API</acronym> and an authorization
+ <acronym>API</acronym>, with default implementations of both.</para>
+
+ <para>The job of the authentication <acronym>API</acronym> is to
+ authenticate the user credentials and return the user Id and a set of
+ roles for that user. This information is then used in one of two ways.
+ The authorization <acronym>API</acronym> uses it to implement
+ declarative class-based security, that is, associating access to
+ features based on the roles of the user. In addition, though, a domain
+ object instance can also access the user credentials, and so can
+ implement imperative instance-based checks if required.</para>
+
+ <para>For example, we might say that only a user with
+ <acronym>HR</acronym> role can award pay rises to an
+ <classname>Employee</classname>. This is a class-based check and would
+ be implemented through the authorization <acronym>API</acronym>. But,
+ we might also say that a user is allowed to view (though not modify)
+ their own salary of their <classname>Employee</classname> object, but
+ no-one else's. This would be an instance-based check, and would be
+ implemented in the object itself.</para>
+
+ <para>In terms of how naked objects restricts access, this is done
+ either by making an object member (property, collection or action)
+ invisible, or, if it is visible, then making it unusable (greyed
+ out).</para>
+ </sect1>
+
+ <sect1>
+ <title>How does an Isis applications manage the custom logic in terms
+ of business rules, workflow and other business logic that developers
+ have to manually implement outside the generated code?</title>
+
+ <para>"Business rules" is one of those amorphous terms that means
+ different things to different people. A consequence is that the team
+ can struggle to nail down exactly where such rules should reside, so
+ that these rules can start to leach out of the domain layer and the
+ application layer, or even worse, the presentation layer. As noted
+ already, one of the principles of naked objects is that domain objects
+ are behaviourally complete. What that means is that business rules and
+ "other business logic" are the responsibility of domain objects. For
+ workflow, again as noted earlier, we suggest that you introduce a view
+ model object and have that manage the user's interaction.</para>
+
+ <para>However, saying that business rules are an object's
+ responsibility doesn't necessarily mean that the implementation has to
+ be in Java. We already said that domain objects can delegate work out
+ to domain services that are injected into them. So if you want to put
+ your business rules into a rules engine, that's fine. Wrap the
+ interface to the rules engine within a domain service, and have the
+ domain object call out to the domain service in order to fulfil its
+ responsibility.</para>
+
+ <para>In practical terms, you're going to see business rules both in
+ the small-scale and the large. Small-scale business rules tend to be
+ implemented in terms of the supporting methods (disable, validate and
+ so on) that encode the preconditions for interactions. These ensure
+ that the object or the providing arguments is are valid and will veto
+ the interaction otherwise (blacklisted customers, out-of-stock
+ products). The larger-scale business rules are represented as actions
+ on an object that can perform arbitrary business logic, such as
+ modifying its own state, or related objects, and/or delegating out to
+ domain services.</para>
+ </sect1>
+
+ <sect1>
+ <title>How does Isis support SOA-based applications, eg where an
+ enterprise service component is consumed by several different
+ applications and other clients?</title>
+
+ <para>We can actually answer this both in terms of an Isis application
+ consuming <acronym>SOA</acronym><footnote>
+ <para>SOA=Service Oriented Architecture</para>
+ </footnote> services, and in it <emphasis>providing</emphasis>
+ services.</para>
+
+ <para>For consuming <acronym>SOA</acronym> services, the answer is
+ easy enough: wrap the <acronym>SOA</acronym> service in a domain
+ service interface, and then register the implementation with the
+ framework so that the service is injected into each domain object.
+ That interaction can be either synchronous or asynchronous; there's
+ nothing to prevent the domain object publishing an event to be picked
+ up by some other component out there on your enterprise service
+ bus.</para>
+
+ <para>As to providing <acronym>SOA</acronym> services, Isis' RESTful
+ viewer exposes the domain objects as a set of RESTful resources. We
+ map objects and object members to the standard <acronym>HTTP</acronym>
+ verbs, eg so that a GET on an object returns an object representation,
+ a PUT on an object's property will modify the state, or a POST on an
+ object's actions will invoke the action. Right now the representation
+ is in terms of <acronym>XHTML</acronym>, which has the nice side
+ effect that the representation can actually be viewed directly from a
+ web browser. We do intend to also provide a <acronym>JSON</acronym>
+ representation, but that's still on the roadmap for now.</para>
+ </sect1>
+
+ <sect1>
+ <title>Most enterprise applications need to reuse the domain and
+ service layer classes between several different applications. How does
+ Apache Isis address this?</title>
+
+ <para>One way to think of reuse in terms of strategic domain-driven
+ design, which couches the discussion in terms of identifying bounded
+ contexts and understanding the relationship between these contexts -
+ context maps.</para>
+
+ <para>You can think of a bounded context as both the user population
+ that understands a particular ubiquitous language as well as the
+ actual system that they use. For example, the term "Customer" is going
+ to mean one thing to the marketing department, but a potentially
+ different thing to those in shipping. Those two user populations
+ therefore have incompatible languages, and so any integration of
+ systems that support both sets of users will need to explicitly map
+ their meanings of those terms.</para>
+
+ <para>Simplifying somewhat, an Isis (naked objects) application can be
+ thought of in three parts: the domain model objects themselves, the
+ viewer that provides a channel to interact with the domain model, and
+ the domain services that are used by the domain model objects. The
+ domain model objects encode a ubiquitous language for a particular
+ bounded context, so it only makes sense to reuse them by users who
+ have the same understanding of that language. We can if we want use
+ view model objects to provide projections of the domain entities to
+ different subsets of that user population, but all must agree with
+ what a Customer is, even if they use different parts of said
+ Customer.</para>
+
+ <para>Viewers are channels by which the domain model is accessed.
+ <emphasis>Apache Isis</emphasis> has viewers that expose the domain
+ model as either a desktop app or as a webapp, and also has its RESTful
+ viewer which allows the view model objects/domain objects to be
+ surfaced as RESTful resources. In <acronym>DDD</acronym> terms the
+ RESTful viewer is an "open host service" context mapping from some
+ client bounded context up to our model's context.</para>
+
+ <para>With respect to domain services, these are not reusable per se,
+ rather they allow the domain objects to be the client of some other
+ service within the enterprise. That said, one common type of domain
+ service is to provide an interface to an enterprise service bus, in
+ which case the domain objects can publish events onto that bus. In
+ <acronym>DDD</acronym> terms this would be an example of a "published
+ language" context mapping; the downstream systems consuming the events
+ of the publishing domain objects.</para>
+
+ <para>Naked objects also allows a somewhat finer-grained level of
+ reuse; indeed its support for "don't repeat yourself" is one of the
+ reasons that some people are attracted to the pattern. For example, if
+ we declare a property or an action parameter to be a date, then the
+ viewers will automatically provide a date chooser widget for that
+ property or parameter unless indicated otherwise. Or, if a property's
+ type is an enum, then we'll get a drop-down box. It's the conventions
+ of the naked objects programming model - establishing a protocol of
+ interaction between the presentation layer and the domain model - that
+ enable this sort of reuse.</para>
+
+ <para>Some of Isis' more recent viewers also allow mashups within the
+ <acronym>UI</acronym>. For example, the viewer that we've implemented
+ using Apache Wicket uses the chain of responsibility pattern to build
+ the <acronym>UI</acronym>. If we have an entity can provide its
+ <classname>Location</classname> (eg, it implements
+ <classname>Locatable</classname>), then a GoogleMapsWidget will render
+ the entity in a map. Or, if an entity has a date, then a
+ CalendarWidget might render the entity on a calendar. This stuff is
+ extensible so you're free to write your own components and reuse (or
+ indeed invent your own) domain semantics as you see fit.</para>
+ </sect1>
+
+ <sect1>
+ <title>What is the future road map of the project?</title>
+
+ <para>Our proposal to join the incubator is online, and that captured
+ the thoughts we had at that point in time [***1]. A general theme is
+ in the ongoing development of the various viewers, such as the Wicket
+ viewer, JSON support for the RESTful viewer, and ongoing development
+ of the taglib-based viewer, Scimpi. Contributors who have expressed
+ interest in developing similar viewers using JSF/Facelets, Tapestry,
+ on Android and in JavaFX/Visage.</para>
+
+ <para>Isis has a pluggable architecture with about five major APIs
+ (and numerous more fine-grained APIs) that can be developed. Probably
+ the most significant of these is the runtime/persistence
+ <acronym>API</acronym>. One piece of work is to develop an ORM-based
+ object store from Hibernate (which is not compatible with Apache's) to
+ a compatible JPA implementation, We've also had a suggestion [***2] to
+ re-implement using JDO 3.0/DataNucleus, which would allow us to cover
+ a lot of persistence technologies in one fell swoop</para>
+
+ <para>Another objective during incubation is to make Isis more easily
+ bootstrappable and embeddable, and for that JSR-299 (Contexts and
+ Dependency Injection) looks promising. For example, it should be easy
+ to take just the <emphasis>Isis</emphasis> metamodel component and use
+ it within your own applications, eg to drive the rendering of domain
+ objects within custom <acronym>UI</acronym> code.</para>
+
+ <para>One other area we might see work is in support for other JVM
+ languages. Isis already supports Groovy as well as Java, and the way
+ that Isis builds up its metamodel means that supporting other
+ languages (Scala, Fantom, Go) ought to be pretty
+ straightforward.</para>
+
+ <para>Ultimately, though, Apache Isis' roadmap depends on where its
+ community wants to take it; so any of the above might change as we
+ progress through to graduation.</para>
+ </sect1>
+ </chapter>
+
+ <chapter id="chp.DevelopmentProcess">
+ <title>A Development Process</title>
+
+ <abstract>
+ <para>This chapter describes the general approach to follow that we
+ recommend for developing domain-driven applications on Isis.</para>
+ </abstract>
+
+ <para>There's quite a lot to <emphasis>Apache Isis</emphasis>, with lots
+ of optional components, and we do recognize that it may be difficult to
+ know how to get going. This chapter outlines a development process which
+ you can use as the basis for developing your own way of working.</para>
+
+ <sect1 id="sec.ApplicationArchetypes">
+ <title>Run the Quickstart Archetype</title>
+
+ <para>We tend to organize <emphasis>Isis</emphasis> applications to
+ follow a standard structure, and you can use the
+ <emphasis>quickstart</emphasis> Maven archetype (see <xref
+ linkend="apx.Archetype" />) to set this up for you. This sets up a
+ simple application that can be run out-of-the-box using the default
+ runtime and in-memory object store, and supporting all of the main
+ viewers, either run from the command lineor as webapps served by
+ Jetty.</para>
+ </sect1>
+
+ <sect1>
+ <title>Programming Model</title>
+
+ <para>Once you've got the archetype application running, you're ready
+ to start developing your own domain objects. But no matter what
+ application you are developing, you'll need to understand the
+ <emphasis>Isis programming model</emphasis>. </para>
+
+ <para>The programming model is the set of annotations and programming
+ conventions that Isis recognizes. You'll find full details of the
+ programming model in this guide; see <xref
+ linkend="prt.WritingDomainObjects" />.</para>
+
+ <para>In addition, the applib contains a small number of utilities
+ which can be useful when writing your application: one such is the
+ ability to create XML snapshots of your domain object graphs, see
+ <xref linkend="chp.XmlSnapshots" />.</para>
+ </sect1>
+
+ <sect1>
+ <title>Fixtures and Prototyping</title>
+
+ <para>We suggest that the fastest way to develop your application is
+ to start prototyping using the in-memory object store (set up
+ automatically by the quickstart archetype). The nice thing about
+ working this way is that there is no database schema to slow you down;
+ you can make changes and then rapidly try them out.</para>
+
+ <para>On the other hand, the in-memory object store doesn't persist
+ objects between runs, so you'll soon tire of continually recreating
+ test objects to try out your changes. You should therefore use
+ fixtures: blocks of code that are used to setup objects in the
+ in-memory object store prior to the app running.</para>
+
+ <para>You can find more information about using fixtures in <xref
+ linkend="chp.Fixtures" />. It's also worth knowing about fixtures
+ because they are used when writing tests for your domain application
+ (see <xref linkend="sec.AgileTesting" />).</para>
+ </sect1>
+
+ <sect1 id="sec.Viewers">
+ <title>Viewers</title>
+
+ <para><emphasis>Apache Isis</emphasis> allows the same domain object
+ model to be consumed by multiple presentation layers. You'll find that
+ the quickstart archetype sets up modules for each of the viewers
+ currently available:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <acronym>DnD</acronym> viewer (in
+ <filename>viewers/dnd</filename>) provides a generic view of all
+ domain objects as a desktop app, supporting a drag-n-drop metaphor
+ between forms/icons that represent each object.</para>
+
+ <para>The viewer also provides its own <acronym>API</acronym> to
+ allow more sophisticated views to be constructed.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <acronym>HTML</acronym> viewer (in
+ <filename>viewers/html</filename>) provides a basic webapp.</para>
+
+ <para>Other than tweaking <acronym>CSS</acronym>, the views that
+ it provides of objects cannot be customized.</para>
+ </listitem>
+
+ <listitem>
+ <para>Scimpi (in <filename>viewers/scimpi</filename>) allows your
+ application to be deployed as a webapp.</para>
+
+ <para>Out-of-the-box you get a generic view (very similar to that
+ provided by <acronym>HTML</acronym> viewer); you can then
+ customize the view by providing custom pages that use Scimpi
+ tags.</para>
+ </listitem>
+
+ <listitem>
+ <para>The Wicket viewer (in <filename>viewers/wicket</filename>)
+ uses <ulink url="http://wicket.apache.org">Apache Wicket</ulink>
+ to render generic views of your domain objects in a webapp.</para>
+
+ <para>Like Scimpi, it allows these views to be customized, this
+ time by leveraging the Wicket <classname>Component</classname>
+ <acronym>API</acronym>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The RESTful viewer (in <filename>viewers/restful</filename>)
+ is designed to expose your domain objects through a <ulink
+ url="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</ulink>
+ interface. </para>
+
+ <para>The intention of this viewer is to allow programmatic access
+ to your domain objects from other (perhaps non-Java) clients. The
+ viewer does also render as <acronym>XHTML</acronym> for debugging
+ purposes.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If deploying with the <acronym>DnD</acronym> viewer you also
+ need to decide whether to deploy standalone (ie, each user has their
+ own private object store) or in client/server mode (so all users share
+ a server-based object store).</para>
+ </sect1>
+
+ <sect1 id="sec.AgileTesting">
+ <title>Agile Testing</title>
+
+ <para><emphasis>Apache Isis</emphasis> is very much aligned to agile
+ development practices, and provides two complementary mechanisms for
+ you to test-drive the development of your application.</para>
+
+ <sect2>
+ <title>Story (BDD) Testing</title>
+
+ <para>Many agile practitioners use story tests as a means to capture
+ the acceptance (or completion) criteria for high-level user stories.
+ These story tests are typically captured in a non-programmatic form
+ so that is understandable to domain experts as well as
+ programmers.</para>
+
+ <para><emphasis>Apache Isis</emphasis> provides an out-of-the-box
+ integration with <ulink
+ url="http://concordion.org">Concordion</ulink> (where the story test
+ is captured as <acronym>HTML</acronym>).<footnote>
+ <para>An integration with <ulink
+ url="http://fitnesse.org">FitNesse</ulink> (where the story test
+ is captured within a wiki) also exists. Due to licensing this is
+ not part of <emphasis>Isis</emphasis> proper.</para>
+ </footnote>There is full coverage of how to use this integration
+ in the <acronym>BDD</acronym> viewer's
+ (<filename>viewers/bdd</filename>) documentation.</para>
+ </sect2>
+
+ <sect2 id="sec.UnitTesting">
+ <title>Unit Testing</title>
+
+ <para>Unlike story tests, unit tests are normally written in a
+ programming language, typically in a framework such as <ulink
+ url="http://junit.org">JUnit</ulink>. <emphasis>A story test ensures
+ that the right system is built, while a unit tests ensures the
+ system is built right</emphasis>.</para>
+
+ <para>When writing unit tests, you have a choice. Since all the
+ business logic in Isis applications is encapsulated in domain object
+ pojos, you can just write unit tests using nothing more than JUnit
+ and perhaps also a mocking library such as <ulink
+ url="http://jmock.org">JMock</ulink>.</para>
+
+ <para>A slightly more sophisticated approach is to use the JUnit
+ integrations and supporting classes of the Wrapper programming model
+ . The idea of these utilities is to wrap your domain objects in
+ proxies that apply the same rules as an <emphasis>Apache
+ Isis</emphasis> viewer. For example, if you try to change a property
+ or invoke an action that is disabled, then the proxy will throw an
+ exception. You write your test to pass if the exception is thrown,
+ and failed otherwise (eg using
+ <code>@Test(expected=DisabledException.class)</code>).</para>
+
+ <para>Full documentation for unit testing support is in the JUnit
+ viewer's guide (<filename>viewers/junit</filename>).</para>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>A Domain Library</title>
+
+ <para>The idea behind the <filename>domain</filename> module is to
+ provide some off-the-shelf code for you to use and adapt in your own
+ applications. This code is fully tested (comes with tests), and is
+ intended to be well-designed. Using code from the library should give
+ you a kick-start in writing your own domain applications.</para>
+
+ <note>
+ <para>The library is currently very modest, but we hope it might
+ build up in time.</para>
+ </note>
+
+ <para>Of course, there's a limit to the complexity of the code that's
+ included in the library, because every domain is different. But having
+ a full set of tests should allow you to safely refactor the code to
+ your own requirements.</para>
+
+ <para>There's also no guarantee that the library will contain code for
+ your specific requirement. But if you do write some domain logic that
+ you think might be reusable by others, why not consider donating it
+ back to Isis when you've done so?</para>
+
+ <para>The domain library breaks out into three: services, entities and
+ values.</para>
+
+ <sect2>
+ <title>Domain Services</title>
+
+ <para><emphasis>Apache Isis</emphasis> applications use
+ <emphasis>domain service</emphasis>s (a domain-driven design
+ pattern) to allow objects to interact with other domains (or
+ <emphasis>bounded context</emphasis>s, to use the correct term).
+ These domain services are automatically injected into each domain
+ object as it is instantiated.</para>
+
+ <para>Domain services split into two: those that interact with
+ technical domains (such as sending email, or rendering
+ <acronym>PDF</acronym>s), and those that interact with business
+ domains (such as general ledger, <acronym>CRM</acronym>s or legacy
+ systems).</para>
+
+ <para>Obviously domain services that bridge to business domain
+ services are always likely to be specific to each individual
+ application. So the services in the
+ <filename>domain/services</filename> module focus on providing
+ off-the-shelf implementations for some of the more common
+ <emphasis>technical</emphasis> domain services.</para>
+ </sect2>
+
+ <sect2>
+ <title>Domain Values</title>
+
+ <para>As you probably would expect, <emphasis>Apache Isis</emphasis>
+ treats Java primitives, Java wrapper classes,
+ <classname>java.lang.String</classname>,
+ <classname>java.math.BigDecimal</classname> and
+ <classname>java.math.BigInteger</classname> as immutable values, It
+ allows <classname>java.util.Date</classname> and its subclasses
+ (java.sql.Date, java.sql.Time and
+ <classname>java.sql.Timestamp</classname>) to be treated as values
+ also. In addition, it offers a small number of its own value types,
+ such as <classname>Money</classname>.</para>
+
+ <para>In addition, it is possible to extend Isis support for value
+ types using its <classname>@Value</classname> annotation. We hope in
+ time to provide out-of-the-box integrations for popular 3rd party
+ libraries such as JodaTime.</para>
+ </sect2>
+
+ <sect2>
+ <title>Domain Entities</title>
+
+ <para>In the future we hope that Isis will provide some well-defined
+ and ready-tested domain entities for use in your systems. For
+ example, a set of entities to model customers
+ (<classname>Customer</classname>/<classname>Name</classname>/<classname>Address</classname>)
+ might be useful in many systems.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sec.DeployingAnIsisApplication">
+ <title>Deploying an Isis Application</title>
+
+ <para>There are two main decisions to make in deploying an
+ <emphasis>Isis</emphasis> application.</para>
+
+ <sect2>
+ <title>Persistence (the Default Runtime / Object Store)</title>
+
+ <para>In the same way that viewers provide pluggability for the
+ "front-end", <emphasis>Apache Isis</emphasis> also offers
+ pluggability on the back-end, i.e. persistence.</para>
+
+ <para>In fact, there are two decisions to be made here: which
+ runtime to use, and (if using the default runtime), which object
+ store to use. The default runtime is the one originally developed
+ within the <emphasis>Naked Objects Framework</emphasis>, and
+ therefore has been inherited by <emphasis>Apache
+ Isis</emphasis>.<footnote>
+ <para>At the time of writing the default runtime is the only
+ real runtime available; however we expect to be developing
+ lighter-weight replacements for the default runtime in the
+ future.</para>
+ </footnote>The default runtime is also the one configured by the
+ quickstart archetype.</para>
+
+ <para>If using the default runtime, you have the option of choosing
+ the objectstore. As already discussed, the quickstart archetype
+ configures the in-memory objectstore by default, which is great for
+ rapid prototyping. However, at some point you will need to integrate
+ with a "real" object store that persists object to some sort of
+ serialized persistence.</para>
+
+ <para>Of the object stores to provided by the default runtime, some
+ are easy to configure, some more complex; some are only suitable for
+ single-user apps, others for multi-users. Each of the object stores
+ has its own documentation, so you can select the correct object
+ store to choose:<footnote>
+ <para>In addition to those listed here, there have also been
+ objectstores for JPA (using Hibernate) and BerkeleyDB. These are
+ currently not part of Apache Isis distribution because of
+ incompatible licenses. Support for an ORM will in the future be
+ provided either by porting the JPA object store to the default
+ runtime, or, we may support it via a JDO-based new
+ runtime.</para>
+ </footnote></para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the <acronym>XML</acronym> object store (in
+ <filename>objectstores/xml</filename>) is designed for
+ single-user systems, and persists to its own internal
+ (proprietary) <acronym>XML</acronym> format;</para>
+ </listitem>
+
+ <listitem>
+ <para>the <acronym>SQL</acronym> object store (in
+ <filename>objectstores/sql</filename>) is a multi-user object
+ store that persists to an <acronym>RDBMS</acronym> (direct over
+ <acronym>JDBC</acronym>);</para>
+ </listitem>
+
+ <listitem>
+ <para>the <acronym>NoSQL</acronym> object store (in
+ <filename>objectstores/nosql</filename>) is a multi-user object
+ store that persists to NoSQL databases in JSON form.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You'll also find coverage of the object store
+ <acronym>API</acronym> itself in the default runtime's
+ documentation.</para>
+
+ <para>Alternatively, the default runtime can be configured to
+ support client/server remoting. This configuration only makes sense
+ for the <acronym>DnD</acronym> viewer, whereby it is configured as
+ the client and a separate instance of Isis runs as the server.
+ Again, full guidance is available in the default runtime's
+ documentation.</para>
+ </sect2>
+
+ <sect2>
+ <title>Authentication and Authorization</title>
+
+ <para><emphasis>Apache Isis</emphasis> provides an
+ <acronym>API</acronym>s for both authentication and
+ authorization.</para>
+
+ <para>The core implementation of these <acronym>API</acronym>s are
+ simple basic noop-based authentication and authorization mechanisms.
+ For deployment into production, you'll need to configure with
+ another alternative implementation.</para>
+
+ <para>One option is the file-based implementation (in
+ <filename>security/file</filename>), that stores the security
+ information in flat files. This is simple, but unlikely to be robust
+ enough for enterprise use.</para>
+
+ <para>Another alternative is to use the <acronym>LDAP</acronym>
+ implementation (in <filename>security/ldap</filename>), which can
+ integrate with an <acronym>LDAP </acronym>infrastructure if you have
+ one. If you have a different security infrastructure, then you might
+ consider to write your own implementation (the
+ <acronym>API</acronym> is not complex).</para>
+ </sect2>
+ </sect1>
+ </chapter>
+ </part>
+
+ <part id="prt.WritingDomainObjects">
<title>Writing Domain Objects</title>
<partintro>
@@ -3726,7 +4644,7 @@ public class Money extends Magnitude {
</chapter>
</part>
- <part>
+ <part id="prt.SupportingFeatures">
<title>Supporting Features</title>
<chapter id="chp.Clock">
@@ -4260,7 +5178,7 @@ Element customerXsd = snapshot.getXsdEle
</chapter>
</part>
- <part>
+ <part id="prt.ReferenceAppendices">
<title>Reference Appendices</title>
<appendix>
@@ -4310,15 +5228,15 @@ Element customerXsd = snapshot.getXsdEle
<row>
<entry>addTo</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>removeFrom</entry>
</row>
@@ -4326,31 +5244,31 @@ Element customerXsd = snapshot.getXsdEle
<row>
<entry>choices</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>clear</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>modify</entry>
</row>
@@ -4360,37 +5278,37 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>default</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>disable</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
@@ -4398,23 +5316,23 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>get</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>set</entry>
</row>
@@ -4424,13 +5342,13 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>(services only)</entry>
</row>
@@ -4438,7 +5356,7 @@ Element customerXsd = snapshot.getXsdEle
<row>
<entry>hide</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
@@ -4446,9 +5364,9 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4456,15 +5374,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4472,15 +5390,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4488,29 +5406,29 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>modify</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>clear</entry>
</row>
@@ -4520,15 +5438,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4536,15 +5454,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4552,15 +5470,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4568,29 +5486,29 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
<entry>removeFrom</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>addTo</entry>
</row>
@@ -4598,15 +5516,15 @@ Element customerXsd = snapshot.getXsdEle
<row>
<entry>set</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
<entry>get</entry>
</row>
@@ -4616,15 +5534,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4632,15 +5550,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4648,15 +5566,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4664,15 +5582,15 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
- <entry> </entry>
+ <entry></entry>
</row>
<row>
@@ -4684,11 +5602,11 @@ Element customerXsd = snapshot.getXsdEle
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
<entry>Y</entry>
- <entry> </entry>
+ <entry></entry>
</row>
</tbody>
</tgroup>
@@ -6559,5 +7477,468 @@ public class ComplexNumber {
</imageobject>
</mediaobject>
</appendix>
+
+ <appendix id="apx.Archetype">
+ <title>Running the Quickstart Archetype</title>
+
+ <para>*** talk through using the "quickstart" archetype, which generates
+ a read-to-run app.</para>
+
+ <sect1>
+ <title>Run Archetype</title>
+
+ <para></para>
+
+ <para></para>
+
+ <para></para>
+
+ <para>Using Maven archetype plugin we can generate a new Isis
+ application very quickly. These are multi-moduled projects with
+ separate sections for the domain code, fixtures, web interfaces and so
+ on.</para>
+
+ <para>One option is to create the archetype from the commandline. Note
+ that if you are using Eclipse and have installed the m2eclipse plugin
+ then it provides a dialog to create the project from an archetype;
+ this is discussed below.</para>
+
+ <remark>TODO: update the listing below, it is out of date. The
+ archetype to use is called
+ 'org.apache.isis.support.archetype:quickstart</remark>
+
+ <screen>[rcm@localhost ~]$ <emphasis role="bold">mvn archetype:generate -DarchetypeCatalog=http://isis.apache.org</emphasis>
+[INFO] Scanning for projects...
+[INFO] Searching repository for plugin with prefix: 'archetype'.
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Maven Default Project
+[INFO] task-segment: [archetype:generate] (aggregator-style)
+[INFO] ------------------------------------------------------------------------
+[INFO] Preparing archetype:generate
+[INFO] No goals needed for project - skipping
+[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
+[INFO] Setting property: velocimacro.messages.on => 'false'.
+[INFO] Setting property: resource.loader => 'classpath'.
+[INFO] Setting property: resource.manager.logwhenfound => 'false'.
+[INFO] [archetype:generate]
+[INFO] Generating project in Interactive mode
+[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
+Choose archetype:
+1: local -> isis-application (Isis Application (Archetype))
+2: local -> isis-icons (Isis Icons (Archetype))
+3: local -> htmlviewer-war (Isis WAR (Archetype))
+4: local -> hibernate-support (Hibernate Support (Archetype))
+5: local -> remoting-support (Isis Remoting Support (Archetype))
+Choose a number: (1/2/3/4/5): <emphasis role="bold">1</emphasis></screen>
+
+ <para>To create a project from an archetype you must specify a
+ <emphasis>groupId</emphasis> and <emphasis>artifactId</emphasis>, a
+ <emphasis>version</emphasis> and a <emphasis>Java
+ package</emphasis>.</para>
+
+ <para>After choosing the archetype number and pressing enter you are
+ prompted for the project's details. The <emphasis>groupId</emphasis>
+ is an identifier representing your company/group; ours would typically
+ be "org.apache.isis" for the domain followed by a name for the group
+ of products. The <emphasis>artifactId</emphasis> identifies the
+ projects that we are creating. The <emphasis>version</emphasis>
+ indicates how mature the project is, and should be left as the
+ default, e.g. 1.0-SNAPSHOT. Finally, the <emphasis>package</emphasis>
+ is the base package name used for all Java files. After these have
+ been entered you are prompted to confirm by entering Y, as shown
+ below.</para>
+
+ <para>Be wary of using invalid names. The <emphasis>groupId</emphasis>
+ should be alphanumeric with dots to separate the words. The
+ <emphasis>artifactId</emphasis> should also be alphanumeric, with '-'
+ (hyphens) to separate the words. The <emphasis>package</emphasis> name
+ should be a valid Java package name, i.e. should have no spaces or
+ dashes. Maven does little to check these things.</para>
+
+ <screen>Define value for groupId: : <emphasis role="bold">org.example</emphasis>
+Define value for artifactId: : <emphasis role="bold">expenses</emphasis>
+Define value for version: 1.0-SNAPSHOT: :
+Define value for package: : <emphasis role="bold">org.example.expenses</emphasis>
+Confirm properties configuration:
+groupId: org.example
+artifactId: expenses
+version: 1.0-SNAPSHOT
+package: org.example.expenses
+ Y: : <emphasis role="bold">y</emphasis>
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 1 minute 13 seconds
+[INFO] Finished at: Thu Oct 02 20:42:50 BST 2008
+[INFO] Final Memory: 13M/247M
+[INFO] ------------------------------------------------------------------------
+</screen>
+
+ <para>This will create a new directory with the name of the
+ <emphasis>artifactId</emphasis>. So in this example this is
+ <filename>expenses</filename> as shown below.<screen>expenses
+|-- pom.xml
+|-- dom
+| |-- pom.xml
+| `-- src
+|-- commandline
+| |-- config
+| |-- ide
+| |-- pom.xml
+| `-- src
+|-- fixture
+| |-- pom.xml
+| `-- src
+|-- service
+| |-- pom.xml
+| `-- src
+`-- webapp
+ |-- pom.xml
+ `-- src</screen></para>
+
+ <para></para>
+ </sect1>
+
+ <sect1>
+ <title>Building the application</title>
+
+ <para>Once an archetype is created it can be built using Maven and
+ run. Build using the <emphasis>install</emphasis> goal as shown
+ here.</para>
+
+ <screen>[rcm@localhost expenses]$ <emphasis role="bold">mvn clean install</emphasis>
+[INFO] Scanning for projects...
+[INFO] Reactor build order:
+[INFO] Isis Application
+[INFO] Domain Model
+[INFO] Services
+[INFO] Fixtures
+[INFO] Exploration
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Isis Application
+[INFO] task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean]
+[INFO] [site:attach-descriptor]
+[INFO] [install:install]
+[INFO] Installing /home/rcm/tmp/bearingpoint/expenses/pom.xml to /home/rcm/.m2/repository/org/example/expenses/1.0-SNAPSHOT/expenses-1.0-SNAPSHOT.pom
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Domain Model
+[INFO] task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean]
+[INFO] Deleting directory /home/rcm/tmp/bearingpoint/expenses/dom/target
+[INFO] [resources:resources]
+[INFO] Using default encoding to copy filtered resources.
+[INFO] [compiler:compile]
+[INFO] Compiling 7 source files to /home/rcm/tmp/bearingpoint/expenses/dom/target/classes
+[INFO] [resources:testResources]
+[INFO] Using default encoding to copy filtered resources.
+:
+:
+[INFO] [resources:testResources]
+[INFO] Using default encoding to copy filtered resources.
+[INFO] [compiler:testCompile]
+[INFO] No sources to compile
+[INFO] [surefire:test]
+[INFO] No tests to run.
+[INFO] [jar:jar]
+[INFO] Building jar: /home/rcm/tmp/bearingpoint/expenses/exploration/target/expenses.jar
+[INFO] [assembly:attached {execution: default}]
+[INFO] Reading assembly descriptor: src/main/assembly/descriptor.xml
+[INFO] Processing DependencySet (output=lib)
+[INFO] Copying files to /home/rcm/tmp/bearingpoint/expenses/exploration/target/expenses-exploration-1.0-SNAPSHOT-prototype.dir
+[WARNING] Assembly file: /home/rcm/tmp/bearingpoint/expenses/exploration/target/expenses-exploration-1.0-SNAPSHOT-prototype.dir is not a regular file (it may be a directory). It cannot be attached to the project build for installation or deployment.
+[INFO] [install:install]
+[INFO] Installing /home/rcm/tmp/bearingpoint/expenses/exploration/target/expenses.jar to /home/rcm/.m2/repository/org/example/expenses-exploration/1.0-SNAPSHOT/expenses-exploration-1.0-SNAPSHOT.jar
+[INFO]
+[INFO]
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Isis Application .............................. SUCCESS [6.087s]
+[INFO] Domain Model .......................................... SUCCESS [8.711s]
+[INFO] Services .............................................. SUCCESS [2.432s]
+[INFO] Fixtures .............................................. SUCCESS [2.283s]
+[INFO] Commandline ........................................... SUCCESS [10.774s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 31 seconds
+[INFO] Finished at: Tue Mar 03 11:59:50 GMT 2009
+[INFO] Final Memory: 40M/495M
+[INFO] ------------------------------------------------------------------------
+[rcm@localhost expenses]$ </screen>
+
+ <para>Once the project is built the results can be found in the
+ <filename>exploration/target</filename> directory, which contains both
+ a zipped distribution (in this example
+ <filename>expenses-exploration-1.0-SNAPSHOT-prototype.zip</filename>)
+ and an expanded distribution (again for this example,
+ <filename>expenses-exploration-1.0-SNAPSHOT</filename>). Using the
+ contained script files the application can be run from the command
+ line.<screen>exploration
+|-- config
+|-- ide
+|-- pom.xml
+|-- src
+`-- target
+ |-- archive-tmp
+ |-- classes
+ |-- expenses-exploration-1.0-SNAPSHOT-prototype.dir
+ | `-- expenses-exploration-1.0-SNAPSHOT
+ | |-- config
+ | |-- images
+ | |-- expenses.jar
+ | |-- isis.bat
+ | |-- isis.sh
+ | |-- lib
+ |-- expenses-exploration-1.0-SNAPSHOT-prototype.zip
+ |-- expenses.jar
+ `-- maven-archiver</screen></para>
+ </sect1>
+
+ <sect1>
+ <title>Running with the DnD Viewer</title>
+
+ <para>*** below was taken from the tutorial on running the old
+ expenses demo</para>
+
+ <para></para>
+
+ <para>The executable version of the Expenses demo application exists
+ within the <filename class="directory"
+ moreinfo="none">demos</filename> directory of the Isis
+ distribution.</para>
+
+ <para>Run the batch file <filename class="directory"
+ moreinfo="none">ExpensesDND.bat</filename> file either by
+ double-clicking on the icon (in Windows) or using the following
+ commands on the command line. In Windows the commands are</para>
+
+ <programlisting>> cd demos\expenses
+> ExpensesDND.bat</programlisting>
+
+ <para>while on the Mac or when using Unix/Linux they are:</para>
+
+ <programlisting>> cd demos/expenses
+> ./ExpensesDND.sh</programlisting>
+
+ <para>After seeing the Isis splash screen, you'll be presented with a
+ Login screen:</para>
+
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata contentwidth="40%" fileref="images/log-on-dnd.png"
+ format="PNG" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <para>Log in as 'sven' and a password of 'pass'. The application will
+ then open like this:</para>
+
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata contentwidth="40%" fileref="images/home-dnd.png"
+ format="PNG" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <para>When an application is started an application window is opened
+ and the user's services are displayed on the left hand side. These
+ icons typically give the user access to the domain objects held and
+ used by the system, and provide a way for to create new instances. Any
+ other object that subsequently appears on the screen represents one of
+ those objects.</para>
+
+ <remark>TODO replace with up-to-date shot using current
+ example</remark>
+
+ <screenshot>
+ <screeninfo></screeninfo>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata contentwidth="40%" fileref="images/dnd-example.png" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <para>The service and objects can be manipulated as follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Object actions can be invoked by
+ <emphasis>right-clicking</emphasis> on an icon and selecting one
+ of the options from the menu.</para>
+ </listitem>
+
+ <listitem>
+ <para>Resource actions can be invoked by
+ <emphasis>right-clicking</emphasis> on a resource icon.To inspect
+ an object (when only an icon is shown)
+ <emphasis>double-click</emphasis> it - this normally opens up the
+ object in a new window.</para>
+ </listitem>
+
+ <listitem>
+ <para>Objects can be dragged by
+ <emphasis>click-dragging</emphasis> on the icons and dropped by
+ releasing the mouse button.</para>
+ </listitem>
+
+ <listitem>
+ <para>Dragged objects can be dropped on an empty object field
+ (identified by the grey hole; the label to the right of the hole
+ specifies what type of object can be dropped). If the object can
+ be dropped into that field then it will flash green. If the object
+ cannot be dropped - either because it is the wrong type or that
+ specific object is disallowed for some other reason - then the
+ field will flash red. Dropping an object into a field sets up that
+ field, effectively associating the two objects.</para>
+ </listitem>
+
+ <listitem>
+ <para>Dragged objects can be dropped on to other object icons. If
+ the object that you attempting to drop onto accepts that type of
+ object then if will flash green. If that object does not accept
+ that kind of object, or disallows that specific object, then it
+ will flash red. Dropping one object on to another invokes a
+ specific object action, for example: add this product to that
+ order.</para>
+ </listitem>
+
+ <listitem>
+ <para>To quit the application, or access other application related
+ options right-click on the desktop to bring up the system
+ menu.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para></para>
+ </sect1>
+
+ <sect1>
+ <title>Running with the HTML Viewer</title>
+
+ <para>*** below was taken from the tutorial on running the old
+ expenses demo</para>
+
+ <para></para>
+
+ <para>2</para>
+
+ <para>To run the expenses demo with the HTML user interface, run the
+ batch file <filename class="directory"
+ moreinfo="none">ExpensesHTML.bat</filename> either by double-clicking
+ on the icon (in Windows) or using the following commands on the
+ command line. In Windows the commands are.</para>
+
+ <programlisting>> cd demos\expenses
+> ExpensesHTML.bat</programlisting>
+
+ <para>while on the Mac or when using Unix/Linux they are:</para>
+
+ <programlisting>> cd demos/expenses
+> ./ExpensesHTML.sh</programlisting>
+
+ <para>Allowing a few seconds for the application to start up, you then
+ need to launch a browser and point it to <filename class="directory"
+ moreinfo="none">http://localhost:8080/logon.app</filename> and you'll
+ be presented with a Login screen.</para>
+
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata contentwidth="40%" fileref="images/html-login.png"
+ format="PNG" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <para>Log in as 'sven' and a password of 'pass'. This will direct you
+ to the start page of the application, a welcome page is displayed and
+ links to the application resources are shown across the top. In the
+ same ways as for dnd these links give the user access to the objects
+ held and used by the system and provide a way for to create new
+ objects. Any other object that subsequently appears on the screen
+ represents one of those objects.</para>
+
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata contentdepth="40%" fileref="images/html-start.png"
+ format="PNG" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <para>For example if the claims link is clicked on within the expenses
+ demo the claims service page is shown with the resource actions
+ available in a menu on the left hand side of the screen.</para>
+
+ <screenshot>
+ <screeninfo></screeninfo>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata contentwidth="40%"
+ fileref="images/html-exampl-claims.png" />
+ </imageobject>
+ </mediaobject>
+ </screenshot>
+
+ <itemizedlist>
+ <listitem>
+ <para>Object actions can be invoked by clicking on one of the of
+ the options from the left hand menu.</para>
+ </listitem>
+
+ <listitem>
+ <para>Resource actions can be invoked clicking on a resource icon
+ link in the resource bar and then clicking on a menu item.</para>
+ </listitem>
+
+ <listitem>
+ <para>As objects are created or opened they are shown in an object
+ history beneath the resource bar.</para>
+ </listitem>
+
+ <listitem>
+ <para>Similarly the current context, i.e. the current nesting of
+ actions is shown beneath the object history.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1>
+ <title>Running with the Scimpi Viewer</title>
+
+ <para></para>
+ </sect1>
+
+ <sect1>
+ <title>Running with the Restful Viewer</title>
+
+ <para></para>
+ </sect1>
+
+ <sect1>
+ <title>Running with the Wicket Viewer</title>
+
+ <para></para>
+ </sect1>
+
+ <sect1>
+ <title>Running the BDD (Concordion) Tests</title>
+
+ <para></para>
+ </sect1>
+ </appendix>
</part>
</book>
Modified: incubator/isis/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/pom.xml?rev=1082839&r1=1082838&r2=1082839&view=diff
==============================================================================
--- incubator/isis/trunk/core/pom.xml (original)
+++ incubator/isis/trunk/core/pom.xml Fri Mar 18 07:47:32 2011
@@ -33,7 +33,7 @@
<dependency.locations.enabled>false</dependency.locations.enabled>
<docbkxGuideTitle>Apache Isis Core</docbkxGuideTitle>
- <docbkxGuideSubTitle>Design, APIs and Customization</docbkxGuideSubTitle>
+ <docbkxGuideSubTitle>Architecture, APIs and Customization</docbkxGuideSubTitle>
<docbkxGuideName>isis-core</docbkxGuideName>
</properties>