Snippet: JSP para invocar script groovy

Fri Feb 27 13:49:59 CET 2015       Sergio Raposo Vargas       Código - Snippet, OpenCms, Programación

Definición de Groovy

En primer lugar, ¿sabéis qué es Groovy? Os dejo una definición (fuente: http://www.codejobs.biz)

Groovy es un lenguaje de programación dinámico orientado a objetos para la máquina virtual Java (JVM) que se puede utilizar en cualquier lugar dónde se utilice Java. El lenguaje puede ser utilizado para combinar módulos de Java, ampliar las aplicaciones existentes de Java ó escribir nuevas aplicaciones.

Por lo tanto, es un lenguaje de programación totalmente compatible con el código de java pero mucho menos estricto a la hora de escribir código que java y sobre todo, no requiere de compilación para su ejecución. Por lo tanto, podemos programar una clase que podemos subir a nuestro OpenCms, ejecutarla, y si algo está mal o tenemos que modificar algo, podemos hacerlo en caliente sin tener que reiniciar nuestro servidor de aplicaciones.

call-groovy.jsp

Ya sabemos porque groovy nos parece interesante, ahora vamos a ver como llamar un script groovy desde una jsp en OpenCms.

En primer lugar debemos crearnos un módulo por ejemplo: org.opencmshispano.groovy. Dentro de nuestro módulo nos creamos dos carpetas que llamaremos script-groovy y lib, y en la configuración del módulo pondremos un punto de exportación de dicha carpeta a: WEB-INF/script-groovy/ y a WEB-INF/lib/.

En la carpeta lib subiremos la librería de groovy necesaria para que funcione, en concreto: groovy-all-2.3.7.jar (se ha probado con esta versión, pero puede funcionar con otra sin problema)

Ahora creamos una jsp dentro de la carpeta script-groovy que llamaremos: call-groovy.jsp y cuyo código será:

<%@page buffer="none" session="false" taglibs="c,cms,fmt, fn" 
import="java.util.*,org.opencms.util.CmsStringUtil,org.opencms.file.*, org.opencms.main.*,
org.opencms.file.types.CmsResourceTypeFolder,org.opencms.main.*,org.opencms.util.*,
groovy.lang.*, java.io.*" trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="cms" uri="http://www.opencms.org/taglib/cms" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="es">
<head>
<title>Ejecucion Script Groovy</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="SAGA SOLUCIONES - OpenCms Partners">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row clearfix">
<div class="col-md-12 column">
<h1>Ejecuci&oacute;n script Groovy</h1>
<form method="post">
<div class="form-group">
<label for="script">Indique el nombre del script:</label>
<input type="text" class="form-control" id="scriptname" name="scriptname" value="<c:out value="${param.scriptname }"/>" placeholder="script-groovy/ctc/ScriptTest.groovy">
<p class="small">Recuerda que debe estar el script en la ruta WEB-INF/</p>
</div>
<input type="hidden" value="true" name="exec"/>
<input class="btn btn-success" type="submit" value="Ejecutar!"/>
</form>
<c:if test="${param.exec != null and param.scriptname!=null}">
<c:set var="cmsObject" value="${cms.vfs.cmsObject }" scope="request"/>
<%
CmsObject cmsObject = (CmsObject)request.getAttribute("cmsObject");
//Tenemos que inicializar el site donde vamos a trabajar
cmsObject.getRequestContext().setSiteRoot("/sites/sitename/");
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
//Obtenemos la ruta del webinf:
String webInfPath = OpenCms.getSystemInfo().getWebInfRfsPath();
String scriptName = request.getParameter("scriptname");
//Obtiene la clase groovy
Class groovyClass = loader.parseClass(new File(webInfPath+scriptName));
out.println("<br/><p> <strong>Se est&aacute; ejecutando el script: "+webInfPath+scriptName+"</strong></p>");
//Llama al metodo init del script groovy indicado
try{
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
groovyObject.invokeMethod("init", new Object[] { cmsObject });
%>
<p class="alert alert-success">El script se ha ejecutado correctamente</p>
<%
}catch(Exception ex){
%>
<p class="alert alert-danger">Se ha producido un error: <br/> <%=ex %></p>
<%
}
%>
</c:if>
</div>
</div>
</div>
</body>
</html>

Si os fijáis, esta jsp muestra inicialmente un formulario donde debemos indicar la ruta de la clase groovy que queremos ejecutar, siempre a partir del WEB-INF de nuestro OpenCms.

TestOpenCmsGroovy.groovy

Una vez que ya tenemos la jsp, tenemos que hacer nuestra clase groovy a ejecutar, para ello vamos a crear una clase de prueba que llamaremos TestOpenCmsGroovy.groovy y la guardamos en la misma carpeta de script-groovy. Veamos un código de ejemplo:

import groovy.xml.*
import org.opencms.file.CmsObject
class TestOpenCmsGroovy{
CmsObject cmsObject;
public TestOpenCmsGroovy(){
}
public void init(def cms){
cmsObject = cms;
println("************************************");
println("Script Test");
println("************************************");
println("Ejecución lanzada correctamente ...");
}
}

 Es importante que se publique cada vez que hagamos un cambio en esta clase ya que tiene que estar exportada siempre en disco. Tras publicar, podemos ejecutar este script directamente desde la jsp anterior escribiendo en el cuadro de texto: script-groovy/TestOpenCmsGroovy.groovy

Consejo de seguridad

Tened en cuenta que con esta jsp podemos ejecutar cualquier script groovy que tengamos en nuestro sistema, por lo que es aconsejable que esta jsp la protejamos de alguna forma, ya sea por permiso o restricción de apache o algo similar de forma que nos aseguremos que solo se puede invocar por los usuarios adecuados.

 Snippet, Código, groovy, jsp, OpenCms