Pages

Wednesday, June 25, 2008

Flex embedded youtube player 1.1

A new version 1.2 is out click here, A few weeks ago I already made a blog about the flex embedded youtube player. This blog is about version 1.1. You can use this youtube player in your own website. You don't have to use a proxy or php script. You only has to update a xml with your own youtube video url's. This xml is loaded in a tree and just click on an entry. The selected video is shown in the video window.
Version 1.1 change list.
  • I now use a Tree for the movies overview so I know when a node is a branch and when it is a youtube movie.
  • Search your movies.
  • The player now supports bookmarks, you can add #video=101 to the page url and the player directly plays movie 101.
To let bookmarking work we have to add a css and javascript reference to the html page where the flash is embedded.
<!-- BEGIN Browser History required section -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!-- END Browser History required section -->
<!-- BEGIN Browser History required section -->
<script src="history/history.js" language="javascript"></script>
<!-- END Browser History required section -->

Here is a screenshot of the new player



For version 1.1 I had to change the xml. Every element has the name "node" and has to have the id and category attribute. Id is necessary for the bookmarking and category is necessary for the search and the label.

<node id="0" category="main">
<node id="0" category="own">
<node id="101" category="viper" url="http://www.youtube.com/v/ejlbNl3y5y8"/>
</node>
<node id="0" category="race">
<node id="0" category="European">
<node id="2012" category="Bauska 2008" url="http://www.youtube.com/v/c9BqEm7zxU4"/>
<node id="2010" category="autocross photo's" url="http://www.youtube.com/v/SMshJRp1YR8"/>
</node>
</node>
<node id="0" category="etc">
<node id="301" category="cross movie" url="http://www.youtube.com/v/VLlrpOUO3Qs"/>
</node>
</node>

Here is the source code of the new youtube player

Monday, June 23, 2008

For the Dutch people: Oproep enquête

Names een ordina collega Peter Minkjan een oproep om mee te doen aan een enquete over corporate blogs. Hier bij zijn oproep.
Een paar jaar geleden kwamen (corporate) blogs enorm in opkomst. Nu lijkt de interesse in dit fenomeen wat aan het afnemen. Toch onderhouden veel bedrijven een eigen blog. Vooral in de ICT branche zijn er veel organisaties die een corporate blog hebben. Als student bedrijfskunde doe ik op dit moment onderzoek naar corporate blogs van ICT bedrijven. Ben jij werkzaam in de ICT branche? En bezoek jij wel eens corporate blogs? Dan ben jij de ideale respondent voor mijn enquête. Deze kan je invullen via deze link. Het invullen van de enquête kost je slechts 5 minuten. Door de enquête in te vullen lever je een belangrijke bijdrage aan mijn onderzoek. De gegevens worden anoniem verwerkt. Hopelijk kan ik rekenen op jullie medewerking, alvast hartelijk bedankt voor de moeite.

Ik zal de resultaten van de enquête hier posten.

Sunday, June 22, 2008

Advanced TaskFlow Train Features

In this blog I will explain you more about some features of a bounded taskflow train. A train is a wizard with stops or steps which helps the user to complete the transaction. In this blog I'll show how you can skip or disable a train stop, this can be handy when a user already did this step or this step is in this case not necessary. The second part of the blog explains how you can use a other taskflow as a train stop.Here an example of a train with four steps. If you the user to go from step 1 to Step 3 we have to set the sequential to false. You can always use a method in a bean to control this To disable a step we have to add true to the skip flied of the property editor of a train stop.
You don't only have to use views for the train stops you can also use bounded taskflows as a train stop. This taskflow has to be a bounded train with only one view page and a taskflow return ( else you can't navigate back to the main train). Here is an example of the main train taskflow.
Train_step2-flow-definition is the sub train taskflow. You can see I have added two control flow cases next and previous to this taskflow, else we can't navigate to step 1.5 and step3 from this sub taskflow. Next and previous are the outcome values of the two taskflow returns. Here you can see an example of the sub train taskflow. The two taskflow returns have the outcome values next and previous. I have to add two buttons to the step2 page which call the next or previous action. At last a more complex example of a train. You can find this example in the oracle documentation. It gives an impression what you can do in taskflow.

Wednesday, June 18, 2008

ODTUG ADF & SOA highlights

This week I saw a lot of interesting things about ADF and Soa suite 11G. Clemens Utschig did show in BPEL how to use the sdo webservice created with adf bc and use this in a bpel bind entity activity. The bind entity can be used to update a particuler record without using a database adapter, it binds to the sdo web service. You can use the xslt editor to put in a new value on a element and the soa suite updates the right record in the database. And off course the soa suite is all about events. Publish an event from ADF or from a Complex event processing (CEP) and use a Mediator which can listen for these event. You may think why this is important. It is very important because in the old days you have to make one big process. This can be a very complex process. With events you can split up this big process in smaller parts which are much easier to maintain.
Duncan Mills did some nice ADF demo with excel as a gui client. He had a webapp where a flash graph is shown. He opens the excel document and the data was retrieved from the webapp (this is done with a servlet , no odbc). Duncan updates the data in excel and the graph detects the updated records and refreshes the graph. There will be an adf installer for office with this you can create a excel document, which can cummunicate with ADF in the webapp. This installer will be released in Jdev 11g TP6.
Steven Davelaar did a nice presentation how JSF components internally work and what the impact of the immediate option is. He also presented with Wilfred van der Deijl the new JHeadstart with OraFormsFaces integration. With this solution you can easily generate new webapp and embed your existing Oracle Forms into this webapp. So you can mix new and old technology and generate it all with jheadstart.

Monday, June 16, 2008

ADF Faces templating in 10.1.3

Today I attended a presentation of Peter Koletzke at ODTUG, where he explains that jsf templating is possible in jdeveloper 10.1.3, so let's give it a try. Steve Muench wrote a nice article in the oracle magazine over how you can do it in 11G. In 10.1.3 this is called regions and JHeadstart is using this for branding, menu tabs etc. In this blog I will show you the basics how it works. The First step is to know what to template in your application. In my case I want to template the header of the page and the menu buttons. We need to make a new file called region-metadata.xml and put this in the web-inf folder. In this file we create templates entries.

<?xml version="1.0" encoding="windows-1252"?>
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<component>
<component-type>nl.ordina.jsf.templating.Header</component-type>
<component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
<component-extension>
<region-jsp-ui-def>/regions/header.jspx</region-jsp-ui-def>
</component-extension>
</component>
<component>
<component-type>nl.ordina.jsf.templating.Menu</component-type>
<component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
<attribute>
<attribute-name>name</attribute-name>
<attribute-class>java.lang.String</attribute-class>
<default-value>empty</default-value>
<attribute-extension>
<required>false</required>
</attribute-extension>
</attribute>
<component-extension>
<region-jsp-ui-def>/regions/menu.jspx</region-jsp-ui-def>
</component-extension>
</component>
</faces-config>
The things you should know, give an unique value to the component-type element of the template component.
This is important because your need this value to reference it in the jsf page. What is the path to region jsf page, this is defined in the region-jsp-ui-def and do I need to pass variables from the.Now we can create the menu template jsf page

<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
xmlns:af="http://xmlns.oracle.com/adf/faces">
<jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
doctype-system="http://www.w3.org/TR/html4/loose.dtd"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
<af:regionDef var="menu">
<af:menuBar>
<af:commandMenuItem text="#{menu.name}" action="start" />
</af:menuBar>
</af:regionDef>
</jsp:root>

In the template page we have to define the regionDef component and by using the attribute var we can reference the template variables defined in the region-metadata.xml. In my case I can use #{menu.name} to get value of the main page.

<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:af="http://xmlns.oracle.com/adf/faces">
<jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
doctype-system="http://www.w3.org/TR/html4/loose.dtd"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
<jsp:directive.page contentType="text/html;charset=windows-1252"/>
<f:view>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>main</title>
</head>
<body>
<af:messages/>
<h:form>
<af:panelPage title="Mainpage">
<f:facet name="menuGlobal">
<af:region id="menu" regionType="nl.ordina.jsf.templating.Menu">
<af:attribute name="name" value="MainPage"/>
</af:region>
</f:facet>
<f:facet name="branding">
<af:region id="header" regionType="nl.ordina.jsf.templating.Header"/>
</f:facet>
<af:outputText value="bodytext"/>
</af:panelPage>
</h:form>
</body>
</html>
</f:view>
</jsp:root>

In the main page we have to use a region component to reference the template page. The value of the regionType attribute must be the same as the region-metadata.xml. Because this template has also an attribute, we have to define an child element with the name attribute. Make sure if you using a template variable then you need create the region component inside a panel component else the variables are empty. You are now ready to run the main page

Tuesday, June 10, 2008

Openesb & Soa Suite comparison

Last week I have been testing the glassfish openesb opensource soa platform and I am very surprised to see how far the opensource community is. Ok I think it is not so far as Oracle but give it some time and it will be a strong soa suite for free. The main difference is there is no mediator or esb part in openesb like Oracle has. The second difference Oracle has a esb and bpel console where you can see the soa processes. In the esb console you can change the esb processes at runtime. In openesb you have to do with the output console of glassfish server. There are also positive things about openesb. I like the xlst mapper it even knows anytype type and you don't have to add many copy entries in the bpel assign step ( you can do this in one xslt window). More important you have to configure the wsdl for the bpel and the adapters yourself. This is a great advantage for experience developers, you now know what it does because you have to configure it yourself. In Oracle Soa Suite you have a lot of wizards which helps you to create a esb or bpel process. You don't have to know how it works internally. This is fine untils you got a error or you have performance problems.
Here you see the components which you can use in the openesb BPEL designer
The BPEL process with on the left side the bpel web service with the request and response. On the right a partnerlink for the file adapter and the jdbc partnerlink ( database adapter in Oracle). Openesb provides a wizard which generates the wsdl for the jdbc adapter.
The xslt editor of the assign step.
Openesb gives you the option to create a composite project ( Oracle has this in Soa Suite 11g) where you can import the bpel projects as a jar. In the composite project you can use many adapters and deploy it as one project to the glassfish server
Here a example of a composite project where a bpel project is added as jbi module. I also connected an file adapter and activemq jms adapter to the bpel process.
Openesb has a great future and let's hope it will be a great or the best soa suite there is.

Friday, June 6, 2008

Flex embedded youtube player

There is a new version 1.1, Click on this entry to go to that version.
In this blog I will provide you the Adobe Flex code to create your own embedded youtube player which you can use in own website. You don't have to use a proxy or php script. You only has to update a xml with the youtube video urls. This xml is loaded in a tree and just click on an entry. The selected video is shown in the window. You can display your own text over the video too.


The xml with the youtube videos looks like this

<videos category="overview">
<category category="2008">
<video category="auto cross movie" url="http://www.youtube.com/v/VLlrpOUO3Qs"/>
</category>
<category category="European">
<year category="2007">
<video category="Autocross Championship - Murça 1" url="http://www.youtube.com/v/8TZgXfqpd5I"/>
</year>
</category>
<category category="Netherlands">
<year category="2007">
<video category="EUROPOKAL AutoCross" url="http://www.youtube.com/v/kprW-snP5oI"/>
<video category="VEKA NK AutoCross Visvliet" url="http://www.youtube.com/v/5OxVm-p0mC0"/>
</year>
</category>
</videos>

You can easily extend this xml with extra levels or video's you only have to add a new element with an attribute with the name category. For a you tube video entry you have to add two attributes category and url.
Here is the source code
The main code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
backgroundGradientAlphas="[1.0, 1.0]"
backgroundGradientColors="[#CCCCCC, #CCCCCC]"
creationComplete="service.send()" height="700" width="875">

<mx:Style>
@font-face {
src:url("assets/arial.ttf");
font-family: Arial;
}

.timeStyle {
color: #FFFFFF;
font-family: Arial;
font-size: 12;
}

.playPauseStyle {
/* play button skins */
skin: Embed('assets/control_play.png');
downSkin: Embed('assets/control_play_blue.png');

/* pause button skins */
selectedUpSkin: Embed('assets/control_pause.png');
selectedOverSkin: Embed('assets/control_pause.png');
selectedDownSkin: Embed('assets/control_pause_blue.png');
}

.stopStyle {
skin: Embed('assets/control_stop.png');
downSkin: Embed('assets/control_stop_blue.png');
}

.controllerStyle {
bottom: 5;
left: 5;
right: 5;
paddingBottom: 5;
paddingLeft: 5;
paddingRight: 5;
paddingTop: 5;
alpha: 0;
background-color: #000000;
background-alpha: 0.5;
}
</mx:Style>


<mx:Script>
<![CDATA[
import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
import mx.collections.HierarchicalData;
import mx.collections.XMLListCollection;
import mx.events.MetadataEvent;
import mx.utils.ObjectUtil;
import mx.events.VideoEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;

[Bindable]
private var youtubeOverLay:String = "You tube player";


private function videoDisplay_metadataReceived(evt:MetadataEvent):void {
var arr:Array = [];
var item:String;
var meta:Object = evt.info; // videoDisplay.metadata;
var value:*;
for (item in meta) {
if (ObjectUtil.isSimple(meta[item])) {
if (meta[item] is Array) {
value = "[Array]";
} else {
value = meta[item]
}
arr.push({name:item, value:value});
}
}
arr.sortOn("name", Array.CASEINSENSITIVE);
dataGrid.dataProvider = arr;
// dataGrid.visible = true;
}

private function showControls():void {
fadeIn.play([controls]);
}

private function hideControls():void {
fadeOut.play([controls]);
}

private function videoDisplay_playheadUpdate(evt:VideoEvent):void {
var pTime:Date = new Date(videoDisplay.playheadTime * 1000 || 100);
var tTime:Date = new Date(videoDisplay.totalTime * 1000);
time.text = dateFormatter.format(pTime) + " / " + dateFormatter.format(tTime);
// time2.text = "Tijd " + dateFormatter.format(pTime) + " / " + dateFormatter.format(tTime);

}

private function playPauseButton_click(evt:MouseEvent):void {
if (videoDisplay.playing) {
videoDisplay.pause();
} else {
videoDisplay.play();
}
}

private function stopButton_click(evt:MouseEvent):void {
videoDisplay.stop();
}

private function doStateChange(evt:VideoEvent):void {


switch (evt.currentTarget.state) {
case VideoEvent.CONNECTION_ERROR:
evt.currentTarget.visible = false;
Alert.show(evt.currentTarget.source, "Unable to connect to video");
break;
}
}


private var vidRequest:YouTubeVideo;
private var flvURL:String;
private var youtubeXml:XML;

public function getVideoURL():void
{
vidRequest = new YouTubeVideo(adg1.selectedItem.@url);
vidRequest.addEventListener(YouTubeVideoEvent.COMPLETE, onVideoComplete);
}

private function onVideoComplete(evt:YouTubeVideoEvent):void
{
flvURL = evt.video;
videoDisplay.source = flvURL;
videoDisplay.load();
copyToClipboard();
}

private function copyToClipboard():void
{
flash.system.System.setClipboard(flvURL);
}

private function resultHandler(event:ResultEvent):void {
youtubeXml = event.result as XML;

// init the tree
adg1.dataProvider= new HierarchicalData(youtubeXml);
var columns:Array = [];
var col:AdvancedDataGridColumn = new AdvancedDataGridColumn();
col.dataField = "@category";
col.headerText = "Video";
columns.push(col);
adg1.columns = columns;


}

]]>
</mx:Script>

<mx:HTTPService id="service" url="videos.xml"
result="resultHandler(event)"
resultFormat="e4x"
useProxy="false"
showBusyCursor="true" />

<mx:Fade id="fadeIn" alphaFrom="0.0" alphaTo="1.0" />
<mx:Fade id="fadeOut" alphaFrom="1.0" alphaTo="0.0" />

<mx:DateFormatter id="dateFormatter" formatString="NN:SS" />



<mx:HBox width="100%" borderColor="#CCCCCC" backgroundColor="#CCCCCC">
<mx:VBox>
<mx:HBox>
<mx:ApplicationControlBar width="100%">
<mx:Button label="expand all" click="adg1.expandAll()" />
<mx:Button label="collapse all" click="adg1.collapseAll()" />
</mx:ApplicationControlBar>
</mx:HBox>


<mx:AdvancedDataGrid x="75" y="27" id="adg1" width="300" height="500" selectionMode="singleRow"
click="getVideoURL()" themeColor="#91280B" creationComplete="adg1.expandAll();">
</mx:AdvancedDataGrid>


</mx:VBox>
<mx:VBox width="100%" height="100%">
<mx:VBox width="100%">
<mx:Text text="{adg1.selectedItem.@category}" fontSize="16" width="100%" fontWeight="bold" color="#91280B"/>
<mx:Text text="Move your mouse on the video to control it" fontSize="12" width="100%" fontWeight="bold" color="#000000"/>

</mx:VBox>

<mx:Canvas rollOver="showControls()" rollOut="hideControls()">
<mx:VideoDisplay id="videoDisplay"
autoPlay="true"
visible="true"
ready="videoDisplay.visible = true; progressBar.visible = true ; "
metadataReceived="videoDisplay_metadataReceived(event);"
playheadUpdate="videoDisplay_playheadUpdate(event)"
stateChange="doStateChange(event);" height="400" width="500" />
<mx:HBox id="controls" styleName="controllerStyle" alpha="0.0">
<mx:Text text="{youtubeOverLay}" x="10" y="50" fontSize="12" width="100%" fontWeight="bold" color="#91280B"/>

<mx:Button id="playPauseButton" styleName="playPauseStyle" toggle="true" selected="{videoDisplay.playing}" click="playPauseButton_click(event)" />
<mx:Button id="stopButton" styleName="stopStyle" click="stopButton_click(event)" />
<mx:Spacer width="100%" />
<mx:Label id="time" styleName="timeStyle" />
</mx:HBox>
</mx:Canvas>


<mx:VBox width="100%">
<mx:ProgressBar id="progressBar" color="#91280B" barColor="#CCCCCC"
visible="false" width="{videoDisplay.width}"
mode="polled"
source="{videoDisplay}"
label="%1 of %2 KB loaded (%3%%)"
conversion="1024"
labelPlacement="center" />
<!-- <mx:Label id="time2" styleName="timeStyle" /> -->

</mx:VBox>
<mx:HBox>
<mx:Button id="aan" visible="true" click="dataGrid.visible = true; aan.visible = false; uit.visible = true;" label="Details on"/>
<mx:Button id="uit" visible="false" click="dataGrid.visible = false; uit.visible = false; aan.visible = true;" label="Details off"/>
</mx:HBox>
<mx:DataGrid id="dataGrid" visible="false" width="100%">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Name:" sortable="false" />
<mx:DataGridColumn dataField="value" headerText="Value:" sortable="false" />
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:HBox>
</mx:Application>