In short, it provides much easier configuration of the backend infrastructure and services you want to expose to the client and it integrates perfectly with the Spring application contexts and the Spring programming model in general.
To import a binary module, right-click on the target package in the Project Browser and select the Code Engineering | Import Binary Module context menu option
note: the file dialog that opens after selecting 'import binary module' opens with filtering for .net binaries, so .jars won't be visible. change filter to .jar and happy happy
CDI managed beans. The @EJB annotation is removed and @Inject is used instead
Annotating the boundary (Cart) with the @Named annotation makes the Cart immediately visible for expression language (EL) expressions in JSP and JSF
@Named annotation takes the simple name of the annotated class, puts the first character in lowercase, and exposes it directly to the JSF pages (or JSP). The Cart bean can be accessed directly, without any backed or managed beans, by the JSF pages: <h:commandButton value="Check out!" action="#{cart.checkout}" />
If there is a need for abstraction, the class can be turned into an interface (or abstract class)
local implementation (with CDI events
@Inject
Event<String> event;
event.fire("Order proceeded!");
remote implementation:
javax.enterprise.event.Event belongs to the CDI-implementation
class Event can be considered to be a lightweight alternative to the java.beans.PropertyChangeSupport class
@Inject
Event<String> event;
event.fire("Order proceeded!");
event can be received by any managed bean and also by EJB beans
provide a method with a single @Observes annotated parameter
@Observes String event
there is no real event, just the payload:
The during attribute in the @Observes annotation allows you to select in which transactional phase the event gets delivered. The default setting is IN_PROGRESS, which causes an immediate event delivery regardless of the transaction outcome. The AFTER_SUCCESS configuration causes the delivery to occur only after successful transaction completion
Although CDI events work only inside a single process (in the default case, CDI is extensible), they are perfectly suitable for decoupling packages from modules
The method checkout() starts a transaction that gets "reused" by the OrderSystem and CustomerNotification session beans
It is also possible to define serverName, serverPort and the url mappings for Granite AMF remoting and for Gravity push graniteUrlMapping and gravityUrlMapping.
It's even possible to use the Tide framework if you don't use GraniteDS as the AMF remoting provider by initializing the application with the singleton Tide.
Client-side setup for remoting
initialize manually the Flex remoting channels that will be used by Tide
use the DefaultServiceInitializer component
of course don't forget to change the context root to your web app path
always have to include this library in either
WEB-INF/lib
support for CDI is included in the library granite-cdi.jar
10.1. Configuration with Servlet 3
On Servlet 3 compliant containers, GraniteDS can use the new APIs to automatically register its own servlets and filters and thus does not need any
particular configuration in web.xml. This automatic setup is triggered when GraniteDS finds a class annotated with
@FlexFilter in one of the application archives:
@FlexFilter declaration will setup an AMF processor for the specified url pattern
tideAnnotations
defines suitable default values
@TideEnabled
@RemoteDestination
always declared by default
tideInterfaces
tideRoles
exceptionConverters
amf3MessageInterceptor
10.3.2. Typesafe Remoting with Dependency Injection
It is possible to benefit from even more type safety by using the annotation [Inject] instead of In.
When using this annotation, the full class name is used to find the target bean in the CDI context instead of the bean name.
Security
integration between the client RemoteObject
credentials and the server-side container security
client-side component named
identity
API to define runtime authorization checks on the Flex UI
possible to define common handlers for particular fault codes on the client-side, and exception converters on the server-side, to convert server exceptions to common fault codes
* instead of *wrapping* the server-side exception and rethrowing it to the client,
** extract only details relevant to the client (eg. include: human-friendly error message and any helpful parametrized data, exclude: stack traces),
** "wrap" it in a generic ServiceException, which gets "thrown" remotely to the client
* client can check ServiceException.getCode() to implement behavior tailored to server-side exception 'type'
Especially in the context of pagination, where the data is mostly retrieved for read-only purposes, database views are the easier and more efficient alternative. Instead of implementing a lot of plumbing on the “Java-side” all the work could be easily done in the database
GDS/Tide project represents the Data Services part of GDS
comparable to LiveCycle Data Services, which is neither open source nor free, as it provides similar features such as client container of managed entities, data paging, and integration with server components, but it is based on completely different principles:
All managed entity instances are unique in a Tide context
Tide keeps the classic three layers web architecture, when LCDS removes the service layer, and is some kind of remote JPA provider for Flex applications
Tide approach is to minimize the amount of code needed to make things work between the client and the server
principles are very similar to the ones of JBoss Seam, which is the main reason why the first integration of Tide has been done with this framework. Integrations with Spring, EJB 3 and CDI are also available
need to compile your MXML/AS sources with the granite-essentials.swc and granite.swc libraries
An implementation of this interface must be thread safe
If authorization fails, either because the user is not logged in or because it doesn't have required rights, it must throw an appropriate
org.granite.messaging.service.security.SecurityServiceException.
Writing a Security Service
SecurityService interface
nothing to do with a true Flex destination
only one instance of this service is used in the entire web-app
and will be called by concurrent threads
configure
login
This method is called upon each and every service method call invocations (RemoteObject)
or subscribe/publish actions (Consumer/Producer). When used with RemoteObjects,
the authorize method is responsible for checking security, calling the service method, and returning the corresponding result.
authorize
logout
handleSecurityException
default implementation of this method in AbstractSecurityService is to do nothing
security services
are not exposed to outside calls
Seam Security is built around the premise of users being granted roles and/or permissions, allowing them to
perform operations that may not otherwise be permissible for users without the necessary security privileges
15.6.1.1. What is a role?
A role is a group, or type, of user that may have been granted certain
privileges for performing one or more specific actions within an application
used to create logical groups of users for the convenient assignment of specific application privileges
15.6.1.2. What is a permission?
A permission is a privilege (sometimes once-off) for performing a single, specific action. It is entirely possible to
build an application using nothing but permissions, however roles offer a higher level of convenience when granting
privileges to groups of users
consisting of three
"aspects";
a target
an action
a recipient
An empty @Restrict implies a permission check of componentName:methodName
implied permission required to call the delete() method is
account:delete
equivalent of this would be to write
@Restrict("#{s:hasPermission('account','delete')}")
@Restrict annotation may reference any objects that
exist within a Seam context. This is extremely useful when performing permission checks for a specific
object instance.
selectedAccount
selectedAccount
Identity.instance().checkRestriction
If the expression specified doesn't evaluate to true, either
if the user is not logged in, a NotLoggedInException
exception is thrown or
if the user is logged in, an AuthorizationException
exception is thrown.