Open ESB Tip : BPEL 2 SVG Usage Documentation

Following on from my previous blogs and some of Adam's I have noticed that I need to add some more documentation around the usage of the BPEL 2 SVG generator. Therefore the purpose of this blog entry is to do just that. I will take some example code (from the NetBeans Plug-in Action) and explain what each of the parameters and settings achieve.


Related Articles

Documentation


This documentation will describe the process for calling the BPEL 2 SVG converter using the simple Java Classes this is the same method as that used within the NetBeans Plug-in performAction methods below.
 protected void performAction(Node[] activatedNodes) {
EditorCookie editorCookie = activatedNodes[0].getLookup().lookup(EditorCookie.class);
DataObject dataObject = activatedNodes[0].getLookup().lookup(DataObject.class);
try {
//Layout
BPEL2SVGFactory factory = BPEL2SVGFactory.getInstance();
LayoutManager layoutManager = factory.getLayoutManager();
// Set properties defined in the Option Panel
layoutManager.setXSpacing(NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.HORIZONTAL_SPACING_KEY, 20));
layoutManager.setYSpacing(NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.VERTICAL_SPACING_KEY, 50));
layoutManager.setIncludeAssigns(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.INCLUDE_ASSIGN_KEY, true));
layoutManager.setShowSequenceBoxes(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.INCLUDE_BOXES_KEY, true));
layoutManager.setVerticalLayout(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.VERTICAL_LAYOUT_KEY, true));

layoutManager.setAddIconOpacity(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.ADD_ICON_LAYER_KEY, false));
layoutManager.setAddSimpleActivityOpacity(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.ADD_SIMPLE_ACTIVITY_LAYER_KEY, true));
layoutManager.setAddCompositeActivityOpacity(NbPreferences.forModule(GenerateSVGPanel.class).getBoolean(GenerateSVGPanel.ADD_COMPOSITE_ACTIVITY_LAYER_KEY, false));
int iconOpacity = NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.OPACITY_ICON_LAYER_KEY, 20);
int simpleOpacity = NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.OPACITY_SIMPLE_ACTIVITY_LAYER_KEY, 20);
int compositeOpacity = NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.OPACITY_COMPOSITE_ACTIVITY_LAYER_KEY, 100);
layoutManager.setIconOpacity(Float.toString(((float) iconOpacity) / 100));
layoutManager.setSimpleActivityOpacity(Float.toString(((float) simpleOpacity) / 100));
layoutManager.setCompositeActivityOpacity(Float.toString(((float) compositeOpacity) / 100));

factory.setIconSource(NbPreferences.forModule(GenerateSVGPanel.class).get(GenerateSVGPanel.ICON_SOURCE_KEY, GenerateSVGPanel.DEFAULT_ICON_SOURCE));
int startIconDim = NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.START_ICON_DIM_KEY, 48);
int endIconDim = NbPreferences.forModule(GenerateSVGPanel.class).getInt(GenerateSVGPanel.END_ICON_DIM_KEY, 32);
layoutManager.setStartIconDim(startIconDim);
layoutManager.setEndIconDim(endIconDim);

// Get BPEL
InputStream is = ((CloneableEditorSupport) editorCookie).getInputStream();
BPELInterface bpel = new BPELImpl();
String bpelStr = bpel.load(is);
bpel.processBpelString(bpelStr);

// Layout SVG
layoutManager.layoutSVG(bpel.getRootActivity());
// Write SVG
SVGInterface svg = new SVGImpl();
svg.setRootActivity(bpel.getRootActivity());
// System.out.println(svg.getSVGFileAsString());
System.out.println(dataObject.getFolder().getPrimaryFile() + "/" + dataObject.getPrimaryFile().getName() + ".svg");
FileObject svgFileObj = FileUtil.createData(dataObject.getFolder().getPrimaryFile(), dataObject.getPrimaryFile().getName() + ".svg");
DataObject svgDo = DataObject.find(svgFileObj);
File svgFile = new File(svgDo.getPrimaryFile().getPath());
svg.store(svgFile);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} catch (Throwable ex) {
ex.printStackTrace();
}
}
It should be noted that the sequencing of the calls is important because the initialiser of the Activity implementation perform action based on the contents of the BPEL2SVGFactory class. To work correctly the following sequence must be implemented within the Java:
  1. Create new BPEL2SVGFactory Instance
  2. Retrieve LayoutManager
  3. Specify the IconSource location in the BPEL2SVGFactory
  4. Assign layout properties to the LayoutManager
  5. Get BPEL and processBPELString
  6. LayoutSVG for BPEL
  7. Write SVG File
To achieve the desired results you must perform 1 thru 4 before 5.

BPEL2SVGFactory.class


setIconSource(String src)

This method is used to define the base location of the Icons that will be used within the generated SVG. By default this will look for icons at "http://localhost:8080/BPEL2SVGIcons/icons" (hence the application supplied in the previous blog entries). This can be change so if you are building a web application the icons could be included as part of the deployment and hence this could be changed to "icons" and then the icons will be retrieved from <Application URL>/icons.

LayoutManager.class


setXSpacing(int spacing)

Defines the Horizontal spacing between components and defaults to 20.

setYSpacing(int spacing)

Defines the Vertical spacing between components and defaults to 50.

setIncludeAssigns(boolean include)

This defines if the Assign activities are to be included in the generated SVG file. By default this is true but if changed the SVG will be generated with all Activities except for the Assign Activities.

setShowSequenceBoxes(boolean show)

Defines whether boxes should be drawn around the Composite Activities. By default this is true an hence the complex activities will be surrounded by light grey boxes.

setVerticalLayout(boolean vertical)

Defines the layout of the resulting SVG file. By default this is true and a vertical representation will be generated and hence be displayed in the same way as the original BPEL process. Setting this to false will cause the orientation to be switched to a horizontal format similar to the Java CAPS eInsight layout.

setAddIconOpacity(boolean b)

Define if all all icons should be displayed with the opacity defined within the SVG. This will affect all icons that are displayed and by default is set to false. In preference the Simple Activity opacity should be used.

setAddSimpleActivityOpacity(boolean b)

Defines if Simple Activities (Assign, Invoke, Receive, Reply, etc) have their opacity set. This will work in an additive fashion so if the IconOpacity is set then this work on top of that. By default it is set to true because this is the preferred method of setting opacity.

setAddCompositeActivityOpacity(boolean b)

Defines if the Complex Activities (For, Sequence, Pick, etc) have their opacity set. Again this is additive and will wrap the Simple Activities. By default his is false because Simple Activity should be enough.

setIconOpacity(String opacity)

Define the actual opacity percentage to be used. By default this is 50%.

setSimpleActivityOpacity(String opacity)

Define the actual opacity percentage to be used. By default this is 25%.

setCompositeActivityOpacity(String opacity)

Define the actual opacity percentage to be used. By default this is 10%.

setStartIconDim(int dim)

Define the dimensions (in pixels) of the start icon. It is assumed that all icons are square and hence this defines both the width and height. By default this is 48 pixels.

setEndIconDim(int dim)

Define the dimensions (in pixels) of the end icon. It is assumed that all icons are square and hence this defines both the width and height. By default this is 32 pixels.

layoutSVG(BPELInterface bpel)

Takes the bpel Implementation and works through the embedded components calculating the SVG layout and dimensions.

BPELImpl.class


processBPELString(String bpel)

Takes the BPEL file as a string and then processes it converting it into the internal representation, based on the Interfaces & Implementation within the package, and then stores it internally.

SVGImpl.class


getSVGFileAsString()

Takes the previous added top level BPEL process and converts it and all its sub-activities into the SVG representation.

SVGImpl.class


getSVGFileAsString()

Takes the previous added top level BPEL process and converts it and all its sub-activities into the SVG representation.

ActivityImpl.class


The ActivityImpl Class implements all the functionality, define within ActivityInterface, required to calculate the layout, dimensions and positioning of the components within the resulting SVG document. Each Activity that exists within a BPEL 2 process has an Impl class derived from the ActivityImpl and where appropriate the methods within the ActivityImpl class are overridden. During the initial processing of the BPEL file a nested structure of ActivityInterface elements will be built based on the structure in the BPEL. Hence we will start with a single ProcessImpl object and it will contain a reference to each of its direct child Activities. Each of these Children with have a reference to their direct child elements; recursively implementing the structure until we reach one of the Simple Activities (Receive, Invoke, Reply, etc). Once this structure has been build it will be recursed by a number of the other methods.

Each Activity implementation knows how to calculate its own dimensions and given a starting point its child layout. So for example each of the Simple Activities will calculate their Dimensions as the Size of there Start Image plus the appropriate X and Y Spacing whilst a complex Activity, such as a Sequence, will need to calculate its Dimensions as the Sum of its child dimensions plus the appropriate spacings. The exact nature of the Complex Activity calculation depends on the type of activity. Given the default vertical layout a Sequence will need to calculate its height as the sum of its child heights plus the Y Spacing and its width as the maximum of the child widths plus the X Spacing. Conversely a Flow will need to calculate it Width as the sum of the Child Widths plus X Spacing and its height as the maximum child height plus the Y Spacing. Hence each of the Activity Implementation knows how to calculate it own dimensions but knows nothing about any other  activities. Therefore when calculating the dimensions of the SVG the code starts at the lowest level and works up summing appropriately.

Based on this calculation the SVG can be layed out in a similar fashion each Activity knows how to lay its children out give a set of starting coordinates. So for the Simple Activities they need only define the Image location whereas the complex activities need to loop through there children calculating appropriate starting coordinates for each of them.

Once the Activities are layed out correctly the call to getSVGString() will return a String containing all the appropriate tags to display the Activity. This string is dynamically built from Constant String Fragments that represent the appropriate SVG Tag.

For example the getArrowDefinition will return a path definition to define an arrow between one activity and another.

    protected String getArrowDefinition(int startX, int startY, int endX, int endY, String id) {
        StringBuffer svgSB = new StringBuffer();
        svgSB.append("<path\\n");
        svgSB.append("\\td=\\"M " + startX + "," + startY + " L " + endX + "," + endY + "\\"\\n");
        svgSB.append("\\tid=\\"" + id + "\\"\\n");
        svgSB.append(getArrowStyle());
        svgSB.append(" />\\n");
//        System.out.println("Path : "+arrowSB.toString());
        return svgSB.toString();
    }

The Arrow Style references a style defined as part of the ProcessImpl SVG Header generation.


Comments:

Thanks for the new update, Can you describe more about "How the layout manager determine the locations of seperate icons in the SVG layout"

Posted by ddweerasiri on November 06, 2008 at 08:45 AM GMT #

How the arrows are generated for each component?

Posted by njayan on November 07, 2008 at 12:01 AM GMT #

Added an extra section that will hopefully give enough information of how each Activity generates its child layout and connecting arrows.

Posted by guest on November 07, 2008 at 06:41 AM GMT #

Post a Comment:
Comments are closed for this entry.
About

As a member of the Oracle A-Team we specialise in enabling and supporting the Oracle Fusion Middleware communities.

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today