Fórumok

Publishing custom asset to Asset Framework

Marco Walz, módosítva 9 év-val korábban

Publishing custom asset to Asset Framework

New Member Bejegyzések: 13 Csatlakozás dátuma: 2014.07.12. Legújabb bejegyzések
Hi,

I'm getting really frustrated trying to implement that AssetPublisher can show my custom asset. I'm trying to implement it on Liferay 6.2-ce-ga2. First of all I want to tell you what I already did:

For this example I just had an entity "person" with 3 attributes

At first I had a primefaces jsf-portlet that used hibernate to persist my entity without servicebuilder in external datasource -> all worked fine

Then I followed this (https://www.liferay.com/de/documentation/liferay-portal/6.2/development/-/ai/asset-framework-liferay-portal-6-2-dev-guide-06-en) tutorial to add/update/delete AssetEntries for my entity -> no problem, AssetLocalServiceUtil working fine

Now I faced the issues while trying to make the asset accessible through AssetPublisher ... I followed the example and created 2 classes extending "BaseAssetRendererFactory" and "BaseAssetRenderer". I also created the abstract.jsp and full_content.jsp. At this point I used my own dao in the Factory-class to access my entity.

Mhh, nothing happened, I couldn't choose my entity in AssetPublisher.

Later I found out that it's also necessary to to add "<asset-renderer-factory>de.mw.examples.assetframework.PersonAssetRendererFactory</asset-renderer-factory>" into liferay-portlet.xml

Well ok, now i was able to choose my entity in AssetPublisher. But when I tried to use the dynamic view for my custom assettype, something like this happend:
[view_jsp:1944] com.liferay.portlet.journal.NoSuchArticleException: No JournalArticle exists with the key {groupId=10181, articleId=/16568, status=-1}
com.liferay.portlet.journal.NoSuchArticleException: No JournalArticle exists with the key {groupId=10181, articleId=/16568, status=-1}


And always when I tried to choose a specific element of my custom assettype, the popup opened and status "loading...." appeared for minutes before I got an OutOfMemoryError.

OK! Maybe it wasn't possbile to use custom asset with jsf-portlet OR custom datasource?!?! But someone got it to work with jsf -> https://www.sio2.cz/web/psiotwo/home/-/blogs/jsf-for-rendering-assets-in-liferay (how did he do that?! emoticon) ... I think I just need a full example with all necessary configuration files to understand this.....

Ok, jsf went out. So I decided to give Spring MVC a try ... basic configuration like this example: http://www.liferaysavvy.com/2013/12/liferay-spring-portlet.html
Again I used my custom datasource with Spring+Hibernate ( I really didn't want to use ServiceBuilder ) ...

It turned out -> (nearly?!) SAME problem! ... dynamic view (nosucharticleexception) and specific view (outofmemory)

Ok, so let's give ServiceBuilder a try (with Spring MVC).

In all 3 variants (jsf with hibernate, spring mvc with hibernate, spring mvc with servicebuilder) I got it to work, that my entity is written to database and that the AssetEntry get's added/updated/deleted with AssetLocalServiceUtil ... but I couldn't manage that AssetPublisher can show assets of my entity.

So now my questions:
1. Is it possible to use AssetPublisher for custom assets without ServiceBuilder?
2. Is "AssetEntry" however, linked to AssetPublisher or am I right when I say that the creation of AssetEntries has nothing to do with publishing assets with AssetPublisher? (I'm wondering because in the documentation it sounds like AssetPublisher depends on AssetEntries)
3. Is it possible really possible to use it with jsf? (or with spring mvc)?

It would be really nice if someone can provide me a full example or exactly explain what to do here and where to place the necessary files.

Thanks,
Marco
thumbnail
Nagendra Kumar Busam, módosítva 9 év-val korábban

R: Publishing custom asset to Asset Framework

Liferay Master Bejegyzések: 678 Csatlakozás dátuma: 2009.07.07. Legújabb bejegyzések
AFAIK, you should have entries for your custom asset in asset entry table as well

Sent from my iPhone with Liferay.com Forums
Marco Walz, módosítva 9 év-val korábban

RE: R: Publishing custom asset to Asset Framework

New Member Bejegyzések: 13 Csatlakozás dátuma: 2014.07.12. Legújabb bejegyzések
Well that's not the problem. The records of my entity (or asset) are also written to "assetentry"-table in database when I add a new "Person" in my example. I'm really freaking out with this.

The overwritten method never get's invoked when I try to choose my custom asset in asset publisher:
@Override
	public AssetRenderer getAssetRenderer( long classPK, int type )
			throws PortalException, SystemException
	{
		Person person = PersonLocalServiceUtil.getPerson(classPK);
		return new PersonAssetRenderer( person );
	}


What's needed to get this working? I followed these steps:
  • When persisting my "Person"-entity I call "updateEntry"-method of AssetEntryLocalService -> AssetEntry is present in Liferay-DB and set to visible
  • I implemented PersonAssetRenderer (extends BaseAssetRenderer) and PersonAssetRendererFactory (extends BaseAssetRendererFactory)
  • full_template.jsp and abstract.jsp are present and the path to each of them is returned by "render"-method of PersonAssetRenderer
  • PersonAssetRendererFactory is registered in liferay-portlet.xml (<asset-renderer-factory>)


I'm just wondering what I missed or why it doesn't work emoticon

Do I have to add the model-resource for my "Person"-entity in resource-actions? But as long as I know this should only be necessary for security and permissions?!

Does somebody know what I missed? Maybe it doesn't work with Spring MVC or JSF?

Here is my actual code:

PersonAssetRendererFactory.java
package de.mw.examples.assetframework;

import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.WindowState;
import javax.portlet.WindowStateException;

import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
import com.liferay.portal.kernel.portlet.LiferayPortletURL;
import com.liferay.portlet.asset.model.AssetRenderer;
import com.liferay.portlet.asset.model.BaseAssetRendererFactory;

import de.mw.examples.servicebuilder.model.Person;
import de.mw.examples.servicebuilder.service.PersonLocalServiceUtil;

public class PersonAssetRendererFactory extends BaseAssetRendererFactory
{
	
	private static final boolean _LINKABLE = true;
	
	public static final String CLASS_NAME = Person.class.getName();

    public static final String TYPE = "person";
    
	@Override
	public AssetRenderer getAssetRenderer( long classPK, int type )
			throws PortalException, SystemException
	{
		Person person = PersonLocalServiceUtil.getPerson(classPK);
		return new PersonAssetRenderer( person );
	}

	@Override
	public String getClassName()
	{
		return CLASS_NAME;
	}

	@Override
	public String getType()
	{
		return TYPE;
	}
	
	@Override
	public boolean isLinkable()
	{
		return _LINKABLE;
	}

//	@Override
//	public PortletURL getURLView(
//		LiferayPortletResponse liferayPortletResponse,
//		WindowState windowState) {
//
//		LiferayPortletURL liferayPortletURL =
//			liferayPortletResponse.createLiferayPortletURL(
//				"springmvcexample_WAR_springmvcexampleportlet", PortletRequest.RENDER_PHASE);
//
//		try {
//			liferayPortletURL.setWindowState(windowState);
//		}
//		catch (WindowStateException wse) {
//		}
//
//		return liferayPortletURL;
//	}
}


PersonAssetRenderer.java
package de.mw.examples.assetframework;

import java.util.Locale;

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

import com.liferay.portlet.asset.model.BaseAssetRenderer;

import de.mw.examples.servicebuilder.model.Person;

public class PersonAssetRenderer extends BaseAssetRenderer
{

	private Person _person;
	
	public PersonAssetRenderer( Person person )
	{
		_person = person;
	}
	
	@Override
	public String getClassName() {
		return Person.class.getName();
	}

	@Override
	public long getClassPK() {
		return _person.getPersonId();
	}

	@Override
	public long getGroupId() {
		return _person.getGroupId();
	}

	@Override
	public String getSummary(Locale locale) {
		return _person.getDescription();
	}
	
	@Override
	public String getTitle(Locale locale) {
		return _person.getFirstname() + " " + _person.getLastname();
	}
	
	@Override
	public long getUserId() {
		return _person.getUserId();
	}

	@Override
	public String getUserName() {
		return _person.getUserName();
	}

	@Override
	public String getUuid() {
		return _person.getUuid();
	}

	@Override
	public String render(RenderRequest renderRequest,
			RenderResponse renderResponse, String template) throws Exception {
		
		renderRequest.setAttribute("person", _person);
		
		if (template.equals(TEMPLATE_FULL_CONTENT)) {
			

			return "/jsp/asset/full_content.jsp";
		}
		else {
			return "/jsp/asset/abstract.jsp";
		}
	}

}
thumbnail
Nagendra Kumar Busam, módosítva 9 év-val korábban

RE: R: Publishing custom asset to Asset Framework

Liferay Master Bejegyzések: 678 Csatlakozás dátuma: 2009.07.07. Legújabb bejegyzések
I have not done full blown example w/ Spring MVC as you mentioned, can you quickly test the sampe using Liferay MVCPortlet if you have some time - so that it may help narrow down exact issue.
Michael Hoos, módosítva 9 év-val korábban

RE: R: Publishing custom asset to Asset Framework

New Member Bejegyzések: 8 Csatlakozás dátuma: 2013.11.14. Legújabb bejegyzések
Hi I'm facing a similar problem, but with MVC Portlet:

service.xml:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd">
<service-builder package-path="com.liferay.aft">
<author>michael</author>
<namespace>aft</namespace>

<entity name="Foo" uuid="true" local-service="true" remote-service="true">

<!-- PK fields -->

<column name="fooId" type="long" primary="true" />

<!-- Group instance -->

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

<!-- Audit fields -->

<column name="companyId" type="long" />
<column name="userId" type="long" />
<column name="userName" type="String" />
<column name="createDate" type="Date" />
<column name="modifiedDate" type="Date" />

<!-- Other fields -->

<column name="field1" type="String" />
<column name="field2" type="boolean" />
<column name="field3" type="int" />
<column name="field4" type="Date" />
<column name="field5" type="String" />

<!-- Order -->

<order by="asc">
<order-column name="field1" />
</order>

<!-- Finder methods -->

<finder name="Field2" return-type="Collection">
<finder-column name="field2" />
</finder>

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

</entity>

</service-builder>

My AssetRendererFactory class:

public class FooAssetRendererFactory extends BaseAssetRendererFactory {

public FooAssetRendererFactory() {
super();
System.out.println("Using FooAssetRendererFactory");
}


@Override
public AssetRenderer getAssetRenderer(long fooId, int type) throws PortalException, SystemException {
System.out.println("getAssetRenderer fooId:" + fooId + ", type=" + type);
Foo foo = FooLocalServiceUtil.getFoo(fooId);
FooAssetRenderer renderer = new FooAssetRenderer(foo);
renderer.setAssetRendererType(type);
return renderer;
}


@Override
public String getType() {
System.out.println("FooAssetRendererFactory:getType: foo");
return "foo";
}


@Override
public boolean hasPermission(PermissionChecker permissionChecker,
long entryClassPK, String actionId) throws Exception {
System.out.println("FooAssetRendererFactory::hasPermissions");
return true;
}

@Override
public String getClassName() {
System.out.println("FooAssetRendererFactory:getClassName: " + className);
return className;
}

private static final String className = Foo.class.getName();

}



I do find entries for my foo objects in the AssetEntry table. Also I see that the FooAssetRendererFactory is constructed. However the FooAssetRenderer is never called. I've attached the full sources as jar file.

Any help very much appreciated,
Michael
Dat Ho, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

New Member Bejegyzés: 1 Csatlakozás dátuma: 2014.01.11. Legújabb bejegyzések
I'm facing with a similar problem, and my Asset Publisher can show exactly model which was configured. But it always shows message: "There are no results." although my custom asset was created (check in my database) and "visible" field is true. Does somebody know how to solve it emoticon.
thumbnail
Fabio Zambelli, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

Junior Member Bejegyzések: 28 Csatlakozás dátuma: 2010.02.22. Legújabb bejegyzések
hi, have you solved? i've the same problem, i moved my attention on LuceneIndexSearcher. with the log debug enabled i verified the query - Query +(+((+(entryClassName:<myEntity>) +(status:0))) +(+(groupId:16802) +(scopeGroupId:16802))) -; the indexes are correctly generated but i still get none result found. i've the same using with the following code:
com.liferay.portal.kernel.search.Indexer indexer = <myEntity>Indexer.getInstance();
com.liferay.portal.kernel.search.SearchContext searchContext = com.liferay.portal.kernel.search.SearchContextFactory.getInstance(request);
com.liferay.portal.kernel.search.BooleanQuery query = com.liferay.portal.kernel.search.BooleanQueryFactoryUtil.create(searchContext);
System.out.println("query:"+indexer.getFullQuery(searchContext));
com.liferay.portal.kernel.search.Hits hits = indexer.search(searchContext);
Michael Hoos, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

New Member Bejegyzések: 8 Csatlakozás dátuma: 2013.11.14. Legújabb bejegyzések
No Luck on my side.

Configuring my asset type in the asset publisher shows all but my asset :-( I wonder if anybody was able to implement this successfully ?
thumbnail
Olaf Kock, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

Liferay Legend Bejegyzések: 6403 Csatlakozás dátuma: 2008.09.23. Legújabb bejegyzések
You might want to give xmlportletfactory a try and adopt your service.xml to its source form, generate the entity again and compare its results with your code. Xmlportletfactory generates Assets, not sure how much work it is to compare the two source trees though.
Michael Hoos, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

New Member Bejegyzések: 8 Csatlakozás dátuma: 2013.11.14. Legújabb bejegyzések
Many thanks Olaf, using the xmlportletfactory gave a hint of what was actually missing. It seems that you must implement an Indexer and call it form your Service to get your custom assets displayed by the AssetPublisher. Wished this had been documented and would have saved me a lot of time and frustration ...

I've attached updated sources of my test portlet, maybe this could help folks and save time struggeling with this.
thumbnail
Olaf Kock, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

Liferay Legend Bejegyzések: 6403 Csatlakozás dátuma: 2008.09.23. Legújabb bejegyzések
Thanks for reporting back and good to know that the suggestion helped.

Are you aware of dev.liferay.com? It's beta, but scheduled to be the full documentation for everything Liferay related. You might want to check if it's documented there - if not, there's a "Edit on github" link which you (or anyone else who feels like it) can use to send a pull request to our docs team, with the correct (and full) information.
thumbnail
Fabio Zambelli, módosítva 9 év-val korábban

RE: Publishing custom asset to Asset Framework

Junior Member Bejegyzések: 28 Csatlakozás dátuma: 2010.02.22. Legújabb bejegyzések
the problem is that some search document fields are not stored in the index because they are empty. i've not still understood why but i find a solution (workaround?) with the following implementation in <myEntity>Indexer.doReindex

Document document = getDocument(myEntityInstance);
document.add(new Field(Field.GROUP_ID,Long.toString(myEntityInstance.getGroupId())));
document.add(new Field(Field.SCOPE_GROUP_ID,Long.toString(myEntityInstance.getGroupId())));
document.add(new Field(Field.STATUS,Long.toString(0L)));

now i have result from LuceneIndexSearcher, happiness