When a project is initialized using the Jspresso application archetype, 5 standard SJS source files are created :
application.groovy is a wrapper for the
other files. You will rarely modify it unless you want to change the
default project setup (to split the SJS files in functional domains
for instance).
model.groovy contains the application
domain model (compiled using SJS Domain).
view.groovy contains the application
views (compiled using SJS Front).
frontend.groovy contains everything that
is frontend related but distinct from the views, e.g. modules and
workspaces for instance (compiled using SJS Front).
backend.groovy contains everything that
is backend related but distinct from the domain model, e.g. backend
actions for instance (compiled using SJS Front).
All the boiler plate SJS code is already written in
application.groovy. This means that you don't have
to deal with the application namespace, error reporting, and so on. All
you have to do is directly write you application SJS code into the
pre-initialized SJS files. For instance, the following declaration in
model.groovy is enough to generate an entity
:
Entity('Person') {
string_32 'name'
integer 'age'
}You can further modularize SJS applications using the
include statement :
include('filename.groovy')included files are merged exactly as if all their statements had
been written directly into the in the including SJS source file. This is
actually the same mecanism that is used by the
application.groovy wrapper to include the standard
SJS source files.
As a general rule, component identifers must be unique across the appliction. If 2 components are declared using the same identifier, SJS will raise a compilation error duringthe build.
However, SJS allows an advanced usage in order to open specific scopes in which you can define components with the same identifier. A typical usage of this feature is to declare different implementation for the same identifier depending on the UI channel (e.g. Qooxdoo vs Flex vs Swing). This specific scopes feature is only available for SJS Front and not for SJS Domain.
Opening a specific scope is achieved using the spec
statement, e.g. :
spec('qooxdoo') {
...
}
spec('flex') {
...
}
spec('swing') {
...
}All the declarations that are placed inside the spec closure belong to this scope.
Contrary to what you might believe, components that are declared in a specific scope are visible from their inner AND outer scopes. They are only isolated from their same level scopes.
Scopes meaning are not limited to UI based customization. You could define staging scopes like development pre-production and production.
Scopes are then used in application.groovy to
write specific Spring XML context files that are afterwards used to
compose specific Spring contexts to declare in
beanRefFactory.xml.
In application.groovy :
frontendBuilder.writeOutputFile('swing',
project.properties['outputDir'],
'swing-'+project.properties['viewOutputFileName'])This will produce a custom swing-dsl-view.xml
Spring context file in the build output directory. This custom Spring
context file is then available for inclusion in a custom Spring
context.
In beanRefFactory.xml :
<bean
id="hrsample-swing-context"
class="org.springframework.context.support.ClassPathXmlApplicationContext"
lazy-init="true">
<constructor-arg>
<list>
...
<value>org/jspresso/hrsample/spec/swing-dsl-view.xml</value>
...
</list>
</constructor-arg>
</bean>