Table of Contents
Documentation for developer who want to use and extend the Geomajas GIS framework.
Geomajas is a free and open source GIS application framework for building rich internet applications. It has sophisticated capabilities for displaying and managing geospatial information. The modular design makes it easily extendable. The stateless client-server architecture guarantees endless scalability. The focus of Geomajas is to provide a platform for server-side integration of geospatial data, allowing multiple users to control and manage the data from within their own browsers. In essence, Geomajas provides a set of powerful building blocks, from which the most complex GIS applications can easily be built. Key features include:
Modular architecture
Clearly defined API
Integrated client-server architecture
Built-in security
Advanced geometry and attribute editing with validation
Custom attribute definitions including object relations
Advanced querying capabilities (searching, filters, style, ...)
Copyright © 2009-2010 Geosparc nv.
Licensed under the GNU Affero General Public License. You may obtain a copy of the License at http://www.gnu.org/licenses/
This program is distributed in the hope that it will be useful, but without any warranty ; without even the implied warranty of merchantability or fitness for a particular purpose . See the GNU Affero General Public License for more details.
The project also depends on various other open source projects which have their respective licenses.
From the Geomajas source (possibly specific module), the
dependencies can be displayed using the "mvn
dependency:tree
" command.
For the dependencies of the Geomajas back-end, we only allow dependencies which are freely distributable for commercial puposes (this for example excludes GPL and AGPL licensed dependencies).
This framework and documentation was written by the Geomajas Developers. If you have questions, found a bug or have enhancements, please contact us through the user fora at http://www.geomajas.org/.
List of contributors for this manual:
Pieter De Graef
Jan De Moerloose
Joachim Van der Auwera
Frank Wynants
Table of Contents
Geomajas is an application framework which allows building powerful GIS application. We will try to look at the architecture starting from a high level overview, drilling down to discover more details.
At the highest level, Geomajas makes a distinction between the back-end and faces.
The back-end is where you configure your maps, layers and attributes/features. It is always server side. The back-end has an API for interaction with the outside world and for extension using plug-ins. While one of the main purposes of the back-end is to provide bitmaps and vector graphics for the maps and provide data about features to be rendered and edited, it contains no display code.
The actual display and editing is done in the faces. The back-end is agnostic of web (or other) display frameworks. Faces are often split in two modules, a sever-side module (which directly talks to the back-end using java calls) and serializes data to the client, and a client-side module which only talks to the server side module. The communication between the two modules is private to the face. The face itself provides a additional client API. This will typically provide details about available widgets, parameters for these widgets and other possible interactions (like message queues or topics you can subscribe to).
The purpose of Geomajas is to provide rich editing of GIS data in the browser, but the faces also make other applications possible. You could unlock the maps which are configured in Geomajas using a face which makes data available as web services (this would result in a face with only a server-side module). You could also build a java swing application using the Geomajas back-end by writing a swing face. This would result in a thick client application (possibly accessible using Java Web Start).
Geomajas contains two faces out-of-the-box.
The a dojo face, which uses the dojo toolkit JavaScript widget library in the browser, is mainly provided for backward compatibility. Up until Geomajas 1.4 this was the only face which existed. It integrates well with dojo but has the disadvantage that you need to develop in both java (for the server side) and JavaScript (for the client side) and that debugging can be a challenge.
Since 1.5 we also provide a GWT face. This allows all development to be done in Java and GWT will handle conversion to Javascript for code which needs to run in the browser. Obviously this integrates best with GWT based applications, but it can be combined with other web frameworks as well.
The Geomajas back-end is built from many services which are wired together using dependency injection (DI). This wiring is partly done automatically, and partly through the configuration files. Thanks to the inversion of control (IoC) the back-end is very flexible and can be customized at will.
The client-server communication is done through the command dispatcher. This delegates to one of the action based services which handle the command. These typically interact with one or more of the topic based services (though the command could also handle everything directly). The most important built-in topic based services are the raster and vector layer service. They are used to access the GIS data which is stored as either raster or vector layer.
All the services are running in a secured zone and will typically interact with the security context to verify access rights (or policies).
The layers access the actual GIS data, either directly or using some kind of transformation service (for example a GeoServer or MapServer instance).
With this advanced configuration, many integration options exist. One example is displayed above, the inclusion of Geomajas in an existing application. On the client side, you just have to include the map widget in your web application. On the server side, there are many options, but you could for example assure that the transactions are shared between your existing application and Geomajas.
As is the case for most powerful frameworks, Geomajas stands on the shoulder of giants. We use some of the major open source libraries in our framework (and we integrate with a lot more).
The Geomajas back-end is itself built from several modules which are tied together using the Spring framework (http://springframework.org/). The Geomajas-api module is a set of interfaces which shields implementation details between the different modules. The base plumbing and some generic features are provided by the Geomajas-impl module.
There are four possible ways to extend the back-end.
command : commands are used as main interaction point between the face (client side) and the Geomajas back-end. The retrieval of maps and features, calculations, updates on the features and all all other functionalities which are available client-side are done using commands.
layer : this groups a set of access options for all details of the layers of a map. A layer can be either raster or vector based. A vector layer can be editable. The features describing the objects which are part of the vector layer are accessed through the "feature model" which converts generic feature objects into something Geomajas can use (this way, there is no need for the generic feature objects to implement a "feature" interface, allowing the use of pojos). A feature contains a geometry and can contain attributes, style and labels. Attributes can be complex, including one-to-many and many-to-one relations to other objects.
pipeline : all Geomajas back-end services which deal with layers are implemented using pipelines. A pipeline is a list of steps (actions) executed in order. Each pipeline can be overwritten for a layer, or you can change the default which is used when not overwritten for a layer.
Configuring pipelines can be used to change the rendering method, add additional rendering steps (for example marking the editable area on a tile), to introduce caching,...
security : these modules contain the pluggable security features. You can configure the security services which are used to verify the validity of an authentication token and return the authorization objects based on it. These authorization objects can read the security policies from your (secure) policy store.
The interaction of the client faces with the Geomajas back-end is handled using commands.
When a command needs to be invoked (probably as result of a
user interaction), the client will build a
CommandRequest
object. This contains the name of the
command to be used, the parameters for the command, and optionally
the user authentication token and language of the user
interface.
This object is transferred to the face server. For web applications, this will typically be done using an AJAX request.
The face server will use this CommandRequest
to
invoke the CommandDispatcher
service, which can be
obtained using the Spring context.
The CommandDispatcher
will start by invoking the
SecurityManager
to check whether the execution of the
requested command is allowed. If it is allowed, the actual Command
is obtained using the Spring context. The
CommandResponse
object is created and the command is
executed.
The Command
will now do its job, writing the
results in the CommandResponse
object. When problems
occur during execution of the command, it can either write this into
the response object or throw an exception.
When the command has executed, if it threw an exception, the dispatcher will add this in the response object. It will then convert any exceptions in the response object into some messages which may be sensible to the user (put the message in the correct language in the result object, assuring the "cause" chain is also included). Some extra information is also added in the response object (like command execution time).
The CommandResponse
is returned to the face
server.
The face server serializes the CommandResponse
back to the face client.
When the command had something to do with rendering, then the
response object is likely to contain a Tile
.
All the layer access services provided by the Geomajas back-end
are implemented by invoking a pipeline. Using
PipelineService
, blocks of functionality become reusable
and highly configurable with limited coupling between the
pipeline step
s.
Some of the services which are implemented as
PipelineService
include:
RasterLayerService
: methods for accessing a
raster layer, especially getting tiles for a raster
layer.
VectorLayerService
: methods for accessing a
vector layer, for example for getting the features or obtaining
vector tiles.
Pipelines can nest. One of the steps in the default "vectorLayer.saveOrUpdate" pipeline will loop over all features to be updated and invoke the "vectorLayer.saveOrUpdateOne" pipeline for each.
Pipelines are server side only, client access is typically made available by invoking a command.
Pipelines are typically invoked for a specific layer. In that case, the default pipeline can be replaced by a layer specific pipeline. This way, layer specific configurations (like optimizations or specific rendering) can be applied. When a layer does not overwrite a pipeline, the default is used. Pipelines are always selected on pipeline name. You can create the layer specific pipeline by setting the layer id for which it applied. When several pipelines have the same steps, you can define the pipeline once, and refer to it later by using a pipeline delegate instead of a list of steps.
A pipeline consists of a number of steps. A pipeline is
configured using a PipelineInfo
object which details the
pipeline id and steps. When a pipeline is started (using the
PipelineService
) it executes the pipeline steps until the
pipeline is finished (a status which can be set by one of the steps),
or until no more steps are available in the pipeline. Each step gets
two parameters.
a context which contains a map of (typed) objects which can be used to pass data between the steps (including initial parameters for the pipeline).
the result object which can be filled or transformed during the pipeline's execution.
Pipelines can be extended. When a pipeline is defined, it is possible to include hooks for extensions. These are special no-op steps. When a pipeline is defined, your can either define all the pipeline steps, or refer to a delegate pipeline combined with a map of extension steps. The pipeline will then be based on the delegate pipeline with the extensions steps added after the hooks with matching names.
The layer extensions allow determining how a layer is built, which data is part of the layer, update and creation of extra data on a layer.
A Layer
has some metadata (id, coordinate system,
label, bbox, stored in the LayerInfo
object) and allows you
get obtain the layer data.
The data which is accessed using Geomajas can be security sensitive.
Geomajas is built to be entirely independent of the authentication mechanism and the way to store policies.
Based on the user who is logged into the system, the following restrictions can apply:
access rights to a command
access rights for a layer
a filter which needs to be applied for a layer
a region which limits the data which may be accessed for a layer
access rights on the features
access rights on the individual attributes of the features
To assure the authentication mechanism is pluggable, an authentication token is used. The authentication token is used to determine the security context . The security context contains the policies which apply and which can be queried.
A list of
security services
can be defined
(using Spring bean security.SecurityInfo
). This list can
be overwritten in configuration. By default the list is empty, which
prohibits all access to everyone. The back-end does however include a
security service which can be used to allow all access to
everyone.
The security service is responsible for converting the
authentication token into a list of
authorization
objects
. The security manager will loop all configured
security services (using Spring bean
security.SecurityInfo
) to find all the authorization
objects which apply for the token. By default the security manager
will stop looping once one of the security services gave a result. You
can change this behaviour to always combine the authorization objects
from all security services.
The system explicitly allows authentication tokens to be generated by different authentication servers. In that case for each authentication server, at least one security service should be configured in Geomajas. However, when using such a configuration, you have to verify that the authentication tokens which are generated by the different servers cannot be the same.
In many systems (including RBAC systems) an authorization object matches a roles for the authenticated user.
Note that, as the actual authentication mechanisms are handled by the security services, Geomajas does not know any passwords or credentials. Similarly the secure, tamper-proof storage of policies is not handled by Geomajas either.
Details about the current authentication token and access to the
policies (using the authorization objects) is available using the
SecurityContext
. The security context is thread specific.
When threads are reused between different users, the security context
needs to be cleared at the end of a request (group). This is normally
handled by the faces.
The following general authorization checks exist:
isToolAuthorized(String toolId)
: true when the
tool can be used. The "toolId" matches the "id" parameter which is
used in the configuration as specified using the
ToolInfo
class.
isCommandAuthorized(String commandName)
: true
when the command is allowed to be called. The "commandName"
parameter is the same as the command name which is passed to the
CommandDispatcher
service.
And for each layer:
isLayerVisible(String layerId)
: true when (part
of) the layer is visible.
isLayerUpdateAuthorized(String layerId)
: true
when (some of) the visible features may be editable.
isLayerCreateAuthorized(String layerId)
: true
when there is an area in which features can be created.
isLayerDeleteAuthorized(String layerId)
: true
when (some of) the visible features may be deleted.
getVisibleArea(String layerId)
: only the area
inside the returned geometry is visible (uses layer coordinate
space). All features which fall outside the layer's MaxExtent area
are also considered not visible.
getUpdateAuthorizedArea(String layerId)
: only
the area inside the returned geometry may contain updatable
features (uses layer coordinate space). All features which fall
outside the layer's MaxExtent area are also considered not
updatable.
getCreateAuthorizedArea(String layerId)
: only
the area inside the returned geometry can new features be created
(uses layer coordinate space). All features which fall outside the
layer's MaxExtent area are also considered not creatable.
getDeleteAuthorizedArea(String layerId)
: only
the area inside the returned geometry may contain deletable
features (uses layer coordinate space). All features which fall
outside the layer's MaxExtent area are also considered not
deletable.
getFeatureFilter(String layerId)
: get an
additional filter which needs to be applied when querying the
layer's features.
isFeatureVisible(String layerId, InternalFeature
feature)
: check the visibility of a feature.
isFeatureUpdateAuthorized(String layerId,
InternalFeature feature)
: check whether a feature is
editable.
isFeatureUpdateAuthorized(String layerId,
InternalFeature oldFeature, InternalFeature newFeature)
:
check whether the update contained in the feature is allowed to be
saved.
isFeatureCreateAuthorized(String layerId,
InternalFeature feature)
: check whether a feature is
allowed to be created.
isFeatureDeleteAuthorized(String layerId,
InternalFeature feature)
: check whether deleting the
specific feature is allowed.
isAttributeReadable(String layerId, InternalFeature
feature, String attributeName)
: check the readability of an
attribute. The result can be feature specific.
isAttributeWritable(String layerId, InternalFeature
feature, String attributeName)
: check whether an attribute
is editable. The result can be feature specific.
These authorizations are split in several groups. The security service is not required to provide an implementation of each authorization test (see API), the security context always ensures that all methods are available.
Checking authentication and fetching the authorization details
can be time consuming (not to mention the hassle of logging in again).
To solve this, the results of the security services can be cached.
When a security service can authenticate a token, the reply can
contain details about the allowed caching. Three parameters are
allowed to be passed, the validUntil
and
invalidAfter
timestamps and an extendValid
duration.
The security manager first checks the cache to find (valid) authentication results. A cache entry is only valid until the "validUntil" timestamp. When an entry is valid, validUntil may be extended until "now" plus "extendValid" duration. However, "validUntil" is never extended past "invalidAfter". When no data can be found in the cache, the security services are queried.
There may be multiple authentications stored for a authentication token. When one of them becomes invalid, they are all considered invalid.
Entering credentials is never handled by Geomajas. When the authentication token cannot be verified, a security exception is thrown. It is up to the client application (the face probably) to assure that a new authentication token is created.
The authorization have two possible results. When reading or rendering, all unauthorized data should simply be filtered without warning or exception. When trying to invoke a command or to create, update or delete, any attempt which is not authorized should result in a security exception.
The security uses the approach that all access is forbidden unless is is allowed. Hence, you will always need to configure at least one security service to assure the system is usable.
The security is applied throughout Geomajas. A list of places (which is not necessarily complete) and some additional ideas for application follow.
Back-end services:
CommandDispatcher
verifies the existence of a
SecurityContext
and creates one if needed.
CommandDispatcher
verifies whether the command
is allowed to be used.
VectorLayerService:
Check layer access.
Handle the "filter" for the layer (if any).
Filter on visible area as this can increase query speed.
Post-process features filtering unreadable attributes, set update flags, remove features which are not allowed.
Commands:
configuration.Get and configuration.GetMap: layers which are invisible should be removed, tools which are not authorized should be removed, "editable" and "deletable" statusses on layers, features, attributes need to be set.
configuration.UserMaximumExtent: max extent should only consider visible features.
feature.PersistTransaction: making changes to attributes which are not editable should cause a security exception.
feature.SearchByLocation: only return visible features and readable attributes.
feature.SearchFeature: only return visible features and readable attributes.
geometry.Get: only return the geometry for visible features.
geometry.MergePolygon: no security implications.
geometry.SplitPolygon: no security implications.
render.GetRasterTiles: should only return data for visible layers, ideally post-processing the image to ensure only visible area is included (making the rest transparent).
render.GetVectorTile: should only return data for visible layers, only display visible features, only return visible features, only render visible features. When attributes need to be included, only readable attributes should be included and the "editable" flag needs to be set.
Rendering:
The individual rendering steps (especially the layer/feature
model) can use the SecurityContext
to filter the data
they produce.
Images can have areas masked which are not allowed to be seen.
The rendering pipeline can include steps which check the security. This can make life easier on the layer model which are not guaranteed (or forced) to handle all security aspects. These are active by default but can be removed for speed (when you are sure this is double work).
Cache:
The caching needs to consider the access rights when storing and retrieving data.
Face:
The face is responsible for assuring a authentication token is included in all access to the back-end.
The "get configuration" commands filter the data to assure invisible layer and attributes and tools which are not allowed are not displayed. No action needed.
Specific tests on editability of individual features and attributes would be useful to assure the user does try to enter or modify data which cannot be saved.
The face should ask for credentials again when the token was
not available or is no longer valid. Specifically when a
GeomajasSecurityException
is received which code
ExceptionCode.CREDENTIALS_MISSING_OR_INVALID
.
While this is not really touched by description above, the following system configuration issues are likely to be important when you want to secure your Geomajas application.
Make sure the communication between the client and server uses encryption, possibly by using https. This prevents snooping of your data and/or hijacking the security token.
Even if your application is using http for some reason, at the very least your authentication method should use https to prevent your passwords from being transmitted on the wire in cleartext. I would expect all authentication servers do this.
Depending on your needs, it may make sense to store the data encrypted on the server. If you want that, your need a layer model which can access your secured data (possibly passing on the security token).
Geomajas provides a basic set of functionality as part of the back-end core. This can be extended and made available using plug-ins. One of the functions of the back-end core is to act as a plug-in container. Plug-ins are optional libraries that extend the core functionality by taking advantage of the public API. There are three special types of plug-ins, faces, layers and security plug-ins. which provide extra features, faces, layers and other plu
Faces provide external interfaces for Geomajas. These give access to users or external systems to the configured data. The faces which are included in the Geomajas project are
GWT face : our recommended face for displaying and editing GIS data in the browser. This allows you to build your web user interface in Java.
dojo face : a face which allows web display and editing using dojo toolkit. The user interface needs to be developed using JavaScript.
The layer plug-ins provide access to the actual data which needs to be displayed as part of a maps. There are basically two types of layers, providing either raster data (bitmaps) or vector data. The layers which are provided as part of the normal distribution include
geomajas-layer-hibernate (vector): allow access to any kind of features which are stored in a spatial (relational) database. The data is accessed using the hibernate and hibernate-spatial open source libraries.
geomajas-layer-geotools (vector): access data from any vector data source which has a GeoTools data store defined for it (http://geotools.org/javadocs/org/geotools/data/DataStore.html).
geomajas-layer-google (raster): include Google rasters. This allows access to the normal and satellite views provided by Google. You still have to make sure you comply with Google terms of use (http://code.google.com/apis/maps/).
geomajas-layer-openstreetmap (raster): support for raster data coming from the OpenStreetMap project (http://www.openstreetmap.org/).
geomajas-layer-wms (raster): access data from a WMS server (http://www.opengeospatial.org/standards/wms).
geomajas-layer-shapeinmem (vector): access data from an ESRI shape file which handled in memory. The actual data access if done using GeoTools (http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf).
Other plug-ins allow extensions in functionality, either by providing additional commands or extending the rendering pipelines, or they provide additional security services.
geomajas-command : set of commands which are provided as part of the standard distribution. This is so fundamental to using Geomajas that it is provided as a back-end module.
geomajas-plugin-printing : printing extensions for the framework
geomajas-plugin-staticsecurity : a basic security service which can be configured as part of the Spring configuration and does not use an external source for users or policies, making the security configuration entirely static.
The back-end also contains a set of spatial services. These include services for accessing raster and vector services and a set of utility services.
The project is built from a large set of modules. A specific application can choose which modules are used or not. In principle, the back-end module are always required and at least one face and at least one layer plug-in. More plug-ins or faces can be added as needed.
Plug-ins (which include faces) are automatically discovered when available on the classpath. This is done using two files: META-INF/geomajasContext.xml and META-INF/geomajasWebContext.xml.
The geomajasContext.xml file contains information about the plug-in, the dependencies for the plug-in (which are checked when the application context is built, assuring that the set of plug-ins is complete and can be combined) and contains copyright and license information for the plug-in and its dependencies. Additional beans and services can also be defined.
The geomajasWebContext.xml file is provided to allow additional
endpoints to be added in the web tier. Geomajas normally installs a
DispatcherServlet
in the web.xml file to allow additional
web endpoints to be added using Spring MVC.
Different modules have different impacts and different purposes. Therefore different categories of modules are required. Geomajas has defined the following set of module categories (matching the directories in the source):
application: working examples of applications using the Geomajas GIS framework.
backend : these are essential Geomajas modules. Each Geomajas application needs these modules. However, you also need some a face and some plug-ins (like layers) or you won't be able to do much.
build-tools : some modules which are useful for starting or building Geomajas or a Geomajas project.
documentation : documentation modules, specifically the different Geomajas guides. These are the general guides, each of the plug-ins also has a documentation module.
face : faces that present a certain Geomajas client interface to the user.
plugin : modules that extend Geomajas. This can either add new functionality, add support for a certain type of data source, provide a security service or a combination.
test : modules which are used for (integration) testing of Geomajas.
Full list of Geomajas modules:
Name | Purpose |
---|---|
geomajas-dojo-example | Example application using the dojo face. Is more advanced than the dojo-simple demo. Can be useful as template project when starting a new dojo based Geomajas application which uses project specific JavaScript code. |
geomajas-dojo-simple | Simple example project using the dojo face. Can be a useful template project when starting a new dojo based Geomajas application. |
geomajas-gwt-example | Example application using the GWT face which serves both as showcase and test application. |
geomajas-gwt-simple | Simple example project using the GWT face. Very similar to the GWT archetype which can be used to start a new GWT based Geomajas project. |
Table 4.1. List of Geomajas application modules
Name | Purpose |
---|---|
geomajas-api | Stable interfaces. Reference guide for other modules. |
geomajas-api-experimental | Experimental interfaces. This contains some experimental stuff which may be promoted to the supported API when useful, or may be changed or dumped. As this is not part of the API, it may change between revisions. |
geomajas-command | Lists all basic commands. |
geomajas-common-servlet | Code which is shared by the different faces which are servlet based. |
geomajas-impl | Main library with default implementations. |
geomajas-testdata | Module which contains data which is used for testing Geomajas. |
Table 4.2. List of Geomajas back-end modules
Name | Purpose |
---|---|
geomajas-checkstyle | Module which contains the checkstyle definitions which should be adhered to for all code in the Geomajas source tree. |
geomajas-dep | This module can be included in your "dependencyManagement" section to set default versions for many possible dependencies. This includes the current release versions of all Geomajas project modules and their major dependencies. The versions can always be overwritten in your pom. It does not indicate that module versions play well together (though they should if the API contract is adhered). This module should never contain snapshot builds. |
geomajas-maven-dojo | Maven plugin which helps to combine all the JavaScript code for dojo, Geomajas and the project itself. This is usually referred to as the "shrink" or "shrinksafe" step. |
geomajas-maven-plugin | Maven plugin which is used for generating the documentation. It extracts excerpts from the code to allow inclusion in the docbook guides. |
geomajas-parent | parent project which includes some Geomajas specific settings like copyright, java version, checkstyle etc. |
geomajas-plugin-archetype | Archetype for starting a new plugin. |
Table 4.3. List of Geomajas build-tools modules
Name | Purpose |
---|---|
contributorguide | Guide for contributors to the project. Includes information about compilation of the project, coding style, how to contribute to the documentation, JIRA guidelines etc. |
devuserguide | Guide for developers who want to use Geomajas in their applications. |
enduserguide | Guide for end-users who use the Geomajas widgets. This guide should probably be included in the application documentation. |
style | Style module for conversion of the docbook files to usable output. |
xslt | Transformation module for conversion of the docbook files to usable output. |
Table 4.4. List of Geomajas documentation modules
Name | Purpose |
---|---|
geomajas-face-dojo | Modules for the dojo face, including documentation. |
geomajas-face-gwt | Modules for the GWT face, including the documentation. |
Table 4.5. List of Geomajas face modules
Name | Purpose |
---|---|
geomajas-layer-geotools | Support for any data format GeoTools supports. |
geomajas-layer-google | Support for GoogleMaps raster format. |
geomajas-layer-hibernate | Support for database formats through Hibernate. |
geomajas-layer-openstreetmap | Support for OpenStreetMap raster format. |
geomajas-layer-wms | Support for the WMS raster format. |
geomajas-plugin-printing | Adds printing capabilities beyond printing in the browser, by delivering the map as PDF. |
geomajas-plugin-staticsecurity | Simple security service which allows including the entire security configuration in the Spring configuration files, making the configuration static. |
geomajas-plugin-caching | Caching plug-in which allows improved speed by calculating data only once. |
Table 4.6. List of Geomajas plug-in modules
Name | Purpose |
---|---|
geomajas-test-integration | Integrations tests, currently mostly testing the security handling. |
Table 4.7. List of Geomajas test modules
Table of Contents
As Geomajas is a framework for building enterprise application, it is important to be very accurate about what exactly is considered part of the API, specifically which classes and interfaces and which methods in these classes and interfaces are considered as part of the API.
For this reason, we have introduced the "@Api
"
annotation. A class or interface is only considered part of the public
API when it is annotated using "@Api
". When all public
methods in the class or interface are considered part of the API, you
could use "@Api(allMethods = true)
". The alternative is to
annotate the individual methods.
The API includes many interfaces. These interfaces should only be
implemented by client code when they are annotated by
"@
". All other interfaces are
provided to indicate the methods available on instances which are
obtained through the API or Spring wiring and may have extra methods
added in future versions.UserImplemented
All classes and methods which are indicated with
"@Api
" should also have a "@since
" javadoc
comment indicating the version in which the class or method was added to
the API.
Please beware that only the annotations determine whether something is part of the API or not. The manual may discuss things which are not considered API, probably because they are experimental.
The full details about the API can be found in the published javadoc, available on the Geomajas site at http://www.geomajas.org/gis-documentation. There you can find the links for the different versions.
The API for the Geomajas back-end is contained in the geomajas-api module. This contains only interfaces, exceptions and data transfer objects. The data transfer objects are classes which only contain getters and setters. The back-end API is divided in the following packages:
command : interfaces, services and data transfer objects related with the command extension points.
configuration : data transfer objects which are used for defining the configuration in Geomajas.
geometry : Geomajas geometry related data transfer objects.
global : some general interfaces, annotations and exceptions which are relevant for a combination of several extension points or the entire API.
layer : interfaces, services, exceptions, data transfer objects and some internal objects related with the layers and objects in a layer. These include the definition of a layer, tiles, features and feature models.
security : interfaces, services and data transfer objects related with the security extension points and security handling.
service : utility services provided by Geomajas.
The back-end also contains a module geomajas-api-experimental. This contains some experimental stuff which may be promoted to the supported API when useful, or may be changed or dumped. As this is not part of the API, it may change between revisions.
For commands and plug-ins, the same rule applies as for the
back-end API. That means that the "@Api
" annotation
indicates the stability of the interfaces, classes and methods.
These classes can typically be found in packages containing "command.dto" for command request and response objects or packages containing "configuration" for objects which are expected to be defined from the Spring configuration files.
The command name is also considered part of the API when the
implementing class in annotated using the "@Api
"
annotation.
The GWT plug-in also uses the "@Api
" annotation to
indicate classes and methods which are supported to remain stable
between minor versions of the face.
You can expect to find this annotation on all widgets, though it is likely that not all public methods will be considered part of the API.
Versions have the structure "major.minor.revision". Geomajas uses a even-odd versioning scheme for the "minor" part.
The major number indicates major changes in the framework and thus gives no guarantee about API compatibility with previous major versions.
Versions with an even minor part are considered stable and suitable for production use. Odd minor versions are used for development to work on and test new features to be released in the next stable version. The API for Geomajas needs to be upward compatible for all stable versions with same major number. Specifically this means that
No API classes or interfaces may be removed.
No API classes or interfaces may be renamed.
No API classes or interfaces may have their package name modified.
No API methods may be removed.
No API methods may have their signature changed.
No methods may be added to classes annotated using
"@
".UserImplemented
Additionally, all methods and classes which are added should
include an indication of the version in which the class and/or method
was added. This is done using the "@since
" javadoc comment
for the methods, class or interface.
Because of the guarantees about API, the use of the
"@Deprecated
" annotation only indicates that a method or
class is not recommended to be used. The method or class will not be
removed in future versions with the same major number.
The command dispatcher is the main command execution service. It accepts commands serializable data for executing a command and returns a response which can again be serialized. It is the main entry point into the back-end for use by the faces.
The following methods are provided:
CommandResponse execute(String commandName,
CommandRequest commandRequest, String userToken, String
locale)
: given the command name, request object, user
token and locale, try to execute the requested command. The
result, including any exception which may have been thrown are
included in the returned response object.
The commands are all registered in the Spring context. The "registry key" as indicated below is used to retrieve the commands. These are services, so a singleton should be sufficient for this.
The default naming for the keys is derived from the fully qualified class name. This is automatically assigned when the command is in a (sub package of) the "command" package. To determine the bean name, all parent packages of the "command" package are removed. Then the name is simplified. It will end up having "command." as prefix, optionally followed by a package, followed by the name. As there already is a "command" prefix, the "Command" suffix is removed from the name if present. When the resulting name starts or end with the sub package, then that is removed as well. For example the "org.geomajas.command.configuration.GetConfigurationCommand" class will get "command.configuration.Get" as registry key.
CopyrightCommand | |
---|---|
Registry key | command.general.Copyright |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.EmptyCommandRequest |
Parameters | none |
Description | This allows you to obtain copyright and license information for Geomajas, it's dependencies, the plg-ins and the dependencies of the plug-ins. This can be used to display that information in a "about" box to assure the copyright and license conditions are adhered. |
Response object class | org.geomajas.command.dto.CopyrightResponse |
Response values | List of CopyrightInfo objects for the
dependencies. Any duplicates are removed based on the
copyright info key. |
Table 6.1. CopyrightCommand
GetConfigurationCommand | |
---|---|
Registry key | command.configuration.Get |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.EmptyCommandRequest |
Parameters | none |
Description | Get the client side configuration information. This returns information about all maps which have been configured. |
Response object class | org.geomajas.command.dto.GetConfigurationResponse |
Response values |
|
Table 6.2. GetConfigurationCommand
GetMapConfigurationCommand | |
---|---|
Registry key | command.configuration.GetMap |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.GetMapConfigurationRequest |
Parameters |
|
Description | Get the client side configuration information for the specified map. |
Response object class | org.geomajas.command.dto.GetMapConfigurationResponse |
Response values |
|
Table 6.3. GetMapConfigurationCommand
GetRasterTilesCommand | |
---|---|
Registry key | command.render.GetRasterTiles |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.GetRasterTilesRequest |
Parameters |
|
Description | Retrieve a set of raster tiles as image links for a given layer within a certain bounding box expressed in a certain coordinate reference system. |
Response object class | org.geomajas.command.dto.GetRasterTilesResponse |
Response values |
|
Table 6.4. GetRasterTilesCommand
GetVectorTileCommand | |
---|---|
Registry key | command.render.GetVectorTile |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.GetVectorTileRequest |
Parameters |
|
Description | Fetches a single tile for a vector layer. The tile can contain both vectors and labels. This command is used to paint vector layers in the map. |
Response object class | org.geomajas.command.dto.GetVectorTileResponse |
Response values |
|
Table 6.5. GetVectorTileCommand
LogCommand | |
---|---|
Registry key | command.general.Log |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.LogRequest |
Parameters |
|
Description | This allows you to send a statement to the server side which will be logged there. |
Response object class | org.geomajas.command.CommandResponse |
Response values | none |
Table 6.6. LogCommand
MergePolygonCommand | |
---|---|
Registry key | command.geometry.MergePolygon |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.MergePolygonRequest |
Parameters |
|
Description | This command allows the user to merge multiple polygons into a single polygon or multipolygon. |
Response object class | org.geomajas.command.dto.MergePolygonResponse |
Response values |
|
Table 6.7. MergePolygonCommand
PersistFeatureTransactionCommand | |
---|---|
Registry key | command.feature.PersistTransaction |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.PersistTransactionRequest |
Parameters |
|
Description | Persist a single transaction on the backend (create, update, delete of features). |
Response object class | org.geomajas.command.dto.PersistTransactionResponse |
Response values |
|
Table 6.8. PersistTransactionCommand
SearchAttributesCommand | |
---|---|
Registry key | command.feature.SearchAttributes |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.SearchAttributesRequest |
Parameters |
|
Description | Search for attribute possible values for a certain attribute. This command is only used for many-to-one and one-to-many relationships, to search for possible values. |
Response object class | org.geomajas.command.dto.SearchAttributesResponse |
Response values |
|
Table 6.9. SearchAttributesCommand
SearchByLocationCommand | |
---|---|
Registry key | command.feature.SearchByLocation |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.SearchByLocationRequest |
Parameters |
|
Description | This command allows you to search for features, based on geographic location. |
Response object class | org.geomajas.command.dto.SearchByLocationResponse |
Response values |
|
Table 6.10. SearchByLocationCommand
SearchFeaturesCommand | |
---|---|
Registry key | command.feature.Search |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.SearchFeatureRequest |
Parameters |
|
Description | This command allows you to search for features, based criteria which allow matching on feature attributes. You can specify multiple search criteria and a filter. |
Response object class | org.geomajas.command.dto.SearchFeatureResponse |
Response values |
|
Table 6.11. SearchFeatureCommand
SplitPolygonCommand | |
---|---|
Registry key | command.geometry.SplitPolygon |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.SplitPolygonRequest |
Parameters |
|
Description | Split up a geometry into many pieces by means of a splitting geometry. |
Response object class | org.geomajas.command.dto.SplitPolygonResponse |
Response values |
|
Table 6.12. SplitPolygonCommand
UserMaximumExtentCommand | |
---|---|
Registry key | command.configuration.UserMaximumExtent |
Module which provides this command | geomajas-command |
Request object class | org.geomajas.command.dto.UserMaximumExtentRequest |
Parameters |
|
Description | Get the bounding box of the visible features across the requested layers (visible area for the raster layers). |
Response object class | org.geomajas.command.dto.UserMaximumExtentResponse |
Response values |
|
Table 6.13. UserMaximumExtentCommand
Layers allow access to data which needs to be displayed in a map.
For the existing layers, the details about configuring you map to include that layer are included in the map configuration chapter.
All access to raster layers should be done using the raster layer service. The following methods exist
List<RasterTile> getTiles(String layerId,
CoordinateReferenceSystem crs, Envelope bounds, double scale)
throws GeomajasException
: this method allows you to obtain
the list of raster tiles which need to be displayed for the given
bounds at the requested scale.
Vector layers and the data contained within are accessible using the vector layer service. You should not try to access the layers directly. This service assures that the security constraints are adhered. Following access methods are available
void saveOrUpdate(String layerId,
CoordinateReferenceSystem crs, List<InternalFeature>
oldFeatures, List<InternalFeature> newFeatures) throws
GeomajasException
: allows creating or updating several
features. You have to pass both the old features (null or the
feature before it was modified) and the new value of the feature.
The two are at compared to determine whether to create, update or
delete.
List<InternalFeature> getFeatures(String
layerId, CoordinateReferenceSystem crs, Filter filter,
NamedStyleInfo style, int featureIncludes) throws
GeomajasException
: read all features from the layer which
match the filter. You can specify which aspects of the feature
need to be set.
List<InternalFeature> getFeatures(String
layerId, CoordinateReferenceSystem crs, Filter filter,
NamedStyleInfo style, int featureIncludes, int offset, int
maxResultSize) throws GeomajasException
: read a batch of
features from the layer which match the filter. You can specify
which aspects of the feature need to be set..
Envelope getBounds(String layerId,
CoordinateReferenceSystem crs, Filter filter) throws
GeomajasException
: get the bounds of the visible features
which match the filter. This can be useful for fit-to-page like
functionality.
List<Attribute<?>> getAttributes(String
layerId, String attributeName, Filter filter) throws
GeomajasException
: get the list of possible attribute
values.
InternalTile getTile(TileMetadata tileMetadata) throws
GeomajasException
: get a vector tile.
Geomajas has security built-in. If you don't provide a security configuration, nothing will be authorized. For unsecured access, you can add
<bean name="security.securityInfo" class="org.geomajas.security.SecurityInfo"> <property name="loopAllServices" value="false"/> <property name="securityServices"> <list> <bean class="org.geomajas.security.allowall.AllowAllSecurityService"/> </list> </property> </bean>
Example 8.1. Allow full access to everybody
which will allow all access to everybody, including full access to features which are only partly within configured bounds.
It is also possible to configure other security services, to allow authentication and authorization to be done by the services which are configured.
When configuring security services, it is important to assure that login is possible. Anything which is not explicitly allowed in not allowed, which likely includes the command which is used to login. You have to make sure that everybody can access the login command.
Specific configuration depends on the configured security services, details of which can be found in the specific plugin's documentation.
The security infrastructure makes a clear distinction between authentication and authorization.
Authentication is the act of identifying the user and user the user is how he/she says he is (whether that person is "authentic"). In Geomajas the authentication will result in a authentication token which encapsulated that a user has provided valid credentials. The token in itself does not contain either information about the user or information about what is allowed or authorized (no policies). These can however be accessed using the token.
The Geomajas back-end core does not do authentication, though it is likely that your security plug-in either provide commands to allow creation of a token (by supplying user credentials) and invalidating the token (logout), or the plug-in will stipulate where this can be done (possibly supplying a redirect to an SSO service or similar).
Authorization on the other hand reads the policies which are in effect to determine what an authenticated user if allowed or disallowed to do and/or access. Geomajas only uses policies which allow access, Everything which is not explicitly allowed is disallowed.
Based on the user who is logged into the system, the following restrictions can apply:
access rights to a command
access rights for a layer
a filter which needs to be applied for a layer
a region which limits the data which may be accessed for a layer
access rights on the features
access rights on the individual attributes of the features
You can extend this by providing additional authentication interfaces which are also implemented by the authentication object returned by your security service. Details can be found in Chapter 19, Create a security plug-in .
The security manager manages the (thread-local) security context. It delegates to the available security services to build the authentication objects and get the user information which is then stored in the in the security context. The security services themselves will check with the authentication server or service whether the token is still valid, and will get the policies from a policy server or service to populate the authentication objects with the credentials.
The SecurityManager service has the following methods:
boolean createSecurityContext(String
authenticationToken)
: create the security context for this
thread, based on the authentication token.
void clearSecurityContext()
: clear the security
context for this thread.
The security context allows access to the currently valid user's policies and some limited information (user id, name and organization). In your code, you just have to inject the security context. The face is responsible for assuring the current thread has the correct security context based on the credentials used when accessing the back-end (it will use the SecurityManager service to do that).
The security context contains all methods from the UserInfo and Authorization interfaces, plus some methods to get the current token and get the list of authentication objects which have been combined.
Pipelines are building blocks which are used in Geomajas to make certain aspects highly extend- and customizable. For more details, see the architecture Section 2.2, “Pipelines”.
The pipeline service helps you to execute a pipeline. It allows you to fetch a named pipeline which applies for a specific layer (either the layer specific pipeline or the default pipeline). It also has methods to create an empty pipeline context and execute a pipeline.
A pipeline can be defined by specifying the pipeline name and the pipeline steps.
<bean class="org.geomajas.service.pipeline.PipelineInfo"> <property name="pipelineName" value="pipelineTest"/> <property name="pipeline"> <list> <bean class="org.geomajas.internal.service.pipeline.Step1"> <property name="id" value="s1"/> </bean> <bean class="org.geomajas.internal.service.pipeline.Step2"> <property name="id" value="s2"/> </bean> <bean class="org.geomajas.internal.service.pipeline.Step3"> <property name="id" value="s3"/> </bean> </list> </property> </bean>
Example 9.1. Simple pipeline definition
A pipeline can be layer specific and can refer to a delegate (bean reference). The use of the delegate means that the pipeline definition (list of steps) is copied from the delegate.
<bean id="inter" class="org.geomajas.service.pipeline.PipelineInfo"> <property name="pipelineName" value="pipelineTest"/> <property name="layerId" value="inter"/> <property name="delegatePipeline" ref="stop" /> </bean>
Example 9.2. Layer specific pipeline which refers to a delegate
When referring to the pipeline definition using a delegate, the pipeline can also be extended by inserting additional steps at the extension hooks. You can pass a map of "extensions" which are named steps. When a extension hook of the name is found, that step will be included in the pipeline just after the hook definition.
<bean id="hooked2" class="org.geomajas.service.pipeline.PipelineInfo"> <property name="pipelineName" value="hookedTest"/> <property name="layerId" value="delegate"/> <property name="delegatePipeline" ref="hooked" /> <property name="extensions"> <map> <entry key="PreStep2"> <bean class="org.geomajas.internal.service.pipeline.Step2"> <property name="id" value="ps2"/> </bean> </entry> </map> </property> </bean>
Example 9.3. Extending a delegate pipeline
The default pipelines are detailed here. All the steps mentioned here have a hook before and after the step to allow customization of the pipeline. These hooks have the name of the step as mentioned here, with either "pre" or "post" as prefix (note that these keys are case dependent).
The Geomajas back-end core also contains a set of utility services.
This service allows you to easily access some of the configuration information.
Provided methods are:
VectorLayer getVectorLayer(String id)
: get a
vector layer based on the layer id.
RasterLayer getRasterLayer(String id)
: get a
raster layer based on the layer id.
Layer<?> getLayer(String id)
: get a layer
(can be either vector or raster), based on the layer id.
ClientMapInfo getMap(String mapId, String
applicationId)
: get the map with given id for a specific
application.
GeoServices provides a set of methods which ease the working with geometries and related objects.
CoordinateReferenceSystem getCrs(String crs) throws
LayerException
: get the CRS object based on the CRS
id.
int getSridFromCrs(String crs)
: attempts to
extract the SRID (Spatial Reference Id) from the CRS.
int getSridFromCrs(CoordinateReferenceSystem crs)
: attempts to extract the SRID (Spatial Reference Id) from the
CRS.
MathTransform
findMathTransform(CoordinateReferenceSystem sourceCrs,
CoordinateReferenceSystem targetCrs) throws GeomajasException
: get the transformation which converts between two coordinate
systems.
Geometry transform(Geometry source,
CoordinateReferenceSystem sourceCrs, CoordinateReferenceSystem
targetCrs) throws GeomajasException
: transform a geometry
from source to target CRS.
Coordinate calcDefaultLabelPosition(InternalFeature
feature)
: determine a default position for positioning the
label for a feature.
Geometry createCircle(Point center, double radius, int
nrPoints)
: get a geometry which approximates a circle (if
only a geometry could contain curves).
This service allows conversion between objects which are used internally (which may contain JTS or Geotools objects) and data transfer objects which can be used for communication with the outside world (including the faces).
There are two methods which are provided, toInternal() and toDto() and these are overloaded for many different types of objects.
FilterService allows you to build filters which can be applied when requesting vector features.
Utility functions for calculating text and font related parameters server-side. These parameters could in principle be calculated more accurately on the displaying device itself, but unfortunately there is no support for this in browser environments.
Rectangle2D getStringBounds(String text, FontStyleInfo
fontStyle)
: get the bounds for the given string.
Table of Contents
Geomajas leverages the Spring framework for configuration. The initial configuration needs to be done using web.xml. There you need to indicate the files which contain the configuration information.
In your web.xml
file, you need to assure the
configuration is made available to the application, and you can indicate
which files are used to contain the configuration. Though it is possible
to put all configuration information in one file, we recommend splitting
your configuration in several files. At least one file per application,
possibly split further per client layer configuration, and one file for
server-side configuration of each of the layers.
The listener class initialises the application context as needed
for Geomajas. It appends the context configuration locations which are
specified in the contextConfigLocation
context parameter to
the list of internal configuration locations and uses these to build the
application context. When no location is specified, the files is
searched on the class path. You can also use location prefixes as
defined by Spring. To allow use of configuration file on the web
context, use an empty location (just a colon as prefix, eg
":/WEB-INF/config.xml"). Note that whitespace is used as separator which
means that the path itself should not contain spaces.
These are defined using an excepts like the following:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> org/geomajas/dojo/simple/*.xml </param-value> </context-param> <listener> <listener-class>org.geomajas.servlet.GeomajasContextListener</listener-class> </listener>
Example 11.1. Defining spring configuration locations in web.xml
You also need to define at least the dispatcher servlet and possible an additional servlet for your faces. The dispatcher servlet can be defined as follows.
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/geomajasWebContext.xml</param-value> <description>Spring Web-MVC specific (additional) context files.</description> </init-param> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/d/*</url-pattern> </servlet-mapping>
Example 11.2. Dispatcher servlet declaration in web.xml
Each configuration file needs the following header:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
Example 11.3. Spring configuration preamble
This defines the most common schemas which are needed. The configuration is built by populating the configuration classes. The configuration classes are split up between client-side and back-end. Only the back-end classes are necessary to configure the back-end, which behaves as a catalog of layers. The client side classes are used to define applications and maps, which are purely client-side concepts in the Geomajas architecture.
The back-end classes exist in the have a class name ending in
"Info" and are mostly found in the
org.geomajas.configuration
package. These classes are
actually used to represent the DTO part of the back-end layers, thereby
allowing to transfer information or metadata of these layers to the
client.
Configuration is done using the Spring Framework. We will give some notions here, but for a full introduction to Spring, please read the reference documentation http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/.
Each configuration file can contain one or more bean definitions,
which correspond to actual Java bean instances. You can set all the
properties of the objects using this configuration file. Primitive types
can be set directly using a string representation of the value. When the
value is another bean, then it can either be defined in-line, or you can
use a reference. You can choose whether the referenced bean is defined
in the same file or a different one. As long as the bean name is unique,
and the location is added in the contextConfigLocation
context parameter in the web.xml file, the reference is resolved.
It is possible to define a bean with the same name (or id) more than once. In that case, the last occurrence will be used.
The initial bean which needs to be defined is a bean indicating the client application info .
<bean name="gwt-simple" class="org.geomajas.configuration.client.ClientApplicationInfo"> <property name="maps"> <list> <ref bean="sampleFeaturesMap" /> <ref bean="sampleOverviewMap" /> </list> </property> </bean>
Example 11.4. ClientApplicationInfo definition
As you can see, this defines the list of maps for the application. It may (optionally) also define some additional user info and a screen DPI parameter. The DPI refers to the resolution in pixels per inch of your monitor, for a PC its usually 96 (the default) or 72.
There needs to be at least one ClientApplicationInfo
bean. The bean name is used when requesting the application info.
The central configuration which needs to be done is the map and the collection of layers which are part of that map.
Raster layers are image-based layers which, depending on the type,
may be configured to retrieve their images from WMS, Google Maps or
OpenStreetMap (tile) servers. All raster layer implementations implement
the org.geomajas.layer.RasterLayer
interface, which means
they provide an accessor for a RasterLayerInfo
metadata
object. The info object configuration is normally defined in the Spring
configuration as part of the entire layer configuration. Depending on
the type of layer, extra properties are needed to provide a full
configuration.
For all raster layers, you will need to define a raster layer info object to define the back-end configuration for the layer. The exact meaning for some of the fields depend on the actual layer, but most important features include:
Name | Description |
---|---|
dataSourceName | The name of the data source as used by the layer. |
crs | The coordinate reference system, expressed as "EPSG:<srid>". Caveat: make sure this is the same as the maps' crs as full raster image reprojection is not supported! If the crs is not the same, an attempt will be done to rescale and align the center coordinates, though. |
maxExtent | The bounds of the layer, specified in layer coordinates. After transformation to map coordinates, this determines the locations and absolute size of the tiles. |
zoomLevels |
A list of scale values corresponding to the zoom levels at which the raster data should be fetched. An image or tile scale is obtained by dividing the size of the tile in pixels by the size of the tile in map units. For example, if the tile is 256 x 256 pixels and this corresponds to an area of 100 m x 100 m, the scale can be calculated as 256/100 = 2,56 pixels per meter.The inverse value of the scale is more often used and is sometimes called the resolution . Images are usually optimized or prerendered for a specific (set of) resolution(s), so it is important to specify these here if they are known. On top of that, some servers provide specific tile caching for these predefined resolutions (for example WMS-T). A word of caution concerning zoom levels : setting the zoom levels here will only make sure that tiles will be fetched at predefined levels but does not impose any restrictions on the zoom levels of the map itself. If the zoom levels of the map have different values or are not specified at all (arbitrary zooming), raster images will be stretched on the client side to accomodate for these differences. |
tileWidth | Width in pixels of the requested images. |
tileHeight | Height in pixels of the requested images. |
Table 12.1. Raster Layer info
The location of the images or tiles is defined by calculating the real width and height (based on the resolution) and "paving" the maximum extent with tiles starting at the origin (x,y) of the extent. If no resolutions are predefined, the tiles are calculated by dividing the maximum extent by successive powers of 2. Make sure the width/height ratio of the maximum extent corresponds to the width/height ratio of the tile.
Vector layers contain homogeneous vectorial features. All vector
layer implementations implement the
org.geomajas.layer.VectorLayer
interface, which means they
provide an accessor for a VectorLayerInfo
metadata object.
The info object configuration is normally defined in the Spring
configuration as part of the entire layer configuration. Depending on
the type of layer, extra properties are needed to provide a full
configuration.
The definition of the actual layer is similar to the definition of a raster layer.
For the layer configuration, you have to create the layer info object.
<bean name="airportsInfo" class="org.geomajas.configuration.VectorLayerInfo"> <property name="layerType" value="POINT" /> <property name="crs" value="EPSG:4326" /> <property name="maxExtent"> <bean class="org.geomajas.geometry.Bbox"> <property name="x" value="-87.4" /> <property name="y" value="24.3" /> <property name="width" value="8.8" /> <property name="height" value="6.4" /> </bean> </property> <property name="featureInfo" ref="airportsFeatureInfo" /> <property name="namedStyleInfos"> <list> <ref bean="airportsStyleInfo" /> </list> </property> </bean>
Example 12.1. Style info
This defines the details common to both raster and vector layers, like layer id, crs, layer type, max extent (bounding box) etc.
The following table describes the properties of the
VectorLayerInfo
object:
Property | Description |
---|---|
layerType | This property determines the type of the default geometry of the features. The following types are supported: POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING and MULTIPOLYGON |
crs | The coordinate reference system, expressed as "EPSG:<srid>". This is probably determined by the layer, but has to be specified anyhow as we have no autodetection in place yet.. |
maxExtent | The bounds of the layer, specified in layer coordinates. After transformation to map coordinates, this determines the locations and absolute size of the tiles. |
featureInfo | The feature metadata |
namedStyleInfos | The list of predefined style metadata objects which define the named styles for this layer |
Table 12.2. VectorLayer info
The feature metadata can be found in the
FeatureInfo
object. This objects contains the complete
feature type description (id, attributes and geometry) as well as the
validation rules for the attributes. An example definition of this
object is given below:
<bean class="org.geomajas.configuration.FeatureInfo" name="airportsFeatureInfo"> <property name="dataSourceName" value="airprtx020" /> <property name="identifier"> <bean class="org.geomajas.configuration.PrimitiveAttributeInfo"> <property name="label" value="Id" /> <property name="name" value="ID" /> <property name="type" value="LONG" /> </bean> </property> <property name="geometryType"> <bean class="org.geomajas.configuration.GeometryAttributeInfo"> <property name="name" value="the_geom" /> <property name="editable" value="true" /> </bean> </property> <property name="attributes"> <list> <bean class="org.geomajas.configuration.PrimitiveAttributeInfo"> <property name="label" value="Name" /> <property name="name" value="NAME" /> <property name="editable" value="true" /> <property name="identifying" value="true" /> <property name="type" value="STRING" /> </bean> <bean class="org.geomajas.configuration.PrimitiveAttributeInfo"> <property name="label" value="County" /> <property name="name" value="COUNTY" /> <property name="editable" value="true" /> <property name="identifying" value="false" /> <property name="type" value="STRING" /> </bean> </list> </property> </bean>
Example 12.2. Feature info
The following table describes the properties of the
FeatureInfo
object:
Name | Description |
---|---|
dataSourceName | This name is used by the layer to internally reference the source that provides the data. Depending on the type of layer, this could be a table name (geotools-postgis), a shape file name (geotools-shapeinmem, in this case there is a 1-to-1 correspondence withe the geotools datastore), a WFS layer name (geotools-wfs) or a java class name (hibernate). |
identifier | Metadata of the primitive attribute that provides a unique identification of the feature. |
geometryType | Metadata of the geometrical attribute that provides the default geometry of the feature. |
attributes | Metadata of all other attributes |
Table 12.3. Feature info configuration
This defines the identifier, geometry object and attributes for the feature.
Attributes can be either primitive attributes or association
attributes. Primitive attributes represent primitive Java types as
well as some common types like Date and String. The following
primitive attribute types are defined: BOOLEAN, SHORT, INTEGER, LONG,
FLOAT, DOUBLE, CURRENCY, STRING, DATE, URL and IMGURL. Association
attributes represent non-primitive Java types. There are two types of
association attributes defined: MANY_TO_ONE and ONE_TO_MANY. These
reflect the many-to-one and one-to-many relationships as defined in an
entity-relationship model and can only be used in conjunction with the
HibernateLayer
.
Last but not least, you can define one or more named style
definitions which should be used for rendering of the layer. The
actual style that is being used by the client is determined in the
client configuration, but you predefine a number of styles (of type
NamedStyleInfo
) here for later reference in the client
configuration.
Each style object is itself composed of a number of feature
styles (FeatureStyleinfo
) and a label style
(LabelStyleInfo
). You can define formulas to determine
which feature style should be used. The first style whose formula
passes will be applied for the feature.
<bean class="org.geomajas.configuration.NamedStyleInfo" name="airportsStyleInfo"> <property name="featureStyles"> <list> <bean class="org.geomajas.configuration.FeatureStyleInfo"> <property name="name" value="Airports (Florida)" /> <property name="fillColor" value="#FF3333" /> <property name="fillOpacity" value=".7" /> <property name="strokeColor" value="#333333" /> <property name="strokeOpacity" value="1" /> <property name="strokeWidth" value="1" /> <property name="symbol"> <bean class="org.geomajas.configuration.SymbolInfo"> <property name="rect"> <bean class="org.geomajas.configuration.RectInfo"> <property name="w" value="12" /> <property name="h" value="12" /> </bean> </property> </bean> </property> </bean> </list> </property> <property name="labelStyle"> <bean class="org.geomajas.configuration.LabelStyleInfo"> <property name="labelAttributeName" value="NAME" /> <property name="fontStyle"> <bean class="org.geomajas.configuration.FontStyleInfo"> <property name="color" value="#FEFEFE" /> <property name="opacity" value="1" /> </bean> </property> <property name="backgroundStyle"> <bean class="org.geomajas.configuration.FeatureStyleInfo"> <property name="fillColor" value="#888888" /> <property name="fillOpacity" value=".8" /> <property name="strokeColor" value="#CC0000" /> <property name="strokeOpacity" value=".7" /> <property name="strokeWidth" value="1" /> </bean> </property> </bean> </property> </bean>
Example 12.3. Style info
Most feature attributes should be validated before they can be saved to a file or database. Validation is a concern that stretches across many layers of a typical application: there is usually a need for client-side validation (making the application more user friendly) , server-side validation (to protect the server from invalid data) as well as database validation (to preserve data integrity). Preferably validation rules should be defined as much as possible in a single place to avoid conflicts and duplication.
Our attribute configuration supports several types of
validation by defining a "validator"
property inside
the attribute:
<property name="validator"> <bean class="org.geomajas.configuration.validation.ValidatorInfo"> <property name="toolTip" value="Is this city a capital city or not? (Y or N)" /> <property name="errorMessage" value="Invalid value: The value must be either Y or N." /> <property name="constraints"> <list> <bean class="org.geomajas.configuration.validation.NotNullConstraintInfo" /> <bean class="org.geomajas.configuration.validation.PatternConstraintInfo"> <property name="regexp" value="[YN]$" /> </bean> </list> </property> </bean> </property>
Example 12.4. Attribute validator configuration
This property contains some general validator information and a set of constraints that should be applied to the attribute. The available constraint types have been based on the new JavaBeans standard: JSR-303.
Bean layer provides an in-memory layer which is not persisted in any way. The features can be defined in the configuration file using some specialised beans. It is particularly useful for testing.
TODO.....
Name | Description |
---|---|
features | List of features, which should be
org.geomajas.layer.bean.FeatureBean
instances. |
Table 12.4. BeanLayer configuration
A map is a client side object. The Geomajas back-end works almost exclusively on layers.[1]On the client side however, these layers are combined into maps. In general, the back-end never needs to know which map the layer is displayed in when doing its work. However the back-end does need to know the coordinate reference system which is used.
<bean name="sampleFeaturesMap" class="org.geomajas.configuration.client.ClientMapInfo"> <property name="crs" value="EPSG:4326" /> <property name="displayUnitType" value="CRS" /> <property name="initialBounds"> <bean class="org.geomajas.geometry.Bbox"> <property name="x" value="-180"/> <property name="y" value="-90"/> <property name="width" value="360"/> <property name="height" value="180"/> </bean> </property> <property name="layers"> <list> <ref bean="wmsLayer" /> <ref bean="countries110mLayer" /> </list> </property>
Example 12.5. Client map configuration
The crs evidently refers to the map's coordinate reference system. The display unit type determines the unit type of the scale bar (METRIC, ENGLISH or CRS). The initial bounds determine the visible area of the map at startup time. The layers refers to the client layer info objects, not the server layer info or layer instances.
Additionally, a lot of style information can be included in the map configuration. This includes information like background colour, styles which should be used for selected points, lines and polygons and whether scale bare or pan buttons should be enabled.
<property name="backgroundColor" value="#F0F0F0" /> <property name="lineSelectStyle"> <bean class="org.geomajas.configuration.FeatureStyleInfo"> <property name="fillOpacity" value="0" /> <property name="strokeColor" value="#FF6600" /> <property name="strokeOpacity" value="1" /> </bean> </property> <property name="pointSelectStyle"> <bean class="org.geomajas.configuration.FeatureStyleInfo"> <property name="fillColor" value="#FFFF00" /> </bean> </property> <property name="polygonSelectStyle"> <bean class="org.geomajas.configuration.FeatureStyleInfo"> <property name="fillColor" value="#FFFF00" /> <property name="fillOpacity" value=".5" /> </bean> </property> <property name="scaleBarEnabled" value="true" /> <property name="panButtonsEnabled" value="true" />
Example 12.6. Client map configuration
An other important aspect of the map is the scale configuration. The scale configuration allows to define a maximum scale beyond which the user is not allowed to zoom in. This is not needed for zooming out as there is always a maximum bounds defined for the map (either explicitly or calculated as the union of the layer bounds). Next to that you can define a list of zoom levels. By default, the map will allow zooming to arbitrary scale levels but you may wish to enforce certain scale or zoom levels upon the user (like Google Maps does). By doing so, continuous zooming will no longer be possible and any zooming action will "snap" to the predefined scale levels.
<property name="scaleConfiguration"> <bean class="org.geomajas.configuration.client.ScaleConfigurationInfo"> <property name="maximumScale" value="1:1000" /> <property name="zoomLevels"> <list> <value>1:128000000</value> <value>1:64000000</value> <value>1:32000000</value> <value>1:16000000</value> <value>1:8000000</value> <value>1:4000000</value> <value>1:2000000</value> <value>1:1000000</value> <value>1:500000</value> <value>1:100000</value> <value>1:25000</value> <value>1:15000</value> <value>1:10000</value> <value>1:5000</value> <value>1:2500</value> <value>1:1000</value> </list> </property> </bean> </property>
Example 12.7. Client map configuration - scale configuration
Scales can be defined in 2 possible notations:
the 1 : x notation (see the above listing) is most commonly used in geographics and expresses the ratio between 1 meter on the screen and 1 meter on the earth's sphere
the floating point notation (e.g. 0.0001) is used by us to express the number of pixels on the screen that correspond to 1 unit on the map (1 pixel per 10000 map units in our example)
Both scale definitions serve a different purpose. The 1 : x scale should give you an idea of what the true scale is at which the map is shown, although in practice this may depend on the DPI (actually PPI) and pixel size of your device. The floating point scale (which has units of pixel/m or pixel/deegree) is used to precisely define the resolution of raster images on the screen. If you use floating point notation, you can make sure that the scales that are being used in an application are the same as those of the raster layer(s) that lies beneath (see raster layer configuration). Otherwise the raster images may get blurry or unreadable when they need to be resized.
A map typically also contains a tool bar. If you want one, you have to specify the tools it should include.
<property name="toolbar"> <bean name="sampleFeaturesMapToolbar" class="org.geomajas.configuration.client.ClientToolbarInfo"> <property name="tools"> <list> <ref bean="ZoomIn" /> <ref bean="ZoomOut" /> <ref bean="ZoomToRectangleMode" /> <ref bean="PanMode" /> <ref bean="ToolbarSeparator" /> <ref bean="ZoomPrevious" /> <ref bean="ZoomNext" /> <ref bean="ToolbarSeparator" /> <ref bean="EditMode" /> <ref bean="MeasureDistanceMode" /> <ref bean="SelectionMode" /> </list> </property> </bean> </property>
Example 12.8. Client map configuration
Obviously the tools themselves need to be defined as well. You can pass some parameters to the tools. An example tool definition look like this.
<bean name="ZoomIn" class="org.geomajas.configuration.client.ClientToolInfo"> <property name="parameters"> <list> <bean class="org.geomajas.configuration.Parameter"> <property name="name" value="delta" /> <property name="value" value="2" /> </bean> </list> </property> </bean>
Example 12.9. Tool configuration
Note that the tool id and the names of the parameters are interpreted by the client, so it is the client face which defines the possible values.
Last but not least, you can also configure the layer tree component which may be connected to the map.
<property name="layerTree"> <bean name="sampleFeaturesTree" class="org.geomajas.configuration.client.ClientLayerTreeInfo"> <property name="tools"> <list> <ref bean="LayerVisibleTool" /> <ref bean="LayerLabeledTool" /> <ref bean="ShowTableAction" /> <ref bean="LayerRefreshAction" /> </list> </property> <property name="treeNode"> <bean class="org.geomajas.configuration.client.ClientLayerTreeNodeInfo"> <property name="label" value="Layers" /> <property name="layers"> <list> <ref bean="wmsLayer" /> <ref bean="countries110mLayer" /> </list> </property> <property name="expanded" value="true" /> </bean> </property> </bean> </property> </bean>
Example 12.10. Client map configuration
This defines the tools which are available in the layer tree widget, and the tree of layers (as a node, which can contain a list of nodes etc).
Note that the layers are indicated by referring to the client configuration object.
Layer configuration is split in two (linked) parts. You have to create the actual layer which is used in the back-end, and this layer needs to know the configuration information which is also used on the client side. Secondly, there is a distinction between raster and vector layers as they each needs a lot of specific information.
[1] The only current exception is the printing command which converts maps to PDF document. Clearly this also uses the map configuration.
To make sure the system can be used, you have to configure the security to allow access. The easiest configuration is to allow access to everybody.
<bean name="security.securityInfo" class="org.geomajas.security.SecurityInfo"> <property name="loopAllServices" value="false"/> <property name="securityServices"> <list> <bean class="org.geomajas.security.allowall.AllowAllSecurityService"/> </list> </property> </bean>
Example 13.1. Allow full access to everybody
Any other configuration would depend on the available security services. For example, when using the staticsecurity plugin, the following could be defined.
<bean name="SecurityService" class="org.geomajas.plugin.staticsecurity.security.StaticSecurityService"/> <bean name="security.securityInfo" class="org.geomajas.security.SecurityInfo"> <property name="loopAllServices" value="true"/> <property name="securityServices"> <list> <ref bean="SecurityService"/> <bean class="org.geomajas.plugin.staticsecurity.security.LoginAllowedSecurityService"/> </list> </property> </bean> <bean class="org.geomajas.plugin.staticsecurity.configuration.SecurityServiceInfo"> <property name="users"> <list> <!-- User elvis has restricted attribute editing permissions on roads layer --> <bean class="org.geomajas.plugin.staticsecurity.configuration.UserInfo"> <property name="userId" value="elvis"/> <property name="password" value="BUOMyQ95onvc7gMrMjFtDQ"/> <!-- "elvis" --> <property name="userName" value="Elvis Presley"/> <property name="authorizations"> <list> <bean class="org.geomajas.plugin.staticsecurity.configuration.AttributeAuthorizationInfo"> <property name="commandsInclude"> <list> <value>.*</value> </list> </property> <property name="visibleLayersInclude"> <list> <value>.*</value> </list> </property> <property name="updateAuthorizedLayersInclude"> <list> <value>beans</value> </list> </property>
Example 13.2. Partial staticsecurity configuration
Most notable in this example is the inclusion of two security services. The first is provided to allow login and logout ( only ) for everybody. The second defines users and authorizations (only the beginning of the configuration is displayed here).
Spring has support declarative transaction management, which
relieves us from the burden of writing our own transaction demarcation and
exception handling code. Of course, Spring transaction management has to
be hooked up with the transaction definition and life cycle of the
underlying data platform (hibernate, JTA, JDBC) . Each data access
technology should provide its own implementation of the Spring class
PlatformTransactionManager
. You should check your plug-in
documentation for details about configuring the transaction
manager.
Transaction management is typically only needed for editable database layers (although we support and encourage it for read-only layers as well). There is currently no support for having multiple platform transaction managers, although configurations with multiple transaction managers should be possible. This will be investigated and fixed in the future. In practice this means that you currently must not mix editable layers which require a different transaction manager..
Geomajas uses GeoTools' gt-epsg-wkt module to define the coordinate reference systems which are available.
If you want to add extra coordinate reference systems, this can be done by defining them in the configuration. For example, Geomajas itself already defines the "EPSG:900913" crs (which one of the many codes for the Mercator projection used by Google Maps and OpenStreetMap).
<bean class="org.geomajas.global.CrsInfo"> <property name="key" value="EPSG:900913"/> <property name="crsWkt"> <value> PROJCS["Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","900913"]] </value> </property> </bean>
Example 15.1. Custom CRS addition
You can add as many of these beans as needed. The keys transformation which are added this way are tested before the GeoTools library, so you can overwrite definitions if needed.
If you don't like the dependency on the gt-epsg-wkt library, then you could exclude this dependency in your maven pom and use a different dependency if needed.
Table of Contents
A Geomajas command usually consist of three classes, the actual
command (which implements the Command
interface), and two
data transfer objects, one to pass the request parameters (extending
CommandRequest
, LayerIdCommandRequest
or
LayerIdsCommandRequest
), and one which carries the response
(extending CommandResponse
).
It is important to assure your request object extends from LayerIdCommandRequest or LayerIdsRequest when one of the parameters is the layer id (or a list thereof). This can be used by the command dispatcher to assure the layer specific (transaction) interceptors are called.
To create a new command we recommend you use a similar package structure as we used in the geomajas-extension-command module. That is to create a "command" package with under that a "dto" package which contains all the request and response objects, and to put the actual commands in sub packages based on some kind of grouping. This helps to automatically determine a sensible command name.
The basic command implementation looks like this:
package com.my.program.command.mysuper; import com.my.program.command.dto.MySuperDoItRequest; import com.my.program.command.dto.MySuperDoItResponse; import org.geomajas.command.Command; import org.slf4j.LoggerFactory; import org.slf4j.Logger; import org.springframework.stereotype.Component; /** * Simple example command. * * @author Joachim Van der Auwera */ @Component() public class MySuperDoItCommand implements Command<MySuperDoItRequest, MySuperDoItResponse> { private final Logger log = LoggerFactory.getLogger(MySuperDoItCommand.class); public MySuperDoItResponse getEmptyCommandResponse() { return new MySuperDoItResponse(); } public void execute(MySuperDoItRequest request, MySuperDoItResponse response) throws Exception { log.debug("called"); // ..... perform the actual command } }
Example 16.1. Example command template
Note the presence of the "@Component" annotation which assures the command is registered. You could add the name under which the command needs to be registered in the annotation, but when that is omitted, the default command name is derived from the fully qualified class name. In the example given here this results in command name "command.mysuper.DoIt".
The default way to determine the command name assumes there is a package named "command" in the fully qualified name of the implementing class. It will remove everything before that. It will then remove a "Command" suffix if any. Lastly, it will remove duplication between the intermediate package (between "command" and the class name) and the class name itself. Some examples:
Fully qualified class name | Command name |
---|---|
my.app.command.DoIt | command.DoIt |
my.app.command.super.DoIt | command.super.DoIt |
my.app.command.super.DoItCommand | command.super.DoIt |
my.app.command.super.SuperDoItCommand | command.super.DoIt |
my.app.command.super.DoItSuperCommand | command.super.DoIt |
my.app.command.super.CommandDoIt | command.super.CommandDoIt |
my.app.command.super.CommandSuperDoIt | command.super.CommandSuperDoIt |
my.app.command.super.CommandDoItSuper | command.super.CommandDoIt |
Table 16.1. Samples of command name resolution
You have to include a line in your Spring configuration to scan class files for annotation to make the components available. For the case above, this could be done by including the following XML fragment in one of your Spring configuration files.
<context:component-scan base-package="com.my.program" name-generator="org.geomajas.spring.GeomajasBeanNameGenerator" />
Example 16.2. Scan to assure command is available
The command will be executed using a singleton. The use of object variables is not recommended. Any object variables will be shared amongst all command invocation, which can be coming from multiple threads at the same time.
Note that it is not mandatory to create your own request and
response object classes. If you don't require any parameters you can use
EmptyCommandRequest
as request class. If you only require a
layer id, then use LayerIdCommandRequest
. If you only return
a success code, you could use the SuccessCommandResponse
class.
You have to take care that all objects which are referenced by your
request and response objects are actually serializable for the faces in
which the commands need to be used. For the dojo face this may require the
use of the "@Json
" annotation to exclude fields. For GWT you
have to assure the no-arguments constructor exists and that the class can
be compiled by GWT (no Hibernate enhanced classes, no use of
"super.clone()
",...).
When the commands are included in a separate module, you should assure the sources are available as these are needed for GWT compilation. This can easily be done using the Maven source plugin.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.2</version> <executions> <execution> <goals> <goal>jar</goal> </goals> <configuration> <includePom>true</includePom> </configuration> </execution> </executions> </plugin>
Example 16.3. Maven source plugin
Actually including the sources can then be done using a dependency like the following (this includes the staticsecurity module, both the actual code and the sources). You could set "provided" scope on the source dependency to exclude it from the war file. However, this may prevent use of GWT development mode.
<dependency> <groupId>org.geomajas.plugin</groupId> <artifactId>geomajas-plugin-staticsecurity</artifactId> <version>${geomajas-plugin-staticsecurity-version}</version> </dependency> <dependency> <groupId>org.geomajas.plugin</groupId> <artifactId>geomajas-plugin-staticsecurity</artifactId> <version>${geomajas-plugin-staticsecurity-version}</version> <classifier>sources</classifier> </dependency> <dependency> <groupId>org.geomajas.plugin</groupId> <artifactId>geomajas-plugin-staticsecurity-gwt</artifactId> <version>${geomajas-plugin-staticsecurity-version}</version> </dependency> <dependency> <groupId>org.geomajas.plugin</groupId> <artifactId>geomajas-plugin-staticsecurity-gwt</artifactId> <version>${geomajas-plugin-staticsecurity-version}</version> <classifier>sources</classifier> </dependency>
Example 16.4. staticsecurity source plugin - including source
The general procedure for creating a new plug-in is described here. Additional information for specific types of plug-ins is described in subsequent chapters.
Layers allow access to data which needs to be displayed in a map.
For the existing layers, the details about configuring you map to include that layer are included in the configuration section above.
Table of Contents
ApplicationContextUtils
has been renamed to
ApplicationContextUtil
and is now included in the api
(this was done to adhere to the coding style).
When building the dojo face and the dojo-example application, the maven "-Pnoshrink" has been replaced by "-DskipSkhrink".
The use of the dispatcher servlet was introduced in 1.7.1. It is strongly recommended that you include it in your web.xml file to assure all plug-ins which expect this can function.
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/geomajasWebContext.xml</param-value> <description>Spring Web-MVC specific (additional) context files.</description> </init-param> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/d/*</url-pattern> </servlet-mapping>
the "springsecurity" module has be renamed "staticsecurity" to more correctly address the nature of the plug-in and and to avoid possible confusion with Spring's security stuff. Additionally the old module has been split in two, one part being the back-end/configuration module, and another the gwt module.
Many of the layers contain a bug in the 1.6.0 version assuming that injected services are fully initialised (and thus usable) while building the application context. Because of changes in the implementation of some services, these bugs become visible when using the 1.7 backe-end. You have to update your layers as well to 1.7+ to avoid these problems.
The gwt-client module no longer automatically adds the "nl" locale to the application. This should now be done by the application. You can do this by adding the line
<extend-property name="locale" values="nl"/>
to your gwt.xml file.
In the GWT face, you should now use MapContext
instead of directly accessing GraphicsContext
.
RasterLayer.paint()
now throws
GeomajasException
instead of
RenderException
. The RenderException
class has been moved to api-experimental.
LocaleSelect
now needs a parameter in the
constructor. This parameter is the name of the default
language.
The OpenStreetMap layer changes changed groupId from "geomajas-layer-opentreetmaps" to "geomajas-layer-opentreetmap".
GeomajasSecurityException
has moved from
"org.geomajas.global
" to
"org.geomajas.security
".
AllowAllSecurityService
has moved from
"org.geomajas.internal.security
" to
"org.geomajas.security.allowall
".
VectorLayerService
and
RasterLayerService
have moved from
"org.geomajas.service
" to
"org.geomajas.layer
".
In LabelStyleInfo
the style for the font is now
of type FontStyleInfo
.
LayerIdsCommandRequest
has been introduced and
this is now extended by SearchByLocationRequest
(no
change) and UserMaximumExtentRequest
(changing
includeLayers
to layerIds
).
SuccessCommandResponse class contained typos. The methods
isSucces()
and getSucces()
have been
renamed to isSuccess()
and getSuccess()
respectively.
Changes in pipeline and promotion to stable API.
The method getRasterLayer()
has been added in
ConfigurationService
.
The findMathTransform()
method in
GeoService
now throws GeomajasException
instead of FactoryException
.
InternalTile changes (should not affect anybody as these are used internally in the back-end).
Many DtoConverterService
methods now throw
GeomajasException
.
The method getId()
has been added to
Layer.
All server layers should have a unique id. The
id is automatically assigned based on the Spring bean name.
Configuration changes: maxTileLevel
has been
removed as this was not used.
Configuration changes: the server-side layers are no longer connected to the client-side layer configurations via the layerInfo objects. Instead, client-side layers refer directly to the server layer's id via a serverLayerId property. The references to the layerinfo objects are injected by a configuration postprocessor, so the layerInfo should no longer be set manually.
Name | Property | Description |
---|---|---|
LayerInfo | id | Removed, use id property of Layer instead |
SnappingRuleInfo | layerInfo | Replaced with serverLayerId |
serverLayerId | String ,should refer to id of Layer bean |
Table A.1. Back end configuration changes
Name | Property | Description |
---|---|---|
ClientLayerInfo | serverLayerId | String, should refer to id of Layer bean |
layerInfo | Should no longer be set manually, will be set by Spring |
Table A.2. Client configuration changes
The LayerModel
class has been integrated in
VectorLayer
. This modifies the configuration. Where
before you would have written
<bean name="countriesModel" class="org.geomajas.layermodel.shapeinmem.ShapeInMemLayer"> <property name="url" value="classpath:shapes/africa/country.shp"/> </bean> <bean name="countries" class="org.geomajas.internal.layer.layertree.DefaultVectorLayer" > <property name="layerInfo" ref="countriesInfo" /> <property name="layerModel" ref="countriesModel" /> </bean>
into
<bean name="countries" class="org.geomajas.layer.shapeinmem.ShapeInMemLayer"> <property name="layerInfo" ref="countriesInfo" /> <property name="url" value="classpath:shapes/africa/country.shp"/> </bean>
Note that this includes changing "layermodel" to "layer" in all module and package names.
FeaturePainter
interface and related stuff has
been removed. These are obsolete with the introduction of the
VectorLayerService
.
GeotoolsLayer
has been renamed
GeoToolsLayer
.
With the change in directory structure, the commands have
moved from the org.geomajas.extension.command
package
to org.geomajas.command
. The LogCommand
has also been moved into the general
sub-package.
Security constraints are now applied in Geomajas. By default, nothing is authorized, so you always have to configure at least one security service. To go back to the old (allow-all) behaviour, include the following excerpt in your configuration file.
<bean name="security.securityInfo" class="org.geomajas.security.SecurityInfo"> <property name="loopAllServices" value="false"/> <property name="securityServices"> <list> <bean class="org.geomajas.security.allowall.AllowAllSecurityService"/> </list> </property> </bean>
Layers are now more sensitive to the attributes which are
defined for the layer. Attributes which have not been defined in the
feature info are not accessible this is the result of the
refactoring where the InternalFeature
store attributes
as Attribute
objects).
The geomajas-API has been split up in a formal (geomajas-API) and experimental API (geomajas-api-experimental). All interfaces/classes from the cache and rendering packages have been moved to experimental. This means that the rendering pipeline is at the moment not a part of the official API, but instead more of a preview of what's to come. Furthermore, some major changes have been made in many other packages:
The org.geomajas.rendering.tile
has been moved
to org.geomajas.layer.tile
Introduction of a DtoConverterService that is able to convert DTO objects from and to back-end internal representations.
All the different feature definitions have been cut down.
Only 2 versions remain at the moment: a DTO feature
(org.geomajas.layer.feature.Feature
) and a feature
definition used internally in the backed
(org.geomajas.layer.feature.InternalFeature
).
All the different tile definitions have been cut down. Only
3 remain. 2 DTO tiles:
org.geomajas.layer.tile.VectorTile
- used in vector
layers and org.geomajas.layer.tile.RasterTile
- used
in raster layers. The third is the
org.geomajas.tile.InternalTile
. This tile is used
internally on the back-end.
GeometricAttributeInfo
has been renamed to
GeometryAttributeInfo
.
ApplicationService
has been renamed to
ConfigurationService
.
The configuration API has been split up in a back-end part and a client (or faces) part. The following general rules have been kept in mind:
Back-end configuration should be restricted to those properties that are functionally needed on the back-end. We essentially regard the back-end as a container of layers or, in WFS terms, feature types. Higher level concepts like map or application should be dealt with at the client (or faces) level.
Client configuration should not impact the back-end state. In the near future, this will make it possible to reconfigure clients without restarting the server.
The configuration API has profoundly changed. Where
possible, the back-end classes have retained their original (before
the split) names, after pruning them to remove all client related
information. The client classes have been mostly created from scratch
and have been named ClientXxxInfo.java
for consistency.
They have been located in a separate package, called
org.geomajas.configuration.client.
The following table
gives a top-down overview of the back-end configuration classes (new
classes and properties have been marked in
bold
):
Name | Property | Action or description |
---|---|---|
ApplicationInfo | * | removed |
LayerInfo | label | moved to ClientLayerInfo |
visible | moved to ClientLayerInfo | |
viewScaleMin, viewScaleMax | moved to ClientLayerInfo | |
VectorLayerInfo | labelAttribute | moved to LabelStyleInfo |
snappingRules | moved to ClientVectorLayerInfo | |
styleDefinitions | replaced by namedStyleInfos | |
creatable, updatable, deletable | moved to ClientVectorLayerInfo (automatically assigned) | |
namedStyleInfos | list of NamedStyleInfo. Lists the predefined styles available for this layer. Multiple styles are possible so clients can choose a style | |
RasterLayerInfo | style | moved to ClientRasterLayerInfo |
NamedStyleInfo | featureStyles | list of FeatureStyleInfo. Ordered list of style definitions with applicable filters. Together with the label style they define a single named layer style. |
labelStyleInfo | label attribute name and style | |
FeatureStyleInfo | * | replaces StyleInfo same properties except for index |
index | replaces id (automatically assigned) | |
LabelStyleInfo | * | replaces LabelAttribute, same properties |
ValidatorInfo and XxxConstraintInfo | * | moved to package
org.geomajas.configuration.validation
|
Table A.3. Back end configuration changes
The most important changes are:
The removal of client-side properties like visible, label, viewScaleMin, viewScaleMax, style and snapping rules. These are moved to the client configuration (see hereafter).
The replacement of the single style definition list by a set of named styles. These are styles that are preconfigured in the back end.
Inclusion of the label attribute name and style as part of the named style. This is more logical and in line with the SLD (Styled Layer Descriptor) specification.
The client or face classes are largely new and have been
relocated to the org.geomajas.configuration.client
package. The following table gives a top-down overview of the back-end
configuration classes (new classes and properties have been marked in
bold
):
Name | Property | Action or description |
---|---|---|
ClientApplicationInfo | name | removed |
ClientMapInfo | maxBounds | replaces MapInfo, optional maximum extent of the map, if present it will be used instead of the union of the layers' maximum extent |
ClientLayerInfo | label | moved from LayerInfo |
visible | moved from LayerInfo | |
viewScaleMin, viewScaleMax | moved from LayerInfo | |
layerInfo | reference to back-end LayerInfo | |
maxExtent | transformed extent from back-end | |
ClientVectorLayerInfo | snappingRules | moved from VectorLayerInfo |
namedStyleInfo | The style to apply on the layer. Should be a reference to one of the back-end layer's predefined styles (see VectorLayerInfo). | |
creatable, updatable, deletable | moved from VectorLayerInfo | |
featureInfo | optional replacement of the back-end layer's FeatureInfo. If present, it is used instead. | |
ClientRasterLayerInfo | style | moved from ClientRasterLayerInfo |
ClientLayerTreeInfo | * | rename of LayerTreeInfo, same properties |
ClientLayerTreeNodeInfo | * | rename of LayerTreeNodeInfo |
layers | list of ClientLayerInfo objects, replaces previous list of layer ids | |
expanded | changed from string to boolean | |
ClientToolbarInfo | * | rename of ToolbarInfo |
ClientToolInfo | * | rename of ToolInfo |
Table A.4. Client configuration
Apart from these changes in content, some general technical improvements have been made as well:
The Spring bean name (or id) is used to set the id property
of the class if there is one. This makes it unnecessary to define
the id separately. The way this is done is by using a Spring
BeanPostProcessor
. (see
org.geomajas.internal.configuration.ConfigurationBeanPostProcessor
)
Some calculations that were previously done in the
GetConfigurationCommand
are now done in the
ConfigurationBeanPostProcessor.
Cloning of the client configuration classes can be done with general deep cloning techniques like serialization, bypassing the need for custom cloneable implementations.
As usual, example configurations can be found in the application projects.
"layerRef" is renamed to "layerIds" in
LayerTreeNodeInfo
.
Configuration has changed from the proprietary format to using Spring configuration.
There is now a CommandDispatcher
service and
official command names and defined request and response objects.
Deprecated commands have been removed.
In your application.xml, you should change "OSMLayerFactory" to "OsmLayerFactory"
In your application.xml, you should change "WMSLayerFactory" to "WmsLayerFactory"
replace package "layermodels" with "layermodel"
replace "org.geomajas.core.application.DefaultLayerFactory" with "org.geomajas.internal.application.DefaultLayerFactory"
mapWidget.addController() and mapWidget.removeController() have been removed. They are replaced by mapWidget.setController(). You could only add one controller anyway.