jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dvit...@apache.org
Subject svn commit: r1653018 - in /jspwiki/trunk/jspwiki-war/src: main/java/org/apache/wiki/ main/java/org/apache/wiki/plugin/ main/scripts/ main/webapp/WEB-INF/ test/java/org/apache/wiki/
Date Mon, 19 Jan 2015 14:49:17 GMT
Author: dvittor
Date: Mon Jan 19 14:49:17 2015
New Revision: 1653018

URL: http://svn.apache.org/r1653018
Log:
JSPWIKI-566: Added an AJAX framework for Plugins

Added:
    jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java
  (with props)
    jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java 
 (with props)
    jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java   (with
props)
Modified:
    jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/DefaultPluginManager.java
    jspwiki/trunk/jspwiki-war/src/main/scripts/jspwiki-common.js
    jspwiki/trunk/jspwiki-war/src/main/webapp/WEB-INF/web.xml

Added: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java?rev=1653018&view=auto
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java
(added)
+++ jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java
Mon Jan 19 14:49:17 2015
@@ -0,0 +1,146 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.     
+ */
+package org.apache.wiki;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+/**
+ * This provides a simple ajax servlet for handling /ajax/<ClassName> requests.
+ * Classes need to be registered using {@link WikiAjaxDispatcherServlet.register}
+ *
+ * @author David VIttor
+ * @date 20/01/2015
+ * @since 2.10.2-svn10
+ */
+public class WikiAjaxDispatcherServlet extends HttpServlet {
+	private static final long serialVersionUID = 1L;
+	private static Map<String,HttpServlet> ajaxServlets = new HashMap<String,HttpServlet>();
+    static final Logger log = Logger.getLogger(WikiAjaxDispatcherServlet.class.getName());
+    private static final String PATH_AJAX = "/ajax/";
+
+    /**
+     * {@inheritDoc}
+     */
+    public void init(ServletConfig config)
+            throws ServletException {
+        super.init(config);
+
+        log.info("WikiAjaxDispatcherServlet initialized.");
+    }
+
+    public static void register(HttpServlet servlet) {
+    	log.info("WikiAjaxDispatcherServlet registering "+servlet.getClass().getSimpleName()+"="+servlet);
+        ajaxServlets.put(servlet.getClass().getSimpleName(),servlet);
+    }
+
+    /**
+     * Calls {@link this.performAction}
+     */
+    public void doPost(HttpServletRequest req, HttpServletResponse res)
+            throws IOException, ServletException {
+        performAction(req,res);
+    }
+
+    /**
+     * Calls {@link this.performAction}
+     */
+    public void doGet(HttpServletRequest req, HttpServletResponse res)
+            throws IOException, ServletException {
+        performAction(req,res);
+    }
+
+    /**
+     * The main method which get the requestURI "/ajax/<ServletName>", gets the 
+     * {@link this.getServletName} and finds the servlet using {@link this.findServletByName}.

+     * It then calls servlet.service().
+     * @param req the inbound request
+     * @param res the outbound response
+     * @throws IOException
+     * @throws ServletException if no registered servlet can be found
+     */
+    private void performAction(HttpServletRequest req, HttpServletResponse res)
+            throws IOException, ServletException {
+        String path = req.getRequestURI();
+        String servletName = getServletName(path);
+        if (servletName!=null) {
+            HttpServlet ajaxServlet = findServletByName(servletName);
+            if (ajaxServlet != null) {
+                ajaxServlet.service(req, res);
+            } else {
+                log.error("No registered class for servletName=" + servletName + " in path="
+ path);
+                throw new ServletException("No registered class for servletName=" + servletName);
+            }
+        }
+    }
+
+    /**
+     * Get the name of the servlet given the requestURI.
+     * @param path The requestURI, which must contains "/ajax/<ServletName>" in the
path
+     * @return The ServletName for the requestURI, or null
+     * @throws ServletException if the path is invalid
+     */
+    public String getServletName(String path) throws ServletException {
+        String result = null;
+        if (StringUtils.isBlank(path)) {
+            return result;
+        }
+        int index = path.indexOf(PATH_AJAX);
+        if (index<0) {
+            throw new ServletException("Invalid path provided " + path + " does not contain
'" + PATH_AJAX + "'");
+        }
+        path = path.substring(index+6);
+        index = path.indexOf("/");
+        if (index == -1) {
+            index = path.indexOf("#");
+            if (index == -1) {
+                index = path.indexOf("?");
+            }
+        }
+        if (index == -1) {
+            result = path;
+        }
+        else {
+            result = path.substring(0,index);
+        }
+
+        return result;
+    }
+
+    /**
+     * Find the servlet as registered in {@link WikiAjaxDispatcherServlet.register}.
+     * 
+     * @param servletName the name of the servlet from {@link this.getServletNamee}
+     * @return The first servlet found, or null.
+     */
+    public HttpServlet findServletByName(String servletName) {
+    	return ajaxServlets.get(servletName);
+    }
+
+}

Propchange: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/WikiAjaxDispatcherServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/DefaultPluginManager.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/DefaultPluginManager.java?rev=1653018&r1=1653017&r2=1653018&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/DefaultPluginManager.java
(original)
+++ jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/DefaultPluginManager.java
Mon Jan 19 14:49:17 2015
@@ -29,6 +29,7 @@ import org.apache.oro.text.regex.Pattern
 import org.apache.oro.text.regex.Perl5Compiler;
 import org.apache.oro.text.regex.Perl5Matcher;
 import org.apache.wiki.InternalWikiException;
+import org.apache.wiki.WikiAjaxDispatcherServlet;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.WikiEngine;
 import org.apache.wiki.api.engine.PluginManager;
@@ -65,6 +66,8 @@ import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
 
+import javax.servlet.http.HttpServlet;
+
 /**
  *  Manages plugin classes.  There exists a single instance of PluginManager
  *  per each instance of WikiEngine, that is, each JSPWiki instance.
@@ -601,6 +604,8 @@ public class DefaultPluginManager extend
         
         /**
          *  Initializes a plugin, if it has not yet been initialized.
+         *  If the plugin extends {@link HttpServlet} it will automatically 
+         *  register it as AJAX using {@link WikiAjaxDispatcherServlet.register}.
          *
          *  @param engine The WikiEngine
          *  @param searchPath A List of Strings, containing different package names.
@@ -616,6 +621,9 @@ public class DefaultPluginManager extend
                     if( p instanceof InitializablePlugin ) {
                         ( ( InitializablePlugin )p ).initialize( engine );
                     }
+                    if( p instanceof HttpServlet ) {
+                    	WikiAjaxDispatcherServlet.register( (HttpServlet) p );
+                    }
                 } catch( Exception e ) {
                     log.info( "Cannot initialize plugin " + m_className, e );
                 }

Added: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java?rev=1653018&view=auto
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java (added)
+++ jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java Mon
Jan 19 14:49:17 2015
@@ -0,0 +1,66 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+package org.apache.wiki.plugin;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.api.plugin.WikiPlugin;
+
+/**
+ * @author David VIttor
+ * @date 20/01/2015
+ * @since 2.10.2-svn10
+ */
+public class SampleAjaxPlugin extends HttpServlet implements WikiPlugin {
+	private static final long serialVersionUID = 1L;
+
+	@Override
+    public String execute(WikiContext context, Map<String, String> params) throws PluginException
{
+    	String id = Integer.toString(this.hashCode());
+        String baseUrl = context.getEngine().getBaseURL();
+        String url = baseUrl+"ajax/SampleAjaxPlugin";
+        String html= "<div onclick='makeRequest(\"GET\",\""+url+"\",\"result"+id+"\",\"Loading...\")'
style='color: blue; cursor: pointer'>Press Me</div>\n"+
+                        "<div id='result"+id+"'></div>";
+        return html;
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
+        try {
+            Thread.sleep(5000); // Wait 5 seconds
+        } catch (Exception e) {}
+        resp.getWriter().print("You called by get!");
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
+        try {
+            Thread.sleep(5000); // Wait 5 seconds
+        } catch (Exception e) {}
+        resp.getWriter().print("You called by post!");
+    }
+}

Propchange: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/plugin/SampleAjaxPlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/jspwiki-common.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/jspwiki-common.js?rev=1653018&r1=1653017&r2=1653018&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/jspwiki-common.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/jspwiki-common.js Mon Jan 19 14:49:17 2015
@@ -219,6 +219,66 @@ function getAncestorByTagName( node, tag
 	}
 }
 
+/** AJAX Requests as per http://javapapers.com/ajax/getting-started-with-ajax-using-java/
**/
+/*
+ * creates a new XMLHttpRequest object which is the backbone of AJAX,
+ * or returns false if the browser doesn't support it
+ */
+function getXMLHttpRequest() {
+	var xmlHttpReq = false;
+	// to create XMLHttpRequest object in non-Microsoft browsers
+	if (window.XMLHttpRequest) {
+		xmlHttpReq = new XMLHttpRequest();
+	} else if (window.ActiveXObject) {
+		try {
+			// to create XMLHttpRequest object in later versions
+			// of Internet Explorer
+			xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
+		} catch (exp1) {
+			try {
+				// to create XMLHttpRequest object in older versions
+				// of Internet Explorer
+				xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
+			} catch (exp2) {
+				xmlHttpReq = false;
+			}
+		}
+	}
+	return xmlHttpReq;
+}
+
+/*
+ * AJAX call starts with this function
+ */
+function makeRequest(method,url,responseId,loading) {
+	var xmlHttpRequest = getXMLHttpRequest();
+	xmlHttpRequest.onreadystatechange = getReadyStateHandler(xmlHttpRequest,responseId,loading);
+	xmlHttpRequest.open(method, url, true);
+	xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+	xmlHttpRequest.send(null);
+}
+
+/*
+ * Returns a function that waits for the state change in XMLHttpRequest
+ */
+function getReadyStateHandler(xmlHttpRequest,responseId,loading) {
+	// an anonymous function returned
+	// it listens to the XMLHttpRequest instance
+	return function() {
+		if (xmlHttpRequest.readyState >=1 && xmlHttpRequest.readyState <4) {
+			document.getElementById(responseId).innerHTML = loading;
+		}
+		if (xmlHttpRequest.readyState == 4) {
+			if (xmlHttpRequest.status == 200) {
+				document.getElementById(responseId).innerHTML = xmlHttpRequest.responseText;
+			} else {
+				document.getElementById(responseId).innerHTML("HTTP error " + xmlHttpRequest.status +
": " + xmlHttpRequest.statusText);
+			}
+		}
+	};
+}
+/** End AJAX Requests **/
+
 
 /** 100 Wiki functions **/
 var Wiki = {
@@ -414,6 +474,12 @@ var Wiki = {
 
 	$jsonid : 10000,
 	jsonrpc: function(method, params, fn) {
+		$$('meta').each(function(el){
+			var n = el.getProperty('name') || '';
+			if( n.indexOf('wiki') == 0 ) this[n.substr(4)] = el.getProperty('content');
+		},this);
+
+		if (Wiki.JsonUrl) {
 		new Ajax( Wiki.JsonUrl, {
 			postBody: Json.toString({"id":Wiki.$jsonid++, "method":method, "params":params}),
 			method: 'post',
@@ -425,6 +491,7 @@ var Wiki = {
 				}
 			}
 		}).request();
+		}
 	}
 }
 

Modified: jspwiki/trunk/jspwiki-war/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/webapp/WEB-INF/web.xml?rev=1653018&r1=1653017&r2=1653018&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/webapp/WEB-INF/web.xml (original)
+++ jspwiki/trunk/jspwiki-war/src/main/webapp/WEB-INF/web.xml Mon Jan 19 14:49:17 2015
@@ -141,6 +141,13 @@
        <load-on-startup>1</load-on-startup>
    </servlet>
 
+    <!-- WikiAjaxDispatcherServlet -->
+    <servlet>
+        <servlet-name>WikiAjaxDispatcherServlet</servlet-name>
+        <servlet-class>org.apache.wiki.WikiAjaxDispatcherServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
    <!--
        Attachment exchange handler.
      -->
@@ -159,7 +166,12 @@
        <servlet-name>WikiServlet</servlet-name>
        <url-pattern>/wiki/*</url-pattern>
    </servlet-mapping>
-   
+
+    <servlet-mapping>
+        <servlet-name>WikiAjaxDispatcherServlet</servlet-name>
+        <url-pattern>/ajax/*</url-pattern>
+    </servlet-mapping>
+
    <servlet-mapping>
        <servlet-name>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-name>
        <url-pattern>/JSON-RPC</url-pattern>

Added: jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java?rev=1653018&view=auto
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java (added)
+++ jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java Mon Jan
19 14:49:17 2015
@@ -0,0 +1,69 @@
+/*
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+package org.apache.wiki;
+
+import javax.servlet.http.HttpServlet;
+
+import junit.framework.TestCase;
+
+import org.apache.wiki.plugin.SampleAjaxPlugin;
+import org.apache.wiki.xmlrpc.RPCServlet;
+
+/**
+ * @author David VIttor
+ * @date 20/01/2015
+ * @since 2.10.2-svn10
+ */
+public class WikiAjaxServletTest extends TestCase {
+
+    public void testServlets() throws Exception {
+        String[] paths = new String[] {
+                "/ajax/MyPlugin",
+                "/ajax/MyPlugin/",
+                "/ajax/MyPlugin/Friend",
+                "/ajax/MyPlugin?",
+                "/ajax/MyPlugin?param=123&param=231",
+                "/ajax/MyPlugin#hashCode?param=123&param=231",
+                "http://google.com.au/test/ajax/MyPlugin#hashCode?param=123&param=231",
+                "/test//ajax/MyPlugin#hashCode?param=123&param=231",
+                "http://localhost:8080/ajax/MyPlugin#hashCode?param=123&param=231" };
+
+        assertEquals(9,paths.length);
+        WikiAjaxDispatcherServlet wikiAjaxDispatcherServlet = new WikiAjaxDispatcherServlet();
+        for (String path : paths) {
+            String servletName = wikiAjaxDispatcherServlet.getServletName(path);
+            assertEquals("MyPlugin", servletName);
+        }
+
+        // The plugin SampleAjaxPlugin
+        WikiAjaxDispatcherServlet.register(new SampleAjaxPlugin());
+        HttpServlet servlet = wikiAjaxDispatcherServlet.findServletByName("SampleAjaxPlugin");
+        assertNotNull(servlet);
+        assertTrue(servlet instanceof SampleAjaxPlugin);
+
+        WikiAjaxDispatcherServlet.register(new RPCServlet());
+        HttpServlet servlet2 = wikiAjaxDispatcherServlet.findServletByName("RPCServlet");
+        assertNotNull(servlet2);
+        assertTrue(servlet2 instanceof RPCServlet);
+
+        HttpServlet servlet3 = wikiAjaxDispatcherServlet.findServletByName("TestWikiNonAjaxServlet");
+        assertNull(servlet3);
+    }
+
+}

Propchange: jspwiki/trunk/jspwiki-war/src/test/java/org/apache/wiki/WikiAjaxServletTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message