mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
. Added 'script' element config support to externally configured UI action definitions.
. ActionLink component now renders any params found from config definition as URL arguments for an 'href' style action (to support above change) . Added new root scope object 'logger' to the JavaScript API to aid with debugging of scripts git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3480 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -87,6 +87,11 @@ public class RhinoScriptService implements ScriptService
|
|||||||
throw new IllegalArgumentException("Script ClassPath is mandatory.");
|
throw new IllegalArgumentException("Script ClassPath is mandatory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Executing script: " + scriptClasspath);
|
||||||
|
}
|
||||||
|
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -123,6 +128,11 @@ public class RhinoScriptService implements ScriptService
|
|||||||
throw new IllegalArgumentException("Script NodeRef is mandatory.");
|
throw new IllegalArgumentException("Script NodeRef is mandatory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Executing script: " + scriptRef.toString());
|
||||||
|
}
|
||||||
|
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -168,6 +178,11 @@ public class RhinoScriptService implements ScriptService
|
|||||||
throw new IllegalArgumentException("Script argument is mandatory.");
|
throw new IllegalArgumentException("Script argument is mandatory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Executing script:\n" + script);
|
||||||
|
}
|
||||||
|
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -330,6 +345,7 @@ public class RhinoScriptService implements ScriptService
|
|||||||
|
|
||||||
// add other useful util objects
|
// add other useful util objects
|
||||||
model.put("search", new Search(services, companyHome.getStoreRef(), resolver));
|
model.put("search", new Search(services, companyHome.getStoreRef(), resolver));
|
||||||
|
model.put("logger", new ScriptLogger());
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
42
source/java/org/alfresco/repo/jscript/ScriptLogger.java
Normal file
42
source/java/org/alfresco/repo/jscript/ScriptLogger.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Mozilla Public License version 1.1
|
||||||
|
* with a permitted attribution clause. You may obtain a
|
||||||
|
* copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.alfresco.org/legal/license.txt
|
||||||
|
*
|
||||||
|
* 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.alfresco.repo.jscript;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Roast
|
||||||
|
*/
|
||||||
|
public final class ScriptLogger
|
||||||
|
{
|
||||||
|
private static final Logger logger = Logger.getLogger(ScriptLogger.class);
|
||||||
|
|
||||||
|
public boolean isLoggingEnabled()
|
||||||
|
{
|
||||||
|
return logger.isDebugEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean jsGet_isLoggingEnabled()
|
||||||
|
{
|
||||||
|
return isLoggingEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String str)
|
||||||
|
{
|
||||||
|
logger.debug(str);
|
||||||
|
}
|
||||||
|
}
|
@@ -97,6 +97,9 @@ public final class TemplateNode implements Serializable
|
|||||||
private ChildAssociationRef primaryParentAssoc = null;
|
private ChildAssociationRef primaryParentAssoc = null;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Construction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@@ -124,6 +127,10 @@ public final class TemplateNode implements Serializable
|
|||||||
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
|
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Node API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The GUID for the node
|
* @return The GUID for the node
|
||||||
*/
|
*/
|
||||||
@@ -201,49 +208,6 @@ public final class TemplateNode implements Serializable
|
|||||||
return this.children;
|
return this.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A map capable of returning the TemplateNode at the specified Path as a child of this node.
|
|
||||||
*/
|
|
||||||
public Map getChildByNamePath()
|
|
||||||
{
|
|
||||||
return new NamePathResultsMap(this, this.services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A map capable of returning a List of TemplateNode objects from an XPath query
|
|
||||||
* as children of this node.
|
|
||||||
*/
|
|
||||||
public Map getChildrenByXPath()
|
|
||||||
{
|
|
||||||
return new XPathResultsMap(this, this.services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Saved Search
|
|
||||||
* object. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
|
||||||
*/
|
|
||||||
public Map getChildrenBySavedSearch()
|
|
||||||
{
|
|
||||||
return new SavedSearchResultsMap(this, this.services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Lucene search
|
|
||||||
* string. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
|
||||||
*/
|
|
||||||
public Map getChildrenByLuceneSearch()
|
|
||||||
{
|
|
||||||
return new LuceneSearchResultsMap(this, this.services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A map capable of returning a TemplateNode for a single specified NodeRef reference.
|
|
||||||
*/
|
|
||||||
public Map getNodeByReference()
|
|
||||||
{
|
|
||||||
return new NodeSearchResultsMap(this, this.services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes.
|
* @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes.
|
||||||
*/
|
*/
|
||||||
@@ -376,6 +340,142 @@ public final class TemplateNode implements Serializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the node is currently locked
|
||||||
|
*/
|
||||||
|
public boolean getIsLocked()
|
||||||
|
{
|
||||||
|
boolean locked = false;
|
||||||
|
|
||||||
|
if (getAspects().contains(ContentModel.ASPECT_LOCKABLE))
|
||||||
|
{
|
||||||
|
LockStatus lockStatus = this.services.getLockService().getLockStatus(this.nodeRef);
|
||||||
|
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
|
||||||
|
{
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parent node
|
||||||
|
*/
|
||||||
|
public TemplateNode getParent()
|
||||||
|
{
|
||||||
|
if (parent == null)
|
||||||
|
{
|
||||||
|
NodeRef parentRef = this.services.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
||||||
|
// handle root node (no parent!)
|
||||||
|
if (parentRef != null)
|
||||||
|
{
|
||||||
|
parent = new TemplateNode(parentRef, this.services, this.imageResolver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the primary parent association so we can access the association QName and association type QName.
|
||||||
|
*/
|
||||||
|
public ChildAssociationRef getPrimaryParentAssoc()
|
||||||
|
{
|
||||||
|
if (primaryParentAssoc == null)
|
||||||
|
{
|
||||||
|
primaryParentAssoc = this.services.getNodeService().getPrimaryParent(nodeRef);
|
||||||
|
}
|
||||||
|
return primaryParentAssoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Content API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the content String for this node from the default content property
|
||||||
|
* (@see ContentModel.PROP_CONTENT)
|
||||||
|
*/
|
||||||
|
public String getContent()
|
||||||
|
{
|
||||||
|
ContentService contentService = this.services.getContentService();
|
||||||
|
ContentReader reader = contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
|
||||||
|
return (reader != null && reader.exists()) ? reader.getContentString() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return For a content document, this method returns the URL to the content stream for
|
||||||
|
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||||
|
* <p>
|
||||||
|
* For a container node, this method return the URL to browse to the folder in the web-client
|
||||||
|
*/
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
if (getIsDocument() == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] {
|
||||||
|
nodeRef.getStoreRef().getProtocol(),
|
||||||
|
nodeRef.getStoreRef().getIdentifier(),
|
||||||
|
nodeRef.getId(),
|
||||||
|
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } );
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException err)
|
||||||
|
{
|
||||||
|
throw new TemplateException("Failed to encode content URL for node: " + nodeRef, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MessageFormat.format(FOLDER_BROWSE_URL, new Object[] {
|
||||||
|
nodeRef.getStoreRef().getProtocol(),
|
||||||
|
nodeRef.getStoreRef().getIdentifier(),
|
||||||
|
nodeRef.getId() } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The mimetype encoding for content attached to the node from the default content property
|
||||||
|
* (@see ContentModel.PROP_CONTENT)
|
||||||
|
*/
|
||||||
|
public String getMimetype()
|
||||||
|
{
|
||||||
|
if (mimetype == null)
|
||||||
|
{
|
||||||
|
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
mimetype = content.getMimetype();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The size in bytes of the content attached to the node from the default content property
|
||||||
|
* (@see ContentModel.PROP_CONTENT)
|
||||||
|
*/
|
||||||
|
public long getSize()
|
||||||
|
{
|
||||||
|
if (size == null)
|
||||||
|
{
|
||||||
|
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
size = content.getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size != null ? size.longValue() : 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Node Helper API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FreeMarker NodeModel for the XML content of this node, or null if no parsable XML found
|
* @return FreeMarker NodeModel for the XML content of this node, or null if no parsable XML found
|
||||||
*/
|
*/
|
||||||
@@ -466,24 +566,9 @@ public final class TemplateNode implements Serializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the node is currently locked
|
|
||||||
*/
|
|
||||||
public boolean getIsLocked()
|
|
||||||
{
|
|
||||||
boolean locked = false;
|
|
||||||
|
|
||||||
if (getAspects().contains(ContentModel.ASPECT_LOCKABLE))
|
// ------------------------------------------------------------------------------
|
||||||
{
|
// Security API
|
||||||
LockStatus lockStatus = this.services.getLockService().getLockStatus(this.nodeRef);
|
|
||||||
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
|
|
||||||
{
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return List of permissions applied to this Node.
|
* @return List of permissions applied to this Node.
|
||||||
@@ -519,114 +604,56 @@ public final class TemplateNode implements Serializable
|
|||||||
return this.services.getPermissionService().getInheritParentPermissions(this.nodeRef);
|
return this.services.getPermissionService().getInheritParentPermissions(this.nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the parent node
|
|
||||||
*/
|
|
||||||
public TemplateNode getParent()
|
|
||||||
{
|
|
||||||
if (parent == null)
|
|
||||||
{
|
|
||||||
NodeRef parentRef = this.services.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
|
||||||
// handle root node (no parent!)
|
|
||||||
if (parentRef != null)
|
|
||||||
{
|
|
||||||
parent = new TemplateNode(parentRef, this.services, this.imageResolver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent;
|
// ------------------------------------------------------------------------------
|
||||||
|
// Search API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A map capable of returning the TemplateNode at the specified Path as a child of this node.
|
||||||
|
*/
|
||||||
|
public Map getChildByNamePath()
|
||||||
|
{
|
||||||
|
return new NamePathResultsMap(this, this.services);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the primary parent association so we can access the association QName and association type QName.
|
* @return A map capable of returning a List of TemplateNode objects from an XPath query
|
||||||
|
* as children of this node.
|
||||||
*/
|
*/
|
||||||
public ChildAssociationRef getPrimaryParentAssoc()
|
public Map getChildrenByXPath()
|
||||||
{
|
{
|
||||||
if (primaryParentAssoc == null)
|
return new XPathResultsMap(this, this.services);
|
||||||
{
|
|
||||||
primaryParentAssoc = this.services.getNodeService().getPrimaryParent(nodeRef);
|
|
||||||
}
|
|
||||||
return primaryParentAssoc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the content String for this node from the default content property
|
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Saved Search
|
||||||
* (@see ContentModel.PROP_CONTENT)
|
* object. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||||
*/
|
*/
|
||||||
public String getContent()
|
public Map getChildrenBySavedSearch()
|
||||||
{
|
{
|
||||||
ContentService contentService = this.services.getContentService();
|
return new SavedSearchResultsMap(this, this.services);
|
||||||
ContentReader reader = contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
|
|
||||||
return (reader != null && reader.exists()) ? reader.getContentString() : "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return For a content document, this method returns the URL to the content stream for
|
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Lucene search
|
||||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
* string. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||||
* <p>
|
|
||||||
* For a container node, this method return the URL to browse to the folder in the web-client
|
|
||||||
*/
|
*/
|
||||||
public String getUrl()
|
public Map getChildrenByLuceneSearch()
|
||||||
{
|
{
|
||||||
if (getIsDocument() == true)
|
return new LuceneSearchResultsMap(this, this.services);
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] {
|
|
||||||
nodeRef.getStoreRef().getProtocol(),
|
|
||||||
nodeRef.getStoreRef().getIdentifier(),
|
|
||||||
nodeRef.getId(),
|
|
||||||
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } );
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException err)
|
|
||||||
{
|
|
||||||
throw new TemplateException("Failed to encode content URL for node: " + nodeRef, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return MessageFormat.format(FOLDER_BROWSE_URL, new Object[] {
|
|
||||||
nodeRef.getStoreRef().getProtocol(),
|
|
||||||
nodeRef.getStoreRef().getIdentifier(),
|
|
||||||
nodeRef.getId() } );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The mimetype encoding for content attached to the node from the default content property
|
* @return A map capable of returning a TemplateNode for a single specified NodeRef reference.
|
||||||
* (@see ContentModel.PROP_CONTENT)
|
|
||||||
*/
|
*/
|
||||||
public String getMimetype()
|
public Map getNodeByReference()
|
||||||
{
|
{
|
||||||
if (mimetype == null)
|
return new NodeSearchResultsMap(this, this.services);
|
||||||
{
|
|
||||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
|
||||||
if (content != null)
|
|
||||||
{
|
|
||||||
mimetype = content.getMimetype();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mimetype;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The size in bytes of the content attached to the node from the default content property
|
|
||||||
* (@see ContentModel.PROP_CONTENT)
|
|
||||||
*/
|
|
||||||
public long getSize()
|
|
||||||
{
|
|
||||||
if (size == null)
|
|
||||||
{
|
|
||||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
|
||||||
if (content != null)
|
|
||||||
{
|
|
||||||
size = content.getSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size != null ? size.longValue() : 0L;
|
// ------------------------------------------------------------------------------
|
||||||
}
|
// Misc helpers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the image resolver instance used by this node
|
* @return the image resolver instance used by this node
|
||||||
@@ -654,6 +681,9 @@ public final class TemplateNode implements Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Inner classes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class wrapping and providing access to a ContentData property
|
* Inner class wrapping and providing access to a ContentData property
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user