Thursday, October 25, 2012

Liferay: authorization of actions on dynamic data lists


Another feature you might want to include in your dynamic data list template, is that the edit button is only shown to users of a certain role. This, again, requires some thinking and trying, but I have done it for you. What I did, was get all the roles for the current user (through the user id in the request's theme display).
#set ($user_id = $request.theme-display.user-id)

#set ($roles = $serviceLocator.findService("com.liferay.portal.service.RoleLocalService").getUserRoles($getterUtil.getLong($user_id)))
Now, we can loop the roles, and set a variable if the user has a certain role.
#set ($can_edit = 'false')

#foreach ($role in $roles)
    #if ($role.name == 'Administrator')
        #set ($can_edit = 'true')
    #end
#end
Later in the template, we can than use the $can_edit variable to conditionally display the edit link.

Tuesday, October 23, 2012

Liferay: dynamic data lists record actions

I'm still working with Liferay 6.1, and more specific their dynamic data lists. A question I've encountered a lot, and just ran into, is how to display the action buttons of a record in a custom list template. I haven't found the answer online, so I started to try some things myself.

 I figured the solution would be a lot like in my previous post: using the generated URL. I again switched back to the default list view, and copied the URL for the 'Edit' action. Stripping it down, this is the result:
/your_page?p_p_id=169_INSTANCE_ToH96dipcgdr&struts_action=%2Fdynamic_data_list_display%2Fedit_record&cmd=update&redirect=%2Fyour_page&recordId=$record.getRecordId()
Notice the p_p_id is copied from the URL (you can also get it from the $request), while the record id is dynamically fetched from the resultset's current record. Another important parameter is redirect. Provide it with the URL of the page you're going to display your list on. It will make sure the user will return to that page after saving or canceling the edit action. If you forget this, the user is stuck on the edit page.

Wednesday, October 17, 2012

Liferay: dynamic data list detail

I've been working with Liferay 6.1's dynamic data lists for the last few days. I like how easy it is to create a CRUD system for data lists. The out-of-the-box functionality to display lists using the Liferay defaults and a custom VM-template is amazing.

To display a detail of a record, however, is a lot more painful. For some reason, there's no VM-template support there. So what I wanted to do, was the following:
  • Create a detail link in the list VM-template
  • Let the detail page display my own custom page
Not all that much asked, I'd think, yet this was NOT easy to achieve in Liferay. The documentation in this area is very limited, and basically only covers the creation of a list-template. So, first things first, I created my custom list-template using the Liferay documentation, and my dynamic data list looked good.

Of course, I wanted links in that list, to click through to the details of a record. This was the first difficulty I encountered. I couldn't find any clues or documentation on how to get the correct link. So what I did, was switching the list view back to 'default', and copied the link URL there. It looked really, really ugly.

I then started to dissect that URL. I concluded that there's lot of parameters I didn't need, so I stripped it down to the bare minimum: the portlet ID, a struts action and a record ID. The portlet ID and struts action can be copied from the URL the default list provides, the record ID is dynamic and can be fetched using $record.getRecordId(). My URL looked like this:

/your_page?p_p_id=169_INSTANCE_ToH96dipcgdr&struts_action=%2Fdynamic_data_list_display%2Fview_record&recordId=$record.getRecordId()
This of course redirects to the default detail page, which might be OK for adding and editing records, but not for displaying them in an enterprise application. I somehow had to either edit the detail page, or find a way to redirect the detail-link to another page.

That was the second obstacle. Editing the detail-page wasn't really an option, since it would then be altered for ALL detail pages of all records, not just the ones I wanted to display at that time. With that idea out of the way, I had to find a way to make the detail URL redirect to a custom JSP. Therefor, I had to create a new struts action, and map it to a new JSP I also had to create.

The easiest way to do that is using a hook. In that hook, we need to do 3 things:

  • Create an Action class (extending from BaseStrutsPortletAction)
  • Create a custom JSP
  • Map the Action class to a certain path
The last one is the easiest: simply add this to your liferay-hook.xml

  /dynamic_data_list_display/view_office
  be.c4j.hook.action.SomeAction
 
This means you have to change the struts-action parameter in your detail-url to %2Fdynamic_data_list_display%2Fview_office. Of course, we also need to define the SomeAction class.

import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.util.ParamUtil;

import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;

public class SomeAction extends BaseStrutsPortletAction {

 @Override
 public String render(PortletConfig portletConfig, RenderRequest renderRequest,
   RenderResponse renderResponse) throws Exception {
  
  long recordId = ParamUtil.getLong(renderRequest, "recordId");
  
  DDLRecord record = DDLRecordLocalServiceUtil.getRecord(recordId);
  
  renderRequest.setAttribute("ddlRecord", record);
  
  return "/portlet/dynamic_data_lists/view_office.jsp";
 }
}

Now all you have to do is build the JSP. Make sure you place in the folder $customs_jsps$\html\portlet\dynamic_data_lists. In the JSP you can access the ddlRecord attribute.

<%
DDLRecord record = (DDLRecord)request.getAttribute("ddlRecord");

%>; 

This is a field of our record<%= record.getFieldValue("fieldName") %>;

If you know what to do, it isn't all that hard, but it took me a lot of time to figure this out. Liferay offers a lot of out-of-the-box functionality, but sometimes you have to go through a lot of trouble for adding just that little extra.

Thursday, October 4, 2012

Oracle Open World - thursday

Last day of the conference... Not a lot of sessions today (only 1 and the Java community keynote), but we've subscribed to a trip to Oracle HQ this afternoon. We're getting a tour in their usability labs.

But first things first. I started my day with the Java community keynote. It was mainly about innovation, and some cool demos of robots (by Perrone Robotics) were given. In the end, James Gosling entered the stage and showed us what he is currently doing: Liquid Robotics. Medium-sized robots that roam the seas and gather data.

Then I went to an ADF session by Eugene Fedorenko. He took us through the process of developing an ADF application. During his 'deep dive', he showed us how to programatically create entities and view objects, end display them on the screen. I found it a bit odd to do everything programatically, instead of using the declarative strength of the framework, but I'm sure that in some cases this will turn out to be the best way.

On to Redwood City then. Oracle took us on a tour in their usability labs. They showed us how their apps are tested and evaluated using some advanced eye-reading techniques. An interesting afternoon, as closure for a very interesting conference. I learned a lot, saw some very nice demos and met interesting people. All in the lovely setting of San Francisco.


Wednesday, October 3, 2012

Oracle Open World - wednesday

Another day in San Francisco! Today's sessions are mainly about deveoping apps in the cloud, but there's also some ADF and an ADF Meetup tonight. I saw my early morning session about Java Heap and memory usage cancelled, so I used the extra time to go running in a San Francisco where the sun was just coming up. Lovely!

Develop apps with Oracle database cloud services (Rick Greenwald)

This session was presented to us by Rick Greenwald, director of Projectmanagement at Oracle Cloud. It didn't really tell me anything new. It was more of an APEX session than a cloud DB session. Rick gave a demo of an APEX application, running in the cloud.

One thing I noticed, though, was that the Oracle cloud DB only supports 1 schema. And that it's expensive. Pricing is $175 a month (for 5GB storage, 50GB would be $2000 a month). If you consider it includes everything (license, server, support, ...), it's not all that much, but if you take into account you can get a 5 GB MySQL cloud database, $175 is quite a lot. There's also a data transfer limit of 6 times your storage. Rick however told us that they will be monitoring the traffic (to avoid DOS attacks), but won't undertake any immediate action upon exceeding.

Another issue is that when you want to access your database from outside Oracle cloud, you'll have to use RESTful services. SQLDeveloper has a cloud connector built in these days, so you can still easily connect to your database. But if you want to connect another application (not running in Oracle cloud) to your cloud database, you need to expose your queries to REST web services. We were shown this is quite an easy process, though, but you really don't want to do this for larger applications.

I think Oracle Cloud has a lot of potential, but also a lot of limitations. You'll be kinda forced to use a full Oracle stack if you want to have all the benefits. Of course, if you just intend to write an APEX application, one Oracle cloud database can work wonders.

Developing with cloud services (Chris Richardson)

Chris Richardson is the founder of Cloudfoundry. He presented a very nice session on using cloud services. He used an application he wrote as guidance through the session: VoteMeetEat.com. The concept is simple: you text the word 'register' to a certain number, you get a confirmation SMS with an URL, you subscribe to that URL and you're in the program. The idea is to find restaurants and friends nearby. Anyone can then vote on a restaurant of their choice, and a group of friends can meetup at the highest voted restaurant.

To vote, you have to call a certain number, and based on your location it reads you the available restaurants. You vote by using your keypad. All participants receive a text message with the results. If you have to all write this by yourself, it would take months to get it done. And it would be a huge headache. So Chris takes advantage of cloud services, in this case for location, data and telephony.

In the demo he gave, he showed the different services he used. As a database to store friends in, MongoDB was used. It has an integration with CloudFoundry, so it's easy to use. Then, to find the restaurants nearby, a 3rd party service named Factual was used. Based on the geolocation of your phone, the Factual API returns a list of restaurants, and their information.

The most difficult part to setup and maintain yourself, though, is telephony. Setting up a database isn't all that difficult, but setting up your own telephony provider and maintaining it, doesn't sound like something you'd want to do yourself. And then we didn't even mention the complex protocols. So Chris has Twilio to do that for him. You talk HTTP to Twilio, Twilio handles all the complexity of the telephony. It's on a pay per use basis, so if your app is rather small, it's not all that expensive.

The VoteMeetEat application is a very nice example of how cloud services can be used to make the life of the developer a lot easier. And to lower development , hardware and maintenance costs.

Tuesday, October 2, 2012

Oracle Open World - tuesday


This day, I have done a lot of sessions on something I've been waiting for for quite a while: ADF Mobile. I won't discuss each session seperately (since it's all on the same topic), but I'll just give my general view.

First, it's worth noting that ADF Mobile really looks promising. The idea that you develop 1 application and then deploy it to different platforms, is really good. You build an app, then deploy it to Apple's App Store or Google's Play. Or both. Without having to deal with either Android specific stuff or Objective C. Pretty neat. Also, ADF Mobile makes sure your app is future proof. If Windows 8 turns out to be a huge hit, or any other OS that might appear in the future, ADF Mobile will have support for it.

All of this is possible because of an HTML5-based user interface. Below that, ADF Mobile uses PhoneGap to acces the device specific services. Build once, deploy everywhere. I did an hands-on session today, where we built a simple ADF Mobile app and deployed it to both iOS and Android, and I must say it works pretty good. The look and feel is generally the same and all of the functionality you build in is available in both versions.

Apart from that, I've seen quite a few demos on ADF Mobile. Or rather: demo. All presentations use the same demo app. I must admit, it looks definitely great, but seeing the same stuff over and over again gets dull after a while. Therefore I was very happy to see a real-world application demo by Infosys. They have built a mobile app using ADF Mobile for one of their customers. It's good to see the theory also appears to work in a real business usescase. The app also looked good, so I'm even more eager to get started with ADF Mobile myself now!

Monday, October 1, 2012

Oracle Open World - monday

This year, I have the privilege of going to one of the biggest conferences in the world: Oracle Open World. If you look at the numbers... they're pretty huge! During this week, I'll try to keep you posted on the most interesting sessions I followed. There'll be a short summary, and my personal thoughts and views.

Why should you switch to Java 7 (David Keenan, Staffan Friberg)

Summary

The presentation was a summary of, as the title says, why you should switch to Java 7. I'll just sum them up again!

JCommands
Garbage First
Runtime compiler improvements
Sockets Direct Protocol
Performance benefits to
  •    Date
  •    BigDecimal
  •    Crypto
  •    String to byte conversion
  •    concurrency API
  •    Hotspot JVM
  •    PermGen
  •    Internal strings
  •    XML API
Backwards compatibility (source, binary, behavioural)
Heap retuning

My thoughts

Not really a very innovating session, just a sum up of what's new in Java 7 and what's to come in Java 8. A good review, though, and makes you think of upgrading.

Future of development for Oracle Fusion (Chris Tonas)

Summary

Chris gave a demo using ADF Faces. It was a  typical ADF application with fancy graphs and components. Then he showed us the same app, but on an iPad. It had the same functionality, but HTML5 instead of Flash. It also had a slightly different layout and supported gestures and touch. The pagination in tables we so liked in ADF 10g has returned (in an  im:proved way), to avoid scrollbars.

He then talked about the iOS and Android SDK support in JDeveloper, and the visual preview of the app you're building. Apparantly, you build an ADF app once, and then deploy it to Android and/or iOS (and any other vendor Oracle decides to support). Pretty convenient! Further, Chris discussed offline support and gave an ADF Mobile demo. This time, it was a native iOS app, which I thought was pretty impressive.

To end the Mobile part, Thomas Quilligan presented a real-life case. He is from Accenture, an ADF Mobile Beta Program Partner. It was nice to see the Oracle ADF Mobile technology being used in a real-life project.

After that, we moved on to the Cloud part of the talk., with a strong focus on Developer Cloud Service. These are some of the out of the box services that the Developer Cloud offers:
  • Source control
  • Maven support
  • Issue tracking
  • Continuous Integration (Hudson) 
  • Wiki




The demo of the Developer Cloud Service that followed, was very nice. It showed the full development lifecycle, all brought to the cloud, organized in neat dashboards.






My thoughts

This was a very nice presentation. The ADF Mobile still looks promising, and appears to be finally released soon. The cloud part really surprised me. I've been waiting for Oracle Cloud for quite a while now, but I didn't know they were going to offer something like the Developer Cloud. I really liked that. If it all integrates as well as in the demos, this will definitely be a product I'd want and like to use!

Oracle's public cloud strategy (Abhay Parasnis)

I'm writing an article about this session on Cloudspring. I'll update the link as soon as it gets published.

Classic mistakes with ADF (Frank Nimphius, Duncan Mills)

This was a nice light session about some of the most made errors with ADF. Driven by real examples and questions, Duncan and Frank guided us through. I'll add the slides as soon as they're available, since writing it all out seems a little pointless.

I'll just give a bit more details about one of the errors discussed. It's one we ran into as well, and Frank and Duncan categorized it as 'silent, but deadly' (as opposed to 'unforgiveable' and 'bear traps'). It's about using a bean that is not request scope, but that contains references to UI components. The problem here is that UI components only last as long as a request. They are therefore not serializable, and any bean with a scope higher than request, will want to serialize all it's variables.