Fusion Middleware
Give Back/Help Out
These don't even begin to scratch the surface of great organizations that offer great ways to help others. I listed these because I know a bit more about them personally and I'm confident that they do good (efficiently!). Another good friend, Edwin, recently added a blog post on Abilities United, which works with kids experiencing challenges in development and gives them special attention based on their needs. Take a careful look at Abilities United: they deserve support and all the help they can get.
Estimating global delivery - Don't toe the line
What is OpenID Good For? Lots!
Latest Wordle
Quarterly Customer Update Sept 10 - Mark it Down!
Hello Dallas, meet Bangalore
A little more on OpenID adoption
Web 2.0 Peer Pressure
Oracle Community Call For ECM
In case you didn't get the invite, Oracle's quarterly ECM community seminar is in about three weeks...
Americas / EMEA time zones: Customer UpdateSeptember 10, 2008
9:00am US PDT / 12:00pm US EDT / 16:00 GMT
You can register early... and just like last time, this is for Oracle customers and select partners only... There's a repeat webcast for Asia-Pacific at 7pm US Pacific time (12:00pm Sydney AEST, 10:00am Singapore).
If you missed the previous ones, they're up on Metalink. The last one covered how to find Stellent resources in Metalink... as well as Universal Online Archive, Captovation, what's going on with Verity, important patches, and general news items.
Put it on your calendar now!
Flex upload and download with Blazeds
To use the new FileReference features please read these two articles flexexamples.com and using flashplayer 10
Here are some screenshots of the flex application.
First we can upload a file. The datagrid show the status of the uploaded files.

Off course we can download some files from a remote server. First we need to get a list of the remote files. For this we need to press the Get remote files button.

We can select a file and press the Retrieve File Button. When the status is ready we can save this file by pressing the Save File Button.

Here you can download the Flex source code
The code of the upload panel
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" width="100%" height="100%"
title="Upload Files">
<mx:Script>
<![CDATA[
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private var refUploadFile:FileReference;
private var UploadFiles:Array = new Array();
// Called to add file(s) for upload
private function addFiles():void {
refUploadFile = new FileReference();
refUploadFile.browse();
refUploadFile.addEventListener(Event.SELECT,onFileSelect);
refUploadFile.addEventListener(Event.COMPLETE,onFileComplete);
}
// Called when a file is selected
private function onFileSelect(event:Event):void {
UploadFiles.push({ name:refUploadFile.name,
size:formatFileSize(refUploadFile.size),
status:"initial"});
listFiles.dataProvider = UploadFiles;
listFiles.selectedIndex = UploadFiles.length - 1;
refUploadFile.load();
for ( var i:int = 0 ; i < UploadFiles.length ; i++ ) {
if( UploadFiles[i].name == refUploadFile ) {
UploadFiles[i].status = "loaded";
listFiles.dataProvider = UploadFiles;
break;
}
}
}
// Called to format number to file size
private function formatFileSize(numSize:Number):String {
var strReturn:String;
numSize = Number(numSize / 1000);
strReturn = String(numSize.toFixed(1) + " KB");
if (numSize > 1000) {
numSize = numSize / 1000;
strReturn = String(numSize.toFixed(1) + " MB");
if (numSize > 1000) {
numSize = numSize / 1000;
strReturn = String(numSize.toFixed(1) + " GB");
}
}
return strReturn;
}
private function onFileComplete(event:Event):void
{
refUploadFile = event.currentTarget as FileReference;
var data:ByteArray = refUploadFile.data;
var loader:Loader = new Loader();
loader.loadBytes(data);
var token:AsyncToken = AsyncToken(
remoteUpload.doUpload(data, refUploadFile.name)
);
token.kind = refUploadFile.name;
for ( var i:int = 0 ; i < UploadFiles.length ; i++ ) {
if( UploadFiles[i].name == refUploadFile ) {
UploadFiles[i].status = "upload";
listFiles.dataProvider = UploadFiles;
break;
}
}
}
private function uploadResultHandler(event:ResultEvent):void
{
for ( var i:int = 0 ; i < UploadFiles.length ; i++ ) {
if( UploadFiles[i].name == event.token.kind ) {
UploadFiles[i].status = "finished";
listFiles.dataProvider = UploadFiles;
break;
}
}
}
private function faultResultHandler(event:FaultEvent):void
{
for ( var i:int = 0 ; i < UploadFiles.length ; i++ ) {
if( UploadFiles[i].name == event.token.kind ) {
UploadFiles[i].status = "error";
listFiles.dataProvider = UploadFiles;
break;
}
}
}
]]>
</mx:Script>
<mx:RemoteObject id="remoteUpload" destination="FileUtils"
result="uploadResultHandler(event)"
fault="faultResultHandler(event)"/>
<mx:Canvas width="100%" height="100%">
<mx:DataGrid id="listFiles" left="0" top="0" bottom="0" right="0"
allowMultipleSelection="true" verticalScrollPolicy="on"
draggableColumns="false" resizableColumns="false" sortableColumns="false">
<mx:columns>
<mx:DataGridColumn headerText="File" width="150" dataField="name" wordWrap="true"/>
<mx:DataGridColumn headerText="Size" width="50" dataField="size" textAlign="right"/>
<mx:DataGridColumn headerText="Status" width="50" dataField="status" textAlign="right"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
<mx:ControlBar horizontalAlign="center" verticalAlign="middle">
<mx:Button id="btnAdd" toolTip="Add file(s)" click="addFiles()"
label="Upload Files" width="150"/>
</mx:ControlBar>
</mx:Panel>
The code of the download panel
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
width="100%" height="100%" title="Download Files">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.AsyncToken;
private var UploadFiles:Array = new Array();
private var UploadFilesColl:ArrayCollection = new ArrayCollection();
private var fileData:ByteArray = new ByteArray();
private var fileName:String;
private function uploadResultHandler(event:ResultEvent):void
{
if ( event.token.kind == "remoteFileList") {
UploadFilesColl = event.result as ArrayCollection;
for ( var i:int = 0 ; i < UploadFilesColl.length ; i++ ) {
UploadFiles.push({ name:UploadFilesColl[i]
, status:"initial"});
}
listFiles.dataProvider = UploadFiles;
} else {
fileData = event.result as ByteArray;
fileName = event.token.kind;
for ( var b:int = 0 ; b < UploadFiles.length ; b++ ) {
if( UploadFiles[b].name == event.token.kind ) {
UploadFiles[b].status = "Ready";
listFiles.dataProvider = UploadFiles;
break;
}
}
}
}
private function faultResultHandler(event:FaultEvent):void
{
}
private function saveFile(event:Event):void
{
var fileReference:FileReference = new FileReference();
fileReference.save(fileData,fileName);
}
private function getRemoteFiles(event:Event):void
{
var token:AsyncToken = AsyncToken(remoteDownload.getDownloadList());
token.kind = "remoteFileList";
}
private function getDownload(event:Event):void
{
var token:AsyncToken = AsyncToken(
remoteDownload.doDownload(listFiles.selectedItem.name));
token.kind = listFiles.selectedItem.name;
}
]]>
</mx:Script>
<mx:RemoteObject id="remoteDownload" destination="FileUtils"
result="uploadResultHandler(event)"
fault="faultResultHandler(event)"/>
<mx:Canvas width="100%" height="100%">
<mx:DataGrid id="listFiles" left="0" top="0" bottom="0" right="0"
verticalScrollPolicy="on"
draggableColumns="false" resizableColumns="false" sortableColumns="false">
<mx:columns>
<mx:DataGridColumn headerText="File" width="150" dataField="name" wordWrap="true"/>
<mx:DataGridColumn headerText="Status" width="50" dataField="status" textAlign="right"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
<mx:ControlBar horizontalAlign="center" verticalAlign="middle">
<mx:Button id="btnList" toolTip="List remote files"
width="150"
label="Get Remote Files"
click="getRemoteFiles(event)"/>
<mx:Button id="btnRetrieve" toolTip="Retrieve file"
width="150" click="getDownload(event)" label="Retrieve File"/>
<mx:Button id="btnSave" toolTip="Save file"
width="150" click="saveFile(event)" label="Save File"/>
</mx:ControlBar>
</mx:Panel>
The java code
package nl.ordina.flex;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
public class FileUtils {
public String doUpload(byte[] bytes, String fileName) throws Exception
{
fileName = System.getProperty("java.io.tmpdir") + "/" + fileName;
File f = new File(fileName);
FileOutputStream fos = new FileOutputStream(f);
fos.write(bytes);
fos.close();
return "success";
}
public List getDownloadList()
{
File dir = new File(System.getProperty('java.io.tmpdir'));
String[] children = dir.list();
List dirList = new ArrayList();
if (children == null) {
// Either dir does not exist or is not a directory
} else {
for (int i=0; i<children.length; i++) {
// Get filename of file or directory
dirList.add( children[i]);
}
}
return dirList;
}
public byte[] doDownload(String fileName)
{
FileInputStream fis;
byte[] data =null;
FileChannel fc;
try {
fis = new FileInputStream(System.getProperty("java.io.tmpdir") + "/" + fileName);
fc = fis.getChannel();
data = new byte[(int)(fc.size())];
ByteBuffer bb = ByteBuffer.wrap(data);
fc.read(bb);
} catch (FileNotFoundException e) {
// TODO
} catch (IOException e) {
// TODO
}
return data;
}
}
How to do a "desc emp" from JDBC
Firstly here is what we get when we describe the EMP table in SQL*Plus.
SCOTT@linux10g> desc emp;
Name Null? Type
----------------------------------- -------- ------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
Now here is the SQL we can use to get the same output from an SQL query.
select
column_name as "Name",
decode(NULLABLE, 'Y', '', 'N', 'Not Null') as "Null",
data_type||decode(data_type,
'NUMBER', decode(DATA_PRECISION, NULL, '',
'('||DATA_PRECISION||','||data_scale||')'),
'VARCHAR2', '('||data_length||')',
'CHAR', '('||data_length||')') as "Type"
from user_tab_columns
where table_name = 'EMP'
The output of that is as follows from the query above , identical to a "desc emp", or close enough, couple more decodes will sort out a few minors issues , but seems to work for most tables I tested it against.
Name Null Type
------------------------------ -------- ------------------------------
EMPNO Not Null NUMBER(4,0)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4,0)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2,0)
So with a bind variable defined it would simply be as follows
select
column_name as "Name",
decode(NULLABLE, 'Y', '', 'N', 'Not Null') as "Null",
data_type||decode(data_type,
'NUMBER', decode(DATA_PRECISION, NULL, '',
'('||DATA_PRECISION||','||data_scale||')'),
'VARCHAR2', '('||data_length||')',
'CHAR', '('||data_length||')') as "Type"
from user_tab_columns
where table_name = ?
And then easily be integrated into a JDBC program, I did this over the web using a JSP page, which lists all user tables and adds a DESCRIBE button next to the table name to get the output above when clicked.http://feeds.feedburner.com/TheBlasFromPas
Cisco launches Russia/CIS fund
We're Number 1! We're Number 1!
We're Number 1! At least according to Gartner
Check out Insightory
Setting the high level services.
Enterprise 2.0 - sometimes its like that
Forget "Knowledge Management", Focus on "Context Management"
I was always bugged with the buzzword "Knowledge Management." Not because it is a buzzword... but because it appears to NOT be a buzzword. A buzzword should either be really concrete, or vague enough to lead to questions -- like "Enterprise 2.0." Instead, "Knowledge Management" is somewhere in the middle, and sounds like annoying advice:
- The key to getting rich is making more money!
- The key to winning races is going faster!
- The key to a smarter enterprise is managing your knowledge!
As such, I feel that the very phrase "Knowledge Management" might have led people to ask the wrong questions, and implement the wrong solutions... I think Chuck Klein down here in Albuquerque said it best:
We don't need "Knowledge Management." We need knowledge capture and context management.
That puts it pretty well... the goal is to capture as much knowledge as you can, and store it safely and securely. At the same time, you need to constantly gather more and more context, so you know what information to get to which people, and when. Information without context is worse than useless: its merely clutter that wastes everyone's time.
Too many projects lose focus on the context management problem... some of the easy questions revolve around things like metadata and keywords, but that is rapidly becoming insufficient. As the amount of information you manage gets larger and larger, you need to ask a lot of hard questions before you can maximize the value of your system:
- Who is the intended audience for this item?
- Where does this item fit in my taxonomy?
- If people like this document, what related items would they like?
- How would people find this item, if your search engine did not exist?
- Under what conditions should we archive this item to reduce clutter?
- Under what conditions should we destroy this item to save storage space, and mitigate risk?
- Who is the current user?
- Where is this user, and how are they accessing the system?
- What is the user's search, download, and feedback history?
- What is the most effortless way to gather feedback from this user?
- Based on this user's past behavior, what information are they likely to want next?
Some good Knowledge Management folks already ask these kinds of questions... but I feel that not enough clients understand what kinds of questions to ask. If we used more specific terminology -- like context management -- it gets people thinking about the problem in a very concrete way... and I feel would lead to better implementations.



