12/30/2011

Activiti and Spring

I am currently starting to work myself into Alfresco Activiti, which is, by the way a great process engine that you can use from and in liferay.


The following problem might occur to you if you are working with Spring and Activiti:


You can use the activiti designer in eclipse to connect several steps in your activiti process to one process chain like "unzip files", "inpect unzipped files" and "copy inspected files to fileserver".


To do so, you can either use the simplest approach: Specify a Java Class (extending JavaDelegate) for your Service Task, connect all tasks by a Sequence Flow and let activiti do the calling. In this way you have access to the DelegateExecution object that lets you (for example) share variables across your process.


This will work, and every class will get called, but your spring configuration will be totally ignored.


If you decide to work with the "Expression" type, you need to define your Task in your Spring config and then you have all the spring injection magic that you like. But how do you get the DelegateExecution object in it?


I found out that "execution" is a reserved word in activiti and if you want to have an expression that just calls the standard execution(DelegateExecution execution) method, you can do it simply like this:


#{yourTask.execute(execution)}

This is how it will look like in your Eclipse Designer:

Eclipse Designer: Adding Expression


That´s all: You have your Spring injection AND you have the DelegateExecution object.


If you got interested and you are thinking about taking a look into Activiti (it´s free by the way!), you can do so here: http://activiti.org/


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

12/22/2011

Xmas Break

This blog will pause for at least 2 weeks because the author is in desperate need of christmas !


I am wishing all my readers happy holidays and a happy new year.


I hope to see / read all of you next year for some intense Liferay 6.1 and ICEfaces 3.0 stuff !!!


Daniel Breitner



12/02/2011

Connecting Liferay to Facebook

Welcome to Part 2 of my series on how to connect liferay to social networks. The Last time I showed you how to do it with linkedIn, this time we will take a look into the facebook integration.


Everything that I said about linkedIn also goes for facebook: you need to know your business use cases to know how to integrate it. All I can do is to sho you how to connect to facebook. If you need asisstance, or if you need someone to help you programming in liferay you can book me by sending me an email, or adding me on linkedIn or Skype.


The first step to connect your liferay instance to facebook is to create a developer account. You can do so here: http://developers.facebook.com/. If you need any assistance during your authentication process to facebook you can either ask me or take a look here: http://developers.facebook.com/docs/authentication/.


After you did that, you will have an API key and a secret passcode. That´s like a user / password combination. Add yourself as developer to your app and everybody else who wants to take part in the development.


The next step is to choose a java library that will help you to get the data our of facebook or simply connect your liferay instance of it. I chose restFB, which you can find here: http://restfb.com/.


The general authentication flow is as follows: Redirect the user on his first visit to your app to the authentication URL of facebook and let him accept your app. Then, the flow will return to your servlet, portlet or java application. You can then use the oauth verifier to get the access token from facebook which you can store and reuse.

Redirecting the user


It doesn´t matter, if you use Servlets or portlets as long as you have access to request parameters. if you are using JSF portlets, you can look up how to access request parameters in my blog.


So, the first step will be to redirect the User to facebook to let him accept your app. You can do so by using the following snippet:
String connect = "https://www.facebook.com/dialog/oauth?client_id="
+ Facebook.api_key "&redirect_uri="
+ REDIRECT_URL + "&scope=email,read_stream,offline_access";

response.sendRedirect(URL_USER_CONNECT);
Let´s go through this snippet in detail. The first two lines are pretty straight forward: Redirect the User to the facebook oauth page and provide your api key. Then you need to specify a redirect URL. This won´t be a complete URL but instead a path that will be added to the canvas URL you have specified in your facebook developer signup. If you didn´t specify a URL back then, then please do it now. Specify it like http://your-ip and provide the path as redirect URL like /your-facebook-app/your-servlet.
The last thing you have to provide are the rights (= scope) you want to have for your facebook app. All scope types can be found here: http://developers.facebook.com/docs/reference/api/permissions/


The last thing you do is to send the redirect. The User is transported to facebook, needs to accept your app and transported back to your redirect URL.

Get the access token


If the authentication flow returns to you page, you have access to the authentication code:
String code = request.getParameter("code");
This code will be used to get the authentication token. You need to connect to the following URL:
String urlAuthToken= "https://graph.facebook.com/oauth/access_token?client_id="

+ Facebook.api_key+ "&redirect_uri="+ REDIRECT_URL+ "&client_secret="+ Facebook.secret + "&code="+code;
If you perform a GET request to this URL, you will receive the authentication token. This token you need to store and reuse every time your user wants to login  or update some data.
Here is an exemplary call to facebook to get the first- and lastName of a User:
FacebookClient facebookClient = new DefaultFacebookClient("your-authentication-token);
User user = facebookClient.fetchObject("me",User.class);
log.info("Got last name:" + user.getLastName());
That´s all. Now you must decide how to integrate facebook into your liferay portal. If you need help - just contact me by mail (daniel.breitner32@googlemail.com) or skype(daniel_breitner).




If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

11/24/2011

How to find out on which page your Web Content is displayed

Think about the following problem:


You created a WebContent and within one of your portlets you need to find out where this WebContent is displayed (using Journal Article Display portlets). Sadly, there is no convenience method for this, so we have to biuld our own. We will do this using dynamic queries.


First we are going to get all portlet preferences that have been saved by portlet "56" (which is the Journal Article Display Portlet) and contain the ID of the Web Content we are looking for. This is exactly what is written into the database if you are selecting a WebContent in the WebContent Display portlet. I haven´t found another way to get the info.


Once we have the portlet preferences, we use their "plid" property to get the layouts (= Liferay pages) the portlet is deployed on. And that´s it. You can for example use the friendly URL to navigate to that page.


//create query to retrieve Layouts

DynamicQuery layoutQuery = DynamicQueryFactoryUtil.forClass(Layout.class, PortalClassLoaderUtil.getClassLoader());

//create query to retrieve portlet preferences

DynamicQuery preferencesQuery = DynamicQueryFactoryUtil.forClass(PortletPreferences.class, PortalClassLoaderUtil.getClassLoader());

//tell preferences to look for instances of portlet "56" with the journalArticle in its preferences

preferencesQuery.add(RestrictionsFactoryUtil.like("portletid", "56 INSTANCE%"));
preferencesQuery.add(RestrictionsFactoryUtil.like("preferences", "%<name>article-id</name><value>"+journalArticleId+"</value>%"));
preferencesQuery.setProjection(ProjectionFactoryUtil.property("plid"));

//just return the layouts that have the plid set for the ones we retrieve in the preferences query

layoutQuery.add(PropertyFactoryUtil.forName("plid").in(preferencesQuery));

//get the data

List dynamicQuery = PasswordPolicyLocalServiceUtil.dynamicQuery(layoutQuery);



If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

11/08/2011

Solr: Q.Op default value

Currently working with Solr. As you know, you can use Solr as primary search engine in your liferay environment. One thing that might be interesting to you is the fact what the Q.OP operator does. The Q.OP operator specifies the "connector" between your search terms. Possible values are AND and OR.

I took a look into google and found no entry for "q.op default value", so here it is: The default value is ... up to you ;)


You can specify it in your schema.xml file like this:



 <solrQueryParser defaultOperator="OR"/>


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

10/31/2011

Connecting Liferay to LinkedIn

Whenever you think about using liferay in your business you will surely think of it as an "integration platform": One platform to integrate all the information sources that matter to your customers.

In this blog post we will look at how to integrate LinkedIn into your portal. In one of the next posts we will do the same with facebook, but today we will care about the world´s leading business network.

When we talk about integration we mean: "Getting the Data". Liferay always expects to have the users data in its user table and it doesn´t make any sense to rip that core functionality out of liferay. Our goal is to get you connected to linkedIn, so that you have the following possibilities


  • Authenticate with linkedIn
  • Import data from linkedIn

Preparation


Our first step will be to allow your liferay instance to connect to linkedIn.
To do so, you need to create an application for linkedIn. If you already did that, you can skip this step and continue with step 2.

To be able to connect to linkedIn (no matter what you do) you need to create a linkedIn application. 

Enter all necessary data and create your linkedIn application. If you do so, you should now have an API - Key and a secret password. You need those to create the OAuth authentication flow that is needed to authorize your application to access the data of the users.


What business case ?


Something that you should know before even registering your app at linkedIn is what you want to do with the data you get on linkedIn. Your use cases define the way you need to change or configure the liferay implementation. You might



  • Show job offerings in an own portlet
  • Send linkedIn messages from liferay
  • authenticate the User with linkedIn



etc etc etc 


There is a lot you can do. So think about it, and when you are ready, go on to step 3


Accessing LinkedIn


There are many ways to connect to LinkedIn, but I am only going to show one here. There is a pretty good java API available under http://code.google.com/p/linkedin-j/. It seems to be pretty up to date, still under development and (as far as I could see) offers access to all the data LinkedIn provides.

Download the latest version and put all the jars either into the lib dir of your application server or into WEB-INF\lib of the portlet you are developing. Now you should think about how to implement the OAuth flow for linkedIn (facebook is the same ...). The OAuth authentication mechanism basically consists of two steps:

Get the user-specific access token for every user by letting them autorize your app.

Use the access token to get their data from linkedIn.

The first step is something that can be done pretty good in a servlet because it requires some back - and forth communication between the linkedIn and your server. But if you have all the parameters from your portlet at hand, I am sure you can also embed it into a portlet. The code to let the User authenticate your app at linkedIn is the following:


// Create the oauthService

final LinkedInOAuthService oauthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(your-consumerKey, your-consumerSecret);

//Create the request token to get the autorization URL. You need to specify
//a Callback URL. That´s the URL where the auth token is forwarded to
LinkedInRequestToken requestToken = oauthService.getOAuthRequestToken(CALLBACK_URL);
String authUrl = requestToken.getAuthorizationUrl();

//forward to authorization page
resp.sendRedirect(authUrl);

By implementing this, the user should be transported to the LinkedIn page where he has to authorize your app. If he accepts, he will be transported back to the CALLBACK_URL you specified and you will then have access to his access token. To get his access token, implement the following:

// Get the OAuth Verifier from the request
String oauthVerifier = req.getParameter("oauth_verifier");

//create the oauth service
final LinkedInOAuthService oauthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(your-consumerKey, your-consumerSecret);

//Create the request token 
LinkedInRequestToken requestToken = oauthService.getOAuthRequestToken(CALLBACK_URL);
String authUrl = requestToken.getAuthorizationUrl();

//finally: The access token !!!
LinkedInAccessToken accessToken = oauthService.getOAuthAccessToken(requestToken, oauthVerifier);

If you have this access token, you´re done. You don´t need more to access all fields of the user. Persist this access token somewhere in your database and retrieve it every time you need to update your data. Here is an example of how to get the Users first name:

LinkedInConnector connector = new LinkedInConnector();
LinkedInApiClient client = connector.connect(accessToken);

Person profile = client.getProfileForCurrentUser();
System.out.println("First name: "+profile.getFirstName());

That´s all! All you need to do now is to define your business use case and get all the fields you need. Contact me if you need any assistance.


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

10/29/2011

How to get Request Parameters in your JSP

I think, you know the problem: You have a link to a portlet site that expects a request parameter.
Example: http://localhost:8080/web/guest/page?customer=JohnDoe


How do you get the customer name in your JSP ? Just use this: 


PortalUtil.getOriginalServletRequest(request).getParameter("customer" )



If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

Creatting an XSD from an XML instance

Currently very busy finishing up some work for a client. I´ve searched a lot for a tool that allows me to create an XSD (XML Schema) from an XML file. I finally found "Trang". You can get it here: http://www.thaiopensource.com/download/
(newest version as of today is trang-20030619.zip )

And this is how you use it:

from your command line, simply type:

java -jar trang.jar yourXMLFile.xml new.xsd.

That´s  it ! Just great !


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

10/23/2011

Liferay URL Parameter details

Whenever you have used liferay, you surely have seen a URL like this:


http://localhost:8080/web/guest/neu?p_p_id=23&p_p_lifecycle=0&p_p_state=maximized&p_p_col_id=column-1

In my case it´s a URL that is shown when the portlet is maximized.
In this blog post I want to show you how to interpret those URL parameters so that you have the possibility to construct one on your own.

p_p_id : 


This is the unique ID of your portlet. If you don´t know the ID, you can just maximize it. If you want to have a list of the portlet IDs, the liferay portlet provides, take a look here:


http://www.liferay.com/de/community/wiki/-/wiki/Main/Portlet+IDs

Whenever you perform an action in your portlet and you submit a form, then this is the variable that liferay uses to identify the portlet to update.

p_p_lifecycle :


This was called p_p_action before and determines whether the render() method of your portlet should be executed or a struts action. 0 means render, 1 means execute.


p_p_mode: This just tells the Struts action you executed


p_p_state:


This hoolds the state of the portlet, just like you woulkd do if you would click on the "+" and "-" buttons on the top right corner of the portlet.


Maximized: Maximizes the portlet, taking the whole width of the page. No other portlet will be shown.


Minimized: Minimizes the portlet so that it just shows it´s title:


Exclusive: Expands the portlet to thr browsers width and height. No more portal ...





If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

10/06/2011

A New Blog

Hi you all.


I am neither dead, nor does this blog go to sleep. I am just distracted by a lot of new projects, involving PHP5. I do not want to clutter this blog with "normal" Java, PHP5 etc, so I quickly set up a new one: 


http://daniel-breitner.blogspot.com/


There you will find everything that doesn´t relates to Liferay, JSF or Portals.


I will have some time to update this blog in a couple of days, so stay tuned ...


p.s. 350+ visitors each day on liferay-blogging: this is so great !!!


If you like this blog it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/30/2011

Hiding the Liferay Control Panel

Whenever you set up Liferay for a customer, there will be a requirement to prevent the "normal" user from accessing the control panel. Some administrators fear, the user might do things he´s not supposed to do, others fear, the the user might be confused.

But how do you hide the control panel?

Well, there are several possibilities, and none of them is really nice. There is no portal.properties entry and there is no permission you could set. Either you do it programmatically or by CSS and then you also have the loophole of users entering the control panel URL into the browser:

You, and all of your users can always access the control panel by entering "http://localhost:8080/group/control_panel" into the Browser, no matter what you do. To prevent this, I suspect you have to take a look at ServletFilters and prevent every access to this URL if the User is no administrator.

I will now point out two possibilities how to hide the control panel and I would be very glad if you could describe your own approaches in the comments section.


Hiding the Control Panel programmatically


if you want to hide the control panel for all users, who are no administrators you can overwrite the ServicePreAction class in your ext environment. If you take a look at the servicePre method you will find this:
themeDisplay.setShowControlPanelIcon(signedIn);
So, what ever you do in the .vm files your theme provides: All logged in users will always see the link to the control panel. To remove it, just call the RoleLocalServiceUtil, check whether your user has administrative rights, and change the code above.


Hide the Control Panel using CSS


You could hide the control panel using CSS: You need to apply display:none styles to all elements of the class(es) "control-panel last aui-menu-item".


But how do you make sure, the control panel is hidden from normal users ? To do this, you need to have your own theme. In your theme you need to change the portal_normal.vm and add the following:

#if ($permissionChecker.isCompanyAdmin($company_id))
<style type="text/css"> 
  .control-panel{
    display:none;
  }
</style>
#end


That´s it .. control panel should be hidden!


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/22/2011

Creating New Struts Actions with Liferay 6.1

I just stumbled upon this Liferay Blog Post which I find very interesting:


It would solve one of the problems I right now have:

Liferay 6.1 allows you to add or modify structs actions in a hook plugin. Just a little configuration for your liferay-hook.xml and a little programming and you could easily extend every existing Liferay Portlet. I can`t wait for it to be finished ...


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

Let Liferay create Roles automatically

If you want to assure that everyone of your developers always works with the same Roles for your Users, you should let liferay create them. It´s very easy, take a look here:


Add the following into your portal-ext.properties:
system.roles = Role1, Role2,Role3
system.role.Role1.description = Role 1
system.role.Role2.description = Role 2
system.role.Role3.description = Role 3
This will automatically create the three roles and also provide a description after you restart your server :)



If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/18/2011

Liferay 6.1 Features: Dynamic Data Lists

Overview | Liferay App-Store | Required Categories | Page Customizations | Dynamic Data Lists


Welcome to the next part in my series about the forthcoming and promising Liferay 6.1. Today we will take a look at dynamic data lists and what they offer to you. To summarize it in one sentence, dynamic data lists (DDLs) are a little like Excel Workflows in a portlet.


The administrator has the possibility to create a DDL by first creating a data definition. A data definition is kind of a template that specifies which entities (Integer, Boolean, Date, Text ...) the dynamic data list may hold. The DDL is just an instantiation of this template.


Data Definition Editor
The Data Definition Editor allows to drag and drop all the fields that you want to appear in the Dynamic data List.  If we take a look at the DDL Explorer we can see that we now have the possibility to modify our DDL and to enter into a Spreadsheet View. 


Dynamic Data List Explorer




This Spreadship view allows us to enter some data into the DDL and this is the reason why I call it "Excel for Portlets". You enter enter as much data as you want according to the Data Definition we just created.


Spreadsheet View
The DDL we just created and enriched with some data is exportable by CSV or XML so you may well use it in your Excel to calculate monthly incomes etc.


One thing I am missing are formulars and calculations: Wouldn´t it be nice not having to use Excel at all? It would save some money and make some workflows totally automatic. Maybe they will go for that in Liferay 6.2? Who knows...


To use DDLs in your portlet environment, Liferay has already created a working Dynamic Data List Display Portlet that lets you choose a DDL, decide whether it should be editable and assign it to your Users. This lets your Users remotely create records of data that your financial officer can use to calculate summarized monthly expenses.


Dynamic Data List Display Portlet
Also the asset publisher allows to filter its results for only DDL records. Good idea, if someone needs to have a quick glimpse over all newly created records.


If you take a look at the DDLD Portlet, you will see, that you can also create list and detail templates. Isn´t that great? Now you also have the possibility to customize the view of your DDL! So - without and programming you can create a fully working, customizable remote Excel-light. Of course, the DDLs can also be accessed programatically. The tables you need to know are:

  • DDLRecord (the individual DDL),
  • DDLRecordSet (Data Definition) and 
  • DDLRecordVersion (everything is versioned in liferay).
UPDATE:


I just saw that Liferay also has a blog entry about dynamic data lists. Take a look here:
http://www.liferay.com/de/web/marcellus.tavares/blog/-/blogs/9961174


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/16/2011

How to create a Liferay Action Menu

Just a quick tutorial on how to create those Liferay Action Menus that you can find everywhere in liferay. Here is one example from the Liferay User Menu:

And here is a little tutorial that shows how those so-called icon menus can be created. All you need are URLs (pointing to your portlets class` methods) and icons. That´s it. The example I will show you now will use all the icons you can find under 
\tomcat-6.0.29\webapps\ROOT\html\themes\classic\images\common.


Here is an example that creates two icons and links them to actionURLs in the portlet class. Notice how we just have to specify that we want to have the edit or permissions icons without having to specify a path or a filename. That´s what I call convention over configuration!

<liferay-ui:icon-menu>
  <portlet:actionURL name="edit" var="edit"/>
  <liferay-ui:icon image="edit" message="Edit" url="<%=edit.toString() %>" />
  <portlet:actionURL name="permissions" var="permissions"/> 
  <liferay-ui:icon image="permissions" message="Permissions" url="<%= permissions.toString() %>" />
</liferay-ui:icon-menu>
Quick Explanation: the action URLs link to the method in the portlet class that matches the "name" attribute. The icon tag is linked to an icon in the chosen theme, has a message and connect to the action URL. That´s all !! I love it !!!


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

Creating Liferay Search Container GUIs

Time for some basic knowledge:

What does the liferay-ui tld say about the search container? How is it possible to create nice and functional search container GUIS? Read the following and you know more:

The search container is always rendering a set of rows that contain one or more columns to display search results. You may change the way the search container is rendering the rows but in the end it will always be a set of rows. So what we are going to do now will only affect the rows itself. We won't change the search container to display grids or something similar.


The liferay search container is structured as follows:

<liferay-ui:search-container > 
<liferay-ui:search-container-results>
<!-- Calculate results-->
</liferay-ui:search-container-results>
<liferay-ui:search-container-row>
<!--Create the rows that display the search results-->
</liferay-ui:search-container-row>
</liferay-ui:search-container >


Because we will only care for the rows, we will jump right in and take a look at some of the tags you can use:


search-container-column-text


<liferay-ui:search-container-column-text name="userName" property="userName" />

The column text tag creates a label filled with a header text (name) and a populated value of the search container entity (property). In our case, the property userName would be taken from our entity and displayed.


search-container-column-jsp


<liferay-ui:search-container-column-jsp path="/your.jsp" align="right" />

Very powerful! Allows to create a complete JSP that will be displayed in every row. By using this tag you can create your own forms with AlloyUI or standard HTML / Javascript and let the search container do all the magic.

search-container-column-button


<liferay-ui:search-container-column-button align="right" href="<%= yourUrl %>" name='clickMe' />

Allows to create a button pretty easy and connect it to a URL.


search-container-column-score

<liferay-ui:ratings classPK="<%=user.getUserId()%>" className="<%=User.class.getName() %>" />
Shows the score for the retrieved object.


These tags allow you to create very fast very powerful search container GUIs. I´ve only touched the surface here and there is a lot more of liferay magic that you can discover. Just take a look at the TLD which you can find here: 


http://code.google.com/p/liferay-book/source/browse/trunk/portlets/library-portlet/docroot/WEB-INF/tld/liferay-ui.tld?spec=svn3&r=3


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/12/2011

Liferay 6.1 Features: Page Customizations

Overview | Liferay App-Store | Required Categories | Page Customizations | Dynamic Data Lists

A rather small but nice feature is the possibility for administrator to lock certain parts of a liferay page for modifications. Depending on the page layout you use you have two or more areas that you can lock or unlock. Simply click on "Manage -> Page Customizations" and you will see the following screen:


As you can see, you can lock or unlock every area in you portlet page by selecting or deselecting it. If you want users only to edit the upper and lower part of your page you would check the according checkboxes and see the following:


Users now have no possibility to move or edit the portlets in the middle areas.

If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/11/2011

Liferay 6.1 Features: Required Categories

Overview | Liferay App-Store | Required Categories | Page Customizations | Dynamic Data Lists


I am currently playing with Liferay 6.1 and I am going to report every cool feature I will stumble upon. The first post in this series will be about required categories.


Required categories allow an administrator to define categories for certain asset types (documents, users, comments etc) that HAVE to be set. So it is very easy to extend the user interface liferay provides, say for documents, by a dropdown box that allows to choose the author or the year the manuscript was published. Here is how you use it.


First enter the new categories view in the new control panel:




Add a new vocabulary , give it a name and a description and take a look at the "associated asset types". They allow to link the category to an asset type of your choice. In this case it`s Document Library Document. By selecting an asset, the Vocabulary will only appear on forms for this very special asset. In our case, it won´t be possible to select a color category for a comment or a blog entry.
By deselecting "Allow Multiple Components" we make sure that only ONE category can be selected, by selecting "Required" we make sure that it HAS to be selected.
The next screenshot shows the new Categories section with the selected Color Vocabulary and its enclosed Categories Blue, Green and Red.




If you now add a document, you will see that you have to select a color. In my opinion, this is just great because it will make programmatically changes to the document library less and less possible.




The required categories will speed up development and save you some money. Thumbs up !


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

Direct Connection to the Liferay Database

In Liferay, if you want to modify or read entities you would normally use dynamic queries. You can find a lot of tutorials here at liferay-blogging about the DynamicQuery API.


Sometimes you need a direct access to the database to use SQL for whatever reason there might be. This is a little tutorial to show you how you can archieve this with Liferay 6 and Tomcat 6.0.29. To access the database directly you need to define a datasource in your tomcat.
Open the file /conf/context.xml and add the following in the <Context> section:

<Resource 
name="jdbc/Liferay" 
auth="Container" 
type="javax.sql.DataSource" 
maxActive="100" 
maxIdle="30" 
maxWait="10000" 
username="root" 
password="root" 
driverClassName="com.mysql.jdbc.Driver" 
url="jdbc:mysql://localhost:3306/lportal"/>

This defines an access point for your database for the database lportal and the user "root" with the password "root". Change it to fit your needs and open the web.xml of the portlet or hook that needs to access the database.

Add the following:
<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/Liferay</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

This makes the dataSource accessible in your portlet. To access and use it, trythe following snippet.It should print our all screen names of all registered users:
Context ctx = new InitialContext(); 
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Liferay"); 
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement(); 
ResultSet set = stmt.executeQuery("select screenname from user_"); 
if(set.next()) {
  System.out.println("Screenname :"+set.getString(1);
 } 
conn.close();

If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

Download Liferay 6.1 Preview

If you like to try our the forthcoming Liferay 6.1, you can download a nightly build here:


http://releases.liferay.com/portal/nightly/


Use it together with the newest version of Liferay IDE which you can find here:


http://sourceforge.net/projects/lportal/files/Liferay%20IDE/1.3.0/


I am downloading it right now and will keep you all informed about what we can expect from the newest version of Liferay.


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/10/2011

How to change the Liferay Login Module / Authentication Pipeline

If you want to change the Login Module, Liferay uses, or you want to add LDAP authentication to your liferay system, you need to use the liferay authentication pipeline.


To configure your pipeline, you have to take a look into your portal.properties. You will find the following properties:



auth.pipeline.enable.liferay.check=false
auth.pipeline.pre=de.test.auth.RefuseAuthenticator



Those configure the authentication pipeline. The first one disables the standard liferay behaviour to authenticate vs. its configured database. The second tells liferay which classes to use to verify name/password combinations. You can enter as much Authenticators as you want and they will be processed sequentially.


Every Authenticator must implement the interface com.liferay.portal.security.auth.Authenticator. If you take a look you will know what you have to do: The methods authenticateByEmailAddress, authenticateByScreenName and authenticateByUserId are self explanatory.


Here is an example of a RefuseAuthenticator that will refuse every user. Not very useful but it shows how an implemented Authenticator may look like:


package de.test.auth;

import java.util.Map;
import com.liferay.portal.security.auth.AuthException;
import com.liferay.portal.security.auth.Authenticator;

public class RefuseAuthenticator implements Authenticator {

public int authenticateByEmailAddress(long arg0, String arg1, String arg2, Map<String, String[]> arg3, Map<String, String[]> arg4) throws AuthException {

    System.out.println("failed by mail");
    return FAILURE;
}

public int authenticateByScreenName(long arg0, String arg1, String arg2, Map<String, String[]> arg3, Map<String, String[]> arg4) throws AuthException {

    System.out.println("failed by screen name");
    return FAILURE;
}

public int authenticateByUserId(long arg0, long arg1, String arg2, Map<String, String[]> arg3, Map<String, String[]> arg4) throws AuthException {

    System.out.println("failed by user id");
    return FAILURE;
}

}




If you add the lines to your portal-ext.properties and provide the class with your ext environment you should not be able to log into liferay anymore.


If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/06/2011

Using parameterized method calls in JSF 2.0

One of the very nice features of JSF 2.0 is the ability to call action methods with parameters. 


Why is that important ? It is important because it allows you to call any method with a click without having to use parameter tags. This is conjunction with JSF 2.0 composite components lets you do magical things like creating unlimited ICEfaces popups.


Let me explain further:


If you use ICEfaces or JSF in a business environment you will always try to reuse components: Don´t Repeat Yourself (DRY). By using composite components, developers using JSF 2.0 (and ICEfaces 2.0) have this ability: One team is creating the components, another team is reusing them to create great applications.


If you want to create a component that displays an ICEfaces popup (PanelPopup component) you have to find a way to let the user call and recall the same popup. The user must have the possibility to create, close and create the popup again and again. 


So the questions are: 


1) How do you let the business component developer tell the composite component which popup to open ?


2) How has the composite component to be developed to open and close always the right popup and keep its state ?


This is my solution, if you have any other solution, please let me know.


The composite component


The composite component that is rendering the popups is a popup component like you would develop it if you wouldn´t care about reusability. You need a boolean value to determine whether it is opened or not and a close Button. Of course you will always need more buttons, business logic etc etc but for our little example here we will just open and close the popup:



<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:icecore="http://www.icefaces.org/icefaces/core"
xmlns:ace="http://www.icefaces.org/icefaces/components"
xmlns:ice="http://www.icesoft.com/icefaces/component">

<head>
    <title>A Popup</title>
</head>
<body>
    <cc:interface>
      <cc:attribute name="bean" required="true" />
    </cc:interface>

    <cc:implementation>
      <ice:panelPopup rendered="#{cc.attrs.bean.show}" modal="true">
      <f:facet name="header">
      <ice:outputText value="Confirmation" />
      </f:facet>
      <f:facet name="body">
      <ice:panelGrid columns="1">
      <ice:outputText value="This is a popup" />
      <ice:commandButton value="Close" actionListener="#{cc.attrs.bean.toggleShow}" />
      </ice:panelGrid>
      </ice:panelGrid>
      </f:facet>
      </ice:panelPopup>
</cc:implementation>
</body>
</html>


As you can see ... nothing special about the composite component so far. We have a bean that holds its state and has a method that allows to toggle the state.


The code


Something much more interesting is the code invoking the composite component:
<composite:popup bean="#{popupCreator.createPopup('test')}" />
We invoke the composite component by calling a parameterized method that returns a Bean. The Bean that we are using in our composite component. This is the code:



private Bean createPopup(String id) {

  Bean bean= beanMap.get(id);
  if (bean== null) {
  bean= new Bean();
  beanMap.put(id, confirmationBean);
  }
  return bean;
}


That´s basically all. If you know how to do composite components, you know how to use this code. This is kind of a generic approach to create truly reusable components. I would be interested in your approaches: How did you solve challenges like this ?




If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

8/02/2011

Liferay and Java 7

Java 7 is out ! Hooray !


If you want to know what Java7 can do for you, take a look here: http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html#changes.


It has a lot of interesting features, some of them I am going to describe in detail in the coming weeks. If you are interested in using Applets in your Portlets you might be intersted in a feature that allows you to determine if your applet is ready to make javaScript calls. This might come in very handy.


But beware, you should not use it right away. Give the folks at Oracle some time to fix some of the bugs that are still in the code. Some of them make working with Lucene and Solr impossile which then means, that working with Liferay is impossible (you can use either Lucene or Solr). If you want to know more, you can take a look here:


http://lucene.apache.org/#28+July+2011+-+WARNING%3A+Index+corruption+and+crashes+in+Apache+Lucene+Core+%2F+Apache+Solr+with+Java+7


My suggestion would be to stick with your existing Java 1.6 installation and try again in 6 months.


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

7/18/2011

About myself

A little advertisement about myself:


My name is Daniel Breitner, and I am a freelancer for everything that has to do with Liferay, Portlets and J2EE. 


If you found this blog you are most likely searching for information about Liferay, ICEfaces, JSF or just pure Java. This blog has a lot of articles that should help you with most of your questions. Go ahead, read it and use it in your project. It´s free !


If you need further assistance: 


I am also offering my programming and consulting skills. If you need questions answered, portlets programmed or need to make a technological decision: I am sure I can help you out. 


If you want to contact me, you can do that either by mail or you can visit my Linkedin Profile.

6/23/2011

Liferay 6.1 Features, Part 1 : The App - Store

Overview | Liferay App-Store | Required Categories | Page Customizations | Dynamic Data Lists


So, welcome to a set of posts about the forthcoming Liferay 6.1. Today we will take a look at the Liferay App Store, which is targeted for the release of Liferay 6.1 in Q4 2011.


The source for my post is (again) a Liferay presentation. You can download it here: Click


So, what is the Liferay App Store, how does it work? The App Store works as every other App Store does: Developers  have the possibility to program and submit Apps. They pay a part of their revenue to Liferay and therefore Liferay provides a portal that makes downloading and installing the apps very easy. Liferay also checks the apps for compatibility.


Apps


Apps can be developed in two flavours:


Free Apps


If you want to create and distribute free apps (wouldn´t a liferay-blogging app be just great?),all you have to do is to download the App SDK, read the Marketplace Developers Guide and create a Marketplace Profile. That´s all.


Selling Apps


If you want to sell apps (who doesn´t)  you need to buy at least a One - Year subscription to the Liferay Developer Program which costs 99$. By doing so you will get the right to sell your app- 20% of your revenues will go to Liferay. 
If you choose to sell your app, it will be validated by Liferays engineering team for compatibility with an EE release. CE validation is up to you. 


What you don´t get is the EE source code,what may be a little tricky when you want to publish hooks that (for example) extend the Asset Publisher. If you just want to sell portlets, then there will be no additional costs.


App Store


The Liferay App - Store will have all those features that you would expect when you think of iTunes or the Android Marketplace: Ratings, One-Click Buy Following and Smart Suggestions to let you buy even more apps :)




What is an app ?


An app is a typical liferay distributable: a portlet, webs, hooks, themes etc. - everything you can develop with the Liferay IDE is something you might sell. Isn´t that great ?? I can´t wait to get started ...


The Marketplace APIs gives you additional possibilities like In-App-Purchases.


When does it start?


According to the Liferay presentation, Early Q3 will be the time when you get the developer´s guide, Late Q3 allows you to take a sneak peak at the app store and the Launch is targeted for Q4.


If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.

6/18/2011

New Features of Liferay 6.1


Overview | Liferay App-Store | Required Categories | Page Customizations | Dynamic Data Lists


So - you are all using Liferay 6.06 CE or 6.011 EE and you want to know, what´s next ? Well, the folks at Liferay gave  a glimpse at what we can expect in Liferay 6.1. at the hungarian symposium. If you want to have the complete presentation, take a look at the slides held at 16:35PM:
http://www.liferay.com/de/events/liferay-symposiums/hungary-2011/agenda
If you just want to know what´s going on ... here are some of the new features:


1) Greatly Improved Document Library with a redesigned UI.

  • It allows to integrate several existing content repositories (CMIS, Sharepoint, Documentum, Alfresco). 
  • Image Gallery and Document Library will be unified

2) Support for Staging 

  • modify several versions of your portal at the same time 
  • create a special christmas version without having to change all your sites.

3) Web Content title and description will finally be translatable


4) Simplified publishing of contents

  • Let end-users publish content without having to fight with asset publisher properties.
  • Link Web Content Links to configurable pages

5) Taxonomy Enhacements 

  • internationalization for vocabularies and categories
  • mandatory vocabularies
  • multi valued categorization

6) Custom Entities


This seems to be very interesting: A possibility to create a Liferay Service with Entities and GUIs simply by using a portlet. Sounds like taking the Liferay Service approach to a whole new level by also generating GUIs and allowing Users to do this within Liferay - not within Eclipse. I am very curious how this fits in your development environment. How will the source code be stored ? How do we migrate from one server to another ? We´ll see.


7) Workflow Aware Forms


Very interesting approach to create workflows and the GUIs / Forms that fit into the workflow as single steps. Should be possible to define business processes without development. Lets hope that all this data is exportable somehow...


8) Implementation of OpenSocial 1.1 


Visit http://www.opensocial.org/


9) Improved Social Features


Liferay 6.1 will introduce a Contact Center that will contain all Friends, FriendsRequests, Followers etc. Very good feature that will incorporate all the portlets that you have to find for yourself, create a page, configure everything etc etc. It will also contain "short status updates"  - looks like a twitter clone to me. Let´s see how it works.


10) Redesigned Calendar portlet


Finally - the calendar portlet will be complete rewritten, looks a little like the Google Calendar.Possibility to add ressources like conference rooms and view the availability of these ressources. Great ! Maybe we can get rid of outlok and do it in Liferay. This will maybe help to save costs for firms.

11) Improved MessageBoards


12) Improved Blogs

  • Attachments
  • Autotagging
  • sharing via Facebook and twitter



13) Improved Chat


Weehow ! The Chat Portlet will be rewritten and will contain features such as message broadcasts to a group of users, offline messaging and a chat history with pruning

14) Mobile themes


Great - Mobile themes for iPhone, iPad and Android will be available out of the box. This is one of the main requested features of my customers.

15) Suport for SAML 2.0


Liferay will work as an SSO provider - nice. One of my customers has three consultants sitting and configuring the SSO Framework - costy !

16) Improved documentation


Ok, I am curious about that ...


17) Improved Liferay IDE and Liferay Developer Studio

  • Create JSF 2.0 Portlets
  • Visual UI builder with AlloyUI
  • Workflow designer

If you like this post it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.