Recent Bloggers

Milen Dyankov

Staff
5 Publications
9 décembre 2016

gulnaaz Shaik

2 Publications
8 décembre 2016

Javeed Chida

15 Publications
8 décembre 2016

Neeraj Gautam

Staff
1 Publications
7 décembre 2016

David H Nebinger

32 Publications
6 décembre 2016

Vikash Chandrol

1 Publications
2 décembre 2016

Eduardo P. Garcia

Staff
10 Publications
2 décembre 2016

James Hinkey

Staff
6 Publications
29 novembre 2016

Adrian Johnson

Staff
1 Publications
22 novembre 2016

Lauri Hiltunen

8 Publications
21 novembre 2016

Liferay Arquillian test cases using maven and spring

General Blogs 2 août 2016 Par priti parmar

Liferay Arquillian test cases using maven and spring

Arquillian integrates seamlessly with familiar testing frameworks (e.g., JUnit, TestNG), allowing tests to be launched using existing IDE, Ant and Maven test plugins.

Arquillian can use three containers types 

1. Embedded: the test runner contains the container as a library

2. Managed: the test runner starts and stops the container as a separated process

3. Remote: the test runner relies on an operational container, already started.

There are a few steps required to setup and run Arquillian for plugin projects.

  • Setup Tomcat for Arquillian
  • Configure Project
  • Write Unit Test Case
  • Code coverage Report

Setup Tomcat for Arquillian

1. Adding Users to Tomcat

Arquillian will deploy the plugin inside the container which is how it has a runtime with which it can locate your dependencies from the test. 

Go to your $TOMCAT_HOME/conf directory and open the tomcat-users.xml file. 

If none exists, create it and add the following to the file  Save and close the file

   <?xml version="1.0"?>

            <tomcat-users>

        <role rolename="tomcat" />

        <role rolename="manager-gui" />

        <role rolename="manager-script" />

        <role rolename="manager-jmx" />

        <role rolename="manager-status" />

        <user password="tomcat" roles="tomcat, manager-gui,

  manager-script ,manager-jmx, manager-status"  

username="tomcat"/>

</tomcat-users>

2. Add Connection for Arquillian

Arquillian is going to use the manager application of Tomcat to deploy the plugin as part of the test execution, So modify environment properties to support it.

              Make sure that tomcat has manager folder in webapps directory.

  • Go to your $TOMCAT_HOME/bin directory and open the setenv.sh (if you are on MAC/Linux) or setenv.bat (if you are on Windows)

  • Add the following to the file.

JMX_OPTS="-Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.authenticate=false  -Dcom.sun.management.jmxremote.port=8099  -Dcom.sun.management.jmxremote.ssl=false"

       CATALINA_OPTS="${CATALINA_OPTS} ${JMX_OPTS}"

You can alter port to use a different value other than 8099 – but this is the "default" value.

Restart your TOMCAT server to make sure the changes are picked up.

 

Configure Project

 1. Open the pom.xml for your project and add below dependencies

<!-- Test Dependencies -->

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

</dependency>

<dependency>

<groupId>org.jboss.arquillian.container</groupId>

<artifactId>arquillian-tomcat-remote-7</artifactId>

<version>1.0.0.CR7</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.jboss.shrinkwrap.resolver</groupId>

<artifactId>shrinkwrap-resolver-impl-maven</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.jboss.arquillian.junit</groupId>

<artifactId>arquillian-junit-container</artifactId>

<scope>test</scope>

</dependency>

Note: arquillian-tomcat-remote-7 is for Container type Remote for Managed use arquillian-tomcat-managed-7 and for embedded use arquillian-tomcat-embedded-7 maven dependencies

2. Add the following dependency management node just above your listed dependencies

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.jboss.arquillian</groupId>

<artifactId>arquillian-bom</artifactId>

<version>1.1.11.Final</version>

<scope>import</scope>

<type>pom</type>

</dependency>

</dependencies>

</dependencyManagement>

3 .Now add a folder called java under the /src/test folder.

4. Add a new folder resources and create a new file called arquillian.xml and place the following contents (adjusting values based on your settings).

  • Arquillian settings for Remote type container :

<?xml version="1.0" encoding="UTF-8"?>

<arquillian xmlns="http://jboss.org/schema/arquillian"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://jboss.org/schema/arquillian  http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

    <engine>

        <property name="deploymentExportPath">target/deployments</property>

    </engine>

    <container qualifier="tomcat" default="true">

        <configuration>

            <property name="user">tomcat</property>

            <property name="pass">tomcat</property>

        </configuration>

    </container>    

</arquillian>

  • Arquillian settings for Managed type container 

        <container qualifier="tomcat" default="true">

        <configuration>

            <property name="user">tomcat</property>

            <property name="pass">tomcat</property>

            <property name="catalinaHome">Path of Tomcate folder</property>

            <property name="catalinaBase">Path of Tomcate folder</property>

        </configuration>

    </container>

 

Write Unit Test Case

Click on the /test/java folder and create new test classes  ArquillianDeployment.java and MyArquillianPortletTest.java

  • ArquillianDeployment.java is a generic class which is used to define a deployment type of test cases (ex : war or jar).

package com.arquillian.portlet.test;

import java.io.File;

import org.jboss.shrinkwrap.api.ShrinkWrap;

import org.jboss.shrinkwrap.api.spec.WebArchive;

import org.jboss.shrinkwrap.resolver.api.maven.Maven;

import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;

public class ArquillianDeployment {

private static final String LOCAL_WEBAPP_DIR = "src/main/webapp/WEB-INF";

public static WebArchive createDeployment() {

PomEquippedResolveStage mavenResolver =  Maven.resolver().loadPomFromFile("pom.xml");

File[] libs = mavenResolver.importRuntimeAndTestDependencies().resolve().withTransitivity().asFile();

WebArchive war = ShrinkWrap.create(WebArchive.class, "arquillian-test.war")

.addPackages(true,"com.arquillian.portlet.test","com.arquillian.controller")

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR, "portlet.xml"))

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR,    "liferay-plugin-package.properties"))

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR, "liferay-display.xml"))

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR, "liferay-portlet.xml"))

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR+"/spring-context/portlet",    "arquillian-portlet.xml"),"/spring-context/portlet/arquillian-portlet.xml")

.addAsWebInfResource(new File(LOCAL_WEBAPP_DIR+"/spring-context",  "portlet-application-context.xml"), 

"/spring-context/portlet-application-context.xml");

for (File file : libs) { war.addAsLibrary(file);}

return war;

}

}

  • MyArquillianPortletTest.java is Arquillian test class which used to create test methods

package com.arquillian.portlet.test;

import org.jboss.arquillian.container.test.api.Deployment;

import org.jboss.arquillian.junit.Arquillian;

import org.jboss.shrinkwrap.api.spec.WebArchive;

import org.junit.Before;

import org.junit.Test;

import org.junit.runner.RunWith;

import com.liferay.portal.kernel.log.Log;

import com.liferay.portal.kernel.log.LogFactoryUtil;

import com.arquillian.controller.PortletViewController;

@RunWith(Arquillian.class) 

public class MyArquillianPortletTest {

private static Log LOGGER  = 

LogFactoryUtil.getLog(MyArquillianPortletTest.class);

private PortletViewController mvcPortlet;

private long userId=10101;

@Deployment(name="MyArquillian")

public static WebArchive init() {

return ArquillianDeployment.createDeployment();

}

@Before

public void setUp() throws Exception {

mvcPortlet = new PortletViewController();

}

  @Test

    public void testGetUserDetails(){

          mvcPortlet.getUserDetails(userId); 

     }

}

3. Save the file

4. Execute test cases by maven clean test.

 

Code Coverage Report using Jacoco

Jacoco is a free code coverage library for Java. it is very simple to add to all types of build including ANT and Maven.

  • Add Jacoco profile in pom.xml

<profiles>

<profile>

    <id>jacoco</id>

    <dependencies>

        <dependency>

            <groupId>org.jacoco</groupId>

            <artifactId>org.jacoco.core</artifactId>

            <version>0.7.4.201502262128</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.jboss.arquillian.extension</groupId>

            <artifactId>arquillian-jacoco</artifactId>

            <version>1.0.0.Alpha8</version>

            <scope>test</scope>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.jacoco</groupId>

                <artifactId>jacoco-maven-plugin</artifactId>

                <version>0.7.4.201502262128</version>

                <executions>

                    <execution>

                        <goals>

                            <goal>prepare-agent</goal>

                        </goals>

                   </execution>

                    <execution>

                        <id>report</id>

                        <phase>prepare-package</phase>

                        <goals>

                            <goal>report</goal>

                        </goals>

                    </execution>

                </executions>

            </plugin>

        </plugins>

    </build>

</profile>

  • Run unit test cases using maven clean test -Pjacoco jacoco:report

NOTE: 

  • Generated war of test classes will be store in \target\deployments folder of portlet
  • You can see report in \target\site\jacoco folder.

 

 

Set display order of different elements in the journal article.

General Blogs 19 novembre 2014 Par priti parmar

If content creator wants to decide during creation in which order the different elements will be displayed in the article then there should be a field like DisplayOrder which decide the position of elements in the article , By using structure and templates it is possible to achive this requirment.

Lets have a simple example of structure and template .

Structure has Content_Title , Display_Order1 ,Body &  Display_Order2 elements .

  • Display_Order1  is a child element of Content_Title
  • Display_Order2 is a child element of Body field. 

Cotnent_Title and Body both are repeated fields.

Now in template read all elements and decide their positions based on its display order.

so as a result end user will able to view the content based on decided order.

Step1 : create a structure:

 <root available-locales="en_US" default-locale="en_US">

     <dynamic-element dataType="string" indexType="keyword" name="Content_Title" readOnly="false"            
                    repeatable="true" required="false" showLabel="true"  type="text" width="small">
                       <dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword"
                               name="Display_Order1" readOnly="false"                
                               repeatable="false" required="true" showLabel="true" type="ddm-number" width="small">
                                 <meta-data locale="en_US">
                                  <entry name="label"><![CDATA[Display Order]]></entry>
                                  <entry name="predefinedValue"><![CDATA[1]]></entry>
                                  <entry name="tip"><![CDATA[]]></entry>
                                  </meta-data>
                          </dynamic-element>
                           <meta-data locale="en_US">
                                <entry name="label"> <![CDATA[Content Title]]></entry>
                               <entry name="predefinedValue"> <![CDATA[]]></entry>
                                <entry name="tip"><![CDATA[]]></entry>
                             </meta-data>
             </dynamic-element>
             <dynamic-element dataType="html" fieldNamespace="ddm" indexType="keyword" name="Body"
                         readOnly="false" repeatable="true"            
                         required="true" showLabel="true" type="ddm-text-html" width="small">
                           <dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword" n              
                                      name="Display_Order2" readOnly="false"          
                                      repeatable="false" required="false" showLabel="true" type="ddm-number" width="small">
                                      <meta-data locale="en_US">
                                           <entry name="label"><![CDATA[Display Order]]></entry>
                                           <entry name="predefinedValue"><![CDATA[2]]></entry>
                                           <entry name="tip"><![CDATA[]]></entry>
                                      </meta-data>
                             </dynamic-element>
                           <meta-data locale="en_US">
                            <entry name="label"><![CDATA[Body]]></entry>
                            <entry name="predefinedValue"><![CDATA[]]></entry>
                            <entry name="tip"><![CDATA[]]></entry>
                            </meta-data>
              </dynamic-element>
</root>
 
 
Step 2: create template
    " #set($displayItems = [])
      #if (!$Content_Title.getSiblings().isEmpty())
              #foreach($cur_Content_Title in $Content_Title.getSiblings())
                            #set($void = $displayItems.add({"sortOrder" : $cur_Content_Title.Display_Order1.getData(), 
                                   "itemField" : $cur_Content_Title.getData() }))
              #end
      #end
      #if (!$Body.getSiblings().isEmpty())
              #foreach ($cur_Body in $Body.getSiblings())
                             #set($void = $displayItems.add({"sortOrder" : $cur_Body.Display_Order2.getData(), 
                                    "itemField" : $cur_Body.getData()}))
               #end
      #end
      #set($size=$displayItems.size())
      #foreach($obj in $displayItems)
             #if($obj.sortOrder)
                 #if($getterUtil.getNumber($obj.sortOrder) > $size)
                      #set($size=$getterUtil.getNumber($obj.sortOrder))
                  #end 
             #end
      #end 
      #foreach ($number in [1..$size])
             #foreach($items in $displayItems)
                 #if($items.sortOrder == $number)
                      <div>$items.itemField</div>
                   #end
            #end
      #end"
 
 
 

Search Organization using Facets Search

General Blogs 16 juillet 2013 Par priti parmar

Liferay provide facet search with great features ,we can add new entries in search using configuration of portlet  to achive this follow the below steps,

Step 1 : create a hook

  • override init.jsp in hook add organization model entry

 

if (displayAssetTypeFacet) {

sb.append("{className: 'com.liferay.portal.kernel.search.facet.AssetEntriesFacet',

data: {frequencyThreshold: 1, values:

[ 'com.liferay.portlet.blogs.model.BlogsEntry',

'com.liferay.portlet.documentlibrary.model.DLFileEntry',

'com.liferay.portlet.journal.model.JournalArticle',

'com.liferay.portlet.wiki.model.WikiPage',

'com.liferay.portal.model.User',

'com.liferay.portal.model.Organization'

]},

displayStyle: 'asset_entries', fieldName: 'entryClassName',

label: 'asset-type',

order: 'OrderHitsDesc',

static: false,

weight: 1.5},

");

}

 

  • override main_search_result_form.jsp and add url entry for organization detail view

 

PortletURL portletURL = (PortletURL)request.getAttribute("search.jsp-portletURL");

//Condition for Organization redirection

PortletURL orgURL = PortletURLUtil.clone(portletURL, renderResponse);

orgURL.setParameter("struts_action", "/search/view_organization");

orgURL.setParameter("organizationId", document.get(Field.ORGANIZATION_ID));

orgURL.setParameter("redirect",portletURL.toString());

if(className.contains("Organization"))

{

viewURL =orgURL.toString();

}

else

{

viewURL = _checkViewURL(themeDisplay, viewURL, currentURL);

}

  • Create view_organization.jsp to display the organization detail
     

<%@ include file="/html/portlet/directory/init.jsp"%>

 

<%

Organization organization = (Organization) request.getAttribute("organization");

long organizationId = BeanParamUtil.getLong(organization, request,"organizationId");

request.setAttribute(WebKeys.ORGANIZATION, organization);

request.setAttribute("addresses.className",

Organization.class.getName());

request.setAttribute("addresses.classPK", organizationId);

request.setAttribute("emailAddresses.className",

Organization.class.getName());

request.setAttribute("emailAddresses.classPK", organizationId);

request.setAttribute("phones.className",

Organization.class.getName());

request.setAttribute("phones.classPK", organizationId);

request.setAttribute("websites.className",

Organization.class.getName());

request.setAttribute("websites.classPK", organizationId);

String redirect = ParamUtil.getString(request, "redirect");

String backURL = ParamUtil.getString(request, "backURL", redirect);

%>

<liferay-ui:header backURL="<%=backURL.toString()%>" title="organization" />

<div class="organization-information">

<div class="section entity-details">

<liferay-util:include page="/html/portlet/directory/organization/details.jsp" />

</div>

 

<div class="section entity-email-addresses">

       <liferay-util:include

        page="/html/portlet/directory/common/additional_email_addresses.jsp" />

</div>

 

<div class="section entity-websites">

<liferay-util:include  page="/html/portlet/directory/common/websites.jsp" />

</div>

 

<div class="section entity-addresses">

<liferay-util:include page="/html/portlet/directory/organization/addresses.jsp" />

</div>

 

<div class="section entity-phones">

<liferay-util:include page="/html/portlet/directory/organization/phone_numbers.jsp" />

</div>

 

<div class="section entity-services">

<liferay-util:include page="/html/portlet/directory/organization/services.jsp" />

</div>

 

<div class="section entity-comments">

<liferay-util:include page="/html/portlet/directory/organization/comments.jsp" />

</div>

</div>

 

Step 2 : add new Struts action in liferay-hook.xml

 

<portal-properties>portal.properties</portal-properties>

<struts-action>

<struts-action-path>/search/view_organization</struts-action-path>

<struts-action-impl>

com.liferay.portal.hook.action.OrganizationSearchAction

</struts-action-impl>

</struts-action>

 

Step 3 : add struts action entry in portal.properties

auth.public.paths=/search/view_organization

 

Step 4 : Create a package com.liferay.portal.hook.action and add OrganizationSearchAction.java

 

package com.liferay.portal.hook.action;

 

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

import com.liferay.portal.kernel.struts.StrutsPortletAction;

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

import com.liferay.portal.model.Organization;

import com.liferay.portal.service.OrganizationLocalServiceUtil;

 

import javax.portlet.ActionRequest;

import javax.portlet.ActionResponse;

import javax.portlet.PortletConfig;

import javax.portlet.RenderRequest;

import javax.portlet.RenderResponse;

import javax.portlet.ResourceRequest;

import javax.portlet.ResourceResponse;

 

public class OrganizationSearchAction extends BaseStrutsPortletAction {

public void processAction(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, ActionRequest actionRequest,

ActionResponse actionResponse)

throws Exception {

 

originalStrutsPortletAction.processAction(

originalStrutsPortletAction, portletConfig, actionRequest,

actionResponse);

}

 

public String render(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, RenderRequest renderRequest,

RenderResponse renderResponse)

throws Exception {

long organizationId = ParamUtil.getLong(renderRequest, "organizationId");

Organization org = OrganizationLocalServiceUtil.getOrganization(organizationId);

renderRequest.setAttribute("organization", org);

return "/portlet/search/view_organization.jsp";

}

 

public void serveResource(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, ResourceRequest resourceRequest,

ResourceResponse resourceResponse)

throws Exception {

 

originalStrutsPortletAction.serveResource(

originalStrutsPortletAction, portletConfig, resourceRequest,

resourceResponse);

}

}

 

Step 5: Deploy hook now organization is available for search in search portlet.

 

 

Open Document Library popup in custom portlet

General Blogs 11 juillet 2013 Par priti parmar

Step 1 : create document library URL in your jsp

    <% long dlScopeGroupId = themeDisplay.getScopeGroupId();

          LiferayPortletURL documentLibURL = PortletURLFactoryUtil.create(request,          

          PortletKeys.JOURNAL, themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);

          documentLibURL.setWindowState(LiferayWindowState.POP_UP);

          documentLibURL.setPortletMode(PortletMode.VIEW);

          documentLibURL.setParameter("struts_action","/journal/select_document_library");

          documentLibURL.setParameter("groupId", String.valueOf(dlScopeGroupId));

     %>

 

Step 2: Create a div or html content

         <input type="hidden" name="<portlet:namespace/>documentLibraryInput" 

               id="<portlet:namespace/>documentLibraryInput" />

         <div class="profile-image">

          <img class="journal-image" hspace="0" id="<portlet:namespace/>article-image" src=""   

           style="width:82px;height:83px" vspace="0" />

           </div>

<div class="image-data">

<label>

<a style="text-decoration: none;cursor: pointer;"

onclick="javaScript:<portlet:namespace/>showImages()" >

Select a thumbnail image

</a>

</label>

</div>

 

Step 3: Create javascript Function

<script charset="utf-8" type="text/javascript">

function <portlet:namespace/>showImages()

{

AUI().ready('aui-dialog','aui-dialog-iframe','aui-overlay-manager','liferay-portlet-url', function(A) {

var url = '<%= documentLibURL %>';

window.myDialog = new A.Dialog(

{

title: '',

width: 1050,

draggable: true,

modal: true,

xy: [150, 50],

id:'documentDetails'

}

).plug(

A.Plugin.DialogIframe,

{

uri: url,

iframeCssClass: 'dialog-iframe'

}

).render();

});

}

 

</script>

 

Step 4 : after completion of step 3 on click of Select a thumbnail image Document Library popup will be open, now after choosing an image from poprup we need to keep those values in parameters of jsp

<script charset="utf-8" type="text/javascript">

function _15_selectDocumentLibrary(url) {

document.getElementById("<portlet:namespace/>documentLibraryInput").value = url;

var pic1 = document.getElementById("<portlet:namespace/>article-image");

pic1.src = url;

var iframe = document.getElementById('documentDetails');

iframe.parentNode.removeChild(iframe);

}

</script>

kaleo configuration for custom portlet in liferay 6.0 EE.

General Blogs 10 juillet 2013 Par priti parmar

Step1 : Add following reference and column to your service.xml (service in which you would like add workflow),out of these some of fields must be there which will help in mapping between workflow tables and your custom table.

<column name="resourcePrimKey" type="long"></column>

<column name="title" type="String"></column>

<column name="status" type="int"></column>

<column name="statusByUserId" type="long"></column>

<column name="statusByUserName" type="String"></column>

<column name="statusDate" type="Date"></column>

<!-- Finder methods -->

<finder name="R_S" return-type="Collection">

<finder-column name="resourcePrimKey"></finder-column>

<finder-column name="status"></finder-column>

</finder>

<reference package-path="com.liferay.portal" entity="WorkflowInstanceLink"></reference>

<reference package-path="com.liferay.portlet.asset" entity="AssetEntry"></reference>

<reference package-path="com.liferay.portlet.social" entity="SocialActivity"></reference>

 

Step 2 :Build service to make sure there is no compile time error.

 

Step 3: Once you Confirm with service just add following line in liferay-portlet.xml <portlet> tag on which you wish to apply workflow.

 

<workflow-handler>path</workflow-handler>

<asset-renderer-factory>path</asset-renderer-factory>

 

- path : This is path of your own workflow handler class and your own

AssetRendererFactory handler class

- Note : This tag should before initialize of portlet.

 

E.x

<asset-renderer-actory>

com.liferay.admin.asset.ArticleAssetRendererFactory

</asset-renderer-factory>

<workflow-handler>com.liferay.workflow.ArticleWorkflowHandler</workflow-handler>

 

Step 4: You need to extend com.liferay.portal.kernel.workflow.BaseWorkflowHandler class and override four abstract method.

 

  • String getClassName()
  • String getType(Locale locale)
  • Object updateStatus(int status,Map workflowContext)
  • String getIconPath(ThemeDisplay themeDisplay)

 

public class ArticleWorkflowHandler extends BaseWorkflowHandler

{

----------

--------

-----------

}

Note : Here one thing is very important updateStatus() method called another method which you gonna developed in Step5.

 

E.x

public Object updateStatus(int status, Map<String, Serializable> workflowContext)

{

return DemoLocalServiceUtil.updateStatus(userId, resourcePrimKey, status,      serviceContext);

}

 

Step 5: Now you need to implement one method called updateStatus() in you LocalServiceImpl class. which will return object of your model class.

 

E.x

public class DemoLocalServiceImpl extends DemoLocalServiceBaseImpl

{

public Demo updateStatus(long userId, long resourcePrimKey, int status,ServiceContext serviceContext)

{

User user = userPersistence.findByPrimaryKey(userId);

Date now = new Date();

// Article

Demo dempObj = null;

dempObj.setStatus(status);

dempObj.setStatusByUserId(user.getUserId());

dempObj.setStatusByUserName(user.getFullName());

dempObj.setStatusDate(serviceContext.getModifiedDate(now));

demoPersistence.update(dempObj, false);

if (status != WorkflowConstants.STATUS_APPROVED)

{

return dempObj;

}

return dempObj;

}

}

}

Step6: You need to extend com.liferay.portlet.asset.model.BaseAssetRendererFactory class and override abstract method.

 

  • String getClassName()
  • String getType(Locale locale)
  • Object getAssetRenderer(long classPK, int type)

E.x

public class ArticleAssetRendererFactory extends BaseAssetRendererFactory

{

----------

--------

public static final String CLASS_NAME = Article.class.getName();

public static final String TYPE = "article";

@Override

public AssetRenderer getAssetRenderer(long classPK, int type)

throws PortalException, SystemException {

// TODO Auto-generated method stub

int status = WorkflowConstants.STATUS_ANY;

if (type == TYPE_LATEST_APPROVED) {

status = WorkflowConstants.STATUS_APPROVED;

}

Article article = ArticleLocalServiceUtil.getLatestArticle(

classPK, status);

return new ArticleAssetRenderer(article);

}

     }

Note : Here one thing is ArticleAssetRenderer Class which you gonna developed in Step7.

 

Step7: Now you need to create one class called ArticleAssetRenderer and extends BaseAssetRenderer and override 7 abstract method.

 

  • long getClassPK()
  • long getGroupId()
  • String getSummary()
  • String getTitle()
  • long getUserId()
  • String render(RenderRequest renderRequest,
  • RenderResponse renderResponse, String template)

E.x.

public class ArticleAssetRenderer extends BaseAssetRenderer

{

----------

--------

----------

public String render(

RenderRequest renderRequest, RenderResponse renderResponse,

String template) throws Exception {

if (template.equals(TEMPLATE_FULL_CONTENT)) {

   return "/admin/asset/fullcontent.jsp";

}else {

return null;

}

}

}

 

 

 

Step8: Now Deploy service and portlet you will find out your asset in control panel as showing below .now you can apply any definition on that.

 

 

Step9: Start workflow

  • Now you need to start Workflow at the time of add content there.
  • You have to write following method in your addContent() and updateContent() in your ***LocalServiceImpl class.

 

  • assetEntryLocalService.updateEntry(

userId, article.getGroupId(), Article.class.getName(),

article.getClassPK(), article.getUuid(), assetCategoryIds,

assetTagNames, article.isApproved(), null, null, null, null,

ContentTypes.TEXT_HTML, article.getTitle(),

article.getDescription(), null, null, 0, 0, null, false);

  •  WorkflowHandlerRegistryUtil.startWorkflowInstance(

     user.getCompanyId(), groupId, userId, Demo.class.getName(),

     resourcePrimKey, article, serviceContext);

-E.x

public class ArticleLocalServiceImpl extends ArticleLocalServiceBaseImpl{

   public Article addArticle(long userId, long parentResourcePrimKey, String title,String content, String description, int priority, String dirName, ServiceContext serviceContext)

    throws PortalException, SystemException      

   {

User user = userPersistence.findByPrimaryKey(userId);

long groupId = serviceContext.getScopeGroupId();

long articleId = counterLocalService.increment();

long resourcePrimKey = counterLocalService.increment();

Article article = articlePersistence.create(articleId);

articlePersistence.update(article, false);

    // Asset

     updateAsset(

     userId, article, serviceContext.getAssetCategoryIds(),

     serviceContext.getAssetTagNames());

    // Workflow

     WorkflowHandlerRegistryUtil.startWorkflowInstance(

     user.getCompanyId(), groupId, userId, Article.class.getName(),

     resourcePrimKey, article, serviceContext);

return article;

}

public void updateAsset(long userId, Article article, long[] assetCategoryIds,String[] assetTagNames)throws PortalException, SystemException {

   assetEntryLocalService.updateEntry(userId, article.getGroupId(), Article.class.getName(),article.getClassPK(), article.getUuid(), assetCategoryIds,assetTagNames, article.isApproved(), null, null, null, null,ContentTypes.TEXT_HTML, article.getTitle(), article.getDescription(), null, null, 0, 0, null, false);

}

}

Static Navigation for Liferay Portal

General Blogs 28 juin 2013 Par priti parmar

create a ServicePreAction, which will create a new
custom NavItem object and a change in navigation.vm of the theme, which
will show the custom navigation.


Here are the steps to create the custom navigation


1) Create a new ServicePreAction hook
2) In the run() method of ServicePreAction, retrieve the your community
group object


ThemeDisplay themeDisplay = (ThemeDisplay)
req.getAttribute(WebKeys.THEME_DISPLAY);
Group baseCommunity = GroupLocalServiceUtil.getGroup(themeDisplay.getCompanyId(), "yourcommunitName");
long defaultLayoutId = LayoutLocalServiceUtil.getDefaultPlid(baseCommunity.getGroupId());
Layout defaultLayout = LayoutLocalServiceUtil.getLayout(defaultLayoutId);
List<Layout> layoutSet = LayoutLocalServiceUtil.getLayouts(baseCommunity.getGroupId(), false);
List<Layout> publicNonHiddenLayouts = newArrayList<Layout>(layoutSet.size());
for(Layout layout:layoutSet) {

    if(!layout.isHidden() && layout.getParentLayoutId()==0)
    {
         publicNonHiddenLayouts.add(layout);
    }
}
RequestVars requestVars = new RequestVars(req,themeDisplay,
defaultLayout.getAncestorPlid(), defaultLayout.getAncestorLayoutId());
List navItems = NavItem.fromLayouts(requestVars,publicNonHiddenLayouts);
Map vmVariables = new HashMap();
vmVariables.put("baseNavItems", navItems);
req.setAttribute(WebKeys.VM_VARIABLES, vmVariables);
---------------------------------------------------------------------------------------
Now, in the navigation.vm of the Theme,
replace  #foreach ($nav_item in $nav_items)  with  #foreach ($nav_item in $baseNavItems)

Most Visited Pages Count in Liferay 6.1

General Blogs 28 juin 2013 Par priti parmar

Liferay 6.1 provides Custom Fileds for Pages , set viewCount as a Custom Field and update it using a servicePreAction Hook.

public class CustomServicePreAction extends Action {

    /**
     * This Method is used for Creating the Map Variable of the Pages
     *
     * @param HttpServletRequest
     * @param HttpServletResponse
     */
    @Override
    public void run(HttpServletRequest req, HttpServletResponse res)
            throws ActionException {
              ThemeDisplay themeDisplay = (ThemeDisplay) req
                .getAttribute(WebKeys.THEME_DISPLAY);
        if (!themeDisplay.getURLCurrent().contains("control_panel")) {
            Layout layout = themeDisplay.getLayout();
            try {
                    setupExpandos(layout);
                } catch (Exception e) {
                  
                }
            }
    
    }

    protected void setupExpandos(Layout layout) throws Exception {
        
        
        ExpandoTable table = null;
        try {
            table = ExpandoTableLocalServiceUtil.addTable(layout.getCompanyId(), Layout.class.getName(),ExpandoTableConstants.DEFAULT_TABLE_NAME);
        } catch (DuplicateTableNameException dtne) {
            table = ExpandoTableLocalServiceUtil.getTable(layout.getCompanyId(), Layout.class.getName(),ExpandoTableConstants.DEFAULT_TABLE_NAME);
        }
         String column = "viewCount";
         ExpandoColumn expcolumn = null;
         try {
              expcolumn = ExpandoColumnLocalServiceUtil.addColumn(table.getTableId(), column,ExpandoColumnConstants.LONG,0L);
         }
         catch (DuplicateColumnNameException dcne)
         {
               expcolumn =        ExpandoColumnLocalServiceUtil.getColumn(layout.getCompanyId(),PortalUtil.getClassNameId(Layout.class.getName()), table.getName(), column);
         }
        long count = Long.valueOf(ExpandoValueLocalServiceUtil.getData(layout.getCompanyId(),Layout.class.getName(),      table.getName(), expcolumn.getName() , layout.getPrimaryKey(),0L));
        ExpandoValueLocalServiceUtil.addValue(layout.getCompanyId(),Layout.class.getName(), table.getName(), expcolumn.getName() , layout.getPrimaryKey(),count+1L);

    }

  
}

Configure solr 4.0 with Liferay 6.1.2 EE

General Blogs 28 juin 2013 Par priti parmar

PART 1: SETTING UP SOLR with TOMCAT

Step 1: Download Solr. It's just a zip file.

Step 2: Copy from your SOLR_HOME_DIR/dist/apache-solr-1.3.0.war to your tomcat webapps directory: $CATALINA_HOME/webapps/solr.war – Note the war file name change. That’s important.

Step 3: Create your solr home directory at a location of your choosing. This is where the configuration for that solr install resides. The easiest way to do this is to copy the SOLR_HOME_DIR/examples/solr directory to wherever it is you want your solr home container to be. Say place it in C:\solr.

Step 4: Hope you have set your environment variables, if not then please set JAVA_HOME, JRE_HOME, CATALINA_OPTS, CATALINA_HOME. Note that CATALINA_HOME refers to your Tomcat directory & CATALINA_OPTS refers to the amount of heap memory you want to give to your Solr.

Step 5: Start tomcat. Note this is only necessary to allow tomcat to unpack your war file. If you look under $CATALINA_HOME/webapps there should now be a solr directory.

Step 6: Stop tomcat

Step 7: Go into that solr directory and edit WEB-INF/web.xml. Scroll down until you see an entry that looks like this:

<!-- People who want to hardcode their "Solr Home" directly into the
     WAR File can set the JNDI property here...
 -->
<!--
  <env-entry>
     <env-entry-name>solr/home</env-entry-name>
     <env-entry-value>/Path/To/My/solr/Home/solr/</env-entry-value>
     <env-entry-type>java.lang.String</env-entry-type>
  </env-entry>
-->

Set your Solr home (for example: C:\solr) and uncomment the env entry.

Step 8: Start Tomcat again, and things should be going splendidly. You should be able to verify that solr is running by trying the url http://localhost:8080/solr/admin/.




PART 2: CONFIGURE SOLR PLUGIN ON LIFERAY

    Once the Solr instance is set, install the Solr plug-in in the portal. How does it work? The following is a sample which could bring the plugin Solr into the portal.

Step 1:    Download required WAR file ${solr.web.war}.  

Step 2:    Drop the WAR file ${solr.web.war} to the folder $LIFERAY_HOME/deploy when the portal is running

           After deploying successfully, you should shut down the portal and Solr instance, and moreover, configure the Solr instance with the Solr plugin as follows.

Step 3:    Open $AS_WEB_APP_HOME/solr-web/WEB-INF/classes/META-INF/solr-spring.xml and update Solr instance settings as follows

            <bean id=”solrServer”     class=”com.liferay.portal.search.solr.server.BasicAuthSolrServer”>
            <constructor-arg type=”java.lang.String” value=” http://${solr.host.domain}:$    {solr.port.number}/solr” />
            </bean>

            <bean id="com.liferay.portal.search.solr.SolrSearchEngineImpl"

            class="com.liferay.portal.kernel.search.BaseSearchEngine">

            <property name="clusteredWrite" value="false" />

            <property name="indexSearcher"

            ref="com.liferay.portal.search.solr.SolrIndexSearcherImpl" />

            <property name="indexWriter" ref="com.liferay.portal.search.solr.SolrIndexWriterImpl" />

            <property name="luceneBased" value="true" />

            <property name="vendor" value="SOLR" />

            </bean>

        

            <!-- Configurator -->

            

            <bean id="searchEngineConfigurator.solr"

            class="com.liferay.portal.kernel.search.PluginSearchEngineConfigurator">

            <property name="searchEngines">

            <map key-type="java.lang.String" value-

            type="com.liferay.portal.kernel.search.SearchEngine">

            <entry key="SYSTEM_ENGINE_ID">

            <ref bean="com.liferay.portal.search.solr.SolrSearchEngineImpl" />

            </entry>

            </map>

            </property>

            <property name="defaultSearchEngineId" value="SYSTEM_ENGINE_ID" />

            </bean>

Step 4:    Drop the schema file schema.xml from $AS_WEB_APP_HOME/solr-web/WEB-INF/conf to $SOLR_HOME/example/solr/conf in the domain ${solr.host.domain} – replacing the exiting the schema file schema.xml; and restart Solr instance and the portal

Affichage de 8 résultat(s).
Items 20
de 1