Wednesday, December 9, 2009

Ora-02429 cannot drop index used for enforcement of unique/primary key

There are multiple reasons why Ora-02429 error may happen. I encountered this problem while deleting tablespace dedicated to indexes in the product we are using.

One may want to try following options:

  1. Use "cascade constraints" e.g. drop tablespace [name of ts] cascade constraints;
  2. check what objects are in this tablespace and move these to some where else and drop the tablespace.
  3. alter index [indexname] rebuild [tablespacename]; (this is because, rowid's will change when a table is moved/re-org)
  4. If you are trying to delete tablespace which is still referenced by any user; you need to make sure either users are removed (recursively) and that there are no data related to any user in there. Delete the user (Schema) with all the objects and it should free up any references.

For me the last option worked!

Tuesday, December 8, 2009

Helpful SQL Scripts

There may come a time for database developers to perform bulk operations e.g. compile all the stored procedures or rebuild all the indices. This might be required esp. when you are supporting a product and have to upgrade it.

I had to do this with help of oracle XE instance with only a web interface and here is the solution I developed.

Recompiling All Procedures:

begin
declare
cursor c_proc is
select object_name from user_objects where object_type = 'PROCEDURE';
v_sql varchar2(512);

begin
for c_proc_rec in c_proc LOOP
v_sql := 'ALTER PROCEDURE 'c_proc_rec.object_name' COMPILE';
execute immediate v_sql;
END LOOP;

end;
end;


Rebuilding all indexes:
This might be required after inserting thousands of rows as part of product upgrade. Here is the script that I used.


begin
begin
declare
cursor c_idx is
select index_name from user_indexes where index_type = 'NORMAL' and uniqueness = 'NONUNIQUE';
v_sql varchar2(512);

begin
for c_idx_rec in c_idx LOOP
v_sql := 'Alter index 'c_idx_rec.index_name' rebuild';

execute immediate v_sql;
END LOOP;
end;
end;


Hope this helps!

Monday, December 7, 2009

Restarting a Windows XP when connected over Remote Desktop

If you ever have to connect to a windows machine over remote desktop and have to shut it down; it might not be straight forward to shutdown / restart the remote machine.

Here is a simple work around that I could find. Please note that the remote desktop program by design disables the shutdown option when connected.

"Shutdown" is the utility and can be invoked from command prompt. If you have access to command prompt - run the following command and you should see a dialoguebox displaying countdown to shutdown.

C:\>shutdown -s

please note that if you don't pass any arguments; the command will list all available parameters that "shutdown" utility can take as arguments.

Following command will restart the machine.

C:\>shutdown -r

Hope this helps...

Monday, November 30, 2009

Importance of Traceability

With the fast pace industry – it becomes imperative to understand how any change impacts you. I am sure most of us try to calculate this mentally and can narrate most of the impacts. In daily life we do this subconsciously and intuitively that seldom we notice this. And since humans perform the actions off of his brains – there is a chance of human error. The way to avoid the margin of error is to define a process. A process will be based on a methodology and guidelines that will help us derive outcomes which sometimes go overlooked and cause disasters.

In software world – methodology is what helps maintain a discipline. We were pitching in at a new client who is in the business of oil trading. They implemented complex trading system and the implementation was Rapid Application Development. A flip side of the implementation approach was that it sometimes overlooks the documentation. Documentation has been a secondary priority and in the process to keep showing progress, they are always neglected by developers, designers and testers.

Let’s think about a few scenarios:

  1. Sometimes a good project execution will ensure right amount of relevant documentation is in place but documents produced at the end of the project execution is voluminous enough to be unmanageable
  2. Sometimes the application will change hands between implementation and maintenance team. New people join team old people leave team and KT for a few hours during the hand off process is not sufficient enough to provide coverage for every document produced during implementation.
  3. Sometimes documentation is present but one needs to identify which is the area where the documentation is missing or can be improved.
  4. A new requirement is being introduced half way thru the implementation and one needs to determine where all places the change will impact and what all documentation will have to be changed
  5. Software upgrade is scheduled in 3rd year of implementation and impact analysis is required

Unless there is a map that leads from and links all the requirements to the configuration / implementation details – the task will become rather manual and time consuming and unreliable.

These pain points bring us to Traceability of change in an application. Traceability becomes all-the-more important once the application enters maintenance phase. There has to be a matrix which will explain the requirements and map it back to low level technical requirements, design, implementation, configuration artifacts associated with it including the coverage of QA on different environment.

I have noticed tremendous help a matrix like this provides to the Clients, maintenance team, the developers and testers.

Please feel free to get in touch if you need to learn more about traceability to me.

Tuesday, November 10, 2009

Mailbox Size in Corporate World - A Rant...

Advent of Data Centers, and Cloud Computing opens up a whole new infinite window of opportunity for IT Infrastructure. It liberates us from small time computing and space constraints. I still remember how we treasured the fact when Yahoo! Announced to increase the mailbox size from 25MB to 100MB in April 2004. Google Mail used to lead the bandwagon by providing 2 GB space. And then almost every tom dick and harry email provider offered unlimited mailbox size.

I wonder when the IT companies will start looking at ways and means to making this available to an average employee. I am constrained with 100MB storage on Exchange Server and there is no way I can retrieve emails older than 6 months unless... I keep taking backup manually. It becomes really frustrating when I have to search something that I sent last year to my clients. Taking a backup on my PC and synchronizing the emails with Laptop again is a big pain.

E-mails is the most critical means of running every day business. I wonder if putting a restriction on email box for people will *not* have an impact on business. Every time I miss an email / have to re-create information in my email; I end up wasting my precious time. Either that gets billed to the clients or makes me work long hours if I don’t want that to happen. Think about the magnitude of effort when 80,000 employees spending 15 minutes every day re-creating information in emails. It will be 20,000 man hours i.e. 2500 man days. And if we look at it from Cost perspective; (Assuming average pay of US $150 per person per day) it will be US $375000. Let’s assume we are supposed to find opportunity cost of this time spent by assuming Clients are charged US $65 per hour for 8 hours per person every day. It will total to US $1,550,000 (1.55 Mil) worth of revenues *Daily*!

You see, now it makes sense to you.

Wouldn’t it be great if IT companies who brag about setting trends in the industry pay a little attention to bring the change in their own organization?

Tuesday, October 27, 2009

Oracle Invalid Objects

Here is a quick query for Oracle users to identify all invalid objects:

SELECT owner,object_name,object_type
FROM dba_objects WHERE status='INVALID'

Monday, October 12, 2009

Deleting Objects from a Schema in Oracle

Here is a script that would come handy if you need to delete all the objects in a schema. Please ensure you are NOT logged in as System / Sys. Log in as the user for whose schema all the objects need to be dropped. Hope this helps.

--

prompt >>>

prompt >>> dropping it all..................

prompt >>>

--

begin

declare

cursor c1 is

select table_name, constraint_name from user_constraints where constraint_type = 'R';

cursor c2 is

select table_name, constraint_name from user_constraints where constraint_name not like 'SYS_IL%';

cursor c3 is

select index_name from user_indexes where index_name not like 'SYS_IL%';

cursor c4 is

select table_name, constraint_name from user_constraints where constraint_type = 'P';

cursor c5 is

select index_name from user_indexes where index_type = 'NORMAL' and uniqueness = 'NONUNIQUE';

cursor c6 is

select table_name from user_tables;

cursor c7 is

select object_name from user_objects where object_type = 'PROCEDURE';

cursor c8 is

select sequence_name from user_sequences;

v_sql varchar2(512);

begin

for c8_rec in c8 LOOP

v_sql := 'drop sequence '||c8_rec.sequence_name;

execute immediate v_sql;

END LOOP;

for c1_rec in c1 LOOP

v_sql := 'alter table '||c1_rec.table_name||' drop constraint '||c1_rec.constraint_name;

execute immediate v_sql;

END LOOP;

for c2_rec in c2 LOOP

v_sql := 'alter table '||c2_rec.table_name||' drop constraint '||c2_rec.constraint_name||' drop index';

execute immediate v_sql;

END LOOP;

for c3_rec in c3 LOOP

v_sql := 'drop index '||c3_rec.index_name;

execute immediate v_sql;

END LOOP;

for c4_rec in c4 LOOP

v_sql := 'alter table '||c4_rec.table_name||' drop constraint '||c4_rec.constraint_name||' drop index';

execute immediate v_sql;

END LOOP;

for c5_rec in c5 LOOP

v_sql := 'drop index '||c5_rec.index_name;

execute immediate v_sql;

END LOOP;

for c6_rec in c6 LOOP

v_sql := 'drop table '||c6_rec.table_name||' cascade constraints';

execute immediate v_sql;

END LOOP;

for c7_rec in c7 LOOP

v_sql := 'drop procedure '||c7_rec.object_name;

execute immediate v_sql;

END LOOP;

end;

end;

/

Useful SQL commands

A – How to create a Tablespace

Please log as “system” (with its valid password) using SqlPlus.

-- Create a 1GB tablespace from scratch.
CREATE TABLESPACE  LOGGING DATAFILE 'X:\full\path\to\XXXX.DBF' SIZE 1000M EXTENT MANAGEMENT LOCAL;
 
-- Change existing tablespace name.
ALTER TABLESPACE  RENAME TO ;
 
-- Change default user tablespace.
ALTER USER  DEFAULT TABLESPACE  QUOTA UNLIMITED ON ;
 
B – How to create a user for the Tablespace
 
CREATE USER  IDENTIFIED BY  DEFAULT TABLESPACE  TEMPORARY TABLESPACE temp;
GRANT SELECT ANY TABLE TO ;
GRANT UNLIMITED TABLESPACE TO ;
GRANT UPDATE ANY TABLE TO ;
GRANT RESOURCE TO ;
GRANT CONNECT TO ;
GRANT CREATE SESSION TO ;
grant query rewrite to ;
 
C – How to export your own database:
 
Exp system/@<instance> file= owner= log=explogfile.log
 
Parameters:
 - Oracle user name.
 - Oracle instance name.
 - System password.
 - Your database dump (like myDump.dmp).

Wednesday, October 7, 2009

Tech Jokes

Here they go... :-) Hope you like 'em!
----------
1. An SQL query walks into a bar and sees two tables. It walks up to them and says "Can I join you?" Tables say, "Sure, if you have the key?"

2. A Session Bean walks into a bar and asks for a Jack Daniels on the rocks. Bartender says, "I'm afraid I can't serve you any alcohol", and the Session Bean says, "why not? Are you discriminating against Session Beans?" The bartender replies "well, look at the state you're in".

Tuesday, September 15, 2009

Flex : Downloading a Binary (Excel) File

Context:
It was surprising for me to know that flex calls like navigateToURL(urlReq,"_self"); are stateless calls. This essentially means that I cannot attach a listener or hook my custom method calls upon events. So, if you are trying to download a dynamically generated binary file using Flex and want the UI to notify the user of any errors / progress of the operation, you cannot.

Finding the solution wasn't straight forward - I noticed a hand ful of developers asking the same question on various forums. Here is how I have solved this problem.

The Approach:
There were two approaches to solve this problem at high level.

  1. Use serverside component to catch all the errors (including throwable- if you are using Java) and spool it as part of the response OR generated file. However, this is not a fool proof approach coz it will not be able to handle error conditions like server going down or network error etc.
  2. Better approach would be to leverage FileReference class that comes bundled with Flex. This will allow users the download the file from a URL. One can also pass parameters while creating URLRequest in case the file needs to be generated dynamically (which was precisely the case for us)

The code that does the trick:









01 private var fileRef:FileReference;
02 private var popupPanel:Panel=null;
03 private function sendRequest():void
04 {
05 var urlStr:String = "/myWebService/services/GenerateFile"
06 urlStr = urlStr + "?param1=someValue1";
07 urlStr = urlStr + "&param2=someValue2";
08 urlStr = urlStr + "&param3=someValue3";
09 urlStr = urlStr + "&param4=someValue4";
10 urlStr = urlStr + "&param5=someValue5";
11
12
13 initPopup();
14
15 try
16 {
17 var urlReq:URLRequest = new URLRequest(urlStr);
18 urlReq.method = URLRequestMethod.GET;
19
20 fileRef = new FileReference();
21 fileRef.addEventListener("complete", commpleteHandler);
22 fileRef.addEventListener("open", showPopup);
23 fileRef.download(urlReq, reportType.text+".xls");
24 }
25 catch(error:Error)
26 {
27 Alert.show("Could not generate file", "Error");
28 }
29 }
30
31 private function initPopup()
32 {
33 var vb:VBox = new VBox();
34 vb.setStyle("paddingBottom", 5);
35 vb.setStyle("paddingLeft", 5);
43 vb.setStyle("paddingRight", 5);
44 vb.setStyle("paddingTop", 5);
45 vb.percentHeight=100;
46 vb.percentWidth=100;
47
48 popupPanel=new Panel();
49 popupPanel.width=this.parentDocument.width / 2;
50 popupPanel.height=this.parentDocument.height / 5;
51
52 popupPanel.x = this.parentDocument.parentDocument.width / 3
53 popupPanel.y=this.parentDocument.parentDocument.height / 3;
54
55
56 var reportStatus:Label = new Label();
57 reportStatus.text="Please wait while file is generated.";
58 reportStatus.move(100, 100)
59
60 vb.addChild(reportStatus);
61
62 var cancelButton:Button = new Button();
63 cancelButton.setFocus();
64 cancelButton.label="Cancel";
65 cancelButton.x = popupPanel.width/2 - 40
66 cancelButton.y = popupPanel.height/2 - 20
67 cancelButton.addEventListener(MouseEvent.MOUSE_UP, cancelHandler);
68 vb.addChild(cancelButton)
69
70 popupPanel.title = reportType.text + " Status"
71 popupPanel.addChild(vb);
72 }
73
74 private function cancelHandler(event:Event):void
75 {
76 try
77 {
78 fileRef.cancel();
79 PopUpManager.removePopUp(popupPanel);
80 }
81 catch(error:*)
82 {
83 Alert.show"Could not cancel the file generation.", "Error");
84 }
85 }
86
87 private function commpleteHandler(event:Event) : void
88 {
89 PopUpManager.removePopUp(popupPanel);
90 }
91
92 private function showPopup(event:Event) : void
93 {
94 PopUpManager.addPopUp(popupPanel,this,true);
95 }




A few things to keep in mind:

  1. The code above uses only two types of listeners "complete" and "open" - you may want to use various other events supported here e.g. "progress", "select" etc
  2. The code above demonstrates the functionality - may have not been coded the best :)



Flip Side of using FileReference:

One flip side I have noticed about this implementation is the File Save As dialogue box (attached a screenshot below. This dialogue may turn out to be annoying for users where they just want to download the

Another thing to keep in mind is that when clicked cancel button in the code sample above - if a time consuming process was invoked at the server side - it will not interrupt. The method call - fileRef.cancel() method will only cancel the HTTP request. Application server will not be able to identify this and halt the process it started upon receiving the request

Conclusion:

If there is a requirement to track the state of the URL call and build functionality dependent on it (e.g. showing progress bar etc.) FileReference object e.g. showing the progress bar for file being downloaded or notify user of the HTTP Errors or a server side error in the file generation if this was for a dynamically created binary file based on user request

Tuesday, August 18, 2009

Perl : Finding Installed Modules in Perl

Context:
I was working on a solution to upload data from an excel file - that contains macros - using Perl. Perl is a module based implementation of parsing langugage and has a different module used for Windows / Linux based implementation for parsing / creating excel files (Win32::OLE->GetActiveObject('Excel.Application') viz. Spreadsheet::ParseExcel )

Perl file would work on Windows environment but not on Linux. I will not get into the details what the error message I got and what does it means for now.

Commands to list Perl modules:
After a while of googling - I figured out following one line script that will list all the Perl modules installed on Linux environment.

perl -MFile::Find=find -MFile::Spec::Functions -lwe 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC'

here is the same command to for Windows:
perl -MFile::Find=find -MFile::Spec::Functions -lwe find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC
Nothing much has changed other than double quotes highlighted in red.

An Alternate Way:
One can also try executing following command to fetch the details. If there is an error while execuing command, it means the module is not installed.

perl -MSample::Module -e 'print "\nModule is Installed\n\n"'

sample output - installed module:
bash-3.2$ perl -MExtUtils::Installed -e 'print "\nModule is Installed\n\n"'
Module is Installed
bash-3.2$


Sample output - module that is not installed:
bash-3.2$ perl -MSpreadsheet::ParseExcel -e 'print "\nModule is Installed\n\n"'
Can't locate Spreadsheet/ParseExcel.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi ... /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .).
BEGIN failed--compilation aborted.
bash-3.2$

Hope this helps . . .

Thursday, August 13, 2009

Blogger : Code formatting support and Blogger

It would be difficult for someone like me - being a software developer - to eschew from writing technical blog. It is a best practice to share the code and give example wherever possible. I started blogging recently and as it appears, lack of ability to format the code is becoming a major hold up for me to document every day learning if not sharing.

I am more of switching from Wiki to Blogging - and hence this problem, but there seems to be a scope for development if one can do. I have been a big fan of wiki. I absolutely love how smart macros does it offer and do all the hard I hate it when it comes to writing some code and 'Ctrl + Shft + F' short cut doesn't work. How dependent I have become on the editors is a topic - not for today's blog.

Syntax highlight is a very basic feature - I would use it day in and day out. I don't get it on blogger! I have to go to some sites to covert the code to HTML first and then replace all the HTML tags to comply with the standards.

One more thing which I miss is excel macros in WiKi. It just doesn't get limited there. Wiki seems to offer a pluggable framework. I have seen people add their own macros for various applications.

Reference Material:
Some sites I have found while I re-searched this subject online are:
  1. Java 2 Html tool converts java code into HTML and is available as online applet http://www.java2html.de/
  2. Built on Java2Html but offers a way to covert esp. flex action script code in HTML with syntax highlight. http://keg.cs.uvic.ca/flexdevtips/java2html/
  3. explains how to get formatting up and running on your blogger account http://codeblog.kello.se/2009/01/07/getting-code-formatting-with-syntax-highlighting-to-work-on-blogger/
  4. If you want an HTML based tool - here is one for you. However, the flip side is that it cannot highlight the code - http://codeformatter.blogspot.com/2009/06/about-code-formatter.html
  5. Something that I have read about but not tried - http://www.manoli.net/csharpformat/
Conclusion:
Blogger may not be an obvious choice of a technology geek! There are some basic features, I would like to see before I find it addictive!

Tuesday, August 11, 2009

Java : Garbage Collection

Context:
I got a query - how does garbage collection work in Java? This was the time I started gathering details by means of googling. The details compiled here are based on my research online. Please note that the question I was asked about is very generic - and the details below touch upon the topic at very high level.


What is a Garbage collection?
Garbage collection is a mechanism in java which works on mark and sweep basis and relives programmers from spending time in writing code to claim back the memory allocated to the objects.

The mechanism also is part of Java's security strategy. It will prevent current program to crash JVM instance by means of memory hazards.

This service of course doesn't come free, it causes a small overhead since the process has to be continuously running in the background. However, keep in mind that scale of the application will determine the magnitude of overhead caused by this process.

How it works?

Garbage collector will iterate over all the available objects. The ones which are left out are marked for garbage collection. In the sweep stage, Garbage Collector deletes the objects for which the heap space was allocated and make it available to executing program.

Garbage collector will determine eligibility of an object by measuring its "reachability" from the root node. Any objects which are referred to by a root is a live object. Subsequently any objects referred to by a live object is also considered live object. Objects which are not reachable are dead and will be removed from heap space.

There are algorithms used by Garbage collectors to mark "reachable" objects abut it would be a subject in itself to learn more about them.

Garbage Collection Strategies

The garbage collectors might use Compacting and Copying strategies to deal with heap fragmentation.

What are generations?

Generations refer to the life span of the variables. Local variables for example are the most short lived ones and will be the first ones to be identified and claimed back. They are called young generations. Old generations are the objects which survive across multiple collections. Old and Young generations symbolize the memory pool available to store such objects.

When young generations are filled up, it causes minor collection and when tenured generation pool will cause Major Collection to occur. Note that later is much a slow process considering the fact that it involves all live objects

Java program is allocated heap space. Every thread is allocated a separate stack of functions and stacks reside in Heaps. Local variables are part of stacks.

Conclusion:

Although JVM encapsulates memory management under the hood - knowing how it works will make the developers write code more consciously keeping scalability in mind.

More (Technical) resources:

  1. Command line parameters which come for JMV's performance improvement are described by Sun here: http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
  2. The details on how to performance tune Garbage Collection in java 1.5 is given here - http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

Flex : Making flex application full screen

Context:
While performing unit testing of a new module I was transition a couple months back, I figured out a problem. The button that read "Toggle Full Screen" did not work how it should have i.e. it didn't switch between browser and full screen mode.

Why full screen doesn't work?
RTFM still holds true. None really read the manual to make it work. Merely copy pasting the code from Adobe example / sample code doesn't work!!

One needs to make changes in the java script / html templates as they are the ones which will initialize flash player and allow it to run or not run in full screen mode.

How to make it work?
You may want to walk thru following steps to verify all the elements to make flex application full screen are in place

  1. You must have version 9,0,28,0 or later of Flash Player installed to use full-screen mode and 9,0,115,0 or later for hardware-scaled full-screen mode (You can check it here - http://kb2.adobe.com/cps/155/tn_15507.html)
  2. Check if index.template.html contains reference to AC_FL_RunContent function.
  3. If yes, update the function to also include following pair of parameters
    AC_FL_RunContent(
    "src", "${swf}",
    "width", "${width}",
    "height", "${height}",
    "align", "middle",
    "id", "${application}",
    "quality", "high",
    "bgcolor", "${bgcolor}",
    "name", "${application}",
    "allowScriptAccess","sameDomain",
    "type", "application/x-shockwave-flash",
    "pluginspage", href="http://www.adobe.com/go/getflashplayer">http://www.adobe.com/go/getflashplayer, "allowFullScreen", "true"
  4. Update <object> tag in index.template.html to include parameter allowFullScreen and set its value to "true" <param name="allowFullScreen" value="true" >
  5. If you are using <embed> tag - you need to update it to set value of allowFullScreen attribute to true e.g. <embed
    src="${swf}.swf" quality="high" bgcolor="${bgcolor}"
    width="${width}" height="${height}" name="${application}" align="middle"
    play="true"
    loop="false"
    quality="high"
    allowScriptAccess="sameDomain"
    type="application/x-shockwave-flash"
    pluginspage="http://www.adobe.com/go/getflashplayer"
    allowFullScreen="true" />
  6. The flex code is in place to toggle the mode from normal to fullscreen and vice versa

Conclusion:

Its easy to miss on trivial things and reading the manual and doing implementation will save clients from going baffled! :-)

Thursday, July 30, 2009

Flex : How expensive pretty looking DataGrids are?

In software world - especially while thriving on Rapid Application Development, people start with prototype development. Under the influence of re-usability - developers land up using the same prototype to build the application framework. At this point in time - probably none would have anticipated the scalability and the volume of data. A small application works like grand-ma and end users get pissed!


Whole gamut of changes has brought the Flex DataGrids to work very slow for an intranet based application.


We ran into this classic case of short-sighted-ness in recent past. Clients came to us frustrated about "performance" of Flex DataGrid implementation in various modules in our application.


While analyzing - we realized that
  1. there were way too many containers used in hierarchical fashion in the layout
  2. Data Grids were using labels for displaying the data and applying dynamic styling
  3. Item Renderer implementation of Labels was such that it would cause
  4. Large amount of data was being transferred over XML from server to the client application

Let's take an example of each of them:

1) Too many contain hierarchies
The way flex layout and children component display works is by applying algorithms to determine x, y position and preferred size and styling. When a flash player runs out of a browser - it is at mercy of memory allocated to browser instance. The more it has to do with limited resources, the more time it will take i.e. degraded performance.


2) Labels as Item renderers in data grids
Think about it from a different perspective. We have a data grid with 45 rows and 28 columns. Based on the display region out of 1260 - required number of label objects will be initialized. The re-draw logic on flex display may invoke various methods on all these object instances even on a mouse move! Even if the execution time for each of them is in milliseconds, multiply it with number of cells visible and you will see how performance degrades.



3) Item renderer implementation

A Label used as ItemRenderer is fine but one has to be mindful of how best to use it? I am sure one cannot call start extending the component by including Label in MXML script and initialize the attribute of Label to cause method calls for colors and text e.g. following declaration may not be a great way to initialize a Label that will be used as itemRenderer.

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" color="{(String)(getColorCode(data))}" text="{ getLabelText(data ) }" >


4) Large amount of data transfer between browser and server
Think of a couple of thousands of lines with 38 columns each to be retrieved - be converted to java objects - java objects be converted to XML format - xml be sent to the client - client to parse the xml within memory allocation limits - generate collection of local data types...
There is possibly a scope of improvement 1) to avoid converting the java object to xml and back by switching to binary data transfer and 2) Using a faster data transfer protocols like AMF.

Conclusion:
I would only want to imphasise the importance of giving enough weightage to trivial looking things from beginning and to address the issues in rightest possible way to avoid aging of application and ensuring of scalability.

Tuesday, July 28, 2009

Flex : AdvancedDataGridColumn - problem and solution to make only selected columns editable


Context:

AdvandedDataGridColumn stores list data and stylesheets for AdvancedDataGrid. "editable" is a property of AdvancedDataGridColumn intending to make the column editable or uneditable. When made editable (set editable="true" for the AdvancedDataGridColumn) the cells in the editable column will allow a user to change the cell values by invoking a user specified or default (text) editor in the cell by pressing F2 or with a single mouse click on the cell.

When set a column in AdvancedDataGrid implementation; a user while navigating thru the grid using keyboard will be able to press F2 key and make the cell editable just like Microsoft Excel.

Flex developers will not realize the issue till the time requirement is around implementing something simple. The moment one has to make only selected columns editable; the problem will surface up.

The problem:
When pressed F2 when the datagrid cell is selected, irrespective of editable propertly set to false, column will become editable.
This issue is acknowledged by Adobe Fex but still waiting to be fixed at Adobe's end. Take a look at following URL for more details on this issue - http://bugs.adobe.com/jira/browse/FLEXDMV-2084

Solution at High Level:
My approach to solution was to utlize the event propagation to intercept the keyboard event and hoook my validation to decide if the event should be prevented or allowed.

1. Trap the keyboard event on AdvancedDataGrid
2. Validate if the column isEditable
2.1 if yes: let the control flow thru the business logic to update the cell
2.2 if no: prevent the event propagation further

Implementation Details:
I would want a custom function to be invoked before making the cell editable.

AdvancedDataGrid allows this by letting you specify method name as value of itemEditBeginning attribute in AdvancedDataGrid declaration.

It might look something like this:

validateColumnEditability(event)" selectionMode="multipleCells" editable="true" />

Implementation of validateColumnEditability() might look something like:

public function validateColumnEditability(event:AdvancedDataGridEvent):void
{
if(event.dataField == "allowedCol1" event.dataField== "allowedCol1" ...)
{
//this will return the control and make the column editable
return;
}
else
{
//This will prevent event from being propagated thru the stack
event.preventDefault();
}
}

Further Improvements:
The list of the editable can be made a collection and performing look up on the collection would be much easier / better than string coparison
The function can be coded in utility class as static function (this will require you to import the utility class and invoke this static method.

Please note:
Above code defines the approach to fix the problem and not the best way to code


Monday, July 27, 2009

Flex : Advanced Data Grid - The solution to Keyboard Navigation

Context:
We were in the process to achieve keyboard navigation using Flex on DataGrid. The DataGrid would contain editable and non-editable cells. The proof of concept (POC) started when Flex Builder 2.0 was the only version available.

The proof of Concept:
We figured out working with keyboard event and synchronizing the data and itemEditors would require us lot more effort to come up with a generic component which will not be full proof despite all the testing.

The next step:
The features of Flex 3.0 were released around that time which provided us with a hope. Flex was releasing AdvancedDataGrid and single cell selection was one of the features. We decided to use wait for Flex 3.0 and use AdvancedDataGrid for this implementation.

The pros:
Grouping functionality is great and works wonders with multi level grouping
Allows single cell and multiple cell selections
Objective hierarchy is simple - all the components have a parallel implementation with "Advanced" prefixed. e.g. DataGridColumn and AdvancedDataGridColumn

The cons:
A parallel implementation was required in our code for all the components referring to DataGridObjects as AdvancedDataGrid and DataGrid components do not share the common parent.
For being a Java Developer - it makes life difficult if one cannot utilize polymorphism.
Known bugs required us to take work around way for being early implementers e.g. http://bugs.adobe.com/jira/browse/FLEXDMV-2084

Lessons Learnt:
There are bugs still being fixed in the released component e.g. possible memory leak and single cell selection mode not working in editable mode when some columns are editable and some are not.

Conclusion:
Despite known issues - its great to have a keyboard friendly flex component available. I am sure Adobe will look into making the component more stable and introduce more features with its gaining popularity