portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christophe Lombart <christophe.lomb...@gmail.com>
Subject Re: Ajax
Date Thu, 24 Nov 2005 19:27:02 GMT
David,

I'm going to review the code. Do you advise me to review Rico ? Do you
plan to integrate it into Jetspeed ?

Thanks,
Christophe

On 11/24/05, David Sean Taylor <david@bluesunrise.com> wrote:
> Christophe Lombart wrote:
> > Hi all,
> >
> > What is the current status of the Ajax support in J2 ?   I didn't
> > follow all messages about this topic and I'm wondering what we can do
> > with Ajax within J2.
> >
> > Are there some tools to use Ajax in my own portlet  ? or is it better
> > to use other frameworks like Taconite, dwr, ...       For example, I
> > would like to build a dynamic tree view which can retrieve subitems
> > only when it is needed.
> >
> Funny that you ask, thats what Roger and I plan to work on next week.
> And yes, there is an AJAX pipeline in Jetspeed-2 to handle AJAX request
> through the Jetspeed pipeline.
> We're currently working on a Layout API for Javascript customization.Its
> in subversion trunk under the portal component:
>
> org.apache.jetspeed.ajax.AjaxRequestServiceImpl and AjaxServiceImpl
> org.apache.jetspeed.layout.impl.*
>
> This is still a work in progress..
>
> In a custom project, we wrote an AJAX treeview widget with Rico. The
> code is mixed in another project but was more of a first time prototype,
> so its not integrated with the ongoing work in subversion head. It uses
> a concept of builders and actions to supply XML responses over HTTP.
> Here is an example builder that builds a tree view, the javascript to
> expand and contract, and finally the service that handles the request.
> Since doing this work, Ive been working on porting it back into
> Jetspeed, although I haven't considering porting back the treeview yet.
> The builder and action classes are not included here, since they are
> being refactored in the SVN trunk. It would be best if we ported the
> treeview code back to the new AJAX services and builders in SVN trunk.
> I'd be glad to work with you on that.
>
> <?xml version="1.0"?>
> #macro (ajaxChildren $children)
>    #foreach( $child in $children)
>      #set($isLeaf = "false")
>      #set($isDocument = "false")
>      #if($child.isLeaf() == true)
>         #set($isLeaf = "true")
>      #end
>      #if($child.isDocument() == true)
>         #set($isDocument = "true")
>      #end
>         <child label="$child.label" name="$child.name" isLeaf="$isLeaf"
> isDocument="$isDocument" #if($child.anchor.length() > 0)
> anchor="$child.anchor" #end >
>          #if($child.getChildren().size() > 0)
>              #set($grandchildren = $child.getChildren())
>              #ajaxChildren($grandchildren)
>          #end
>      </child>
>    #end
> #end
> <ajax-response>
> <response type="object" id="treeUpdater"><node name="${ajaxnode.name}"
> contextPath="$contextPath">
>    #set($t = $ajaxnode.getChildren())
>    #ajaxChildren( $t )
> </node>
> </response>
> </ajax-response>
>
> Javascript to expand / contract tree nodes:
>
> var treeBuilder = "";
> var documentBuilder = "";
> var loaded = { };
> var currentDocument = "";
> var expandTree = "";
>
> var TreeUpdater = Class.create();
> /*
> TreeUpdater.attributes = [ "fullName", "title", "firstName", "lastName",
> "streetAddress",
> "city", "state", "zipcode", "occupation", "phoneNumber", "mobileNumber",
> "personNotes"  ];*/
>
> TreeUpdater.prototype = {
>
>     initialize: function() {
>        this.useHighlighting    = true;
>        this.lastNodeSelected = null;
>     },
>
>     ajaxUpdate: function(ajaxResponse) {
>         log("Received response from server");
>         this.updateTree(ajaxResponse.childNodes[0]);
>         },
>         updateTree: function(node) {
>                 this.lastNodeSelected = node;
>
>                 log("Found node with nodeName=" + node.nodeName);
>                 var treeNodeName = node.getAttribute("name");
>                 log("TreeNodeName=" + treeNodeName);
>                 var div = document.getElementById(treeNodeName);
>                 div.style.display = "inline";
>                 log("DIV Object Id =" + div);
>
>                 this.updateExpandInfo(treeNodeName);
>
>                 var html = this.outputChildren(node, treeNodeName);
>
>                 div.innerHTML = html;
>          html = null;
>         },
>      updateExpandInfo: function(treeNodeName) {
>          //var a = document.getElementById("PLUS_" + treeNodeName);
>                 //a.innerHTML = "-";
>      },
>      outputChildren: function(node, treeNodeName) {
>          var children = node.childNodes;
>          var html = "";//"<ul>"
>                 log("Number of Children = " + children.length);
>
>                 for(var i=0; i< children.length; ++i) {
>              var child = children[i];
>                 log("Found child " + child.nodeName);
>                 if(child.nodeName == "#text") continue;
>
>              var childName = child.getAttribute("name");
>              var label = child.getAttribute("label");
>              var title = child.getAttribute("title");
>
>              var hasChildren =
> child.getElementsByTagName("child").length > 0;
>
>              //loaded[childName] = "false";
>
>              log("ChildNodeName=" + child.nodeName);
>              log("childName=" + childName);
>              var isLeaf = child.getAttribute("isLeaf");
>              html = html + "<li>";
>
>              /*
>              if(isLeaf == "true") {
>                //do nothing
>              } else {
>                html = html + "<a id=\"PLUS_" + childName + "\" ";
>                if(title != null) { html = html + "title=\"" + title +
> "\" "; }
>                html = html + "href=\"javascript:getNodeInfo('" +
> childName + "');\"> "
>                if(hasChildren) {
>                    html = html + "-";
>                } else {
>                    html = html + "+";
>                }
>                html = html + " </a>";
>              }
>              */
>
>              var spanStyle = "<span>";
>              var isDoc = child.getAttribute("isDocument");
>              var anchor = child.getAttribute("anchor");
>              if(isDoc == "true") {
>                  html = html + "<a href=\"javascript:getDocInfo('" +
> childName +"');\">" + spanStyle + label + "</span></a>";
>              } else if(anchor != null && currentDocument == treeNodeName) {
>                  html = html + "<a href=\"" + anchor + "\">" + label +
> "</a>";
>              } else if(anchor != null) {
>                  log("Anchor=" + anchor);
>                  html = html + "<a href=\"javascript: currentAnchor='" +
> anchor + "'; getDocInfo('" + childName +"');\">" + spanStyle + label +
> "</span></a>";
>              } else {
>                  html = html + spanStyle + "&nbsp; <a
> href=\"javascript:getNodeInfo('" + childName + "');\"> " + label +
> "</a></span>";
>              }
>              html = html + "<div id=\"" + childName + "\" ";
>
>              if(hasChildren) {
>                  html = html + "style=\"display:inline;\"";
>              } else {
>                  html = html + "style=\"display:none;\"";
>              }
>              html = html + ">";
>
>              if(child.childNodes.length > 0) {
>                  html = html + this.outputChildren(child, treeNodeName);
>              }
>              html = html + "</div>";
>              html = html + "</li>";
>                 }
>
>          if(html.length > 0) {
>              html = "<ul>" + html + "</ul>";
>          } else {
>              //html = "&nbsp;";
>          }
>          log(html);
>          return html;
>      }
>
>                 /*
>         substitute: function( tagName, tagClass, value ) {
>                 var elements = document.getElementsByTagAndClassName(
>                 tagName, tagClass);
>                 for ( var i = 0 ; i < elements.length ; i++ )
>                 elements[i].innerHTML = value;
>                 },*/
> };
>
> function getDocInfo(nodeName) {
>         log("Sending doc info request");
>
>         var now = new Date();
>         log("Started at " + formatTime(now));
>
>      log("NodeName=" + nodeName);
>      log("CurDoc=" + currentDocument);
>
>      if(nodeName && nodeName.length > 0) {
>          var hash = nodeName.indexOf("#");
>          var anchor = "";
>          if(hash != -1) {
>              anchor = nodeName.substring(hash);
>              nodeName = nodeName.substring(0, hash);
>          }
>      }
>
>      if(currentDocument && currentDocument.length > 0 &&
> currentDocument.indexOf(nodeName) >= 0) {
>          log(anchor);
>          if(anchor.length > 0) {
>              location.hash = anchor;
>          }
>          log("Returning..."); return;
>      }
>      currentDocument = nodeName;
>
>      if(nodeName == null) {
>          nodeName = "";
>      }
>
>      var ranNum= Math.random()*4;
>         ajaxEngine.sendRequest( 'getDocInfo', "node=" + nodeName,
> "builder=" + documentBuilder, "random="+ranNum);
>    }
>
>    function expand(nodeName) {
>        log("Sending expand info");
>        var ranNum= Math.random()*4;
>        ajaxEngine.sendRequest( 'expandState', "node=" + nodeName,
> "action=expandState", "expandTree="+expandTree, "random="+ranNum);
>    }
>
>     function getNodeInfo(nodeName) {
>        var div = document.getElementById(nodeName);
>        //var a = document.getElementById("PLUS_" + nodeName);
>        log(nodeName);
>
>        if(loaded[nodeName] == "true") {
>          log("Request div info for already loaded div.  Will hide or
> display as appropriate.");
>         if(div.style.display == "none") {
>                     log("Displaying node " + nodeName);
>              div.style.display = "inline";
>              //a.innerHTML = "-";
>              expand(nodeName);
>          } else {
>                     log("Hiding node " + nodeName);
>              div.style.display = "none";
>              //a.innerHTML = "+";
>              expand(nodeName);
>          }
>        } else {
>            if(div.style.display == "none") {
>               log("Sending AJAX request to server");
>               ajaxEngine.sendRequest( 'getNodeInfo', "node=" + nodeName,
> "builder=" + treeBuilder);
>               expand(nodeName);
>            }
>               loaded[nodeName] = "true";
>            //expand(nodeName); //TODO: add action param to getNodeInfo
> request, combine http request this way
>        }
>      }
>
>      function expandRoot() {
>          log("expandRoot");
>          var ranNum= Math.random()*4;
>          ajaxEngine.sendRequest( 'getNodeInfo', "node=ROOT-NODE",
> "builder="+treeBuilder, "random="+ranNum);
>      }
>
> THe Java service:
>
> package com.xxxxx.xxxx.services.ajax;
>
> import java.io.*;
> import java.util.Map;
>
> import javax.servlet.ServletConfig;
> import javax.servlet.ServletContext;
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
>
> import org.apache.velocity.VelocityContext;
> import org.apache.velocity.app.VelocityEngine;
> import org.apache.velocity.context.Context;
>
> import xxx.xxxxx.xxx.cms.request.XXXXRequestContext;
> import xxx.xxxxx.xxx.cms.request.XXXXRequestContextImpl;
> import xxx.xxxxx.xxx.services.context.builder.ContextBuilder;
> import xxx.xxxxx.xxx.services.context.velocity.VelocityContextImpl;
>
> /**
>   * @author Jeremy Ford
>   *
>   */
> public class AjaxService
> {
>      private boolean debug = false;
>
>      private static final String WAIT_FOR_RESPONSE = "WAIT_FOR_RESPONSE";
>      private static final String CONTENT_TYPE = "text/xml";
>      private static final String AJAX_PROCESSOR = "AJAX processor";
>
>      private static final String BUILDER = "builder";
>      private static final String ACTION = "action";
>
>      private VelocityEngine engine = null;
>      private Map builders;
>      private Map actions;
>
>      private String velocityProperties =
> "/WEB-INF/velocity/velocity.properties";
>
>      public AjaxService(Map builders)
>      {
>          this.builders = builders;
>      }
>
>      public AjaxService(Map builders, Map actions, VelocityEngine engine)
>      {
>          this.builders = builders;
>          this.actions = actions;
>          this.engine = engine;
>      }
>
>      public ContextBuilder getBuilder(String key)
>      {
>          return (ContextBuilder) builders.get(key);
>      }
>
>      public void init(ServletConfig config) throws Exception
>      {
>          /*
>          if (engine == null)
>          {
>              engine = new VelocityEngine();
>              Properties props = new Properties();
>
>              props.load(config.getServletContext().getResourceAsStream(
>                      velocityProperties));
>              engine.init();
>          }
>          */
>      }
>
>      public void process(HttpServletRequest request,
>              HttpServletResponse response, ServletConfig servletConfig)
>      {
>          processAction(request, response, servletConfig);
>          processRequest(request, response, servletConfig);
>      }
>
>      public void processAction(HttpServletRequest request,
>              HttpServletResponse response, ServletConfig servletConfig)
>      {
>          XXXXRequestContext requestContext = new
> XXXXRequestContextImpl(request,
>                  response, servletConfig);
>
>          String actionKey = request.getParameter(ACTION);
>          if(actionKey != null) {
>              AJAXRunnable action = (AJAXRunnable) actions.get(actionKey);
>
>              String waitForResponse =
> request.getParameter(WAIT_FOR_RESPONSE);
>
>              boolean wait = true; //by default, wait for response
>
>              if(waitForResponse != null) {
>                  Boolean.getBoolean(waitForResponse);
>              }
>              if(wait) {
>                  action.run(requestContext);
>              } else {
>                  //TODO:  handle pooling
>                  Thread t = new Thread(action);
>                  t.start();
>              }
>          }
>      }
>
>      public void processRequest(HttpServletRequest request,
>              HttpServletResponse response, ServletConfig servletConfig)
>      {
>          response.setContentType(CONTENT_TYPE);
>
>          XXXXRequestContext requestContext = new
> XXXXRequestContextImpl(request,
>                  response, servletConfig);
>
>          Context context = new VelocityContext();
>          VelocityContextImpl responseContext = new
> VelocityContextImpl(context);
>
>          String builderKey = request.getParameter(BUILDER);
>          ServletContext servletContext = request.getSession()
>                  .getServletContext();
>
>          ContextBuilder builder = getBuilder(builderKey);
>          if (builder == null)
>          {
>              buildError();
>          }
>          else
>          {
>              try
>              {
>                  StringWriter writer = new StringWriter();
>                  boolean result = builder.buildContext(requestContext,
>                          responseContext);
>                  if (result)
>                  {
>                      final InputStream templateResource = servletContext
>                              .getResourceAsStream(builder.getTemplate());
>                      Reader template = new
> InputStreamReader(templateResource);
>                      engine.evaluate(context, writer, AJAX_PROCESSOR,
> template);
>
>                      String buffer = writer.getBuffer().toString();
>                      if (debug)
>                      {
>                          System.out.println(buffer);
>                      }
>                      response.getWriter().write(buffer);
>                  }
>                  else
>                  {
>                      buildError();
>                  }
>              }
>              catch (Exception e)
>              {
>                  //TODO: log
>                  buildError();
>                  e.printStackTrace();
>              }
>          }
>      }
>
>      private void buildError()
>      {
>
>      }
>      /**
>       * @param velocityProperties The velocityProperties to set.
>       */
>      public void setVelocityProperties(String velocityProperties)
>      {
>          this.velocityProperties = velocityProperties;
>      }
> }
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message