[jboss-user] [JBoss Seam] - Re: Getting objects from conversation in a custom PhaseListe

JakeC do-not-reply at jboss.com
Mon Jul 9 16:34:32 EDT 2007


That looks like exactly what I need, but I can't use 2.0, with a handy-dandy ContextualHttpServletRequest. Here is what I've come up with for 1.1.5GA:
components.xml

  | <component name="documentResource" class="com.myco.myproject.DocumentResource" scope="APPLICATION" auto-create="true"/>
  | 

DocumentResource.java

  | package com.myco.myproject;
  | 
  | import static org.jboss.seam.InterceptionType.NEVER;
  | import static org.jboss.seam.ScopeType.APPLICATION;
  | import static org.jboss.seam.annotations.Install.BUILT_IN;
  | 
  | import java.io.File;
  | import java.io.InputStream;
  | import java.io.IOException;
  | import java.util.Set;
  | 
  | import javax.faces.context.FacesContext;
  | import javax.servlet.http.HttpServletRequest;
  | import javax.servlet.http.HttpServletResponse;
  | 
  | import org.jboss.seam.annotations.Install;
  | import org.jboss.seam.annotations.Intercept;
  | import org.jboss.seam.annotations.Name;
  | import org.jboss.seam.annotations.Scope;
  | import org.jboss.seam.annotations.Startup;
  | import org.jboss.seam.annotations.security.Restrict;
  | import org.jboss.seam.contexts.ContextAdaptor;
  | import org.jboss.seam.contexts.Lifecycle;
  | import org.jboss.seam.core.Expressions;
  | import org.jboss.seam.core.Manager;
  | import org.jboss.seam.core.Expressions.ValueBinding;
  | import org.jboss.seam.log.Log;
  | import org.jboss.seam.log.Logging;
  | import org.jboss.seam.servlet.AbstractResource;
  | 
  | import com.myco.myproject.db.Document;
  | import com.myco.myproject.db.DocumentSet;
  | 
  | @Startup
  | @Scope(APPLICATION)
  | @Name("documentResource")
  | @Restrict("#{identity.loggedIn}")
  | @Install(precedence = BUILT_IN)
  | @Intercept(NEVER)
  | public class DocumentResource extends AbstractResource {
  | 	private static final String RESOURCE_PATH = "/document";
  | 
  | 	public static final String WEB_RESOURCE_PATH = "/seam/resource" + RESOURCE_PATH;
  | 
  | 	private static Log log = (Log) Logging.getLog(DocumentResource.class);
  | 
  |     private static String docDir = "C:\\resources\\docs";
  | 
  |     static final int	BUF_SIZE = 16384;
  | 
  |     @Override
  | 	protected String getResourcePath() {
  | 		return RESOURCE_PATH;
  | 	}
  | 
  | 	Document getDocument(int index) {
  | 		Set<Document> attachments = null;
  | 		try {
  | 			ValueBinding vb = Expressions.instance().createValueBinding("#{currentDocumentSet}");
  | 			if (vb == null)
  | 				log.error("VB is null!");
  | 			else {
  | 				Object o = vb.getValue();
  | 				log.info("vb type=" + vb.getType() + ", value=" + o);
  | 				if (o != null && o instanceof DocumentSet)
  | 					attachments = ((DocumentSet) o).getAttachments();
  | 			}
  | 		} catch (Throwable t) {
  | 			log.error("Exception getting VB", t);
  | 		}
  | 
  | 		return attachments == null || index >= attachments.size() ? null : (Document) attachments.toArray()[index];
  | 	}
  | 
  | 	@Override
  | 	public void getResource(HttpServletRequest request,
  | 			HttpServletResponse response) throws IOException {
  | 		String pathInfo = request.getPathInfo().substring(getResourcePath().length());
  | 		log.info("pathInfo=" + pathInfo);
  | 		beginConversation(request);
  | 
  | 		String path[] = pathInfo.split("/");
  | 		int i = 0;
  | 		boolean src = false;
  | 		if ("".equals(path))
  | 			++i;
  | 		if ("src".equals(path)) {
  | 			src = true;
  | 			++i;
  | 		}
  | 		Document doc = null;
  | 		try {
  | 			doc = getDocument(Integer.parseInt(path));
  | 		} catch (Throwable t) {
  | 			log.error("Exception parsing document index", t);
  | 		}
  | 
  | 		InputStream is = null;
  | 		if (doc != null)
  | 			try {
  | 				if(docDir == null) {
  | 					try {
  | 						docDir = getServletContext().getInitParameter("document.folder");
  | 					} catch (Throwable t) {
  | 						log.error("Exception getting init parameter", t);
  | 					}
  | 				}
  | 				is = doc.getInputStream(src, docDir);
  | 				int len = -1;
  | 				byte[] buf = new byte[BUF_SIZE];
  | 				while((len = is.read(buf)) != -1)
  | 					response.getOutputStream().write(buf, 0, len);
  | 			} catch (IllegalArgumentException e) {
  | 				response.sendError(HttpServletResponse.SC_NOT_FOUND);
  | 				return;
  | 			} catch (Throwable t) {
  | 				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  | 				return;
  | 			} finally {
  | 				if(is != null) try {is.close();} catch (Exception ignored){}
  | 			}
  | 		else {
  | 			response.sendError(HttpServletResponse.SC_NOT_FOUND);
  | 			return;
  | 		}
  | 		response.setHeader("Cache-Control", "no-store");
  | 		response.setHeader("Pragma", "no-cache");
  | 		response.setDateHeader("Expires", 0);
  | 		response.setContentType("application/octet-stream");
  | 		response.getOutputStream().flush();
  | 		response.getOutputStream().close();
  | 		endConversation(request);
  | 	}
  | 
  | 	private void beginConversation(HttpServletRequest request) {
  | 		Lifecycle.beginRequest(getServletContext(), request.getSession(), request);
  | 		Manager.instance().restoreConversation(request.getParameterMap());
  | 		Lifecycle.resumeConversation(request.getSession());
  | 		Manager.instance().handleConversationPropagation(request.getParameterMap());
  | 	}
  | 	private void endConversation(HttpServletRequest request) {
  | 		Manager.instance().endRequest(ContextAdaptor.getRequest(request));
  | 		Lifecycle.endRequest();
  | 	}
  | }
  | 

The code in my beginConversation() and endConversation() methods seem to be roughly equivalent to code in ContextualHttpServletRequest, but I'm sure that I'm not doing it correctly, as I'm still getting an exception, and still killing the conversation.

The exception I get now is:
ERROR [DocumentResource] Exception getting VB
  | javax.el.PropertyNotFoundException: ELResolver cannot handle a null base Object with identifier
  |  'currentDocumentSet'

If I log "Manager.instance().getCurrentConversationId()", I get the correct ID, but I can't seem to get the information out of the conversation. And once again, if I try to continue after this, I get an error:

  | Caused by: javax.ejb.EJBTransactionRolledbackException: org.jboss.seam.NoConversationException:
  |  no long-running conversation for @Conversational bean:
  |  documentSetController
  | 

Also, it is ignoring the @Restrict and allowing access to un-logged-in users, although, of course, they also get the javax.el.PropertyNotFoundException.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4062139#4062139

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4062139



More information about the jboss-user mailing list