Merged V2.2 to HEAD

8067: WCM browse view screen now allows Template/WebScript based 'custom views'
   8069: Fix to UIWebScript component to correctly replace arbituary context tokens in webscript urls


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8467 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-03-07 14:37:05 +00:00
parent a0450bf1a8
commit 51c836cfeb
8 changed files with 255 additions and 12 deletions

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Apply AVM Custom View</shortname>
<description>Simple UI to help apply a WebScript based custom view to an AVM folder</description>
<url>/avm/applyavmcustomview</url>
<format default="html">extension</format>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,52 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Apply AVM WebScript Custom View</title>
<style>
body {
font-family: Verdana, Helvetica, sans-serif;
font-size: 10pt;
}
.label {
float: left;
width: 10em;
}
.data {
float: left;
}
.field {
clear: left;
float: left;
padding: 8px;
}
</style>
</head>
<body>
<form action="${url.serviceContext}${url.match}" method="post">
<div class="field">
<span class="label">Store:</span>
<span class="data"><input type="text" name="store" size="32" /><br />e.g. website1--admin</span>
</div>
<div class="field">
<span class="label">Folder Path:</span>
<span class="data"><input type="text" name="path" size="64" /><br />e.g. /ROOT/images</span>
</div>
<div class="field">
<span class="label">WebScript URL:</span>
<span class="data"><input type="text" name="view" size="64" value="" /><br />e.g. /utils/avmview<br>A well known token {path} can be used in the url and will be replaced by the current AVM folder path at runtime.</span>
</div>
<div class="field">
<span><input type="submit" value="Apply" /></span>
</div>
</form>
</body>
</html>

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Apply AVM Custom View POST</shortname>
<description>Simple UI to help apply a WebScript based custom view to an AVM folder</description>
<url>/avm/applyavmcustomview</url>
<format default="html">extension</format>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Apply AVM WebScript Custom View - Done</title>
<style>
body {
font-family: Verdana, Helvetica, sans-serif;
font-size: 10pt;
}
</style>
</head>
<body>
<#if success>
Operation Complete.
<#else>
Operation FAILED. Unable to find store or node.
</#if>
</body>
</html>

View File

@@ -0,0 +1,27 @@
// check that search term has been provided
if (args.store == undefined || args.store.length == 0 ||
args.path == undefined || args.path.length == 0 ||
args.view == undefined || args.view.length == 0)
{
status.code = 400;
status.message = "Mandatory arguments not set - please complete all form fields.";
status.redirect = true;
}
else
{
// lookup the root on the store
var storeRootNode = avm.lookupStoreRoot(args.store);
if (storeRootNode != null)
{
var path = storeRootNode.path + args.path;
var node = avm.lookupNode(path);
if (node != null)
{
// add the custom view aspect
node.addAspect("cm:webscriptable");
node.properties["cm:webscript"] = "/wcs" + args.view;
node.save();
model.success = true;
}
}
}

View File

@@ -45,6 +45,7 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
import org.alfresco.config.ConfigService; import org.alfresco.config.ConfigService;
import org.alfresco.linkvalidation.HrefValidationProgress; import org.alfresco.linkvalidation.HrefValidationProgress;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel; import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.AVMNodeType; import org.alfresco.repo.avm.AVMNodeType;
@@ -59,14 +60,19 @@ import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.search.LimitBy; import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
@@ -208,20 +214,23 @@ public class AVMBrowseBean implements IContextListener
protected NavigationBean navigator; protected NavigationBean navigator;
/** AVM service bean reference */ /** AVM service bean reference */
transient private AVMService avmService; transient protected AVMService avmService;
/** AVM sync service bean reference */ /** AVM sync service bean reference */
transient private AVMSyncService avmSyncService; transient protected AVMSyncService avmSyncService;
/** Action service bean reference */ /** Action service bean reference */
transient private ActionService actionService; transient protected ActionService actionService;
/** The FormsService reference */ /** The FormsService reference */
transient private FormsService formsService; transient protected FormsService formsService;
/** The SearchService reference */ /** The SearchService reference */
transient private SearchService searchService; transient private SearchService searchService;
/** The PermissionService reference */
transient protected PermissionService permissionService;
/** /**
* Default Constructor * Default Constructor
@@ -279,6 +288,20 @@ public class AVMBrowseBean implements IContextListener
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* Getter used by the Inline Edit XML JSP
*
* @return The NodeService
*/
public NodeService getNodeService()
{
if (nodeService == null)
{
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
}
return nodeService;
}
/** /**
* Set the workflow service * Set the workflow service
* @param service The workflow service instance. * @param service The workflow service instance.
@@ -320,17 +343,20 @@ public class AVMBrowseBean implements IContextListener
/** /**
* Getter used by the Inline Edit XML JSP * @param permissionService The PermissionService to set.
*
* @return The NodeService
*/ */
public NodeService getNodeService() public void setPermissionService(PermissionService permissionService)
{ {
if (nodeService == null) this.permissionService = permissionService;
}
protected PermissionService getPermissionService()
{
if (permissionService == null)
{ {
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); permissionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
} }
return nodeService; return permissionService;
} }
/** /**
@@ -888,6 +914,90 @@ public class AVMBrowseBean implements IContextListener
this.location = location; this.location = location;
} }
/**
* @return true if the current node has a custom view available
*/
public boolean getHasCustomView()
{
return getHasWebscriptView() || getHasTemplateView();
}
/**
* @return true if the current node has a Template based custom view available
*/
public boolean getHasTemplateView()
{
AVMNode node = getCurrentPathNode();
if (node.hasAspect(ContentModel.ASPECT_TEMPLATABLE))
{
NodeRef templateRef = (NodeRef)node.getProperties().get(ContentModel.PROP_TEMPLATE);
return (templateRef != null && this.getNodeService().exists(templateRef) &&
getPermissionService().hasPermission(templateRef, PermissionService.READ) == AccessStatus.ALLOWED);
}
return false;
}
/**
* @return true if the current node has a Webscript based custom view available
*/
public boolean getHasWebscriptView()
{
AVMNode node = getCurrentPathNode();
if (node.hasAspect(ContentModel.ASPECT_WEBSCRIPTABLE))
{
return (node.getProperties().get(ContentModel.PROP_WEBSCRIPT) != null);
}
return false;
}
/**
* @return the NodeRef.toString() for the current node Template custom view if it has one
*/
public String getCurrentNodeTemplate()
{
NodeRef ref = (NodeRef)getCurrentPathNode().getProperties().get(ContentModel.PROP_TEMPLATE);
return ref != null ? ref.toString() : null;
}
/**
* @return the service url for the current node Webscript custom view if it has one
*/
public String getCurrentNodeWebscript()
{
return (String)getCurrentPathNode().getProperties().get(ContentModel.PROP_WEBSCRIPT);
}
/**
* Returns a model for use by a template on a space Dashboard page.
*
* @return model containing current current space info.
*/
@SuppressWarnings("unchecked")
public Map getTemplateModel()
{
HashMap model = new HashMap(4, 1.0f);
model.put("space", getCurrentPathNode().getNodeRef());
model.put("path", getCurrentPathNode().getPath());
model.put(TemplateService.KEY_IMAGE_RESOLVER,
new TemplateImageResolver()
{
public String resolveImagePathForName(String filename, FileTypeImageSize size)
{
return Utils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
}
});
return model;
}
public Map getCustomWebscriptContext()
{
HashMap model = new HashMap(2, 1.0f);
model.put("path", getCurrentPathNode().getPath());
return model;
}
/** /**
* @return true if the current user has the manager role in the current website * @return true if the current user has the manager role in the current website
*/ */
@@ -915,7 +1025,7 @@ public class AVMBrowseBean implements IContextListener
{ {
// see if there are any deployment attempts for the staging area // see if there are any deployment attempts for the staging area
NodeRef webProjectRef = this.getWebsite().getNodeRef(); NodeRef webProjectRef = this.getWebsite().getNodeRef();
String store = (String)nodeService.getProperty(webProjectRef, String store = (String)getNodeService().getProperty(webProjectRef,
WCMAppModel.PROP_AVMSTORE); WCMAppModel.PROP_AVMSTORE);
List<NodeRef> deployAttempts = DeploymentUtil.findDeploymentAttempts(store); List<NodeRef> deployAttempts = DeploymentUtil.findDeploymentAttempts(store);

View File

@@ -3395,6 +3395,10 @@
<property-name>searchService</property-name> <property-name>searchService</property-name>
<value>#{SearchService}</value> <value>#{SearchService}</value>
</managed-property> </managed-property>
<managed-property>
<property-name>permissionService</property-name>
<value>#{PermissionService}</value>
</managed-property>
</managed-bean> </managed-bean>
<managed-bean> <managed-bean>

View File

@@ -188,6 +188,21 @@
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width=4></td> <td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width=4></td>
</tr> </tr>
<%-- Custom Template View --%>
<a:panel id="custom-wrapper-panel" rendered="#{AVMBrowseBean.hasCustomView && AVMBrowseBean.searchContext == null}">
<tr valign=top>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td>
<td style="padding:4px">
<a:panel id="custom-panel" border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white" styleClass="mainSubTitle"
label="#{msg.custom_view}" progressive="true">
<r:webScript id="webscript" scriptUrl="#{AVMBrowseBean.currentNodeWebscript}" context="#{AVMBrowseBean.customWebscriptContext}" rendered="#{AVMBrowseBean.hasWebscriptView}" />
<r:template id="template" template="#{AVMBrowseBean.currentNodeTemplate}" model="#{AVMBrowseBean.templateModel}" rendered="#{!AVMBrowseBean.hasWebscriptView && AVMBrowseBean.hasTemplateView}" />
</a:panel>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width=4></td>
</tr>
</a:panel>
<%-- Details - Folders --%> <%-- Details - Folders --%>
<tr valign=top> <tr valign=top>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td> <td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td>