Saturday, August 3, 2013

Liferay Plugin portlet connecting to multiple data bases/Data Sources

Liferay Plugin portlet connecting to multiple data bases/Data Sources


Lifray portal 6.1GA2+Tomcat7.X+Mysql 5.1X

Download Portlet from following URL


Place the portlet into your plugins/portlet directory

Create portlet using Liferay IDE from existing portlet and select portlet what you have downloaded.

Note:

 before import please delete .project, .classpath and .settings  files from downloaded portlet.

Create   data base in mysql database  name is “anotherdatabase”  

Create Table name is TableFromAnotherDataSource in “anotherdatabase”  database.

CREATE TABLE `tablefromanotherdatasource` (
            `IFADSId` BIGINT(20) NOT NULL,
            `Description` VARCHAR(75) NULL DEFAULT NULL,
            PRIMARY KEY (`IFADSId`)
);

Add following properties in portal-ext.properties file

jdbc.anotherdbconfig.driverClassName=com.mysql.jdbc.Driver
jdbc.anotherdbconfig.url=jdbc:mysql://localhost:3306/anotherdatabase?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.anotherdbconfig.username=root
jdbc.anotherdbconfig.password=

Note:

When we change portal-ext.proprties file you have to stop server after add some properties you have to restart.

portal-ext.properties file should be available in liferay home path if not you have to create and add above properties.

Generally home path like below

/bundles/ portal-ext.proprties  or liferay-portal-6.1.1-ce-ga2/ portal-ext.proprties 

Run ant build-service target from your eclipse ant view

Run and deploy then portle will be deployed

Note: 
this portlet developed in Loferay Portal 6.1GA2 version and Plug-in SDK 6.1GA2

This portlet will use to connect to multiple data bases. When we get requirement plugin portlet need to connect to multiple databases or data sources we have to configure data source and Session Factory information in ext-spring.xml. 

We have to create xml file and we need to place file in src/META-INF/ext-spring.xml

Generally Liferay plugin portlets uses default liferay database or data source. If we want connect to another database we have to configure those details in ext-spring.xml file.

Once we configured the data source and session factory in ext-spring.xml file then have to use these data source information in service.xml file that’s for entity.

following is ext-spring.xml

<?xml version="1.0"?>
<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
       xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

       <bean id="anotherDataSource"
              class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
              <property name="targetDataSource" ref="anotherDataSourceWrapper" />
       </bean>
       <bean id="anotherDataSourceImpl"
              class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean">
              <property name="propertyPrefix" value="jdbc.anotherdbconfig." />
       </bean>
       <bean id="anotherDataSourceWrapper" class="com.liferay.portal.dao.jdbc.util.DataSourceWrapper">
              <constructor-arg ref="anotherDataSourceImpl" />
       </bean>
       <bean class="com.liferay.portal.dao.jdbc.util.DataSourceSwapper">
              <property name="liferayDataSourceWrapper" ref="anotherDataSourceWrapper" />
       </bean>
       <bean id="anotherHibernateSessionFactory" class="com.liferay.portal.kernel.spring.util.SpringFactoryUtil"
              factory-method="newBean">
              <constructor-arg                  value="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration" />
              <constructor-arg>
                     <map>
                           <entry key="dataSource" value-ref="anotherDataSource" />
                     </map>
              </constructor-arg>
       </bean>
       <bean id="anotherSessionFactory" class="com.liferay.portal.kernel.spring.util.SpringFactoryUtil"
              factory-method="newBean">
              <constructor-arg
                     value="com.liferay.portal.dao.orm.hibernate.PortletSessionFactoryImpl" />
              <constructor-arg>
                     <map>
                           <entry key="dataSource" value-ref="anotherDataSource" />
                           <entry key="sessionFactoryClassLoader" value-ref="portletClassLoader" />
                           <entry key="sessionFactoryImplementor" value-ref="anotherHibernateSessionFactory" />
                     </map>
              </constructor-arg>
       </bean>
</beans>


Once we configured data source and session factory in ext-spring.xml we have to provide data source properties from portal-ext.properties file which in you liferay home path.

Generally home path like below

/bundles/ portal-ext.proprties  or liferay-portal-6.1.1-ce-ga2/ portal-ext.proprties 

Add the following properties in portal-ext.proprties 

jdbc.anotherdbconfig.driverClassName=com.mysql.jdbc.Driver
jdbc.anotherdbconfig.url=jdbc:mysql://localhost:3306/anotherdatabase?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
 jdbc.anotherdbconfig.username=root
 jdbc.anotherdbconfig.password=


Note: 

jdbc. anotherdbconfig. Is the propertyPrefix which we have mentioned in ext-spring.xml file


<bean id="anotherDataSourceImpl"
                        class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean">
                        <property name="propertyPrefix" value="jdbc.anotherdbconfig." />
</bean>


Now we have to provide this information to entity which we have configured in service.xml .

In entity tag we have two attributes from that we can explicitly said about data source and session factory information .

<entity name="TableFromAnotherDataSource" table="TableFromAnotherDataSource"  local-service="true" remote-service="true" data-source="anotherDataSource" session-factory="anotherSessionFactory">
                        <column name="IFADSId" type="long" primary="true" />
                        <column name="Description" type="String" />
            </entity>


Note: 
we have table attribute in entity tag when we mention this entity class targeting to that particular table

If we not provide table attribute then service builder create table name as namespace_entityname

If provide table attribute then table will be created exact name that we provided in table attribute.

Example:

We already having existed data base then we need not create tables from service builder then we just pass table name in table attribute then out entity class targeting to that table.

Observations:

Note: 

When we use other data source for plugin portlet when we run service builder then tables creation script is not create so we have to create table manually in database if the table is new.

If you need create table script you can see in the class XXXModelImpl.java

XXX= entity Name

public static final String TABLE_SQL_CREATE = "create table TableFromAnotherDataSource (IFADSId LONG not null primary key,Description VARCHAR(75) null)";

You can also find data source and session factory that is used by your Entity class

public static final String DATA_SOURCE = "anotherDataSource";
public static final String SESSION_FACTORY = "anotherSessionFactory";


Friday, March 8, 2013

Liferay search container with curd operations.


Liferay search container with curd operations.

I create port let which explained how to use life ray search container to display records as grid.
I added some of records in person tables and I display all records in liferay grid and when click on any row it will navigate to update form, once we finished upadate it will navigate to search container page.
The following the link to get search container portlet.

Steps to run the portlet:
1.      Download portlet
2.      Place the portlt into liferau plugins/portlet directory / if you are use Liferay IDE create liferay project from existing source
3.      Run ant build-service
4.      Run ant deploy
5.      See the sample category and drag and drop the port let
6.      If records available you can see the records otherwise add new person by click on Add new person link.
7.      When you click on liferay grid row you can update the person record.

Screen Shots:


Note: This is done in liferay6.0.6 if you are using liferay 6.1 then create your portlet and manually copy file to your portlet. When you copy portet.xml , liferay-portelt.xm. you should not copy directly because dtd version changed so make sure dtd version should acceding to liferay versions.

Friday, March 1, 2013

Connection pooling in multithreaded applications


Connection pooling in multithreaded applications

Introduction
This article talks about developing design approaches for multithreaded applications performing database operations. While developing a multithreaded database application, we always end up scratching our heads answering (or trying to answer) mischievous questions as:
  1. Who should create the connection object?
  2. Should a connection object be a property of the business object? Or should it be used as a utility?
  3. How to handle transaction operations?
  4. Who should dispose the connection object?
Looks like seven W's of Wisdoms are making enough noise in our head. I found my way of answering these questions, and I am sharing them here with you. I have tried two approaches for it, which are described here.
Single connection object, multiple transactions objects
I have used the Singleton design pattern to make sure that only one connection object is created. The same connection object is shared across multiple threads. It is now every individual thread's responsibility to handle the transaction. Every thread will create its own transaction object and will pass it to all commands it will be executing. So straight away, the thread should maintain its own commit and rollback policy. Thus, a single connection may execute multiple transactions simultaneously, wholly managed by the calling threads.
As parallel transactions are not supported by the database, make sure the code block handling the opening of the connection and transaction creation is executed under a lock mechanism. Thus, in this approach, though we can use the same connection object, we have to make sure the code is thread safe (use of lock).
Advantages:
  1. Implements a Singleton, shares one connection object across multiple calling threads.
  2. No need to dispose the connection object (but you must call the close method).
Disadvantages:
  1. Does not use the connection pool feature, as only one connection object is created and used.
  2. Increases execution time as the command must be executed using the same connection object.
Here is the block diagram for the singleton approach:
Multiple connection objects
The multiple connection approach is slightly different. This one gives the calling code control of the connection object. It becomes the calling code's responsibility to use and dispose the connection object. In an ideal scenario, the calling code (Business Layer) should not hold the reference of the connection object. It should request for the connection object when required, and use and pass it to its sub-routines, if required. Thus, the connection object is opened in a method and closed in the same one. The pseudo-code will look like:
Method (){
 - Create local connection object, open it
 - Do transaction with database.
 - Pass connection object to other methods called from this.
 - Commit or rollback transaction
 - Close connection, dispose it
}
This approach allows us to create multiple connection objects and execute them in parallel. But, it also enforces some conditions as:
  1. Calling code should take ownership of the connection object.
  2. Calling code should handle the connection pool by declaring it in the connection string.
  3. As there could be multiple connections opened simultaneously, it's the calling code which must maintain the relationship between the connection and its transaction.
Advantages:
  1. Uses connection pool to create multiple connections simultaneously.
  2. Faster compared to singleton, as multiple connections will execute their own transactions.
Disadvantages:
1.       Need to make sure that the connection object is disposed properly.
2.       Connection object needs to pass through methods.
Here is the block diagram for the multiple connection approach:

Thursday, February 28, 2013

Liferay Important Code Snippets

Get Theme display object
<portlet:defineObjects />
<liferay-theme:defineObjects/>
<%=themeDisplay%>

Get PortletDisplay Object

themeDisplay.getPortletDisplay()


PortletConfigurationUrl

themeDisplay.getPortletDisplay().getURLConfiguration()


RenderURL creation

<portlet:renderURL var="configurationURL" windowState="pop_up">
 <portlet:param name="struts_action" value="/portlet_configuration/edit_configuration"></portlet:param>
 </portlet:renderURL>
=====================
  <portlet:renderURL var="sendEmailURL" windowState="<%= LiferayWindowState.EXCLUSIVE.toString() %>">
    <portlet:param name="jspPage" value="/html/adminfeedbackportlet/mailsent.jsp"/>
  </portlet:renderURL>



Use back url in JSP Pages:

<liferay-ui:header
            backURL="<%= backURL %>"
            title='<%= (organization == null) ? "new-organization" : organization.getName() %>'
/>


PropsValues class

public static final String[] ORGANIZATIONS_FORM_ADD_MAIN = PropsUtil.getArray(PropsKeys.ORGANIZATIONS_FORM_ADD_MAIN);
String[] mainSections = PropsValues.ORGANIZATIONS_FORM_ADD_MAIN;
String[] identificationSections = PropsValues.ORGANIZATIONS_FORM_ADD_IDENTIFICATION;
String[] miscellaneousSections = PropsValues.ORGANIZATIONS_FORM_ADD_MISCELLANEOUS;


Combine Multiple Arrays

String[] allSections = ArrayUtil.append(mainSections, ArrayUtil.append(identificationSections, miscellaneousSections));


Prevent Default Success Messages in Jsp Pages After Action performed.
Write this in portlet.xml file

<init-param>
            <name>add-process-action-success-action</name>
            <value>false</value>

 </init-param>


Get ThemeDisplay Object in Action Class

ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);


Form Submission through js and dynamic URL
submitForm(document.<portlet:namespace />fm, "<portlet:actionURL><portlet:param name="struts_action" value="/enterprise_admin/edit_organization" /></portlet:actionURL>");



Get Original HttpRequest in lifaray action class

PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(actionRequest))


Get Search Container IteratorURL

searchContainer.getIteratorURL();


If you want to change to logic say for just one action you can override the method

     protected void addSuccessMessage(
        ActionRequest actionRequest, ActionResponse actionResponse) {
        if (!addProcessActionSuccessMessage) {
            return; }
        String successMessage = ParamUtil.getString(
            actionRequest, "successMessage");
        SessionMessages.add(actionRequest, "request_processed", successMessage); }



Find organization and community

ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
long orgnizationId=0;
 com.liferay.portal.model.Group currentGroup =  themeDisplay.getLayout().getGroup();
 if (currentGroup.isOrganization()){
            orgnizationId = currentGroup.getClassPK();
 } else if (currentGroup.isCommunity() {
            orgnizationId = currentGroup.getGroupId();}}


Gets Session Messages

<c:if test='<%= SessionMessages.contains(renderRequest.getPortletSession(),"lore-request-added-successfully")%>'>
<liferay-ui:success key="lore-request-added-successfully" message="lore-request-added-successfully" />
</c:if>

           

AUI.IO.Request for Action URL
Liferay.provide(window,'<portlet:namespace />TestFunction',
function() {var A = AUI();
A.io.request('<portlet:actionURL><portlet:param name="javax.portlet.action" value="searchLoreBasedOnCategory" /></portlet:actionURL>',{
data: {directionsAddress:'meera',},
on: {failure: function() {alert("failure");},
success: function(event, id, obj) {
alert("sucess");}}});},'aui-io-request']);


jquery Ajax Function
jQuery.ajax({type : "POST",
url :"<%=feedbackActionURL.toString()%>", dataType : "html",
data: {user_Name:userName,feedBackType:feedBackType},
success:function(msg) {… },
error : function() {..}});



Hibernate Auto dll

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- This should be set to validate on production -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.format_sql">true</property>
        <property name="show_sql">true</property>
    </session-factory>
</hibernate-configuration>    


Important HttpRequest Methods
Actual Reqest for this: http://www.vidyayug.com:8080/c/portal/login?p_l_id=18009

request.getRemoteAddr()>> 127.0.0.1
request.getRemoteHost()>> 127.0.0.1
request.getRemotePort()>> 3899
request.getRequestURI()>> /c/portal/login
request.getLocalPort()>>  8080
request.getLocalAddr()>>  127.0.0.1
request.getPathInfo()>>    /portal/login
request.getQueryString()>> p_l_id=18009
request.getServerPort()>>  8080
request.getRequestURL()>> http://www.vidyayug.com:8080/c/portal/login


Display Session Messages

<c:if test="<%= SessionMessages.contains(portletRequest, key) %>">
            <div class="portlet-msg-success">
                        <c:choose>
                                    <c:when test="<%= translateMessage %>">
                                                <%= LanguageUtil.get(pageContext, message) %>
                                    </c:when>
                                    <c:otherwise>
                                                <%= message %>
                                    </c:otherwise>
                        </c:choose>
            </div>
</c:if>


Special Characters Regular Expression

var regExpression=/[&\/\\#,+()$~%.'":*?<>{}^!@|;?"`~]/;
var indiaMobileNumber = /^[7-9]\d*(?:\d+)?$/;


Sign In and Create Account URL with Icons

<liferay-ui:icon-list><liferay-ui:icon image="add_user" message="create-account"
url="<%= themeDisplay.getURLCreateAccount().toString() %>"/>
<liferay-ui:icon image="status_online" message="sign-in" url="<%= themeDisplay.getURLSignIn() %>"/>
</liferay-ui:icon-list>


Apply Liferay css to our messages
<div class="portlet-msg-info"> Please select a tool from the left menu.</div>
<div class="portlet-msg-success"> Please select a tool from the left menu.</div>
<div class="portlet-msg-error"> Please select a tool from the left menu.</div>


Liferay Tool Tip

<img alt="" onmouseover="Liferay.Portal.ToolTip.show(this, '<%=helpMessage %>');" src="/html/themes/control_panel/images/portlet/help.png" id="tooltipMessage">


Resource messages with variable values

loreshare-categories-count-message=Lore Share found more than {0} {1}.Hurry up you can search what you
<%= LanguageUtil.format(pageContext, "loreshare-categories-count-message",new String[]{String.valueOf(categoryBasedLoreCount),String.valueOf(loreCategoryName)})


Get Organization Logo
Organization organization = (Organization)request.getAttribute(WebKeys.ORGANIZATION);
long logoId = organization.getLogoId();
<%= themeDisplay.getPathImage() %>/organization_logo?img_id=<%= logoId %>&t=<%= ImageServletTokenUtil.getToken(logoId) %>


Call Portal Services through Java script API.
Below code give all countries which are in active state.

<script src="/html/js/liferay/service.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
function getCountry() {Liferay.Service.Portal.Country.getCountries({active:'<%=true%>'},
function(msg){alert(msg[0].countryId);});
}
</script>


The Following code in Entity ModelImpl class. If we set these properties in properties file then we can enable or disable cache for particular entity. This cache applicable foe Entity and Finder cache. By default it is true.
Following is we can write in property files.

value.object.entity.cache.enabled.YOUR ENTITY MODEL CLASS NAME WITH FULLY QUAKIFIED NAME=true/false
value.object.finder.cache.enabled.YOUR ENTITY MODEL CLASS NAME WITH FULLY QUAKIFIED NAME=true/false
lock.expiration.time.YOUR ENTITY MODEL CLASS NAME WITH FULLY QUAKIFIED NAME= its Number
public static final boolean ENTITY_CACHE_ENABLED = GetterUtil.getBoolean(com.liferay.util.service.ServiceProps.get(
"value.object.entity.cache.enabled.com.vidyayug.global.model.ApplicationParamGroup"),true);
public static final boolean FINDER_CACHE_ENABLED = GetterUtil.getBoolean(com.liferay.util.service.ServiceProps.get(
"value.object.finder.cache.enabled.com.vidyayug.global.model.ApplicationParamGroup"),true);
public static final long LOCK_EXPIRATION_TIME = GetterUtil.getLong(com.liferay.util.service.ServiceProps.get(                "lock.expiration.time.com.vidyayug.global.model.ApplicationParamGroup"));


Load Portal class and Portlet Classes
PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.UserImpl")
Ex:
query.addEntity("User_", PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.UserImpl"));
ClassLoader classLoader = (ClassLoader)PortletBeanLocatorUtil.locate(ClpSerializer.SERVLET_CONTEXT_NAME,
"portletClassLoader");
classLoader. loadClass("your portlet class name with fully qualified name");
Ex: query.addEntity("feedBack", classLoader.loadClass("com.vidyayug.global.model.impl.ApplicationParamGroupImpl"));


Get the Portlet level session Factory object.

private static SessionFactory  sessionFactory = (SessionFactory)PortalBeanLocatorUtil.locate("liferaySessionFactory");
session = sessionFactory.openSession();


Print log  messages in console:

private static Log _log = LogFactoryUtil.getLog(UniversalCommunicationAction.class);
_log.error("Number format exception whhile paring selected criteri id Cerittin Id migh not be expected value");
_log.info("this is json object====="+criteriaControlIdObject);


JQGrid:

jQuery('#list3').jqGrid('getGridParam','datatype')
jQuery('#list3').jqGrid('setGridParam',{page:1}).trigger('reloadGrid');
jQuery("#list3").jqGrid("clearGridData");
jQuery('#list3').jqGrid('getGridParam','reccount')
jQuery("#gridWrapper").hide();
var allrowssel_ids = grid.jqGrid('getGridParam', 'selarrrow');
var single row = jQuery("#list3").jqGrid('getGridParam','selrow');
var myCellData = grid.jqGrid('getCell', sel_ids[0], 'userId');


Get Phones List:
PhoneLocalServiceUtil.getPhones(String companyId, String className, String classPk)
Where companyId is the companyId you are using, classname is 'com.liferay.portal.model.Contact', and the classPk is the username you want.
This should return you a list of com.liferay.portal.model.Phone objects.


Check Method on Process Action This URL can only be invoked using POST

protected boolean isCheckMethodOnProcessAction() {
              return _CHECK_METHOD_ON_PROCESS_ACTION;
        }
private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;




Instance Factory is class creating instances for classes which are outside the current class loader.


Get Portlet Configuration URL
themeDisplay.getPortletDisplay().getURLConfiguration()


Get Organization URL

set ($test_url = (($theme_display.getPortalURL()) + "/" + ($theme_display.getLocale()) + ("/web") + ($group.getFriendlyURL()) + ("/sitemap")))



Load class and create object

Class<?> classObj=PortalClassLoaderUtil.getClassLoader().
loadClass("com.liferay.portlet.journal.model.impl.JournalArticleImpl");
JournalArticle journalArticleObj = (JournalArticle)classObj.newInstance();

Create URL for Portlet
PortletURL portletURL = PortletURLFactoryUtil.create(request,PortletKeys.PORTLET_CONFIGURATION, plid,PortletRequest.RENDER_PHASE);
portletURL.setParameter("struts_action", "/portlet_configuration/edit_permissions");
portletURL.setParameter("redirect", PortalUtil.getCurrentURL(request));
portletURL.setParameter("returnToFullPageURL",PortalUtil.getCurrentURL(request));
portletURL.setParameter("portletResource", "onceclicksite_WAR_OneclickSiteportlet");
portletURL.setParameter("resourcePrimKey", PortletPermissionUtil.getPrimaryKey(10296,"onceclicksite_WAR_OneclickSiteportlet"));
portletURL.setWindowState(LiferayWindowState.POP_UP);
portletURL.setPortletMode(PortletMode.VIEW);


Get Portlet List in Layout

LayoutTypePortlet layoutTypePortlet1 = (LayoutTypePortlet)layoutObject.getLayoutType();
              List<Portlet> portletList = layoutTypePortlet.getPortlets();


AUI Pop UP window
AUI().use('aui-dialog', 'aui-io', 'event', 'event-custom', function(A) {             
 var smsDialog = new A.Dialog({   title: 'Site Preview',  centered: true, draggable: true,
  modal: true, width:600, height:400}).plug(A.Plugin.IO, {uri:url,data:{ }}).render();
smsDialog.show();});


JQuery On Click Function
jQuery('#<portlet:namespace />publicLayoutSetPrototypeId').change(function(){
alert("this is meera");
});


Jquery Selected option value
var optioVal=jQuery('#<portlet:namespace />publicLayoutSetPrototypeId option:selected').val();
alert(jQuery(this).val());
alert(optioVal);
});


Jquery get Css property values
jQuery('#theid').css('display')
Jquery Add  Css property values
jQuery('#theid').css('display','none')


Jquery Add dynamic options
jQuery('#<portlet:namespace />siteDefaultRoles ').append( new Option(text,msg[0].val));
jQuery('#<portlet:namespace />siteDefaultRoles ').append('<option value="'+msg[k].categoryId+'" selected="selected">'+msg[k].categoryName+'</option>');


Jquery Bind events to element.
<input class="aui-field-input aui-field-input-text" id="eleId" name="elename" type="text" value="" selector="site-cutome-role-name">
 jQuery('[selector="site-cutome-role-name"]').bind('keypress keydown keyup', function(){
alert("this is in textt bxa key uppp");
jQuery('[selector="site-default-user-name"]').each(function() {
});});


jQuery Find element

jQuery("#siteCustomeRoles").find(".aui-field-input-select");


jQuery Empty method
Remove all child elements

jQuery("#siteCustomeRoles").find(".aui-field-input-select").empty();


jQuery remove method remove selected element and its Childs.


jQuery("#siteCustomeRoles").remove();


jQuery add attribute method to element

jQuery("#siteCustomeRoles").find(".aui-field-input-text").attr("placeholder", msg[k].categoryName);


jQuery after method
add element after sleelcted object

jQuery("#siteCustomeRoles").after(currentRow.html());



Creating Portlet URLs(renderURL/actionURL/resourceURL) in Liferay through jsp and javascript

Here I am creating renderURL only.Other URL's can be created in the similar way
 In JSP :
<portlet:renderURL var="renderURL ">
    <portlet:param name="param-name" value="param-value" />
    <portlet:param name="param-name" value="param-value" />
</portlet:renderURL>
OR
 <%
           PortletURL renderURL = renderResponse.createRenderURL();
           renderURL.setParameter("param-name", "param-value");
           renderURL.setParameter("param-name", "param-value");
%>


In the above example param-name could be "jspPage" and param-value could be "/html/edit.jsp" if you want to navigate from current jsp page to some other jsp page (in this case edit.jsp) . We can set other parameters also as per our requirements.

Inside your java script :
<script type="text/javascript">
function createRenderURL() {
    AUI().ready('liferay-portlet-url', function(A) {
        var renderURL = Liferay.PortletURL.createRenderURL();
        renderURL .setParameter("param-name","param-value");
        renderURL .setPortletId("your-unique-portlet-id");
        // i.e. your-unique-portlet-id can be like "helloworld_WAR_helloworldportlet"
    });
}
</script>


Note: Key point here is to set PortletId which is mandatory or else it would not be able to recognize the correct URL.
Playing with portletURL in Liferay
Without tld :
1.To get currentURL :
PortletURL url = PortletURLUtil.getCurrent(renderRequest, mimeResponse or renderResponse)


2. To make clone of a URL:
PortletURL url = PortletURLUtil.clone(portletURL, mimeResponse or renderResponse)


3. Creating PortletURL from action Response:

PortletURL renderURL = ((ActionResponseImpl) actionResponse).createRenderURL();


4. Creating PortletURL from render Response:
a.For RenderURL:
PortletURL renderURL = renderResponse.createRenderURL();
b.For actionURL:
PortletURL actionURL = renderResponse.createActionURL();


5. Using TLD's in Life ray :
a.
<portlet:renderURL windowState="<%= WindowState.ur_state.toString() %>">
<portlet:param name="param_name" value="param_value" />
<portlet:param name="param_name" value="param_value" />
</portlet:renderURL>
b.
<portlet:actionURL windowState="<%= WindowState.ur_state.toString() %>">
<portlet:param name="param_name" value="param_value" />
<portlet:param name="param_name" value="param_value" />
</portlet:actionURL>



If you put the *-service.jar inside the tomcat/lib/ext then you should remove it from your custom-portlet's WEB-INF/lib/.
I would suggest using the following property in your liferay-plugin-package.properties in all other portlets which use the services of MyCommon-portlet:
required-deployment-contexts=MyCommon-portlet
Only put the *-service.jar inside the tomcat/lib/ext when you need that your *-service.jar's method should be available to even the Hooks or EXTs you would create. For custom plugin portlets the liferay-plugin-package.properties should suffice.




Recent Posts

Recent Posts Widget

Popular Posts