Sakai Fall 2008 Sakai Student Survey Based on 100 responses.
Developing Sakai Services and Tools
description
Transcript of Developing Sakai Services and Tools
Page 1
Developing Sakai Services and Tools
Mark J. Norton
Senior Technical Consultant
The Sakai Project
Page 2
Overview
• General Information
• Creating APIs
• Implementing Service
• Writing Tools
• Framework Considerations
• Development Example
• Coming Attractions – Framework 2
Page 3
Building Tools with a Framework
Page 4
The Sakai Framework
• Architecture overview– Sakai has a simple, layered architecture.
• The Sakai framework– Common services are part of the framework– JSF, Spring, Context, Hibernate
Page 5
Sakai Architecture
• Descriptions of the Sakai Architecture are being collected into a set of documents
• The Tool Portability Profile defines how to write Sakai tools and is being updated
• The architecture is intended to promote tool portability and data interoperability
Page 6
Abstract Sakai Architecture
System
Client
Sak
ai F
ram
ewor
kAggregator
Presentation
Tool
Services
The aggregator combines content from various sources into a single user interface experience.
The presentation layer allows the user interface to be described separately from the tool code.
The tool handles events and adjusts data for presentation back to the user/client
Services provide abstract capabilities for application logic and common support functions.
The system includes Tomcat, the webserver, file system, databases, etc..
Page 7
Sakai Design Patterns
• Separation of Tool Logic and UI– Velocity and JSF separate UI representation.
• Service Injection– Spring and JSF inject services as needed.
• Model – View – Controller– JSF
• Object persistence via ORM– Legacy uses XML fragments, later we use Hibernate.
• Coding to APIs– Sakai APIs and OKI OSIDs. Look for
the PatternSymbol
Page 8
Sakai Framework Technology
• Hibernate for object persistence
• Sakai APIs that imitate OKI OSIDs
• Tools are based on APIs and servlets
• JavaServer Faces separate out the presentation from tool logic
• uPortal integrates tools at the UI level
Page 9
Velocity or JSF
Spring
ComponentManager
JetspeedPortal
iFrame BasedPortal
CommonServices
Apache &Tomcat
ApplicationServices
Tool
The Sakai 1 FrameworkBrowser
injection
injection
rendering
response and request
Page 10
The Sakai Module
• A Sakai module consists of:– A tool.– Application services.– Implementations of those services.
TheTool
Service Interface A Service Interface B
Implementation of A Implementation of B
CommonServices
Page 11
Design Methodology
• Consider the users needs first.
• Develop the user interface (prototyping).
• Next consider your application services.
• Develop their interfaces.
• Implement them as components.
• Write the tool to connect UI to services.
Page 12
Development Considerations
• User interface design is critical, but out of scope for this workshop. Have a close look at the Sakai Style Guide and consider user centric design approaches.
• Let’s take a close look at what goes into an application service interface and implementation.
• Then we’ll explore tool development.
Page 13
Application Service Interfaces
Page 14
Application Service Interfaces
• What is a Sakai Service?
• What is available?
• Common practices
• Definitions
InterfaceDesignPattern
Page 15
Sakai Services - Definition
• A Sakai Service is a collection of classes defined by an interface that provides an integrated set of functionality.– Roughly split between application and
common services.– Tools call on services for the functions they
provide.– Services may depend on other services.– Services are portable, modular, and reusable.
Page 16
Two Kinds of Interfaces
• Sakai APIs– Older legacy services and newer common
services.– Sakai APIs are designed to make it easy to
create powerful Sakai tools
• OKI OSIDs– Focused on access to data.– OKI OSIDs are designed to maximize tool
portability to environments other than Sakai.
Page 17
OSIDs and APIs
• Sakai has interface requirements above and beyond the OKI OSIDs
• There is no way to cleanly extend the OKI OSIDs
• Therefore, Sakai is creating a set of APIs that correspond as closely as possible to the OSIDs, but extend them in various ways.
• The OSIDs are covers over the Sakai services.
Page 18
Sakai APIs
• Make tool development easier
• Promote portability between Sakai environments
• Hide some data management details
• Simplify Error handling
• Provide re-usable system and application services to tool developers
Page 19
Example – API vs. OSID
OSID Adaptor Component
Org.sakaiproject.common.component.agent.Agent
Org.sakaiproject.common.service.Agent
Org.osid.agent.Agent Interface
Implementation
Page 20
The OKI Agent OSID
package org.osid.agent;
public interface Agent extends java.io.Serializable { public String getDisplayName() throws osid.shared.SharedException; public osid.shared.Id getId() throws osid.shared.SharedException; public osid.shared.Type getType() throws osid.shared.SharedException; public PropertiesIterator getProperties() throws osid.shared.SharedException; Properties getPropertiesByType(Type propertiesType) throws osid.shared.SharedException; public TypeIterator getPropertiesTypes() throws osid.shared.SharedException;}
Serializable
Access only
Exceptions
OKI Interators
Page 21
The Sakai Agent APIpackage org.sakaiproject.service.common.agent;
public interface Agent { public String getDisplayName(); public void setDisplayName(String displayName); public Long getId(); public String getReferenceName(); public void setReferenceName(String referenceName); public Type getType(); public void setType(Type type); public String getUuid(); public void setUuid(String uuid); public Integer getVersion(); public Node getNode(); public void setNode(Node node); public String getAlias(); public void setAlias(String alias);}
Same name
POJO style
Java GUIDs
Sakai features
Page 22
Which Interface Should I Use?
• Use the Sakai APIs:– To develop Sakai tools– To access Sakai service features
• Use the OKI OSIDs:– For maximum tool portability– When data modification isn’t relevant
Page 23
Sakai API Guidelines• Include convenience methods and
objects built on OKI methods (e.g. equals())
• Include Java-oriented methods which directly relate to underlying OKI language-neutral equivalents (e.g. Calendar)
• Include Java-oriented methods which tie more directly to the Sakai framework, increasing performance at the expense of portability to non-Sakai environments.
• Extend beyond the OSIDs to allow explicit exposure of out of band agreements
• Extend beyond the OSIDs to allow for easy/simple/natural support of use-cases not directly supported by current OSID specifications
• Methods should be evaluated carefully for what exceptions are thrown
• Java-based exception classes and subclasses are used for the exceptions thrown
• Consider using exceptions which are subclasses of RuntimeException: A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.
• Implementations of the APIs may be java beans: therefore the APIs use set/get in a bean-compatible way
• Methods may use/return Java-native objects/interfaces, e.g. Calendar, io.stream
• The term 'properties' is used for consistency with OKI, but the Java interface used for this is a Map
• Sakai iterators extend java.util.Iterator
Page 24
Including Services in a Module
• The service APIs associated with a Sakai module should be contained in a sub-directory of the module (called service).
• Service APIs are deployed to the shared lib directory of Tomcat via Maven.
• Services are registered with the Sakai Component Manager to make them available to the tool (and other services).
Page 25
Implementing Components
Page 26
Service Implementations
• Further design considerations
• Writing an application service
• Using Common Services
• Injecting dependent services
• Persistence – hibernate
Page 27
OKI Application OSIDs
• There are a few OKI application level OSIDs:– Repository, Grading, Course Management, and
Assessment. All of these are being developed.
• If your application is closely based on these service use the existing implementations if possible.
• If you need to create a new implementation, use the OKI OSID 2.0 interface definitions and have a close look at other implementations.
Page 28
Application Service Design
• Follow the best practices exhibited in other services, for example use a Manager class to create and access service objects.
• Give careful thought to the classes included in the service.
• Non-OSID services don’t need an OSID style cover interface.
Page 29
Application Service Characteristics
• Calls common services via injection.
• Deals with objects reflected in a user interface.
• Defines a process or workflow.
• Might be tied to an app or tool.
• Designed to be generally usable in many tools (repository service, for example).
Page 30
Migrating a Legacy Service
• Migration of legacy services will be handled by the core Sakai development team, in general.
• Since legacy tools are closely tied to these services, service migration must be coordinated with tool migration.
• Talk to Mark or Chuck before doing anything!
Page 31
Creating a Brand New Service
• Define the Interface based on Sakai service best practices.
• Use the TPP for guidelines.
• Define data modules and definitions.
• Use Hibernate for object persistence.
• Write a test harness application (or unit tests).
• Submit the new service for evaluation and release.
Page 32
Creating an Application Service
• Check to see if anyone has already created something similar to this service.
• Define the interface based on Sakai best practices.
• Use the TPP for guidelines.• Define data modules and definitions.• Use Hibernate for object persistence.• Write a test harness application (or unit tests).• Submit the new service for evaluation and
release.
Page 33
Using Common Services
Page 34
Dependency Injection
• Bean style access and setters
• Inserted at runtime by the Spring container
• Dependencies are defined in XML configuration files, as appropriate.
• This is one of the standard design patterns described further in the TPP document.
InjectionDesignPattern
Page 35
Object Persistence
• Hibernate provides ORM support.• Objects are persisted to a database.• Hibernate handles atomic Java data types,
POJOs, collections, and complex objects.• HQL allows selective object retrieval which
can be optimized by DBAs.• Support for transactions, locking,
clustering, and multi-stage caching.
ORMDesignPattern
Page 36
Data Models• Standards
– Use existing industry standards where available.
• Data Elements– Design and document your data elements and
organization.
• Access Model– Use object persistence. Avoid DB dependencies.
• Interchange – consider data migration needs.
Page 37
Generic vs. Custom Repositories
• Sakai will provide a generic repository
• It will provide basic file management, access control, and metadata support.
• You may have special needs which require a custom repository.
• Capabilities can be layered on the Sakai Repository or you can build one from scratch.
Page 38
Example: Presentation Service
• The presentation service manages three objects:
PresentationManager
Presentation
Show
Slide
Page 39
The Slide Class
• A simple POJO containing the following data elements:– URL– Display Name– Content– Type (MIME type)
Page 40
The Slide Interface
package org.sakaiproject.service.presentation;
public interface Slide extends java.io.Serializable {
public String getUrl();public void setUrl(String url);public Serializable getContent();public void setContent(Serializable content);public String getDisplayName();public void setDisplayName(String name);public String getType();public void setType(String type);
}
Page 41
Notes on the Slide Interface
• A POJO interface allows easy access via Spring, Hibernate, and JavaServer Faces.
• URLs are represented by strings here, but they could be Java URLs classes as well.
• Content type is managed by using a Type object as a MIME type, similar to the OKI Filing OSID.
Page 42
The Presentation Class
• The Presentation class is a structured collection of slides:– Identifier– Title and Author properties– Slide set– Wait slide
Page 43
The Presentation APIpublic interface Presentation extends java.io.Serializable {
public static final String PRESENTATION_TITLE = "org.sakaiproject.tools.presentation.title";
public Id getId();public void setId (Id id);public String getTitle ();public void setTitle (String title);public String getAuthor ();public void setAuthor (String author);public List getSlides();public Slide getSlide (int offset);public void addSlide(Slide slide);public int getSlideCount();public void deleteSlide (int position);public void insertSlide(int position, Slide slide);public Slide getWaitSlide();public void setWaitSlide(Slide waitSlide);
}
Page 44
Notes on the Presentation API
• Convenience methods provided for easy access to title and author properties.
• Access to a List object instead of an iterator.
• Most of the heavy lifting is done by the Presentation Manager class.
Page 45
Service Example: Agent
package org.sakaiproject.service.common.agent;import org.sakaiproject.service.common.shared.Resource;public interface Agent extends Resource { }
package osid.agent;public interface Agent extends java.io.Serializable { public String getDisplayName() throws osid.shared.SharedException; public osid.shared.Id getId() throws osid.shared.SharedException; public osid.shared.Type getType() throws osid.shared.SharedException; PropertiesIterator getProperties() throws osid.shared.SharedException; Properties getPropertiesByType(Type propertiesType) throws osid.shared.SharedException; TypeIterator getPropertiesTypes() throws osid.shared.SharedException;}
Page 46
package org.sakaiproject.service.common.shared;import org.sakaiproject.exception.PermissionException;import org.sakaiproject.exception.VersionException;import org.sakaiproject.service.common.id.Id;public interface Resource extends Comparable {String getDescription(); String getDisplayName(); Id getId(); Type getType(); PropertiesIterator getProperties(); Properties getPropertiesByType(Type propertiesType); TypeIterator getPropertyTypes(); void setDescription(String description); void setDisplayName(String displayName); void setType(Type type); String getReference(); String getUrl(); boolean allowDelete(); boolean allowUpdate(); Properties addPropertiesType(Type propertiesType); void removePropertiesType(Type propertiesType); void delete() throws PermissionException; Version getVersion(); boolean isCurrentVersion(); boolean isCurrentVersion(Version version); void update() throws VersionException, PermissionException; void updateIgnoreVersion() throws PermissionException; }
Service Example: Resource
Page 47
Legacy Services
Page 48
Legacy Services
• Jon Andersen of U. Michigan will talk for 15 – 20 minutes on Sakai Legacy Services including:– Active user– Active worksite– Authorization– Resources and content API
Page 49
Legacy Services
• Legacy services were created primarily for the tools in the 1.0.0 release (Announcements, Chat, Resources, etc)
• Legacy services manage all persistent data such as current user, current site, security, and tool-specific information.
• Legacy services will evolve as JSF tools are developered and OKI OSID services mature, and a migration path will be provided.
Page 50
How to use Legacy Services
1. Identify the needed legacy service 2. Inject the legacy service into your own
tool bean or service3. Use the legacy service in your tool bean
logic or service logic4. Provide access methods in the tool bean
for the data or actions that the JSF page requires
Page 51
package org.sakaiproject.service.legacy.site;
public interface SiteService { … boolean allowUpdateSite(String siteId); …}
Identify Needed Services
package org.sakaiproject.service.legacy.user;
public interface UserDirectoryService { … User getCurrentUser(); …}
package org.sakaiproject.service.framework.portal;
public interface PortalService { … String getCurrentSiteId(); String getCurrentSitePageId(); String getCurrentToolId(); …}
Q: How do I find out about the current user, site, page or tool?
A: Use one of the legacy services (until Sakai 2.0)
Page 52
<faces-config> <managed-bean-name>MyTool</managed-bean-name> <managed-bean-class>org.sakaiproject.tool.mytool.MyTool</managed-bean-class> <managed-bean-scope>request</managed-bean-scope>
<managed-property> <description>Service Dependency: UserDirectoryService</description> <property-name>userDirectoryService</property-name> <value>#{Components["org.sakaiproject.service.legacy.user.UserDirectoryService"]}</value> </managed-property>
<managed-property> <description>Service Dependency: SiteService</description> <property-name>siteService</property-name> <value>#{Components["org.sakaiproject.service.legacy.site.SiteService"]}</value> </managed-property>
<managed-property> <description>Service Dependency: PortalService</description> <property-name>portalService</property-name> <value>#{Components["org.sakaiproject.service.framework.portal.PortalService"]}</value> </managed-property> </managed-bean></faces-config>
Inject needed services (1)(faces-config.xml)
Legacy services are indexed by the class names of the service interfaces
Page 53
…public class MyTool implements ToolBean { private UserDirectoryService m_userDirectoryService; private SiteService m_siteService; private PortalService m_portalService;
public void setUserDirectoryService(UserDirectoryService service) { this.m_userDirectoryService = service; }
public void setSiteService(SiteService service) { this.m_siteService = service; }
public void setPortalService(PortalService service) { this.m_portalService = service; } …}
Inject needed services (2)(MyTool.java)
Setters enable JSF to inject the services selected by faces-config.xml
Page 54
Provide access methods…public class MyTool implements ToolBean { public User getCurrentUser() { return m_userDirectoryService.getCurrentUser(); }
public String getCurrentSiteId() { return m_portalService.getCurrentSiteId(); }
public boolean getCanCurrentUserModifySite() { return m_siteService.allowUpdateSite(m_portalService.getCurrentSiteId()); } …}
(MyTool.java)
Access methods enable the JSF page to interact with the legacy services.
Page 55
Use in JSF...<%@ taglib uri="http://sakaiproject.org/jsf/sakai" prefix="sakai" %>...<f:view><sakai:view_container title="#{msgs.sample_title}"><h:form> ... <sakai:view_content> ... <sakai:group_box title="#{msgs.sample_one_groupbox}"> <sakai:panel_edit> ... <h:outputText value="Site ID (1.0.0)" /> <h:outputText value="#{MyTool.currentSiteId}" /> <h:outputText value="Current user" /> <h:outputText value="#{MyTool.currentUser.displayName}" /> <h:outputText value="Can current user modify the structure of this site?" /> <h:outputText value="#{MyTool.canCurrentUserModifySite}" /> </sakai:panel_edit> </sakai:group_box> ... </sakai:view_content></h:form></sakai:view_container></f:view>
(main.jsp)
JSF value references can access JavaBean-style getters in service-managed objects
Page 56
Identify Needed Serviceshttp://cvs.sakaiproject.org/release/1.0.0/javadoc/index.html
org.sakaiproject.service.framework.cluster org.sakaiproject.service.framework.component org.sakaiproject.service.framework.config org.sakaiproject.service.framework.courier org.sakaiproject.service.framework.current org.sakaiproject.service.framework.email org.sakaiproject.service.framework.log org.sakaiproject.service.framework.memory org.sakaiproject.service.framework.portal org.sakaiproject.service.framework.session org.sakaiproject.service.framework.sql org.sakaiproject.service.legacy.alias org.sakaiproject.service.legacy.announcement org.sakaiproject.service.legacy.archive org.sakaiproject.service.legacy.assignment org.sakaiproject.service.legacy.calendar org.sakaiproject.service.legacy.chat org.sakaiproject.service.legacy.content org.sakaiproject.service.legacy.digest org.sakaiproject.service.legacy.discussion org.sakaiproject.service.legacy.dissertation org.sakaiproject.service.legacy.email org.sakaiproject.service.legacy.event org.sakaiproject.service.legacy.id org.sakaiproject.service.legacy.news org.sakaiproject.service.legacy.notification org.sakaiproject.service.legacy.preference org.sakaiproject.service.legacy.presence org.sakaiproject.service.legacy.realm org.sakaiproject.service.legacy.resource org.sakaiproject.service.legacy.security org.sakaiproject.service.legacy.site org.sakaiproject.service.legacy.time org.sakaiproject.service.legacy.user
Lots of services…
portal – Portal info site – Manages Sakai sitesuser – Current user, manage userscontent – Uploaded files (resource tool) courier – Automatic refreshing when content changes email – Send emaillog – Loggingsql – SQL access to Sakai DBpreference – User preferencessecurity – Check user permissions (security)
… only a few that tools will likely access:
Page 57
Resources and the Content API(Javadoc)
• The ContentHostingService manages uploaded files and folders, their properties, and permissions.
Page 58
Resources and the Content API(Javadoc)
package org.sakaiproject.service.legacy.content;
public interface ContentHostingServiceextends ResourceService {
…String getSiteCollection(String siteId);ContentCollection getCollection(String collectionId);ContentCollectionEdit addCollection(String collectionId);ContentResource addResource(String id, String type, byte[] content,
ResourceProperties properties, int priority);ContentResourceEdit editResource(String resourceId);void commitResource(ContentResourceEdit editedResource);void cancelResource(ContentResourceEdit editedResource);boolean allowUpdateResource(String resourceId);boolean allowUpdateCollection(String collectionId);allowRename(String oldId, String newId);allowAddCollection(String collectionId) ;allowAddAttachmentResource();ResourceProperties getProperties(String collectionOrResourceId);
…
Page 59
Legacy Service Patterns• Objects - Service manages a collection of objects (ie,
ContentCollection, AnnouncementMessage, ChatMessage, Calender, CalenderItem). Service manages entire lifecycle of the objects.
• Security - allowXXX() methods check that the current user has proper permissions for XXX operation. Also, some methods do inline permissions checking and throw PermissionException if the operation is not allowed.
• References - Many managed objects implement the Resource interface, and can be referenced through an internal ID, a internal string URI, or an externally accessible URL.
• Properties - Managed objects that implement Resource have standard properties (created by, last modified, etc) and arbitrary tool-specific properties.
Page 60
Resources and the Content API(Javadoc)
package org.sakaiproject.service.legacy.content;
public interface ContentHostingServiceextends ResourceService {
…String getSiteCollection(String siteId);ContentCollection getCollection(String collectionId);ContentCollectionEdit addCollection(String collectionId);ContentResource addResource(String id, String type, byte[] content, ResourceProperties properties, int priority);ContentResourceEdit editResource(String resourceId);void commitResource(ContentResourceEdit editedResource);void cancelResource(ContentResourceEdit editedResource);boolean allowUpdateResource(String resourceId);boolean allowUpdateCollection(String collectionId);allowRename(String oldId, String newId);allowAddCollection(String collectionId) ;allowAddAttachmentResource();ResourceProperties getProperties(String collectionOrResourceId);
…
Access objects
Edit objects
Check permissions
Access properties
Page 61
Resources and the Content APIpackage org.sakaiproject.service.legacy.content;
public class PresentationManagerImpl implements PresentationManager {… public List getPresentations() { String home = contentHostingService.getSiteCollection(PortalService.getCurrentSiteId()); String collectionId = home + “Presentations/”; try { ContentCollection collection = contentHostingService.getCollection(collectionId); int size = newMembers.size(); for (int i = 0; i< size; i++) { Resource resource = (Resource) newMembers.get(i); String nextId = resource.getId(); boolean isCollection = resource.getProperties().getBooleanProperty(ResourceProperties.PROP_IS_COLLECTION); if (isCollection) { loadPresentation(nextId); } catch (PermissionException e) { (Inform the user that they are not allowed to do that) } catch (IdUnusedException e) { …} catch (TypeException e) { … } catch (EmptyException e) { …} return this.presentations; }}
Example code snippet from the Presentation Service
Page 62
JSF toolConfig Variable(Javadoc)
• The implicit JSF variable “toolConfig” provides convenient access to some common textual information that might be displayed in a tool. More properties will be available in the Sakai 1.5 release.
1.0.0 release
#{toolConfig.toolId}
#{toolConfig.title}
#{toolConfig.containingPage.title}
#{toolConfig.containingPage.containingSite.title}
#{toolConfig.containingPage.containingSite.description}
#{toolConfig.containingPage.containingSite.type}
#{toolConfig.containingPage.containingSite.skin}
#{toolConfig.containingPage.containingSite.joinable}
Added in 1.5.0 release (or in CVS now)
#{toolConfig.pageId}
#{toolConfig.siteId}
#{toolConfig.containingPage.containingSite.createdBy}
#{toolConfig.containingPage.containingSite.modifiedBy}
#{toolConfig.containingPage.containingSite.createdTime}
#{toolConfig.containingPage.containingSite.modifiedTime}
#{toolConfig.containingPage.containingSite.shortDescription}
#{toolConfig.containingPage.containingSite.published}
#{toolConfig.containingPage.containingSite.pubView}
Page 63
Developing Tools
Page 64
Tool Development
• The MVC Pattern and JSF
• Creating New Tools
• UI Design using Faces
• Service Injection
• Application Context
• Using the Style Guide
Page 65
Tools Glue Things Together
JavaServer Faces
Faces-config.xml
Sakai Tool Class
Application Service Class
GUI Element
Action Method
App Logic
<xml> <faces></xml>
ControllerDesignPattern
ViewDesignPattern
ModelDesignPattern
Page 66
Creating a New Tool
• Describe the UI using JSF pages.• Create an Application Service.• Implement the Application Services.• Create a Tool Class which uses the
application service via injection.• Create Maven project files to compile and
deploy.• Register the tool with the Component
Manager
Page 67
The Tool Class
• Written as a JavaBean so that JavaServer Faces can access it. It is the model part of the MVC pattern.
• Application and common services are injected as needed.
• Handles initializations and data defaults.• Implements JSF response methods
(events).
Page 68
Designing a UI
• Wire frames and layouts should be used to get a feel for views needed and flow in the application.
• Standard Sakai elements are defined to ensure consistent look and feel
• Standard Sakai layouts are provided for standard UI containers (boxes, toolbars, forms, etc.).
Separate UIDesignPattern
Page 69
JSF is Used to Describe the UI<sakai:view_container title="#{msgs.sample_title}">
<sakai:tool_bar> <sakai:tool_bar_item/> </sakai:tool_bar>
<sakai:instruction_messagevalue="#{msgs.sample_one_instructions}" />
<sakai:group_box title="#{msgs.sample_one_groupbox}">
<h:inputText value="#{MyTool.userName}" />
<sakai:date_input value="#{MyTool.date}" />
<sakai:button_bar><sakai:button_bar_itemaction="#{MyTool.processActionDoIt}value="#{msgs.sample_one_cmd_go}" /></sakai:button_bar>
Page 70
Backing Beans Handle Action<h:inputText value="#{MyTool.userName}" />
<sakai:date_input value="#{MyTool.date}" />
<sakai:button_bar><sakai:button_bar_itemaction="#{MyTool.processActionDoIt}value="#{msgs.sample_one_cmd_go}" /></sakai:button_bar>
MyTool.userName() {}
MyTool.date() {}
MyTool.processActionDoIt() {}
Page 71
Service Injection
• Sakai uses a service injection pattern to resolve dependencies at runtime.
• This is a kind of Inversion of Control (IoP).
• The Spring Framework handles initialization of manager objects and injects dependent services.
• This is all done in XML configuration files.
• Allows version dependencies.
Page 72
Application Context
Page 73
The Sakai Style Guide
• Includes illustrations of Sakai GUI elements and widgets.
• JSF tags are described with options noted.• Use considerations and best practice.• Accessibility and uPortal guidelines.• A draft version of the Sakai Style Guide
will be released during or following the SEPP conference. See Rob Lowden’s presentation.
Page 74
Tool Development Example
Page 75
Overview of Tool Development
• Sample Methodology
• Design the UI (mockups, wireframe)
• Write the JSF descriptions
• Write the application interface and service
• Write and configure the tool
• Porting tools
Page 76
A Development MethodologyWireframes
Id Panels and Modes
MakeServices
MakeBacking Beans
DevelopUI with JSF
Click ThruMockup
ToolIntegration
Developed by Ben Brophy and the MIT Gradebook team.
Page 77
The Presentation Tool
• Upload a set of slides and make them available as a presentation that can be shown to one or more viewers with simple controls.
• Currently implemented using a Presentation service based on direct file access.
• Being integrated with Sakai Legacy services (Content API, etc).
• Use the “presentation” CVS root.
Page 78
Presentation Views
• The tool has four basic presentation states:
Each of these state diagram nodes become a JSF view.
Page 79
Main Page These are presentations available to be shown
Buttons provide the transition to other faces.
Presentations are managed by an application service
Shows are run time objects that are deleted once complete.
Uses theSakai Style
Guide Elements
Page 80
Presentation Controls
Only a single controller of a presentation is allowed. Three controls are provided at this time: go to next, go to previous, and end the presentation. The current slide is shown for reference.
Page 81
The Viewer Page
Any number of people may view the presentation. The interactive option is to exit the viewer. Current slide is synchronized via a file. Viewer refreshes every 20 seconds (settable).
Page 82
JavaServer Faces• Tool pages are described by JavaServer
Faces tags using a JSP file as a container.
• Each page is a JSF view.
• Sakai supports the standard JSF tags.
• Eventually, Sakai will have a full set of tags which represent the Sakai GUI elements, to be documented in the Sakai Style Guide.
• This set is partially implemented and under development.
Page 83
JSF Navigation
• JSF Views are described in JSP files.
• Navigation from one view to the next is handled by returning the name of the next view. Return null to stay with current view.
• The transition from main.jsp to show.jsp is handled by returning “show” out of processActionShow().
Page 84
<faces-config>
<application> <message-bundle>org.sakaiproject.tool.mytool.bundle.Messages</message-bundle> <locale-config><default-locale>en</default-locale></locale-config> </application>
<managed-bean><description>Presentation Tool Bean</description><managed-bean-name>PresentationTool</managed-bean-name><managed-bean-class>org.sakaiproject.tool.mytool.PresentationTool</managed-bean-class><managed-bean-scope>tool</managed-bean-scope>
<managed-property><description>Service Dependency: Presentation Service</description><property-name>prMgr</property-name><value> #{Components["org.sakaiproject.service.presentation.PresentationManager"]}</value>
</managed-property> </managed-bean></faces-config>
Faces-config.xml
This is how the Presentation Service is injected into the Presentation Tool. This is a reference to the Sakai Component Manager.
Page 85
<sakai:group_box title="#{msgs.pt_showing_groupbox}"> <h:form>
<sakai:tool_bar><sakai:tool_bar_item
action="#{PresentationTool.processActionJoin}"value="#{msgs.pt_join_button}" />
</sakai:tool_bar><sakai:view_content>
<h:messages showSummary="true" showDetail="true" />
<%-- the list of presentations --%><sakai:flat_list value="#{PresentationTool.prMgr.shows}" var="show">
<h:column> <%-- Check box column. --%><f:facet name="header">
<h:outputText value=""/></f:facet><h:selectBooleanCheckbox value="#{show.presentation.selected}"/>
</h:column><h:column> <%-- The title column. --%>
<f:facet name="header"><h:outputText value="#{msgs.pt_col_head_title}" />
</f:facet><h:outputText value="#{show.presentation.title}"/>
</h:column></sakai:flat_list>
<sakai:button_bar><sakai:tool_bar_item
action="#{PresentationTool.processActionJoin}"value="#{msgs.pt_join_button}" />
</sakai:button_bar>
</sakai:view_content> </h:form></sakai:group_box>
main.jspThis is the “showing” box on main page. The list of presentations is similar, but more complex.
Page 86
How JSF Looks Rendered<sakai:group_box title="#{msgs.pt_showing_groupbox}">
<sakai:tool_bar> <sakai:tool_bar_item/> </sakai:tool_bar>
<sakai:flat_list value="#{PresentationTool.prMgr.shows}" var="show">
<sakai:button_bar><sakai:tool_bar_itemaction="#{PresentationTool.processActionJoin}"
value="#{msgs.pt_join_button}" /></sakai:button_bar>
<h:column><f:facet name="header"> <h:outputText value=""/></f:facet><h:selectBooleanCheckbox value="#{show.presentation.selected}"/></h:column>
<h:column> <f:facet name="header"> <h:outputText value="#{msgs.pt_col_head_title}" /> </f:facet> <h:outputText value="#{show.presentation.title}"/></h:column>
Page 87
Messages.Properties
pt_new_button=Newpt_delete_button=Deletept_show_button=Show
pt_col_head_title=Titlept_col_head_author=Author
pt_title_main=Presentation Tool
pt_presentation_groupbox=Presentations
The messages.properties file defines text resources thatcan be inserted into JSF renderings, accessed by backingbeans, etc. Internationalization support is provided byhaving alternative versions of this file with country codeextensions.
These are the messages used on the Main view of the presentation tool. Property names are conventions to make it easier to keep things straight,
Page 88
Writing the Application Service
• Design the Application Service– Think about reuse at this stage.– Good object design will benefit all.
• Implement it as a POJO managed bean.
• Access is provided via a Manager class.
• Other services can be defined as dependencies and injected by the Spring container.
Page 89
Presentation Service - Interfacepackage org.sakaiproject.service.presentation;
public interface PresentationManager { IdManager getIdManager(); void setIdManager (IdManager im);
public Show getShow (Id id); public List getShows(); public Show getCurrent (); public void setCurrent (Show show); public Show createShow (Presentation presentation); public void deleteShow (Id id); public Presentation getPresentation (Id id); public List getPresentations(); public Presentation createPresentation(List slides, String title, String author); public void deletePresentation (Id presentationId); public Slide createSlide(String url, String name, String type); public void load(); public void save(); public void updateShowFile(Show show); public Slide readShowFile(Show show); }
Allows the IdManager to be injected.
This List is displayed as available shows.
This List is displayed as available presentations.
Initialization is done automatically.
Page 90
Presentation Service Managerpublic class PrManager implements org.sakaiproject.service.presentation.PresentationManager { protected IdManager idManager = null; private List presentations = new Vector(); private List shows = new Vector();
public List getPresentations() {return this.presentations;
}
public Presentation createPresentation(List slides, String title, String author) { Id id = null;
try { id = this.idManager.createId(); } catch (Throwable t) {return null;}
Presentation pres = (Presentation) new PrPresentation(id, slides, title, author); this.presentations.add (pres); return pres; }
public void deletePresentation(Id id) { Presentation pres = this.getPresentation (id); this.presentations.remove(pres); } ....}
Page 91
Tool Implementation
• Tool classes typically have a set of properties (data elements).
• Each property has get and set methods, so that Spring can manage it as a bean.
• The tool is registered as a bean.
• The tool has JSF event handler methods.
Page 92
Tool Data Elementspublic class PresentationTool{
/** Service Dependency: Presentation Service. */protected PresentationManager prMgr = null;
….}
The Presentation Manager is the main access point in thePresentation Tool. Most of the faces code access informationvia this object.
Page 93
Tool Access Methodspublic class PresentationTool{
…
public PresentationManager getPrMgr () {return this.prMgr;
}
public void setPrMgr (PresentationManager mgr) {this.prMgr = mgr;
}
….}
Since the tool is a managed bean, both set and get methodsmust be provided that correspond to the data element.
Page 94
Tool Event Handlerspublic class PresentationTool {
public String processActionShow() {Show currentShow = null;List prs = this.prMgr.getPresentations();
for (int i=0; i<prs.size(); i++) { // Scan for selected presentation.Presentation pres = (Presentation) prs.get(i);if (pres.getSelected() == true) {
currentShow = prMgr.createShow (pres);this.shows.add (currentShow);this.prMgr.setCurrent (currentShow);pres.setSelected(false);
}}
if (currentShow == null) return “main”; // Nothing selected.this.slide = currentShow.getCurrent(); // Set the current slide.return "show"; // Transfer to the show page (the controller).
}}
Returning the name of the next view is how transfer to the view happens.
Page 95
Servlet Definition
• Each Sakai tool is defined as a Tomcat servlet. In Sakai, servlets can access code in other servlets, which not the case for most web applications.
• This is handled by the Sakai Dispatcher and the FacesServlet along with the Sakai Component Manager.
• This also forces code into specific spots for delivery (shared/lib, repository, etc.).
Page 96
Tool Web.xml<web-app> <display-name>sakai-present-tool</display-name> <description>Sakai Presentation Tool</description> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup> 2 </load-on-startup> </servlet>
<servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping>
<welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list>
</web-app>
This is an edited version of the tool web.xml file showing how the Faces servlet is mapped.
Page 97
Registering a Service
• Registering a service requires that the interface being shared/lib and the component be included in the local repository.
• The component.xml file is used to define how dependent services are injected into this service.
• To make the service visible to other services or tools, it must be registered with the Sakai Component Manager.
• This is done in the web.xml file of the component.
Page 98
Components.xml
<bean id="org.sakaiproject.service.presentation.PresentationManager"class="org.sakaiproject.component.presentation.PrManager"init-method="init"singleton="true">
<property name="idManager"><ref bean="org.osid.id.IdManager"/></property> <property name="hosting">
<ref bean="org.sakaiproject.service.legacy.content.ContentHostingService"/> </property></bean>
Defines an identifier for the Presentation service and what class it isassociated with. IdManager is included as a dependency.
Page 99
Component web.xml<web-app> <display-name>sakai-present-component</display-name> <description>Sakai Presentation Service Implementation</description> <servlet> <servlet-name>components</servlet-name> <servlet-class>org.sakaiproject.component.ComponentsServlet</servlet-class> <init-param> <param-name>components-file</param-name> <param-value>components.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>components</servlet-name> <url-pattern>/components/*</url-pattern> </servlet-mapping>
<welcome-file-list><welcome-file>index.html</welcome-file></welcome-file-list>
</web-app>
This is where the component is registered with the Sakai Component Manager. A URL mapping is provided for debugging (list components).
Page 100
Deployment
Page 101
Deployment and Development
• Directory Structure
• Deployment
• Eclipse and Maven
• The CVS Repository
• Bug reporting and tracking
• UI Review
• Porting Existing Tools
Page 102
Structure of a Sakai Module
• A Sakai module is a collection of code chunks that will be deployed to various places in the Tomcat environment.
• Each module has an application service API, application service implementation, and a tool implementation.
/service
/component
/tool
/module name
Page 103
Module Directory Structure/service
/src
/bundle
/java
/webapp
/WEB-INF
/tool-name
index.html
faces-config.xml
components.xml
web.xml
JSF pages
properties
code
/component /tool
maven.xmlproject.xml
/
Each of the three directories under the module root has pretty much the same structure. Not all files are present in all directories, though.
Page 104
Configuration Files
• Component.xml– Service components to be injected.
• Web.xml– Servlet definitions
• Faces-config.xml– JSF configuration (also injection)
• Messages.properties– Display messages, etc.
Page 105
Deployment
• Deployment is the process of moving code and resources into the Tomcat (etc) environment which enables the tool to be included in a particular Sakai environment.
• Software is broken down into three parts forming a module:– APIs (interface)– Service Components– Tool
Page 106
Code Deployment
InterfaceCode
ComponentCode
ToolCode
TomcatShared/lib
Tomcatwebapps
LocalRepository
Page 107
Creating a Module from Scratch
• Create a module directory structure similar to other Sakai modules.
• Use other configuration files as templates.• Design and write the application service
interface.• Implement the application service• Design UI and describe in JSF pages.• Write the tool to handle JSF events ….
Etc.
Page 108
Working with Maven
• Maven is a powerful software configuration and management tool.
• Project files describe software dependencies which are resolved against project goals.
• Each module has its own project.xml file.• The deploy module has a special project.• http://maven.apache.org/start/download.html
Page 109
The Maven Project File
• The maven documentation describes how to set up dependencies. Use other modules as a project file template.
• If you stray from the Sakai templates, you are on your own! Be careful of version agreement.
• Maven will generate error messages if it fails and indicate “Build Failed” if not successful.
Page 110
Eclipse Support
• Eclipse provides several plug-ins which can simplify the development process:– base XML editing– JSF layout– Servlet definitions and editing– Maven project editing
• Eclipse is strongly recommended as the best IDE for developing Sakai tools.
• myEclipse is even better since it provides additional tools and better XML support.
Page 111
The Sakai CVS Repository
• Sakai has created a public CVS repository– cvs.sakaiproject.org
• Top level branches for:– Sakai Framework– Sakai Assessment and Assignment Manager
• Public read only access
• Project leaders will have commit access
Page 112
UI and QA Review
• Sakai is setting up a UI Review team to review submitted UI designs, prototypes, and completed code.
• Similarly, a Sakai QA team is being set up to test code and ensure that it meet Sakai quality standards.
• Contact Mark Norton for now, more information later.
Page 113
Bug Reporting
• Sakai has settled on using JIRA as it’s bug reporting and tracking system.
• Report problems at bugs.sakaiproject.org
• If you are developing tools, you may want to register as a developer. Send mail to [email protected].
• Registering means fixing bugs reported against your code.
Page 114
Debugging Techniques
• Use JUnit testing.• Attaching to Tomcat
– You can set Tomcat up to listen on a debug port and then connect to it from Eclipse.
• Problems with injection– Injection problems will generate entries in
tomcat console and log files.– Make sure of configuration files and
constructors.
Page 115
Porting Tools to Sakai
• Use existing page snapshots to design JSF
• Separate out presentation from application logic.
• Pull application services out into stand alone services.
• Re-code to use existing services.• Use similar tool implementations to help
with configuration files (etc).
Page 116
Development Projects
• Project coordination via SEPP work groups.
• Write up a proposal containing who, what, and by when and send to me.
• Projects can be managed and developed by a single institution, or set up as a collaborative effort.
Page 117
How Code is Released
• Currently, Indiana is controlling the 1.5 release.
• Later, a release manager will be in charge of what goes into a particular release.
• Submissions should be vetted by the Sakai QA and UI review teams.
Page 118
Portability
Page 119
Portability Considerations
• Sakai is an integration framework which allows tools to be combined with services using a set of guiding principles (TPP)
• Sakai tools are intended to be portable to other Sakai sites.
• Non-Sakai tools can be brought into the Sakai environment with limited integration.
Page 120
Porting Applications
• Tools can be developed to be portable with other frameworks– Use OSIDs and Web Services
• Or tools can be ported and integrated into Sakai– Follow the guidelines for porting a tool.– Use Sakai APIs and TPP.– Test final functionality against the original.
Page 121
Interoperability Considerations
• Use industry interoperability standards where available:– IMS specifications, SCORM profile– IEEE and ISO standards– W3C, IETF, GRID, etc.
• Services should include the concept of import and export using these interchange standards.
Page 122
Sneak Preview!
Page 123
Sakai 1.5
• SAMigo
• Grade book (maybe)
• OSP
• Presentation Tool
• Framework improvements
• More common services
• Gap satisfaction
More information on the future of Sakai releases will be reported during the SEPP Conference starting tomorrow.
Page 124
Sakai 2.0 - Spring 2005
• Significant replacement of legacy tools– TPP Compliant, using OKI and Sakai APIs– New and improved tools based on Sakai-wide
requirements process– Each partner institution will focus on a set of
tools to develop• SEPP partners will be involved in the new tool
development based on ability and commitment.
Page 125
JavaServer Faces
Spring
ComponentManager
uPortalOther
Portals
CommonServices
Apache &Tomcat
ApplicationServices
Tool
The Sakai 2 FrameworkBrowser
injection
injection
rendering
response and request
HibernateORM
Page 126
Sakai and OKI• OKI has produced a series of APIs to support
learning management system portability:– Enterprise Integration– Tool Portability
• The OKI APIs allow for flexible out-of-band agreements
• The Sakai APIs are designed to be closely aligned with the OSIDs.
• Sakai will continue to work closely with OKI and make recommendations for changes to the OSIDs.
Page 127
IMS Tool Portability SIG
• Sakai has approached IMS to develop a tool portability specification.
• A charter proposal has been written and approved by the IMS Technical Board.
• This spec will allows tools to be ported between environments by identifying certain “core” services: AuthN, AuthZ, User/Group, and Repository.
• If your organization is a member of IMS, please consider participating in this effort.
Page 128
Things You Can Do
Page 129
Call to Action
• Participate in the discussion groups
• Develop in-house Sakai expertise
• Install and review Sakai 1.0 (etc)
• Develop or port tools to Sakai
• Contribute requirements
• Share lessons learned
• Be an active voice in how SEPP is run
Page 130
Read SEPP Communications
• Update Message– A weekly electronic newsletter– Latest news– References to papers and documentation– Reports from discussion groups
• White Papers• Reports on Events• SEPP Conference
Page 131
Participate in SEPP Discussion Groups
• Requirements – UC Berkeley
• Migration – Columbia
• Cross Language Support – U. Washington
• User Interface – Dartmouth
• Content & Authoring – U. Wisconsin
• Libraries - Columbia
• Developers – Mark Norton
Page 132
Development Discussion Groups
• The “Sakai Devel” group is now the default place to ask questions, report results, etc.
• This is a public group open to all.
• The SEPP group will evolve into SEPP development coordination, development support, and other issues.
Page 133
Sakai Tool Development Skills
• Java Beans (dependency insertion)
• Understanding of Servlets
• Interface design and implementation
• OKI OSIDs and Sakai APIs
• Maven deployment techniques
• JavaServer Faces and Sakai GUI elements
• Hibernate is useful if developing new APIs
Page 134
Resources
• Mark J. Norton– [email protected]– 781-275-4070
• http://sakaiproject.org/
• http://collab.sakaiproject.org/– sakai-user worksite– sakai-devel worksite
• http://cvs.sakaiproject.org/
Page 135
Questions?