<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Skip Sauls&apos; Blog</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/" />
    <link rel="self" type="application/atom+xml" href="http://dev2dev.bea.com/blog/skip/atom.xml" />
   <id>tag:dev2dev.bea.com,2008:/blog/skip//133</id>
    <updated>2008-04-25T21:58:15Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.31</generator>
 
<entry>
    <title>The Importance of Frontend Performance</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/04/the_importance.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/04/the_importance.html</id>
    
    <published>2008-04-25T21:58:15Z</published>
    <updated>2008-04-25T21:58:15Z</updated>
    
    <summary>Live-blogging from the Web 2.0 Expo in San Francisco in Steve Souders&apos; presentation.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>I've never "live-blogged" before, and in fact blogging is normally something that takes me forever as I treat the entries more like whitepapers than anything else.  I think that comes from the "enterprise" culture and my age more than anything else.  That being said, I'm sitting in a session by Steve Souders, who has been the chief performance Yahoo and is now at Google, and is the guy behind YSlow, etc., and it's quite interesting.</p>
<p>I'm blown away by the stats he has on various large sites, where he shows that 80-90% of the time is spent getting the content to and rendered on the client, with a relatively small amount of time spent on the server.  This is interesting because many BEA products are very good at the server side, with all the various -ilities that we are famous and loved for.  What we haven't done a ton of work on is the client, instead focusing on implementing the latest J2EE and industry standards.  The WebLogic Portal team certainly cares about the client, but I can't say that we've gone nearly as far in that area as we could/should have.</p>
<p>A lot of what is being presented may seem obvious, and he's building on the types of things that YSlow, etc. focus on.  The slide he's on as I type this is on JavaScript and how it is loaded, where a huge amount of time is spent just getting the code to the client (assuming an empty cache), and that's before it actually starts doing something.  If you've followed my earlier blogs then you know that I've minified, combined, and so on the code on they <a href="http://wlp.bea.com/dvt/appmanager/demo/dvt">wlp.bea.com playground</a>, but even after all that there is still room for improvement.</p>
<p>My personal opinion is that I shouldn't have had to do this, it should just "work" when I'm using a WLS/WLP/etc. server.  If as a developer I specify N JavaScript files, the server should be smart enough to package them all up, minify them, gzip them,etc. to do the right thing to make the client more efficient.  As a client-side developer I shouldn't have to use tricks or otherwise fool around with trying to optimize it.  Hey, we do a lot on the server to ensure that it works well, so why not on the client?</p>
<p>I sometimes get the impression that some folks don't think the client is important, and in fact they consider it "fluff" compared to the "hard stuff" on the back end.  I firmly believe that plenty has been done on the back end, and in fact any further optimization is going to be minimal and won't necessarily add any measurable value.  We've been in various horse races to show that the server is fast, and I'm sure that's important at some level, but if the client experience is slow and annoying, who really cares how fast the server is?  There is an old saying that the customer is king, and the real end-game customer are the users of the sites, not the people using our products.  If these end users aren't happy, our customers won't be happy.</p>
<p>And hey, if the client really is easy and fluffy, solving these problems ought to be a cinch for a bunch of hard core enterprise developers, right?</p>

]]>
        
    </content>
</entry>
<entry>
    <title>Play and REST on wlp.bea.com</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/04/play_and_rest_o.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/04/play_and_rest_o.html</id>
    
    <published>2008-04-02T19:55:53Z</published>
    <updated>2008-04-02T21:23:41Z</updated>
    
    <summary>You&apos;ve seen plenty of product presentations, demos, and so on, but how often do you really get to do something on your own without going through a lot of hassle?  Have some fun using some of the new features in BEA WebLogic Portal 10.2 with the new portlets on wlp.bea.com.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>If you've read my previous entries or otherwise heard about BEA WebLogic Portal 10.2, you probably know that we have some interesting new features to support <a href="http://en.wikipedia.org/wiki/Rich_Internet_application">Rich Internet Applications</a> and <a href="http://en.wikipedia.org/wiki/Web_2.0">Web 2.0</a>.  If you haven't, or would like a refresher, here are some background materials you might want to take a look at:</p>
<ul>
<li><a href="http://edocs.bea.com/wlp/docs102/clientdev/index.html">Client-Side Developer's Guide</a></li>
<li><a href="http://edocs.bea.com/wlp/docs102/clientdev/disc.html">The WLP Disc Framework</a></li>
<li><a href="http://edocs.bea.com/wlp/docs102/clientdev/rest.html">The WebLogic Portal REST API</a></li>
</ul>
<p>Now it's time to have some fun and play with these technologies directly.  I've added a few new portlets to the <a href="http://wlp.bea.com/dvt/appmanager/demo/dvt">WebLogic Portal Playground</a> that you can start using today.  If you haven't already done so, go to the site and login and/or create a new user account, which is quick and easy.  Once you're there, go to the <em>Exploration</em> page and you'll see these portlets:</p>
<h3>Try It!</h3>
<a href="http://dev2dev.bea.com/blog/skip/tryit_01.html" onclick="window.open('http://dev2dev.bea.com/blog/skip/tryit_01.html','popup','width=718,height=481,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false">
<img  title="Click for larger image" src="http://dev2dev.bea.com/blog/skip/tryit_01_thumb.png" width="359" height="240" />
</a>
<h3>View It!</h3>
<a href="http://dev2dev.bea.com/blog/skip/viewit_01.html" onclick="window.open('http://dev2dev.bea.com/blog/skip/viewit_01.html','popup','width=718,height=255,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img title="Click for larger image" src="http://dev2dev.bea.com/blog/skip/viewit_01_thumb.png" width="359" height="128" />
</a>
<p><strong>Using the Try It! Portlet</strong></p>
<p>
This portlet will let you try out the client-side Disc and REST features directly.  The user interface should be fairly straightforward, but here is a key:
</p>
<p>You can select a code template using the <em>Template</em> list:</p>
<img alt="tryit_templates_01.png" src="http://dev2dev.bea.com/blog/skip/tryit_templates_01.png" width="212" height="113" />
<p>This will change the code displayed in the code text area:</p>
<img alt="tryit_code_01.png" src="http://dev2dev.bea.com/blog/skip/tryit_code_01.png" width="472" height="205" />
<p>The buttons on the toolbar allow you to <em>Try It!</em> the code, <em>Copy to Clipboard</em> (IE only), and <em>Clear Output</em></p>
<img alt="tryit_buttons_01.png" src="http://dev2dev.bea.com/blog/skip/tryit_buttons_01.png" width="82" height="23" />
<p>Many of the code templates have related documentation that can be accessed via the <em>Doc Links</em> list:</p>
<img alt="tryit_doclinks_01.png" src="http://dev2dev.bea.com/blog/skip/tryit_doclinks_01.png" width="262" height="62" />
<p>Try some of these out for yourself.  For example, select the <em>List Look and Feels</em> template and press the <em>Try It!</em> button to see a list like this:<./p>
<p>If there is any output from the code it will be displayed in the lower text area:</p>
<img alt="tryit_output_01.png" src="http://dev2dev.bea.com/blog/skip/tryit_output_01.png" width="472" height="205" />
<p>The code for this template looks like this:</p>
<pre>

    var appContext = bea.wlp.disc.context.Application.getInstance();
    var xmlHttpReq = new bea.wlp.disc.io.XMLHttpRequest;
    var url = "/" + appContext.getWebAppName() + "/bea/wlp/api/lookandfeel/list";
    var params = "";
    params += "?portal=" + appContext.getPortalPath();
    params += "&desktop=" + appContext.getDesktopPath();
    params += "&webapp=" + appContext.getWebAppName();
    params += "&scope=visitor";
    params += "&format=json";
    url += params;
    xmlHttpReq.open("GET", url, true);
    xmlHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    function handler(xmlHttpReq) {
        if (xmlHttpReq.readyState == 4) {
            if (xmlHttpReq.status == "200") {
                var result = eval("(" + xmlHttpReq.responseText + ")");
                var content = result.content;
                var lookAndFeelDetails = content.lookandfeels;
                var lookAndFeelDetail = null;
                output("Displaying title: markup_name");
                for (var i = 0; i < lookAndFeelDetails.length; i++) {
                    lookAndFeelDetail = lookAndFeelDetails[i];
                    output(lookAndFeelDetail.title + ": " + lookAndFeelDetail.markup_name);
                }
            } else {
                output("Unable to retrieve look and feels.");
                output("Server response:\n\"" + xmlHttpReq.responseText + "\"");
            }
        }
    }

    xmlHttpReq.onreadystatechange = function () {handler(xmlHttpReq);};
    xmlHttpReq.send(null);

</pre>
<p>Note: The <em>output</em> function is a special-case provided for this sample and will direct output to the lower text area.  If you are using <a href="http://www.getfirebug.com/">Firebug</a> or another console, you may wish to use that for the output.  Similarly, the <em>codearea</em> variable used in some of the samples is a special-case used to represent the text area element for the code, which is useful for finding the portlet context, etc. using Disc.</p>
<p>You can modify the text in any of the templates and try it out yourself.  The doc links for each of the templates are a great way to learn what is possible, and you'll find that you can do quite a lot.   If you come up with some interesting templates that you think others might benefit from, send them my way and I'll add them along with a comment giving you credit.</p>
<p><strong>Using the View It! Portlet</strong></p>
This portlet provides a tree-style view into the portal context objects provided by Disc.  It builds the tree by iterating over the Disc objects, showing the type and either the title or the markup name.  When an object is selected in the tree it will update the property sheet and attempt to highlight that object.  The properties all come from Disc, and will give you an idea of what is available using that API.  Simply add <em>get</em> to the attribute name and you will have the name of the function for that object.  For example, if you click on a portlet you will see attributes such as:</p>
<img alt="viewit_props_01.png" src="http://dev2dev.bea.com/blog/skip/viewit_props_01.png" width="298" height="202" />
<p>You can use these in the <em>Try It!</em> portlet with code such as:</p>
<pre>

var portlet = bea.wlp.disc.context.Portlet.findByElement(codearea);
output("Label: " + portlet.getLabel());
output("Title: " + portlet.getTitle());
output("Page Title: " + portlet.getParentPage().getTitle());

</pre>
<p>Notice that there are functions for <em>getMarkupElement</em> and <em>getContentMarkupElement</em>, which are for the entire portlet and just the contents, respectively.  Depending on the selected look and feel you can use these to change the portlet's style dynamically.  For example, change the background color of the content area with the following:</p>
<pre>

var portlet = bea.wlp.disc.context.Portlet.findByElement(codearea);
portlet.getContentMarkupElement().firstChild.style.background = "green";

</pre>
<p>Note that you need to get the <em>firstChild</em> of the context object as the context object itself is a container.</p>
<p>
<p>You can dynamically change the portlet title with code such as:</p>
<pre>

var portlet = bea.wlp.disc.context.Portlet.findByElement(codearea);
var titlebar = portlet.getTitlebar().getMarkupElement();
var titleElement = titlebar.firstChild.firstChild;
output("Titlebar innerHTML: " + titleElement.innerHTML);
titleElement.innerHTML = "My Portlet"; 

</pre>
<p>Note that this won't change the portlet title permanently, but you can combine this with the REST command for  updating the portlet if you'd like to do so.  Check out the <em>Update Portlet Title</em> template to see the REST command in action, and where you could insert the code above to make this completely dynamic.  This is how the DVT (Dynamic Visitor Tools) sample works, and it should demonstrate just how easy using Disc and REST can be.</p>
<p>I'm hoping to replace the simple text area-based editor in the sample with something better soon, and may provide an <em>Upload Your Code</em> feature as well.  If you have other ideas for features, templates, etc., I'd love to hear from you.</p>
]]>
        
    </content>
</entry>
<entry>
    <title>Web 2.0 Performance Optimization - Images</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_3.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_3.html</id>
    
    <published>2008-03-28T23:31:34Z</published>
    <updated>2008-03-28T23:31:34Z</updated>
    
    <summary>In this entry I&apos;ll discuss some of the ways that images can be optimized for a site, including various formats, techniques, and utilities.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>The work that I've been doing around performance optimization for the <a href="http://wlp.bea.com/dvt/appmanager/demo/dvt">WebLogic Portal Web 2.0 Playground</a> site has made me realize just how truly bloated things have become.  In the early 1990's I was building <em>electronic brochures</em> for PCs running DOS with 640k memory and 256 color VGA displays.  This was before most people had ever heard of the web, and things like Flash, AJAX, and so on were unheard of.  These apps certainly didn't do as much or look as nice as modern web-based apps, but one thing that they were was efficient!  We spent a lot of our time optimizing the images and code to ensure that everything would fit onto a 1.4M floppy disk and run correctly within the tight confines of the PC.</p>
<p>So how does this ancient history relate to what I'm doing now?  I've been doing some of the same type of optimization in order to make our site run better.  While there are relatively few restrictions on modern computers compared to those ancient PCs, there are limits in the form of available bandwidth.  If you've read my previous entries you've seen what a difference can be made by optimizing the resources for the application based on the restrictions imposed by the medium.  Call me crazy, but I think that this sort of thing is fun, and I have to wonder how much better all software could be if it weren't so bloated.</p>
<p><strong>PNG Optimization</strong></p>
<p>I became a fan of the <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics">Portable Network Graphics (PNG)</a> format when I realized it was lossless, unlike JPEG, and supported transparencies and other features better than GIF.  Most modern browsers and tools support it well, and there are some nice utilities available.  It's not suitable for everything, and in fact I've gone back to JPEGs for some large backgrounds, but it's arguably the best all-around format today.</p>
<p>A problem with PNG is that many image editing programs don't do a good job of optimizing the files.  They include extraneous information when they save the files, and if I had to guess it is because they take a general purpose approach and save everything.  This is fine for editing and sharing, but the extra bloat is not helpful when deploying these images in a web application.</p>
<p>The good news is that there are several utilities that can be used to optimize PNGs, and I would recommend that everyone doing web development have one in their arsenal.  If you are interested in the technical details check out <a href="http://www.cs.toronto.edu/~cosmin/pngtech/optipng.html">A guide to PNG optimization</a> by Cosmin Truţa. After trying a couple of the free and online tools, I found that I really needed good batch mode support and ended up purchasing <a href="http://www.ardfry.com/pngoutwin/index.html">PNGOUTWin</a> from Ardfry Imaging, LLC.  I am not affiliated with them in any way, but I do think that they have a great product that is well worth the price.</p>
<p>So how good is the compression?  It really depends on the image, but 10-30% seems to be the average range.  For our site the total savings for the PNGs used in various look and feels ranges from 8% to 25%, although the actual savings are higher as some of the larger PNGs are replaced with JPEGS.  This might not sound like a lot, but when all of the images that are on a page are taken into consideration it adds up quickly.</p>
<p><strong>Optimizing Other Formats</strong></p>
For the sample look and feels most of the images are PNGs, but there are a few GIFs in use for the titlebar images.  These are typically fairly small and won't benefit much from optimization.  If you do want to optimize the GIFs, most paint programs offer options for reducing the number of colors.</p>
<p>As stated earlier, you may wish to use JPEGs for things like photographs, large header graphics, backgrounds, and so on.  JPEGs will typically be smaller, and offer lots of compression options if you're not picky about the quality.  There are some cases where a PNG will be smaller, but these are typically mostly empty.  Be careful when working with JPEGs if you think you might want to edit the images later, as once they're saved as JPEGs they are often mangled by the compression.  The various JPEG cleanup tools only go so far, and you may spend time using pixel-level editing tools trying to restore images, which is not fun!</p>
<p>I'm still going to go over CSS optimization and some other things in this area, but my next entry is probably going to dive into Disc and REST a bit more, and will include a new way for you to play with them live on wlp.bea.com.  Stay tuned!</p>

]]>
        
    </content>
</entry>
<entry>
    <title>And Now For Something Completely Different</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/03/and_now_for_som.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/03/and_now_for_som.html</id>
    
    <published>2008-03-20T18:01:05Z</published>
    <updated>2008-03-20T22:50:24Z</updated>
    
    <summary>No, I haven&apos;t abandoned the Web 2.0 Performance Optimization series, but I do want to point out some of the other new features in WebLogic Portal 10.2, starting with the REST commands.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>It seems like a long, long time ago that I first wrote about the sample <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>commands that we had made available on <a href="http://wlp.bea.com">wlp.bea.com</a>, but in fact it was less than a year.  It's amazing how much has happened since then for me, WebLogic Portal, and of course BEA.</p>
<p><strong>A Quick Refresher</strong></p>
<p>My blog entry <a href="http://dev2dev.bea.com/blog/skip/archive/2007/07/the_rest_of_the.html">The REST of the Story</a> includes an introduction to REST, and here are some of the links again if you'd like to read a bit about it:</p>
<ul>
<li><a href="http://www.oreilly.com/catalog/9780596529260/">RESTful Web Services by Leonard Richardson, Sam Ruby</a></li>
<li><a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Representational State Transfer (REST) - Chapter 5 of Roy T. Fielding's Dissertation</a></li>
<li><a href="http://wiki.opengarden.org/REST/REST_for_the_Rest_of_Us">REST for the Rest of Us, Various</a></li>
</ul>
There are others, and there is naturally lots of discussion and debate over how <em>RESTful</em> something is.  I have always been more interested in the practical application of ideas and technologies rather than the theory, so I try to avoid getting into these debates.  What I do know is that REST-style commands work very well for Web 2.0 applications, and I like not having to use heavyweight server-side Java for everything.</p>
<p><strong>A Web 2.0 Demonstration</strong><p>
<p>You can see the REST commands in WLP 10.2 in action by visiting the <a href="http://wlp.bea.com/dvt/">Dynamic Visitor Tools Sample</a> site.  Follow the link on that page and you'll see this portal desktop:</p>
<img alt="dvt_desktop.png" src="http://dev2dev.bea.com/blog/skip/dvt_desktop.png" width="831" height="525" />
<p>You can create an account and login very easily, and when you do so it will enable the DVT functionality for things like drag-and-drop, adding portlets/pages/books, and changing the look and feel, layout, menus, and so on.  What you might not be aware of is that nearly everything you see is powered by a combination of the <a href="http://edocs.bea.com/wlp/docs102/clientdev/rest.html">WebLogic Portal REST API</a>, the <a href="http://edocs.bea.com/wlp/docs102/clientdev/disc.html">WLP Disc Framework</a>, the <a href="http://dojotoolkit.org">Dojo Toolkit</a>, and the <a href="http://edocs.bea.com/wlp/docs102/samples/dvt-sample.html">Dynamic Visitor Tools Sample</a> code.</p>
<p><strong>Patterns</strong></p>
</p>A visitor to this site will push buttons, make selections, drag and drop items, use inline editing, and so on as part of a  Web 2.0 style interactive experience.  A common pattern is used for nearly everything in the DVT, illustrated here:</p>
<img alt="rest_flow.png" src="http://dev2dev.bea.com/blog/skip/rest_flow.png" width="711" height="455" />
<p>We'll look into Disc more in an upcoming entry, for now we'll start by saying that it makes it easy to get to the client-side representations for portal objects.  The DVT sample uses Disc to  get information about the portal desktop, including the various labels, titles, DOM nodes, and so on that make them up.  Without Disc a portal page is just a collection of DIVs and other HTML tags, and in the past developers often had to invent their own solutions for mapping these to the server-side definitions and instances.  Not impossible, but it wasn't always easy and it meant custom solutions that might not interoperate or upgrade well.</p>
<p><strong>Try It!</strong></p>
One thing that makes REST interesting is that it is very easy to use; in fact you can try it out without writing a single line of code.  I will suggest that you use Mozilla Firefox with the <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> add-on as you can do a lot with the console, but any browser will at least let you try the basics.  Try the following URL:</p>
<p><a href="http://wlp.bea.com/dvt/bea/wlp/api/portlet/list?webapp=dvt">http://wlp.bea.com/dvt/bea/wlp/api/portlet/list?webapp=dvt</a></p>
</p>This will return a list of available portlets in the <em>dvt</em> web app, which will look something like this:</p>
<img alt="rest_portlet_list.png" src="http://dev2dev.bea.com/blog/skip/rest_portlet_list.png" width="769" height="636" />
<p>The XML is fairly straightforward:</p>
<pre>
&nbsp;
&lt;rsp&gt;
  &lt;portlet_summaries&gt; - Array of portlet summarys
    &lt;portlet_summary&gt; - Summary for a portlet
      &lt;label&gt;portlet_1&lt;/label&gt; - The unique label for the portlet
      &lt;title&gt;My Portlet&lt;/title&gt; - The title to display
      &lt;icon&gt;portlets/icons/myportlet.png&lt;/icon&gt; - The optional icon
      &lt;description&gt;The portlet&lt;/description&gt; - The optional description    &lt;/portlet_summary&gt;
   ...
  &lt;/portlet_summaries&gt;
&lt;/rsp&gt;
&nbsp;
&nbsp;
</pre>
<p>This list can be used to display a list of portlets, as in this example from the DVT <em>Gallery</em>:</p>
<img alt="dvt_portlet_list.png" src="http://dev2dev.bea.com/blog/skip/dvt_portlet_list.png" width="845" height="276" />
<p><strong>A Closer Look</strong></p>
While XML is great for many things, it's not really great on the client side, especially when going cross-browser.  It's often easier to use <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>, JavaScript Object Notation, which is fully supported by the WLP REST API.  Simply include the argument <em>format=json</em> and you'll get a response that contains JSON, which is easily used on the client.  Here is a screenshot from Firebug showing the arguments being used by the DVT to build the gallery listing above:</p>
<img alt="rest_portlet_list_params.png" src="http://dev2dev.bea.com/blog/skip/rest_portlet_list_params.png" width="731" height="522" />
<p>These include:</p>
<ul>
<li>desktop: dvt - The portal desktop, from Disc</li>
<li>format: json - Return the results as JSON</li>
<li>max: 200 - Return a maximum of 200 portlet summaries</li>
<li>portal: demo - The portal, from Disc</li>
<li>scope: visitor - Can be visitor, admin, or library</li>
<li>start: 0 - Start with the first portlet</li>
<li>webapp: The webapp to get the portlets for, from Disc</li>
</ul>
<p>This will return the following:</p>
<img alt="rest_portlet_list_response.png" src="http://dev2dev.bea.com/blog/skip/rest_portlet_list_response.png" width="731" height="522" />
<p>This is fairly dense, but if you format it you can see that it is similar to the XML:</p>
<pre>
&nbsp;
{
   "content": {
    "portlet_summaries": [ 
      { "title":"My Portlet Customers","label":"portlet_1","icon":"portlets/icons/myportlet.png" },
      ...
    ]
  }
}
&nbsp;
&nbsp;
</pre>
<p>If you haven't already used JSON it might not be obvious why this is so much easier than XML.  With JSON you can use the JavaScript <em>eval</em> function (or a nice wrapper for it as provided by Dojo and other toolkits) and get a JavaScript object back.  This takes just a few lines of code:</p>
<pre>
&nbsp;
  var result = eval("(" + XMLHttpRequest.responseText + ")");
  var content = result.content;
  var portletSummaries = content.portlet_summaries;
  for (var i = 0; i &lt; portletSummaries.length; i++) {
    var title = portletSummaries[i].title;
    var label = portletSummaries[i].label;
  ...
&nbsp;
&nbsp;
</pre>
<p><strong>More Examples</strong></p>
You can use the same pattern to get lists of most of the portal resources, using the following pattern:</p>
&lt;protocol&gt;://&lt;host&gt;:&lt;port&gt;/&lt;webapp&gt;/bea/wlp/api/&lt;type&gt;/&lt;action&gt;/&lt;label&gt;?&lt;params&gt;
<p>This is covered in more detail on our edocs site in <a href="http://edocs.bea.com/wlp/docs102/clientdev/rest.html">The WebLogic Portal REST API </a>, which is a good follow-up to this blog entry.  If you'd like to explore some more, here are some of the types and actions you can try, all starting with http://wlp.bea.com/dvt/bea/wlp/api/:</p>
<ul>
<li>portlet/details/&lt;label&gt;?webapp=dvt - Where <em>label</em> is from the portlet summary</li>
<li>lookandfeel/list?webapp=dvt</li>
<li>page/list?webapp=dvt</li>
<li>book/list?webapp=dvt</li>
<li>menu/list?webapp=dvt</li>
<li>theme/list?webapp=dvt</li>
</ul>
<p>As you've probably noticed, so far the focus has been on reading from the server via HTTP GETs, but there is a lot more you can do using POSTs.  The DVT sample uses this to change the look and feel, add portlets to a page, and so on, using the data from the GETs to create the various parameters.  You can't really explore POSTs using URLs in the browser, but you can do so with a small amount of code.  One thing to note is that you will need to be authenticated in order to do anything interesting, and you can only do the things that the server security allows.</p>
<p>I've got a set of sample portlets that I've been working on that duplicate much of the functionality in the DVT using "plain" JavaScript, with no reliance on Dojo, etc.  All you need to do is have Disc enabled in a WebLogic Portal 10.2 desktop.  They aren't meant to be examples of how to write portlets so much as they are demonstrations of using REST and Disc, and can be used to learn how to use these technologies with most any framework.  I hope to make these available soon, but if you can't wait drop me a line and I'll send you the current set.</p>
<p>More to come on this, and I'll continue with the optimization series as well.</p>

]]>
        
    </content>
</entry>
<entry>
    <title>Web 2.0 Performance Optimization - JavaScript</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_2.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_2.html</id>
    
    <published>2008-03-20T00:20:14Z</published>
    <updated>2008-03-20T00:20:14Z</updated>
    
    <summary>In this entry we&apos;ll look at how to combine and minify the JavaScript files using server modes, various tools, and manual optimizations.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>In the two previous entries we have looked at some of the ways that we can optimize a site for Web 2.0 features by reducing the size and number of files.  In our case we wanted to optimize <a href="http://wlp.bea.com">wlp.bea.com</a> in order to ensure that users had a pleasant experience when visiting the site.  When it comes to JavaScript there are a few things that can be done, including these three:</p>
<ul>
<li>Combine the code to reduce the number of files</li>
<li><a href="http://en.wikipedia.org/wiki/Minify">Minify</a> the code to all unnecessary characters</li>
<li><a href="http://www.gzip.org/">gzip</a> the code </li> to further reduce the size</li>
</ul>
<p>The last one is largely a function of the server, and you can download the GZip filter from the <a href="http://dev2dev.bea.com/utilitiestools/adminmgmt.html">Dev2Dev > Utilities & Tools > Administration/Management</a> page, use the <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">mod_deflate</a> module for Apache, use <a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/25d2170b-09c0-45fd-8da4-898cf9a7d568.mspx?mfr=true">HTTP Compression</a> for IIS, and so on.  This will give you the largest bang for your buck in terms of the size of the download, but as mentioned earlier, watch out for firewalls that block or otherwise thwart this compression.</p>
<p>Combining the files sounds easy enough, and in many cases you can probably get by using a command-line tool such as the UNIX-style <i>cat</i> or other utilities.  The problem is that some JavaScript libraries and applications rely upon the order of loading, and may not work well (if at all) if this isn't taken into consideration.  We use the <a href="http://dojotoolkit.org">Dojo Toolkit</a> for the <a href="http://wlp.bea.com/dvt/">Dynamic Visitor Tools</a> and they provide some nice tools for this.  I would expect that most toolkits provide something similar, and if not you could use one of the many available.</p>
<p>To see the effect of combining these files, take a look at this diagram:</p>
<img alt="js_optimization.png" src="http://dev2dev.bea.com/blog/skip/js_optimization.png" width="800" height="632" />
<p>The various bits include:</p>
<ul>
<li>Disc (Dynamic Interface Scripting) - 23 files combined into 2 files</li>
<li>PM (Placeable Movement) - 40 files combined into 2 files</li>
<li>Bighorn (Look and Feel Skeleton) - 2 files combined into 1 file</li>
<li>DVT (Dynamic Visitor Tools) - 42 files combined into 2 files</li>
</ul>
<p>Going from 107 files to 8 files is fairly dramatic, especially when you consider that many browsers only allow a couple of connections at a time.  We haven't measured the impact on the server side, but it's reasonable to assume that it helps out there as well.  In case you're wondering, the remaining 2 files are for localization, one from the Dojo toolkit and the other from the DVT.  This brings the total to 108 before and 10 after, a better than 10X reduction.</p>
<p>When it comes to minification a good read is <a href="http://www.crockford.com/javascript/jsmin.html">JSMIn, The JavaScript Minifier</a> by Douglas Crockford, and his site has other good tips and tools.  Most minification tools do one of more of the following:</p>
<ul>
<li>Remove comments</li>
<li>Remove whitespace</li>
<li>Remove blank lines</li>
<li>Remove new-line characters</li>
<li>Obfuscation</li>
</ul>
<p>How much compression is possible via minification will vary wildly, but from our own testing it appears that anywhere from 10-30% is possible.  There are examples of minified code on Crockford's site as well as others, and you can try it out on your own code using one of the available online tools.  What I haven't measured is the difference between non-minified code vs. minified code when all of it is gzipped, but I do know that gzip doesn't always work and therefore minifying the code is worthwhile in any case.</p>
<p>We'll take a look at doing much the same thing for CSS files next, and we still want to look into further optimizations to reduce dynamic code loading, reduce image sizes, and so on.  We're also interested in hearing about other tips, techniques, and tools, so please feel free to post a comment or email us.</p>
]]>
        
    </content>
</entry>
<entry>
    <title>Web 2.0 Performance Optimization - Testing, Measurement, and Scoring</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_1.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa_1.html</id>
    
    <published>2008-03-12T18:33:10Z</published>
    <updated>2008-03-12T18:33:10Z</updated>
    
    <summary>In this entry I&apos;ll discuss the tools and technologies that we used to determine how our site was doing and learn what we might do to improve it.  WebLogic Portal 10.2, Firebug, YSlow, and more are discussed.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>In the first entry in this series <a href="http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa.html">Web 2.0 Performance Optimization - Get an A on YSlow!</a> I included a few screenshots of before/after results from <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> and <a href="http://developer.yahoo.com/yslow/">YSlow</a>.  These aren't the only tools available, but they are among the best at the moment, and are invaluable for diagnosing problems in your web applications, even those you may not be aware of.</p>
<p>How do you use these tools?  They're actually fairly easy to use, with straightforward user interfaces that integrate nicely into <a href="http://www.mozilla.com">Mozilla Firefox</a>.  There is something called <a href="http://www.getfirebug.com/lite.html">Firebug Lite</a> that works in other browsers, including IE, but this is really just a console and not the same thing at all.  There are some tools for IE that I'll discuss, and it looks like Microsoft has copied the Firebug features in the <a href="http://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=ie8whitepapers&ReleaseId=580">IE8 Developer Tools</a>.  These tools are only going to get better, and I believe we're just starting to scratch the surface in this area.</p>
<p>So how can you use them?  Let's take a look at Firebug, selecting the <i>Net</i> tab and  <i>All</i> subtab and viewing the results for a non-authenticated user on the <i>Welcome</i> page on the optimized <a href="http://wlp.bea.com/dvt/appmanager/demo/dvt">wlp.bea.com</a> site.  Note that I've cleared all of the private data (cache, cookies, etc.) in order to see what the raw performance of the site would be for a first-time user:</p>
<img alt="firebug_optimized_welcome.png" src="http://dev2dev.bea.com/blog/skip/firebug_optimized_welcome.png" width="566" height="506" />
<p>As you might guess, clicking on the various tabs for <i>JS</i>, <i>CSS</i>, and so on will show you the results for only those object types.  When there are only 20 or so files total as in the optimized site this isn't really a big deal, but when you look at the results for the non-optimized site the value becomes apparent:</p>
<img alt="firebug_original_welcome.png" src="http://dev2dev.bea.com/blog/skip/firebug_original_welcome.png" width="566" height="506" />
<p>If you are surprised that the non-optimized site took <b>25.24s</b> to finish loading, I can promise you that we were even more surprised by it.  The funny thing (and I don't mean that in the good sense) is that one of the biggest problems turned out to be the <a href="http://www.symantec.com/norton/products/overview.jsp?pcid=is&pvid=nis2008">Symantec/Norton Client Firewall</a>, which is installed and active on most BEA employee machines.  This is not meant as a knock on Symantec or their products, but this firewall has a very annoying feature that causes issues with <a href="http://www.gzip.org/">gzipped</a> files, JavaScript files in particular.</p>
<p>This firewall is acting as a proxy for any internet connections and is decompressing the gzipped files before sending them to the browser.  The good news is that the gzipped files are being sent from the server to the client, reducing the network bandwidth.  The bad news is that it appears to be scanning the files after decompressing them, adding some overhead.  This gets far worse when there are lots of JavaScript files as it appears that the firewall is processing them sequentially, limiting the connections to the server, or both.  The even worse news is that there doesn't appear to be a way to disable this "feature" for known and trusted sites, although I remain hopeful that they'll enhance it at some point.  The only workaround at the moment is to disable the firewall entirely, not something that everyone will be comfortable with.</p>
<p>Here are the results for the non-optimized site with the firewall disabled:</p>
<img alt="firebug_original_nofirewall_welcome.png" src="http://dev2dev.bea.com/blog/skip/firebug_original_nofirewall_welcome.png" width="566" height="506" />
<p>We still have the same large number of requests, but the size of the download has decreased by more than 3X and the page rendering time is 4X faster.  That's not bad, but we're still far from what we'd like.  Over the next few blog entries we'll see how we can optimize the site to have 4X fewer files, 1/2 the download size, and render the pages over 4X faster.</p>
<p>Now let's take a look at YSlow, which is thoughtfully integrated into Firebug.  Here are the performance results for the original non-optimized site, with the firewall enabled:</p>
<img alt="yslow_original_welcome.png" src="http://dev2dev.bea.com/blog/skip/yslow_original_welcome.png" width="566" height="506" />
<p>Seeing the big fat <b>F</b> was depressing, although after looking around at various well-known Web 2.0 sites I knew that many of them weren't much better, and even the best of them still got a <b>C</b>.  As a long time BEA employee and a true believer in performance and scalability, I was not going to rest until I got a C or better, and an <b>A</b> was always the target.  Here are the results today for the optimized site:</p>
<img alt="yslow_optimized_welcome.png" src="http://dev2dev.bea.com/blog/skip/yslow_optimized_welcome.png" width="566" height="506" />
<p>As I stated in the first entry, using a <a href="http://en.wikipedia.org/wiki/Content_Delivery_Network">CDN</a> would easily get us that A.  Disabling localization would also do it, but that's not very friendly, and I have some ideas on how to provide localization while reducing the file request count even further.  The cool thing is that we're now looking into ways to provide some or all of these optimizations automagically in the server, using the PRODUCTION_MODE flag to toggle them on or off.  I can't promise these for the WebLogic Portal <i>Sunshine</i> release currently scheduled for later this year, but we're going to try.</p>
<p>If you've read all of this and are wondering what the effects of disabling the firewall are on the original site, here they are:</p>
<img alt="yslow_original_nofirewall_welcome.png" src="http://dev2dev.bea.com/blog/skip/yslow_original_nofirewall_welcome.png" width="566" height="506" />
<p>In <a href="http://imdb.com/title/tt0114694/">Tommy Boy</a> the late, great <a href="http://imdb.com/name/nm0000394/">Chris Farley</a> shouted out "D+?... Oh, my God... I passed! I passed! Oh, man! "  A 60 isn't a D+, and it's nothing really to shout about, but hey, I liked the movie and the quote, and it's somewhat fitting.  I won't name or shame them, but there are plenty of interesting and well-known sites out there that are even worse off, and we haven't even started to optimize our site yet.</p>
<p>You may recall that I listed <a href="http://www.fiddler2.com/fiddler2/">Fiddler</a> in the earlier blog entry, an add-on for IE.  It's not really the same thing as Firebug, but it can provide similar information about the files, download sizes, times, etc.  In some ways it offers even more information, but quite frankly it doesn't feel as seamless as Firebug.  I would suggest having it in your arsenal and using it, but personally I tend to develop on Firefox first using the various tools it offers and porting to other browsers.</p>
<p>In the next entry we'll start looking into how to reduce the number of files, as well as their size.  The nice thing is that there is a huge improvement to be made by simply enabling production mode on the server, and as I said earlier in this entry we'll be looking at how to extend this even further in the future.</p>







]]>
        
    </content>
</entry>
<entry>
    <title>Web 2.0 Performance Optimization - Get an A on YSlow!</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/03/web_20_performa.html</id>
    
    <published>2008-03-10T22:58:49Z</published>
    <updated>2008-03-11T00:56:15Z</updated>
    
    <summary>This is the first of a series of blog entries detailing how we optimized the wlp.bea.com demo site, going from a flat F in YSlow to an A.  The technologies covered include BEA WebLogic Portal 10.2, Dojo 1.0.x, Apache server, Firebug, YSlow, and more.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
            <category term="Role: Architect" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>Okay, first off I have to be honest and admit that we only managed to get a high <b>B</b> on YSlow, with a score of 86.  We weren't able to use a CDN, so that category dragged down the overall score.  A CDN would easily get us to an <b>A</b>, and a relatively high one at that.</p>

<p>Some of you read that first paragraph and it made sense, others of you may be wondering at some of the jargon used.  In this series of blogs I'll be covering a variety of technologies and techniques, and I'll try to clearly define them.  If something isn't making sense, Googling a bit can help, but if you post a comment I'll post a reply trying to clear things up.  Here are a few that might be helpful when reading these entries:</p>

<ul>
<li><a href="http://bea.com/framework.jsp?CNT=index.htm&FP=/content/products/weblogic/portal/">BEA WLP (WebLogic Portal) 10.2</a>- A J2EE (okay "Java EE", sheesh) -based enterprise portal</li>
<li><a href="http://wlp.bea.com/dvt/">DVT (Dynamic Visitor Tools) Sample </a>- A Web 2.0-based front-end for WLP apps</li>
<li><a href="http://dojotoolkit.org/">Dojo 1.0.x</a> - An Ajax toolkit that is used in WLP 10.2 for the DVT sample</li>
<li><a href="http://httpd.apache.org/">Apache HTTP Server</a> - Popular web server</li>
<li><a href="http://www.gzip.org/">gzip</a> (GNU Zip) -  compression utility</li>
<li><a href="http://www.libpng.org/pub/png/">PNG </a>(Portable Network Graphics) - Lossless image compression format</li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> - Add-on for Firefox that provides diagnostic information</li>
<li><a href="http://developer.yahoo.com/yslow/">YSlow</a> - Add-on for Firefox that works with Firebug to provide site optimization information</li>
<li><a href="http://www.fiddler2.com/fiddler2/">Fiddler</a> - Add-on for Internet Explorer that provides diagnostic information</li>
<li><a href="http://en.wikipedia.org/wiki/Content_Delivery_Network">CDN</a> (Content Delivery Network) - A system for distributing content across a network</li>
</ul>
<p>There are a number of other tools and utilities that I'll discuss, and I'll try to provide links to them where possible.</p>
<p>When we first went live with the <a href="http://wlp.bea.com/dvt/appmanager/demo/dvt">WebLogic Portal 10.2 Playground</a> we asked a number of people to try it out and provide feedback on the performance.  Some of the reports were glowing, with users saying that it was very fast, while others reported extremely slow page load times.  We began by looking at the server-side configurations, tweaking and tuning the WebLogic and Apache servers, which helped a bit.  After a while it became obvious that some machines were being overwhelmed by the number of requests, and the size of the responses weren't helping either.  No amount of caching or other server tuning was going to solve all of the issues that we were seeing, so we set off on our quest for speed.</p>
</p>We'll cover the details of this quest in the next few blog entries, but for now let's look at some before and after screenshots.  These were captured using Firebug and YSlow for Firefox, with caching enabled but after a recent flush.  This is after logging into the site to ensure that the maximum number of JavaScript files, images, etc. are shown.  Note that the results have been trimmed a bit, with only the top and bottom shown.</p>

<p>Here are the Firebug results for the original site:</p>
<div>
<img alt="firebug_laptop_original_login.png" src="http://dev2dev.bea.com/blog/skip/firebug_laptop_original_login.png" width="702" height="410" />
</div>

<p>Compare this to the results for the optimized site, with far fewer requests, far less downloaded to the client, and a much faster response time:</p>
<div>
<img alt="firebug_laptop_optimized_login.png" src="http://dev2dev.bea.com/blog/skip/firebug_laptop_optimized_login.png" width="702" height="410" />
</div>

<p>YSlow, a great tool from the <a href="http://developer.yahoo.com/">Yahoo! Developer Network</a>, provides grades for website performance, suggestions on how to speed things up.  Here is the original site:</p>
<div>
<img alt="yslow_laptop_original_login.png" src="http://dev2dev.bea.com/blog/skip/yslow_laptop_original_login.png" width="702" height="425" />
</div>

<p>Here are the YSlow results for the optimized site:</p>
<div>
<img alt="yslow_laptop_optimized_login.png" src="http://dev2dev.bea.com/blog/skip/yslow_laptop_optimized_login.png" width="702" height="425" />
</div>

<p>As you can see we've managed to improve everything quite a bit, with only the use of a CDN keeping us from getting that <b>A</b>.  We would also get a <b>B</b> for the <i>Make fewer HTTP requests</i> if we turned of localization, or if we interned the localized strings, and we could probably get to an <b>A</b> on that if we combined a few of the remaining JavaScript files.  At this point we're happy with the progress, especially when the optimized results are compared with the original.  To summarize, here are the improvements:</p>

<ul>
<li>Number of requests - 135 - 26 = <b>109 fewer requests</b></li>
<li>Size of responses - 1064k - 171k = <b>893k smaller</b></li>
<li>Total response time - 42.15s - 1.86s = <b>40.29s faster</b></li>
</ul>

<p>Once the browser caches are primed the original site will get faster, but in the best cases it is still 3 or more times slower, and it can be much slower in certain circumstances.  We can be thankful that the web, the browsers, the servers, and more are reasonably efficient, but there is no magical solution.  Or as I like to say, even BEA hasn't figure out how to use quantum physics, wormholes, or magic to get around the laws of nature.  What we can do is try to understand the problem and take the steps to create solutions, and thankfully none of it is truly <a href="http://www.doubletongued.org/index.php/dictionary/rocket_surgery/">rocket surgery</a>.<p>

<p>Look for follow-ups on this over the next couple of weeks, with plenty of details.  If you have any questions or suggestions, I'd love to hear them.</p>




 ]]>
        
    </content>
</entry>
<entry>
    <title>WebLogic Portal Look and Feel Techniques - Rounded Borders for Portlets</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2008/02/weblogic_portal.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2008/02/weblogic_portal.html</id>
    
    <published>2008-02-22T20:35:55Z</published>
    <updated>2008-02-22T20:35:55Z</updated>
    
    <summary>In this blog entry I&apos;ll discuss a technique used to create rounded borders for portlets using CSS.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>Over the past few months we've been working on the upcoming WebLogic Portal 10.2 release, which <a href="http://dev2dev.bea.com/blog/jlannin/">Josh Lannin</a> has been recently blogging about.  Check out his YouTube video entitled <a href="http://dev2dev.bea.com/blog/jlannin/archive/2008/02/a_video_introdu.html">A Video Introduction To WebLogic Portal 10.2</a> to see some of the new features, many of which have been previewed on the playground at <a href="http://wlp.bea.com">wlp.bea.com</a>.</p>

<p>This release includes more than 40 new sample look and feels (LAFs) that demonstrate a number of techniques for using CSS and dynamic DOM manipulation via JavaScript to create a variety of styles.  In this blog entry I'll discuss a few of these techniques, focusing on those used to create rounded border portlets.  If you haven't seen these on the playground or the video, here are a few examples:</p>

<img alt="roundedborderportlets_01.png" src="http://dev2dev.bea.com/blog/skip/roundedborderportlets_01.png" width="700" height="426" />

<p>Going clockwise from the upper left, these are from the "Tech - Fone", "Sunrise", "Tech - Logan", and "Tech - Aqua".  The first one is inspired by the iPhone, the second is an original, the third was designed by Chris Bales, and the last is inspired by the "Aqua" desktop style on the Mac.  The full desktop for each includes various images, colors, fonts, and styles to provide very different looks for the same portal desktops.  It's important to emphasize that all of this is possible by modifying only the <i>skin</i> for the look and feel, including the CSS and images, without touching the <i>skeleton</i>.  Each of the sample LAFs uses the <i>Bighorn</i> skeleton, which was first introduced in WebLogic Portal 10.0 and is the basis for all of our future work in this area.</p>

<p>There are numerous articles, blogs, and other resources that describe CSS techniques for pretty much everything, and by Googling a bit you can find what you need.  Many of these use an image for each corner and then colors and borders to fill in the rest, but this tends to work best only when you have complete control over the widths and heights of the various divs.  A portlet is a generic container for arbitrary content which is in turn contained by a placeholder, layout, page, book, shell, desktop, etc., so it must be dynamic.  There are techniques for dynamically sized rounded borders, and it's surprisingly simple.</p>

<p>A WebLogic Portal desktop contains a number of nested divs to create the various elements, and a portlet itself contains a number of them.  This diagram shows some of the elements that are used for creating the rounded borders:</p>

<img alt="roundedborderportlets_02.png" src="http://dev2dev.bea.com/blog/skip/roundedborderportlets_02.png" width="686" height="464" />

<p>Here is a key that identifies the name and style by matching the color:</p>

<div style="width: 75%; font-weight: bold; background: black; color: red">Window: wlp-bighorn-window</div>
<div style="width: 75%; font-weight: bold; background: black; color: royalBlue">Window Content: wlp-bighorn-window-content</div>
<div style="fwidth: 75%; ont-weight: bold; background: black; color: yellow">Titlebar ButtonPanel: wlp-bighorn-titlebar</div>
<div style="width: 75%; font-weight: bold; background: black; color: lightGreen">Titlebar ButtonPanel: wlp-bighorn-titlebar-button-panel</div>

<p>This image and key hints at how the rounded borders are achieved, with overlapping images used as the background style for each of the divs.  Since the size of the portlet isn't fixed, these images should be large enough to accommodate fairly large screens, although there is no real rule-of-thumb to use here.  The sample LAFs tend to handle anything from 1200 or so to more than 2000 pixels wide and high, which works well for many screens.  I have seen some gigantic screens at the Apple Store, but I'm hoping that not many folks will be using maximized or published portlets in a browser taking up the entire screen...</p>

<p>The image below shows each of the border images, scaled down for this blog:</p>

<img alt="roundedborderportlets_03.png" src="http://dev2dev.bea.com/blog/skip/roundedborderportlets_03.png" width="345" height="317" />

<p>Clockwise from the top left are the images <i>tl.png</i>, <i>tr.png</i>, <i>br.png</i>, and <i>bl.png</i>, which you've probably guessed stand for top-left, top-right, bottom-right, and bottom-left.  These are used as the background image for the titlebar, titlebar button panel, window content, and window, respectively.  If the order seems odd, it might help if you look at the DOM structure, simplified here for clarity:

<pre>
&lt;div class="wlp-bighorn-window"&gt;
  &lt;div class="wlp-bighorn-titlebar"&gt;
    &lt;div class="wlp-bighorn-titlebar-button-panel"&gt;
      ...
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="wlp-bighorn-window-content"&gt;
    ...
  &lt;/div&gt;
&lt;/div&gt;
</pre>

<p>The window is the main div which contains the titlebar and content divs, effectively on top of the window div and stacked vertically.  The titlebar button panel div is contained within the titlebar div and is on top of it, occupying the right side and in turn containing the buttons for minimize, mazimize, and so on.  It takes very little in the way of CSS and images to create the desired effect, and with some modifications you should be able to create almost anything that is required for site design, branding, and other requirements.</p>

<p>For the sample LAFs the file <i>custom.css</i> contains all of the styles that override those in the default Bighorn LAF.  This reduces the number of CSS styles to modify and keep track of, and makes it easier to move between LAFs.  You could take the same technique even further, layering your own CSS files in order to achieve the desired effects.  The CSS styles for the rounded corners are defined as follows:</p>

<pre>
.wlp-bighorn-titlebar
{
  overflow: hidden;
  background: url(../images/borders/tl.png) no-repeat scroll left top transparent;
  font-size: 10pt;
  font-weight: normal;
  border-color: transparent;
  border-width: 0px;
  border-style: none;
  padding: 0px;
  margin: 0px;
}

.wlp-bighorn-titlebar-button-panel
{
  color: #FFFFFF;
  vertical-align: bottom;
  padding: 0px;
  margin: 0px;
  background: url(../images/borders/tr.png) no-repeat scroll right top transparent;	
  clear: right;
  text-align: right;
}

.wlp-bighorn-window
{
  min-width: 200px;
  margin: 5px;
  background: url(../images/borders/bl.png) no-repeat scroll left bottom transparent;
  border: 0px none;
  font-size: 10pt;
}

.wlp-bighorn-window-content
{
  width: auto;
  overflow: auto;
  padding: 0px 16px 40px 16px;
  margin: 0px;
  background: url(../images/borders/br.png) no-repeat scroll right bottom transparent;
  border: 0px none;
  color: #F0F0F0;
  min-height: 50px;
  overflow: hidden;
}

</pre>

<p>The background attributes for each of these styles uses a URL for the image, which is path relative, along with parameters for placing the image at the top, left, right, bottom, etc..  Other style attributes are used to pad the content, set colors, and otherwise customize the display.  If you're a J2EE programmer without a lot of web design experience it may seem odd, but it is quite powerful and is ultimately easier than writing code for everything.  I would suggest that you use Firefox with <a href="http://www.getfirebug.com/">Firebug</a> to develop and tune the LAFS as it provides a great "what if" environment.  Look for a future blog posting on Firebug and other tools.</p>

<p>One thing to watch out for is IE6, which is always a challenge when trying to do anything interesting with CSS.  Firefox, Safari, Opera, and even IE7 support the CSS specification well enough, but IE6 is buggy at best, and some would say it is broken.  Most of the sample LAFs work on IE6, but the iPhone-inspired one and a few others will not look quite right.  There are CSS hacks to use different styles  on IE6, and those are included in the samples, but these can only go so far.  I'll end my commentary on IE6 with that, and I wish you luck if you have to deal with it!</p>


]]>
        
    </content>
</entry>
<entry>
    <title>Mashing WebLogic Portal Content Using Microsoft Popfly</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2007/08/mashing_weblogi.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2007/08/mashing_weblogi.html</id>
    
    <published>2007-08-01T20:32:59Z</published>
    <updated>2007-08-01T20:33:08Z</updated>
    
    <summary>If you&apos;ve been working with or investigating Web 2.0 technologies then you&apos;ve probably heard of Microsoft Popfly.  It&apos;s an interesting tool for creating Mashups, and as part of my ongoing research into such things I&apos;ve been using it with the REST prototype on wlp.bea.com.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Portal" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>It's been a while since my last blog entry, and as many bloggers have found
out it's more work than it would seem!  We are hard at work here in WebLogic
Portal engineering on the upcoming <em>Flatirons</em> release, due later this
year.  There are lots of exciting new features, many of which are for Web 2.0,
and we'll be talking more about it over the coming months.  If you're going to
<a href="http://www.bea.com/beaworld/index.html">BEAWorld 2007</a>, find a
WebLogic Portal team member and we'll talk about and demonstrate it to you.</p>
<p><strong>Viewing Images in the PhotoSphere</strong></p>
<p>If you've followed my previous blog entries then you're familiar with some
of the prototype REST commands on 
<a href="http://wlp.bea.com">wlp.bea.com</a> for viewing content.  Using these
with Popfly was easy, taking me about an hour to figure out how to get going.
I used Peter Laird's blog entry on 
<a href="http://dev2dev.bea.com/blog/plaird/archive/2007/06/bea_weblogic_mi.html">
BEA WebLogic + Microsoft Popfly = Enterprise Mashups</a> and the docs to write
the first test "block" to display a single image.  I then wrote a second block
to get a list of images from a specified repository.  Using the two together
along with the various image viewer blocks quickly made for some interesting
mashups, as in the following using the PhotoSphere block:</p>
<img 
src="http://dev2dev.bea.com/blog/skip/popfly_imagesphere.png"
width="629" height="600"/>

<p>The images are displayed in the sphere which can be rotated at varying
speeds by moving the mouse around.  While it's not something that you might
want to use for viewing your images on a daily basis, it does make for an
impressive demonstration.  Like Adobe Flex, the Silverlight technology used
by Popfly goes beyond what is possible using standard DHTML, AJAX, and so on.
I suspect it's going to be a while before one or more of these emerge as a
dominant player, so it's not going to be prudent for us to limit WLP to just
one.  We may choose to support one or more OOTB, but our goal is to allow
WLP users to use other RIA technologies if they desire.</p>
of forcing one on them.</p>
<p><strong>Using the Blocks</strong></p>
One of the interesting features of Popfly is that sharing the blocks is easy,
and I've shared a couple of them:</p>
<img 
src="http://dev2dev.bea.com/blog/skip/popfly_projects.png"
width="436" height="347" />
<p>The names of the blocks suggest what they do, which is to list the nodes
given a path and to get the details about a particular node.  These aren't
especially sophisticated at this point, but they do show how easy it is to
use the content from wlp.bea.com via the prototype REST commands.  I like the
fact that Popfly uses JavaScript as its language, making it quite easy to
use.  If you'd like the code to the blocks, which I don't think is available
otherwise, drop me a line.</p>
<p>Using the blocks in the mashup involves dragging and dropping them along
with others, then wiring things up.  In many cases Popfly makes good guesses
about the inputs and outputs, even handling things like arrays fairly well.
I suspect that like anything else you'll have to write code to do the really
interesting things, but it is a fairly nice visual environment.  Here's the
two blocks I created along with the PhotoSphere block to create the mashup:</p>
<img src="http://dev2dev.bea.com/blog/skip/popfly_designview.png"
width="597" height="444" />
<p>That's really all it takes to create the mashup.  It will be interesting
to see where this and other such tools go, and as I've said one of the goals
of the WLP product team is to support most or all of them.  We're working on
some new product ideas that enhance and complement WLP, many of them in the
Web 2.0 space.  Stay tuned!</p>]]>
        
    </content>
</entry>
<entry>
    <title>REST-Powered Flex Applications to Access wlp.bea.com</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2007/07/restpowered_fle.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2007/07/restpowered_fle.html</id>
    
    <published>2007-07-16T20:56:51Z</published>
    <updated>2007-07-16T20:56:59Z</updated>
    
    <summary>This blog entry is based on my attempt to understand how Adobe Flex can
be used with WebLogic Portal, in particular the prototype REST commands
that we&apos;ve made available on wlp.bea.com.</summary>
    <author>
        <name>skip</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>Like many of you I've used various Adobe products and have seen the types
of things that can be done with Flash and other technologies.  I've also heard
that Flex can be used with various BEA products, including WebLogic Portal,
but there aren't many examples.  I find it hard to just tell customers that something
can be done without knowing how, so I set out to do some exploration.  Read
on to see how I was able to use Flex to build an application that displays content
from the WebLogic Portal Virtual Content Repository (VCR).</p>
<p><strong>Using Flex Builder</strong></p>
<p>I'm not going to describe
<a href="http://www.adobe.com/products/flex/">Flex Builder</a> in great
detail, but it's an Eclipse-based tool that should be quite familiar to
anyone already products such as Workshop for WebLogic Platform.  I chose to
install it standalone instead of as a plug-in, and actually like keeping it
separate from Workshop, which I use frequently. It's probably strange to
some, but I prefer having two distinct views and making a conscious context
switch between them instead of cluttering up my already busy Workshop
instance.</p>
<p>The visual editors in Flex Builder are nice, being far more WYSIWYG than
many other Eclipse editors.  Given Adobe's experience in this area with their
various media-centric tools this is no real surprise.  I did find it a bit of
a surprise to have to edit the XML by hand so much.  It's not that I mind
doing so, in fact I like having the control, but I was expecting things to
be a bit more visual.  They do have very good editors for
<a href="http://www.adobe.com/products/flex/technologies/">ActionScript and
MXML</a>, with code completion and validation that is much nicer than what
Workshop currently provides.  Having such features makes it easier to learn
without having to constantly consult the docs.</p>
<p>Where I think they come up short is how to package and deploy the apps,
something I couldn't quite figure out.  I'm sure there must be docs, but I
couldn't get the apps to run outside of the Flex environment and ran out of
time.  I'm sure it's not hard, but they should have made this easier or at
least more obvious.</p>
<p><strong>Building a Content Viewer</strong></p>
If you have followed my earlier blog entries you'll have learned how to use
some of the prototype REST commands available on
<a href="http://wlp.bea.com">wlp.bea.com</a>.  Many of these are focused on
the content management features of BEA WebLogic Portal, with the goal of
making mashups and other Web 2.0 applications more relevant.  Flex provides
a rich, and perhaps the richest, user interface technology, going beyond
what's possible with DHTML, CSS, AJAX, and so on.  That being said, I do
wish that they had based Flex on JavaScript and HTML instead of forcing me
to learn another scripting and markup
language.</p>
<p>Here is a screenshot of the content viewer that I built:</p>
<img alt="flex_cm_viewer1.png"
src="http://dev2dev.bea.com/blog/skip/flex_cm_viewer1.png/flex_cm_viewer1.png"
width="519" height="575" />
<p>This content in the DataGrid comes from the content.nodelist REST command
on wlp.bea.com, with the images and articles coming from content.node.  These
are used in the same way as in the JavaScript examples, with the benefit of
the Flex UI components and effects.  While this example doesn't look that
much different from something built with an AJAX toolkit, the potential for
a much richer UI is greater.  Here is
<a href="http://dev2dev.bea.com/blog/skip/WLPCMViewer.mxml/WLPCMViewer.mxml">WLPCMViewer.mxml</a>
that you can download or cut-and-past if you'd like:</p>
<div style="height: 200px; width: 90%; overflow: auto;">
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="vertical"
	verticalAlign="top"
	horizontalAlign="left"
	backgroundImage="images/background2.png"
	viewSourceURL="srcview/index.html" width="100%" height="100%" paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0" verticalGap="2"&gt;
	&lt;mx:Label height="0" id="baseUrl" visible="false" text="http://wlp.bea.com"/&gt;
	&lt;mx:Label height="0" id="baseRestUrl" visible="false" text="{baseUrl.text}/rest-web-lib/api/"/&gt;
	&lt;mx:HBox width="100%" verticalAlign="bottom" height="50" paddingTop="0" verticalGap="0"&gt;
		&lt;mx:Image source="images/bealogo.png"/&gt;
		&lt;mx:Label height="36" text="WebLogic Portal Content Viewer" width="100%" htmlText="WebLogic Portal Content Viewer" fontSize="20" fontStyle="normal" fontWeight="bold" textAlign="left"/&gt;
	&lt;/mx:HBox&gt;
	&lt;mx:Script source="WLPCMViewer.as"/&gt;
	&lt;mx:VBox width="100%" height="100%"
		borderThickness="2" borderStyle="solid" borderColor="#A0A0F0"
		backgroundColor="#C0C0C0" backgroundAlpha="0.5"
		initialize="init()" paddingTop="5" paddingLeft="5" paddingRight="5" paddingBottom="5"&gt;
		&lt;mx:HBox width="100%" horizontalGap="2"&gt;
			&lt;mx:TextInput width="303" id="nodePathInput" text="/BEA Repository"/&gt;
			&lt;mx:Button icon="@Embed('images/rt_arrow.png')" click="{wlp_content_node_list.send()}" width="23" toolTip="Display folders for path"/&gt;
			&lt;mx:Button icon="@Embed('images/updir.png')" click="upOneLevel();" paddingLeft="0" horizontalGap="0" width="22" toolTip="Go to parent folder"/&gt;
		&lt;/mx:HBox&gt;
		&lt;mx:DataGrid id="nodes" rowCount="6"
			width="100%"
			backgroundAlpha="0.5"
			dataProvider="{wlp_content_node_list.lastResult.rsp.nodes}"
			itemClick="itemClickEvent(event);"&gt;
			&lt;mx:columns&gt;
				&lt;mx:Array&gt;
					&lt;mx:DataGridColumn dataField="name" headerText="Name"/&gt;
					&lt;mx:DataGridColumn dataField="path" headerText="Path"/&gt;
					&lt;mx:DataGridColumn dataField="type" headerText="Type"/&gt;
					&lt;mx:DataGridColumn dataField="workflowStatus" headerText="Status"/&gt;
				&lt;/mx:Array&gt;
			&lt;/mx:columns&gt;
		&lt;/mx:DataGrid&gt;
		&lt;mx:VBox width="100%" height="500" horizontalAlign="center" verticalAlign="top"&gt;
			&lt;mx:Canvas width="100%" height="100%"&gt;
				&lt;mx:Image id="imageContent" visible="true" source=""/&gt;
				&lt;mx:Image id="imageContent2" visible="true" source=""/&gt;
				&lt;mx:TextArea id="htmlContent" visible="false" width="100%" height="100%"
					horizontalScrollPolicy="auto" verticalScrollPolicy="auto"&gt;
					&lt;mx:htmlText&gt;
	     			&lt;/mx:htmlText&gt;
	  			&lt;/mx:TextArea&gt;				
			&lt;/mx:Canvas&gt;
		&lt;/mx:VBox&gt;
	&lt;/mx:VBox&gt;
	&lt;mx:HTTPService id="wlp_content_node_list"
		url="{baseRestUrl.text}content.nodelist"
		method="GET" showBusyCursor="true"&gt;
		&lt;mx:request xmlns=""&gt;
			&lt;nodePath&gt;{nodePathInput.text}&lt;/nodePath&gt;
		&lt;/mx:request&gt;
	&lt;/mx:HTTPService&gt;
	&lt;mx:HTTPService id="wlp_content_node"
		url="{baseRestUrl.text}content.node"
		method="GET" showBusyCursor="true"&gt;
		&lt;mx:request xmlns=""&gt;
			&lt;nodePath&gt;&lt;/nodePath&gt;
		&lt;/mx:request&gt;
	&lt;/mx:HTTPService&gt;
&lt;/mx:Application&gt;
</pre>
</div>
<p>The data-binding for the DataGrid is possible without coding, using the
following to define the service:</p>
<p>
<pre>
	&lt;mx:HTTPService id="wlp_content_node_list"
		url="{baseRestUrl.text}content.nodelist"
		method="GET" showBusyCursor="true"&gt;
		&lt;mx:request xmlns=""&gt;
			&lt;nodePath&gt;{nodePathInput.text}&lt;/nodePath&gt;
		&lt;/mx:request&gt;
	&lt;/mx:HTTPService&gt;

</pre>
</p>
<p>The <em>baseRestUrl</em> maps to <code>http://wlp.bea.com/rest-web-lib/api/</code>,
just as in the earlier JavaScript examples.</p>  Setting the <em>nodePath</em>
request parameter is done via the <em>nodePathInput</em>, which is a text input
field.  That's all that is needed to call the data service, and mapping it to
the DataGrid is also quite simple:</p>
<pre>
	&lt;mx:DataGrid id="nodes" rowCount="6"
		width="100%"
		backgroundAlpha="0.5"
		dataProvider="{wlp_content_node_list.lastResult.rsp.nodes}"
		itemClick="itemClickEvent(event);"&gt;
		&lt;mx:columns&gt;
			&lt;mx:Array&gt;
				&lt;mx:DataGridColumn dataField="name" headerText="Name"/&gt;
				&lt;mx:DataGridColumn dataField="path" headerText="Path"/&gt;
				&lt;mx:DataGridColumn dataField="type" headerText="Type"/&gt;
				&lt;mx:DataGridColumn dataField="workflowStatus" headerText="Status"/&gt;
			&lt;/mx:Array&gt;
		&lt;/mx:columns&gt;
	&lt;/mx:DataGrid&gt;
</pre>
<p>The <em>dataProvider</em> attribute points to the <em>lastResult</em> for
the <em>wlp_content_node_list</em> defined above.  This is the XML value
returned from the REST command, and we can map the array of nodes using
<em>rsp.nodes</em>.  The DataGrid is smart enough to display the values at
this point, with the remainder of the markup being used to set the column
names.  We will get to the ActionScript code soon, but it should be noted
that you can display the wlp.bea.com data with 7 lines of MXML markup:</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"&gt;
		&lt;mx:DataGrid dataProvider="{wlp_content_node_list.lastResult.rsp.nodes}" initialize="{wlp_content_node_list.send()}"/&gt;
	&lt;mx:HTTPService id="wlp_content_node_list" method="GET" url="http://wlp.bea.com/rest-web-lib/api/content.nodelist"&gt;
		&lt;mx:request xmlns=""&gt;&lt;nodePath&gt;/BEA Repository/Smithsonian&lt;/nodePath&gt;&lt;/mx:request&gt;
	&lt;/mx:HTTPService&gt;
&lt;/mx:Application&gt;
</pre>
<p>You can try this out by copying the code above or downloading 
<a href="http://dev2dev.bea.com/blog/skip/Simple.mxml/Simple.mxml">Simple.mxml</a>
and using it in Flex Builder.  When it is run it will populate the DataGrid 
using the content nodes from wlp.bea.com, with no code required.  That's pretty
cool, and it's just the beginning.</p>
<p><strong>Using ActionScript to Do More</strong></p>
<p>This site is <em>By developers, for developers</em>, so if you're reading
this blog the chances are good you have written or understand the importance of
writing code.  While MXML is easy to use via the visual or text editors, it can
only do so much by itself.  This isn't a problem; in fact it's great to see that
Adobe isn't trying to fool people into thinking that the so-called business users
can do anything and everything with visual tools.  Far too many products focus
on flashy (no pun intended) front-ends with no substance on the back-end.</p>
<p>ActionScript is similar to JavaScript with stronger typing.  I'm sure that
there are other differences, but this isn't meant to be an academic discussion
of the language.  I did find it reasonably easy to use without having to read
lots of documentation or buy a huge book.  The online Adobe docs are good, and
there are lots of blogs, discussion threads, and other resources on the web that
you can find via Google or your favorite search engine.</p>
<p>The code referenced by the viewer described in this blog can be downloaded
from
<a href="http://dev2dev.bea.com/blog/skip/WLPCMViewer.as/WLPCMViewer.as">WLPCMViewer.as</a>
or copied from here:</p>
<div style="height: 200px; width: 90%; overflow: auto;">
<pre>
	import mx.rpc.events.ResultEvent;
	import mx.events.ListEvent;
	import mx.collections.ArrayCollection;
	import mx.core.Application;
	import mx.core.UIComponent;
	import mx.effects.Parallel;
	import mx.effects.Fade;
	import mx.controls.Image;
	import flash.events.Event;	

	private var parentNodePath:String = "";
	private var imageIndex:int = 0;
	
	private function debug(text:String):void {
	}
	
	private function init():void {

		debug("init");

		wlp_content_node_list.addEventListener(ResultEvent.RESULT, nodeListResultEvent);
		wlp_content_node.addEventListener(ResultEvent.RESULT, nodeResultEvent);
		wlp_content_node_list.send();
	}

	private function nodeListResultEvent(event:ResultEvent):void {
		var path:String = wlp_content_node_list.lastResult.rsp.nodePath;

		if (path == null || path == "null") {
			path = "/BEA Repository";
			parentNodePath = path;
		} else {

			parentNodePath = path.substring(0, path.lastIndexOf("/"));				
		}
		nodePathInput.text = path;
		debug(path + " -&gt; " + parentNodePath);
	}
	
	private function itemClickEvent(event:ListEvent):void {
		var type:String = event.currentTarget.selectedItem.type;
		var path:String = event.currentTarget.selectedItem.path;

		if (type == "folder") {
			wlp_content_node_list.request.nodePath = path;
			wlp_content_node_list.send();
		} else {
			wlp_content_node.request.nodePath = path;
			wlp_content_node.send();
		}
	}

	private function upOneLevel():void {
		wlp_content_node_list.request.nodePath = parentNodePath;
		wlp_content_node_list.send();
	}	
		
	private function nodeResultEvent(event:ResultEvent):void {
		var name:String = null;
		var contentType:String = null;
		var property:Object = null;
		var value:Object = null;
		var url:String = null;
		var nodeName:String = wlp_content_node.lastResult.rsp.name;
		var type:String = wlp_content_node.lastResult.rsp.type;
		var path:String = wlp_content_node.lastResult.rsp.path;
		var canDisplay:Boolean = false;
		
		for (var i:int = 0; i &lt; wlp_content_node.lastResult.rsp.properties.length; i++) {
			property = wlp_content_node.lastResult.rsp.properties[i];
			name = property.name;

			if (name == "file") {
				contentType = property.values.contentType;
				debug("contentType is " + contentType);
				if (contentType.indexOf("text") &gt;= 0) {
					htmlContent.htmlText = property.values.value;
					htmlContent.setVisible(true);
					imageContent.setVisible(false);
					imageContent2.setVisible(false);
					canDisplay = true;
				} else if (contentType.indexOf("image") &gt;= 0) {
					url = "http://wlp.bea.com" + property.values.value;
					showImage(url);
					imageContent.setVisible(true);
					imageContent2.setVisible(true);
					htmlContent.setVisible(false);
					canDisplay = true;
				}
			} else if (name == "url") {
				if (property.values != null) {
					url = property.values.value;
					showImage(url);
					imageContent.setVisible(true);
					imageContent2.setVisible(true);
					htmlContent.setVisible(false);
					canDisplay = true;
				}
			}
		}
		
		if (!canDisplay) {
			var msg:String = "No viewer for &lt;b&gt;" + nodeName + "&lt;/b&gt;";
			msg += " of type &lt;i&gt;" + type + "&lt;/i&gt;."
			htmlContent.htmlText = msg;
			htmlContent.setVisible(true);
			imageContent.setVisible(false);
			imageContent2.setVisible(false);
		}
	}

	private function showImage(url:String):void {

		var image:Image;
		var image2:Image;
	
		if (imageIndex == 0) {	
			image = imageContent2;
			image2 = imageContent;
		} else {
			image = imageContent;
			image2 = imageContent2;	
		}

		image2.addEventListener(Event.COMPLETE, _imageLoadedEvent);
		image2.load(url);
	}
	
	private function _imageLoadedEvent(event:Event):void {

		var image:Image;
		var image2:Image;

		if (imageIndex == 0) {	
			image = imageContent2;
			image2 = imageContent;
		} else {
			image = imageContent;
			image2 = imageContent2;	
		}

		var parallel:Parallel = new Parallel();

		var fade:Fade = new Fade();
		fade.target = image;
		fade.duration = 1000;
		fade.alphaFrom = 1;
		fade.alphaTo = 0;
		
		parallel.addChild(fade);
		
		var fade2:Fade = new Fade();
		fade2.target = image2;
		fade2.duration = 1000;
		fade2.alphaFrom = 0;
		fade2.alphaTo = 1;
		
		parallel.addChild(fade2);
		parallel.play();

		imageIndex++;
		if (imageIndex &gt; 1)
			imageIndex = 0;
	}
</pre>
</div>
<p>This code is largely event handlers to do some setup when the app is run
and to react to user clicks to display content.  Much of the code deals with
the special effects for fades between images and folder navigation.  I haven't
yet compared this with Dojo or other toolkits to see which takes more code,
and I suspect that Flex will have benefits when richer UI components are used.
That being said, it shouldn't be assumed that Flex is going to do everything
you want with little or no coding.  The good news is that it isn't hard, and
the tools and framework do a lot for you.</p>
<p>There are a few additional files that you will need in order to use this
sample, and to make it simple I've included everything in a single zip file
that you can download
<a href="http://dev2dev.bea.com/blog/skip/WLPTest_Flex_07162007.zip/WLPTest_Flex_07162007.zip">here</a>.
<o>This file contains the MXML and ActionScript files described above, along
with images for the background and buttons.  You can use them by creating a
new Flex project in Flex Builder and importing this file, which should end up
looking something like this:</p>
<img alt="flex_project1.png" 
src="http://dev2dev.bea.com/blog/skip/flex_project1.png/flex_project1.png"
width="202" height="228" />
<p>The <em>bin</em> and <em>html-template</em> folders are generated by Flex
Builder, as are some hidden files for the project.  To run the application
you can select <em>WLPCMViewer.mxml</em> and click the <em>Run</em> button
or right-click and select <em>Run Application</em>.  Try navigating the folder
hierarchy and selecting content nodes to display.  This sample app will display
nodes of type <em>image</em>, <em>swivelgraph</em>, and <em>article</em>, but
could be modified to handle others if desired.</p>
<p>As promised in earlier blog entries there is more to come.  I have some Dojo
widgets that I'll share, as well as examples of how to use the REST prototype
commands with Microsoft Popfly.  If there are other Web 2.0 technologies that
you're interested in, let me know and I'll try to check them out.</p>
]]>
        
    </content>
</entry>
<entry>
    <title>Web 2.0 Sample Code for REST Commands on wlp.bea.com</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2007/07/web_20_sample_c.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2007/07/web_20_sample_c.html</id>
    
    <published>2007-07-11T18:53:44Z</published>
    <updated>2007-07-11T18:53:51Z</updated>
    
    <summary>In previous entries I&apos;ve shown you the lower-levels of how to access the REST commands on wlp.bea.com and some simple JavaScript code.  In this entry I&apos;m going to provide you with sample code that makes it easier to use so that you can start mashing up the data and content available from the site.</summary>
    <author>
        <name>skip</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p><strong>Browsing the Content</strong></p>
<p>As we've seen it's easy to list and display the content on
<a href="http://wlp.bea.com">wlp.bea.com</a> using the REST commands with
a small amount of code.  The first samples aren't really reusable, and
mixing in lots of JavaScript with HTML doesn't have much appeal on multiple
levels.  In this entry I'll share with you some JavaScript that can be used
for rapidly building samples.</p>
<p>Here's the content browser, which is modeled on the standard Windows file
chooser:</p>
<img alt="contentBrowser1.png" 
 src="http://dev2dev.bea.com/blog/skip/contentBrowser1.png/contentBrowser1.png" 
 width="786" height="480" />
<p>In this screenshot the user has navigated to
<em>/BEA Repository/Demo/Images/Logos</em> and then clicked on the
<em>BEA</em> node.  This displays the logo below the browser and the
node properties to the right.  The user can also use the
<em>Up One Level</em> button to move back up the folder hierarchy and select
other nodes to browse and display.  This sample will display the properties
for any content type, but will only show the contents for content that has
image or text properties.  If you're willing to do a bit of exploration and
coding, you'll find that viewing other types of content isn't hard.</p>
<p>I won't go into great detail explaining the code, but I do want to point
out a few things that will help get you going.  You will need to use some
sort of proxy on the server that you host the sample code on, and if you don't
have one you should try the one from my previous blog entry
<a href="http://dev2dev.bea.com/blog/skip/archive/2007/07/mashing_up_wlpb.html">
Mashing Up wlp.bea.com using REST</a>.  I've also included this code in the
sample archive if you'd rather use that instead of cutting and pasting.  Again,
please note that this proxy is not secure and has only been tested for these
samples, so it's not meant for anything but exploration.</p>
<p>The file <em>contentBrowser.html</em> has a few things that you may need
to change based on your host environment, all of them in the <em>myInit</em>
function:</p>
<div style="height: 100px; overflow: auto;">
<pre>
    setHostName("wlp.bea.com");
    setProxyUrl("http://localhost:7001/portalTools/proxy");
    setBaseRestUrl("rest-web-lib/api/");
</pre>
</div>
<p>The one that you'll most likely need to change is the <em>proxy url</em>,
which should match that of the proxy that you're using.  If you're not using
the sample proxy servlet that I provided, you may also need to change the
way that the proxy url is constructed in the <em>getBaseRestUrl</em> function,
which is located in the file <em>js/util.js</em>.  This is used by other
functions to create and send the requests, and should be easy enough to modify
for other proxies.</p>
<p><strong>Accessing User Data</strong></p>
One thing that tends to make apps more interesting is being able to get to
useful data about a user.  Without access to data about employees, customers,
prospects, and other users, most business applications aren't useful.  If
you are using one or more BEA WebLogic or AquaLogic products then it is very
likely that you have existing user data.  Users of BEA WebLogic Portal are
probably familiar with the Unified User Profile, or UUP as we like to call it.
UUP allows for direct access to enterprise data so that you don't have to worry
with synchronization.  Because it is a unified view, all of the services, APIs,
tools, etc. in the portal can use it directly.</p>
<p>There are several articles here on dev2dev that can be found
by typing <code>unified user profile</code> or <code>uup</code> into the
search field found in the header.  You can also find information in the 
<a href="http://edocs.bea.com/wlp/docs100/users/index.html">User Management
Guide</a> on BEA's edocs site.  You won't need to be an expert on UUP to
use it, but you may find it helpful to understand how things work.</p>
<p>An example of using the user profile can be seen here, where the user
<em>mashup1</em> has logged into <em>userProfile.html</em> and has clicked
the <em>Get Profile</em> button:
<img alt="userProfile1.png" 
 src="http://dev2dev.bea.com/blog/skip/userProfile1.png/userProfile1.png" 
 width="328" height="336" />
<p>This sample shows a few of the properties in the <em>CustomerProperties</em>
property set which deal with the user's name and address.  In a moment we
will mashup this data, but first I'll tell you how you can create your own
user on <a href="http://wlp.bea.com">wlp.bea.com</a>.  If you haven't been
to this site, it's a great way to see some of the things that we're doing
with WebLogic Portal today and in the near future.  There live demo site
<a href="http://wlp.bea.com/wlp10/detect.jsp?url=http://wlp.bea.com/wlp10/appmanager/demos/play">
WebLogic Portal 10 Playground</a> is built on WLP 10 and is a <em>playground</em>
for Web 2.0 features.  Once there you can use the <em>Create User</em> portlet
to create a new user and login to the site.</p>
<p>Any user can now have their properties in a named property set, ready
for use.  There is no need for low-level RDBMS work, synchronization, or
other hassles, you just get and set the properties using tools, APIs, and
now the prototype REST commands.  You should try setting some values for
your user, logging out, the logging back in and getting them again.  These
are now persisted on wlp.bea.com and can be used in various ways.</p>
<p><strong>Mashing up User Data with Maps</strong></p>
It wouldn't be a proper discussion about mashups without the use of a map
somewhere, would it?  Map mashups are all over the place, and it may well
be that they cause some folks to write off the name <em>mashup</em> without
fully appreciating the potential.  This is unfortunate as there doesn't
appear to be anything else quite as concise or descriptive, but then again
it doesn't sound very businesslike either.  In any case maps do make for
interesting demonstrations of Web 2.0 features because they are visual and
interactive.</p>
<p>Here is a screenshot of a modified version of
<a href="http://dev2dev.bea.com/pub/au/3439">Peter Laird's</a> Google Maps
mashup.  The user name <em>mashup1</em> has been entered and the "Get Location"
button has been pressed:</p>
<img alt="userLocation1.png" 
 src="http://dev2dev.bea.com/blog/skip/userLocation1.png/userLocation1.png" 
 width="685" height="407" />
<p>You can try this out for yourself by changing the location using the
<em>userProfile.html</em> app and then pressing the <em>Get Location</em>
button on the Google Maps mashup.  Note that this doesn't seem to work well
with non-USA addresses, but you it probably could with some modifications
to the source code.</p>
<p><strong>The REST Commands</strong></p>
<p>I've discussed a number of the prototype REST commands and demonstrated a
few of them.  If you look in the sample source code you'll find out how to
use them, and I hope that you'll try some on your own.  If you do come up
with some examples, if you have questions, or you have suggestions, post
your comments to this blog.</p>
<p>Here are some docs that you may find helpful when using the commands:</p>
<p><a href="http://wlp.bea.com/rest-web-lib/help/profile.html">profile</a>
Gets and sets user profile property set values.</p>
<p><a href="http://wlp.bea.com/rest-web-lib/help/login.html">login</a>
Login and logout a user.</p>
<p><a href="http://wlp.bea.com/rest-web-lib/help/content.node.html">content.node</a>
Creates, reads, and updates content nodes.</p>
<p><a href="http://wlp.bea.com/rest-web-lib/help/content.nodelist.html">content.nodelist</a>
Gets a list of nodes for a specified path.</p>
<p><a href="http://wlp.bea.com/rest-web-lib/help/content.nodesearch">content.nodesearch</a>
Searches for matching nodes.</p>
<p>Note that these may be somewhat out-of-date as these prototypes are a work in
progress, but they'll help get you started.  The sample URLs in the docs are for
a local machine, such as:</p>
<div style="height: 50px">
<pre>

http://localhost:7001/portalTools/api/profile?username=mashup1&propertySet=CustomerProperties&propertyNames=*

</pre>
</div>
<p>You can use this with a proxy as in the following:</p>
<div style="height: 50px">
<pre>

http://localhost:7001/portalTools/proxy?url=http://wlp.bea.com/rest-web-lib/api/profile?username=fnord&propertySet=CustomerProperties&propertyNames=*

</pre>
</div>
<p>Here is the above as a link if you'd like to try it out to see the
properties for <em>mashup1</em> in XML:</p>
<p><a href="http://localhost:7001/portalTools/proxy?url=http://wlp.bea.com/rest-web-lib/api/profile?username=fnord&propertySet=CustomerProperties&propertyNames=*">
Properties for user mashup1</a></p>
<p>If you'd like to learn more about the user properties, you can use BEA
Workshop for  WebLogic Platform to explore them.  These examples use the
<em>CustomerProperties</em> property set, which is defined in the
<em>CustomerProperties.usr</em> file.  For exploring the content types you
can use the <em>WebLogic Portal Administration Tool</em> or you can use
the <em>contentTypeList.html</em> sample, as in the following:</p>
<img alt="contentTypeList.png" 
 src="http://dev2dev.bea.com/blog/skip/contentTypeList1.png/contentTypeList.png"
 width="438" height="171" />
<p><strong>The Demo Code</strong></p>
<p>Here's a link to a zip file containing the demo code:</p>
<p><a href="http://dev2dev.bea.com/blog/skip/wlp_rest_demo_01.zip">wlp_rest_demp_01.zip</a></p>
<p>The easiest way to use this is to extract it into a web application.  If
you are going to use the proxy servlet then you'll need to copy that into
the right place and setup the mappings.  Once you've done that you can open
any of the sample HTML files in a browser to try them out.</p>
<p>There's more to come, including some Dojo-based widgets that are even
easier to use and more powerful.  Please feel free to post comments if there
are things you'd like to see or learn more about.</p>
]]>
        
    </content>
</entry>
<entry>
    <title>Mashing Up wlp.bea.com using REST</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2007/07/mashing_up_wlpb.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2007/07/mashing_up_wlpb.html</id>
    
    <published>2007-07-06T22:41:52Z</published>
    <updated>2007-07-09T21:25:12Z</updated>
    
    <summary>In this entry I&apos;ll be discussing how to use some of the prototype REST commands introduced in the previous entry.  I&apos;ll provide some sample code to get you started and demonstrate how the commands may be used.  By using REST to access enterprise data and content we can create more interesting and useful mashups.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Platform" />
            <category term="Product: WebLogic Portal" />
            <category term="Role: Architect" />
            <category term="Technology: Service-oriented Architecture" />
            <category term="Technology: Web Services" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p>In my previous blog entry I introduce the prototype REST commands that we have made available on <a href="http://wlp.bea.com">wlp.bea.com</a>.  There are commands for accessing content, user profiles, and various portal assets, all of which can now be used outside of WebLogic Portal.  In this entry I'll discuss some of the ways to use these commands with a simple JavaScript client.</p>
<p><strong>Mashups by Proxy</strong></p>
<p>If you've ever tried using an <code>XMLHttpRequest</code> you may have
run into the cross-site scripting (XSS) issue.  This security feature
of web browsers can make mashups a bit difficult as it prevents the use
of anything outside of the original domain.  There are a few different
ways around this, including <a href="http://www.greasespot.net/">
Greasemonkey</a>, which is discussed by
<a href="http://dev2dev.bea.com/blog/plaird/">Peter Laird</a> in some of
his recent blogs.  Peter has been covering a variety of technologies for
mashups, Web 2.0, etc, and are a worthwhile read.</p>
<p>I've been using a proxy servlet based on the one that
<a href="http://dev2dev.bea.com/pub/au/3314">John Margaglione</a> posted
in his article
<a href="http://dev2dev.bea.com/pub/a/2006/03/ajax-portal-2.html?page=1">
Ajax Programming in BEA WebLogic Portal 8.1, Part 2</a>.  My modifications
are mainly to set the HTTP request method and do some basic authorization
to the proxied site.  It should be noted that I'm not suggesting that this
proxy is secure, so be careful.  It will work fine for prototypes, demos,
and for learning, but it's not meant for production use.<p>
<div style="height: 200px; width: 90%; overflow: auto">
<pre>
package test.proxy;

import java.io.*;
import java.net.*;
import java.util.*;

import javax.security.auth.login.LoginException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.ServletOutputStream;

import com.bea.p13n.security.Authentication;

public class ProxyServlet extends javax.servlet.http.HttpServlet 
{
	private static final long serialVersionUID = 0L;
	
	protected void service(HttpServletRequest request, HttpServletResponse response, String method)  throws ServletException, IOException
	{
		// The base 64 encoded username:password parameter
		String userPassword = request.getParameter("_up");
		
		String surl = URLDecoder.decode(request.getParameter("url"), "UTF-8");

		Map paramMap = request.getParameterMap();
        Iterator keys = paramMap.keySet().iterator();
        
        boolean first = true;

        if (request.getParameterMap().size() &gt; 1) 
        {
        	if (surl.contains("?"))
        		surl += "&";
        	else
        		surl += "?";
        }

        while (keys.hasNext())
        {
        	String name = (String) keys.next();
        	if (!name.equals("url") && !name.equals("_up"))
        	{
        		if (!first)
                	surl += "&";
                surl += name + "=" + request.getParameter(name);
                first = false;
            }
        }

        URL url = new URL(surl);

        HttpURLConnection uc = (HttpURLConnection) url.openConnection();
        
        uc.setRequestMethod(method);

        if (userPassword != null && !"".equals(userPassword))
        	uc.setRequestProperty("Authorization", "Basic " + userPassword);

        InputStream is = uc.getInputStream();
        
        while(true)
        {
            byte[] bytes = new byte[128];
            int read = is.read(bytes);
            if (read &lt;= 0)
            	break; 
            response.getOutputStream().write(bytes, 0, read);
        }
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        service(request, response, "GET");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        service(request, response, "POST");
    }

    protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        service(request, response, "PUT");
    }
    
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        service(request, response, "DELETE");
    }
}
</pre>
</div>
<p>To use this servlet you'll need to provide a mapping in <code>web.xml</code> such as:
<div style="height: 200px; width: 90%; overflow: auto">
<pre>
&lt;servlet&gt;
  &lt;servlet-name&gt;ProxyServlet&lt;/servlet-name&gt;
  &lt;servlet-class&gt;test.proxy.ProxyServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;ProxyServlet&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/proxy&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</pre>
</div>
<p>Note that if you don't use the <code>url-pattern</code> <em>/proxy</em>
you'll need to adjust the sample code accordingly.  You should also be
able to use any other proxy servlet, service, etc., along with tools such as
<a href="http://www.popfly.ms/">Microsoft Popfly</a> that do the proxying.
One of the great things about many of the Web 2.0 concepts is that they are
largely language and product independent, freeing the client from the server.</p>
<p><strong>The Simplest Client</strong></p>
<p>If you've read the previous article and tried out some of the sample URLs,
you've scratched the surface a bit.  Doing things with just URLs in a browser
is cumbersome, and you can't really much more than get the results.  To make
things more interesting we'll need a bit of client side code, with the following
as perhaps the simplest example:</p>
<div style="height: 200px; width: 90%; overflow: auto">
<pre>
&lt;html&gt;
&lt;head&gt;&lt;title&gt;Tiny REST&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;form action=""&gt;
  &lt;input type="text" name="path" size="50" value=""/&gt;
  &lt;input type="button" onclick="show(this.form.path.value)" value="Show Image"/&gt;
&lt;/form&gt;
&lt;img src="" id="image"/&gt;
&lt;script type="text/javascript"&gt;
function show(path) {
	var xmlHttpReq = false;
	if (window.ActiveXObject) { // IE
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest) {  // Mozilla/Safari
		xmlHttpReq = new XMLHttpRequest();
		xmlHttpReq.overrideMimeType('text/html');
	}
	var proxyUrl = "http://localhost:7001/portalTools/proxy?url=";
	var url = "http://wlp.bea.com/rest-web-lib/api/content.node"
	url += "?format=json&nodePath=" + path;
	url = proxyUrl + url;
	xmlHttpReq.open("GET", url, true);
	xmlHttpReq.setRequestHeader("Content-Type", "text/html");
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
    		var result = eval('(' + xmlHttpReq.responseText + ')');
			var properties = result.content.properties;
			var img = document.getElementById("image");
			for (i in properties)
				if (properties[i].name == "file")
					for(j in properties[i].values)
						if (properties[i].values[j].contentType.match("image"))
							img.src = "http://wlp.bea.com" + properties[i].values[j].value;
		}
	}
	xmlHttpReq.send(null);
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<p>To use this example you'll need to host it on the same server as the
proxy, and you may need to modify the <code>proxyUrl</code> value 
accordingly.  If you've been using WebLogic products then you'll probably
recognize the value used in the sample above.  You can put the sample HTML
pretty much anywhere on the same server, and it will work fine as a JSP,
etc.</p>
<p>When you access this from a web browser you'll see the following:
<div style="border: 1px solid #C0C0C0; height: 150px; width: 300px; padding: 4px; magin: 4px">
<form action="">
  <input type="text" name="path" size="30" value=""/>
  <input type="button" value="Show Image"/>
</form>
<img src="" id="image"/>
</div>
<p>Try entering the path <em>/BEA Repository/Demo/Logos/BEA</em> into the
field and press the 
<input type="button" value="Show Image"/> 
button to see the following:</p>
<div style="border: 1px solid #C0C0C0; height: 150px; width: 300px; padding: 4px; magin: 4px">
<form action="">
  <input type="text" name="path" size="30" value="/BEA Repository/Demo/Logos/BEA"/>
  <input type="button" value="Show Image"/>
</form>
<img src="http://wlp.bea.com/rest-web-lib/ShowProperty?nodeId=/BEA%20Repository/2010" id="image"/>
</div>
<p>There are some other images in this folder, including <em>AlfredChuang</em>, 
<em>BernersLee</em>, and <em>BEA Boulder</em>.  You can also find several
images under the <em>/BEA Boulder/Smithsonian</em> folder, including 
<em>plane1</em>, <em>Concorde1</em>, and <em>SR71</em>, a plane that BEA's
Ron Schweikert has some experience with.</p>
<p>So how can we display a list of links to make these folders browseable? 
There is a content node list REST command available, as you may recall from
the previous entry.  Using this we can get back the name, type, node path,
and more for all of the nodes within a folder.  The parameters that this
command needs are the <code>repositoryName</code> and <code>nodePath</code>. 
The public repository on <a href="http"//wlp.bea.com">wlp.bea.com</a> is 
called the <em>BEA Repository</em>, which is no surprise.</p>
<p>At the top level of this repository are several folders, some of which
have subfolders, along with content of various types.  The two types that 
we'll concern ourselves with now are <code>article</code> and <code>image</code>,
which have several properties.  When we retrieve a node we can use these
properties to display the images, titles, etc. if desired.  The code below
is a modified version of the sample above, with additions for browsing the
folder hierarchy and viewing images or articles.  It's content browser in
less than 100 lines, and it could probably be even shorter.</p>
<div style="height: 200px; width: 90%; overflow: auto">
<pre>
&lt;html&gt;
&lt;head&gt;&lt;title&gt;Tiny REST 2&lt;/title&gt;&lt;/head&gt;
&lt;body onload="listNodes(document.forms.inputForm.path.value);"&gt;
&lt;form name="inputForm" action=""&gt;
  &lt;input type="text" name="path" id="path" size="50" value=""/&gt;
  &lt;input type="button" onclick="listNodes(this.form.path.value)" value="List Nodes"/&gt;
&lt;/form&gt;
&lt;div id="nodeList" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;"&gt;
&lt;/div&gt;
&lt;div id="outputDiv" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;"&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
function show(path) {
	var xmlHttpReq = false;
	if (window.ActiveXObject) { // IE
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest) {  // Mozilla/Safari
		xmlHttpReq = new XMLHttpRequest();
		xmlHttpReq.overrideMimeType('text/html');
	}
	var proxyUrl = "http://localhost:7001/portalTools/proxy?url=";
	var url = "http://wlp.bea.com/rest-web-lib/api/content.node"
	url += "?format=json&nodePath=" + path;
	url = proxyUrl + url;
	xmlHttpReq.open("GET", url, true);
	xmlHttpReq.setRequestHeader("Content-Type", "text/html");
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
    		var result = eval('(' + xmlHttpReq.responseText + ')');
			var properties = result.content.properties;
			var img = document.getElementById("image");
			var outputDiv = document.getElementById("outputDiv");
			outputDiv.innerHTML = "";
			for (i in properties)
				if (properties[i].name == "file")
					for(j in properties[i].values)
						if (properties[i].values[j].contentType.match("image")) {
							var img = document.createElement("img");
							img.src = "http://wlp.bea.com" + properties[i].values[j].value;
							outputDiv.appendChild(img);
						} else if (properties[i].values[j].contentType.match("text"))
							outputDiv.innerHTML = properties[i].values[j].value;
		}
	}
	xmlHttpReq.send(null);
}

function listNodes(path) {
	var xmlHttpReq = false;
	if (window.ActiveXObject) { // IE
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest) {  // Mozilla/Safari
		xmlHttpReq = new XMLHttpRequest();
		xmlHttpReq.overrideMimeType('text/html');
	}
	var proxyUrl = "http://localhost:7001/portalTools/proxy?url=";
	var url = "http://wlp.bea.com/rest-web-lib/api/content.nodelist"
	url += "?format=json&nodePath=" + path;
	url += "&repositoryName=BEA Repository";
	url = proxyUrl + url;
	xmlHttpReq.open("GET", url, true);
	xmlHttpReq.setRequestHeader("Content-Type", "text/html");
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
    		var result = eval('(' + xmlHttpReq.responseText + ')');
    		var nodes = result.content.nodes;
    		var pathDiv = document.getElementById("path");
    		var nodeListDiv = document.getElementById("nodeList");
    		nodeListDiv.innerHTML = "";
   			var linkDiv = document.createElement("div");
    		linkDiv.innerHTML = "Parent Folder";
    		linkDiv.name = result.content.nodePath.substring(16);
    		pathDiv.value = linkDiv.name;
    		linkDiv.name = linkDiv.name.substring(0, linkDiv.name.lastIndexOf("/"));
    		linkDiv.onmousedown = function(evt) { listNodes(evt.target.name); };
    		nodeListDiv.appendChild(linkDiv);
    		for (i in nodes) {
    			linkDiv = document.createElement("div");
    			linkDiv.style.color = "blue";
    			linkDiv.innerHTML = nodes[i].name;
    			if (nodes[i].type == "folder") {
    				linkDiv.name = nodes[i].path.substring(16); // Strip /BEA Repository/
    				linkDiv.onmousedown = function(evt) { listNodes(evt.target.name); };
    			} else if (nodes[i].type == "image" || nodes[i].type == "article") {
    				linkDiv.name = nodes[i].path;
    				linkDiv.onmousedown = function(evt) { show(evt.target.name); };
    			}
    			nodeListDiv.appendChild(linkDiv);
    		}
		}
	}
	xmlHttpReq.send(null);
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<p>Save this to a file on the server and  open it in a browser to see a display
such as:</p>
<div style="border: 1px solid #C0C0C0; width: 300px; padding: 4px; magin: 4px">
<form action="">
  <input type="text" name="path" id="path" size="30" value=""/>
  <input type="button" value="List Nodes"/>
</form>
<div id="nodeList" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
  <div>Parent Folder</div>
  <div style="color: blue;">Demo</div>
  <div style="color: blue;">Financials</div>
  <div style="color: blue;">Improv</div>
  <div style="color: blue;">Smithsonian</div>
  <div style="color: blue;">spreadsheets</div>
  <div style="color: blue;">swivelgraphs</div>
</div>
<div id="outputDiv" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
</div>
</div>
<p>Click on <em>Demo</em> then <em>Images</em> and finally <em>Logos</em> to
see the list of images we used above.  Click on <em>BEA</em> to open the BEA
logo as follows:</p>
<div style="border: 1px solid #C0C0C0; width: 300px; padding: 4px; magin: 4px">
<form action="">
  <input type="text" name="path" id="path" size="30" value="Demo/Images/Logos"/>
  <input type="button" value="List Nodes"/>
</form>
<div id="nodeList" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
  <div>Parent Folder</div>
  <div style="color: blue;">BernersLee</div>
  <div style="color: blue;">BEA</div>
  <div style="color: blue;">BEA Boulder</div>
  <div style="color: blue;">AlfredChuang</div>
</div>
<div id="outputDiv" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
<img src="http://wlp.bea.com/rest-web-lib/ShowProperty?nodeId=/BEA%20Repository/2010" id="image"/>
</div>
</div>
<p>You can click on the <em>Parent Folder</em> link to go up a level, and if
you go to Demo/Articles you can click on <em>Lorem Ipsum</em> to see
the following:
<div style="border: 1px solid #C0C0C0; width: 300px; padding: 4px; magin: 4px">
<form action="">
  <input type="text" name="path" id="path" size="30" value="Demo/Articles"/>
  <input type="button" value="List Nodes"/>
</form>
<div id="nodeList" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
<div>Parent Folder</div>
  <div style="color: blue;">Web 2.0 Definition</div>
  <div style="color: blue;">History of Web 2.0</div>
  <div style="color: blue;">Ajax and WLP 10 FAQ</div>
  <div style="color: blue;">Lorem Ipsum</div>
  <div style="color: blue;">AquaLogic Commerce Services Released</div>
  <div style="color: blue;">Adrenalize Vista</div>
  <div style="color: blue;">Using the Blog Portlet</div>
</div>
<div id="outputDiv" style="height: 200px; overflow: auto; border: 1px solid #C0C0C0;">
<div id="lipsum1">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas ut ligula. Maecenas eleifend ligula sit amet purus. Curabitur nonummy justo in elit. Maecenas leo risus, volutpat eget, sodales non, euismod sed, lorem. Nam faucibus leo ut risus. Morbi eget enim faucibus turpis feugiat porttitor. Sed sodales facilisis tellus. Phasellus facilisis felis id felis. Cras volutpat neque vel neque. Nulla libero nisl, vehicula vel, iaculis id, sagittis id, ante. Duis eu purus. Phasellus blandit arcu a diam adipiscing ullamcorper. Aliquam facilisis, sapien ut blandit luctus, diam leo aliquet risus, nec consequat elit dui non turpis. Quisque blandit. Donec tellus. Nam quis sem nec dui egestas consectetuer. Donec volutpat, orci id feugiat pharetra, libero ante malesuada sapien, eget venenatis orci dolor in sapien. </p>
<p>Integer interdum adipiscing lorem. Etiam dictum tincidunt dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce ornare sem non leo. Maecenas viverra. Fusce id metus. Donec imperdiet enim sit amet enim. Nulla vitae nisi quis ipsum varius tempus. Phasellus eros. Curabitur fermentum dui quis pede. Nam iaculis fermentum mauris. </p>
<p>Cras molestie lobortis nulla. Morbi eu diam. Nullam molestie tempus elit. Cras pharetra, libero vitae posuere gravida, elit risus convallis risus, at semper orci velit in est. Vestibulum egestas tempor lorem. Praesent ornare tempus lorem. Duis nec orci nec libero placerat eleifend. Sed malesuada felis non velit. In ac massa a lorem bibendum egestas. Aenean eleifend mattis lacus. In consectetuer libero quis tellus. Donec est. Sed elementum. Praesent faucibus mollis tellus. Fusce eget quam. Vestibulum id est. In elementum. Mauris tincidunt sagittis ante. Mauris felis risus, tristique quis, sollicitudin non, porta ut, enim. Nulla facilisi. </p>
<p>Nunc non nisi vitae eros nonummy elementum. Fusce nec lacus sit amet justo condimentum tincidunt. Maecenas ligula mi, placerat at, consectetuer sed, posuere at, arcu. Proin id urna. Praesent vitae velit a pede mattis ullamcorper. Fusce eleifend, sapien in congue dapibus, dolor purus vehicula turpis, non auctor lacus tortor at massa. Donec sem. In hac habitasse platea dictumst. Integer nunc. Donec convallis nisi et risus. Ut molestie elit non sapien. In urna. Praesent sodales urna vel odio. Sed sit amet ipsum et ipsum nonummy molestie. Donec vel ligula ut nulla lobortis convallis. Etiam adipiscing. Cras volutpat neque ut lorem. Nullam blandit nibh. </p>
<p>Nulla euismod. Morbi vestibulum tellus a sapien. Vivamus semper. Sed euismod scelerisque nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. In eu justo a lectus vehicula facilisis. Sed nulla enim, sodales egestas, facilisis sed, cursus ac, nibh. Nunc tempor lectus a mauris. Curabitur iaculis felis quis diam. In euismod diam imperdiet dolor. Vivamus feugiat ullamcorper ipsum. Vestibulum ultrices. Curabitur arcu. Phasellus hendrerit orci non orci. Praesent accumsan. Nam eget velit. Suspendisse sodales mi in ipsum. </p>
</div>
</div>
</div>
<strong>Making It All Easier</strong>
<p>If you've been examining the code samples you'll recognize that they aren't
at all modular or easily reusable.  Hopefully they will show you how to use
some of the REST commands, but I promise you it gets better and easer.  In the
next few blog entries I'll introduce some JavaScript functions that you can
use, as well as some Dojo-based widget that make it even easier.  The source
code for all of these will be provided so you can adapt them as needed.</p>.
<p>If you've been using Web 2.0 technologies and would like to see how they
might be used with WebLogic Portal, I'd love to hear about them.</p>
]]>
        
    </content>
</entry>
<entry>
    <title>The REST of the Story</title>
    <link rel="alternate" type="text/html" href="http://dev2dev.bea.com/blog/skip/archive/2007/07/the_rest_of_the.html" />
    <id>http://dev2dev.bea.com/blog/skip/archive/2007/07/the_rest_of_the.html</id>
    
    <published>2007-07-05T20:27:57Z</published>
    <updated>2007-07-06T22:42:44Z</updated>
    
    <summary>This blog entry is the first in a series describing a set of prototype REST commands that we&apos;re making available on wlp.bea.com.  These commands will make it possible to access various types of content and data from a WebLogic Portal server for use in various Web 2.0 apps and mashups.  All of these are true prototypes and do not reflect the actual product features, but they do provide an indication of what we&apos;re planning for the future.</summary>
    <author>
        <name>skip</name>
        
    </author>
            <category term="Product: WebLogic Platform" />
            <category term="Product: WebLogic Portal" />
            <category term="Role: Architect" />
            <category term="Technology: Service-oriented Architecture" />
    
    <content type="html" xml:lang="en" xml:base="http://dev2dev.bea.com/blog/skip/">
        <![CDATA[<p><strong>Mashups - Where's the Beef?</strong></p>

<p>I'm a big fan of most things Web 2.0, and I believe that the concepts and technologies that are now emerging will play a big role in how we build applications long after the buzz has faded.  Mashups and "situational apps" are great concepts, but at the present far too many examples are technical showcases without a lot of substance.  A business user isn't as likely to be impressed with how many different ways a map can be mashed up with addresses that aren't relevant to their job.  Nor will they think that the latest AI-assisted context-sensitive fish-eye list is interesting if they can't use it with their corporate data.  Much of the current crop of mashups may end up as orphans because no one will find them interesting enough.</p>

<p>So what do we do to ensure that the applications we create are truly useful?  Well, if you're using BEA WebLogic and AquaLogic products for SOA, web applications, and enterprise computing, you've already solved many of the hard problems.  You have ways to get to the processes, data, content, and services that the business users need to do their jobs, and it's likely that you have existing Web 1.0 applications in place.  But what about Web 2.0, and how are you going to get there?  There are lots of possibilities, and it's going to be confusing for a while, but I have one thing to suggest that you keep in mind until all of the dust settles: REST.</p>

<p><strong>Representational State Transfer (REST)</strong></p>

<p>There are many great articles, discussion, blogs, and so on about REST, so I'm not going to make this a tutorial on the subject.  This series will make more sense if you understand the principals of REST, and I'd like to suggest the following:<p>

<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Representational State Transfer - Wikipedia</a><br>
<a href="http://www.oreilly.com/catalog/9780596529260/">RESTful Web Services by Leonard Richardson, Sam Ruby</a><br>
<a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Representational State Transfer (REST) - Chapter 5 of Roy T. Fielding's Dissertation</a><br>

<p><strong>The Miracle</strong></p>

<p>A colleague of mine came up with a great description of how the gap between the enterprise and Web 2.0: "Then a miracle occurred."  If you've built Web 1.0 applications then you probably used technologies such as JSP, JSF, Struts, Beehive, and more to provide the user interface to enterprise applications.  These work well if you know J2EE, and are well suited for the traditional request-response architecture.  With the rise in demand for Web 2.0 features, you have to figure out how you're going to add these features without having to throw everything out and start over. </p>

<p>Despite the title of this section I'm not here to suggest that REST is itself the miracle that will bring Web 2.0 to the enterprise.  What I believe is that it can be an essential part of the solution when combined with RIA (Rich Internet Application) technologies such as Ajax, Flex, Silverlight, and more.  The RIA toolkits and products help make applications more usable; REST will help ensure that the applications are truly useful.  By using REST you can unlock the enterprise data for use in Web 2.0 applications without giving up the various "ilities" that are expected.</p>

<p><strong>A Quick Demonstration</strong></p>

<p>If you've read up on REST or have played with it already, you'll know that one of the basic features is HTTP accessibility.  There are a number of prototype REST services deployed on wlp.bea.com, and I'll be revealing more of them in subsequent entries, along with lots of sample code.  To see REST in action now, simply open a web browser and enter the following URL:</p>

<p><a href="http://wlp.bea.com/rest-web-lib/api/content.nodelist?repositoryName=BEA%20Repository">http://wlp.bea.com/rest-web-lib/api/content.nodelist?repositoryName=BEA%20Repository</a></p>

<p>This will return an XML document that looks something like the following snippet:</p>

<pre>
&lt;?xml version="1.0" encoding="utf-8" ?&gt; 
&lt;rsp stat="ok"&gt;
  &lt;name&gt;null&lt;/name&gt;
  &lt;nodePath&gt;null&lt;/nodePath&gt;
  &lt;id&gt;null&lt;/id&gt;
  &lt;type&gt;null&lt;/type&gt;
  &lt;nodes&gt;
    &lt;name&gt;Demo&lt;/name&gt;
    &lt;path&gt;/BEA Repository/Demo&lt;/path&gt;
    &lt;id&gt;/BEA Repository/2001&lt;/id&gt;
    &lt;type&gt;folder&lt;/type&gt;
    &lt;workflowStatus&gt;published&lt;/workflowStatus&gt;
  &lt;/nodes&gt;
  ...
&lt;rsp&gt;
</pre>

<p>These nodes represent the top level of the specified repository, and each folder type may be browsed by appending its path to a nodePath parameter on the URL.  For example, you can see what's under the Demo folder with the following:</p>

<p><a href="http://wlp.bea.com/rest-web-lib/api/content.nodelist?repositoryName=BEA%20Repository&nodePath=Demo">http://wlp.bea.com/rest-web-lib/api/content.nodelist?repositoryName=BEA%20Repository&nodePath=Demo</a></p>

<p>If you follow the folder hierarchy to Demos/Images/Logos, you'll see a list of images such as:</p>

<pre>
&lt;?xml version="1.0" encoding="utf-8" ?&gt; 
&lt;rsp stat="ok"&gt;
  &lt;name&gt;Logos&lt;/name&gt;
  &lt;nodePath&gt;/BEA Repository/Demo/Images/Logos&lt;/nodePath&gt;
  &lt;id&gt;/BEA Repository/2009&lt;/id&gt;
  &lt;type&gt;folder&lt;/type&gt;
  &lt;nodes&gt;
    &lt;name&gt;BEA&lt;/name&gt;
    &lt;path&gt;/BEA Repository/Demo/Images/Logos/BEA&lt;/path&gt;
    &lt;id&gt;/BEA Repository/2010&lt;/id&gt;
    &lt;type&gt;image&lt;/type&gt;
    &lt;workflowStatus&gt;published&lt;/workflowStatus&gt;
  &lt;/nodes&gt;
  ...
&lt;rsp&gt;
</pre>

<p>So how do get the details of an image?  Use the content.node command with the path as follows:</p>

<p><a href="http://wlp.bea.com/rest-web-lib/api/content.node?nodePath=/BEA%20Repository/Demo/Images/Logos/BEA">http://wlp.bea.com/rest-web-lib/api/content.node?nodePath=/BEA%20Repository/Demo/Images/Logos/BEA</a></p>

<p>This will return the XML describing this node, with properties that match those for the specific content type.  This prototype service treats images as a special case, returning the URL for displaying the image with the ShowProperty servlets rather than the binary data.  To display the image the following URL can be used:</p>

<p><a href="http://wlp.bea.com/rest-web-lib/ShowProperty?nodeId=/BEA%20Repository/2010">http://wlp.bea.com/rest-web-lib/ShowProperty?nodeId=/BEA%20Repository/2010</a></p>

<p>Here's the image:</p>

<p><img src="http://wlp.bea.com/rest-web-lib/ShowProperty?nodeId=/BEA%20Repository/2010"/></p>

<p><strong>Using the Data in a Client Application - JSON to the Rescue</strong></p>

<p>XML is a great way to represent data, but it doesn't always lend itself for use in a client, especially one that is JavaScript-centric.  Thankfully we have JSON (JavaScript Object Notation) which is inherently JavaScript friendly, and is often used with REST.  We can get the JSON response for any REST request by using the format=json parameter, as in the following:</p>

<p><a href="http://wlp.bea.com/rest-web-lib/api/content.node?nodePath=/BEA%20Repository/Demo/Images/Logos/BEA&format=json">http://wlp.bea.com/rest-web-lib/api/content.node?nodePath=/BEA%20Repository/Demo/Images/Logos/BEA&format=json</a></p>

<p>An interesting point is that while JSON is easier to use with JavaScript, it can be harder to read than XML.  Try the URL above and view the response in a text editor.  You may find that Firefox does a better job with this than IE.  The good news is that the point of JSON isn't readability by humans; rather it's how easy it is to use the data in JavaScript.  A JSON response can be turned into a JavaScript object with code such as the following, where the responseText from an XMLHttpRequest is evaluated:</p>

<p><code>var result = eval('(' + xhmlHttpReq.responseText + ')');</code></p>

<p>The result object can be used with standard dot notation, allowing for example "result.content.name" to get the node name, "result.content.properties" to get the array of properties, and so on.  This works nicely with many JavaScript libraries and applications, which I'll be describing and demonstrating in subsequent blog entries.  Source code for JavaScript libaries, including some based on Dojo, will be provided.  I'll also demonstrate how to use these REST commands with various types of mashup tools and technologies.</p>

<p>Stay tuned!</p>]]>
        
    </content>
</entry>

</feed> 