Scripting OpenCms
OpenCms ships with a shell script for accessing the virtual file system from the command line. This is useful for a lot of administrative tasks like importing modules or exporting content. You can supply scripts that issue commands or use the shell interactively. As the syntax for the scripts is quite limited some tasks can’t be achieved that easily. This blogpost describes a way to circumvent these problems by generating the script files.
I will present a simple extension of this mechanism that makes it possible to access the VFS using the groovy scripting language that also runs on the Java Virtual Machine. It can be useful to import users or content from different systems, create content for test runs or any other task you can think of.
The original script file for accessing the cms shell is located in WEB-INF/cmsshell.sh
(See here on how to make it work on Ubuntu systems). The following file is a modification of the original file that doesn’t call the underlying Java class but another groovy script and should be placed next to the original:
#!/bin/sh # Script for evaluating groovy scripts with access to opencms. # # Please make sure that "servlet-api.jar" and "jsp-api.jar" are found. # # get path to opencms base directory OPENCMS_BASE=`pwd` # get path to tomcat home if [ -z "$TOMCAT_HOME" ]; then [ -n "$CATALINA_HOME" ] && TOMCAT_HOME="$CATALINA_HOME" [ -z "$TOMCAT_HOME" ] && TOMCAT_HOME="$OPENCMS_BASE"/../../.. fi TOMCAT_CLASSPATH="" # Support for tomcat 5 for JAR in ${TOMCAT_HOME}/common/lib/*.jar; do TOMCAT_CLASSPATH="${TOMCAT_CLASSPATH}:${JAR}" done for JAR in ${TOMCAT_HOME}/shared/lib/*.jar; do TOMCAT_CLASSPATH="${TOMCAT_CLASSPATH}:${JAR}" done # Support for tomcat 6 for JAR in ${TOMCAT_HOME}/lib/*.jar; do TOMCAT_CLASSPATH="${TOMCAT_CLASSPATH}:${JAR}" done OPENCMS_CLASSPATH="" for JAR in ${OPENCMS_BASE}/lib/*.jar; do OPENCMS_CLASSPATH="${OPENCMS_CLASSPATH}:${JAR}" done groovy -classpath "${OPENCMS_CLASSPATH}:${TOMCAT_CLASSPATH}:classes" evalscripts.groovy -base="${OPENCMS_BASE}" "$@"
As you can see, a groovy script named “evalscripts.groovy” is called and all options are passed to it. The script:
import org.opencms.main.CmsShell; import org.opencms.file.CmsObject; base = args[0].substring(CmsShell.SHELL_PARAM_BASE.length()); shell = new CmsShell(base, null, null, ">", null) { CmsObject getCmsObject() { return m_cms; } } user = "Admin"; pass = "admin"; cms = shell.getCmsObject(); cms.loginUser(user, pass); binding1 = new Binding(); binding1.setProperty('cmsObject' , cms); groovyShell = new GroovyShell(binding1); for (int i = 1; i < args.length; i++) { groovyShell.evaluate(new File(args[i])) } shell.exit();
We start by creating an instance of the CmsShell class and make the underlying CmsObject accessible. We login using the Admin user and bind the instance so we can use it in the scripts that are doing the real work. This is where you come into play: You can write any groovy script that uses this CmsObject and do whatever you want. Some ideas? Why not create some users:
10.times { cmsObject.createUser("User$it", "Pass$it", "", new HashMap()); }
Or list all users:
cmsObject.getUsers().each { println it.name }
How do you use it? You pass the path to the scripts that contain your logic to the shell script and it will execute them automatically. Suppose the shell script is named groovyshell.sh and the groovy files are named createUsers.groovy and listUsers.groovy. Execute them like this:
./groovyshell.sh createUsers.groovy listUsers.groovy
You will see the familiar OpenCms startup sequence followed by the output of the second script:
... Welcome to the OpenCms shell! This is OpenCms 7.5.x. Copyright (c) 2010 Alkacon Software GmbH OpenCms comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions. Please see the GNU Lesser General Public Licence for further details. help Shows this text. help * Shows the signatures of all available methods. help {string} Shows the signatures of all methods containing this string. exit or quit Leaves this OpenCms Shell. Admin Export Guest User0 User1 User2 User3 User4 User5 User6 User7 User8 User9 Goodbye! ...
I think this will be useful for us in the future, maybe also for you?
Florian Hopf
Hi Alejandro,
unfortunately it's been I while since I used this so I can't really help. But I do remember we had the same problem when starting and stopping OpenCms using Maven. It never caused a real problem so we didn't investigate.
It seems to be kind of a background task <a href="http://grepcode.com/file/repo1.maven.org/maven2/org.opencms.modules/org.opencms.frontend.templatetwo/8.0.1/org/opencms/frontend/templatetwo/CmsTemplateModuleAction.java" rel="nofollow">according to the sources</a>. Not sure how this can be shut down correctly.
Good luck
Florian
Alejandro
Hello Florian,
When the process finishes and shuts down the console I get an exception:
Shutting down OpenCms, version 7.5.4 in web application "opencms"
Shutdown completed, total uptime was 00:00:02.
Exception in thread "Thread-2" java.lang.NullPointerException
at org.opencms.db.CmsSecurityManager.existsResource(CmsSecurityManager.j
ava:1572)
at org.opencms.file.CmsObject.existsResource(CmsObject.java:1136)
at org.opencms.file.CmsObject.existsResource(CmsObject.java:1103)
at org.opencms.frontend.templatetwo.CmsTemplateModuleAction$1.run(CmsTem
plateModuleAction.java:107)
at java.lang.Thread.run(Thread.java:744)
How can I avoid this?
Regards
Christoph Kukulies
Thanks, Florian,
that helped.
Only a minor glitch. when exiting:
<code>
root@kukulies:/var/lib/tomcat6/webapps/ROOT/WEB-INF# ./groovyshell listusers.gro ovy
OpenCms WEB-INF path: "/var/lib/tomcat6/webapps/ROOT/WEB-INF".
OpenCms property file: "/var/lib/tomcat6/webapps/ROOT/WEB-INF/config/opencms.pro perties".
Welcome to the OpenCms shell!
This is OpenCms 8.0.3.
Copyright (c) 2010 Alkacon Software GmbH
OpenCms comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to
redistribute it under certain conditions.
Please see the GNU Lesser General Public Licence for
further details.
help Shows this text.
help * Shows the signatures of all available methods.
help {string} Shows the signatures of all methods containing this string.
exit or quit Leaves this OpenCms Shell.
Admin
Export
Guest
User0
User1
User2
User3
User4
User5
User6
User7
User8
User9
Chris
Goodbye!
Shutting down OpenCms, version 8.0.3 in web application "ROOT"
Shutdown completed, total uptime was 00:00:03.
Exception in thread "Thread-2" java.lang.NullPointerException
at org.opencms.file.CmsRequestContext.getAdjustedSiteRoot(CmsRequestCont ext.java:156)
at org.opencms.file.CmsRequestContext.addSiteRoot(CmsRequestContext.java :191)
at org.opencms.file.CmsRequestContext.addSiteRoot(CmsRequestContext.java :174)
at org.opencms.file.CmsObject.addSiteRoot(CmsObject.java:145)
at org.opencms.file.CmsObject.existsResource(CmsObject.java:1097)
at org.opencms.file.CmsObject.existsResource(CmsObject.java:1067)
at org.opencms.frontend.templatetwo.CmsTemplateModuleAction$1.run(CmsTem plateModuleAction.java:107)
at java.lang.Thread.run(Thread.java:679)
</code>
Florian Hopf
Christoph, thanks for your feedback! It seems that the method doesn't exist anymore for OpenCms 8. This is a version that lacks the elegance and brevity of the old version but also works with recent versions:
<code>
org.opencms.main.OpenCms.getOrgUnitManager().getUsers(cmsObject, "/", true).each {
println it.name
}
</code>
Note that there still is no semicolon as fortunately those are <a href="http://groovy.codehaus.org/Statements" rel="nofollow">optional in most cases</a> in Groovy ;)
Christoph Kukulies
Thanks Florian, nice approach. I tried it but I'm getting:
<code>
:/var/lib/tomcat6/webapps/ROOT/WEB-INF# ./groovyshell listusers.groovy
OpenCms WEB-INF path: "/var/lib/tomcat6/webapps/ROOT/WEB-INF".
OpenCms property file: "/var/lib/tomcat6/webapps/ROOT/WEB-INF/config/opencms.properties".
Welcome to the OpenCms shell!
This is OpenCms 8.0.3.
Copyright (c) 2010 Alkacon Software GmbH
OpenCms comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to
redistribute it under certain conditions.
Please see the GNU Lesser General Public Licence for
further details.
help Shows this text.
help * Shows the signatures of all available methods.
help {string} Shows the signatures of all methods containing this string.
exit or quit Leaves this OpenCms Shell.
Caught: groovy.lang.MissingMethodException: No signature of method: org.opencms.file.CmsObject.getUsers() is applicable for argument types: () values: []
Possible solutions: getClass(), readUser(java.lang.String), readUser(org.opencms.util.CmsUUID), readUser(java.lang.String, java.lang.String), getParent(java.lang.String), writeUser(org.opencms.file.CmsUser)
at listusers.run(listusers.groovy:1)
at evalscripts.run(evalscripts.groovy:23)
</code>
--
Christoph
BTW, aren't you missing a semicolon after println it.name in the
example:
<code>
cmsObject.getUsers().each {
println it.name
}
</code>