Monday, July 21, 2014

New Features available in different versions of Liferay


Liferay 6.2

·         In liferay 6.2 inside document & media portlet you can subscribe to folders to be notified of changes, & drag-n-drop multiple files from your desktop into the library with ease.
·         In liferay 6.2 Recycle bin feature has been added. We can recover deleted per site content quickly & painlessly. Quick undo. Automatic flushing & full search.
·         In liferay 6.2, a concept of site hierarchy is introduced.




Liferay 6.1
·         In liferay 6.1, document & media portlet was introduced. Basically it is the redesign of two portlets from the previous versions(Document library portlet & Image gallery portlet).
·         In liferay 6.1, community is converted to sites.
·         In liferay 6.1 you can use hook even for overriding those struts actions which have entry in struts-config.xml file. Earlier which was possible only by the ext-plugin.
·         Liferay 6.1 added a feature to staging called Page Versioning. This feature works with both Local Live and Remote Live staging and allows site administrators to create multiple variations of staged pages. This allows to several different versions of sites and pages to be developed at the same time. Variations can be created, merged, and published using a Git-like versioning system.
·         In liferay 6.1 “Page Customization” feature is added under “Manage” tab. With this feature any user with appropriate permissions can create personalized versions of any public page. Before this, customizations must first be enabled by an administrator. If at any time users determine that they don’t like their customization, they can click “Reset My Customization” to revert their pages back to the default.
·         In liferay 6.1 a new functionality indexer hook was introduced.

Liferay 6.0
·         In liferay 6.0, a new way of friendly url mapping was introduced.
·         In liferay 6.0 Alloy UI script was introduced.
·         Ext plugins were introduced in Liferay 6.0 to replace the Extension environment.
·         In liferay 6.0 arrayable-operator has been added for the finder in service.xml. This attribute takes values AND or OR & will generate additional finder where this column’s parameter takes an array instead a single value.

Sunday, July 7, 2013

Few things about liferay search container



Some brief information about <liferay-ui:search-container/> tag attributes.



          <liferay-ui:search-container

       emptyResultsMessage="enter-or-refine-query-to-search-students"

                  headerNames="firstName,lastName,emailAddress"

                  iteratorURL="<%= portletURL %>"

                  orderByCol="<%= orderByCol %>"

                  orderByType="<%= orderByType %>"

                  delta="<%= delta %>"

                  deltaConfigurable="<%= false %>"

                  rowChecker="<%= new RowChecker(renderResponse) %>" 

          > 

  • rowChecker  - If you want to use check box based search container you have to add “rowChecker” attribute in the <liferay-ui:search-container/> tag.
  • deltaConfigurable  - If you don’t want to include Items per page section in the search container, set “deltaConfigurable” attribute to false. By default it’s value is true.
  • emptyResultMessage  - If you want to display custom message when there is no result available, set “emptyResultMessage” attribute.



Fetching value of selected check boxes in action class.

             <liferay-ui:search-container-row
                         className="com.liferay.portal.model.User"

                         escapedModel="<%= true %>"

                         keyProperty="userId"

                         modelVar="user2"

              >

Set "keyProperty" attribute in <liferay-ui:search-container-row> tag. & use below code in the action class.

String[] rowIds = ParamUtil.getParameterValues(actionRequest, "rowIds");

It will return an array of values selected from the search container. The array will have values which you will set as a ”keyProperty” value in <liferay-ui:search-container-row/>.

Setting custom value to search container check boxes


By default whatever value you will set for attribute “keyProperty” of <liferay-ui:search-container-row/> it will be assigned the value of check boxes, but if you want to set custom value to check boxes, addd “rowVar” attribute inside <<liferay-ui:search-container-row/> tag & then set the value with the help of setPrimaryKey() function of ResultRow clas.



<liferay-ui:search-container-row

                         className="com.liferay.portal.model.User"

                         escapedModel="<%= true %>"

                         keyProperty="userId"

                         modelVar="user2"

                         rowVar="curRow"

               > 

<% curRow.setPrimaryKey(user2.getFirstName() + StringPool.PIPE

                     + user2.getMiddleName() + StringPool.PIPE + user2.getLastName());

               %>

It will make value of check boxes like “userFirstName|userMiddleName|userLastName”.


Getting value of selected check boxes inside aui function.


Liferay.provide(

                           window,

                           '<portlet:namespace />deleteEntries',

                            function() {
                                       var cmd = 
                                              Liferay.Util.listCheckedExcept(
                                                  document.<portlet:namespace />fm,   "<portlet:namespace />allRowIds");
                             },

                             ['liferay-util-list-fields']

              );

In the above code block value of “cmd” parameter is comma separated value of selected check boxes.

Saturday, June 1, 2013

Submitting the parent form from liferay pop up window

Hi friends, sometimes in liferay after doing our stuff in the pop up window we want to send data back to parent form & submit it. So following are few steps to perform this task.

Call the following function on click of save button in liferay pop up window

<script type="text/javascript">
         
        AUI().ready('aui-dialog', function(A) {

               A.one('#<portlet:namespace />save').on('click', function() {

                              var comment = A.one('#<portlet:namespace/>declineCommentPopUp').val();

var declineComment  = Liferay.Util.getOpener().document.getElementById('<portlet:namespace />declineComment');

                              declineComment.value = comment;

Liferay.Util.getOpener().document.getElementById('<portlet:namespace />fm').action  =  '<%=declineAgreement%>';

                              Liferay.Util.getOpener().document.forms['<portlet:namespace />fm'].submit();

               });

});

</script>

In the above mentioned function 'declineCommentPopUp' & 'declineComment' are the fields available inside the form on the pop up & on the parent form respectively. '<portlet:namespace />fm' is the parent form. With the help of syntax

Liferay.Util.getOpener().document.getElementById('idOfElementOnParentForm');

we are able to access elements from the parent form & syntax

Liferay.Util.getOpener().document.forms['<portlet:namespace />fm'].submit(); 

will submit the parent form & close the pop up window.

Monday, June 6, 2011

Playing you tube videos with java script


First thing to play a you tube video, download the swfobject.js file.

<script type="text/javascript" src="swfobject.js"></script>

<div id="showvideo">
</div>

<script type="text/javascript">
    var vid="Vb7xpSeVe6c";
    swfobject.embedSWF("http://www.youtube.com/v/"+vid+"?enablejsapi=1&amp;version=3&amp;border=0", "showvideo", "450", "350", "8", null, null);
</script>


Here vid is the video id of the video, which you want to play with the help of java script. You can easily see this video id as a v parameter in any video link which you tube plays.




Thursday, February 10, 2011

Including Content in a JSP Page


There are two mechanisms for including another Web resource in a JSP page:

1- the include directive
2-the jsp:include element.

The include directive is processed when the JSP page is translated into a servlet class. The effect of the directive is to insert the text contained in another file--either static content or another JSP page--in the including JSP page. You would probably use the include directive to include banner content, copyright information, or any chunk of content that you might want to reuse in another page. The syntax for the include directive is as follows:
 
<%@ include file="filename" %>
 
For example, if you want to include the file init.jsp containing the global content you can use:-
<%@ include file="init.jsp" %>
 
The jsp:include element is processed when a JSP page is executed. The include action allows you to include either a static or dynamic resource in a JSP file. The results of including static and dynamic resources are quite different. If the resource is static, its content is inserted into the calling JSP file. If the resource is dynamic, the request is sent to the included resource, the included page is executed, and then the result is included in the response from the calling JSP page. The syntax for the jsp:include element is as follows:


<jsp:include page="includedPage" />  

Think of the include directive as a header file of languages like C/C++. When using the include directive, the combined contents of the original JSP page and all its included resources are translated into the same implementation servlet i.e. the contents of the included resource is copy pasted before translation to a servlet. The important thing here is that all this happens during translation time and only static content is supported. 

On the other hand, the include action <jsp:include> is almost similar to the include directive except for a few subtle differences. The include action is executed at request time as opposed to translation time. Thus instead of the content of the include file being included in the calling JSP, the output of the JSP is included or passed to the JSPWriter of the calling page. This allows us to include both static and dynamic content into the JSP page. Using the jsp action also allows you to explicitly pass parameters to the included page. 
 
 
 

Saturday, January 29, 2011

Integrating Linkedin in your application with java

There are two ways to integrate linkedin in your application.

First one is manually handling every step like oauth authentication, generating signature etc......
Second one is to use Linkedin api java wrapper classes

We will use second method to integrate linkedin in our application.

Linkedin Provides us Linkedin api java wrapper classes for integrating linkedin.
http://developer.linkedin.com/thread/1275 


I am using linkedin-j-1.0.361-binary. There are some classes, interfaces ,,etc. which i have used in following example, for using them you have to add these jars in your class path. So don't forget this.

Here are steps to integrate linkind in 
1- first we need API key & Secret Key.....for getting these two keys you can refer to this page
 http://developer.linkedin.com/docs/DOC-1251.
In our example we will use terms oauth_consumer_key & secret_key for API key & Secret Key respectively...

2-After getting oauth_consumer_key & Secret Key we will first log in to the account which we want to access. Below is the code snippets with explaination....

LinkedInRequestToken requestToken=null;
LinkedInAccessToken accessToken = null;
private static LinkedInApiClient client=null;
private static LinkedInApiClientFactory factory =null;
String accessTokenValue="";
String tokenSecretValue="";
Person profile=null;

LinkedInOAuthService oauthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(oauth_consumer_key, secret_key);

we need a call back url  in our log in process, because after getting log in, the login process of linkedin redirect  us to the call back url. We provide the url of our application as a call back url, so that after log in we can come back to our own application.

String callback="your call back url"; 
requestToken = oauthService.getOAuthRequestToken(callback);
session.setAttribute("requestToken", requestToken);                     

we set the request token in session because we will in need of this after redirecting to the application with the help of call back url. 

String authUrl = requestToken.getAuthorizationUrl();
res.sendRedirect(authUrl);                           

We send request to the authurl, it means to the log in page of linkedin. After inserting  valid credentials to the log in page, linkedin redirects us to the call back url(which i have mentioned earlier). As we are redirected to the call back url, linkedin embeds two parameters in the url. oauth_token & oauth_verifier. Now after coming back to our application we fetch these parameters from request.

String oauth_token=ParamUtil.getString(actionRequest, "oauth_token");
String oauth_verifier=ParamUtil.getString(actionRequest, "oauth_verifier");
requestToken = (LinkedInRequestToken)(session.getAttribute("requestToken"));           //request token is, one we have stored in session

accessToken = oauthService.getOAuthAccessToken(requestToken,oauth_verifier);

Now we have got accesstoken, which we will use in future to fetch results from linkedin. frankly speaking accesstoken is the only way so that linkedin will consider that a valid user is accessing the data. We can also store this access token in our database.

3-Actually log in process has been over. According to the linkedin point of view, a valid user is loggedin to the linkedin.(whose user name & password you have inserted during log in process). So now we will first fetch the user information who is logged in to the linkedin.

factory = LinkedInApiClientFactory.newInstance(oauth_consumer_key, secret_key);
client = factory.createLinkedInApiClient(accessTokenValue, tokenSecretValue);
accessTokenValue=accessToken.getToken();
tokenSecretValue=accessToken.getTokenSecret();
profile=client.getProfileForCurrentUser(EnumSet.of(ProfileField.FIRST_NAME,ProfileField.LAST_NAME,ProfileField.DATE_OF_BIRTH,ProfileField.HEADLINE,ProfileField.INDUSTRY,ProfileField.API_STANDARD_PROFILE_REQUEST,ProfileField.PICTURE_URL,ProfileField.PUBLIC_PROFILE_URL,ProfileField.CONNECTIONS,ProfileField.CURRENT_STATUS,ProfileField.SUMMARY,ProfileField.EDUCATIONS));

In getProfileForCurrentUser(Set<ProfileField> arg0) method we provide a set of those fields which we want to fetch for the loggedin user. Now we have an object of Person class, we can fetch user data with the help of different methods of Person class. as.....

String fName=profile.getFirstName();
String lName =profile.getLastName();

4-As you will open your account in www.linkedin.com you will first see you network updates along with your personal information. So now we are going to fetch network updates of the loggedin user. Below is the code snippet for this...............


Network network =null;
network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.ANSWER_UPDATE,NetworkUpdateType.APPLICATION_UPDATE,NetworkUpdateType.CONNECTION_UPDATE,NetworkUpdateType.EXTENDED_PROFILE_UPDATE,NetworkUpdateType.GROUP_UPDATE,NetworkUpdateType.JOB_UPDATE,NetworkUpdateType.PICTURE_UPDATE,NetworkUpdateType.PROFILE_UPDATE,NetworkUpdateType.QUESTION_UPDATE,NetworkUpdateType.RECOMMENDATION_UPDATE,NetworkUpdateType.SHARED_ITEM));


we give an argument(Set) in getNetworkUpdates method. This set contains all the field which we want to include in our result. If you want to fetch only those network updates where someone in the network has updated his/her profile, you can use this code.

network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.PROFILE_UPDATE),offset,count);
  
If you want to fetch only those network updates where someone in the network is connected with any other, you can use this code.

network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.CONNECTION_UPDATE),offset,count);  
 
Now  we have all the network updates. We can display them seperatly(according to the network update type) or in a single way combindly. We can fetch our intended network updates by  checking the update type. Linkedin provides us a list of network update types & there meaning, you can find it here.
I am getting only to that update where someone in the netowrk of loggedin user is connected to any other(CONN). By going through this you can easily fetch results of other network update types.

Updates updates=network.getUpdates();
String ufName=null;
String ulName=null;
String tfName=null;
String tlName=null;
String updMsg=null;
java.util.List<com.google.code.linkedinapi.schema.Update> update=updates.getUpdateList();
 for(int i=0;i<update.size();i++)
{
        UpdateContent updateContent=update.get(i).getUpdateContent();
        updateType=update.get(i).getUpdateType().value();
        if(updateType.equals("CONN"))
        {
            String id=updateContent.getPerson().getId();
            Person profile2 =     client.getProfileById(id,EnumSet.of(ProfileField.FIRST_NAME,ProfileField.LAST_NAME,ProfileField.HEADLINE,ProfileField.INDUSTRY,ProfileField.API_STANDARD_PROFILE_REQUEST,ProfileField.PICTURE_URL,ProfileField.PUBLIC_PROFILE_URL,ProfileField.CURRENT_STATUS,ProfileField.SUMMARY));
            profile2.getPublicProfileUrl();
            updateContent.getPerson().getPictureUrl();
            ufName=updateContent.getPerson().getFirstName();
            ulName=updateContent.getPerson().getLastName();
            Connections connections=updateContent.getPerson().getConnections();
           List<Person> list=connections.getPersonList();
          for(int k=0;k<list.size();k++)
          {
             
tfName=list.get(k).getFirstName();
             
tlName=list.get(k).getLastName();
           }
           updMsg=" is now connected to ";
           System.out.println(ufName+" "+ulName+" "+updMsg+" "+tfName+ " "+tlName);
}