Example using Java API for IPSSiteManager

I am trying to get a list of available sites in RX. I’m trying to do this the legit way via the API (as opposed to querying the database directly).

I’ve come up with the following: but I keep getting the following error “org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.percussion.services.assembly.data.PSAssemblyTemplate.slots, no session or session was closed”.

The documentation makes a note that “Important to use this manager and dereference related site objects, you must be in the same Session, so this should be called from within another manager.” But i’m not sure how to do that…any suggestions?


IPSSiteManager test = PSSiteManagerLocator.getSiteManager();
out.println(test.findAllSites());

Thanks,
Jit

Jit,

Where are you calling your code from? Is this a standalone program? A servlet / JSP? Something else?

To call Rhythmyx API functions you normally have to be within the rxapps.war, and in some cases also within a Thread that was started by the server in response to a request (in other words, certain operations fail in background threads).

Describe to me your use case, and I’ll try to tell you what the best approach is.

Dave

Dave,
This would be to address the following problem with generic preview menus: http://forum.percussion.com/showthread.php?t=324.

The solution that I’ve figured out so far does the following. We modify the preview action so that it points to a jsp page. This jsp page acts as a “controller”, finds the correct site id given the content id and then passes that information along to the actual render page.

In more detail, we modify the rxs_cxSupport application (or copy it and call it something else) so that the end url it builds points to the jsp page. We pass the jsp page all the parameters except the sys_siteid. The jsp pages does some kungfu (to quote somebody) and figures out what the site id is. (If it can’t figure out the site id, ie it is not within a site folder, I would get all the sites available to the community of the person logged in and provide them with a list of choices). Once the jsp page figures out the site id, it forwards (via jsp:forward) the user onto /Rhythmyx/assembler/render, passing it all the variables it needs (which now includes the sys_siteid).

Yes, I can build this using sql statements within a loop… I can find out the siteid, because i know the folder id as it is a passed parameter and there is a table for folder relationships, but would like to avoid creating unnecessary sql statements (esp if i can do this via the java api…my thought was to get the site id, and then there is a function that given a site id and content id, it will return the folder id containing the content item).

Ideally, it would be nice to use whatever the impact analysis applet is using to get the folder relationship, but i haven’t tried figuring that one out yet.

Hope that helps you to get a better understanding…

Jit

Jit,

Is your JSP in /Rhythmyx/user/pages, or in a separate Web App?

I’ve done something very similar in a JSP page (in /Rhythmyx/user/pages) without encountering a problem.

Dave

Dave,
It is currently on /Rhythmyx/ui/ but i can easily move it to /user if needed…

Thanks,
Jit

Please try it in the standard (/user/pages) location. You can also check that you have a Request attribute named RX_REQUEST_CONTEXT. If you don’t then you are not logged in properly.

Dave

Looks to me like the issue is not related to the page location, although Dave is correct that all user defined JSP pages should be in the user/pages location, especially to ensure they survive upgrades.

When you load the IPSSite objects, they contain a list of IPSAssemblyTemplate objects that are implicitly loaded along with the site (see IPSSite.getAssociatedTemplates()). The templates in turn can contain a list of IPSTemplateSlot objects (see IPSAssemblyTemplate.getSlots()). The issue is that when the templates are implicitly loaded as part of the site object, the slots are NOT loaded implicitly as part of the templates, and thus you get an error if you try to access the slots.

When you call

out.println(test.findAllSites());

this calls toString() on the site objects, which in turn calls toString() on the templates, and that tries to access the slots, and thus causes the error you are seeing.

From your description of what you want to do, I don’t think you need to access the slots, so this shouldn’t be an issue for you. So if you change your code to avoid accessing the slots of the templates loaded as part of the sites, you should avoid that error.

Jay,
You are correct in that I do not need any slot information. However, I am still unclear as how to “load” the site properly. I’m not sure on how I would change my code (if all I’m trying to do is to get a list of all the sites…for now…). Do you have an example of how to do this? What classes/methods should I use (ie. using .findSiteByName() doesn’t work either)?

I think I understand the issue with it trying to load the templates and slots but how do I prevent it from loading that?

I have moved my file to user/pages and that isn’t the problem as you noted.

Thanks,
Jit

Jit -

You are loading the site properly. The issue is not in how you are loading the site. The issue is about what properties you access on any of the IPSAssemblyTemplate objects that are loaded as part of the IPSSite object.

After loading the sites, just avoid calling toString() explicitly or implicitly on any of the returned IPSSite objects. You can call IPSSite.getAssociatedTemplates() on any of the returned sites, but just don’t call any method on the IPSAssemblyTemplate objects that method returns which will access the template’s slots collection: IPSAssemblyTemplate.getSlots(), addSlot(), removeSlot() or setSlots().

Any other methods on the IPSAssemblyTemplate objects should be okay to call, and any methods on IPSSite besides toString() should be okay to call.

Hope this helps,
Jay

Jay,
I believe that my problem appears to be actually loading a site. How do I go about doing that? From the code below, I’m loading the IPSSiteManager object and then attempting to load a site (IPSSite) at which point i get the error message detailed below.

Both findAllSites() and findSiteByName() doesn’t work…

Thanks,
Jit

Can you please post your code that calls findAllSites() as well as the full call stack of the exception you are getting?

Jsp:


<%@page 
	import="com.percussion.server.*"
	import="com.percussion.services.sitemgr.*"
%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%	
	// Print User roles (check session is valid)
	IPSRequestContext reqCtx = (IPSRequestContext) request.getAttribute("RX_REQUEST_CONTEXT");
	out.println(reqCtx.getSubjectRoles());

	IPSSiteManager test = PSSiteManagerLocator.getSiteManager();
	out.println(test.findAllSites());
%>

Result:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: failed to lazily initialize a collection of role: com.percussion.services.assembly.data.PSAssemblyTemplate.slots, no session or session was closed
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:370)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
	com.percussion.webdav.PSWebDavRequestFilter.doFilter(Unknown Source)
	com.percussion.servlets.PSSecurityFilter.doFilter(Unknown Source)
	org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)

root cause

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.percussion.services.assembly.data.PSAssemblyTemplate.slots, no session or session was closed
	org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
	org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
	org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
	org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
	org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:411)
	java.util.HashMap.containsKey(Unknown Source)
	java.util.HashSet.contains(Unknown Source)
	org.apache.commons.lang.builder.ReflectionToStringBuilder.isRegistered(ReflectionToStringBuilder.java:133)
	org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:629)
......
....
...

Jit,

Your problem is not the loading of the site, but the implicit call to toString() caused by the out.println. Try:

<% 
IPSSiteManager test = PSSiteManagerLocator.getSiteManager();
Iterator sites = test.findAllSites().iterator(); 
while(sites.hasNext())
{
    IPSSite s = (IPSSite)sites.next(); 
    out.println("<p>" + s.getName() + "</p>"); 
}
%>

This works properly on my system.

Dave,
Now that makes sense.
Thanks a bunch,
Jit