Hi Rob,

> On 12 Jul 2018, at 01:22, rob.atkin...@surroundaustralia.com wrote:
> 
> BTW - still trying to get my head around why sometimes a viewClass is used 
> and sometimes an instance of such a class - both seem to co-exist in EDG - 
> but whats the reason for using instances - and do they just behave like their 
> parent classes? and what if there are multiple? 
> 
> the properties of an instance do not shed much light on why they exist.  You 
> previously pointed to classView as a way to invoke a service. the docs leave 
> me no wiser:
> 
> "
> _view The URI of a specific view to display (instance of ui:Element).
> _viewClass    The URI or qname of a user-defined view class (subclass of 
> ui:Elements) to display. All other arguments that match the declared 
> arguments of the view class will be passed into the view, e.g. 
> uispin?_viewClass=ex:MyView&name=Test will be comparable to <ex:MyView 
> arg:name="Test" />."
> 
> is this explained in more detail elsewhere?

Not really, but it should be, so I started to write up some stuff. See below.

Richard




== SWP views are nested blank node structures ==

SWP views are written in XML:

    <ex:MyView arg:name="Test"/>

But internally, this is treated not as XML but as a structure of nested blank 
nodes. The snippet above would be a blank node with rdf:type ex:MyView, and a 
property arg:name with value “Test”.

In the case of XML with child elements, the root will still look as above, but 
there are further connected blank nodes for each child. An SWP developer rarely 
needs to know the details beyond that.


== Associating SWP views with classes and resources ==

There are a number of ways how these blank node structures can be associated 
with classes and resources:

1. ui:view associates an SWP view with a resource (an instance). The view is 
supposed to render the resource.

2. ui:instanceView associates an SWP view with a class. The view is supposed to 
render instances of the class. The instance to render is passed to the 
executing view as variable ?this.

ui:view and ui:instanceView are used to “dress up” domain models (a.k.a. domain 
ontologies) with presentation information that indicates how to display the 
entities in the model. 

3. ui:prototype associates an SWP view with a class. The view is supposed to 
accept arguments, and render a response based on these arguments. The arguments 
are passed in as variables. The view itself does not need to be concerned with 
the question where the arguments come from and who provides them. Classes that 
have a ui:prototype become available for use as custom XML elements in other 
views. The ex:MyView example given earlier assumes that ex:MyView is itself a 
class that has a ui:prototype. When the SWP engine renders the view example, it 
would call the ui:prototype and pass in the argument ?name with value “Test”. 
It is worth noting that the instances of a class with a ui:prototype are 
typically blank nodes that are SWP views. So we can think of our <ex:MyView 
arg:name="Test"> example view as an instance of ex:MyView that fills in the 
required arguments.

4. ui:errorPrototype, ui:headIncludes, and a few other properties are typically 
used to associate helper views for specific purposes to class hierarchies that 
use ui:prototype. They usually do not contain business logic.

ui:prototype and friends are used to package SWP views as reusable building 
blocks, and to develop full interactive web applications.


== Rendering SWP views via the SWP servlet ==

The most important way to execute SWP views is the SWP servlet of TBL/EVN/EDG. 
When calling the servlet, the view to execute can be specified in a number of 
ways:

1. /tbl/swp?_view=xxx directly names the view to render. As stated above, SWP 
views are structures of nested blank nodes, so this would need to name the 
top-level blank node of the view. This option rarely needs to be used directly 
by developers, but is used internally when a part of a view needs to be 
rendered, e.g., with ui:loadable or ui:handle.

2. /tbl/swp?_resource=xxx names a resource to render. The SWP servlet will 
check if the resource has a ui:view property, and if so render that view. Or 
else, walk up the class hierarchy to find a ui:instanceView property, and 
render that with the resource bound to ?this. There are additional arguments to 
pick between multiple applicable views. This is also what the “Browser” tab in 
TBCME does.

3. /tbl/swp?_viewClass=xxx names a class whose ui:prototype to render. Any 
additional parameters to the HTTP request (e.g., &param1=yyy&param2=zzz) will 
be passed in as arguments. In applications written in SWP, most pages are 
rendered in this way. It’s worth knowing that such calls actually create a new 
view on the fly, and render that view. So, ?_viewClass=ex:MyView&name=Test 
would generate our example view given above (in its blank node form), and pass 
that to the SWP engine to render.

(I am glossing over the _base parameter that is especially critical for 2 to 
specify the graph that holds the resource to be rendered.)


== The SWP class hierarchy ==

Another thing worth talking about is the role of the subclass hierarchy when 
working with classes that have ui:prototypes. Since SWP is a programming 
language, and has subclasses, one might think of it as an object-oriented 
language. There are indeed some object-oriented concepts in SWP, but I 
personally found that thinking of SWP in object-oriented terms does more harm 
than good. SWP is not a traditional object-oriented (or, for that matter, 
prototype-oriented) language. It is its own thing and fairly unique.

So, here are the most important uses of subclassing in SWP:

1. As a simple grouping mechanism in TBCME. If I work on a bunch of classes 
related to a certain feature, I might make them all subclasses of a common 
abstract class such as ex:FeatureXyzElements. This makes them appear together 
in the TBCME class tree, which is convenient for navigation in TBCME, even 
though it has no effect on the program itself.

2. To avoid having to repeat argument declarations, error prototypes, and head 
includes on multiple classes. A few select properties, including 
spin:constraints, ui:errorPrototype and ui:headIncludes, are inherited by 
subclasses for the purposes of the SWP engine. So, if I have many classes that 
require a ?projectGraph argument, I might declare it only once on an abstract 
class ex:ProjectGraphElements, and then make all other classes subclasses of 
that one. Or, if I have many classes that require the same ui:errorPrototype 
(e.g., a permission check or configuration check), then I might put that 
ui:errorPrototype on an abstract class ex:AdminElements and make the other ones 
subclasses of that one. Just to avoid having to say the same thing in multiple 
places.

There are other uses and patterns related to subclasses in SWP, but I find them 
less important.


== The “other” class hierarchy: meta-classes ==

It is also important to point out that SWP has two parallel class hierarchies. 
The “real” class hierarchy is rooted at ui:Element, and includes built-in 
abstract classes such as ui:ViewElements, ui:Services and ui:Operations. All 
your classes that have ui:prototypes live as subclasses in this hierarchy. 
Typically, I create new SWP classes by right-clicking on the appropriate class 
in that hierarchy and selecting “Create subclass”.

The “other” class hierarchy is rooted at ui:NodeClass and contains 
meta-classes. Your classes will be instances of those meta-classes. This 
usually happens automatically, and the whole “other” hierarchy can be ignored. 
But it is useful to know about in case one accidentally wanders into it.

The meta-classes mostly exist to make matters confusing. Apart from this, they 
also have the secondary purpose of making TBCME behave nicely when editing the 
“real” classes. For example, the ui:prototype field appears on the TBCME form 
of your classes by virtue of some meta-class magic. It would be nice if TBCME 
did a better job at hiding that magic!

Often, the meta-classes and the “real” classes are distinguished by singular 
vs. plural names, but this is inconsistent and cannot be relied upon.

-- 
You received this message because you are subscribed to the Google Groups 
"TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to topbraid-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to