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 2013/05/22 09:37:26 UTC

svn commit: r1485103 [4/4] - in /isis/site/trunk/content: applib-guide/ applib-guide/DRAFT/ applib-guide/how-tos/ applib-guide/how-tos/images/ applib-guide/images/ applib-guide/recognized-annotations/ applib-guide/recognized-methods/ applib-guide/suppo...

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Exploration.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Exploration.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Exploration.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Exploration.md Wed May 22 07:37:24 2013
@@ -0,0 +1,23 @@
+@Exploration
+------------
+
+> **Support**
+> 
+> * Partly supported by: Wicket viewer (equating to Wicket's DEVELOPMENT mode)
+
+The `@Exploration` annotation marks an action method as available in
+exploration mode only, and therefore not intended for use in the
+production system. An exploration action may or may not also be a debug
+action (annotated with `@Debug`<!--, see ?-->).
+
+For example:
+
+    public class Customer {
+        public Order placeNewOrder() { ... }
+        @Exploration
+        public List<Order> listRecentOrders() { ... }
+        ...
+    }
+
+See also the <!-...@Prototype--> annotation<!--, ?-->.
+

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Facets.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Facets.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Facets.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Facets.md Wed May 22 07:37:24 2013
@@ -0,0 +1,10 @@
+@Facets
+-------
+
+The `@Facets` annotation specifies `FacetFactory` implementations and so can
+be used to run install arbitrary `Facet`s for a type. Generally this is
+not needed, but can be useful for overriding a custom programming model
+where a `FacetFactory` is not typically included.
+
+<!--See the core documentation for more on writing FacetFactorys.-->
+

Added: isis/site/trunk/content/applib-guide/recognized-annotations/FieldOrder.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/FieldOrder.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/FieldOrder.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/FieldOrder.md Wed May 22 07:37:24 2013
@@ -0,0 +1,33 @@
+@FieldOrder
+-----------
+
+> **Note**
+>
+> The recommended mechanism for specifying the order in which fields are
+> listed to the user is `@MemberOrder` <!--(see ?)-->
+
+> **Support**
+> 
+> * Not supported by: Wicket viewer
+
+
+`@FieldOrder` provides a mechanism to specify the order in which fields
+appear in the user interface, in which the order is specified in one
+place in the class.
+
+For example:
+
+    @FieldOrder("Name, Address, DateOfBirth, RecentOrders")
+    public class Customer {
+        public Date getDateOfBirth() {...}
+        public List<Order> getRecentOrders() {...}
+        public String getAddress() {...}
+        public String getName() {...}
+        ...
+    }
+
+The field names are not case sensitive.
+
+However, `@FieldOrder` is more 'brittle' to change: if you change the
+name of an existing property you will need to ensure that the
+corresponding name within the `@FieldOrder` annotation is also changed.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Hidden.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Hidden.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Hidden.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Hidden.md Wed May 22 07:37:24 2013
@@ -0,0 +1,115 @@
+@Hidden
+-------
+
+> **Support**
+> 
+> * Fully supported by: Wicket viewer; other viewers do not yet support the `where` attribute.
+
+The `@Hidden` annotation indicates that the member (property, collection
+or action) to which it is applied should never be visible to the user.
+It can also be applied to service types (it has no effect if applied to
+entities or values).
+
+For example:
+
+    public class Customer {
+        @Hidden
+        public int getInternalId() { ... }
+
+        @Hidden
+        public void updateStatus() { ... }
+        ...
+    }
+
+Or, applied to a service:
+
+    @Hidden
+    public class EmailService {
+        public void sendEmail(...) { ... }
+        ...
+    }
+
+This annotation can also take a parameters indicating where and when it
+is to be hidden. For example:
+
+    public class Customer {
+        @Hidden(when=When.ONCE_PERSISTED)
+        public int getInternalId() { ... }
+        ...
+    }
+
+would show the `Id` until the object has been saved, and then would hide
+it. And:
+
+    public class Customer {
+        @Hidden(where=Where.ALL_TABLES)
+        public int getDateOfBirth() { ... }
+        ...
+    }
+
+would suppress the `dateOfBirth` property of a Customer from all tables.
+
+The acceptable values for the `where` parameter are:
+
+-   `Where.ANYWHERE`
+
+    The member should be hidden everywhere.
+
+-   `Where.OBJECT_FORMS`
+
+    The member should be hidden when displayed within an object form.
+    For most viewers, this applies to property and collection members,
+    not actions.
+
+-   `Where.PARENTED_TABLES`
+
+    The member should be hidden when displayed as a column of a table
+    within a parent object's collection. For most (all?) viewers, this
+    will have meaning only if applied to a property member.
+
+-   `Where.STANDALONE_TABLES`
+
+    The member should be hidden when displayed as a column of a table
+    showing a standalone list of objects, for example as returned by a
+    repository query. For most (all?) viewers, this will have meaning
+    only if applied to a property member.
+
+-   `Where.ALL_TABLES`
+
+    The member should be /hidden when displayed as a column of a table,
+    either an object's \* collection or a standalone list. This combines
+    `PARENTED_TABLES` and `STANDALONE_TABLES`.
+
+-   `Where.NOWHERE`
+
+    Acts as an override if a member would normally be hidden as a result
+    of some other convention. For example, if a property is annotated
+    with `@Title` <!--(see ?)-->, then normally this should be hidden from all
+    tables. Additionally annotating with `@Hidden(where=Where.NOWHERE)`
+    overrides this.
+
+The acceptable values for the `when` parameter are:
+
+-   `When.ALWAYS`
+
+    The member should be hidden at all times.
+
+-   `When.NEVER`
+
+    The member should never be hidden (unless disabled through some
+    other mechanism, for example an imperative disableXxx() supporting
+    method)..
+
+-   `When.ONCE_PERSISTED`
+
+    The member should be visible for transient objects, but hidden for
+    persisted objects.
+
+-   `When.UNTIL_PERSISTED`
+
+    The member should be hidden for transient objects, but visible for
+    persisted objects.
+
+By default the annotated property or action is always hidden (ie
+defaults to `Where.ANYWHERE`, `When.ALWAYS`).
+

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Idempotent (deprecated).md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Idempotent%20%28deprecated%29.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Idempotent (deprecated).md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Idempotent (deprecated).md Wed May 22 07:37:24 2013
@@ -0,0 +1,4 @@
+@Idempotent (deprecated)
+------------------------
+
+Equivalent to using `@ActionSemantics(Of.IDEMPOTENT)` on an action.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Ignore (deprecated).md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Ignore%20%28deprecated%29.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Ignore (deprecated).md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Ignore (deprecated).md Wed May 22 07:37:24 2013
@@ -0,0 +1,7 @@
+@Ignore (deprecated)
+--------------------
+
+Equivalent to using `@Programmatic`.
+
+The `@Programmatic` annotation was
+introduced because `@Ignore` can easily clash with `@org.junit.Ignore`.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Immutable.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Immutable.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Immutable.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Immutable.md Wed May 22 07:37:24 2013
@@ -0,0 +1,39 @@
+@Immutable
+----------
+
+The `@Immutable` annotation may be applied to a class, and indicates to
+the framework that the state of such objects may not be changed. The
+viewers will prevent any change through the user interface, and moreover
+the object stores will reject any changes to the objects that might have
+occurred programmatically.
+
+For example:
+
+    @Immutable
+    public class Country {
+        ...
+    }
+
+This annotation can also take a single parameter indicating when it is
+to become immutable. For example:
+
+    @Immutable(When.ONCE_PERSISTED)
+    public class Email {
+        ...
+    }
+
+This would allow the user to create an email object and set it up, and
+then prevent any changes once it has been saved.
+
+The acceptable values for the parameter are:
+
+-   `When.ALWAYS`
+
+-   `When.NEVER`
+
+-   `When.ONCE_PERSISTED`
+
+-   `When.UNTIL_PERSISTED`
+
+By default the annotated property or action is always immutable (ie
+defaults to `When.ALWAYS`).

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Mask.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Mask.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Mask.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Mask.md Wed May 22 07:37:24 2013
@@ -0,0 +1,47 @@
+@Mask
+-----
+
+> **Support**
+> 
+> * Not supported by: Wicket viewer
+
+The `@Mask` annotation may be applied to any property, or to any
+parameter within an action method, that allows the user to type in text
+as input. It can also annotate a string-based value type, and thereby
+apply to all properties or parameters of that type.
+
+The mask serves to validate, and potentially to normalise, the format of
+the input. The characters that can be used are based on Swing's
+`javax.swing.text.MaskFormatter`, and also Java's
+`java.util.SimpleDateFormat`.
+
+For example, on a property:
+
+    public class Email {
+        @Mask("(NNN)NNN-NNNN")
+        public String getTelephoneNumber() {...}
+        public void setTelephoneNumber(String telNo) {...}
+        ...
+    }
+
+Or, on an action parameter:
+
+    public void ContactRepository {
+        public void newContact(
+                @Named("Contact Name") String contactName
+               ,@Mask("(NNN)NNN-NNNN") 
+                @Named("Telephone Number") String telNo) { 
+            ...
+        }
+        ... 
+    }
+
+Or, on a value type:
+
+    @Value(...)
+    @MaxLength(30)
+    public class CustomerFirstName {
+        ...
+    }
+
+See also `@RegEx` annotation <!--, ?-->.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/MaxLength.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/MaxLength.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/MaxLength.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/MaxLength.md Wed May 22 07:37:24 2013
@@ -0,0 +1,39 @@
+@MaxLength
+----------
+
+The `@MaxLength` annotation indicates the maximum number of characters
+that the user may enter into a `String` property, or a `String`
+parameter in an action, or for a string-based value type. It is ignored
+if applied to any other type.
+
+For example, on a property:
+
+    public class Customer {
+        @MaxLength(30)
+        public String getFirstName() { ... }
+        public void setFirstName(String firstName) { ... }
+        ...
+    }
+
+Or, on an action parameter:
+
+    public class CustomerRepository {
+        public Customer newCustomer(
+            @MaxLength(30)
+            @Named("First Name") String firstName
+           ,@MaxLength(30)
+            @Named("Last Name") String lastName) {
+        ...
+    }
+
+Or, for a value type:
+
+    @Value(...)
+    @MaxLength(30)
+    public class CustomerFirstName {
+        ...
+    }
+
+If the model is being persisted to a relational database then
+`@MaxLength` should be specified for all `String` properties and action
+parameters.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/MemberGroups.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/MemberGroups.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/MemberGroups.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/MemberGroups.md Wed May 22 07:37:24 2013
@@ -0,0 +1,35 @@
+@MemberGroups
+-------------
+
+> **Support**
+> 
+> * Supported by: Wicket viewer; not yet supported by other viewers.
+
+`@MemberGroups` is designed to work in conjunction with `@MemberOrder`
+<!--(see ?)-->, and specifies the order in which groups of members should be
+rendered.
+
+For example:
+
+    @MemberGroups({"General", "Dates", "Other"})
+    public Class Customer {
+        @MemberOrder(name="General", sequence="1.1")
+        public String getFirstName() {...}
+        public void setFirstName(value as String) {...}
+
+        @MemberOrder(name="General", sequence="1.2")
+        public String getLastName() {...}
+        public void setLastName(value as String) {...}
+
+        @MemberOrder(name="Other", sequence="1")
+        public String getAddress() {...}
+        public void setAddress(value as String) {...}
+
+        @MemberOrder(name="Dates", sequence="1")
+        public Date getDateOfBirth() {...}
+        public void setDateOfBirth(value as Date) {...}
+        ...
+    }   
+
+If the `@MemberOrder`'s name is not specified, then its group is assumed
+to be "`General`".

Added: isis/site/trunk/content/applib-guide/recognized-annotations/MemberOrder.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/MemberOrder.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/MemberOrder.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/MemberOrder.md Wed May 22 07:37:24 2013
@@ -0,0 +1,103 @@
+@MemberOrder
+------------
+
+> **Support**
+> 
+> * Supported by all viewers; only Wicket viewer currently supports member grouping.
+
+`@MemberOrder` is the recommended mechanism for specifying the order in
+which fields and/or actions are presented to the user. (`@ActionOrder`
+and `@FieldOrder` provide alternative, deprecated mechanisms).
+
+`@MemberOrder` is specified at the individual member level, relative to
+other members, as a string. The simplest convention is to use numbers -
+1, 2, 3 - though it is a better idea to leave gaps in the numbers - 10,
+20, 30 perhaps - such that a new member may be added without having to
+edit existing numbers. A useful alternative is to adopt the
+'dewey-decimal' notation - 1, 1.1, 1.2, 2, 3, 5.1.1, 5.2.2, 5.2, 5.3 -
+which allows for an indefinite amount of future insertion, and allows
+subclasses to insert their class members as required.
+
+For example:
+
+    public Class Customer {
+        @MemberOrder(sequence="2.1")
+        public String getAddress() {...}
+        public void setAddress(value as String) {...}
+
+        @MemberOrder(sequence="1.1")
+        public String getFirstName() {...}
+        public void setFirstName(value as String) {...}
+
+        @MemberOrder(sequence="1.2")
+        public String getLastName() {...}
+        public void setLastName(value as String) {...}
+
+        @MemberOrder(sequence="3")
+        public Date getDateOfBirth() {...}
+        public void setDateOfBirth(value as Date) {...}
+        ...
+    }   
+
+If a member does not have a specified order then it will be placed after
+those that are specified. Two members may have the same sequence
+specifier, but in such a case the relative ordering of those members
+will be indeterminate.
+
+> **Note**
+>
+> Certain styles of user interface may lay out an object's properties
+> and its collections separately, in which case the relative member
+> order of properties and collections will be evaluated separately. In
+> general, though, consider the layout of all properties and collections
+> together, and of all actions together.
+
+As a refinement to this, some viewers support the notion of grouping
+members together. In this case the `name` attribute can be specified.
+
+For example, the following can be used to group properties:
+
+    public Class Customer {
+        @MemberOrder(name="General", sequence="1.1")
+        public String getFirstName() {...}
+        public void setFirstName(value as String) {...}
+
+        @MemberOrder(name="General", sequence="1.2")
+        public String getLastName() {...}
+        public void setLastName(value as String) {...}
+
+        @MemberOrder(name="Other", sequence="1")
+        public String getAddress() {...}
+        public void setAddress(value as String) {...}
+
+        @MemberOrder(name="Dates", sequence="1")
+        public Date getDateOfBirth() {...}
+        public void setDateOfBirth(value as Date) {...}
+        ...
+    }   
+
+In this case the `sequence` is ordered with respect to the `name`. If
+using group names in this way, typically the `@MemberGroups` annotation
+<!--(see ?)--> should also be specified, allowing the order of the groups
+themselves to be sorted.
+
+Grouping can also be performed on actions. Some viewers (for example the
+Wicket viewer) support the idea that the group name can be the name of a
+collection. In this case, the action is rendered "near to" the
+collection (for example, to support add or remove of elements).
+
+For example:
+
+    public Class Customer {
+
+        public List<CommunicationChannel> getCommunicationChannels() { ... }
+
+        ...
+        @MemberOrder(name="communicationChannels", sequence="1.1")
+        public void addCommunicationChannel(...) { ... }
+
+        @MemberOrder(name="communicationChannels", sequence="1.2")
+        public void removeCommunicationChannel(...) { ... }
+
+        ...
+    }   

Added: isis/site/trunk/content/applib-guide/recognized-annotations/MultiLine.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/MultiLine.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/MultiLine.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/MultiLine.md Wed May 22 07:37:24 2013
@@ -0,0 +1,68 @@
+@MultiLine
+----------
+
+> **Support**
+>
+> Supported, though the Wicket viewer does not support the `preventWrapping` attribute.
+
+The `@MultiLine` annotation provides information about the carriage
+returns in a `String` property or action parameter, or for a
+string-based value type. It also implies a hint to the viewer that the
+widget to be used should be over multiple lines (eg a text area rather
+than a text field), with appropriate wrapping and/or scrollbars.
+
+More formally, the annotation indicates that:
+
+-   the `String` property or parameter may contain carriage returns, and
+
+-   (optionally) the typical number of such carriage returns (meaning
+    the number of rows in the text area), and
+
+-   (optionally) that the text should be wrapped (the default is that
+    text is not wrapped).
+
+The syntax is:
+
+`@MultiLine([numberOfLines=<typicalNumberOfCRs>]
+        [,preventWrapping=<false|true>])`
+
+For example:
+
+    public class BugReport {
+        @MultiLine(numberOfLines=10)
+        public String getStepsToReproduce() { ... }
+        public void setStepsToReproduce(String stepsToReproduce) { ... }
+        ...
+    }
+
+Here the `stepsToReproduce` may be displayed in a text area of 10 rows,
+with no wrapping. A horizontal scrollbar may appear if the number of
+characters on any given row exceeds the width.
+
+Another example:
+
+    public class Email {
+        @MultiLine(numberOfLines=20, preventWrapping=false)
+        public String getBody() { ... }
+        public void setBody(String body) { ... }
+        ...
+    }
+
+Here the body should be displayed in a text area of 20 rows, with
+wrapping.
+
+If the annotation is combined with the `@TypicalLength`, then the
+expected width of the text area in the user interface will be determined
+by the value of the typical length divided by the number of specified
+lines. For example:
+
+    public class Email {
+        @MultiLine(numberOfLines=20, preventWrapping=false)
+        @TypicalLength(800)
+        public String getBody() { ... }
+        public void setBody(String body) { ... }
+        ...
+    }
+
+Here the body will (likely be) displayed in a text area of 20 rows, with
+40 columns.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/MustSatisfy.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/MustSatisfy.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/MustSatisfy.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/MustSatisfy.md Wed May 22 07:37:24 2013
@@ -0,0 +1,33 @@
+@MustSatisfy
+------------
+
+The `@MustSatisfy` annotation allows validation to be applied to
+properties and parameters using an (implementation of a)
+`org.apache.isis.applib.spec.Specification` object.
+
+For example, on a property:
+
+    public class Customer {
+        @MustSatisfy(StartWithCapitalLetterSpecification.class)
+        public String getFirstName() { ... }
+        ...
+    }
+
+Or, on an action parameter:
+
+    public class CustomerRepository {
+        public Customer newCustomer(
+                @MustSatisfy(StartWithCapitalLetterSpecification.class)
+                @Named("First Name") firstName
+               ,@MustSatisfy(StartWithCapitalLetterSpecification.class)
+                @Named("Last Name") lastName) {
+            ...
+        }
+        ...
+    }
+
+The `Specification` is consulted during validation, being passed the
+proposed value.
+
+An alternative to using `@MustSatisfy` is to define a custom value type (though this introduces additional mapping complexity for both viewers and objectstore)<!--,
+see ?-->.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Named.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Named.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Named.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Named.md Wed May 22 07:37:24 2013
@@ -0,0 +1,85 @@
+@Named
+------
+
+The `@Named` annotation is used when you want to specify the way
+something is named on the user interface i.e. when you do not want to
+use the name generated automatically by the system. It can be applied to
+objects, members (properties, collections, and actions) and to
+parameters within an action method.
+
+> **Warning**
+>
+> Generally speaking it is better to rename the property, collection or
+> action. The only common case where `@Named` is common is to rename
+> parameters for built-in value types. Even here though a custom value
+> type can be defined using `@Value` so that the value type is used as the
+> parameter name. `@Named` may also be used if the name needs punctuation
+> or other symbols in the name presented to the user.
+
+### Specifying the name of an object
+
+By default the name of an object is derived, reflectively from the class
+name. To specify a different name for an object, use the `@Named`
+annotation in front of the class declaration.
+
+For example:
+
+    @Named("Customer")
+    public class CustomerImpl implements Customer{
+       ...
+    }
+
+See also the `@Plural` annotation <!--, ?-->.
+
+### Specifying the name of a class member
+
+By default, the name of a class member (a property, collection or
+action) presented to the user is derived, reflectively, from the name of
+the member defined in the program code. To specify a different name use
+the `@Named
+          `annotation immediately before the member declaration.
+
+For example:
+
+    public class Customer {
+        
+        public String getFirstName() { ... }
+
+        
+        public String getSurname() { ... }
+
+        public CreditRating getCreditRating() { ... }
+    }
+
+Note that the framework provides a separate and more powerful mechanism
+for internationalisation.
+
+### Specifying the name for an action parameter
+
+The most common usage of `@Named` is be to specify names for the
+parameters of an action. This is because the parameter name declared in
+the code for the action method cannot be picked up reflectively (by
+default, the user interface will use the type of the parameter as the
+name; for a `String` or a `Boolean`, this is almost certainly not what is
+required).
+
+To specify the name of a parameter, the `@Named` annotation is applied
+'in-line' (i.e. preceding the individual parameter declaration.
+
+For example:
+
+    public class Customer {
+        public Order placeOrder(
+                Product product
+               ,@Named("Quantity")
+                int quantity) {
+            Order order = newTransientInstance(Order.class);
+            order.modifyCustomer(this);
+            order.modifyProduct(product);
+            order.setQuantity(quantity);        
+            return order;
+        }
+        ...
+    }
+
+An alternative is to use a value type (though this introduces additional mapping complexity for both viewers and objectstore) <!--, as described in ?-->.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/NotContributed.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/NotContributed.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/NotContributed.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/NotContributed.md Wed May 22 07:37:24 2013
@@ -0,0 +1,19 @@
+@NotContributed
+---------------
+
+The `@NotContributed` annotation applies only to action methods, and
+specifically to the actions of services. If present, it indicates that
+the action should not be contributed to any of its domain object
+arguments.
+
+For example:
+
+    public class OrderServices {
+        @NotContributed
+        public void cancel(Order order);
+        ...
+    }
+
+If the action should neither be contributed nor appear in the service's
+service menu <!--(see ?)-->, then you could instead simply mark it as `@Hidden`
+<!--(see ?)-->.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/NotInServiceMenu.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/NotInServiceMenu.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/NotInServiceMenu.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/NotInServiceMenu.md Wed May 22 07:37:24 2013
@@ -0,0 +1,20 @@
+@NotInServiceMenu
+-----------------
+
+The `@NotInServiceMenu` annotation applies only to action methods, and
+specifically to the actions of services. If present, it indicates that
+the action should not appear in the service menu for the service. It
+may, however, still be contributed to any of its domain object
+arguments.
+
+For example:
+
+    public class OrderServices {
+        @NotInServiceMenu
+        public void cancel(Order order);
+        ...
+    }
+
+If the action should neither be contributed (see ?) nor appear in the
+service's service menu, then you could instead simply mark it as `@Hidden`
+<!--(see ?)-->.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/NotPersistable.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/NotPersistable.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/NotPersistable.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/NotPersistable.md Wed May 22 07:37:24 2013
@@ -0,0 +1,38 @@
+@NotPersistable
+---------------
+
+> **Support**
+> 
+> * Not supported by: Wicket viewer
+
+The `@NotPersistable` annotation indicates that transient instances of
+this class may be created but may not be persisted. The framework will
+not provide the user with an option to 'save' the object, and attempting
+to persist such an object programmatically would be an error.
+
+For example:
+
+    public class InputForm {
+        // members and actions here
+    }
+
+This annotation can also take a single parameter indicating whether it
+is only the user that cannot persist the object, for example the
+following code would prevent the user from saving the object (via the
+viewer) but still allow the program to persist the object.
+
+For example:
+
+    @NotPersistable(By.USER)
+    public class InputForm {
+        ...
+    }
+
+The acceptable values for the parameter are:
+
+-   `By.USER`
+
+-   `By.USER_OR_PROGRAM`
+
+By default the annotated object is effectively transient (ie default to
+`By.USER_OR_PROGRAM`).
\ No newline at end of file

Added: isis/site/trunk/content/applib-guide/recognized-annotations/NotPersisted.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/NotPersisted.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/NotPersisted.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/NotPersisted.md Wed May 22 07:37:24 2013
@@ -0,0 +1,21 @@
+@NotPersisted
+-------------
+
+The `@NotPersisted` annotation indicates that the property is not to be
+persisted.
+
+> **Note**
+>
+> In many cases the same thing can be achieved simply by providing the
+> property with a 'getter' but no 'setter'.
+
+For example:
+
+    public class Order {
+
+        @NotPersisted
+        public Order getPreviousOrder() {...}
+        public void setPreviousOrder(Order previousOrder) {...}
+
+        ...
+    }

Added: isis/site/trunk/content/applib-guide/recognized-annotations/ObjectType.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/ObjectType.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/ObjectType.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/ObjectType.md Wed May 22 07:37:24 2013
@@ -0,0 +1,19 @@
+@ObjectType
+-----------
+
+The `@ObjectType` annotation is used to provide a unique abbreviation for
+the object's class name. This is used internally to generate a string
+representation of an objects identity (the `Oid`).
+
+For example:
+
+    @ObjectType("ORD")
+    public class Order {
+
+        ...
+    }
+
+If no `@ObjectType` annotation is present, then the framework uses the
+fully-qualified class name.
+
+If an `@ObjectType` is not unique, then the framework will fail to boot.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Optional.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Optional.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Optional.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Optional.md Wed May 22 07:37:24 2013
@@ -0,0 +1,54 @@
+@Optional
+---------
+
+By default, the system assumes that all properties of an object are
+required, and therefore will not let the user save a new object unless a
+value has been specified for each property. Similarly, by default, the
+system assumes that all parameters in an action are required and will
+not let the user execute that action unless values have been specified
+for each parameter.
+
+To indicate that either a property, or an action parameter, is optional,
+use the `@Optional` annotation.
+
+> **Note**
+>
+> The `@Optional`annotation has no meaning for a primitive property (or
+> parameter) such as `int` - because primitives will always return a
+> default value (e.g. zero). If optionality is required, then use the
+> corresponding wrapper class (e.g. `java.lang.Integer`).
+
+### Making a property optional
+
+Annotate the getter to indicate that a property is `@Optional`. For
+example:
+
+    public class Order {
+        public Product getProduct() { ... }
+        
+        public java.util.Date getShipDate() { ... }
+        public void setShipDate(Date java.util.shipDate) { ... }
+
+        @Optional
+        public String getComments() { ... }
+        public void setComments(String comments) { ... }
+    }
+
+Here the `product` and `shipDate` properties are both required, but the
+`comments` property is optional.
+
+### Making an action parameter optional
+
+To indicate that an action may be invoked without having to specify a
+value for a particular parameter, annotate with `@Optional`. For
+example:
+
+    public class Customer {
+        public Order placeOrder(
+                Product product
+               ,@Named("Quantity") int quantity
+               ,@Optional @Named("Special Instructions") String instr) {
+            ...
+        }
+        ...
+    }

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Paged.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Paged.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Paged.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Paged.md Wed May 22 07:37:24 2013
@@ -0,0 +1,36 @@
+@Paged
+------
+
+> **Support**
+> 
+> * Supported by: Wicket viewer; not yet supported by other viewers.
+
+This annotation is used to indicate that parented and/or standalone
+collections should be paginated.
+
+When annotated on a collection, `@Paged` indicates the page size of a
+parented collection. When annotated on a type, `@Paged` indicates the page
+size of a standalone collection.
+
+For example:
+
+    @Paged(30)
+    public class Order {
+
+        @Paged(15)
+        public List<LineItem> getDetails() {...}
+    }
+
+This indicates a page size of 15 for parented collections, and a page
+size of 30 for standalone collections.
+
+When omitting a parameter value or omitting the annotation completely,
+the configured defaults in `isis.properties` will be used.
+
+For example:
+
+    isis.viewers.paged.standalone=20
+    isis.viewers.paged.parented=5
+
+This indicates a page size of 5 for parented collections and a page size
+of 20 for standalone collections.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Parseable.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Parseable.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Parseable.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Parseable.md Wed May 22 07:37:24 2013
@@ -0,0 +1,20 @@
+@Parseable
+----------
+
+> **Support**
+> 
+> * Not supported by: Wicket viewer (which uses Wicket's Converter API instead).
+
+Parseability means being able to parse a string representation into an
+object by way of the `org.apache.isis.applib.adapters.Parser` interface.
+Generally this only applies to value types, where the `@Value` annotation
+<!--(see ?)--> implies encodability through the `ValueSemanticsProvider`
+interface <!--(see ?)-->.
+
+For these reasons the `@Parser` annotation is generally never applied
+directly, but can be thought of as a placeholder for future enhancements
+whereby non-value types might also have be able to be parsed. 
+
+> **Note**
+> 
+> The `@AutoComplete` also allows objects to be looked up from a string represention.

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Plural.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Plural.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Plural.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Plural.md Wed May 22 07:37:24 2013
@@ -0,0 +1,22 @@
+@Plural
+-------
+
+> **Support**
+> 
+> * Not supported by: Wicket viewer
+
+When the framework displays a collection of several objects it may use
+the plural form of the object type in the title. By default the plural
+name will be created by adding an 's' to the end of the singular name
+(whether that is the class name or another name specified using
+`@Named`). Where the single name ends in 'y' then the default plural
+name will end in 'ies' - for example a collection of `Country` objects
+will be titled 'Countries'. Where these conventions do not work, the
+programmer may specify the plural form of the name using `@Plural`.
+
+For example:
+
+    @Plural("Children")
+    public class Child {
+        // members and actions here
+    }
\ No newline at end of file

Added: isis/site/trunk/content/applib-guide/recognized-annotations/Prototype.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-annotations/Prototype.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-annotations/Prototype.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-annotations/Prototype.md Wed May 22 07:37:24 2013
@@ -0,0 +1,22 @@
+@Prototype
+----------
+
+> **Support**
+> 
+> * Partly supported by: Wicket viewer (equating to Wicket's DEVELOPMENT mode)
+
+The `@Prototype` annotation marks an action method as available in
+prototype mode only, and therefore not intended for use in the
+production system. A prototype action may or may not also be a debug
+action (annotated with `@Debug` <!--, see ?)-->.
+
+For example:
+
+    public class Customer {
+        public Order placeNewOrder() { ... }
+        @Prototype
+        public List<Order> listRecentOrders() { ... }
+        ...
+    }
+
+See also the @Exploration annotation <!--, ?-->.

Added: isis/site/trunk/content/applib-guide/recognized-methods/Recognized Methods and Prefixes.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/recognized-methods/Recognized%20Methods%20and%20Prefixes.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/recognized-methods/Recognized Methods and Prefixes.md (added)
+++ isis/site/trunk/content/applib-guide/recognized-methods/Recognized Methods and Prefixes.md Wed May 22 07:37:24 2013
@@ -0,0 +1,324 @@
+Recognized Methods and Prefixes
+===============================
+
+The following table lists all of the methods or method prefixes that are
+recognized by *Apache Isis*' default programming model:
+
+<table>
+<tr>
+    <th>Prefix</th>
+    <th>Object</th>
+    <th>Property</th>
+    <th>Collection</th>
+    <th>Action</th>
+    <th>Action Param</th>
+    <th>See also</th>
+</tr>
+<tr>
+    <td>addTo</td>
+    <td></td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>removeFrom</td>
+    <td></td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>choices</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+</tr>
+<tr>
+    <td>clear</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>modify</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>created</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>default</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+</tr>
+<tr>
+    <td>disable</td>
+    <td>Y</td>
+    <td>Y</td>
+    <td>Y</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>get</td>
+    <td></td>
+    <td>Y</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td>set</td>
+</tr>
+<tr>
+    <td>getId</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>(services only)</td>
+</tr>
+<tr>
+    <td>hide</td>
+    <td></td>
+    <td>Y</td>
+    <td>Y</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>iconName</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>loaded</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>loading</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>modify</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>clear</td>
+</tr>
+<tr>
+    <td>persisted</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>persisting</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>removing</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>removed</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>removeFrom</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>addTo</td>
+</tr>
+<tr>
+    <td>set</td>
+    <td></td>
+    <td>Y</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td>get</td>
+</tr>
+<tr>
+    <td>toString</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>title</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>updating</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>updated</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td>validate</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td>Y</td>
+    <td>Y</td>
+    <td></td>
+</tr>
+<tr>
+    <td>validateAddTo</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>validateRemoveFrom</td>
+</tr>
+<tr>
+    <td>validateRemoveFrom</td>
+    <td></td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>validateAddTo</td>
+</tr>
+</table>
+
+
+There are also a number of deprecated methods:
+
+<table>
+<tr>
+    <th>Prefix</th>
+    <th>Object</th>
+    <th>Property</th>
+    <th>Collection</th>
+    <th>Action</th>
+    <th>Action Param</th>
+    <th>See also</th>
+</tr>
+<tr>
+    <td>deleted</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>removed</td>
+</tr>
+<tr>
+    <td>deleting</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>removing</td>
+</tr>
+<tr>
+    <td>saved</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>persisted</td>
+</tr>
+<tr>
+    <td>saving</td>
+    <td>Y</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>persisting</td>
+</tr>
+</table>
+
+In order to be recognized, all methods must be `public`. Any methods
+that do not match are deemed to be action methods that the user can
+invoke from the user interface.

Added: isis/site/trunk/content/applib-guide/supporting-features/01-Clock.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/supporting-features/01-Clock.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/supporting-features/01-Clock.md (added)
+++ isis/site/trunk/content/applib-guide/supporting-features/01-Clock.md Wed May 22 07:37:24 2013
@@ -0,0 +1,40 @@
+Clock
+=====
+
+> The default Clock and alternative implementations.
+
+Many if not all enterprise applications deal with dates and times in one way or another. For example, if an `Order` is placed, then the `Customer` may have 30 days to pay the Invoice, otherwise a penalty may be levied.
+However, this can complicate automated testing: "today+30" will be a different date every time the test is run.
+
+A common solution is to require that domain objects do not go directly to the system for the current date (ie don't simply instantiate a new `java.util.Date` in order to get the current time); instead they should call some sort of facade.
+
+The *Apache Isis* framework provides such a facade through the
+`org.apache.isis.applib.clock.Clock` class. The defaults for all values refer back to the `Clock`, and - because the `Clock` is a singleton - it is easy for any application code to obtain the current time also.
+
+For example:
+
+    public class Customer {
+         public Order placeOrder(Product p) {
+             Date now = Clock.getTimeAsDate();
+             ...
+         }
+         ...
+    }
+
+Lazily Instantiated
+-------------------
+
+The first call to `Clock.getTime()` will lazily instantiate the singleton, with the default implementation being one that simply delegates to the system's internal clock. To use a different `Clock` implementation, eg one
+that delegates to an NNTP server, all that is required is to instantiate it any time prior to bootstrapping *Isis* itself.
+
+One notable implementation that notably takes advantage of this is `FixtureClock`, used for testing. <!--See ? for more information.-->
+
+Possibly Replaceable
+--------------------
+
+`Clock` implementations can indicate whether they are replaceable as the singleton, or not.
+
+Most (all?) production implementations (eg the default system clock) are *not* replaceable; once instantiated, any attempt to instantiate another subclass will be rejected with an exception.
+
+However implementations to work with tests (such as `FixtureClock`, already mentioned) are more likely to be replaceable, so that they can be setup multiple times as required.
+

Added: isis/site/trunk/content/applib-guide/supporting-features/02-Profiles.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/supporting-features/02-Profiles.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/supporting-features/02-Profiles.md (added)
+++ isis/site/trunk/content/applib-guide/supporting-features/02-Profiles.md Wed May 22 07:37:24 2013
@@ -0,0 +1,62 @@
+Profiles
+========
+
+> Support for user profiles
+
+As well as allowing domain entities to be persisted into object stores,
+*Apache Isis* also allows user *profiles* to be persisted into a profile
+store.
+
+Profiles and Perspectives
+-------------------------
+
+Every user can have one profile associated with them, which consists of:
+
+-   a set of options or preferences
+
+-   a set of perspectives
+
+A perspective is something akin to a layout or desktop, representing a
+configuration of relevant objects as might be displayed on the home page
+of the viewer. In particular, perspectives allow the set of services
+available to a user (eg as icons in the DnD viewer) to be customized for
+that user. Since these services represent the "start points" for the
+user to interact with the domain model, they in a sense define an
+application on a per-user basis.
+
+The elements that make up a perspective are:
+
+-   a set of services (identified by the string returned from each
+    service's getId() method, see ?)
+
+    These are the services (eg icons) that can be accessed from that
+    perspective
+
+-   a set of objects
+
+    These might represent bookmarks to objects saved from a previous
+    session.
+
+The applib contains types to define these two concepts; specifically
+Profile and Perspective. These are actually interfaces, the
+implementation is provided by framework itself.
+
+Runtime and Viewer Support
+--------------------------
+
+Support for profiles will vary across runtime implementations and across
+viewers. The *default runtime* implementation *does* support profiles,
+however, and works such that if a user logs in and no perspective exists
+for that user one will automatically be created. This will either be a
+copy of the 'template' perspective, or, if no such template exists, then
+simply a perspective containing all the known services.
+
+Moreover, the runtime must be configured to use some sort of persistence
+mechanism for profiles such that they are persisted between runs. The
+default runtime does support this (though the default is the in-memory
+profilestore that does not persist any information between sessions).
+
+Even if the configured runtime does support profiles, not every viewer
+necessarily uses the concept. The most notable viewer that *does*
+support the idea is the *dnd viewer*.
+

Added: isis/site/trunk/content/applib-guide/supporting-features/03-Fixtures and SwitchUser.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/supporting-features/03-Fixtures%20and%20SwitchUser.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/supporting-features/03-Fixtures and SwitchUser.md (added)
+++ isis/site/trunk/content/applib-guide/supporting-features/03-Fixtures and SwitchUser.md Wed May 22 07:37:24 2013
@@ -0,0 +1,184 @@
+Fixtures and SwitchUser
+=======================
+
+> Using fixtures to setup the system, generally for testing purposes.
+
+Fixtures are used to setup the framework into a known state. This is
+predominantly done for testing, and in particular when running with the
+in-memory object store. However, fixtures can also be used to specify
+the user that has "logged on", and to set the clock.
+
+Whether a fixture has any effect will depend on several factors:
+
+-   the first is the DeploymentType; specifying the logged on user will
+    only be honoured if running in exploration mode (or more precisely,
+    where DeploymentType\#isExploring() returns true);
+
+-   the second is the object store; most persistent object stores will
+    either ignore fixtures, or only allow them to be installed once or
+    if run with an (object store-specific) flag set
+
+How to register fixtures
+------------------------
+
+All domain services (which includes repositories and factories) should be registered in the *isis.properties* configuration file, under the `isis.fixtures.prefix` and `isis.fixtures` keys.
+
+For example:
+
+    isis.fixtures.prefix= org.apache.isis.support.prototype.fixture
+    isis.fixtures= ClaimsFixture,LogOnAsCliveFixture
+
+It is also possible to specify fixtures from the command line, using the
+--fixture flag.
+
+How to write custom fixtures
+----------------------------
+
+The applib defines several interfaces and classes for writing fixtures.
+The following UML diagram shows their relationships:
+
+![](images/Fixtures.png)
+
+### InstallableFixture and FixtureType
+
+The `InstallableFixture` interface defines the general contract between a
+fixture and the framework: the `FixtureType`, and an `install()` method.
+
+The `FixtureType` is used to characterize whether the fixture:
+
+-   if `FixtureType.DOMAIN_OBJECTS` (the default), then the fixture will
+    be installed only so long as the configured object store does not
+    indicate that fixtures have already been installed
+
+-   if `FixtureType.USER_PROFILES`, then the fixture will be installed
+    only so long as the configured profile store does not indicate that
+    fixtures have already been installed
+
+-   if `FixtureType.OTHER`, then the fixture will always be installed.
+    This usually refers to setting the clock or user.
+
+### BaseFixture and AbstractFixture
+
+The `BaseFixture` class is not API, but is responsible for instantiating `FixtureClock`. This is an implementation of `Clock` singleton, which <!--(as
+described in ?)-->, is used by the rest of the *Isis* framework delegates
+to in order to obtain the current time. The `FixtureClock`'s purpose is to
+allow the current date/time to be set by other fixtures.
+
+The `AbstractFixture` class (inheriting from `BaseFixture`) is an
+general-purpose adapter for writing fixtures. It implements
+`CompositeFixture` interface, meaning that hierarchies of fixtures can be
+created following the composite design pattern. It also provides a
+number of convenience methods:
+
+-   the `setDate(...)` and `setTime(...)` method allow the date/time to be set.
+
+    This is done using by obtaining the `FixtureClock` (from `BaseFixture`).
+    There are also some convenience methods to move the date/time either earlier or later.
+
+-   the `switchUser(...)` method allow the logged-on user to be changed
+
+    This changes the user logged-on while the fixtures are being installed. This is to facilitate tests that have complex setup requirements, eg verifying workflow between different user roles.
+
+An alternative to using `setDate(...)`/`setTime(...)` is to use `DateFixture`, and an alternative to using `switchUser(...)` is to use `SwitchUserFixture`.
+Which you use is largely a matter of personal preference.
+
+### DateFixture
+
+The `DateFixture` provides an alternative to `AbstractFixture`, just allowing the current date/time to be set.
+
+The main difference is one of style; `DateFixture` can be used in a declarative way, whereas `AbstractFixture` is more imperative. For example:
+
+    public class DateIs13Jan2007Fixture extends DateFixture {
+        public DateIs13Jan2007Fixture() {
+            super(2007,1,13);
+        }
+    }
+
+A fixture in this style could then be used within a composite fixture hierarchy.
+
+### SwitchUserFixture
+
+The `SwitchUserFixture` provides an alternative to `AbstractFixture`, just allowing the current user to be switched.
+
+The main difference is one of style; `SwitchUserFixture` can be used in a declarative way, whereas `AbstractFixture` is more imperative.
+
+For example:
+
+    public class SwitchToFrankSupervisorFixture extends SwitchUserFixture {
+        public SwitchToFrankSupervisorFixture() {
+            super("frank", "user", "supervisor");
+        }
+    }
+
+A fixture in this style could then be used within a composite fixture hierarchy.
+
+> **Warning**
+>
+> Do be aware of when you call `switchUser()` in a `Fixture` 
+> as it causes the current transaction to be ended and a 
+> new one started (for the new user). If you share a 
+> reference between the two you will get an exception.
+>
+> For example:
+>
+>     Account account = accounts.createAccount(
+>         "ACME", "Peter Planner", "pplanner@acme.com");
+>     Participant peterPlanner = account.getAdmin();
+>             
+>     switchUser("pplanner@acme.com", new String[0]);
+>
+>     Work work = plan1.createWork();
+>     BcpPlan plan = (BcpPlan) work.getTarget();
+>     plan.getOwner().modifyLeader(peterPlanner);
+>
+> This will fail because `peterPlanner` reference is no longer valid after the switch user.
+>
+> The solution is to retrieve the object again so it is part of the
+> second transaction. In this example we can change to code to this:
+>
+>     accounts.createAccount("ACME", "Peter Planner", "pplanner@acme.com");
+>             
+>     switchUser("pplanner@acme.com", new String[0]);
+>
+>     Account account = uniqueMatch(Account.class, "0 ACME");
+>     Participant peterPlanner = account.getAdmin();
+>
+>     Work work = plan1.createWork();
+>     BcpPlan plan = (BcpPlan) work.getTarget();
+>     plan.getOwner().modifyLeader(peterPlanner);
+
+### LogonFixture
+
+Unlike the very similar `SwitchUserFixture`, this fixture does not affect the currently logged on user while the fixtures are being installed.
+Instead, it is used to specify the user to logon as once all the fixtures have been installed.
+
+If more than one `LogonFixture` is specified, the last one encountered is used.
+
+### UserProfileFixture
+
+The `UserProfileFixture` is used to populate the configured profile store <!--[^1]--> with user profiles <!--(the concept of which is described in ?)-->.
+
+To create a user profile for a specific user, inherit from
+`UserProfileFixture`, use the inherited `newUserProfile()` to create a profile and use the inherited `saveForUser(...)` method to save that profile.
+
+It is also possible to create a 'template' perspective using the `saveAsDefault(...)` method. This is used as the basis for any new perspectives that are automatically created, eg for users who are logging in and for whom there is no perspective in existence.
+
+For example:
+
+    public class PerspectivesFixture extends UserProfileFixture {
+      @Override
+      protected void installProfiles() {
+        Profile profile = newUserProfile();
+        Perspective perspective = profile.newPerspective("ECS");
+        perspective.addToServices(LocationFactory.class);
+        perspective.addToServices(CustomerRepository.class);
+        perspective.addToServices(PaymentMethodFactory.class);
+            
+        saveAsDefault(profile);
+      }
+    }
+
+With that set up, when a new user now logs in they will see three service icons on the screen for locations, customers and payment methods. In the *dnd viewer* the user will be able to add and remove services from their perspective. See the DnD Viewer documentation for further details.
+
+Any fixtures, if specified, are only ever loaded once; the fixture installer checks with `UserProfileSevice.isInitialized()` to see if the fixture is already installed. This allows fixtures to be used for seeding a persisting profile store, and then be ignored thereafter.
+

Added: isis/site/trunk/content/applib-guide/supporting-features/04-XML Snapshots.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/supporting-features/04-XML%20Snapshots.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/supporting-features/04-XML Snapshots.md (added)
+++ isis/site/trunk/content/applib-guide/supporting-features/04-XML Snapshots.md Wed May 22 07:37:24 2013
@@ -0,0 +1,86 @@
+XML Snapshots
+=============
+
+> Generating XML snapshots from domain objects.
+
+The *Apache Isis* framework provides the capability to generate XML snapshots (and if required corresponding XSD schemas) based on graphs of domain objects. This is done using the
+`org.apache.isis.core.runtime.snapshot.XmlSnapshot` class.
+
+Generating an XML Snapshot
+--------------------------
+
+The `XmlSnapshot` can be created either directly or using a builder.
+
+### Basic Usage
+
+The standard usage is to instantiate directly.
+
+    XmlSnapshot snapshot = new XmlSnapshot(customer);
+    Element customerAsXml = snapshot.getXmlElement();
+
+This will return the Customer's fields, titles of simple references, number of items in collections.
+
+In order to use the `XmlSnapshot`, the domain object must implement `org.apache.isis.applib.snapshot.Snapshottable`. This is just a marker interface.
+
+### Including other Elements
+
+It's also possible to instruct the `XmlSnapshot` to "walk" the object graph and include other information within the generated XML.
+
+For example:
+
+    XmlSnapshot snapshot = new XmlSnapshot(customer);
+    snapshot.include("placeOfBirth");   // (1)
+    snapshot.include("orders/product"); // (2)
+    Element customerAsXml = snapshot.getXmlElement();
+
+In (1), we indicate that we want to also navigate to another domain object represented by simple reference `"placeOfBirth"`; in (2), we indicate that we want to navigate the `"orders"` collection (presumably of `Order`s) and for each referenced `Order`, to navigate in turn its `"product"` reference (presumably to a `Product` class).
+
+Note that `XmlSnapshot` is mutable, in that calls to its `getXmlElement()` may return different XML structures based on whether additional paths have been `include()`d, or whether the state of the domain objects themselves have changed.
+
+Using the Fluent API
+--------------------
+
+An `XmlSnapshot` can also be constructed using an alternative "fluent" API:
+
+    XmlSnapshot snapshot = 
+         XmlSnapshot.create(customer)
+                    .includePath("placeOfBirth")
+                    .include("orders/product")
+                    .build();
+    Element customerAsXml = snapshot.getXmlElement();
+
+The SnapshottableWithInclusions interface
+-----------------------------------------
+
+As already mentioned, in order to be snapshotted a domain object must implement the `Snapshottable` interface. This is just a marker interface, so implementing it is trivial.
+
+Alternatively, the domain object can choose to implement the
+sub-interface, `SnapshottableWithInclusions`. This moves the
+responsibility for determining what is included within the snapshot from the caller to the snapshottable object itself:
+
+    public interface SnapshottableWithInclusions extends Snapshottable {
+        List<String> snapshotInclusions();
+    }
+
+If necessary, both approaches can be combined.
+
+Generating an XSD schema
+------------------------
+
+As well as obtaining the XML snapshot, it is also possible to obtain an XSD schema that the XML snapshot conforms to.
+
+    XmlSnapshot snapshot = ...;
+    Element customerAsXml = snapshot.getXmlElement();
+    Element customerXsd = snapshot.getXsdElement();
+
+This can be useful for some tools. Note that for the XSD to be correct, the object being snapshotted must have non-null values for the paths that are `include()`'d. If this isn't done then the XSD will not be correct reflect for another snapshotted object that does have non-null values.
+
+Hints and Tips
+--------------
+
+As an alternative to using `include()`, you might consider building a non-persisted domain object (a "view model") which can reference only the relevant information required for the snapshot.
+
+For example, if only the 5 most recent Orders for a Customer were required, a `CustomerAndRecentOrders` view model could hold a collection of just those 5 `Order`s.
+
+Typically such view models would implement `SnapshottableWithInclusions`.
+

Added: isis/site/trunk/content/applib-guide/supporting-features/images/Fixtures.png
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/supporting-features/images/Fixtures.png?rev=1485103&view=auto
==============================================================================
Binary file - no diff available.

Propchange: isis/site/trunk/content/applib-guide/supporting-features/images/Fixtures.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: isis/site/trunk/content/applib-guide/value-types/010-intro.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/value-types/010-intro.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/value-types/010-intro.md (added)
+++ isis/site/trunk/content/applib-guide/value-types/010-intro.md Wed May 22 07:37:24 2013
@@ -0,0 +1,35 @@
+Value Types
+===========
+
+> Built-in value types, writing your own value types, and supporting
+> third-party value types.
+
+The state of any given entity is characterized by properties (?) and
+collections (?). A collections is a one-to-many reference to another
+entities, while a property is either a one-to-one reference to another
+entity, or it is a value.
+
+But what's a value? Well, it's an atomic piece of state. A string is a
+value, so is a number, so is a date. Values should be designed to be
+immutable (though some system value types, such as java.util.Date,
+famously are not).
+
+*Isis* supports all the standard JDK value types, and defines a number
+of its own (eg Percentage and Color).   *Isis* also allows you to define your own value types, such as `LastName`, or `Celsius`, or `ComplexNumber`.
+
+It's also possible to make Isis integrate with third-party
+value types.  *Isis* provides one such integration, with as [JodaTime](http://joda-time.sourceforge.net/).
+
+
+> **Note**
+>
+> *Isis*' support for a particular value type does not necessarily imply
+> that there is a custom widget for that type in a particular viewer.
+> Rather, it means that the state of the object can be serialized, is
+> expected to have equal-by-content semantics, and is expected to be
+> immutable. It may also be parseable from a string.
+
+
+
+>
+> Also, if using the JDO/DataNucleus ObjectStore, you may also need to perform additional DataNucleus-specific configuration if you want the data to be persisted in a SQL datatype other than SQL Blob (ie a serializable byte array).
\ No newline at end of file

Added: isis/site/trunk/content/applib-guide/value-types/020-Built-in Value Types.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/value-types/020-Built-in%20Value%20Types.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/value-types/020-Built-in Value Types.md (added)
+++ isis/site/trunk/content/applib-guide/value-types/020-Built-in Value Types.md Wed May 22 07:37:24 2013
@@ -0,0 +1,164 @@
+Built-in Value Types
+--------------------
+
+The following are the value types supported by *Isis* out-of-the-box.
+
+### JDK Types
+
+The following JDK types are supported by *Isis*.
+
+#### Primitive Types
+
+All the primitive types may be used as values: `byte`, `short`, `int`, `long`, `float`, `double`, `char`, and `boolean`.
+
+#### Wrapper Types
+
+The wrapper types for each of the primitives can also be used as value types: `java.lang.Byte`, `java.lang.Short`, `java.lang.Integer`, `java.lang.Long`, `java.lang.Float`, `java.lang.Double`, `java.lang.Character`, `java.lang.Boolean`.
+
+#### Java Classes
+
+The following java classes have value semantics and may be used as value types:
+
+-   `java.lang.String`
+
+-   `java.math.BigInteger` and `java.math.BigDecimal`
+
+-   `java.util.Date` (date and time), `java.sql.Date` (date only), and `java.sql.Time` (time only)
+
+-   `java.sql.Timestamp`
+
+-   `java.awt.Image`
+
+#### JODA
+
+The following [Joda](http://joda-time.sourceforge.net/) types are also supported:
+
+-   `org.joda.time.LocalDate`
+
+-   `org.joda.time.LocalDateTime`
+
+-   `org.joda.time.DateTime`
+
+
+#### Isis AppLib
+
+*Isis* itself also provides a number of its own value types. These are
+all in the org.apache.applib.value package:
+
+-   Color
+
+-   Date (date only), DateTime (date and time) and Time (time only)
+
+-   TimeStamp
+
+-   Image
+
+-   Money
+
+-   Password
+
+-   Percentage
+
+### Value formats
+
+*Isis* provides default formats for the inbuilt value types, according
+to type. These can be modified using `isis.properties`.
+
+These formats cut across the above categories; for example the byte
+format relates to both byte (primitive) and java.lang.Byte (wrapper). In
+all cases this setting can be overriden for a specific field using the
+@Mask annotation (see ?).
+
+#### Byte format
+
+The format for all bytes can be set, replacing the default format
+derived from the system, using the following property to specify a mask:
+
+    isis.value.format.byte=####
+
+The mask is used to set up a java.text.DecimalFormat formatting object
+so details of the mask format can be found in the Java documentation.
+
+#### Date Format
+
+The format for all dates can be set, replacing the default format derived from the system, using the following property to specify one of *long*, *medium*, *short*, *isolong*, *isoshort* or a mask:
+
+    isis.value.format.date=dd/MM/yy
+
+When a mask is specified it is used to set up a
+`java.text.SimpleDateFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Date/time Format
+
+The format for all date/time values can be set, replacing the default format derived from the system, using the following property to specify one of *long*, *medium*, *short*, *isolong*, *isoshort* or a mask:
+
+    isis.value.format.datetime=dd/MM/yy
+
+When a mask is specified it is used to set up a
+`java.text.SimpleDateFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Decimal format
+
+The format for `BigDecimal` values can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.decimal=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Double format
+
+The format for all double values can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.double=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Float format
+
+The format for all float values can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.float=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Integer format
+
+The format for all integers (including `BigInteger`) can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.int=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Long format
+
+The format for all long values can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.long=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Short format
+
+The format for all short values can be set, replacing the default format derived from the system, using the following property to specify a mask:
+
+    isis.value.format.short=####
+
+The mask is used to set up a `java.text.DecimalFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Time Format
+
+The format for all time values can be set, replacing the default format derived from the system, using the following property to specify one of *long*, *medium*, *short*, *isolong*, *isoshort* or a mask:
+
+    isis.value.format.time=ddMMyyyy hhmm
+
+When a mask is specified it is used to set up a
+`java.text.SimpleDateFormat` formatting object so details of the mask format can be found in the Java documentation.
+
+#### Timestamp Format
+
+The format for time stamp values can be set, replacing the default format derived from the system, using the following property to specify one of *long*, *medium*, *short*, *isolong*, *isoshort* or a mask:
+
+    isis.value.format.timestamp=hh:mm
+
+When a mask is specified it is used to set up a
+`java.text.SimpleDateFormat` formatting object so details of the mask format can be found in the Java documentation.

Added: isis/site/trunk/content/applib-guide/value-types/030-Custom Value Types.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/value-types/030-Custom%20Value%20Types.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/value-types/030-Custom Value Types.md (added)
+++ isis/site/trunk/content/applib-guide/value-types/030-Custom Value Types.md Wed May 22 07:37:24 2013
@@ -0,0 +1,37 @@
+Custom Value Types
+------------------
+
+In addition to the built-in value types it is also possible to define user-defined value types. This is typically done using the `@Value` annotation.
+
+The `@Value` annotation is used to provide an implementation of the `org.apache.isis.applib.adapters.ValueSemanticsProvider` interface. In turn this provides objects that allow the framework to interact with the value, specifically:
+
+-   the `EncoderDecoder` is used to convert the value into and back out of serializable form
+
+    This is used by some object stores (eg the XML Object Store), for by the XML Snapshot capability <!--(see ?)-->;
+
+-   the `Parser` is used to convert Strings into the value type
+
+    This is used as a fallback by viewers that do not have any specific widgets to support the particular value type, and make do with a simple text field instead.
+
+    An obvious example is to parse a date. But it could be used to parse "TRUE" and "FALSE" into a boolean (as opposed to using a checkbox).
+
+-   the `DefaultsProvider` is used to provide a meaningful default for the value
+
+    Not every value type will have a default, but some do (eg false for a boolean, 0 for a number). This is used as the default value for non-`@Optional` properties and parameters.
+
+Each of these interfaces also reside in `org.apache.isis.applib.adapters`.
+
+For more details, explore the built-in types within the applib, for example `org.apache.isis.applib.value.Money`.
+
+    @Value(semanticsProviderName =  "org.apache.isis.core.progmodel.facets.value.MoneyValueSemanticsProvider")
+    public class Money extends Magnitude {
+        ...
+    }
+
+where `MoneyValueSemanticsProvider` is the implementation of
+`ValueSemanticsProvider` described above.
+
+> **Note**
+>
+> Using value types generally removes the need for using `@MustSatisfy` annotation <!--(see ?)-->; the rules can 
+> instead move down into a `validate()` method on the value type itself.

Added: isis/site/trunk/content/applib-guide/value-types/04-Third-party Value Types.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/applib-guide/value-types/04-Third-party%20Value%20Types.md?rev=1485103&view=auto
==============================================================================
--- isis/site/trunk/content/applib-guide/value-types/04-Third-party Value Types.md (added)
+++ isis/site/trunk/content/applib-guide/value-types/04-Third-party Value Types.md Wed May 22 07:37:24 2013
@@ -0,0 +1,11 @@
+Third-party Value Types
+-----------------------
+
+Third party value types can also supported, again
+through the use of a `ValueSemanticsProvider`. However, since the source code cannot be altered, the provider must be supplied using a key value in `isis.properties` configuration file.
+
+For example, the following would register a semantics provider for `org.jodatime.time.Interval` (not a built-in at the time of this writing):
+
+      isis.core.progmodel.value.org.jodatime.time.DateTime.semanticsProviderName=\
+        com.mycompany.values.JodaIntervalValueSemanticsProvider
+

Modified: isis/site/trunk/content/contributors/release-process.md
URL: http://svn.apache.org/viewvc/isis/site/trunk/content/contributors/release-process.md?rev=1485103&r1=1485102&r2=1485103&view=diff
==============================================================================
--- isis/site/trunk/content/contributors/release-process.md (original)
+++ isis/site/trunk/content/contributors/release-process.md Wed May 22 07:37:24 2013
@@ -262,7 +262,7 @@ To capture the missing license informati
 mvn license:download-licenses
 </pre>
 
-This Maven plugin creates a `licensexml` file in the `target/generated-resources` directory of each module.
+This Maven plugin creates a `license.xml` file in the `target/generated-resources` directory of each module.
 
 Then, run the following script (shown here relative to the `core` module).