Weblog

Nokia joins Eclipse Foundation for developing a Mobile IDE Framewok

On Nokia Press, I read an interesting announcement by Nokia. Nokia announce in this press release that it will join the Eclipse foundation a strategic partner. It will lead the development of a framework for developing mobile Java application.

I wonder how optimized this new development framework would be for developing mobile Java applications for Nokia devices.

However, this partnership illustrates that Nokia believes in the growing market of mobile application development.

Invoking a PL/SQL webservice using WSIF

We want to invoke the following procedure in our Customer package:

PROCEDURE GETCUSTOMER
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 P_CUSTOMERID                      NUMBER                  IN
 P_CUSTOMER_OT                     RLE_CST_OT              OUT
 P_SERVICE_MESSAGE_OT              RLE_SERVICE_MESSAGE_OT  OUT

As you can guess, this procedure fetches a customer (encoded as an oracle object type rle_cst_ot) by its customer ID. It also returns the status after the call, by using a service message (object type rle_service_message_ot).

The package is deployed as a webservice.
In order to use the procedure ‘getCustomer’ in a struts action class using WSIF, the stubs and skeleton classes first have to be generated.
Tom has described how to do this using Axis in an earlier blog.
Note that in this example only the generated PortType class and the two classes that implement the object types rle_cst_ot and the rle_service_message_ot need to be included.

In order to invoke the webservice we use the following code:

try{
// create a service factory
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
factory.cachingOn(true);
WSIFService service =
factory.getService(
 "http://customer.cmp.nl:7779/relationService/RelationWS?wsdl",
 null,  //service namespace
 null,  //service name
 null,  //portType namespace
 null); //portType name

Because we use custom types (‘rle_cst_ot’ and ‘rle_service_message_ot’), we have to map the types to a class which handles these types:

service.mapType(new QName("http://nl.cmp.services/RelationWS.xsd",
"nl_cmp_services_RelationWSImpl_getcustomer_Out"),
Class.forName(
 "services.cmp.nl.RelationWS_xsd.Nl_cmp_services_RelationWSImpl_getcustomer_Out"
 ));                          

service.mapType(new QName("http://nl.cmp.services/RelationWS.xsd",
"nl_cmp_services_RleServiceMessageOtUser"),
Class.forName(
  "services.cmp.nl.RelatieWS_xsd.Nl_cmp_services_RleServiceMessageOtUser"
 ));

Now we can construct the call and handle the outcome:

//create a porttype object to invoke the procedure
RelationWSPortType pt =
   (RelationWSPortType) service.getStub(RelationWSPortType.class);

//get the customer number as a session attribute

String customernrStr = (String)session.getAttribute("customernr");
   if (customernrStr.compareTo("-1") == 0)
      {
        sp.addActionError(errors, "nl.company.error.noUser",null);
        saveErrors(request,errors);
        return mapping.findForward("failure");
       }

//A number variable in PL/SQL is converted to a BigDecimal
//so we have to cast the customernrStr as a BigDecimal

BigDecimal customernr = new BigDecimal(customernrStr);

//now we can get the customer
Nl_customer_services_RelationWSImpl_getcustomer_Out customerOut =
             pt.getcustomer(customernr);

//The servicemessage returns a service code.
//If the code is 0, the call was successful.
if(customerOut.getPserviceberichtotOut().getServiceCode().intValue()==0)
      {
        Nl_cmp_services_RleKltOtUser customer = customerOut.getPcustomerotOut();
        dForm.set("lastname", customer.getLastname());
        dForm.set("shortname", customer.getShortName());
          ..

      return mapping.findForward("success");
     }
//Something has gone wrong
          else
          ..

The methods used in the code above can throw a WSIFException, RemoteException, ClassNotFoundException so these have to be catched.

Interesting State Of Direction Oracle Lite

Recently, Oracle announced in a new Statement Of Direction that it will enhance Oracle Lite with the ability of background synchronization.

According to the Statement Of Direction, background synchronization eliminates the requirement for users to explicitly initiate the synchronization process. The synchronization proces will be triggered by several events. One event that will trigger the synchronization process is network recovery detection by the Mobile Client.

I think this Statement Of Direction will improve the usability of mobile applications using Oracle Lite, because the user now doesn’t need to care about data synchronization issues, even when the client lacks network coverage!

I wonder in which new release of Oracle Lite this feature will be implemented.

Internet explorer developer toolbar

One of the reasons I use Firefox is it’s web developer extension. It’s pretty hard to develop webpages without it. Last week Microsoft released a similar plugin for Internet explorer: Internet Explorer developer plugin. It’s actually a combination of the web developer extension and Firefox’s DOM Inspector. Good news for people stuck on Internet Explorer. Here’s a screenshot:

Internet explorer developer toolbar

Get User information in your portlet

When developing portlets you mostly want to have Oracle Single Sign On handle the authentication of users. If your portlet requires user information you have to get that from either the Single Sign On service or using LDAP.

To request a username in your portlet you can use the following code:

PortletRenderRequest prr = (PortletRenderRequest)request.getAttribute
  (HttpCommonConstants.SERVLET_REQUEST);
ProviderUser pu = prr.getUser();
//Now you can get userinformation from the ProviderUser object.
//If a user is not signed in the username is PUBLIC
String name = pu.getName();
Boolean isDBA = pu.isUserInGroup('DBA');

If you need to get more user information, or information about other users than the one logged in you have to get a LDAP connection to the Directory where your user information is stored. This example will explain how to connect to the Oracle Internet Directory. To get this connection you have to:

  • be able to reach the LDAP server (at the LDAP port)
  • have an user account which can search the Directory tree.

You can use the oracle.portal.provider.v2.oid.OidManager object to query the OID. Before you can construct this object you need to do the following things:

  1. Implement a subclass of interface OidInfo
    Write your own Init() implementation which has to gather credentials for a user to login to OID. This user needs to have sufficient rights to browse the Directory. Make sure these credentials are stored safely. You also have to specify where the OID is located (address, port). Oracle provides a example implementation called UnsafeOidInfo, which as the name says is unsafe to use in a production environment because it gets the required information from your property file unencrypted.
  2. Enable the OidManager in you properties file: /WEB-INF/deployment/application.properties.
    Here you have to tell the application that the OidManager class may be used by setting it true. You also have to specify your subclass of the OidInfo Interface

    oidManager=true
    oidAdminClass= oracle.portal.provider.v2.oid.MyOidInfo
    

    (When this doesn’t work try specifying these lines in the default.properties file aswell).

Now you are able to construct the OidManager object:

OidManager oidman = new OidManager( prr.getProviderInstance().getProviderContext() );

//get any information from the Oid using the getUserProperty function
oidman.getUserProperty(pu.getUserDN(), pu.getSubscriberDN(), "description" );

Integrate Dreamweaver with NetBeans

On this NetBeans site, I found an interesting new feature of NetBeans IDE. You are now able to integrate Netbeans with Macromedia Dreamweaver MX. This enables you as a developer to visual enhance the jsp pages in the Dreamweaver, while developing the page logic in NetBeans.

Dreamweaver can be set up to edit JSP files in your NetBeans project directory, and it can automatically keep those files synched with your build files. You will be able to initiate previewing your JSP pages from the NetBeans IDE as well as from Dreamweaver using the built-in Tomcat server.

I think that this is really benefical when your development team contains page designers, which are experienced in using Dreamweaver, but know nothing about JSP.

ADF improvements in JDeveloper 10.1.3-EA1

I just downloaded Jdeveloper 10.1.3 Early Access 1 to see what ADF improvements have been implemented. The list of new ADF features is pretty big. ADF data binding is now supported for ADF Faces (JSF), control hints can be specified for all data models, whereas previously you could only do this for data models based on Business Components, and many more improvements.

On the project I’m currently working on (dutch) we’re using ADF data bindings to bind a POJO data model to a Swing GUI so I’m especially interested in any improvement in this area. The current production version of ADF has some serious limitations when you use it in combination with a POJO data model. For example, you can’t easily disable a JComboBox. If you disable it, ADF will automatically enable it, because the underlying datacontrol is editable. And this is something you can’t change in the current ADF release: POJO data controls are always editable. This is one of the things which has been improved in the new version of ADF (see Control hints).

After running JDeveloper 10.1.3-EA1 for only a couple of minutes it’s pretty obvious ADF has changed quite extensively. Data controls have a lot more properties where you can specify label text, visibility, etc. I’ve made some screenshots to show the enhancements. First a screenshot displaying the properties of a POJO based data control attribute:

ADF data control properties

When you double click the attribute in the data control structure view the following dialog is displayed. Here you can edit control hints, validation rules (more later), and custom properties:

ADF control hints

The following screenshot shows the rule editor. This has been available for Business Components for a long time, but now you can create rules for POJO attributes. Very nice, actually better than i expected.

ADF rule editor

The rule is stored in the xml file created for the data control. Also new is the fact that you can store messages and labels in a resource bundle. Again, this functionality previously was only available for Business Components. The following screenshot shows the project files, including the generated resource bundle:

ADF project with resource bundle

One last screenshot, showing a data control in the structure view. You can see that the rule is also displayed in the structure view. You can edit the rule in the property editor.

ADF rule properties

So it looks like the next release of ADF will be a great improvement, and ADF finally supports data model frameworks other than Business Components. This also means that many of the current benefits of Business Components over Toplink (business rules, display controls) will also be available in Toplink (and other data models).

My only complaint is that Oracle should release production versions more often. I had expected Oracle to release a production version this week, but instead we get another preview/early access. Is Oracle going for a Google strategy, forever releasing beta’s?

Constraint checking with materialized views

For constraint checking on the database where you have to query other records in the same table or other tables, consider the use (or misuse ?) of materialized views :

  • Create a materialized view with a fast refresh on commit with the relevant query to check (mostly with an aggregate function)
  • Add a check constraint to the MV

Example (on 10.1.0.4.0, but should also work on 8.1.7) :

Constraint
Consider table p which is the parent of table d : For each p there may only be one record in d with default=’Y’.

create table p ( p_id number )
/
create table d ( p_id number, d_id number, deflt varchar2(1) )
/
create materialized view log on d
with rowid (p_id, deflt)
including new values
/
create materialized view d_mv
build immediate refresh fast on commit
as
select  p_id, deflt, count(*) aantal
from d
where deflt = 'Y'
group by p_id, deflt
/
alter table d_mv
add constraint d_mv_ck1
check ( aantal <= 1 )
deferrable
/

insert into p values (1)
/
1 row created.

insert into d values (1,1,'Y')
/
1 row created.

insert into d values (1,2,'N')
/
1 row created.

insert into d values (1,3,'Y')
/
1 row created.

commit;
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (TIK.D_MV_CK1) violated

This could also be solved with associative arrays and database triggers (at least 3), but those checks are always done at statement time. So, if your are switching the defaults in table d between 2 records, and you have no control on the sequence of update statements, then the first statement may be violating the constraint. Also the trigger solution requires more code.

There is a drawback however, a materialized view will cost more diskspace. And I am not sure about the performance, you should benchmark it first before implementing it. On relatively small tables (<10.000) I found no differences.

With this ‘trick’ you can now solve the chicken-egg problem in the database which is impossible to solve with databasetriggers alone : a parent must have at least 1 detail.

BPEL Cookbook published

Today Oracle published SOA Best Practices: The BPEL Cookbook on it’s website. It provides some good insights. In order to minimize dependencies between data and logic, is a good idea to separate both the process definition and the implementation of business rules from the data. There is a recipe provided for this in Kevin Geminiuc’s article A Services-Oriented Approach to Business Rules Development.

Scott Berkun switches to Firefox

I’m currently reading Scott Berkun’s book The Art of Project Management. Scott was a project manager at Microsoft for many years. While working for Microsoft he also worked on the Internet explorer project, so it’s pretty interesting that he switched to Firefox. Read his blog: Why I switched to Firefox. Btw, I haven’t finished reading his book yet, but so far I can recommend it.

Technology
Ben jij slim genoeg voor IT-eye