Showing posts with label wsrp. Show all posts
Showing posts with label wsrp. Show all posts

Saturday, December 1, 2007

Using WSRP CSS classes - an example by Oracle

pencil icon, that"s clickable to start editing the post

Since I wrote my last post Styling my WSRP portlets - does these CSS classes really give us common look-and-feel? I've been looking for recommendations and best practice on this field of web design. In this post I'll list some of the best sources I've found and compare with an example by Oracle.

Semantic (X)HTML

I hadn't heard of this before stumbling upon it, but the concept i straight forward and not to far away from projects I've worked on myself. There are several good references but one of best are The Early Bird Catches the CSS: Planning Structural HTML by Virginia DeBolt (on Wise-Women). Other great sources:

Where the last one has the full crossover to microformats.

The Oracle CSS Portlet

As an effort to enable/show WSRP 1.0 interoperability several of the member of that committee has exposed both producers and some simple portal pages consuming the different producers. One of the portlets exposed by Oracle are The Oracle CSS Portlet:

Oracle sample portlet for using the CSS classes that come with the standard

which can be found alongside others on the Hosted WSRP root page with "WSRP/JSR 168 Sample Portlets". This example portlet is perfect to get an idea on how to use the classes.

Before looking into the actual markup a run through W3C's Markup Validation Service gives:This page is not Valid HTML 4.01 Transitional! - Failed validation, 9 Errors. This is not that bad and most of the errors seem minor.

In the markup there's no rule as to where the portlets start, but in this example it's not so hard. Using the great Web Eeveloper add-on to Firefox, with "View style information" (under 'CSS') it looks like this:

The Oracle CSS portlet - outline the portlet part with the webdeveloper add on to firefox

This is a very resonale guess as to where the page template stops and the portlet starts. This is also of relevance as this concerns the use of section classes.

The first part of the template until the portlet part is like:

    1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    2 <HTML dir="LTR" lang="da">
    3 <HEAD>
    4 <TITLE>CSS Portlet</TITLE>
    5 </HEAD>
    6 <BODY bgcolor="#FFFFFF">
    7 <SCRIPT TYPE="text/javascript">function show_context_help(h) {window.open(h,"Help","menubar=1,toolbar=1,scrollbars=1,resizable=1,width=700,height=500").focus();}</SCRIPT>
    8 <NOSCRIPT></NOSCRIPT>
    9 <LINK REL=Stylesheet TYPE="text/css"
   10   HREF="http://portalstandards.oracle.com/portal/pls/portal/PORTAL.wwui_api_body.render_wizard_css?p_version=10.1.4.0.0.594">
   11 <A HREF="#content"><IMG SRC="/images/pobtrans.gif" ALT="Spring over navigeringslinks" border=0></A>
   12 <TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="90%" align="CENTER" CLASS="OraWizBannerColor">
   13   <TR>
   14     <TD ALIGN="LEFT" width="5%" valign=TOP rowspan=2><IMG SRC="/images/logo.gif" ALT="Oracle Portal" border=0></TD>
   15     <TD ALIGN="RIGHT" valign="TOP"><IMG SRC="/images/pobtrans.gif" height=1 width=10 border=0 ALT=""> <A
   16       HREF="http://portalstandards.oracle.com/portal/pls/portal/PORTAL.home" class="OraWizBannerLink">Startside</A> <IMG
   17       SRC="/images/pobtrans.gif" height=1 width=10 border=0 ALT=""> <A
   18       HREF="http://portalstandards.oracle.com/portal/page/portal/TOPLEVELSITE" class="OraWizBannerLink">Builder</A></TD>
   19   </TR>
   20 </TABLE>
   21 <CENTER>
   22 <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="90%">
   23   <TR>
   24     <TD>
   25     <TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
   26       <TR>
   27         <TD width="3%" class="OraBgColorDark">&nbsp;</TD>
   28         <TD width="96%" class="OraBgColorDark"><FONT class="OraGlobalPageTitle">CSS Portlet</FONT></TD>
   29         <TD class="OraBgColorDark">&nbsp;</TD>
   30       </TR>
   31     </TABLE>
   32 
   33     </TD>
   34   </TR>
   35   <TR>
   36     <TD>
   37     <TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
   38       <TR>
   39         <TD rowspan="2" valign="TOP">
   40         <TABLE border="0" cellpadding="0" cellspacing="0">
   41           <TR>
   42             <TD valign="TOP" class="OraBgColorDark"><IMG src="/images/FFFFFFsl.gif" valign="TOP" border="0"></TD>
   43           </TR>
   44         </TABLE>
   45         </TD>
   46         <TD rowspan="2" valign="TOP"><IMG src="/images/compedit.gif" valign="TOP" border="0"></TD>
   47         <TD align="right" valign="TOP" width="100%">
   48         <FORM>
   49         <TABLE border="0" cellpadding="1" cellspacing="4">
   50           <TR>
   51             <TD BGCOLOR="#999999">
   52             <BUTTON TYPE="button"
   53               onClick="javascript:window.location='http://portalstandards.oracle.com/portal/page/portal/OracleHostedWSRPPortal/Samples'">Close</BUTTON>
   54 
   55             </TD>
   56           </TR>
   57         </TABLE>
   58         </FORM>
   59         </TD>
   60       </TR>
   61     </TABLE>
   62     </TD>
   63   </TR>
   64 </TABLE>
   65 </CENTER>
   66 <CENTER>
   67 <TABLE WIDTH="90%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
   68   <TR>
   69     <TD>
   70     <BLOCKQUOTE>
   71     <BLOCKQUOTE>

Aiming to to be "4.01 Transitional" is a common choice, though strict would have been more correct in terms of the HTML 4.01 specification itself. The layout is clearly controlled by a tables and not through CSS2. The double nesting in <blockquote> elements is non-semantic.

The next markup section is the portlet markup, and it comes with an abvious change from uppercase to lowercase, supporting my guess that this in fact the content provided by the portlet:

   72     <p class="portlet-section-header">This is a portlet section header - uses style "portlet-section-header"</p>
   73     <p class="portlet-section-subheader">This is a portlet section sub-header - uses style "portlet-section-subheader"</p>
   74     <p class="portlet-section-body">This is a portlet section body - uses style "portlet-section-body"</p>
   75 
   76     <p class="portlet-section-alternate">This is an alternate row within this section - uses style
   77     "portlet-section-alternate"</p>
   78     <p class="portlet-section-footer">This is a portlet section footer - uses style"portlet-section-footer"</p>
   79     <p class="portlet-font">This is regular text with in the portlet body - uses style "portlet-font"</p>
   80     <p class="portlet-font-dim">This text uses style "portlet-font-dim"</p>
   81     <p class="portlet-msg-status">This is a status message with in the portlet - uses style "portlet-msg-status"</p>
   82     <p class="portlet-msg-info">Help: This is a Help message - uses style "portlet-msg-info"</span></p>
   83     <p class="portlet-msg-error">Error: This is an error message - uses style "portlet-msg-error"</p>
   84     <p class="portlet-msg-alert">Warning: This is a warning - uses style "portlet-msg-alert"</p>
   85     <p class="portlet-msg-success">This text is a verification of the successful completion of a task - uses style
   86     "portlet-msg-success"</p>

This part of the portlet covers the basic CSS classes for section which here is though the <p> element. Next comes the table:

   87 
   88     <center>
   89     <table width="87%" border="1">
   90       <tr class="portlet-table-header">
   91         <td>This is a table heading - uses style"portlet-table-header"</td>
   92         <td colspan="2">Heading 1</td>
   93         <td>Heading 2</td>
   94         <td>Heading 3</td>
   95       </tr>
   96       <tr class="portlet-table-subheader">
   97         <td>This is a table sub-heading - uses style "portlet-table-subheader"</td>
   98         <td>Sub-heading 1</td>
   99         <td>Sub-heading 2</td>
  100         <td>&nbsp;</td>
  101         <td>&nbsp;</td>
  102       </tr>
  103 
  104       <tr class="portlet-table-body">
  105         <td>This is table body text - uses style "portlet-table-body"</td>
  106         <td>Table body text</td>
  107         <td>Table body text</td>
  108         <td>Table body text</td>
  109         <td>Table body text</td>
  110       </tr>
  111       <tr class="portlet-table-footer">
  112         <td colspan="5" align="center">This is a table footer - uses style "portlet-table-footer"</td>
  113       </tr>
  114     </table>
  115     </center>

If I were to choose I would prefer using the corresponding table elements for header, body and footer. I can't figure out if the subheader is needed or could be done by <caption> and <thead>.

The last part is an example for forms:

  116     <form>
  117     <p align="center" class="portlet-section-header">A Sample Form</p>
  118 
  119     <center>
  120     <table>
  121       <tr>
  122         <td class="portlet-form-label" colspan="2">This is a form label - uses style "portlet-form-label"</td>
  123       </tr>
  124       <tr>
  125         <td class="portlet-form-field-label">This is text for a form field - uses style "portlet-form-field-label"</td>
  126         <td><input name="textfield" type="text" class="portlet-form-input-field"
  127           value='This is user input in a text field - uses style"portlet-form-input-field"' /></td>
  128       </tr>
  129       <tr>
  130         <td class="portlet-form-label" colspan="2" align="center"><input name="Submit" type="button"
  131           class="portlet-form-button" value='This is text on a form button - uses style "portlet-form-button"' /></td>
  132       </tr>
  133     </table>
  134     </center>
  135     </form>

Like with the table part it seems redundant that the style classes repeat the element structure.

And from here it's back to the template with uppercasing:

  136     </BLOCKQUOTE>
  137     </BLOCKQUOTE>
  138     </TD>
  139   </TR>
  140 </TABLE>
  141 </CENTER>
  142 <CENTER>
  143 <TABLE border="0" cellpadding="0" cellspacing="0" width="90%">
  144   <TR>
  145     <TD><IMG src="/images/pobtrans.gif" width="1" height="8"></TD>
  146   </TR>
  147   <TR>
  148     <TD>
  149 
  150     <TABLE width="100%" border="0" cellpadding="0" cellspacing="0">
  151       <TR>
  152         <TD align="right">
  153         <TABLE border="0" cellpadding="0" cellspacing="0">
  154           <TR>
  155             <TD align="right" class="OraBgColorDark"><IMG src="/images/FFFFFFbr.gif"></TD>
  156           </TR>
  157         </TABLE>
  158         </TD>
  159       </TR>
  160       <TR>
  161         <TD height="14" class="OraBgColorDark">&nbsp;</TD>
  162       </TR>
  163     </TABLE>
  164     </TD>
  165   </TR>
  166 </TABLE>
  167 </CENTER>
  168 
  169 </BODY>
  170 </HTML>

Conclusion

Semantic XHTML is considered best practice but it's hard to find in the portlet CSS classes. It is very nice that Oracle has taken the time to create an example for how the classes should be used. The missing part to conclude on is the complexity of the example and even more the richness of the design. The design chosen here is quite minimal and that might make this example more forgiving, as to which variants in the portlet markup would look right.

Read more

Wednesday, March 7, 2007

Trying to be a consumer

pencil icon, that"s clickable to start editing the post
I my last post i looked at the SOAP on he wire between the WSRP4J producer and proxy portlet. After that I wanted to try it out for my self by writing a simple consumer (client) using axis2. I should be very simple since the standard contains the webservice interface (WSDL) which i nicely decomposed into seperate files for: the service definitions are like
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:oasis:names:tc:wsrp:v1:wsdl"
                  xmlns:bind="urn:oasis:names:tc:wsrp:v1:bind"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <import namespace="urn:oasis:names:tc:wsrp:v1:bind"
          location="wsrp_v1_bindings.wsdl"/>

  <wsdl:service name="WSRPService">
    <wsdl:port binding="bind:WSRP_v1_Markup_Binding_SOAP" name="WSRPBaseService">
      <soap:address location="http://my.service:8080/WSRPService"/>
    </wsdl:port>
    <wsdl:port binding="bind:WSRP_v1_ServiceDescription_Binding_SOAP" name="WSRPServiceDescriptionService">
      <soap:address location="http://my.service:8080/WSRPService"/>
    </wsdl:port>
    <wsdl:port binding="bind:WSRP_v1_Registration_Binding_SOAP" name="WSRPRegistrationService">
      <soap:address location="http://my.service:8080/WSRPService"/>
    </wsdl:port>
    <wsdl:port binding="bind:WSRP_v1_PortletManagement_Binding_SOAP" name="WSRPPortletManagementService">
      <soap:address location="http://my.service:8080/WSRPService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
I first first tried to change the endpoints and run i through the Axis2 Codegen, but I only generates the Markup Binding, that is the others are generated by the can't overwrite it. I've therefore changed it to:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
  targetNamespace="urn:oasis:names:tc:wsrp:v1:wsdl"
  xmlns:bind="urn:oasis:names:tc:wsrp:v1:bind"
  xmlns="http://schemas.xmlsoap.org/wsdl/"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <import
    namespace="urn:oasis:names:tc:wsrp:v1:bind"
    location="wsrp_v1_bindings.wsdl" />

  <wsdl:service name="WSRPBaseService">
    <wsdl:port
      binding="bind:WSRP_v1_Markup_Binding_SOAP"
      name="WSRPBaseService">
      <soap:address location="http://localhost:8080/wsrp4j-producer/services/WSRPBaseService" />
    </wsdl:port>
  </wsdl:service>

  <wsdl:service name="WSRPServiceDescriptionService">
    <wsdl:port
      binding="bind:WSRP_v1_ServiceDescription_Binding_SOAP"
      name="WSRPServiceDescriptionService">
      <soap:address location="http://localhost:8080/wsrp4j-producer/services/WSRPServiceDescriptionService" />
    </wsdl:port>

  </wsdl:service>

  <wsdl:service name="WSRPRegistrationService">
    <wsdl:port
      binding="bind:WSRP_v1_Registration_Binding_SOAP"
      name="WSRPRegistrationService">
      <soap:address location="http://localhost:8080/wsrp4j-producer/services/WSRPRegistrationService" />
    </wsdl:port>
  </wsdl:service>

  <wsdl:service name="WSRPPortletManagementService">
    <wsdl:port
      binding="bind:WSRP_v1_PortletManagement_Binding_SOAP"
      name="WSRPPortletManagementService">
      <soap:address location="http://localhost:8080/wsrp4j-producer/services/WSRPPortletManagementService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
So I've changed the ports to each have their own service (and runs Codegen four times, for each service name (@name). This works allright for me except that's I using four services instead of one, which does take an extra effort for ex. session handling that could have been clean out of the Axis2 box (dist). This is an example of the flexibility of WSDL, that seemingly the same can be done i several ways, even though I'm not sure what the semantic differences are. The W3C Note for WSDL 1.1 says the following about services: A service groups a set of related ports together, and that ports within a service have the following relationship:
  • None of the ports communicate with each other (e.g. the output of one port is not the input of another).
  • If a service has several ports that share a port type, but employ different bindings or addresses, the ports are alternatives. Each port provides semantically equivalent behavior (within the transport and message format limitations imposed by each binding). This allows a consumer of a WSDL document to choose particular port(s) to communicate with based on some criteria (protocol, distance, etc.).
  • By examining it's ports, we can determine a service's port types. This allows a consumer of a WSDL document to determine if it wishes to communicate to a particular service based whether or not it supports several port types. This is useful if there is some implied relationship between the operations of the port types, and that the entire set of port types must be present in order to accomplish a particular task.
Maybe the last bullet does imply that what I'm doing is not what should be done if I exposed it, but since I'm only consuming at therefore use to generate my stubs it doesn't really matter.

Read more

Thursday, March 1, 2007

Web traffic for the WSRP4J demo

pencil icon, that"s clickable to start editing the post
Work in slow progress Following the README with the WSRP4J dist I succeded in getting the demo running and heres a dump of the web traffic it generates as captured with the tcpmon tool. The traffic is between the wsrp4j proxy portlet and the wsrp4j-producer (forwarding the jsr168 testportlet that comes with wsrp4j). The portlet page that these (identical) portlets end up in looks like.

What do you have to offer

The first thing the proxyportlet does it to query the wsrp4j-producer about what portlets are available (done with axis 1.4 which the wsrp4j proxyportlet uses):
POST /wsrp4j-producer/services/WSRPServiceDescriptionService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:9101
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "urn:oasis:names:tc:wsrp:v1:getServiceDescription"
Content-Length: 386

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getServiceDescription xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <registrationContext xsi:nil="true" />
    </getServiceDescription>
  </soapenv:Body>
</soapenv:Envelope>

and the answer is
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 06 Mar 2007 09:25:03 GMT
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getServiceDescriptionResponse
      xsi:type="ns1:ServiceDescription"
      xmlns="urn:oasis:names:tc:wsrp:v1:types"
      xmlns:ns1="urn:oasis:names:tc:wsrp:v1:types">
      <ns1:requiresRegistration xsi:type="xsd:boolean">true</ns1:requiresRegistration>
      <ns1:requiresInitCookie xsi:type="ns1:CookieProtocol">perGroup</ns1:requiresInitCookie>
    </getServiceDescriptionResponse>
  </soapenv:Body>
</soapenv:Envelope>


which is kind of an no-answer since it just indicates the it requires registration prior to any thing (requiresRegistration), and that it requires that cookies are initialized per group (requiresInitCookie) more about that later.

All right I'll register
Since it requires registration there's only one thing to do:
POST /wsrp4j-producer/services/WSRPRegistrationService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:9101
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "urn:oasis:names:tc:wsrp:v1:register"
Content-Length: 469

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <register xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <consumerName>WSRP4J Proxy Portlet</consumerName>
      <consumerAgent>WSRP4J Proxy Portlet</consumerAgent>
      <methodGetSupported>false</methodGetSupported>
    </register>
  </soapenv:Body>
</soapenv:Envelope>
and the producer accepts with:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 06 Mar 2007 09:25:03 GMT
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <registerResponse xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <registrationHandle>0:0:0:0:0:0:0:1_1173173104036_0</registrationHandle>
    </registerResponse>
  </soapenv:Body>
</soapenv:Envelope>
so the registrationHandle is 0:0:0:0:0:0:0:1_1173173104036_0.

Okay now show me what you offer After having registred it's now possible to actually get the serviceDescription:
POST /wsrp4j-producer/services/WSRPServiceDescriptionService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:9101
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "urn:oasis:names:tc:wsrp:v1:getServiceDescription"
Content-Length: 464

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getServiceDescription xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <registrationContext>
        <registrationHandle>0:0:0:0:0:0:0:1_1173173104036_0</registrationHandle>
      </registrationContext>
    </getServiceDescription>
  </soapenv:Body>
</soapenv:Envelope>
and here goes the answer which is quite verbose since it contains a complete description of the portlet/service. One annoyiance is all the unnessesary xsi:type the Axis 1.* produces which I've never been able to remove not even with sendXsiTypes.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 06 Mar 2007 09:25:03 GMT
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getServiceDescriptionResponse
      xsi:type="ns1:ServiceDescription"
      xmlns="urn:oasis:names:tc:wsrp:v1:types"
      xmlns:ns1="urn:oasis:names:tc:wsrp:v1:types">
      <ns1:requiresRegistration xsi:type="xsd:boolean">true</ns1:requiresRegistration>
      <ns1:offeredPortlets xsi:type="ns1:PortletDescription">
        <ns1:portletHandle xsi:type="xsd:string">wsrp4j-testportlet.WSRP4JTestPortletA</ns1:portletHandle>
        <ns1:markupTypes xsi:type="ns1:MarkupType">
          <ns1:mimeType xsi:type="xsd:string">text/html</ns1:mimeType>
          <ns1:modes xsi:type="xsd:string">wsrp:view</ns1:modes>
          <ns1:modes xsi:type="xsd:string">wsrp:edit</ns1:modes>
          <ns1:modes xsi:type="xsd:string">wsrp:help</ns1:modes>
          <ns1:windowStates xsi:type="xsd:string">wsrp:normal</ns1:windowStates>
          <ns1:windowStates xsi:type="xsd:string">wsrp:minimized</ns1:windowStates>
          <ns1:windowStates xsi:type="xsd:string">wsrp:maximized</ns1:windowStates>
          <ns1:locales xsi:type="xsd:string">en</ns1:locales>
        </ns1:markupTypes>
        <ns1:groupID xsi:type="xsd:string">wsrp4j-testportlet</ns1:groupID>
        <ns1:description
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test Portlet Description</ns1:value>
        </ns1:description>
        <ns1:shortTitle
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test</ns1:value>
        </ns1:shortTitle>
        <ns1:title
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test Portlet</ns1:value>
        </ns1:title>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP</ns1:value>
        </ns1:keywords>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J</ns1:value>
        </ns1:keywords>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">Test</ns1:value>
        </ns1:keywords>
        <ns1:usesMethodGet xsi:type="xsd:boolean">false</ns1:usesMethodGet>
        <ns1:userContextStoredInSession xsi:type="xsd:boolean">false</ns1:userContextStoredInSession>
        <ns1:templatesStoredInSession xsi:type="xsd:boolean">false</ns1:templatesStoredInSession>
        <ns1:hasUserSpecificState xsi:type="xsd:boolean">true</ns1:hasUserSpecificState>
        <ns1:doesUrlTemplateProcessing xsi:type="xsd:boolean">false</ns1:doesUrlTemplateProcessing>
      </ns1:offeredPortlets>
      <ns1:offeredPortlets xsi:type="ns1:PortletDescription">
        <ns1:portletHandle xsi:type="xsd:string">wsrp4j-testportlet.WSRP4JTestPortletB</ns1:portletHandle>
        <ns1:markupTypes xsi:type="ns1:MarkupType">
          <ns1:mimeType xsi:type="xsd:string">text/html</ns1:mimeType>
          <ns1:modes xsi:type="xsd:string">wsrp:view</ns1:modes>
          <ns1:modes xsi:type="xsd:string">wsrp:edit</ns1:modes>
          <ns1:modes xsi:type="xsd:string">wsrp:help</ns1:modes>
          <ns1:windowStates xsi:type="xsd:string">wsrp:normal</ns1:windowStates>
          <ns1:windowStates xsi:type="xsd:string">wsrp:minimized</ns1:windowStates>
          <ns1:windowStates xsi:type="xsd:string">wsrp:maximized</ns1:windowStates>
          <ns1:locales xsi:type="xsd:string">en</ns1:locales>
        </ns1:markupTypes>
        <ns1:groupID xsi:type="xsd:string">wsrp4j-testportlet</ns1:groupID>
        <ns1:description
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test Portlet Description</ns1:value>
        </ns1:description>
        <ns1:shortTitle
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test</ns1:value>
        </ns1:shortTitle>
        <ns1:title
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J Test Portlet</ns1:value>
        </ns1:title>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP</ns1:value>
        </ns1:keywords>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">WSRP4J</ns1:value>
        </ns1:keywords>
        <ns1:keywords
          lang="en"
          xsi:type="ns1:LocalizedString">
          <ns1:value xsi:type="xsd:string">Test</ns1:value>
        </ns1:keywords>
        <ns1:usesMethodGet xsi:type="xsd:boolean">false</ns1:usesMethodGet>
        <ns1:userContextStoredInSession xsi:type="xsd:boolean">false</ns1:userContextStoredInSession>
        <ns1:templatesStoredInSession xsi:type="xsd:boolean">false</ns1:templatesStoredInSession>
        <ns1:hasUserSpecificState xsi:type="xsd:boolean">true</ns1:hasUserSpecificState>
        <ns1:doesUrlTemplateProcessing xsi:type="xsd:boolean">false</ns1:doesUrlTemplateProcessing>
      </ns1:offeredPortlets>
      <ns1:requiresInitCookie xsi:type="ns1:CookieProtocol">perGroup</ns1:requiresInitCookie>
    </getServiceDescriptionResponse>
  </soapenv:Body>
</soapenv:Envelope>

So there two portlets availeble and they are identified by:

  • wsrp4j-testportlet.WSRP4JTestPortletA
  • wsrp4j-testportlet.WSRP4JTestPortletB

and the are actually the same portlet, that is portlet code but exposed twice to show of som IPC (Inter Portlet Communication) within a portlet group (portletapplication).



Initializing cookie Next the cookie is initialized
POST /wsrp4j-producer/services/WSRPBaseService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:9101
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "urn:oasis:names:tc:wsrp:v1:initCookie"
Content-Length: 442

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <initCookie xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <registrationContext>
        <registrationHandle>0:0:0:0:0:0:0:1_1173173104036_0</registrationHandle>
      </registrationContext>
    </initCookie>
  </soapenv:Body>
</soapenv:Envelope>
The response body is basicly empty since the cookie comes as a normal HTTP header
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=CD75D795F9463373DD7A0919DF0680E0; Path=/
Content-Type: text/xml;charset=utf-8
Date: Tue, 06 Mar 2007 09:25:03 GMT
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <initCookieResponse xmlns="urn:oasis:names:tc:wsrp:v1:types" />
  </soapenv:Body>
</soapenv:Envelope>
I don't understand why it's done this way since it's all webservice and not (legacy) browsers, so all clients will be WSRP aware, but I guess the spec writers wanted to stick with known protocols where possible, so the session handling between the consumer and producer uses normal HTTP cookies. Now discovery and initialization is done and the markup can be exchanged.

Give the markup for the portlet

POST /wsrp4j-producer/services/WSRPBaseService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:9101
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "urn:oasis:names:tc:wsrp:v1:getMarkup"
Content-Length: 1483
Cookie: JSESSIONID=CD75D795F9463373DD7A0919DF0680E0

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getMarkup xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <registrationContext>
        <registrationHandle>0:0:0:0:0:0:0:1_1173173104036_0</registrationHandle>
      </registrationContext>
      <portletContext>
        <portletHandle>wsrp4j-testportlet.WSRP4JTestPortletA</portletHandle>
      </portletContext>
      <runtimeContext>
        <userAuthentication>wsrp:none</userAuthentication>
        <portletInstanceKey>wsrp4j-proxyportlet_row2_col3_p3</portletInstanceKey>
        <namespacePrefix>Pluto_wsrp4j_proxyportlet_row2_col3_p3_</namespacePrefix>
      </runtimeContext>
      <userContext>
        <userContextKey>dummyUserContextKey</userContextKey>
      </userContext>
      <markupParams>
        <secureClientCommunication>false</secureClientCommunication>
        <locales>en</locales>
        <locales>de</locales>
        <mimeTypes>text/html</mimeTypes>
        <mode>wsrp:view</mode>
        <windowState>wsrp:normal</windowState>
        <clientData>
          <userAgent>WSRP4J Proxy Portlet</userAgent>
        </clientData>
        <markupCharacterSets>UTF-8</markupCharacterSets>
        <validNewModes>wsrp:view</validNewModes>
        <validNewModes>wsrp:help</validNewModes>
        <validNewModes>wsrp:edit</validNewModes>
        <validNewWindowStates>wsrp:normal</validNewWindowStates>
        <validNewWindowStates>wsrp:maximized</validNewWindowStates>
        <validNewWindowStates>wsrp:minimized</validNewWindowStates>
      </markupParams>
    </getMarkup>
  </soapenv:Body>
</soapenv:Envelope>

And here it comes (my not so pretty print)
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 06 Mar 2007 09:25:03 GMT
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getMarkupResponse xmlns="urn:oasis:names:tc:wsrp:v1:types">
      <markupContext>
        <mimeType>text/html; charset=UTF-8</mimeType>
        <markupString>
          &lt;h2&gt;URL Types Test&lt;/h2&gt;Time:Tue Mar 06 10:25:04 CET 2007&lt;BR/&gt;Current
          Mode:view&lt;BR/&gt;Current Window State:normal&lt;P/&gt;&lt;FONT
          SIZE=&quot;-1&quot;&gt;&lt;BR/&gt;&lt;B&gt;Render: &lt;/B&gt;Click here on &lt;A
          HREF=&quot;wsrp_rewrite?wsrp-urlType=render&amp;amp;wsrp-navigationalState=rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAAAeA**&amp;amp;wsrp-secureURL=false/wsrp_rewrite&quot;&gt;Render&lt;/A&gt;
          URL.&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Action: &lt;/B&gt;Click here on &lt;A
          HREF=&quot;wsrp_rewrite?wsrp-urlType=blockingAction&amp;amp;wsrp-interactionState=rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAGQUNUSU9OdXIAE1tMamF2YS5sYW5nLlN0cmluZzut0lbn6R17RwIAAHhwAAAAAXQAATF4&amp;amp;wsrp-secureURL=false/wsrp_rewrite&quot;&gt;Action&lt;/A&gt;
          URL.&lt;BR/&gt;&lt;I&gt;Group Scope :0&lt;/I&gt;&lt;BR/&gt;&lt;I&gt;Portlet Scope
          :0&lt;/I&gt;&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Resource: &lt;/B&gt;&lt;BR/&gt;&lt;IMG
          SRC=&quot;wsrp_rewrite?wsrp-urlType=resource&amp;amp;wsrp-url=http%3A%2F%2Flocalhost%3A9101%2Fwsrp4j-testportlet%2Fimages%2Fproject-logo.jpg&amp;amp;wsrp-requiresRewrite=false&amp;amp;wsrp-secureURL=false/wsrp_rewrite&quot;
          align=&quot;TOP&quot;/&gt;&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Namespace:
          &lt;/B&gt;Pluto_wsrp4j_proxyportlet_row2_col3_p3_someFunctionHere()&lt;BR/&gt;&lt;HR/&gt;&lt;B&gt;Navigation&lt;/B&gt;&lt;BR/&gt;Page
          1&lt;BR/&gt;&lt;A
          HREF=&quot;wsrp_rewrite?wsrp-urlType=render&amp;amp;wsrp-navigationalState=rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAHanNwTmFtZXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5-kde0cCAAB4cAAAAAF0AAl0ZXN0Mi5qc3B4&amp;amp;wsrp-secureURL=false/wsrp_rewrite&quot;&gt;Next
          &amp;gt;&amp;gt;&lt;/A&gt;&lt;/FONT&gt;
        </markupString>
        <locale>en</locale>
        <requiresUrlRewriting>true</requiresUrlRewriting>
      </markupContext>
    </getMarkupResponse>
  </soapenv:Body>
</soapenv:Envelope>


and the same for the other portlet (ending with B).

please send the image

The portlet has an image resource that's fetched and cached for the second portlet. The request is a simple HTTP GET request (without a body)

GET /wsrp4j-testportlet/images/project-logo.jpg HTTP/1.1
User-Agent: Java/1.5.0_10
Host: localhost:9101
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


and the answer is the jpeg image in binary so I'll not show that:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: W/"12241-1171550282000"
Last-Modified: Thu, 15 Feb 2007 14:38:02 GMT
Content-Type: image/jpeg
Content-Length: 12241
Date: Tue, 06 Mar 2007 09:25:04 GMT


and that completes the portlet page that the user sees.

Read more

Sunday, February 25, 2007

Pluto 1.0.1 and web-app 2.4

pencil icon, that"s clickable to start editing the post
I wanted to get started on using WSRP by the WSRP4J project at apache , and has ended up in non-productive try and fails and google searches. Long story short, to get started WSRP4J doesn't have a binary to start with and therefore i had to use it from the svn repo, to find out that it uses Maven, which i havn't used before. I did get it running after some time, and then i wanted to tryit on my own portlets. I've tried the 1.1 beta branch of Pluto, but WSRP4J still uses Pluto 1.0.1, and for days i've been hassling to get i running. Logging/debugging in Tomcat 5.5/6.0 still puzzles me (worth and entry of it's own) but the last piece that i've got working was after endless log entries like
Feb 25, 2007 12:34:26 PM org.apache.pluto.portalImpl.services.log.LoggerImpl error
SEVERE: Error in Portlet
java.lang.NullPointerException
   at org.apache.pluto.invoker.impl.PortletInvokerImpl.invoke(PortletInvokerImpl.java:109)
   at org.apache.pluto.invoker.impl.PortletInvokerImpl.load(PortletInvokerImpl.java:80)
   at org.apache.pluto.PortletContainerImpl.portletLoad(PortletContainerImpl.java:218)
   at org.apache.pluto.portalImpl.core.PortletContainerWrapperImpl.portletLoad(PortletContainerWrapperImpl.java:94)
   at org.apache.pluto.portalImpl.aggregation.PortletFragment.service(PortletFragment.java:120)
   at org.apache.jsp.WEB_002dINF.aggregation.ColumnFragment_jsp._jspService(ColumnFragment_jsp.java:76)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
   at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
   at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:505)
   at org.apache.pluto.portalImpl.aggregation.AbstractFragment.service(AbstractFragment.java:112)
   at org.apache.jsp.WEB_002dINF.aggregation.RowFragment_jsp._jspService(RowFragment_jsp.java:76)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
   at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
   at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:505)
   at org.apache.pluto.portalImpl.aggregation.AbstractFragment.service(AbstractFragment.java:112)
   at org.apache.jsp.WEB_002dINF.aggregation.PageFragment_jsp._jspService(PageFragment_jsp.java:85)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
   at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
   at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:505)
   at org.apache.pluto.portalImpl.aggregation.AbstractFragment.service(AbstractFragment.java:112)
   at org.apache.jsp.WEB_002dINF.aggregation.RootFragment_jsp._jspService(RootFragment_jsp.java:147)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
   at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
   at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:505)
   at org.apache.pluto.portalImpl.aggregation.AbstractFragment.service(AbstractFragment.java:112)
   at org.apache.pluto.portalImpl.Servlet.doGet(Servlet.java:254)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:212)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
   at java.lang.Thread.run(Thread.java:595)
I had an idea that web-app versions might be a problem, and had it running when i changed to version 2.3, I then changed it to 2.4 and redeployed and i still worked, but that was probably due to me lack of understanding on redeploying to tomcat. Any how it's also described in the mail archives (this from the google cache) Re: Supporting web.xml with 2.4 XSD The solution was to only put the version="2.4" attribute on the <web-app> tag and not the namespace information. Now I'll have to make sure everything else works without the namespace attributes. That's right for me as well. Now I'm not sure wether it'll actually run as a 2.4 web-app in tomcat, but time will show.

Read more