mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
.externalToolBuilders
config
source
cpp
java
org
alfresco
example
filesys
jcr
linkvalidation
model
repo
action
admin
attributes
audit
avm
cache
clt
coci
configuration
content
copy
deploy
descriptor
dictionary
domain
exporter
forum
importer
jscript
AVM.java
AVMNode.java
AVMScriptStore.java
Actions.java
AlfrescoRhinoScriptDebugger.java
Association.java
BaseScopableProcessorExtension.java
Behaviour.java
CategoryNode.java
CategoryTemplateNode.java
ChildAssociation.java
Classification.java
ClasspathScriptLocation.java
CrossRepositoryCopy.java
ExecuteScriptJob.java
People.java
RhinoScriptProcessor.java
RhinoScriptTest.java
Scopeable.java
ScriptAction.java
ScriptBehaviour.java
ScriptBehaviourTest.java
ScriptLogger.java
ScriptNode.java
ScriptUtils.java
ScriptableHashMap.java
ScriptableQNameMap.java
Search.java
Session.java
ValueConverter.java
test-context.xml
test_onAddAspect_cmCountable.js
test_onCreateChildAssociation.js
test_onCreateNode_cmContent.js
test_script1.js
test_script2.js
test_script3.js
lock
model
module
node
ownable
policy
processor
remote
rule
search
security
service
template
transaction
version
workflow
sandbox
service
tools
util
apache
queryRegister.dtd
meta-inf
test-resources
web
.classpath
.project
build.xml
SVN rename command used to ensure file history is kept. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5920 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
399 lines
19 KiB
Java
399 lines
19 KiB
Java
/*
|
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* As a special exception to the terms and conditions of version 2.0 of
|
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
|
* FLOSS exception. You should have recieved a copy of the text describing
|
|
* the FLOSS exception, and it is also available here:
|
|
* http://www.alfresco.com/legal/licensing"
|
|
*/
|
|
package org.alfresco.repo.jscript;
|
|
|
|
import java.io.InputStream;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import junit.framework.TestCase;
|
|
|
|
import org.alfresco.model.ContentModel;
|
|
import org.alfresco.repo.dictionary.DictionaryComponent;
|
|
import org.alfresco.repo.dictionary.DictionaryDAO;
|
|
import org.alfresco.repo.dictionary.M2Model;
|
|
import org.alfresco.repo.node.BaseNodeServiceTest;
|
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
|
import org.alfresco.repo.transaction.TransactionUtil;
|
|
import org.alfresco.service.ServiceRegistry;
|
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
import org.alfresco.service.cmr.repository.ContentService;
|
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
import org.alfresco.service.cmr.repository.NodeService;
|
|
import org.alfresco.service.cmr.repository.ScriptService;
|
|
import org.alfresco.service.cmr.repository.StoreRef;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.transaction.TransactionService;
|
|
import org.alfresco.util.ApplicationContextHelper;
|
|
import org.mozilla.javascript.Context;
|
|
import org.mozilla.javascript.Scriptable;
|
|
import org.mozilla.javascript.ScriptableObject;
|
|
import org.springframework.context.ApplicationContext;
|
|
|
|
/**
|
|
* @author Kevin Roast
|
|
*/
|
|
public class RhinoScriptTest extends TestCase
|
|
{
|
|
private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
|
|
|
private ContentService contentService;
|
|
private NodeService nodeService;
|
|
private TransactionService transactionService;
|
|
private ServiceRegistry serviceRegistry;
|
|
private AuthenticationComponent authenticationComponent;
|
|
private ScriptService scriptService;
|
|
|
|
/*
|
|
* @see junit.framework.TestCase#setUp()
|
|
*/
|
|
protected void setUp() throws Exception
|
|
{
|
|
super.setUp();
|
|
|
|
transactionService = (TransactionService)ctx.getBean("transactionComponent");
|
|
contentService = (ContentService)ctx.getBean("contentService");
|
|
nodeService = (NodeService)ctx.getBean("nodeService");
|
|
scriptService = (ScriptService)ctx.getBean("scriptService");
|
|
serviceRegistry = (ServiceRegistry)ctx.getBean("ServiceRegistry");
|
|
|
|
this.authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
|
|
this.authenticationComponent.setSystemUserAsCurrentUser();
|
|
|
|
DictionaryDAO dictionaryDao = (DictionaryDAO)ctx.getBean("dictionaryDAO");
|
|
|
|
// load the system model
|
|
ClassLoader cl = BaseNodeServiceTest.class.getClassLoader();
|
|
InputStream modelStream = cl.getResourceAsStream("alfresco/model/contentModel.xml");
|
|
assertNotNull(modelStream);
|
|
M2Model model = M2Model.createModel(modelStream);
|
|
dictionaryDao.putModel(model);
|
|
|
|
// load the test model
|
|
modelStream = cl.getResourceAsStream("org/alfresco/repo/node/BaseNodeServiceTest_model.xml");
|
|
assertNotNull(modelStream);
|
|
model = M2Model.createModel(modelStream);
|
|
dictionaryDao.putModel(model);
|
|
|
|
DictionaryComponent dictionary = new DictionaryComponent();
|
|
dictionary.setDictionaryDAO(dictionaryDao);
|
|
BaseNodeServiceTest.loadModel(ctx);
|
|
}
|
|
|
|
@Override
|
|
protected void tearDown() throws Exception
|
|
{
|
|
authenticationComponent.clearCurrentSecurityContext();
|
|
super.tearDown();
|
|
}
|
|
|
|
public void testRhinoIntegration()
|
|
{
|
|
TransactionUtil.executeInUserTransaction(
|
|
transactionService,
|
|
new TransactionUtil.TransactionWork<Object>()
|
|
{
|
|
public Object doWork() throws Exception
|
|
{
|
|
// check that rhino script engine is available
|
|
Context cx = Context.enter();
|
|
try
|
|
{
|
|
// The easiest way to embed Rhino is just to create a new scope this way whenever
|
|
// you need one. However, initStandardObjects is an expensive method to call and it
|
|
// allocates a fair amount of memory.
|
|
Scriptable scope = cx.initStandardObjects();
|
|
|
|
// Now we can evaluate a script. Let's create a new associative array object
|
|
// using the object literal notation to create the members
|
|
Object result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}", "TestJS1", 1, null);
|
|
|
|
Scriptable obj = (Scriptable)scope.get("obj", scope);
|
|
|
|
// Should resolve a non-null value
|
|
assertNotNull(obj.get("a", obj));
|
|
|
|
// should resolve "obj.a == 1" - JavaScript objects come back as Number
|
|
assertEquals(new Double(1.0), obj.get("a", obj));
|
|
|
|
// try another script eval - this time a function call returning a result
|
|
result = cx.evaluateString(scope, "function f(x) {return x+1} f(7)", "TestJS2", 1, null);
|
|
assertEquals(8.0, cx.toNumber(result));
|
|
}
|
|
catch (Throwable err)
|
|
{
|
|
err.printStackTrace();
|
|
fail(err.getMessage());
|
|
}
|
|
finally
|
|
{
|
|
cx.exit();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
public void testJSObjectWrapping()
|
|
{
|
|
TransactionUtil.executeInUserTransaction(
|
|
transactionService,
|
|
new TransactionUtil.TransactionWork<Object>()
|
|
{
|
|
public Object doWork() throws Exception
|
|
{
|
|
StoreRef store = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "rhino_" + System.currentTimeMillis());
|
|
NodeRef root = nodeService.getRootNode(store);
|
|
BaseNodeServiceTest.buildNodeGraph(nodeService, root);
|
|
|
|
Context cx = Context.enter();
|
|
try
|
|
{
|
|
Scriptable scope = cx.initStandardObjects();
|
|
|
|
// add logger object so we can perform output from within scripts
|
|
ScriptableObject.putProperty(scope, "logger", new ScriptLogger());
|
|
|
|
// wrap a simple NodeRef Java object
|
|
// we can use Java style method calls within the script to access it's properties
|
|
List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(root);
|
|
NodeRef ref1 = childAssocs.get(0).getChildRef();
|
|
Object wrappedNodeRef = Context.javaToJS(ref1, scope);
|
|
ScriptableObject.putProperty(scope, "rootref", wrappedNodeRef);
|
|
|
|
// evaluate script that touches the wrapped NodeRef
|
|
Object result = cx.evaluateString(scope, "obj = rootref.getId()", "TestJS3", 1, null);
|
|
assertEquals(ref1.getId(), cx.toString(result));
|
|
|
|
// wrap a scriptable Alfresco Node object - the Node object is a wrapper like TemplateNode
|
|
ScriptNode node1 = new ScriptNode(root, serviceRegistry, scope);
|
|
Object wrappedNode = Context.javaToJS(node1, scope);
|
|
ScriptableObject.putProperty(scope, "root", wrappedNode);
|
|
|
|
// evaluate scripts that perform methods on the wrapped Node
|
|
result = cx.evaluateString(scope, TESTSCRIPT1, "TestJS4", 1, null);
|
|
}
|
|
catch (Throwable err)
|
|
{
|
|
err.printStackTrace();
|
|
fail(err.getMessage());
|
|
}
|
|
finally
|
|
{
|
|
cx.exit();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
public void testScriptService()
|
|
{
|
|
TransactionUtil.executeInUserTransaction(
|
|
transactionService,
|
|
new TransactionUtil.TransactionWork<Object>()
|
|
{
|
|
public Object doWork() throws Exception
|
|
{
|
|
StoreRef store = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "rhino_" + System.currentTimeMillis());
|
|
NodeRef root = nodeService.getRootNode(store);
|
|
BaseNodeServiceTest.buildNodeGraph(nodeService, root);
|
|
|
|
try
|
|
{
|
|
Map<String, Object> model = new HashMap<String, Object>();
|
|
model.put("out", System.out);
|
|
|
|
// create an Alfresco scriptable Node object
|
|
// the Node object is a wrapper similar to the TemplateNode concept
|
|
ScriptNode rootNode = new ScriptNode(root, serviceRegistry, null);
|
|
model.put("root", rootNode);
|
|
|
|
// execute test scripts using the various entry points of the ScriptService
|
|
|
|
// test executing a script file via classpath lookup
|
|
Object result = scriptService.executeScript(TESTSCRIPT_CLASSPATH1, model);
|
|
System.out.println("Result from TESTSCRIPT_CLASSPATH1: " + result.toString());
|
|
assertTrue((Boolean)result); // we know the result is a boolean
|
|
|
|
// test executing a script embedded inside Node content
|
|
ChildAssociationRef childRef = nodeService.createNode(
|
|
root,
|
|
BaseNodeServiceTest.ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
|
QName.createQName(BaseNodeServiceTest.NAMESPACE, "script_content"),
|
|
BaseNodeServiceTest.TYPE_QNAME_TEST_CONTENT,
|
|
null);
|
|
NodeRef contentNodeRef = childRef.getChildRef();
|
|
ContentWriter writer = contentService.getWriter(
|
|
contentNodeRef,
|
|
BaseNodeServiceTest.PROP_QNAME_TEST_CONTENT,
|
|
true);
|
|
writer.setMimetype("application/x-javascript");
|
|
writer.putContent(TESTSCRIPT1);
|
|
scriptService.executeScript(contentNodeRef, BaseNodeServiceTest.PROP_QNAME_TEST_CONTENT, model);
|
|
|
|
// test executing a script directly as a String
|
|
scriptService.executeScriptString("javascript", TESTSCRIPT1, model);
|
|
}
|
|
catch (Throwable err)
|
|
{
|
|
err.printStackTrace();
|
|
fail(err.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
public void testScriptActions()
|
|
{
|
|
TransactionUtil.executeInUserTransaction(
|
|
transactionService,
|
|
new TransactionUtil.TransactionWork<Object>()
|
|
{
|
|
public Object doWork() throws Exception
|
|
{
|
|
StoreRef store = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "rhino_" + System.currentTimeMillis());
|
|
NodeRef root = nodeService.getRootNode(store);
|
|
|
|
try
|
|
{
|
|
// create a content object
|
|
ChildAssociationRef childRef = nodeService.createNode(
|
|
root,
|
|
BaseNodeServiceTest.ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
|
QName.createQName(BaseNodeServiceTest.NAMESPACE, "script_content"),
|
|
BaseNodeServiceTest.TYPE_QNAME_TEST_CONTENT,
|
|
null);
|
|
NodeRef contentNodeRef = childRef.getChildRef();
|
|
ContentWriter writer = contentService.getWriter(
|
|
contentNodeRef,
|
|
BaseNodeServiceTest.PROP_QNAME_TEST_CONTENT,
|
|
true);
|
|
writer.setMimetype("application/x-javascript");
|
|
writer.putContent(TESTSCRIPT1);
|
|
|
|
|
|
// create an Alfresco scriptable Node object
|
|
// the Node object is a wrapper similar to the TemplateNode concept
|
|
Map<String, Object> model = new HashMap<String, Object>();
|
|
model.put("doc", new ScriptNode(childRef.getChildRef(), serviceRegistry, null));
|
|
model.put("root", new ScriptNode(root, serviceRegistry, null));
|
|
|
|
// execute to add aspect via action
|
|
Object result = scriptService.executeScript(TESTSCRIPT_CLASSPATH2, model);
|
|
System.out.println("Result from TESTSCRIPT_CLASSPATH2: " + result.toString());
|
|
assertTrue((Boolean)result); // we know the result is a boolean
|
|
|
|
// ensure aspect has been added via script
|
|
assertTrue(nodeService.hasAspect(childRef.getChildRef(), ContentModel.ASPECT_LOCKABLE));
|
|
}
|
|
catch (Throwable err)
|
|
{
|
|
err.printStackTrace();
|
|
fail(err.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
public void xtestScriptActionsMail()
|
|
{
|
|
TransactionUtil.executeInUserTransaction(
|
|
transactionService,
|
|
new TransactionUtil.TransactionWork<Object>()
|
|
{
|
|
public Object doWork() throws Exception
|
|
{
|
|
StoreRef store = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "rhino_" + System.currentTimeMillis());
|
|
NodeRef root = nodeService.getRootNode(store);
|
|
|
|
try
|
|
{
|
|
// create a content object
|
|
ChildAssociationRef childRef = nodeService.createNode(
|
|
root,
|
|
BaseNodeServiceTest.ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
|
QName.createQName(BaseNodeServiceTest.NAMESPACE, "script_content"),
|
|
BaseNodeServiceTest.TYPE_QNAME_TEST_CONTENT,
|
|
null);
|
|
NodeRef contentNodeRef = childRef.getChildRef();
|
|
ContentWriter writer = contentService.getWriter(
|
|
contentNodeRef,
|
|
BaseNodeServiceTest.PROP_QNAME_TEST_CONTENT,
|
|
true);
|
|
writer.setMimetype("application/x-javascript");
|
|
writer.putContent(TESTSCRIPT1);
|
|
|
|
// create an Alfresco scriptable Node object
|
|
// the Node object is a wrapper similar to the TemplateNode concept
|
|
Map<String, Object> model = new HashMap<String, Object>();
|
|
model.put("doc", new ScriptNode(childRef.getChildRef(), serviceRegistry, null));
|
|
model.put("root", new ScriptNode(root, serviceRegistry, null));
|
|
|
|
// execute to add aspect via action
|
|
Object result = scriptService.executeScript(TESTSCRIPT_CLASSPATH3, model);
|
|
System.out.println("Result from TESTSCRIPT_CLASSPATH3: " + result.toString());
|
|
assertTrue((Boolean)result); // we know the result is a boolean
|
|
}
|
|
catch (Throwable err)
|
|
{
|
|
err.printStackTrace();
|
|
fail(err.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
private static final String TESTSCRIPT_CLASSPATH1 = "org/alfresco/repo/jscript/test_script1.js";
|
|
private static final String TESTSCRIPT_CLASSPATH2 = "org/alfresco/repo/jscript/test_script2.js";
|
|
private static final String TESTSCRIPT_CLASSPATH3 = "org/alfresco/repo/jscript/test_script3.js";
|
|
|
|
private static final String TESTSCRIPT1 =
|
|
"var id = root.id;\r\n" +
|
|
"logger.log(id);\r\n" +
|
|
"var name = root.name;\r\n" +
|
|
"logger.log(name);\r\n" +
|
|
"var type = root.type;\r\n" +
|
|
"logger.log(type);\r\n" +
|
|
"var childList = root.children;\r\n" +
|
|
"logger.log(\"zero index node name: \" + childList[0].name);\r\n" +
|
|
"logger.log(\"name property access: \" + childList[0].properties.name);\r\n" +
|
|
"var childByNameNode = root.childByNamePath(\"/\" + childList[0].name);\r\n" +
|
|
"logger.log(\"child by name path: \" + childByNameNode.name);\r\n" +
|
|
"var xpathResults = root.childrenByXPath(\"/*\");\r\n" +
|
|
"logger.log(\"children of root from xpath: \" + xpathResults.length);\r\n";
|
|
}
|