introduction to spring web flow andrew petro software developer unicon, inc. jasig 2011 westminster,...

75
Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some rights reserved. This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us/

Upload: neil-lamb

Post on 05-Jan-2016

219 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

Introduction to Spring Web Flow

Andrew PetroSoftware Developer

Unicon, Inc.

Jasig 2011Westminster, CO

23 May 2011

© Copyright Unicon, Inc., 2011. Some rights reserved. This work is licensed under aCreative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us/

Page 2: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

2

Spring Web Flow

1. How Spring Web Flow Fits

2. What's a Flow?

3. Spring Web Flow States

4. Forms

Page 3: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

3

Why is Spring Web Flow important?

uPortal 4 uses Spring Web Flow CAS uses Spring Web Flow Spring Web Flow as viable Portlet

development framework

Quickly build and maintain wizard / flow Web experiences with panache Forms, processes, registrations

This is bread and butter self-service IT

Page 4: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

4

How Spring Web Flow Fits

Page 5: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

5

Sits atop Spring Framework / MVC

Spring Web Flow works with the rest of the Spring Framework and Spring WebMVC

Diagram credit: Spring Web Flow documentation

Page 6: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

6

Purpose of Spring Web Flow

Spring Web Flow is good at building flows

Which just begs the question, really.

Let me get at this another way...

Page 7: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

7

Aside: Spring Framework

Dependency Injection / Inversion of Control Utilities, templates, helpers For easing all aspects of Java development

Especially Java Web development

Page 8: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

8

The Hollywood Principle

Image credit http://www.flickr.com/photos/loop_oh/4337804209/ CC-BY-ND

Page 9: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

9

Don't Call Us, We'll Call You

Page 10: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

10

Dependency Injection

Write POJOs. JavaBeans. Spring wires together using XML or

Annotations or Autowiring or … Stop calling static factories.

Code becomes more reusable, more flexibly configurable, less repetitive, ...

Page 11: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

11

Editing Portlet Publications in uPortal 4 RC1

An example of a flow

Page 12: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

12

Portlet Management

Page 13: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

13

Select Portlet Type

Page 14: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

14

Set basic portlet info

Page 15: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

15

Portlet Parameters

Page 16: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

16

Select Categories

Page 17: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

17

Select Users and Groups

Page 18: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

18

What's a flow anyway?

Page 19: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

19

What's a flow?

A flow is a multi-step experience More than one request in making up a logical

whole

Page 20: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

20

A flow - what

Has a beginning (state) and an end (state) Has zero or more intermediary states Has transitions between these states Has its own scope

Can conveniently remember state between these steps until the flow completes and your application is ready to process the whole result

Page 21: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

21

Flows - why

Re-use multi-step processes Revisit steps in flow

Constrained by allowable state transitions

Stateful!

Flow-scoped state (might) make your application cleaner (not having to model and remember at the persistence/domain layer incomplete state)

Page 22: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

22

Re-use subflows

Page 23: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

23

Revisit steps in flow

Page 24: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

24

Page 25: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

25

States and Transitions

Views, Decisions, Actions, and Subflows

Page 26: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

26

View States

<view-state id=”viewLoginForm” />

Renders a view. By convention, a view with the same name as

the id. So, “viewLoginForm.jsp”, e.g.

Page 27: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

27

Transitions from a View

<view-state id=”someView”>

<transition on=”submit” to=”handleSubmit”/>

<transition on=”cancel” to=”mainMenu” />

</view-state>

<input type=”submit” name=”_eventId_submit” value=”Submit”/>

<input type=”submit” name=”_eventId_cancel”

value=”Cancel”/>

<a href=”${flowExecutionUrl}&_eventId=cancel”>Cancel</a>

Page 28: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

28

Decision States

<decision-state id=”warn”>

<if test=”flowScope.warnCookieValue”

then=”showWarningView” else=”redirect” />

</decision-state>

Boolean decision about what state is next

Page 29: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

29

Action States

<action-state id=”generateServiceTicket”>

<evaluate expression=”generateServiceTicketAction”/>

<transition on=”success” to=”warn”/>

<transition on=”error” to=”viewLoginForm”/>

</action-state>

Page 30: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

30

Subflow States

<subflow-state id="chooseGroup" subflow="entity-selector">

<input name="selectedGroups"

value="portlet.groups"/>

<output name="selectedGroups"

value="portlet.groups"/>

<transition on="back" to="chooseCategory"/>

<transition on="finish"

to="chooseGroupNextScreen"/>

</subflow-state>

Page 31: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

31

How it really works

Start at a start-state Flow through zero or more action and

decision states until you get to another view state. Render it.

Repeat previous step. Eventually exit the flow.

Page 32: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

32

Ending with a view

<end-state id=”viewServiceErrorView” />

Page 33: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

33

Ending with a redirect

<end-state id=”redirectView”

view=”externalRedirect:${requestScope.response.url}”

/>

Page 34: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

34

Ending with return from subflow

<end-state id="finish">

<output name="selectedGroups"

value="flowScope.groups"/>

</end-state>

Page 35: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

35

Setting variables and invoking Java

between and within states

Page 36: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

36

Expression language

<evaluate expression=”authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)” />

Page 37: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

37

Storing result from expression

<evaluate expression=”flowScope.service.getResponse(requestScope.serviceTicketId)” result-type=”org.jasig.cas.authentication.principal.Response” result=”requestScope.response” />

Page 38: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

38

Where can I insert expressions?

On flow start On state entry On view render On transition execution On state exit On flow end

Page 39: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

39

Forms

Page 40: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

40

Form Objects

Form objects are POJOs JavaBean properties

public String getFname() {

return fname;

}

public void setFname(String name) {

fname = name;

}

...

Page 41: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

41

Binding forms to model

<view-state id="chooseType" model="portlet"> <transition on="next" to="afterChooseType" />

<transition on="cancel" to="cancelEditScreen"

bind="false"/>

</view-state>

Model

Form fields bind to JavaBean properties of the model Java object.

Page 42: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

42

Binding

All properties bind by default Bindings can be explicitly declared You can also use a custom binder

Page 43: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

43

Binding forms selectively to model

<view-state id="lifecycle" model="portlet">

<binder>

<binding property="lifecycleState"/>

<binding property="publishHour"/>

...

</binder>

...

</view-state>

Binder

Only bind the properties you intend to bind!

Page 44: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

44

Selectively bind on transitions

<view-state id=”viewLoginForm” view=”casLoginView” model=”credentials”>

<binder>

<binding property=”username” />

<binding property=”password” />

</binder>

<transition on=”submit” bind=”true” to=”handleSubmit”/>

<transition on=”cancel” bind=”false” to=”whyAreYouHere”

/>

</view-state>Bind attribute on transition

You might not bother binding on a cancel, or you might bind but not validate if partial progress completing model.

Page 45: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

45

Select Portlet Type

Page 46: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

46

Next without required field

Page 47: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

47

But cancel doesn't require field

Page 48: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

48

Binding forms to model

<view-state id="chooseType" model="portlet"> <transition on="next" to="afterChooseType" />

<transition on="cancel" to="cancelEditScreen"

bind="false"/>

</view-state>

Model

Form fields bind to JavaBean properties of the model Java object.

Page 49: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

49

Properties can be required

<view-state id=”viewLoginForm” view=”casLoginView” model=”credentials”>

<binder>

<binding property=”username” required=”true” />

<binding property=”password” required=”true”/>

</binder>

</view-state>

Page 50: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

50

CAS login form

Page 51: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

51

Required fields

Page 52: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

52

Properties can be required

<view-state id=”viewLoginForm” view=”casLoginView” model=”credentials”>

<binder>

<binding property=”username” required=”true” />

<binding property=”password” required=”true”/>

</binder>

</view-state>

Page 53: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

53

Validation

Validator for model objects Or Validator for model-in-specific-state

As in, you can program custom validators in Java

Page 54: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

54

Selectively validate on transitions

<view-state id="basicInfo" model="portlet">

<transition on="back" to="chooseType"

validate="false"/> <transition on="next" to="setParameters"/>

</view-state>

validate attribute on transition

You might bind but not validate if you want to capture the user input but not prevent transition if the input is invalid.

Page 55: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

55

Say I pick a portlet type

Page 56: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

56

I fill out this form, but...

Page 57: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

57

So I pick another portlet type

Page 58: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

58

And my form data is right there.

Page 59: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

59

Even though it's not valid

Page 60: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

60

Selectively validate on transitions

<view-state id="basicInfo" model="portlet">

<transition on="back" to="chooseType"

validate="false"/> <transition on="next" to="setParameters"/>

</view-state>

validate attribute on transition

You might bind but not validate if you want to capture the user input but not prevent transition if the input is invalid.

Page 61: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

61

PortletDefinitionForm

public class PortletDefinitionForm implements Serializable {

public String getFname() {

return fname;

}

public void setFname(String name) {

fname = name;

}

...

Page 62: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

62

PortletDefinitionFormValidator

public void validateBasicInfo(PortletDefinitionForm def, MessageContext ctx) {

if (StringUtils.isEmpty(def.getFname())) {

ctx.addMessage(new

MessageBuilder().error().source("fName")

.code("fname.required").build());

} else if (!

FunctionalNameType.isValid(def.getFname())) {

ctx.addMessage(new

MessageBuilder().error().source("fName")

.code("fname.invalid").build());

}

}

...

Page 63: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

63

Validate${viewState}()

<view-state id="basicInfo" model="portlet"> <transition on="back" to="chooseType"

validate="false"/>

<transition on="next" to="setParameters"/>

</view-state>

public void validateBasicInfo(PortletDefinitionForm def, MessageContext ctx) {

. . .

}

Page 64: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

64

Scopes

Page 65: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

65

Scopes

Flash scope View Scope Flow Scope Conversation Scope

Page 66: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

66

Flash scope

Cleared when a view is rendered

Page 67: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

67

View Scope

Created when enter view-state Destroyed on exit view-state Useful for transient state for rendering the

view That you might need on processing the event fired

by the user interaction with the view

Or that you need for re-rendering the view

Page 68: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

68

Flow Scope

Created when enter flow Destroyed on exit flow Useful for transient state within the flow

Page 69: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

69

Conversation scope

Persists across returns from subflows

Page 70: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

70

Conclusions

Page 71: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

71

Spring Web Flow in uPortal 4

Many administrative portlets in uPortal 4 implemented using Spring Web Flow

Page 72: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

72

Spring Web Flow in CAS

Page 73: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

73

Spring Web Flow for Portlet Dev

Works with Spring PortletMVC

Page 74: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

74

Spring Web Flow Web Development

Quickly develop self-service web flows Update, maintain, and tweak these

applications with panache

Page 75: Introduction to Spring Web Flow Andrew Petro Software Developer Unicon, Inc. Jasig 2011 Westminster, CO 23 May 2011 © Copyright Unicon, Inc., 2011. Some

75

Contact Information

Andrew PetroSoftware DeveloperUnicon, Inc.

[email protected]/blog/apetro