<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33104176</id><updated>2011-07-07T22:15:19.222-07:00</updated><category term='J2ME'/><category term='Apache Axis'/><category term='ksoap'/><category term='Google AJAX Search API'/><category term='Closure'/><category term='SqlDataReader'/><category term='Synchronized collection vs. lock'/><category term='simultaneous calls to server'/><category term='GridView'/><category term='Exception management'/><category term='Sort indicator icon'/><category term='Closures'/><category term='ASP .NET Performance'/><category term='ObjectDataSource'/><category term='Proxy-Authorization'/><category term='ASP .NET 2.0'/><category term='Exception Handling'/><category term='Complex Object'/><category term='Retrieving multiple rows with ADO .NET'/><category term='SqlDataAdapter'/><category term='Tomcat'/><category term='SOAPMonitor'/><category term='Google Gadgets'/><category term='DataSet'/><category term='J2ME Web Services Optional Package (JSR 172)'/><category term='Synchronized collection C#'/><category term='inside-out objects'/><category term='Visual Studio Orcas'/><category term='atomic'/><category term='reentrant'/><category term='UpdatePanel'/><category term='Proxy-Authenticate'/><category term='WebSphere Scheduler'/><category term='MIDP 2.0'/><title type='text'>Technical side of me</title><subtitle type='html'>A humble attempt to document my technical triumphs and struggles :-)

Something I should have done much earlier, but as they say: Better late than never!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33104176.post-799599921567520606</id><published>2010-08-18T13:01:00.000-07:00</published><updated>2010-08-18T13:01:25.166-07:00</updated><title type='text'>Definition of a Software Architect</title><content type='html'>Found this nice definition of a Software Architect in a JavaLobby article:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: arial, verdana, helvetica, sans-serif; font-size: 12px; line-height: 18px;"&gt;"Developer is an architect, who just don't want or is not able to deal with the translation of high level requirements into low level code, and enjoys to code more". Therefore an architect is a developer, who enjoys the translation and likes communication, meetings and everything else what is needed to extract the requirements from the customer. An architect should be only a temporary role. Otherwise it will be harder to keep up with the technology and you will end up in an "ivory tower"&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-799599921567520606?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/799599921567520606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=799599921567520606&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/799599921567520606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/799599921567520606'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2010/08/definition-of-software-architect.html' title='Definition of a Software Architect'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-3235168179216040918</id><published>2007-11-12T06:13:00.001-08:00</published><updated>2007-11-12T06:13:22.140-08:00</updated><title type='text'>Social Networking Features of MOSS 2007</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Following is a list of some features provided by MOSS 2007 that will help developers to easily provide social networking features in MOSS based Enterprise wide Social Networking applications. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Colleagues:&lt;/strong&gt; One of the main Social Networking components of MOSS 2007 is the concept of "Colleagues". &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Colleagues are a list of friends, team members and co-workers that are related to a specific person through the establishment of a user profile. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;A list of colleagues for a user is set up at the time of the user's profile creation and of course can be updated later through various built-in web parts. The details about the colleagues can be obtained from the Active Directory, Exchange Server, Live Communications Server 2005 or Office Communications Server 2007 set ups within the organization. Thus, the colleagues list is populated primarily based on Organization hierarchy. As a result, peers, supervisors, managers become a part of the colleagues. Additionally, MOSS can also gather this information by mining data sources like Outlook 2007 and IM contacts. (Note that privacy could become an issue here).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Through the list of colleagues, a user can find subject experts and key contacts within the organization, enabling increased and faster lines of communication.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Built-in Web Parts: &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Colleagues Web Part: &lt;/strong&gt;The colleagues web part allows users to present their mined and compiled colleagues to visitors. The colleagues list is a presentation of other organization members that the specified user works closely with in terms of organizational structure, interaction (i.e., email conversations and instant messaging contact lists) and group/site memberships. SharePoint can make recommendations regarding a colleague based on commonality of interactivity with these small groups, but users can also manually add and remove colleagues. &lt;strong&gt;&lt;br /&gt;				&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Colleagues Tracker Web Part: &lt;/strong&gt;The colleague tracker web part allows organization members to privately view their list of compiled colleagues and to modify their views and inclusion in their colleagues list. The colleague tracker web part allows for the presentation of recommended colleagues and allows the user to modify colleague tracking by profile information. For example, users can modify the colleague tracker to present updated colleagues when anniversaries, profile properties, authored documents and blogs change. Additionally, scoping the presentation can occur when users choose to view colleagues specifically for the user's workgroup or organization-wide.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;In Common With Web Part: &lt;/strong&gt;Office SharePoint Server provides a summary view of information relating to the memberships, organizational managers and colleagues that a visitor has in common with the owner of a My Site.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Membership Web Parts, Links, Sharepoint Sites: &lt;/strong&gt;These web parts provide the ability for users to view their own Office SharePoint Server site, group and mail list memberships and links as well as those that they have in common with others. Additionally, visitors can view a user's memberships, Office SharePoint Server Sites and distribution group memberships.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Web Parts: Colleague Tracker, Colleague Web Part, Membership Web Part&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Presence Information: &lt;/strong&gt;When coupled with Office Communications Server and Exchange Server, presence information indicating online instant messaging status, Out of Office messages and contact information is displayed whenever user information is presented (i.e., colleagues and colleague tracker web parts, etc.).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;People Search: &lt;/strong&gt;Office SharePoint Server supports the discovery of team members, colleagues and other individuals by exposing a search interface in which information workers can search on the organization's personnel. Results are returned to users and are presented in terms of social distance and relevance for grouping. The search can further be refined by user profile attributes including job title and alternatively be viewed based on search term relevance.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;My Sites: &lt;/strong&gt;Finallty, "My Sites" is the place where the list of colleagues will get displayed. My Site allows users to present information about their skills, individuals they know as well as other social information to visitors.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Content from the link: &lt;a href='http://blogs.msdn.com/sharepoint/archive/2007/10/24/enabling-and-managing-social-networks-for-business-use-with-microsoft-office-sharepoint-server-2007.aspx'&gt;http://blogs.msdn.com/sharepoint/archive/2007/10/24/enabling-and-managing-social-networks-for-business-use-with-microsoft-office-sharepoint-server-2007.aspx&lt;/a&gt; (contains some nice images / screenshots of the Sharepoint application)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-3235168179216040918?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/3235168179216040918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=3235168179216040918&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/3235168179216040918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/3235168179216040918'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/11/social-networking-features-of-moss-2007.html' title='Social Networking Features of MOSS 2007'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-2277369297155958697</id><published>2007-11-12T06:06:00.001-08:00</published><updated>2007-11-12T06:12:34.497-08:00</updated><title type='text'>Social Networking</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;If you are in the IT world or are a so-called Net savvy person, you must have heard about the word "Social Networking". It sounds great, although what does it mean really? And is it only restricted to sites like MySpace and Orkut and Facebook? Or can it be applied, is it being applied to intranet applications, for bringing people together within an Organization?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This blog is just a collection of some information, ideas that I found – a high level overview, to shed some light on the very frequently used term "Social Networking".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What is a Social Network?&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;"A social network is a social structure made of nodes (which are generally individuals or organizations) that are tied by one or more specific types of interdependency, such as values, visions, idea, financial exchange, friends, kinship, dislike, conflict, trade, web links, disease transmission (&lt;a title="Epidemiology" href="http://en.wikipedia.org/wiki/Epidemiology"&gt;epidemiology&lt;/a&gt;), or airline routes"&lt;/em&gt; - This is what Wikipedia has to say about "Social Networks". The concept of social networks and social network analysis has been around for quite some time, bringing about a major change in the fields of sociology, social psychology, economics, organizational studies etc., helping social scientists to understand how organizations work, how networks or groups of people within an organization influence the organization in turn. Just to make this point a little more understandable – the size of a social network is a good indicator of its usefulness, its reach and the impact it will have. A small, very highly connected network will be less useful as compared to a loosely connected network, where people within the group have connections to networks / groups outside the home network. More open type of networks as the latter one result in introducing and sharing of newer ideas and opportunities, bringing people with different facets and capabilities together.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In simple words, a "social network" is an association of people drawn together by family, work or hobby. The term was first coined by professor J. A. Barnes in the 1950s, who defined the size of a social network as a group of about 100 to 150 people&lt;span style="font-family:Verdana;"&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What is a Social Networking Site?&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A social networking site is a web site that provides a virtual community for people interested in a particular subject or just to "hang out" together. Members communicate by voice, chat, instant message, videoconference and blogs, and the service typically provides a way for members to contact friends of other members. Examples of public social networking sites of course are Orkut, MySpace, Facebook etc.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;These sites build on the Web 2.0 model, propagating the use of the Web as an application platform, helping members to share content of any form by forming online communities and are typically supported by an Ajaxified / rich / easy to use user interface.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Social Networking within Organizations&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Public social networking sites are the "in things" anyhow – but what is gaining momentum now is the use of social networking sites or applications within organizations, to help employees share data, content, information, in the form of documents, videos, photos, presentations, making finding relevant people within the organization easier, and helping automate a lot of manual workflows and business processes within an organization by making use of a social networking platform.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Microsoft Office Sharepoint Server 2007 (MOSS 2007) fits this scenario and provides a lot of built-in features that will make building social networking applications. More on this in the next blog.&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-2277369297155958697?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/2277369297155958697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=2277369297155958697&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/2277369297155958697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/2277369297155958697'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/11/social-networking.html' title='Social Networking'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-1931716005351735065</id><published>2007-05-22T11:51:00.000-07:00</published><updated>2007-05-22T12:54:41.282-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='atomic'/><category scheme='http://www.blogger.com/atom/ns#' term='Synchronized collection C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Synchronized collection vs. lock'/><category scheme='http://www.blogger.com/atom/ns#' term='reentrant'/><title type='text'>Synchronizing my thoughts on Synchronized collection</title><content type='html'>I admit I was not exactly aware of how Synchronized collections work and what it means exactly to get a Synchronized version of a non-thread-safe collection. It all started with the following code that uses a non-synchronized Queue collection of C# to maintain a queue of tasks:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Main Thread:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;public void EnqueueTask()&lt;/em&gt;&lt;br /&gt;&lt;em&gt;{&lt;/em&gt;&lt;br /&gt;&lt;em&gt;// Create a new task t&lt;/em&gt;&lt;br /&gt;&lt;em&gt;// Enqueue it into the Queue&lt;/em&gt;&lt;br /&gt;&lt;em&gt;JobQueue.Enqueue(t);&lt;/em&gt;&lt;br /&gt;&lt;em&gt;}&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Consumer Thread:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;public void DequeueTask()&lt;/em&gt;&lt;br /&gt;&lt;em&gt;{&lt;/em&gt;&lt;br /&gt;&lt;em&gt;// Check if number of items in the queue is &gt; 0 and dequeue the task if true&lt;/em&gt;&lt;br /&gt;&lt;em&gt;if(JobQueue.Count &gt; 0)&lt;/em&gt;&lt;br /&gt;&lt;em&gt;{&lt;/em&gt;&lt;br /&gt;&lt;em&gt;JobQueue.Dequeue();&lt;/em&gt;&lt;br /&gt;&lt;em&gt;}&lt;/em&gt;&lt;br /&gt;&lt;em&gt;}&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Note that it is known for sure that there is only one "Producer" thread that is adding tasks to the queue and there is exactly one "Consumer" thread that is removing tasks from the queue. There are not multiple consumers.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Questions that can arise when you see the code:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1. Is this code thread safe? After all, a shared Queue object is being accessed by two different threads - one adding to it and the other removing from it. So, our standard knowledge about threads and synchronization says that we need to do some synchronization here.&lt;br /&gt;&lt;br /&gt;2. How to achieve synchronization, if it is needed?&lt;br /&gt;a. Queue is by default not thread safe. Can I make use of the Synchronized Queue collection instead?&lt;br /&gt;b. Synchronization and mutual exclusion can also be achieved by obtaining a lock and making sure only one of the two threads can access the Queue object at any time.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. With this set up (knowing that there is only one producer and only one consumer), do I really need the Synchronization??&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The 3rd question took most of my time today, the logic behind that thinking was this:&lt;br /&gt;&lt;br /&gt;Even if there are two threads T1 and T2, accessing EnqueueTask and DequeueTask respectively, at any point of time, there could be only one thread active and using up the CPU time slice alloted to it. Further, shouldn't it be the case that the &lt;strong&gt;"Enqueue" and "Dequeue" functions on the Queue are atomic?&lt;/strong&gt; What that means is, thread T1 can get preempted by thread T2, either before the call to Enqueue method or after the call to Enqueue is over. T1 cannot be preempted while it is in the process of enqueuing the task. Fair enough?&lt;br /&gt;&lt;br /&gt;I tried searching a lot on whether these operations defined on the Queue object are atomic or reentrant. I never really found any concrete, to the point explanation to it. I am still not 100% sure I am right, but after some thinking I arrived at the following conclusion based on what I read mostly on the Net:&lt;br /&gt;&lt;br /&gt;1. Queue they say is non-thread-safe by default. This actually perhaps means that the operations defined on this object are not atomic or reentrant. That is, it is in fact possible that thread T1 can get preempted while the "Enqueue" function call is in progress by thread T2 that then tries to call the "Dequeue" function. In that case, since both the functions do work on the same object and memory location, some weird, wrong results might be obtained.&lt;br /&gt;&lt;br /&gt;2. I found an implementation of a Synchronized version of the Queue class. Following is how the "Enqueue" method will be implemented in the synchronized Queue class, that wraps a non-synchronized Queue object:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;public override void Enqueue()&lt;br /&gt;{&lt;br /&gt;lock (syncRoot)&lt;br /&gt;{&lt;br /&gt;queue.Enqueue();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;This implementation makes it apparent that the synchronized version in turn is obtaining a "lock" on the sync root.&lt;br /&gt;&lt;br /&gt;3. What the synchronized collection is going to guarantee is that no two threads can call the operations on the synchronized collection object simultaneosly. An interesting point to note is that, it will however, not guarantee thread safety during enumeration or when a sequeunce of these operations needs to be executed as part of a critical section. What does this mean?&lt;br /&gt;&lt;br /&gt;Consider the case when there can be multiple consumers in our earlier example, multiple threads trying to dequeue the tasks from our Queue. In that situation, using the Synchronized version of the Queue will not really help. The code:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;if(queue.Count &gt; 0)&lt;br /&gt;{&lt;br /&gt;queue.Dequeue();&lt;br /&gt;} &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;has to be executed atomically. Otherwise, two threads T1 and T2 can read a Count &gt; 0 and try to Dequeue the tasks. In case there is only one task in the Queue, the thread that dequeues the task later will get an exception. This problem can only be solved by obtaining a lock before entering the critical section.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4. Should we use Synchronized collections?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;C#, Java provide the Synchronized collections as helper classes. And developers will obviously get tempted to use them. But here are a few points to know and remember before or while using them:&lt;br /&gt;&lt;br /&gt;a. A Synchronized collection DOES NOT solve all the synchronization problems for us. Point 3 above gives an example.&lt;br /&gt;&lt;br /&gt;b. If your code has sequence of operations on the collection that are atomic (as shown in Point 3), or you need to enumerate the collection, it is better to not use the synchronized collection. If you do, you would be unnecessarily adding the overhead of the synchronization done internally by the Synchronized collection.&lt;br /&gt;&lt;br /&gt;c. I read in one of the articles that locking the collection object ourselves can give better results that using the synchronized wrapper. Have not tried this out myself, so cannot really comment on this.&lt;br /&gt;&lt;br /&gt;d. The Synchronized collection is after all a wrapper over the actuall collection object. With the wrapper methods in place, every call to any method on the object will incur an overhead of synchronization.&lt;br /&gt;&lt;br /&gt;Any comments / clarifications / corrections in this blog are welcome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-1931716005351735065?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/1931716005351735065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=1931716005351735065&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1931716005351735065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1931716005351735065'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/05/synchronizing-my-thoughts-on.html' title='Synchronizing my thoughts on Synchronized collection'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-4761992208183857096</id><published>2007-05-18T22:54:00.000-07:00</published><updated>2007-05-18T22:55:00.486-07:00</updated><title type='text'>Weak References</title><content type='html'>By default, when we use a "new" operator, we get hold of a strong reference. A strong reference to an object prevents the Garbage Collector from removing the object from the Heap. The GC will not garbage collect any object as long as there are one or more strong references to it.&lt;br /&gt;&lt;br /&gt;While this is the behavior we expect most of the times, there are times when we may not want to hold a strong reference to an object and prevent it from getting garbage collected.&lt;br /&gt;&lt;br /&gt;A typical example of this is a Cache. While implementing a home grown Cache mechanism, it would be good to make use of what are called "Weak References". A weak reference allows the garbage collector to collect the object while still allowing the application to access the object. This means that in the intermediate time when there are no strong references to the object and till the time the garbage collector has not as yet collected the object from the heap, the object is accessible via the weak reference.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Example where Weak Reference can be used:&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Lets say there is a huge DataSet that we are maintaining in memory. The DataSet is displayed to the user on one page. Now, the user visits another page of the application and therefore now the DataSet maintained in memory is not really required. Before the user moves to another page, what we can do is nullify the strong reference to the DataSet while maintaining only a weak reference to it.  What this means is, while the user visits other pages of the application, if at all GC runs and needs to free the memory, the DataSet can be garbage collected. In case other pages do not need a lot of memory, GC will not run and the DataSet will not be garbage collected. If at all the user visits the same page again, the DataSet will still be in memory and can be referenced using the Weak Reference. Thus, a weak reference makes sure that we do not unnecessarily hold on to big objects in memory and prevent the GC from garbage collecting it.&lt;br /&gt; &lt;br /&gt;The basic pattern for the use of a WeakReference would look like this:&lt;br /&gt;&lt;br /&gt;// Create a weak reference to the DataSet ds.&lt;br /&gt;private WeakReference Data = new WeakReference(ds);&lt;br /&gt;// Get Data method that makes use of the Weak Reference&lt;br /&gt;public DataSet GetData(){    DataSet data = (DataSet)Data.Target;    if( data !=null)    {       return data;     }   else    {      data=  GetBigDataSet() // load the data ....       // Create a Weak Reference to data for later use...      Data.Target = data;    }    return data;}&lt;br /&gt;It would be clear by now how Weak References help when implementing a Cache. A cache can always maintain weak references to objects, which means that if memory needs to be cleaned up, objects in the cache that are no longer strong referenced can be picked up by GC freeing up the memory.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt; While Weak Reference is a good thing for saving on memory utilization, weak references should be used only for large objects preferrably, because with small objects, the weak reference pointer itself could be larger than the actual object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-4761992208183857096?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/4761992208183857096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=4761992208183857096&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/4761992208183857096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/4761992208183857096'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/05/weak-references.html' title='Weak References'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-826736956428717969</id><published>2007-05-13T12:43:00.000-07:00</published><updated>2007-05-13T13:17:31.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP .NET Performance'/><title type='text'>Improving ASP .NET Performance - Part I</title><content type='html'>Read a very good, comprehensive article on "Improving ASP .NET Performance" on MSDN. Following are some important and interesting points mentioned in it, particularly concentrating on improving the performance of ASP .NET pages:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Trim your page size&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Not something that is on our top priority list when we think about improving performance! But large pages increase the response times experienced by the client, increase the consumption of the n/w bandwidth, thereby increasing the load on the CPU. To trim the page size:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;a. Remove extra white spaces and tabs&lt;/strong&gt; (though good coding practice would tell you to keep them for better readability of the code)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;b. Use script includes for static javascripts&lt;/strong&gt; so that they can be cached for subsequent requests.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;c. Disable view state&lt;/strong&gt; when you do not need it&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;d. Limit the use of graphics&lt;/strong&gt;, consider using compressed graphics&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;e. Use CSS for styling&lt;/strong&gt; to avoid sending same formatting directives to the client repeatedly&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;f. Avoid long control names&lt;/strong&gt;! (Again something that is contradictory to good coding pratice rules)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Use Page.IsPostBack&lt;/strong&gt; check in the page code-behind to avoid execution of instructions that need to be executed only once when the page loads for the first time&lt;br /&gt;&lt;br /&gt;3. Data Binding in pages:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;a. Avoid using Page.DataBind&lt;/strong&gt; method, since it is a page-level method. It internally invokes DataBind method on all the controls on the page that support data binding. Instead, as far as possible, call DataBind explicitly on required controls.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;b. Minimize calls to DataBinder.Eval&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;DataBinder.Eval uses reflection to evaluate the arguments that are passed to it. This can be quite time consuming and expensive when there are a lot of rows and columns in the table. Instead, one can use explicit casting (cast to DataRowView class) or use ItemDataBound event when the record being bound contains a lot of fields.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4. Partial Page or Fragment Caching&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In cases when caching of the entire page is not possible by using the OutputCache directive (this could be the case when parts of the page are dynamic and change frequently), it is possible to enable fragment caching only for specific portions of a page. These portions need to be abstracted out into user controls. The user controls on a page can be cached independently of the page. Typical examples are headers and footers, navigation menus etc.&lt;br /&gt;&lt;br /&gt;5. If the same user control is repeated on multiple pages, make the pages share the same instance of the user control by setting the &lt;strong&gt;"Shared" attribute of @ OutputCache directive&lt;/strong&gt; of the user control to true. This will save a significant amount of memory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-826736956428717969?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/826736956428717969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=826736956428717969&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/826736956428717969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/826736956428717969'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/05/improving-asp-net-performance-part-i.html' title='Improving ASP .NET Performance - Part I'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-1983371708608914951</id><published>2007-05-12T11:11:00.000-07:00</published><updated>2007-05-13T13:19:45.403-07:00</updated><title type='text'>.NET ThreadPool - Pitfalls and gotchas</title><content type='html'>Multithreading is used extensively in user interface applications, mainly to perform some time consuming operations in the background, while keeping the user interface active at the same time and not having to block the user. While multithreading is good, having too many threads active at a point in time can adversely affect the performance instead of improving it, just because of the number of expensive context switches that need to be performed.&lt;br /&gt;&lt;br /&gt;A middle way therefore, is to make use of Thread Pools. .NET provides you with a readymade implementation of a Thread Pool in the form of the System.Threading.ThreadPool class. A single thread pool (default pool size of 25 threads) is maintained by the CLR for each process, asynchronous tasks can be performed by making use of the methods in this class, typically by calling the QueueUserWorkItem method that queues user requests to be picked up by available threads in the pool.&lt;br /&gt;&lt;br /&gt;While the use of ThreadPool makes it a lot easier on the developer (all the intricacies of creating, managing and destroying a thread are hidden and happen behind the scenes) and also improves performance (a quick comparison between a manual Thread.start() and ThreadPool.QueueUserWorkItem()) shows a big difference), there are some pitfalls / points to remember / gotchas when it comes to using the ThreadPool. Following are some:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. ThreadPool is leveraged by the .NET framework for a lot of tasks&lt;/strong&gt;. ADO .NET, .NET Remoting, Timers, built-in delegate BeginInvoke methods - all of them internally make use of the ThreadPool. So this means, that the thread pool does not belong to your application alone, but is being used and loaded by the framework itself.&lt;br /&gt;&lt;br /&gt;2. The tasks queued up using the QueueUserWorkItem can remain in a wait state for a long time, but the &lt;strong&gt;actual work required for each task has to be really less and fast&lt;/strong&gt; - in order to avoid excessive blocking of a single thread to perform the task.&lt;br /&gt;&lt;br /&gt;3. Once a task is submitted to the queue, there is &lt;strong&gt;no control over the thread that executes it&lt;/strong&gt;, no way to get the state or set the thread's priority. It is &lt;strong&gt;not possible to create named threads using the ThreadPool class&lt;/strong&gt; and therefore there is no way to track a particular thread. It is therefore best to use the ThreadPool only when you want to run independent tasks asynchronously, with no need to prioritize them, or make sure they run in a particular order.&lt;br /&gt;&lt;br /&gt;4. &lt;strong&gt;One ThreadPool is created per process&lt;/strong&gt; - which can possibly have multiple AppDomains. So, if one application using the ThreadPool behaves badly, another application in the same process runs the risk of getting affected!&lt;br /&gt;&lt;br /&gt;5. It is critical to remember to write the code in such a way that deadlocks do not occur. While this is the very basic care one should take while using threads, it becomes pronounced with the use of ThreadPool because of point number 1 mentioned above. The catch is explained below:&lt;br /&gt;&lt;br /&gt;Let us say there is a method called "ConnectTo" that opens and closes a socket using the "BeginConnect" and "EndConnect" methods of .NET that internally make use of the ThreadPool. There is a task "WriteToSocket" that is submitted to the queue - to make use of the ThreadPool. And now imagine there are 2 such tasks created with the pool size being 2. Now, the situation is that the two threads in the ThreadPool are already blocked by the "WriteToSocket" tasks. Each of these tasks, however, call "ConnectTo" which requires a thread from the ThreadPool in order to execute the asynchronous "BeginConnect" method. If you get the picture - what has happened in this case is the famous deadlock situtation.&lt;br /&gt;&lt;br /&gt;Some rules of thumb to remember to avoid a situation as above:&lt;br /&gt;&lt;br /&gt;a. &lt;strong&gt;Do not create any class whose synchronous methods wait for asynchronous functions&lt;/strong&gt;, since this class could be called from a thread on the pool.&lt;br /&gt;&lt;br /&gt;b. &lt;strong&gt;Do not use any class inside an asynchronous function if the class blocks waiting for asynchronous functions&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;c. &lt;strong&gt;Do not ever block a thread executed on the pool that is waiting for another function on the pool&lt;/strong&gt; - so basically know which of the .NET built-in functions make use of the ThreadPool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-1983371708608914951?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/1983371708608914951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=1983371708608914951&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1983371708608914951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1983371708608914951'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/05/net-threadpool-pitfalls-and-gotchas.html' title='.NET ThreadPool - Pitfalls and gotchas'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-2265498004011240283</id><published>2007-05-04T22:05:00.000-07:00</published><updated>2007-05-04T22:49:55.011-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sort indicator icon'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP .NET 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='GridView'/><title type='text'>Showing a Sort Order Indicator in Header of GridView control of ASP .NET 2.0</title><content type='html'>It doesn't take a whole lot of effort to provide sorting on columns in a GridView control of ASP .NET 2.0. However, it does not have built-in support for showing an icon or an image to indicate the column on which the table is sorted and the order in which it is sorted.&lt;br /&gt;&lt;br /&gt;To enable sorting and to show a sort order indicator in the column header of a GridView, the following things need to be done:&lt;br /&gt;&lt;br /&gt;1. In the .aspx page, define event handlers for "OnSorting" and "OnRowCreated" events. The OnSorting event gets called whenever the grid is sorted by clicking on a column header and OnRowCreated event is called when a row in the grid gets created. Also set the "AllowSorting" attribute to true. The following code snippet shows the attributes of the GridView control:&lt;br /&gt;&lt;br /&gt;&lt;?xml:namespace prefix = asp /&gt;&lt;asp:gridview id="gridViewInvoiceSearchResult" autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;&lt;strong&gt;AllowSorting&lt;/strong&gt;="True"&lt;/strong&gt; &lt;strong&gt;OnSorting&lt;/strong&gt;="gridViewInvoiceSearchResult_OnSort" &lt;strong&gt;OnRowCreated&lt;/strong&gt;="gridViewInvoiceSearchResult_OnRowCreated"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;2. Write the event handlers for OnSorting and OnRowCreated events in the code-behind page.&lt;br /&gt;&lt;br /&gt;3. The GridViewSortEventArgs parameter passed to the OnSorting event handler contains the sort direction (ascending or descending) and the sort expression (used to identify the column on which the sorting is done. A particular column in the GridView can be associated with a SortExpression while defining the binding of the column to a particular data field). Store these values in member variables declared within the code-behind page.&lt;br /&gt;&lt;br /&gt;4. In the OnRowCreated event, use the SortExpression and SortDirection values stored earlier to determine which image to add and which column to add it to. The following code snippet shows the OnRowCreated event handler:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;protected void gridViewInvoiceSearchResult_OnRowCreated(object sender, GridViewRowEventArgs e)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{&lt;br /&gt;&lt;strong&gt;// Check whether the row is a header row&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;if (e.Row.RowType == DataControlRowType.Header) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{&lt;br /&gt;&lt;strong&gt;// m_SortExp is the sort expression stored in the OnSorting event handler &lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;if (String.Empty != m_SortExp) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{&lt;br /&gt;&lt;strong&gt;// Based on the sort expression, find the index of the sorted column&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;int column = GetSortColumnIndex(this.gridViewInvoiceSearchResult, m_SortExp); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;if (column != -1)&lt;br /&gt;&lt;strong&gt;// Add an image to the sorted column header depending on the sort direction &lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;AddSortImage(e.Row, column, m_SortDirection); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;// Method to get the index of the sorted column based on SortExpression&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;private int GetSortColumnIndex(GridView gridView, String sortExpression)&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;{ &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;if (gridView == null) &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;return -1; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;foreach (DataControlField field in gridView.Columns)&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; { &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;if (field.SortExpression == sortExpression)&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; { &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;return gridView.Columns.IndexOf(field); &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;}&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; } &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;return -1;&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;// Method to add the sort icon to the column header&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;private void AddSortImage(GridViewRow headerRow, int column, SortDirection sortDirection)&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;{&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; if (-1 == column)&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; { &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;return;&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; } &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;&lt;strong&gt;// Create the sorting image based on the sort direction.&lt;/strong&gt; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;Image sortImage = new Image();&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; if (SortDirection.Ascending == sortDirection) &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;{ &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;sortImage.ImageUrl = "~/down.gif"; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;sortImage.AlternateText = "Ascending order"; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;}&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; else &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;{ &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;sortImage.ImageUrl = "~/up.gif"; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;sortImage.AlternateText = "Descending order"; &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;} &lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;&lt;strong&gt;// Add the image to the appropriate header cell.&lt;/strong&gt;&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt; headerRow.Cells[column].Controls.Add(sortImage);&lt;/span&gt;&lt;/asp:gridview&gt;&lt;br /&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;}&lt;asp:gridview id="gridViewInvoiceSearchResult" autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/asp:gridview&gt;&lt;/span&gt;&lt;/asp:gridview&gt;&lt;asp:gridview autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;span style="font-size:78%;"&gt;&lt;asp:gridview id="gridViewInvoiceSearchResult" autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;/asp:gridview&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;asp:gridview id="gridViewInvoiceSearchResult" autogeneratecolumns="False" datasourceid="invoiceSearchDataSource" runat="server"&gt;&lt;/asp:gridview&gt;&lt;/span&gt;&lt;/asp:gridview&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-2265498004011240283?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/2265498004011240283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=2265498004011240283&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/2265498004011240283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/2265498004011240283'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/05/showing-sort-order-indicator-in-header.html' title='Showing a Sort Order Indicator in Header of GridView control of ASP .NET 2.0'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-7895113284147869350</id><published>2007-04-29T10:46:00.000-07:00</published><updated>2007-04-29T11:36:58.196-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Retrieving multiple rows with ADO .NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SqlDataReader'/><category scheme='http://www.blogger.com/atom/ns#' term='DataSet'/><category scheme='http://www.blogger.com/atom/ns#' term='SqlDataAdapter'/><title type='text'>Retrieving multiple rows from Database Tables with ADO .NET</title><content type='html'>With ADO .NET there are two ways of retrieving multiple rows from a database table:&lt;br /&gt;&lt;br /&gt;1. Using SqlDataAdapter to generate DataSet or DataTable&lt;br /&gt;2. Using SqlDataReader to provide a read-only, forward-only data stream&lt;br /&gt;&lt;br /&gt;The choice between the two approaches is one between performance and functionality. DataReader gives better performance, while DataAdapter approach provides additional functionality and flexibility. Following is a list of points telling you when to use which approach.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Use DataSet with SqlDataAdapter when:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1. You require a disconnected, memory-resident cache of data&lt;br /&gt;2. You want to update some or all of the retrieved rows and use batch update facilities of the DataAdapter&lt;br /&gt;3. You want to bind the data with a control that requires a data source that supports IList&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Good-to-know points about SqlDataAdapter:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;1. Fill method of SqlDataAdapter opens and closes the database connection for you. So you don't need to do connection management.&lt;br /&gt;2. However, that means, if you require the connection to be open after the Fill Method, open the connection yourself before calling the Fill method, thus avoiding unnecessary close-open of the connection.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Use SqlDataReader when:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;1. You are dealing with large volumes of data that is too much for maintaining in a single cache.&lt;br /&gt;2. You want to simply read the data and present to the user (read-only data)&lt;br /&gt;3. You want to bind the data with a control that requires a data source that implements IEnumerable&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Good-to-know points about SqlDataReader:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1. Remember to call Close on SqlDataReader as soon as possible, since the connection to the database remains open as long as the data reader is active.&lt;br /&gt;2. The database connection can be closed implicitly by passing the CommandBehavior.CloseConnection value to the ExecuteReader method - it ensures that the connection is closes when the data reader is closed.&lt;br /&gt;3. Use typed accessor methods (GetInt32, GetString etc.) if the column's data type is know while reading data from the reader. This reduces the amount of type conversion required, improving performance.&lt;br /&gt;4. If you want to stop pulling data from the server to client, call Cancel method on SqlDataReader before calling Close method. Cancel method ensures that the data is discarded. Calling Close directly however, will make the reader pull all the data before closing the stream.&lt;br /&gt;&lt;br /&gt;The main advantage of the SqlDataReader approach over the DataSet approach is that the former avoids the object creation overhead associated with a DataSet. Note that the DataSet object creation will result in creation of many other objects like DataTable, DataRow, DataColumn and the Collection objects used to hold all these sub-objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-7895113284147869350?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/7895113284147869350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=7895113284147869350&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7895113284147869350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7895113284147869350'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/04/retrieving-multiple-rows-from-database.html' title='Retrieving multiple rows from Database Tables with ADO .NET'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-5794636501931685893</id><published>2007-04-28T11:49:00.000-07:00</published><updated>2007-04-29T21:30:09.660-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Exception management'/><category scheme='http://www.blogger.com/atom/ns#' term='Exception Handling'/><title type='text'>Exception Handling Best Practices</title><content type='html'>Anyone who has been a programmer in his life, knows about exceptions and also knows that there is no exception to having Exceptions in one's code! Fresh programmers however often overlook the importance of having exception management framework in their applications. A proper, well-defined exception handling framework along with a logging framework is absolutely essential for making sure that your program or application does not spring surprises on you later!&lt;br /&gt;&lt;br /&gt;So, what are the best ways of handling Exceptions in the code? What should one do and what should one not do as regards Exceptions?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Catch Exceptions the right way&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;In C# or in Java, the way to handle exceptions is to put the code that could generate the exception into a try..catch..finally block. If there are multiple catch blocks, make sure that these are ordered from the most specific type to the most generic type. This ensures that the catch block for the most specific type of exception is considered first for any given exception, thus guaranteeing a specific treatment to that exception if required.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Catch Exceptions only if you know what to do with them!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Most of us, most of the times, blindly write the try..catch blocks, just because the IDE makes us do it. Because of that we end up having catch blocks as below:&lt;br /&gt;catch(Exception exp){ throw exp;}&lt;br /&gt;Now, the thing to note here is that you have not done anything really by catching that exception. It has just been rethrown from the catch block. If you find such lines in your code, the first thing you should be doing is simply removing those catch blocks. Instead, let these exceptions propagate further to the caller methods - which perhaps know better what to do with them.&lt;br /&gt;&lt;br /&gt;Catch an exception only if:&lt;br /&gt;&lt;br /&gt;a. You want to log that exception - The exception message and the stack trace when logged give a good picture to the developer as to what has gone wrong.&lt;br /&gt;b. You want to write some clean-up code - In this case you can rethrow the same exception if no extra information is needed&lt;br /&gt;c. You want to write some code to recover from the exception&lt;br /&gt;d. You want to add some relevant information to the exception - This is particularly necessary in multi-tier applications or end-user applications where some nice user-friendly message has to be shown to the user. As an exception is propagated up the call-stack, often the information associated with it becomes less relevant. In such cases, wrap the actual exception in a custom, application specific exception. Remember to store the actual exception in the "InnerException" property of .NET Exception class (This is possible in Java too). This ensures that the actual exception is never lost and can always be retrieved if required.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. Use Exceptions sparingly&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Catching and Throwing of Exceptions is performance intensive. Never use exceptions to control the normal flow of operations in the code.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4. Use Custom Exceptions&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;As mentioned in point 2 d., one of things that one can do after catching an exception is to wrap it up in a more understandable exception with some extra information. This is where we need custom exception classes, exceptions that are specific to your application. In .NET, this can be done by extending the "ApplicationException" class. The entire hierarchy of the application exceptions can be bundled into one single assembly so that it can be referenced everywhere in your application.&lt;br /&gt;&lt;br /&gt;A comprehensive article on Exception Management in .NET at &lt;a href="http://msdn2.microsoft.com/en-us/library/ms954599.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms954599.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-5794636501931685893?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/5794636501931685893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=5794636501931685893&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/5794636501931685893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/5794636501931685893'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/04/exception-handling-best-practices.html' title='Exception Handling Best Practices'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-691666847030745481</id><published>2007-04-27T23:28:00.000-07:00</published><updated>2007-04-28T02:38:46.514-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UpdatePanel'/><category scheme='http://www.blogger.com/atom/ns#' term='simultaneous calls to server'/><title type='text'>Simultaneous calls to server from UpdatePanel</title><content type='html'>The simplest way of Ajaxifying your ASP .NET web page using the ASP .NET Ajax library is to make use of its "UpdatePanel" control. It allows parts of your web pages to get refreshed, avoiding whole page reloads. This control causes asynchronous postbacks to the server. On receiving a response from the server, only the components inside the UpdatePanel are re-rendered. With the Ajax approach of making the calls to the server asynchronously, the user interface remains active even after a request to the server has been initiated. This means that the user can click on other active buttons on the page and initiate some more asynchronous calls (assuming those actions are also ajaxified).&lt;br /&gt;&lt;br /&gt;Does this mean that I can place multiple UpdatePanels on my web page, let the user perform many actions simultaneously, resulting in many asynchronous calls to the server and different parts of the page getting refreshed as and when the corresponding Ajax call ends? Well - the answer to this question is NO and to understand why it is important to understand how an asynchronous postback is (or is not) different from a regular postback&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The asynchronous postback made by UpdatePanel is exactly the same as a regular postback except for one important thing: the rendering. Asynchronous postbacks go through the same life cycles events as regular pages. Only at the render phase do things get different, since only the components inside the UpdatePanel are re-rendered instead of the whole page.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;What this means for us is: Assume that there are two UpdatePanels on a web page, with one button each. The user clicks on Button 1 in the first UpdatePanel and the processing starts. Since the UI remains active after the first Ajax call, the user clicks on Button 2 in second UpdatePanel - assuming that both the calls will go through and he will get to see both the updates in some time. However, what will happen is that the second button click will invalidate the asynchronous postback initiated by the first button click. Effectively, only the final and the second button click will actually get processed, instead of both!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt; While this is the story of the ASP .NET Ajax UpdatePanel - another interesting thing is the &lt;strong&gt;limit of 2 simultaneous connections to a server&lt;/strong&gt;, a restriction put by most of the browsers today. This means that even with the crude simple Ajax way, it is possible to process only two requests simultaneously. All the other requests will be queued by the browser, until a free connection is available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-691666847030745481?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/691666847030745481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=691666847030745481&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/691666847030745481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/691666847030745481'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/04/simultaneous-calls-to-server-from.html' title='Simultaneous calls to server from UpdatePanel'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-7006761785807349708</id><published>2007-04-22T03:45:00.001-07:00</published><updated>2007-04-22T04:23:26.374-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio Orcas'/><title type='text'>New version of Visual Studio - code named "Orcas"</title><content type='html'>The successor of Visual Studio 2005, code named "Orcas" (named after an island - this knowledge is courtesy Wikipedia) had its Beta 1 release on April 19, 2007. This new Visual Studio version is Vista compatible and promises a lot of new features and enhancements and bug fixes (ahem!) as compared to Visual Studio 2005.&lt;br /&gt;&lt;br /&gt;I am of course yet to try it out, but some of the features that caught my attention:&lt;br /&gt;&lt;br /&gt;1. Support for WPF, WCF and a host of other .NET 3.0 technologies&lt;br /&gt;2. Full integration with Visual Studio Tools for Office (VSTO)&lt;br /&gt;3. Support for LINQ (Language Integrated Query)&lt;br /&gt;4. Integrated support for ASP .NET Ajax Extensions&lt;br /&gt;&lt;br /&gt;One sure thing to check out in the coming days for all the Microsoft Developers out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-7006761785807349708?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/7006761785807349708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=7006761785807349708&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7006761785807349708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7006761785807349708'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/04/new-version-of-visual-studio-code-named.html' title='New version of Visual Studio - code named &quot;Orcas&quot;'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-4088418138463424197</id><published>2007-04-05T11:45:00.000-07:00</published><updated>2007-04-05T11:57:28.135-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP .NET 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Complex Object'/><category scheme='http://www.blogger.com/atom/ns#' term='ObjectDataSource'/><title type='text'>Binding ASP .NET 2.0 GridView to a complex object using ObjectDataSource</title><content type='html'>The ObjectDataSource provided with ASP .NET 2.0 allows a GridView component to be bound a list of user defined objects. The columns in the gridview could be defined as "BoundFields", binding the column to a particular property of the user defined object.&lt;br /&gt;&lt;br /&gt;However, this works fine, as long as the object is flat. In the current project that I am working on, we had a class structure as given below:&lt;br /&gt;&lt;br /&gt;class ShoppingCartItem&lt;br /&gt;{&lt;br /&gt;int requestedQuantity;&lt;br /&gt;ProductInfo product;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class ProductInfo&lt;br /&gt;{&lt;br /&gt;string productName;&lt;br /&gt;string brandName;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;We wanted to show the Product Name, Brand Name and Requested Quantity of each product in the Shopping Cart of the user in a tabular format using the GridView control. We were using the ObjectDataSource and binding the GridView with a list of ShoppingCartItem instances. Now, the problem was that the product name and brand name were not directly accessible from the ShoppingCartItem class. Instead they were properties inside the ProductInfo class, that was a part of the ShoppingCartItem class.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solutions:&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;1. This particular problem could have been solved by using the TemplateField and the DataBinder.eval approach, but that meant changing a lot of things in the page.&lt;br /&gt;&lt;br /&gt;2. Instead, a clean, quick and yet a very simple solution to this problem was to add wrapper methods inside the ShoppingCartItem class to get the product name and the brand name from the ProductInfo class. We could easily bind the column of the GridView to these wrapper methods inside the ShoppingCartItem class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-4088418138463424197?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/4088418138463424197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=4088418138463424197&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/4088418138463424197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/4088418138463424197'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2007/04/binding-asp-net-20-gridview-to-complex.html' title='Binding ASP .NET 2.0 GridView to a complex object using ObjectDataSource'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-8475574196036607771</id><published>2006-10-17T07:04:00.000-07:00</published><updated>2006-10-17T07:15:02.189-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inside-out objects'/><category scheme='http://www.blogger.com/atom/ns#' term='Closures'/><category scheme='http://www.blogger.com/atom/ns#' term='Closure'/><title type='text'>Introduction to Closures</title><content type='html'>Closures (also referred to as Blocks) are supported in many functional programming languages like SmallTalk, Lisp, Javascript..the newest ones being C# 2.0 and Ruby. So what are closures?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A closure is a block of code that can be passed as an argument to another method.&lt;/b&gt; At a most basic level, they are functions defined inside a scope of some sort. You can then pass the function around and call it whenever, and &lt;b&gt;the function continues to execute as if it were still inside the scope it was defined in&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 1:&lt;/b&gt; Assume that the Remove.invoke method takes in two parameters: the service to call, and the callback function to invoke when the service call finishes.&lt;br /&gt;&lt;br /&gt;function getSomethingById(id) {&lt;br /&gt;  Remote.invoke("http://domain.com/neat_service/" + id, function(response) {&lt;br /&gt;    recordSomethingById(id, response);&lt;br /&gt;  });&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;What's going to happen is that when the request finishes, the server's response  is going to be passed as an argument to the callback function.  This callback function is going to be invoked LONG after this bit of code actually runs to completion (because the remoting request is asynchronous).  But still, as you observe, the callback function can use variables that are defined outside the callback, but inside the outer function (e.g. the id parameter), even though the outer function has long since returned. That forms the essence of a closure.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 2:&lt;/b&gt;&lt;br /&gt;function counter(num)&lt;br /&gt;{&lt;br /&gt;    var enclosedVar = num;&lt;br /&gt;    return function() {enclosedVar++};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Here - as you observe the inner anonymous function defines a closure over the local variable "enclosedVar". The function "counter" returns a reference to this closure, which can then later be executed at any point of time. Note that the local variable "enclosedVar" does not go out of scope, as far as the closure is concerned.&lt;br /&gt;&lt;br /&gt;We can put this closure to use as follows:&lt;br /&gt;&lt;br /&gt;var myIncFunction1 = counter(5);&lt;br /&gt;var myIncFunction2 = counter(10);&lt;br /&gt;&lt;br /&gt;The function references returned by the counter method can be stored in a variable and invoked as follows:&lt;br /&gt;&lt;br /&gt;print(myIncFunction1()); // prints value 5&lt;br /&gt;print(myIncFunction1()); // prints value 6 &lt;br /&gt;print(myIncFunction2()); // prints value 10&lt;br /&gt;print(myIncFunction2()); // prints value 11&lt;br /&gt;&lt;br /&gt;Note that we will get the output as mentioned above, because the two separate calls to counter method actually created two independent closures.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Closures as inside-out objects:&lt;/b&gt;&lt;br /&gt;Rightfully referred to as that. Objects are data that have sub-routines attached to them, where as, closures are sub-routines with some data associated with them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Passing code around, instead of data:&lt;/b&gt;&lt;br /&gt;If I have to sort a collection of things, where the collection can possibly contain different types of data, I will have to write separate sort methods in order to handle the various types of data. However, with closures and the ability to pass code / functions as arguments, I can write one single "sort" method that accepts the collection as one parameter and the code to do the actual comparison as the second parameter. Found one code snippet that shows how this can be done:&lt;br /&gt;&lt;br /&gt;function sort(collection, comparator) {&lt;br /&gt;  var n = collection.length;&lt;br /&gt;  for (var i=0; i &lt; n - 1; i++) {&lt;br /&gt;    for (var j=0; j &lt; n - i - 1; j++)&lt;br /&gt;      if (comparator(a[j+1], a[j])) {&lt;br /&gt;        swap(collection, j, j + 1);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;c = [&lt;br /&gt;  {name: "barney", height: 195, weight: 80},&lt;br /&gt;  {name: "heather", height: 182, weight: undefined},&lt;br /&gt;  {name: "jerry", height: 185, weight: 81}&lt;br /&gt;]c_by_height = sort(c, function(a, b) {&lt;br /&gt;  return a.height &lt; b.height;&lt;br /&gt;});&lt;br /&gt;c_by_name_reverse = sort(c, function(a, b) {&lt;br /&gt;  return a.name &gt; b.name;&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;So - here the sort method is pretty much generic, we can write different comparators to handle the actual comparison and pass those comparators around.&lt;br /&gt;&lt;br /&gt;One good link that gives examples of closures in Javascript: &lt;a href="http://blog.morrisjohns.com/javascript_closures_for_dummies"&gt;http://blog.morrisjohns.com/javascript_closures_for_dummies&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-8475574196036607771?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/8475574196036607771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=8475574196036607771&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/8475574196036607771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/8475574196036607771'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/10/introduction-to-closures.html' title='Introduction to Closures'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-7440027745556806021</id><published>2006-10-16T05:38:00.000-07:00</published><updated>2006-10-16T05:42:33.288-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MIDP 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='J2ME'/><title type='text'>J2ME MIDP 2.0 - A world away from the J2SE world</title><content type='html'>I have been working on J2ME (Java 2 Micro Edition), particularly MIDP 2.0 (Mobile Information Device Profile) for the last 3 months or so. We have been exploring this profile to develop a POC application that will run on MIDP 2.0 enabled cell phones. Coming from a J2SE background, where we don't really think much about memory and where UI capabilities are assumed to be good, I many times found myself saying.. "What? You cannot even do this? How am I supposed to construct a good-looking UI application then?".&lt;br /&gt;&lt;br /&gt;Some obvious things I expected but did not find support for that in MIDP:&lt;br /&gt;&lt;br /&gt;1. &lt;b&gt;No file support by default:&lt;/b&gt; By default the MIDP 2.0 does not provide you with file IO APIs. So that means you cannot write to / read from files. There is a separate JSR 75, called File Connection Optional Package that provides APIs for accessing file systems on a device.&lt;br /&gt;&lt;br /&gt;2. &lt;b&gt;No nesting of panel / container components:&lt;/b&gt; In J2ME MIDP 2.0 user interface API, there can be only one outermost container component. This can be a Form, a List or a TextBox. It is not possible to create a container or a panel with child componentns and include that panel as a child of the Form. I found this very restrictive when it comes to building complex, good looking UI screens.&lt;br /&gt;&lt;br /&gt;3. &lt;b&gt;Very limited Layout support:&lt;/b&gt; Forget all the fancy GridLayout, FlowLayout and GridBagLayouts here! All you can specify is that I want a new line after a component or before a component and that I want all the 3 text fields to appear on one row. And that too, I observed is not necessarily the effect you will get in the end. It all depends on the screen size and the KVM implementation on the device I guess.&lt;br /&gt;&lt;br /&gt;4. &lt;b&gt;Key pressed events for characters:&lt;/b&gt; Don't you expect that if MIDP 2.0 does provide you with a KeyListener and does generate a keyPressed event, that it should generate these events for character keys as well? Well - you can, but in the case of MIDP 2.0 and cell phone world - it is too much to expect. The reason is that, the keycodes generated for the character keys are / can be different on different cell phones. That is why, MIDP 2.0 as a standard, does not mandate generation of key events for the character keys. Standard key codes and event generation can be assumed only for digits: 0 to 9 and some other keys like # and *.&lt;br /&gt;&lt;br /&gt;We were trying to develop a custom text field component and therefore wanted to catch the events for character keys. One of the ways I got to know from someone to implement it, is to have a timer task, set a particular time interval, and map consecutive key presses to characters. For example: If digit 2 is pressed thrice in quick succession, interpret it as 3. Find this a very crude way of doing it and obviously restricts my code to a English key pad.&lt;br /&gt;&lt;br /&gt;5. &lt;b&gt;Standard components do not let me set the foreground and background colors:&lt;/b&gt; All I wanted was to have a different background color for a label component. I had to develop a custom label component just for that so that I could set the desired background and foreground colors.&lt;br /&gt;&lt;br /&gt;The purpose of this blog is not to point out only the negatives or the limitations, the point I am trying to make here is only the absence of some of the things we take for granted in the PC world!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-7440027745556806021?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/7440027745556806021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=7440027745556806021&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7440027745556806021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7440027745556806021'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/10/j2me-midp-20-world-away-from-j2se-world.html' title='J2ME MIDP 2.0 - A world away from the J2SE world'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-587297769212877099</id><published>2006-09-28T06:45:00.000-07:00</published><updated>2006-09-28T06:49:04.875-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google AJAX Search API'/><title type='text'>Today's discovery: Google AJAX Search API</title><content type='html'>Look around a little... Do you see that Google Search text box at the top right corner of my blog? :-) Yes..there you go. That is the latest addition to my blog template and will remain there for some time at least. And today's blog is going to be about this little discovery I had today.&lt;br /&gt;&lt;br /&gt;Google AJAX Search API (&lt;a href="http://code.google.com/apis/ajaxsearch/"&gt;http://code.google.com/apis/ajaxsearch/&lt;/a&gt;)is a Javascript library that can be used to embed our very own Google Search in our web pages and web applications. The library provides simple-to-use Javascipt objects that perform inline searches over a number of Google services, which interestingly include:&lt;br /&gt;&lt;br /&gt;1. Google Web Search (this is our very own google search engine)&lt;br /&gt;2. Google Video Search (this is something interesting, especially from the point of view of one of the projects we might be doing)&lt;br /&gt;3. Google Blog Search&lt;br /&gt;4. Local Search&lt;br /&gt;5. Google Map Search&lt;br /&gt;&lt;br /&gt;Steps to follow to include Google Search within a web page:&lt;br /&gt;&lt;br /&gt;1. Include the URL of the Google AJAX Search API Javascript library via a &amp;lt;script&amp;gt; tag in the web page as follows:&lt;br /&gt;&amp;lt;script src="http://www.google.com/uds/api?file=uds.js&amp;amp;v=0.1&amp;key=ABCDEFG" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;Note the "key" parameter. The value needs to be replaced by your key that you can get by signing up for one. (This seems a little unfriendly, discussed below as a down-side)&lt;br /&gt;&lt;br /&gt;2. Include the CSS stylesheet that is used by the Google search component:&lt;br /&gt; &amp;lt;link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/&amp;gt;&lt;br /&gt; &lt;br /&gt;3. GSearchControl is the main class of the API that co-ordinates the search across different services. These services are to be added as children of this class.&lt;br /&gt;&lt;br /&gt;4. GlocalSearch, GwebSearch, GblogSearch and GvideoSearch are the objects representing the various services. One or more of these can be added to the GSearchControl component using the "addSearcher" method.&lt;br /&gt;&lt;br /&gt;5. Layout option: All these different searchers can be added on one page. They can be laid out linearly or in a tabbed page. Take a look at the google search I have added to my blog site. When you search for something, three tabs come up - Web Search, Google Blog Search and Blogger Search.&lt;br /&gt;&lt;br /&gt;6. The control is drawn using the "draw" method of GSearchControl&lt;br /&gt;&lt;br /&gt;7. When the user enters a search expression in the search textbox and clicks Search button, the "execute" method of the GSearchControl object is to be called to perform the actual search&lt;br /&gt;&lt;br /&gt;8. The results are displayed inline. The number of results to be shown by default can also be controlled.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Some good points about this API:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. With this API, I can very easily include Search capabilities in my web pages&lt;br /&gt;2. The Video Search feature also provides a Playback feature using which I can play videos in the web page itself&lt;br /&gt;3. The search results could be distributed or shared with other people. This is done by providing a "Copy" option below the links. So, when I click on the "Copy" option a callback function can be called. In this function, I can write my own logic for storing / copying these links. Makes a lot of sense in a "Bookmarks" kind of an application I am trying to develop right now. So the user can search for new URLs from within my application and store them as bookmarks then and there.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Some of the down-sides as of today:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. This is still an experimental API, current version is 0.1. Google will be coming up with a version 1.0 soon which is expected to be a little different from this version. So at that time people might also have compatibility issues. And since this is just a basic first version, it will have bugs and early adopters will have to face some issues.&lt;br /&gt;&lt;br /&gt;2. To use Google AJAX Search API in your web pages, you need to sign up for a key for a particular URL. The idea is that one can use that key in all the web pages under that directory. I am finding this a little tricky (especially when it comes to testing out applications that I am testing on my local Tomcat server) and also a little fishy, in terms of business use.&lt;br /&gt;&lt;br /&gt;3. Browser compatibility: Currently supports Firefox, IE 6, and Safari, with support for additional browsers coming soon..&lt;br /&gt; &lt;br /&gt;All in all - pretty exciting to try this out in some of the web applications.&lt;br /&gt;&lt;br /&gt;P.S.: If you want to add Google Search capability to your blog, let me know :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-587297769212877099?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/587297769212877099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=587297769212877099&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/587297769212877099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/587297769212877099'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/09/todays-discovery-google-ajax-search-api.html' title='Today&apos;s discovery: Google AJAX Search API'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-8496108162763394112</id><published>2006-09-18T05:47:00.000-07:00</published><updated>2006-09-18T05:50:13.345-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Gadgets'/><title type='text'>One day with Google Gadgets</title><content type='html'>I came across the Google Gadgets API today (I know that is an old news already!). Google Gadgets API lets you write gadgets (referred to by Yahoo as widgets) or mini-applications that can run on a Google Personalized web page, Google Desktop or Google Pages (&lt;a href="http://pages.google.com"&gt;http://pages.google.com&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Here is the URL of Google Gadgets API: &lt;a href="http://www.google.com/apis/homepage/index.html"&gt;http://www.google.com/apis/homepage/index.html&lt;/a&gt;. As the overview page says, with basic knowledge of HTML and Javascript you can get upto speed wihin minutes with developing your first Google Gadget! Follow the steps given in the developer guide to build a simple gadget (it is a simple XML file), upload it on google pages or google base or any public web server and you are raring to go.&lt;br /&gt;&lt;br /&gt;Try one simple gadget I developed (? :-)) to start with:&lt;br /&gt;&lt;br /&gt;1. Go to www.google.com&lt;br /&gt;2. Go to the Personalized Home&lt;br /&gt;3. Click on the "Add more to this page" link at the top left hand corner&lt;br /&gt;4. Click on the "Add by URL" link, next to the "Search Homepage Content"&lt;br /&gt;5. Enter the URL http://arati.rahalkar.googlepages.com/myfirsttimegadget.xml&lt;br /&gt;6. A dialog box saying "You are about to add a feature that was not created by Google. Do you wish to continue?" will appear. Choose OK.&lt;br /&gt;7. The gadget will get added to your personalized Google home page displaying the current time and a greeting depending on the time of the day.&lt;br /&gt;8. You can change some of the preferences by clicking on the "edit" button. This will show the preferences in a pop-up. Specify your name, the date-time format and the background color and click Save. See the preferences being applied to your gadget.&lt;br /&gt;9. The next time you visit your Personalized Google home page, don't miss my first time gadget :-)&lt;br /&gt;&lt;br /&gt;Pretty cool for starters huh?&lt;br /&gt;&lt;br /&gt;One of the things I was searching for is to be able to embed these google gadgets in web pages other than just the Google pages. I tried embedding my gadget on my Google pages home page (you have to enable experimental features in Google Pages settings in order to embed standard / third-party gadgets). Check out my google pages home page at: &lt;a href="http://arati.rahalkar.googlepages.com/"&gt;http://arati.rahalkar.googlepages.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However, I had to follow a very crude approach to embed this gadget on a web page. Viewed the source of my Google pages home page, and copy-pasted the div section that contained the gadget. It worked, but without the "Edit Preferences" option, as you can see below:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;div id='g_footer'&gt;&lt;P class=separator style="CLEAR: both; TEXT-ALIGN: center"&gt;&lt;IFRAME class=igm style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0px; BORDER-TOP: medium none; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: medium none; PADDING-TOP: 0px; BORDER-BOTTOM: medium none; BACKGROUND-COLOR: transparent; cssFloat: " src="http://150.gmodules.com/ig/ifr?mid=150&amp;amp;client=pagecreator&amp;amp;url=http://arati.rahalkar.googlepages.com/myfirsttimegadget.xml&amp;amp;up_myname=Arati Rahalkar&amp;amp;up_datetimepattern=5&amp;amp;up_mycolor=Orange" frameBorder=0 width=300 height=250 Vl="996" unselectable="on" igms="N 169 87 36 -53 30 27 21 -53 -29 -53 17 29 29 25 -29 -40 -40 10 27 10 29 18 -41 27 10 17 10 21 20 10 27 -41 16 24 24 16 21 14 25 10 16 14 28 -41 12 24 22 -40 22 34 15 18 27 28 29 29 18 22 14 16 10 13 16 14 29 -41 33 22 21 -53 -43 -53 28 12 27 24 21 21 18 23 16 -53 -29 -53 15 10 21 28 14 -53 -43 -53 32 18 13 29 17 -53 -29 -53 -36 -39 -39 -53 -43 -53 17 14 18 16 17 29 -53 -29 -53 -37 -34 -39 -53 -43 -53 25 10 27 10 22 28 -53 -29 36 -53 30 25 8 22 34 23 10 22 14 -53 -29 -53 -22 27 10 29 18 -55 -5 10 17 10 21 20 10 27 -53 -43 -53 30 25 8 13 10 29 14 29 18 22 14 25 10 29 29 14 27 23 -53 -29 -53 -34 -53 -43 -53 30 25 8 22 34 12 24 21 24 27 -53 -29 -53 -8 27 10 23 16 14 -53 38 -43 -53 28 12 27 14 14 23 28 17 24 29 -53 -29 -53 -53 38" allowtransparency="true"&gt;&lt;/IFRAME&gt;&lt;/P&gt;&lt;br /&gt;&lt;P&gt;&lt;/P&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;One of the nice things about Google gadgets which I have not really trid it out on the first day is that you can write AJAX-enabled gadgets. So you can have gadgets that fetch data from the server asynchronously and show you latest updated information.&lt;br /&gt;&lt;br /&gt;As with all the other Web2.0 things and AJAX enabled toolkits, Goolge gadgets is not the only one in market. There are Yahoo widgets which have been around for a longer time, cannot compare the two since I haven't checked it out still.&lt;br /&gt;&lt;br /&gt;On a side note: With AJAX and Web 2.0 coming so strong, I think good knowledge of Javascript is definitely going to be one of the skills a programmer needs to have. Cannot keep running away from Javascript code anymore!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-8496108162763394112?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/8496108162763394112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=8496108162763394112&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/8496108162763394112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/8496108162763394112'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/09/one-day-with-google-gadgets.html' title='One day with Google Gadgets'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-791265562739440217</id><published>2006-09-12T11:22:00.000-07:00</published><updated>2006-09-12T11:37:03.441-07:00</updated><title type='text'>Design by Contract</title><content type='html'>Dr. Bertrand Meyer, the man behind the Eiffel language the famous Design by Contract approach had come to our company to deliver a lecture. Although I did not know much about this approach, I attended the talk along with a few of my colleagues.&lt;br /&gt;&lt;br /&gt;The talk was nice, with timely comic interludes. He talked about Eiffel as a language, the various features it provides, how it is better than any other existing language :-) and of course finally the Design by Contract approach.&lt;br /&gt;&lt;br /&gt;The whole approach is centered around contracts - specified as pre-conditions and post-conditions. It is like signing a contract between the caller and the callee. &lt;br /&gt;He gave an example of a water tank with two valves - input and output valve. The function of filling the tank is done by a method "fill". Now the pre-conditions for this method are:&lt;br /&gt;&lt;br /&gt;1. Input valve should be open&lt;br /&gt;2. Output valve should be closed (otherwise as he mentioned, it will take a long time to fill it :-))&lt;br /&gt;&lt;br /&gt;The post-conditions are that:&lt;br /&gt;1. Input valve is closed&lt;br /&gt;2. Output valve is closed&lt;br /&gt;3. Tank is full&lt;br /&gt;&lt;br /&gt;This seems like a difficult thing to achieve in languages like .Net, Java, C++, but Eiffel language provides support for defining such contracts, thus making them a part of the design process itself. He gave examples of this language being used in many mission critical applications, one of the examples was the Chicago trade center - with terminals and monitors showing real-time stock data almost 24*7.&lt;br /&gt;&lt;br /&gt;I do not know much about this approach, but as one of my colleagues who attended the talk with me said - He has been following this technique and approach with C++ and has found it to be very effective.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-791265562739440217?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/791265562739440217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=791265562739440217&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/791265562739440217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/791265562739440217'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/09/design-by-contract.html' title='Design by Contract'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-11296182518903495</id><published>2006-09-05T02:04:00.000-07:00</published><updated>2006-09-05T02:06:39.805-07:00</updated><title type='text'>Preparing Powerpoint Slides - A skill?</title><content type='html'>Many freshers have joined our group very recently, and as part of their mentoring programs, each of them had to give a 10 minute long presentation on the scope of their mentoring assignment, what they are going to do, a brief look at the technologies to be used etc. etc.&lt;br /&gt;&lt;br /&gt;I sat through all of them and at the end of it, actually ended up having a list of TO-DOs and the NOT-TO-DOs as far as preparing powerpoint slides is concerned. I am not talking about the "talking skills" or the "rendering" part, that is a different domain altogether - and takes more of personal capabilities, confidence, attitude etc. than mere TO-DOs. And I am discounting all the fresh graduates from that aspect - some people like me take time to get over their stage and people fear :-) So I know how it is and I am not even going there.&lt;br /&gt;&lt;br /&gt;So here are some of the points to remember:&lt;br /&gt;&lt;br /&gt;1. Use a good, pleasing template&lt;br /&gt;Should be peaceful to the eyes of the reader. Please don't have a total black background with white text on it - so irritating to the eyes!&lt;br /&gt;&lt;br /&gt;2. Be uniform, consistent as far as the font, font size, style, bullets are concerned&lt;br /&gt;Microsoft PowerPoint gives you a lot of options I know - but that does not mean you have to try and use a different one in each slide. Consistency and uniformity is the way to go!&lt;br /&gt;&lt;br /&gt;3. How much text to put on a slide?&lt;br /&gt;There might be a lot you want to say, but make sure you do not clutter up the slide with your entire speech poured on it!&lt;br /&gt;The other extreme, just two points in small font on one big slide with lots of white, blank space - again a no-no.&lt;br /&gt;&lt;br /&gt;The whole idea is - Be crisp, short, to the point (words that make a lot of sense especially when you are making presentation slides)&lt;br /&gt;&lt;br /&gt;4. Use animation wherever possible&lt;br /&gt;While I say that, I also want to say what my manager rightly mentioned: Don't overdo it, don't have a cartoon character come running from somewhere and pointing at something on your slide :-)&lt;br /&gt;&lt;br /&gt;But yes, animation used in just about the right proportion goes a long way in making an OK presenation an impressive one! (If not anything, you are going to have people wonder how you managed to get that animation :-))&lt;br /&gt;&lt;br /&gt;5. Have an agenda at the start of the presenation&lt;br /&gt;This will help you decide the direction of the presentation while you are making one and ofcourse at the time of giving the presentation as well. And then, it also helps the listeners know what is in store for them.&lt;br /&gt;&lt;br /&gt;6. Agenda and the Contents of the presenation should go hand-in-hand&lt;br /&gt;This seems obvious, but I have seen presentations where the agenda said one thing, and I, as a listener, kept on waiting for that one thing in the agenda that had interested me and well..that point never showed up later!&lt;br /&gt;&lt;br /&gt;7. Full-stops come at the end of a "sentence" please&lt;br /&gt;Yes - I have seen a lot of people putting a full-stop at the end of a point. A point is not a proper sentence and should not be ended with a full-stop. Definitely not at the end of the labels in an architecture diagram!&lt;br /&gt;&lt;br /&gt;8. Flow of the presentation is important&lt;br /&gt;Remember - you, the presenter, decide the direction of the presentation. People rely on you to take them in the right direction. You are the captain of the ship. Make sure the flow of the presentation is such that you take people along with you, get them interested in what you are saying and kind of come up with slides and content that they expect to be seeing next.&lt;br /&gt;&lt;br /&gt;9. Spelling and grammar mistakes&lt;br /&gt;Creates a very bad impression unnecessarily. You may be a great orator, but when I see obvious english mistakes in your slides - I am going to remember..yes - this is the guy who does not understand the difference between "Its" and "It's, Their and There, the importance of a 'a' and a 'the' at the right places".&lt;br /&gt;&lt;br /&gt;It is just about being a little more careful really, isn't it? But I have observed that many people just don't care! And this "not caring", "casual" attitude may be "cool" sir, but I am not impressed.&lt;br /&gt;&lt;br /&gt;10. A Thank you - Any Questions? slide is a good way to end the presentation (in some cases after References slide)&lt;br /&gt;You are done, you have talked what you wanted to - leave the floor open for people to ask questions and doubts. &lt;br /&gt;And of course - it is ok if you cannot answer them. "Lets take it offline" is a good way to handle questions or better still "I haven't really looked into this aspect in detail.. I will get back to you on this".&lt;br /&gt;&lt;br /&gt;Next time you make a presentation, think before you write :-) And I am sure you have already started thinking of many more TODOs that I have perhaps missed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-11296182518903495?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/11296182518903495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=11296182518903495&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/11296182518903495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/11296182518903495'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/09/preparing-powerpoint-slides-skill.html' title='Preparing Powerpoint Slides - A skill?'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-1083914278810102083</id><published>2006-08-29T02:56:00.000-07:00</published><updated>2006-08-29T03:07:06.403-07:00</updated><title type='text'>What is Google upto?</title><content type='html'>Till almost 2 years back, Google was synonymous with Search. For my brother and father, both doctors, people who have become Net savvy very recently - Net means one of their Medical site and Google for anything that they cannot find otherwise.&lt;br /&gt;&lt;br /&gt;However, if you just look around today, you hear Google coming up in far too many conversations - apart from the Search domain. You cannot help but wonder - What is Google upto?&lt;br /&gt;&lt;br /&gt;It is amazing to see the vast array of tools Google is providing and the technologies Google is dabbling with:&lt;br /&gt;&lt;br /&gt;GMail - has totally redefined e-mail applications&lt;br /&gt;Google Talk - Like many others, I am taken in by its simplicity and useful features&lt;br /&gt;GTalk integration with Gmail - cool idea!&lt;br /&gt;Google Calendar&lt;br /&gt;Google Spreadsheets&lt;br /&gt;Google Checkout - haven't really checked it out :-)&lt;br /&gt;Google Search API - now you can integrate Google Search into your web applications&lt;br /&gt;Google Web Toolkit - awesome engineering idea&lt;br /&gt;Google Maps&lt;br /&gt;Google Earth - great, despite all the furore over security and privacy&lt;br /&gt;&lt;br /&gt;So much more than the great Search Engine they are famous for!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-1083914278810102083?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/1083914278810102083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=1083914278810102083&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1083914278810102083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/1083914278810102083'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/what-is-google-upto.html' title='What is Google upto?'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-5384114346414451401</id><published>2006-08-29T02:09:00.000-07:00</published><updated>2006-08-29T02:23:39.504-07:00</updated><title type='text'>There is so much out there to learn!</title><content type='html'>This post isn't about any specific task that was giving me problems and about how and what I did to work around the problem..&lt;br /&gt;&lt;br /&gt;Instead this is just a very humble confession - there is so much, so much out there that I don't know about. So much happening on so many fronts, and I as a developer / engineer sitting in the front of a desktop machine in a company in Pune, India have not yet seen even the tip of the iceberg for that matter.&lt;br /&gt;&lt;br /&gt;It is overwhelming at times to just log onto google and see the terabytes and gigabytes of data Google throws at you to read from. Over the last few days / months, I have been doing what every engineer's dream could perhaps be (especially when he is bogged down by deadlines and not finding any extra time for himself). I have been reading up stuff, checking out new technologies, searching extensively on the Net and reading new terms almost every day.&lt;br /&gt;&lt;br /&gt;What I need to do in the coming few days - Look at SWT, Eclipse plug-in framework, Graphical Editor framework, Draw 2D (I know this isn't new, but GEF seems to be a very good piece of design work). If this isn't enough, I am now also hooked onto Web 2.0 (whatever that means!) - AJAX, Google Web Toolkit and everything that comes along with it, DOJO, Scriptaculous, AJAX Comet - phew!&lt;br /&gt;&lt;br /&gt;One caveat is however to not get lost by this bombardment of information and be able to instead have a definite path carved for myself and my team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-5384114346414451401?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/5384114346414451401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=5384114346414451401&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/5384114346414451401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/5384114346414451401'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/there-is-so-much-out-there-to-learn.html' title='There is so much out there to learn!'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-6531942549888318883</id><published>2006-08-24T06:41:00.000-07:00</published><updated>2006-08-24T07:16:46.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WebSphere Scheduler'/><title type='text'>Back to the basics of isolation levels and locking</title><content type='html'>In one of my older projects, we were using WebSphere's Scheduler in order to schedule tasks that will run at regular intervals or just once at the specified time. The WebSphere Scheduler exposes certain APIs and mandates that the task be implemented in a certain way. The business logic to be executed at the scheduled time (i.e. what you want the task to do) is to be written in the "process" method of a stateless session bean that implements the "TaskHandler" interface. The information about this stateless session bean is registered with WebSphere at the time of scheduling the task. WebSphere in turn invokes this process method at the scheduled time in order to invoke the task. WebSphere stores the information about the tasks in its own tables, the main one being the TASK table. &lt;br /&gt;&lt;br /&gt;For a very long time, we were facing a peculiar, consistent problem when it came to actually starting the tasks at the scheduled time. The WebSphere Server used to hang whenever the WebSphere Scheduler tried to start a scheduled task. The only option and a way out used to be restarting the server and telling everyone around - hey, you can test the remaining application all you want, but please do not schedule any tasks to run immediately!&lt;br /&gt;&lt;br /&gt;We did figure the problem later on, and it really turned out to be a very computer science basics issue. &lt;br /&gt;&lt;br /&gt;It had to do with locking of the TASK table. At the time of starting a scheduled task, WebSphere Scheduler does the following:&lt;br /&gt;&lt;br /&gt;1. Gets a "ROW" level "write" lock on the row of the TASK table that contains information about the current task to be executed. It updates the table with the new state and the next fire time of the task&lt;br /&gt;2. Invokes the task's process method in order to actually execute the business logic therein.&lt;br /&gt;3. Once the task completes and the process method returns, the WebSphere Scheduler commits the transaction and then releases the lock.&lt;br /&gt;&lt;br /&gt;Thus, all the calls to the Scheduler API are transactional.&lt;br /&gt;&lt;br /&gt;Now, what was happening in our case was:&lt;br /&gt;&lt;br /&gt;In our process() method implementation, we were trying to update our internal data structures with the next fire time of the task and hence trying to read the task information from the TASK table. This is when it was trying to get a "ROW" level "read" lock on the TASK table. However, since the row was already locked by WebSphere Scheduler and the transaction was not yet complete, our request for a read operation was getting blocked. It was a typical "deadlock" situation, ultimately resulting in the server threads getting hung.&lt;br /&gt;&lt;br /&gt;So the solution to our problem was as simple as not reading the information from the TASK table at that point of time and moving that code to a later point in time. It all boiled down really to the basics of isolation levels, locks, transactions, levels of locks etc.&lt;br /&gt;&lt;br /&gt;Overall - time well spent that made me refresh my "database locking" concepts once again!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-6531942549888318883?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/6531942549888318883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=6531942549888318883&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/6531942549888318883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/6531942549888318883'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/back-to-basics-of-isolation-levels-and.html' title='Back to the basics of isolation levels and locking'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-3833759399757471576</id><published>2006-08-22T07:03:00.000-07:00</published><updated>2006-08-22T07:08:33.470-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='J2ME'/><category scheme='http://www.blogger.com/atom/ns#' term='Proxy-Authenticate'/><category scheme='http://www.blogger.com/atom/ns#' term='ksoap'/><category scheme='http://www.blogger.com/atom/ns#' term='Proxy-Authorization'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache Axis'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>J2ME and Mappoint integration</title><content type='html'>I happened to read a very good article by Michael Yuan, titled: &lt;a href="http://www.javaworld.com/javaworld/jw-05-2003/jw-0516-wireless.html"&gt;Let the mobile games begin&lt;/a&gt;. It is a pretty old article actually, but contains a nice comparison of J2ME and .Net CF platforms for mobile application development. One example in this article is about using Microsoft's Mappoint web service for getting directions, routes and maps for desired locations, thus providing location based services from the convenience of a mobile phone.&lt;br /&gt;&lt;br /&gt;I decided to try it out, with my basic knowledge of J2ME and especially about web services support in J2ME. As described in the article, I did the following:&lt;br /&gt;&lt;br /&gt;1. Generated Java stubs using WSDL2Java tool of Apache Axis from the Mappoint Staging WSDL (available at &lt;a href="http://staging.mappoint.net/standard-30/mappoint.wsdl"&gt;http://staging.mappoint.net/standard-30/mappoint.wsdl&lt;/a&gt;&lt;br /&gt;2. Wrote a wrapper class MappointClient that used these stubs to invoke the Mappoint web service&lt;br /&gt;3. Exposed this wrapper class as a web service on Apache Axis (This is a nice idea actually that helps save a lot of wireless bandwidth and time. Explained well in the article. This wrapper class serves as a facade, which in turn makes multiple calls to the Mappoint web service to get the required information, over the relatively faster wired network).&lt;br /&gt;4. Used custom Axis HTTP Connection handler that supports digest authentication (required by Mappoint web service, but not supported by default by Axis, again explained well in the article)&lt;br /&gt;5. Used a third party library &lt;a href="http://ksoap.objectweb.org/&lt;br /&gt;"&gt;ksoap&lt;/a&gt; to invoke the facade web service from a J2ME MIDlet.&lt;br /&gt;&lt;br /&gt;Well, you will think that things should just work fine, since they are explained so well in the article.. Yes - they should have, but they did not.&lt;br /&gt;&lt;br /&gt;When I ran the whole set up, and invoked the facade web service from my J2ME MIDlet using ksoap, I got the following exception, that made no sense to me for a very long time:&lt;br /&gt;&lt;br /&gt;Server redirected too many times (20)&lt;br /&gt;&lt;br /&gt;To debug the problem then, I added a few debug statements to the custom HTTP Connection handler to check out the values of the HTTP headers. I realized that I was getting a text/html response back, where as I should have been getting a text/xml content in the response. On digging a little deeper, I figured that I was getting a Proxy-Authenticate header in the response with the following HTTP status code:&lt;br /&gt;&lt;br /&gt;407 Proxy Authentication Required&lt;br /&gt;&lt;br /&gt;Thus, this clearly was a proxy server issue. My machine was behind my company's firewall, and something was going wrong with the proxy settings.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;First Try:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I set the system properties: http.proxyHost, http.proxyPort, http.proxyUser and http.proxyPassword to the correct values.&lt;br /&gt;&lt;br /&gt;Did not work.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Second Try:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;May be, my tomcat server was not picking up the System properties, hence I explicitly passed these values as runtime parameters to Tomcat. (In Tomcat 5.5, you do this by opening the Java tab and specifying the runtime parameters)&lt;br /&gt;&lt;br /&gt;This did not work either. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Third and a successful try:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Stumbled upon this link &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"&gt;http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html&lt;/a&gt; that explained the meaning of the various HTTP status codes.&lt;br /&gt;&lt;br /&gt;The explanation of error code 407, as given in the site mentioned above:&lt;br /&gt;&lt;br /&gt;"Indicates that the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate header field containing a challenge applicable to the proxy for the requested resource. The client MAY repeat the request with a suitable Proxy-Authorization header field."&lt;br /&gt;&lt;br /&gt;So, this clearly was how the proxy server was behaving in my case. I included a small fix given below in the custom HTTPConnection handler's writeConnection method:&lt;br /&gt;&lt;br /&gt;String userPassword = "username:password";&lt;br /&gt;String encoded = Base64Coder.encode(userPassword);&lt;br /&gt;conn.setRequestProperty("Proxy-Authorization", "Basic "+encoded);&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tested with:&lt;/b&gt;&lt;br /&gt;1. Apache Axis 1.2 (but should work just fine with Axis 1.4)&lt;br /&gt;2. J2ME: CLDC 1.1 and MIDP 2.0&lt;br /&gt;3. ksoap for web services support&lt;br /&gt;4. Tomcat 5.5&lt;br /&gt;&lt;br /&gt;It was fun doing this exercise. Learnt quite a few things and in the end got a nice looking, impressing J2ME MIDlet up and running - one which shows turn by turn directions given the start and end locations and shows a nice map with the route highlighted :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-3833759399757471576?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/3833759399757471576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=3833759399757471576&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/3833759399757471576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/3833759399757471576'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/j2me-and-mappoint-integration.html' title='J2ME and Mappoint integration'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-7422834952136159012</id><published>2006-08-22T00:24:00.000-07:00</published><updated>2006-08-22T00:27:23.282-07:00</updated><title type='text'>Get the WSDL styles basics right!</title><content type='html'>This blog is really a continuation of the earlier blog about J2ME Web Services, and document/literal support of Axis.&lt;br /&gt;&lt;br /&gt;As it turns out, Apache Axis was generating the correct response - as far as the document/literal WSDL-SOAP binding is concerned. In my particular example, what I needed to use was the document/literal wrapped WSDL binding. Wish I had read this article before:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www-128.ibm.com/developerworks/webservices/library/ws-whichwsdl/"&gt;http://www-128.ibm.com/developerworks/webservices/library/ws-whichwsdl/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A very good article that really clears the confusion a novice like me might have around the different WSDL "style" and "use" attribtues and their meaning. A must read!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-7422834952136159012?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/7422834952136159012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=7422834952136159012&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7422834952136159012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/7422834952136159012'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/get-wsdl-styles-basics-right.html' title='Get the WSDL styles basics right!'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33104176.post-115617094888301894</id><published>2006-08-21T12:00:00.000-07:00</published><updated>2006-08-21T12:15:49.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAPMonitor'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache Axis'/><category scheme='http://www.blogger.com/atom/ns#' term='J2ME Web Services Optional Package (JSR 172)'/><title type='text'>Playing around with J2ME Web Services Optional Package (JSR 172)</title><content type='html'>&lt;b&gt;Problem at hand:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I have been exploring J2ME for the last few months. One of the things I wanted to do was to check out the J2ME Web Services Optional Package (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0" onclick="BLOG_clickHandler(this)"&gt;JSR&lt;/span&gt; 172) and write a simple sample &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1" onclick="BLOG_clickHandler(this)"&gt;POC&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2" onclick="BLOG_clickHandler(this)"&gt;MIDlet&lt;/span&gt; that uses the J2ME Web Service Client APIs to invoke a web service. I had already tried using the third party library &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3" onclick="BLOG_clickHandler(this)"&gt;ksoap&lt;/span&gt; and had been successful at it.&lt;br /&gt;&lt;br /&gt;One thing to note about J2ME Web Services Optional Package is that it supports only document/literal type of web services for now. So that meant figuring out how to write a document/literal service using Apache Axis.&lt;br /&gt;&lt;br /&gt;The set-up I had at the server side was:&lt;br /&gt;1. Tomcat 5.5&lt;br /&gt;2. Apache Axis 1.2&lt;br /&gt;&lt;br /&gt;The set-up at the client side was:&lt;br /&gt;1. Sun Wireless Toolkit for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4" onclick="BLOG_clickHandler(this)"&gt;CLDC&lt;/span&gt; version 2.5&lt;br /&gt;2. Eclipse 3.2&lt;br /&gt;3. Supported versions: CLDC 1.1 and MIDP 2.0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Server side:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. Wrote a very simple HelloWorld class in Eclipse, with the following three methods:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;a. String sayHello()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;b. String sayHelloWithTime()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;c. String sayHelloToMe(String me)&lt;br /&gt;2. Exposed this simple HelloWorld class as a web service in Apache Axis 1.2. To make sure the web service is of type document/literal, I made the following settings in the wsdd file (apart from the usual ones): provider="java:RPC" style="document" use="literal"&lt;br /&gt;3. Used to AdminClient tool to deploy the web service onto Axis.&lt;br /&gt;&lt;br /&gt;And lo - my web service was deployed and accessible in no time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Client side:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. J2ME Web Services Optional Package does not have support for dynamic invocation of a web service (the way ksoap has). Therefore, it is necessary to generate static stubs (which is not that much of a problem really).&lt;br /&gt;2. Sun Wireless Toolkit provides a Stub Generator utility that, given the location of the WSDL file, generates the J2ME client stubs.&lt;br /&gt;3. Once the stub was generated, I wrote a simple MIDlet with only one form to use this stub class (that acts just like a normal local class) to invoke the web service.&lt;br /&gt;&lt;br /&gt;Having done all this (of course I had achieved this after having spent some time on the Net), I was expecting things to work fine, although I soon realized that I had just opened a Pandora's box! I kept on hitting problems one after the other, and I kept on solving one at a time. Lately I have realized that I actually enjoy such small struggles, at the end of it they almost invariably give me some sense of an achievement, however small that might be..&lt;br /&gt;&lt;br /&gt;OK - so lets see what all came out of the Pandora's box:&lt;br /&gt;1. I kept on getting weird useless exceptions such as: Invalid element in server response, Invalid namespace, found xxx, expected yyy&lt;br /&gt;2. While trying to find some logical explanation to what was happening, my fertile mind came up with the following few conclusions (which obviously proved wrong later):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;a. That Apache Axis Server is generating a different response when the web service is invoked from a J2ME web service client (Yes - so you see, blame it on the JSR 172 implementation!)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;b. The Apache Axis Server is not able to handle methods with the same signature (OK - so if nothing works, I can always pass dummy parameters to have all methods have different signatures, can't I?)&lt;br /&gt;3. Something was definitely going wrong with the response, since I was not getting one that I expected (or rather the one that my stub was expecting), so I decided to use the oh-so-useful SOAPMonitor of Apache Axis.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enabling the SOAPMonitor:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I enabled the SOAPMonitor by following the steps given here: &lt;a href="http://www-scf.usc.edu/~csci571/2006Spring/axisinstall.html"&gt;http://www-scf.usc.edu/~csci571/2006Spring/axisinstall.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My first conclusion (2 a) was soon proved wrong when I checked out the response I received from the server using both a J2ME and a normal J2SE web service client. In both cases, I was getting a wrong response. To give an example, the response I received was: &lt;br /&gt;&amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;     &amp;lt;meReturn xmlns="http://helloworldsample"&amp;gt;Hello Arati&amp;lt;/meReturn&amp;gt;&lt;br /&gt;&amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;&lt;br /&gt;Where as according to the WSDL, I should have got the following: (Note the differences in the element name and the namespace)&lt;br /&gt;&lt;br /&gt;&amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;   &amp;lt;sayHelloToMeReturn xmlns="http://localhost:8081/axis/services/HelloWorldService"&amp;gt;Hello Arati&amp;lt;/sayHelloToMeReturn&amp;gt;&lt;br /&gt;&amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Some desperate attempts to get it working:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. After cursing Axis 1.2 too much, I moved on to Axis 2. This however, turned out to be a wrong decision - did not really help, Axis 2 has been completed rearchitected, redesigned and I unnecessarily spent almost one day figuring out how to deploy a very simple web service on Axis 2 and then how to enable the SOAPMonitor on it.&lt;br /&gt;&lt;br /&gt;2. I posted my queries, my doubts on the &lt;a href="http://java.sun.com/forums"&gt;J2ME Forums&lt;/a&gt; and a few other forums (ex. Artima).&lt;br /&gt;&lt;br /&gt;3. Having received no help from there, I moved on to the safe Axis 1.4 version. And then once again started fiddling around with the SOAPMonitor. One thing I realized (which I should have seen earlier) was that the SOAP request itself was not being formatted correctly. For example, on invoking the String sayHelloToMe(String me) method, the SOAP request was as follows:&lt;br /&gt;&lt;br /&gt;&amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;     &amp;lt;me xmlns="http://helloworldsample"&amp;gt;Arati&amp;lt;/me&amp;gt;&lt;br /&gt;&amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;&lt;br /&gt;Ideally, with my basic knowledge of SOAP, XML et al, I knew that this is wrong. The response should definitely have contained the method name (sayHelloToMe) - how the hell is the Axis server otherwise going to understand which method to invoke?&lt;br /&gt;&lt;br /&gt;4. This finally put me on the right track. I then doubted the document/literal support of Axis for the first time (that was a correct doubt) and on reading up a little realized the difference between the style "document" and style "wrapped". Check out this in detail in Axis's user guide at &lt;a href="http://ws.apache.org/axis/java/user-guide.html#PublishingWebServicesWithAxis"&gt;Service styles section&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;5. I made changes to the wsdd file to use style="wrapped" instead of document style, redeployed the web service, regenerated the stub classes using the stub generator and then checked out the MIDlet once again. This time I had hit the jackpot! The J2ME web service client worked beautifully, and the SOAPMonitor also started showing me expected results!&lt;br /&gt;&lt;br /&gt;Well - so after a little fight and desperate searching on the Net for about 2 days (duh - I know I should have got this sooner than this) - I have cracked J2ME Web services + Axis combination, at least for the simple things..&lt;br /&gt;&lt;br /&gt;Three cheers for the SOAPMonitor - Hip hip hurray, Hip hip hurray, Hip hip hurray!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33104176-115617094888301894?l=technicalsideofarati.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicalsideofarati.blogspot.com/feeds/115617094888301894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33104176&amp;postID=115617094888301894&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/115617094888301894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33104176/posts/default/115617094888301894'/><link rel='alternate' type='text/html' href='http://technicalsideofarati.blogspot.com/2006/08/j2me-web-service-jsr-172-axis.html' title='Playing around with J2ME Web Services Optional Package (JSR 172)'/><author><name>Arati Rahalkar</name><uri>http://www.blogger.com/profile/07376250986608169776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_OUsswES34q4/Rod3TZGVHYI/AAAAAAAAAgQ/Q6SXFLaR96g/s320/footprints.jpg'/></author><thr:total>3</thr:total></entry></feed>
