mirror of
https://github.com/Alfresco/acs-community-packaging.git
synced 2026-09-16 18:13:21 +00:00
Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)
125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2)
125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,38 +1,38 @@
|
||||
package org.alfresco.web.action;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Contract supported by all classes that provide dynamic evaluation for a UI action.
|
||||
* <p>
|
||||
* Evaluators are supplied with a Node instance context object.
|
||||
* <p>
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the properties etc. of the Node context and return the result.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface ActionEvaluator extends Serializable
|
||||
{
|
||||
/**
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the properties etc. of the Node context and return the result.
|
||||
*
|
||||
* @param node Node context for the action
|
||||
*
|
||||
* @return result of whether the action can proceed.
|
||||
*/
|
||||
public boolean evaluate(Node node);
|
||||
|
||||
/**
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the state etc. of the given object and return the result.
|
||||
*
|
||||
* @param obj The object the action is for
|
||||
*
|
||||
* @return result of whether the action can proceed.
|
||||
*/
|
||||
public boolean evaluate(Object obj);
|
||||
}
|
||||
package org.alfresco.web.action;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Contract supported by all classes that provide dynamic evaluation for a UI action.
|
||||
* <p>
|
||||
* Evaluators are supplied with a Node instance context object.
|
||||
* <p>
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the properties etc. of the Node context and return the result.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface ActionEvaluator extends Serializable
|
||||
{
|
||||
/**
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the properties etc. of the Node context and return the result.
|
||||
*
|
||||
* @param node Node context for the action
|
||||
*
|
||||
* @return result of whether the action can proceed.
|
||||
*/
|
||||
public boolean evaluate(Node node);
|
||||
|
||||
/**
|
||||
* The evaluator should decide if the action precondition is valid based on the appropriate
|
||||
* logic and the state etc. of the given object and return the result.
|
||||
*
|
||||
* @param obj The object the action is for
|
||||
*
|
||||
* @return result of whether the action can proceed.
|
||||
*/
|
||||
public boolean evaluate(Object obj);
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - 'Approve' workflow step for document or space.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ApproveDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 2958297435415449179L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
Map<String,Object> properties = node.getProperties();
|
||||
|
||||
Boolean approveMove = (Boolean) properties.get("app:approveMove");
|
||||
boolean isMove = approveMove == null ? false : approveMove;
|
||||
|
||||
boolean canProceed = (properties.get("app:approveStep") != null) && !node.isLocked();
|
||||
//If this approval is going to result in a move of the node then we check whether the user
|
||||
//has permission. The delete permission is required in order to move a node (odd, perhaps, but true).
|
||||
canProceed &= (!isMove || node.hasPermission(PermissionService.DELETE));
|
||||
|
||||
return canProceed;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - 'Approve' workflow step for document or space.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ApproveDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 2958297435415449179L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
Map<String,Object> properties = node.getProperties();
|
||||
|
||||
Boolean approveMove = (Boolean) properties.get("app:approveMove");
|
||||
boolean isMove = approveMove == null ? false : approveMove;
|
||||
|
||||
boolean canProceed = (properties.get("app:approveStep") != null) && !node.isLocked();
|
||||
//If this approval is going to result in a move of the node then we check whether the user
|
||||
//has permission. The delete permission is required in order to move a node (odd, perhaps, but true).
|
||||
canProceed &= (!isMove || node.hasPermission(PermissionService.DELETE));
|
||||
|
||||
return canProceed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Cancel checkout document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CancelCheckoutDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -9015403093449070254L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null &&
|
||||
node.hasPermission(PermissionService.CANCEL_CHECK_OUT));
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Cancel checkout document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CancelCheckoutDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -9015403093449070254L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null &&
|
||||
node.hasPermission(PermissionService.CANCEL_CHECK_OUT));
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator for cancel workflow action. The action
|
||||
* is only allowed if the workflow the task belongs to was
|
||||
* started by the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class CancelWorkflowEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 7663087149225546333L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = false;
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
|
||||
// get the task from the node
|
||||
WorkflowTask task = (WorkflowTask)node.getProperties().get("workflowTask");
|
||||
if (task != null)
|
||||
{
|
||||
NodeRef initiator = task.path.instance.initiator;
|
||||
if (initiator != null)
|
||||
{
|
||||
// find the current username
|
||||
User user = Application.getCurrentUser(context);
|
||||
String currentUserName = user.getUserName();
|
||||
|
||||
// get the username of the initiator
|
||||
NodeService nodeSvc = Repository.getServiceRegistry(
|
||||
context).getNodeService();
|
||||
String userName = (String)nodeSvc.getProperty(initiator, ContentModel.PROP_USERNAME);
|
||||
|
||||
// if the current user started the workflow allow the cancel action
|
||||
if (currentUserName.equals(userName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator for cancel workflow action. The action
|
||||
* is only allowed if the workflow the task belongs to was
|
||||
* started by the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class CancelWorkflowEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 7663087149225546333L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = false;
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
|
||||
// get the task from the node
|
||||
WorkflowTask task = (WorkflowTask)node.getProperties().get("workflowTask");
|
||||
if (task != null)
|
||||
{
|
||||
NodeRef initiator = task.path.instance.initiator;
|
||||
if (initiator != null)
|
||||
{
|
||||
// find the current username
|
||||
User user = Application.getCurrentUser(context);
|
||||
String currentUserName = user.getUserName();
|
||||
|
||||
// get the username of the initiator
|
||||
NodeService nodeSvc = Repository.getServiceRegistry(
|
||||
context).getNodeService();
|
||||
String userName = (String)nodeSvc.getProperty(initiator, ContentModel.PROP_USERNAME);
|
||||
|
||||
// if the current user started the workflow allow the cancel action
|
||||
if (currentUserName.equals(userName))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkin document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CheckinDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5398249535631219663L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null &&
|
||||
node.hasPermission(PermissionService.CHECK_IN));
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkin document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CheckinDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5398249535631219663L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null &&
|
||||
node.hasPermission(PermissionService.CHECK_IN));
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkout document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CheckoutDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5510366635124591353L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getDictionaryService();
|
||||
|
||||
return dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
((node.hasPermission(PermissionService.CHECK_OUT) &&
|
||||
(node.isLocked() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false) &&
|
||||
node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION) == false));
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkout document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CheckoutDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5510366635124591353L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getDictionaryService();
|
||||
|
||||
return dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
((node.hasPermission(PermissionService.CHECK_OUT) &&
|
||||
(node.isLocked() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false) &&
|
||||
node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION) == false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Create a forum around a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CreateForumNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -5132048668011887505L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE) == false &&
|
||||
node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Create a forum around a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class CreateForumNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -5132048668011887505L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE) == false &&
|
||||
node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.ml.MultilingualUtils;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Delete document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DeleteDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5742287199692844685L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// the node to delete is a ml container, test if the user has enought right on each translation
|
||||
if(node.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
return MultilingualUtils.canDeleteEachTranslation(node, fc);
|
||||
}
|
||||
|
||||
boolean isPivot = false;
|
||||
|
||||
// special case for multilingual documents
|
||||
if (node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
MultilingualContentService mlservice =
|
||||
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
|
||||
|
||||
// if the translation is the last translation, user can delete it
|
||||
if (mlservice.getTranslations(node.getNodeRef()).size() == 1)
|
||||
{
|
||||
isPivot = false;
|
||||
}
|
||||
// Else if the node is the pivot language, user can't delete it
|
||||
else if (mlservice.getPivotTranslation(node.getNodeRef()).getId()
|
||||
.equalsIgnoreCase(node.getNodeRef().getId()))
|
||||
{
|
||||
isPivot = true;
|
||||
}
|
||||
// finally, the node is not the pivot translation, user can delete it
|
||||
}
|
||||
|
||||
return (node.isLocked() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false &&
|
||||
isPivot == false);
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.ml.MultilingualUtils;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Delete document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DeleteDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 5742287199692844685L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// the node to delete is a ml container, test if the user has enought right on each translation
|
||||
if(node.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
return MultilingualUtils.canDeleteEachTranslation(node, fc);
|
||||
}
|
||||
|
||||
boolean isPivot = false;
|
||||
|
||||
// special case for multilingual documents
|
||||
if (node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
MultilingualContentService mlservice =
|
||||
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
|
||||
|
||||
// if the translation is the last translation, user can delete it
|
||||
if (mlservice.getTranslations(node.getNodeRef()).size() == 1)
|
||||
{
|
||||
isPivot = false;
|
||||
}
|
||||
// Else if the node is the pivot language, user can't delete it
|
||||
else if (mlservice.getPivotTranslation(node.getNodeRef()).getId()
|
||||
.equalsIgnoreCase(node.getNodeRef().getId()))
|
||||
{
|
||||
isPivot = true;
|
||||
}
|
||||
// finally, the node is not the pivot translation, user can delete it
|
||||
}
|
||||
|
||||
return (node.isLocked() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false &&
|
||||
isPivot == false);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,47 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Discuss a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DiscussNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 8754174908349998903L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE))
|
||||
{
|
||||
NodeService nodeService = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getNodeService();
|
||||
List<ChildAssociationRef> children = nodeService.getChildAssocs(
|
||||
node.getNodeRef(), ForumModel.ASSOC_DISCUSSION,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
// make sure there is one visible child association for the node
|
||||
if (children.size() == 1)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Discuss a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DiscussNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 8754174908349998903L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE))
|
||||
{
|
||||
NodeService nodeService = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getNodeService();
|
||||
List<ChildAssociationRef> children = nodeService.getChildAssocs(
|
||||
node.getNodeRef(), ForumModel.ASSOC_DISCUSSION,
|
||||
RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
// make sure there is one visible child association for the node
|
||||
if (children.size() == 1)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Evaluates whether the copy action should be visible.
|
||||
*
|
||||
* If the node is a discussion don't allow the action.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DiscussionCopyEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -4080878553011296677L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = true;
|
||||
|
||||
// if the node in question is a forum...
|
||||
if (node.getType().equals(ForumModel.TYPE_FORUM))
|
||||
{
|
||||
// get the association type
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
|
||||
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(node.getNodeRef());
|
||||
QName assocType = parentAssoc.getTypeQName();
|
||||
|
||||
// only allow the action if the association type is not the discussion assoc
|
||||
result = (assocType.equals(ForumModel.ASSOC_DISCUSSION) == false);
|
||||
}
|
||||
|
||||
// impossible to copy a translation without content.
|
||||
if (result && node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!node.hasPermission(PermissionService.READ))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Evaluates whether the copy action should be visible.
|
||||
*
|
||||
* If the node is a discussion don't allow the action.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DiscussionCopyEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -4080878553011296677L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = true;
|
||||
|
||||
// if the node in question is a forum...
|
||||
if (node.getType().equals(ForumModel.TYPE_FORUM))
|
||||
{
|
||||
// get the association type
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
|
||||
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(node.getNodeRef());
|
||||
QName assocType = parentAssoc.getTypeQName();
|
||||
|
||||
// only allow the action if the association type is not the discussion assoc
|
||||
result = (assocType.equals(ForumModel.ASSOC_DISCUSSION) == false);
|
||||
}
|
||||
|
||||
// impossible to copy a translation without content.
|
||||
if (result && node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!node.hasPermission(PermissionService.READ))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Evaluates whether the cut action should be visible.
|
||||
*
|
||||
* If the node is a discussion don't allow the action.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DiscussionCutEvaluator extends CutNodeEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 7260556874788184200L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = super.evaluate(node);
|
||||
|
||||
// if the node in question is a forum...
|
||||
if (result && node.getType().equals(ForumModel.TYPE_FORUM))
|
||||
{
|
||||
// get the association type
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
|
||||
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(node.getNodeRef());
|
||||
QName assocType = parentAssoc.getTypeQName();
|
||||
|
||||
// only allow the action if the association type is not the discussion assoc
|
||||
result = (assocType.equals(ForumModel.ASSOC_DISCUSSION) == false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Evaluates whether the cut action should be visible.
|
||||
*
|
||||
* If the node is a discussion don't allow the action.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DiscussionCutEvaluator extends CutNodeEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 7260556874788184200L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean result = super.evaluate(node);
|
||||
|
||||
// if the node in question is a forum...
|
||||
if (result && node.getType().equals(ForumModel.TYPE_FORUM))
|
||||
{
|
||||
// get the association type
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
|
||||
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(node.getNodeRef());
|
||||
QName assocType = parentAssoc.getTypeQName();
|
||||
|
||||
// only allow the action if the association type is not the discussion assoc
|
||||
result = (assocType.equals(ForumModel.ASSOC_DISCUSSION) == false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via CIFS.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocCIFSEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -8988276140748731926L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// if the node is inline editable, the default http behaviour should always be used
|
||||
if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == false &&
|
||||
"cifs".equals(Application.getClientConfig(fc).getEditLinkType()))
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) != null &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING))||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via CIFS.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocCIFSEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -8988276140748731926L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// if the node is inline editable, the default http behaviour should always be used
|
||||
if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == false &&
|
||||
"cifs".equals(Application.getClientConfig(fc).getEditLinkType()))
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) != null &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING))||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via HTTP or inline edit.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocHttpEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -3694679925715830430L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// Since the reader returned of an empty translation is the reader of it's pivot translation, it makes
|
||||
// no sens to edit it on-line.
|
||||
if(node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
//result = false
|
||||
}
|
||||
// if the node is inline editable, the default http behaviour should
|
||||
// always be used otherwise the configured approach is used
|
||||
else if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == true &&
|
||||
node.getProperties().get(ApplicationModel.PROP_EDITINLINE) != null &&
|
||||
((Boolean)node.getProperties().get(ApplicationModel.PROP_EDITINLINE)).booleanValue() == true)
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) != null &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING)) ||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via HTTP or inline edit.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocHttpEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -3694679925715830430L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// Since the reader returned of an empty translation is the reader of it's pivot translation, it makes
|
||||
// no sens to edit it on-line.
|
||||
if(node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
//result = false
|
||||
}
|
||||
// if the node is inline editable, the default http behaviour should
|
||||
// always be used otherwise the configured approach is used
|
||||
else if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == true &&
|
||||
node.getProperties().get(ApplicationModel.PROP_EDITINLINE) != null &&
|
||||
((Boolean)node.getProperties().get(ApplicationModel.PROP_EDITINLINE)).booleanValue() == true)
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) != null &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING)) ||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via Webdav.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocWebDavEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 293342561997588700L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// if the node is inline editable, the default http behaviour should always be used
|
||||
if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == false &&
|
||||
"webdav".equals(Application.getClientConfig(fc).getEditLinkType()))
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING)) ||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.coci.EditOnlineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Edit document via Webdav.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditDocWebDavEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 293342561997588700L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// if the node is inline editable, the default http behaviour should always be used
|
||||
if (dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_INLINEEDITABLE) == false &&
|
||||
"webdav".equals(Application.getClientConfig(fc).getEditLinkType()))
|
||||
{
|
||||
if ((node.isWorkingCopyOwner() == true && node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE).equals(EditOnlineDialog.ONLINE_EDITING)) ||
|
||||
(node.hasAspect(ContentModel.ASPECT_WORKING_COPY) && node.hasPermission(PermissionService.WRITE)) ||
|
||||
(node.isLocked() == false && node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkin a document with potentially a Forum attached.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ForumsCheckinDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -924897450989526336L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean allow = false;
|
||||
|
||||
if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null)
|
||||
{
|
||||
if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE))
|
||||
{
|
||||
CheckOutCheckInService checkOutCheckInService =
|
||||
Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCheckOutCheckInService();
|
||||
// get the original locked node (via the copiedfrom aspect)
|
||||
NodeRef lockedNodeRef = checkOutCheckInService.getCheckedOut(node.getNodeRef());
|
||||
if (lockedNodeRef != null)
|
||||
{
|
||||
Node lockedNode = new Node(lockedNodeRef);
|
||||
allow = (node.hasPermission(PermissionService.CHECK_IN) &&
|
||||
lockedNode.hasPermission(PermissionService.CONTRIBUTOR));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no discussion so just check they have checkin permission for the node
|
||||
allow = node.hasPermission(PermissionService.CHECK_IN);
|
||||
}
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Checkin a document with potentially a Forum attached.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ForumsCheckinDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -924897450989526336L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
boolean allow = false;
|
||||
|
||||
if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY) &&
|
||||
node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE) == null)
|
||||
{
|
||||
if (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE))
|
||||
{
|
||||
CheckOutCheckInService checkOutCheckInService =
|
||||
Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCheckOutCheckInService();
|
||||
// get the original locked node (via the copiedfrom aspect)
|
||||
NodeRef lockedNodeRef = checkOutCheckInService.getCheckedOut(node.getNodeRef());
|
||||
if (lockedNodeRef != null)
|
||||
{
|
||||
Node lockedNode = new Node(lockedNodeRef);
|
||||
allow = (node.hasPermission(PermissionService.CHECK_IN) &&
|
||||
lockedNode.hasPermission(PermissionService.CONTRIBUTOR));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no discussion so just check they have checkin permission for the node
|
||||
allow = node.hasPermission(PermissionService.CHECK_IN);
|
||||
}
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - 'Reject' workflow step for document or space.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class RejectDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -7733947744617999298L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.getProperties().get("app:rejectStep") != null &&
|
||||
node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - 'Reject' workflow step for document or space.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class RejectDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -7733947744617999298L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.getProperties().get("app:rejectStep") != null &&
|
||||
node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Create a shortcut to a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ShortcutNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 8768692540125721144L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
NavigationBean nav =
|
||||
(NavigationBean)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), NavigationBean.BEAN_NAME);
|
||||
return (nav.getIsGuest() == false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Create a shortcut to a node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ShortcutNodeEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 8768692540125721144L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
NavigationBean nav =
|
||||
(NavigationBean)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), NavigationBean.BEAN_NAME);
|
||||
return (nav.getIsGuest() == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Start workflow on a node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class StartWorkflowEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final String BPM_ENGINE_BEAN_NAME = "bpm_engineRegistry";
|
||||
private static final long serialVersionUID = 3110333488835027710L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
NavigationBean nav =
|
||||
(NavigationBean)FacesHelper.getManagedBean(facesContext, NavigationBean.BEAN_NAME);
|
||||
|
||||
// determine whether the workflow services are active
|
||||
boolean workflowPresent = false;
|
||||
WebApplicationContext springContext = FacesContextUtils.getRequiredWebApplicationContext(facesContext);
|
||||
BPMEngineRegistry bpmReg = (BPMEngineRegistry)springContext.getBean(BPM_ENGINE_BEAN_NAME);
|
||||
if (bpmReg != null)
|
||||
{
|
||||
String[] components = bpmReg.getWorkflowComponents();
|
||||
workflowPresent = (components != null && components.length > 0);
|
||||
}
|
||||
|
||||
return (workflowPresent && nav.getIsGuest() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION) == false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Start workflow on a node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class StartWorkflowEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final String BPM_ENGINE_BEAN_NAME = "bpm_engineRegistry";
|
||||
private static final long serialVersionUID = 3110333488835027710L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
NavigationBean nav =
|
||||
(NavigationBean)FacesHelper.getManagedBean(facesContext, NavigationBean.BEAN_NAME);
|
||||
|
||||
// determine whether the workflow services are active
|
||||
boolean workflowPresent = false;
|
||||
WebApplicationContext springContext = FacesContextUtils.getRequiredWebApplicationContext(facesContext);
|
||||
BPMEngineRegistry bpmReg = (BPMEngineRegistry)springContext.getBean(BPM_ENGINE_BEAN_NAME);
|
||||
if (bpmReg != null)
|
||||
{
|
||||
String[] components = bpmReg.getWorkflowComponents();
|
||||
workflowPresent = (components != null && components.length > 0);
|
||||
}
|
||||
|
||||
return (workflowPresent && nav.getIsGuest() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION) == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Take ownership of a document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TakeOwnershipDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 3966463533922521230L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Take ownership of a document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TakeOwnershipDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 3966463533922521230L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Unlock a locked document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UnlockDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -7056759932698306087L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
if (node.isLocked())
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
CheckOutCheckInService checkOutCheckInService = (CheckOutCheckInService) FacesHelper.getManagedBean(fc, "CheckoutCheckinService");
|
||||
if (checkOutCheckInService.getWorkingCopy(node.getNodeRef()) == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Unlock a locked document.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UnlockDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -7056759932698306087L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
if (node.isLocked())
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
CheckOutCheckInService checkOutCheckInService = (CheckOutCheckInService) FacesHelper.getManagedBean(fc, "CheckoutCheckinService");
|
||||
if (checkOutCheckInService.getWorkingCopy(node.getNodeRef()) == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Proceed if the document is not locked.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UnlockedDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -3216759932698306123L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.isLocked() == false);
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Proceed if the document is not locked.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UnlockedDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = -3216759932698306123L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
return (node.isLocked() == false);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.web.bean.coci.EditOfflineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Update document content.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UpdateDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 6030963610213633893L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getDictionaryService();
|
||||
|
||||
boolean isOfflineEditing =
|
||||
(EditOfflineDialog.OFFLINE_EDITING.equals(node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE)));
|
||||
|
||||
return dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
((node.isWorkingCopyOwner() && !isOfflineEditing) ||
|
||||
(!node.isLocked() && !node.hasAspect(ContentModel.ASPECT_WORKING_COPY)));
|
||||
}
|
||||
package org.alfresco.web.action.evaluator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.web.bean.coci.EditOfflineDialog;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Update document content.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UpdateDocEvaluator extends BaseActionEvaluator
|
||||
{
|
||||
private static final long serialVersionUID = 6030963610213633893L;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
|
||||
*/
|
||||
public boolean evaluate(Node node)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(
|
||||
FacesContext.getCurrentInstance()).getDictionaryService();
|
||||
|
||||
boolean isOfflineEditing =
|
||||
(EditOfflineDialog.OFFLINE_EDITING.equals(node.getProperties().get(ContentModel.PROP_WORKING_COPY_MODE)));
|
||||
|
||||
return dd.isSubClass(node.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
((node.isWorkingCopyOwner() && !isOfflineEditing) ||
|
||||
(!node.isLocked() && !node.hasAspect(ContentModel.ASPECT_WORKING_COPY)));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,152 +1,152 @@
|
||||
package org.alfresco.web.app;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.jsf.DelegatingVariableResolver;
|
||||
|
||||
/**
|
||||
* JSF VariableResolver that first delegates to the Spring JSF variable
|
||||
* resolver. The sole purpose of this variable resolver is to look out
|
||||
* for the <code>Container</code> variable. If this variable is encountered
|
||||
* the current viewId is examined. If the current viewId matches a
|
||||
* configured dialog or wizard container the appropriate manager object is
|
||||
* returned i.e. DialogManager or WizardManager.
|
||||
*
|
||||
* <p>Configure this resolver in your <code>faces-config.xml</code> file as follows:
|
||||
*
|
||||
* <pre>
|
||||
* <application>
|
||||
* ...
|
||||
* <variable-resolver>org.alfresco.web.app.AlfrescoVariableResolver</variable-resolver>
|
||||
* </application></pre>
|
||||
*
|
||||
* @see org.alfresco.web.bean.dialog.DialogManager
|
||||
* @see org.alfresco.web.bean.wizard.WizardManager
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AlfrescoVariableResolver extends DelegatingVariableResolver
|
||||
{
|
||||
protected List<String> dialogContainers = null;
|
||||
protected List<String> wizardContainers = null;
|
||||
|
||||
private static final String CONTAINER = "Container";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AlfrescoVariableResolver.class);
|
||||
|
||||
/**
|
||||
* Creates a new VariableResolver.
|
||||
*
|
||||
* @param originalVariableResolver The original variable resolver
|
||||
*/
|
||||
public AlfrescoVariableResolver(VariableResolver originalVariableResolver)
|
||||
{
|
||||
super(originalVariableResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the variable with the given name.
|
||||
* <p>
|
||||
* This implementation will first delegate to the Spring variable resolver.
|
||||
* If the variable is not found by the Spring resolver and the variable name
|
||||
* is <code>Container</code> the current viewId is examined.
|
||||
* If the current viewId matches a configured dialog or wizard container
|
||||
* the appropriate manager object is returned i.e. DialogManager or WizardManager.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param name The name of the variable to resolve
|
||||
*/
|
||||
public Object resolveVariable(FacesContext context, String name)
|
||||
throws EvaluationException
|
||||
{
|
||||
Object variable = super.resolveVariable(context, name);
|
||||
|
||||
if (variable == null)
|
||||
{
|
||||
// if the variable was not resolved see if the name is "Container"
|
||||
if (name.equals(CONTAINER))
|
||||
{
|
||||
// get the current view id and the configured dialog and wizard
|
||||
// container pages
|
||||
String viewId = context.getViewRoot().getViewId();
|
||||
List<String> dialogContainers = getDialogContainers(context);
|
||||
List<String> wizardContainers = getWizardContainers(context);
|
||||
|
||||
// see if we are currently in a wizard or a dialog
|
||||
if (dialogContainers.contains(viewId))
|
||||
{
|
||||
variable = Application.getDialogManager();
|
||||
}
|
||||
else if (wizardContainers.contains(viewId))
|
||||
{
|
||||
variable = Application.getWizardManager();
|
||||
}
|
||||
|
||||
if (variable != null && logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Resolved 'Container' variable to: " + variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of configured dialog container pages
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @return The container pages
|
||||
*/
|
||||
protected List<String> getDialogContainers(FacesContext context)
|
||||
{
|
||||
if ((this.dialogContainers == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.dialogContainers = new ArrayList<String>(2);
|
||||
|
||||
ConfigService configSvc = Application.getConfigService(context);
|
||||
Config globalConfig = configSvc.getGlobalConfig();
|
||||
|
||||
if (globalConfig != null)
|
||||
{
|
||||
this.dialogContainers.add(globalConfig.getConfigElement("dialog-container").getValue());
|
||||
this.dialogContainers.add(globalConfig.getConfigElement("plain-dialog-container").getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return this.dialogContainers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of configured wizard container pages
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @return The container page
|
||||
*/
|
||||
protected List<String> getWizardContainers(FacesContext context)
|
||||
{
|
||||
if ((this.wizardContainers == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.wizardContainers = new ArrayList<String>(2);
|
||||
|
||||
ConfigService configSvc = Application.getConfigService(context);
|
||||
Config globalConfig = configSvc.getGlobalConfig();
|
||||
|
||||
if (globalConfig != null)
|
||||
{
|
||||
this.wizardContainers.add(globalConfig.getConfigElement("wizard-container").getValue());
|
||||
this.wizardContainers.add(globalConfig.getConfigElement("plain-wizard-container").getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return this.wizardContainers;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.jsf.DelegatingVariableResolver;
|
||||
|
||||
/**
|
||||
* JSF VariableResolver that first delegates to the Spring JSF variable
|
||||
* resolver. The sole purpose of this variable resolver is to look out
|
||||
* for the <code>Container</code> variable. If this variable is encountered
|
||||
* the current viewId is examined. If the current viewId matches a
|
||||
* configured dialog or wizard container the appropriate manager object is
|
||||
* returned i.e. DialogManager or WizardManager.
|
||||
*
|
||||
* <p>Configure this resolver in your <code>faces-config.xml</code> file as follows:
|
||||
*
|
||||
* <pre>
|
||||
* <application>
|
||||
* ...
|
||||
* <variable-resolver>org.alfresco.web.app.AlfrescoVariableResolver</variable-resolver>
|
||||
* </application></pre>
|
||||
*
|
||||
* @see org.alfresco.web.bean.dialog.DialogManager
|
||||
* @see org.alfresco.web.bean.wizard.WizardManager
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AlfrescoVariableResolver extends DelegatingVariableResolver
|
||||
{
|
||||
protected List<String> dialogContainers = null;
|
||||
protected List<String> wizardContainers = null;
|
||||
|
||||
private static final String CONTAINER = "Container";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AlfrescoVariableResolver.class);
|
||||
|
||||
/**
|
||||
* Creates a new VariableResolver.
|
||||
*
|
||||
* @param originalVariableResolver The original variable resolver
|
||||
*/
|
||||
public AlfrescoVariableResolver(VariableResolver originalVariableResolver)
|
||||
{
|
||||
super(originalVariableResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the variable with the given name.
|
||||
* <p>
|
||||
* This implementation will first delegate to the Spring variable resolver.
|
||||
* If the variable is not found by the Spring resolver and the variable name
|
||||
* is <code>Container</code> the current viewId is examined.
|
||||
* If the current viewId matches a configured dialog or wizard container
|
||||
* the appropriate manager object is returned i.e. DialogManager or WizardManager.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param name The name of the variable to resolve
|
||||
*/
|
||||
public Object resolveVariable(FacesContext context, String name)
|
||||
throws EvaluationException
|
||||
{
|
||||
Object variable = super.resolveVariable(context, name);
|
||||
|
||||
if (variable == null)
|
||||
{
|
||||
// if the variable was not resolved see if the name is "Container"
|
||||
if (name.equals(CONTAINER))
|
||||
{
|
||||
// get the current view id and the configured dialog and wizard
|
||||
// container pages
|
||||
String viewId = context.getViewRoot().getViewId();
|
||||
List<String> dialogContainers = getDialogContainers(context);
|
||||
List<String> wizardContainers = getWizardContainers(context);
|
||||
|
||||
// see if we are currently in a wizard or a dialog
|
||||
if (dialogContainers.contains(viewId))
|
||||
{
|
||||
variable = Application.getDialogManager();
|
||||
}
|
||||
else if (wizardContainers.contains(viewId))
|
||||
{
|
||||
variable = Application.getWizardManager();
|
||||
}
|
||||
|
||||
if (variable != null && logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Resolved 'Container' variable to: " + variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of configured dialog container pages
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @return The container pages
|
||||
*/
|
||||
protected List<String> getDialogContainers(FacesContext context)
|
||||
{
|
||||
if ((this.dialogContainers == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.dialogContainers = new ArrayList<String>(2);
|
||||
|
||||
ConfigService configSvc = Application.getConfigService(context);
|
||||
Config globalConfig = configSvc.getGlobalConfig();
|
||||
|
||||
if (globalConfig != null)
|
||||
{
|
||||
this.dialogContainers.add(globalConfig.getConfigElement("dialog-container").getValue());
|
||||
this.dialogContainers.add(globalConfig.getConfigElement("plain-dialog-container").getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return this.dialogContainers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of configured wizard container pages
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @return The container page
|
||||
*/
|
||||
protected List<String> getWizardContainers(FacesContext context)
|
||||
{
|
||||
if ((this.wizardContainers == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.wizardContainers = new ArrayList<String>(2);
|
||||
|
||||
ConfigService configSvc = Application.getConfigService(context);
|
||||
Config globalConfig = configSvc.getGlobalConfig();
|
||||
|
||||
if (globalConfig != null)
|
||||
{
|
||||
this.wizardContainers.add(globalConfig.getConfigElement("wizard-container").getValue());
|
||||
this.wizardContainers.add(globalConfig.getConfigElement("plain-wizard-container").getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return this.wizardContainers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
package org.alfresco.web.app;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Debug phase listener that simply logs when each phase is entered and exited.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DebugPhaseListener implements PhaseListener
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(DebugPhaseListener.class);
|
||||
|
||||
public int indent = 0;
|
||||
public static final String INDENT = " ";
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
|
||||
*/
|
||||
public void afterPhase(PhaseEvent event)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
|
||||
{
|
||||
printComponentTree(FacesContext.getCurrentInstance().getViewRoot());
|
||||
}
|
||||
|
||||
logger.debug("********** Exiting phase: " + event.getPhaseId().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
|
||||
*/
|
||||
public void beforePhase(PhaseEvent event)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("********** Entering phase: " + event.getPhaseId().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#getPhaseId()
|
||||
*/
|
||||
public PhaseId getPhaseId()
|
||||
{
|
||||
return PhaseId.ANY_PHASE;
|
||||
}
|
||||
|
||||
public void printComponentTree(UIComponent comp)
|
||||
{
|
||||
printComponentInfo(comp);
|
||||
|
||||
List complist = comp.getChildren();
|
||||
if (complist.size()>0)
|
||||
indent++;
|
||||
for (int i = 0; i < complist.size(); i++)
|
||||
{
|
||||
UIComponent uicom = (UIComponent) complist.get(i);
|
||||
printComponentTree(uicom);
|
||||
if (i+1 == complist.size())
|
||||
indent--;
|
||||
}
|
||||
}
|
||||
|
||||
public void printComponentInfo(UIComponent comp)
|
||||
{
|
||||
if (comp.getId() == null)
|
||||
{
|
||||
logger.debug("UIViewRoot" + " " + "(" + comp.getClass().getName() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug(getIndent() + "|");
|
||||
logger.debug(getIndent() + comp.getId() + " " + "(" + comp.getClass().getName() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public String getIndent()
|
||||
{
|
||||
String indent = "";
|
||||
for (int i=0; i<this.indent; i++)
|
||||
{
|
||||
indent += INDENT;
|
||||
}
|
||||
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Debug phase listener that simply logs when each phase is entered and exited.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DebugPhaseListener implements PhaseListener
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(DebugPhaseListener.class);
|
||||
|
||||
public int indent = 0;
|
||||
public static final String INDENT = " ";
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
|
||||
*/
|
||||
public void afterPhase(PhaseEvent event)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
|
||||
{
|
||||
printComponentTree(FacesContext.getCurrentInstance().getViewRoot());
|
||||
}
|
||||
|
||||
logger.debug("********** Exiting phase: " + event.getPhaseId().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
|
||||
*/
|
||||
public void beforePhase(PhaseEvent event)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("********** Entering phase: " + event.getPhaseId().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.event.PhaseListener#getPhaseId()
|
||||
*/
|
||||
public PhaseId getPhaseId()
|
||||
{
|
||||
return PhaseId.ANY_PHASE;
|
||||
}
|
||||
|
||||
public void printComponentTree(UIComponent comp)
|
||||
{
|
||||
printComponentInfo(comp);
|
||||
|
||||
List complist = comp.getChildren();
|
||||
if (complist.size()>0)
|
||||
indent++;
|
||||
for (int i = 0; i < complist.size(); i++)
|
||||
{
|
||||
UIComponent uicom = (UIComponent) complist.get(i);
|
||||
printComponentTree(uicom);
|
||||
if (i+1 == complist.size())
|
||||
indent--;
|
||||
}
|
||||
}
|
||||
|
||||
public void printComponentInfo(UIComponent comp)
|
||||
{
|
||||
if (comp.getId() == null)
|
||||
{
|
||||
logger.debug("UIViewRoot" + " " + "(" + comp.getClass().getName() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug(getIndent() + "|");
|
||||
logger.debug(getIndent() + comp.getId() + " " + "(" + comp.getClass().getName() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public String getIndent()
|
||||
{
|
||||
String indent = "";
|
||||
for (int i=0; i<this.indent; i++)
|
||||
{
|
||||
indent += INDENT;
|
||||
}
|
||||
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
package org.alfresco.web.app.portlet;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.web.app.servlet.AuthenticationHelper;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.apache.myfaces.portlet.DefaultViewSelector;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class AlfrescoDefaultViewSelector implements DefaultViewSelector
|
||||
{
|
||||
/**
|
||||
* Select the appropriate view ID
|
||||
*/
|
||||
public String selectViewId(RenderRequest request, RenderResponse response) throws PortletException
|
||||
{
|
||||
User user = (User) request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER,
|
||||
PortletSession.APPLICATION_SCOPE);
|
||||
if (user != null && user.getUserName().equals(AuthenticationUtil.getGuestUserName()))
|
||||
{
|
||||
return FacesHelper.BROWSE_VIEW_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.myfaces.portlet.DefaultViewSelector#setPortletContext(javax.portlet.PortletContext)
|
||||
*/
|
||||
public void setPortletContext(PortletContext portletContext)
|
||||
{
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.portlet;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.web.app.servlet.AuthenticationHelper;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.apache.myfaces.portlet.DefaultViewSelector;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class AlfrescoDefaultViewSelector implements DefaultViewSelector
|
||||
{
|
||||
/**
|
||||
* Select the appropriate view ID
|
||||
*/
|
||||
public String selectViewId(RenderRequest request, RenderResponse response) throws PortletException
|
||||
{
|
||||
User user = (User) request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER,
|
||||
PortletSession.APPLICATION_SCOPE);
|
||||
if (user != null && user.getUserName().equals(AuthenticationUtil.getGuestUserName()))
|
||||
{
|
||||
return FacesHelper.BROWSE_VIEW_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.myfaces.portlet.DefaultViewSelector#setPortletContext(javax.portlet.PortletContext)
|
||||
*/
|
||||
public void setPortletContext(PortletContext portletContext)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +1,97 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* This servlet filter is used to restrict direct URL access to administration
|
||||
* resource in the web client, for example the admin and jBPM consoles.
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class AdminAuthenticationFilter implements Filter
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(AdminAuthenticationFilter.class);
|
||||
|
||||
private FilterConfig config;
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest httpRequest = (HttpServletRequest)req;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse)res;
|
||||
|
||||
// The fact that this filter is being called means a request for a protected
|
||||
// resource has taken place, check that the current user is in fact an
|
||||
// administrator.
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Authorising request for protected resource: " + httpRequest.getRequestURI());
|
||||
|
||||
// there should be a user at this point so retrieve it
|
||||
User user = AuthenticationHelper.getUser(this.config.getServletContext(), httpRequest, httpResponse);
|
||||
|
||||
// if the user is present check to see whether it is an admin user
|
||||
boolean isAdmin = (user != null && user.isAdmin());
|
||||
|
||||
if (isAdmin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Current user has admin authority, allowing access.");
|
||||
|
||||
// continue filter chaining if current user is admin user
|
||||
chain.doFilter(req, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return the 401 Forbidden error as the current user is not an administrator
|
||||
// if the response has already been committed there's nothing we can do but
|
||||
// print out a warning
|
||||
if (httpResponse.isCommitted() == false)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Current user does not have admin authority, returning 401 Forbidden error...");
|
||||
|
||||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Access denied to '" + httpRequest.getRequestURI() +
|
||||
"'. The response has already been committed so a 401 Forbidden error could not be sent!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
|
||||
*/
|
||||
public void init(FilterConfig config) throws ServletException
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#destroy()
|
||||
*/
|
||||
public void destroy()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* This servlet filter is used to restrict direct URL access to administration
|
||||
* resource in the web client, for example the admin and jBPM consoles.
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class AdminAuthenticationFilter implements Filter
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(AdminAuthenticationFilter.class);
|
||||
|
||||
private FilterConfig config;
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest httpRequest = (HttpServletRequest)req;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse)res;
|
||||
|
||||
// The fact that this filter is being called means a request for a protected
|
||||
// resource has taken place, check that the current user is in fact an
|
||||
// administrator.
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Authorising request for protected resource: " + httpRequest.getRequestURI());
|
||||
|
||||
// there should be a user at this point so retrieve it
|
||||
User user = AuthenticationHelper.getUser(this.config.getServletContext(), httpRequest, httpResponse);
|
||||
|
||||
// if the user is present check to see whether it is an admin user
|
||||
boolean isAdmin = (user != null && user.isAdmin());
|
||||
|
||||
if (isAdmin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Current user has admin authority, allowing access.");
|
||||
|
||||
// continue filter chaining if current user is admin user
|
||||
chain.doFilter(req, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return the 401 Forbidden error as the current user is not an administrator
|
||||
// if the response has already been committed there's nothing we can do but
|
||||
// print out a warning
|
||||
if (httpResponse.isCommitted() == false)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Current user does not have admin authority, returning 401 Forbidden error...");
|
||||
|
||||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Access denied to '" + httpRequest.getRequestURI() +
|
||||
"'. The response has already been committed so a 401 Forbidden error could not be sent!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
|
||||
*/
|
||||
public void init(FilterConfig config) throws ServletException
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#destroy()
|
||||
*/
|
||||
public void destroy()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.alfresco.web.scripts.servlet.X509ServletFilterBase;
|
||||
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* The AlfrescoX509ServletFilter implements the checkEnforce method of the X509ServletFilterBase.
|
||||
* This allows the configuration of X509 authentication to be toggled on/off through a
|
||||
* configuration outside of the web.xml.
|
||||
**/
|
||||
|
||||
public class AlfrescoX509ServletFilter extends X509ServletFilterBase
|
||||
{
|
||||
private static final String BEAN_GLOBAL_PROPERTIES = "global-properties";
|
||||
private static final String SECURE_COMMS = "solr.secureComms";
|
||||
|
||||
private static Log logger = LogFactory.getLog(AlfrescoX509ServletFilter.class);
|
||||
|
||||
@Override
|
||||
protected boolean checkEnforce(ServletContext servletContext) throws IOException
|
||||
{
|
||||
/*
|
||||
* Get the secureComms setting from the global properties bean.
|
||||
*/
|
||||
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
|
||||
Properties globalProperties = (Properties) wc.getBean(BEAN_GLOBAL_PROPERTIES);
|
||||
String prop = globalProperties.getProperty(SECURE_COMMS);
|
||||
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("secureComms:"+prop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true or false based on the property. This will switch on/off X509 enforcement in the X509ServletFilterBase.
|
||||
*/
|
||||
|
||||
if (prop == null || "none".equals(prop))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.alfresco.web.scripts.servlet.X509ServletFilterBase;
|
||||
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* The AlfrescoX509ServletFilter implements the checkEnforce method of the X509ServletFilterBase.
|
||||
* This allows the configuration of X509 authentication to be toggled on/off through a
|
||||
* configuration outside of the web.xml.
|
||||
**/
|
||||
|
||||
public class AlfrescoX509ServletFilter extends X509ServletFilterBase
|
||||
{
|
||||
private static final String BEAN_GLOBAL_PROPERTIES = "global-properties";
|
||||
private static final String SECURE_COMMS = "solr.secureComms";
|
||||
|
||||
private static Log logger = LogFactory.getLog(AlfrescoX509ServletFilter.class);
|
||||
|
||||
@Override
|
||||
protected boolean checkEnforce(ServletContext servletContext) throws IOException
|
||||
{
|
||||
/*
|
||||
* Get the secureComms setting from the global properties bean.
|
||||
*/
|
||||
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
|
||||
Properties globalProperties = (Properties) wc.getBean(BEAN_GLOBAL_PROPERTIES);
|
||||
String prop = globalProperties.getProperty(SECURE_COMMS);
|
||||
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("secureComms:"+prop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true or false based on the property. This will switch on/off X509 enforcement in the X509ServletFilterBase.
|
||||
*/
|
||||
|
||||
if (prop == null || "none".equals(prop))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public enum AuthenticationStatus
|
||||
{
|
||||
Success, Failure, Guest;
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public enum AuthenticationStatus
|
||||
{
|
||||
Success, Failure, Guest;
|
||||
}
|
||||
|
||||
@@ -1,430 +1,430 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.repo.web.util.HttpRangeProcessor;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.surf.util.URLEncoder;
|
||||
import org.springframework.extensions.webscripts.ui.common.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for the download content servlets. Provides common
|
||||
* processing for the request.
|
||||
*
|
||||
* @see org.alfresco.web.app.servlet.DownloadContentServlet
|
||||
* @see org.alfresco.web.app.servlet.GuestDownloadContentServlet
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class BaseDownloadContentServlet extends BaseServlet
|
||||
{
|
||||
private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
|
||||
private static final long serialVersionUID = -4558907921887235967L;
|
||||
|
||||
private static final String POWER_POINT_DOCUMENT_MIMETYPE = "application/vnd.ms-powerpoint";
|
||||
private static final String POWER_POINT_2007_DOCUMENT_MIMETYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||||
|
||||
private static final String HEADER_CONTENT_RANGE = "Content-Range";
|
||||
private static final String HEADER_CONTENT_LENGTH = "Content-Length";
|
||||
private static final String HEADER_ACCEPT_RANGES = "Accept-Ranges";
|
||||
private static final String HEADER_RANGE = "Range";
|
||||
private static final String HEADER_ETAG = "ETag";
|
||||
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
|
||||
private static final String HEADER_LAST_MODIFIED = "Last-Modified";
|
||||
private static final String HEADER_USER_AGENT = "User-Agent";
|
||||
private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||
|
||||
protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
protected static final String MSG_ERROR_CONTENT_MISSING = "error_content_missing";
|
||||
protected static final String MSG_ERROR_NOT_FOUND = "error_not_found";
|
||||
|
||||
protected static final String URL_DIRECT = "d";
|
||||
protected static final String URL_DIRECT_LONG = "direct";
|
||||
protected static final String URL_ATTACH = "a";
|
||||
protected static final String URL_ATTACH_LONG = "attach";
|
||||
protected static final String ARG_PROPERTY = "property";
|
||||
protected static final String ARG_PATH = "path";
|
||||
|
||||
/**
|
||||
* Gets the logger to use for this request.
|
||||
* <p>
|
||||
* This will show all debug entries from this class as though they
|
||||
* came from the subclass.
|
||||
*
|
||||
* @return The logger
|
||||
*/
|
||||
protected abstract Log getLogger();
|
||||
|
||||
/**
|
||||
* Processes the download request using the current context i.e. no authentication checks are made, it is presumed
|
||||
* they have already been done.
|
||||
*
|
||||
* @param req
|
||||
* The HTTP request
|
||||
* @param res
|
||||
* The HTTP response
|
||||
* @param allowLogIn
|
||||
* Indicates whether guest users without access to the content should be redirected to the log in page. If
|
||||
* <code>false</code>, a status 403 forbidden page is displayed instead.
|
||||
*/
|
||||
protected void processDownloadRequest(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean allowLogIn, boolean transmitContent)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
Log logger = getLogger();
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// attachment mode (either 'attach' or 'direct')
|
||||
String attachToken = t.nextToken();
|
||||
boolean attachment = URL_ATTACH.equals(attachToken) || URL_ATTACH_LONG.equals(attachToken);
|
||||
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
|
||||
// get or calculate the noderef and filename to download as
|
||||
NodeRef nodeRef;
|
||||
String filename;
|
||||
|
||||
// do we have a path parameter instead of a NodeRef?
|
||||
String path = req.getParameter(ARG_PATH);
|
||||
if (path != null && path.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef and the Filename element
|
||||
try
|
||||
{
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), path);
|
||||
nodeRef = pathInfo.NodeRef;
|
||||
filename = pathInfo.Filename;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// a NodeRef must have been specified if no path has been found
|
||||
if (tokenCount < 6)
|
||||
{
|
||||
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
// assume 'workspace' or other NodeRef based protocol for remaining URL elements
|
||||
StoreRef storeRef = new StoreRef(URLDecoder.decode(t.nextToken()), URLDecoder.decode(t.nextToken()));
|
||||
String id = URLDecoder.decode(t.nextToken());
|
||||
|
||||
// build noderef from the appropriate URL elements
|
||||
nodeRef = new NodeRef(storeRef, id);
|
||||
|
||||
if (tokenCount > 6)
|
||||
{
|
||||
// found additional relative path elements i.e. noderefid/images/file.txt
|
||||
// this allows a url to reference siblings nodes via a cm:name based relative path
|
||||
// solves the issue with opening HTML content containing relative URLs in HREF or IMG tags etc.
|
||||
List<String> paths = new ArrayList<String>(tokenCount - 5);
|
||||
while (t.hasMoreTokens())
|
||||
{
|
||||
paths.add(URLDecoder.decode(t.nextToken()));
|
||||
}
|
||||
filename = paths.get(paths.size() - 1);
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef parentRef = serviceRegistry.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
||||
FileInfo fileInfo = serviceRegistry.getFileFolderService().resolveNamePath(parentRef, paths);
|
||||
nodeRef = fileInfo.getNodeRef();
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// filename is last remaining token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
// get qualified of the property to get content from - default to ContentModel.PROP_CONTENT
|
||||
QName propertyQName = ContentModel.PROP_CONTENT;
|
||||
String property = req.getParameter(ARG_PROPERTY);
|
||||
if (property != null && property.length() != 0)
|
||||
{
|
||||
propertyQName = QName.createQName(property);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Found NodeRef: " + nodeRef);
|
||||
logger.debug("Will use filename: " + filename);
|
||||
logger.debug("For property: " + propertyQName);
|
||||
logger.debug("With attachment mode: " + attachment);
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
ContentService contentService = serviceRegistry.getContentService();
|
||||
|
||||
// Check that the node still exists
|
||||
if (!nodeService.exists(nodeRef))
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// check that the user has at least READ_CONTENT access - else redirect to an error or login page
|
||||
if (!checkAccess(req, res, nodeRef, PermissionService.READ_CONTENT, allowLogIn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check If-Modified-Since header and set Last-Modified header as appropriate
|
||||
Date modified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
|
||||
if (modified != null)
|
||||
{
|
||||
long modifiedSince = req.getDateHeader(HEADER_IF_MODIFIED_SINCE);
|
||||
if (modifiedSince > 0L)
|
||||
{
|
||||
// round the date to the ignore millisecond value which is not supplied by header
|
||||
long modDate = (modified.getTime() / 1000L) * 1000L;
|
||||
if (modDate <= modifiedSince)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 304 Not Modified.");
|
||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.setDateHeader(HEADER_LAST_MODIFIED, modified.getTime());
|
||||
res.setHeader(HEADER_CACHE_CONTROL, "must-revalidate, max-age=0");
|
||||
res.setHeader(HEADER_ETAG, "\"" + Long.toString(modified.getTime()) + "\"");
|
||||
}
|
||||
|
||||
if (attachment == true)
|
||||
{
|
||||
setHeaderContentDisposition(req, res, filename);
|
||||
}
|
||||
|
||||
// get the content reader
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
// ensure that it is safe to use
|
||||
reader = FileContentReader.getSafeContentReader(
|
||||
reader,
|
||||
Application.getMessage(req.getSession(), MSG_ERROR_CONTENT_MISSING),
|
||||
nodeRef, reader);
|
||||
|
||||
String mimetype = reader.getMimetype();
|
||||
// fall back if unable to resolve mimetype property
|
||||
if (mimetype == null || mimetype.length() == 0)
|
||||
{
|
||||
MimetypeService mimetypeMap = serviceRegistry.getMimetypeService();
|
||||
mimetype = MIMETYPE_OCTET_STREAM;
|
||||
int extIndex = filename.lastIndexOf('.');
|
||||
if (extIndex != -1)
|
||||
{
|
||||
String ext = filename.substring(extIndex + 1);
|
||||
mimetype = mimetypeMap.getMimetype(ext);
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly set the content disposition header if the content is powerpoint
|
||||
if (!attachment && (mimetype.equals(POWER_POINT_2007_DOCUMENT_MIMETYPE) ||
|
||||
mimetype.equals(POWER_POINT_DOCUMENT_MIMETYPE)))
|
||||
{
|
||||
setHeaderContentDisposition(req, res, filename);
|
||||
}
|
||||
|
||||
// get the content and stream directly to the response output stream
|
||||
// assuming the repo is capable of streaming in chunks, this should allow large files
|
||||
// to be streamed directly to the browser response stream.
|
||||
res.setHeader(HEADER_ACCEPT_RANGES, "bytes");
|
||||
|
||||
// for a GET request, transmit the content else just the headers are sent
|
||||
if (transmitContent)
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean processedRange = false;
|
||||
String range = req.getHeader(HEADER_CONTENT_RANGE);
|
||||
if (range == null)
|
||||
{
|
||||
range = req.getHeader(HEADER_RANGE);
|
||||
}
|
||||
if (range != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found content range header: " + range);
|
||||
|
||||
// ensure the range header is starts with "bytes=" and process the range(s)
|
||||
if (range.length() > 6)
|
||||
{
|
||||
HttpRangeProcessor rangeProcessor = new HttpRangeProcessor(contentService);
|
||||
processedRange = rangeProcessor.processRange(
|
||||
res, reader, range.substring(6), nodeRef, propertyQName,
|
||||
mimetype, req.getHeader(HEADER_USER_AGENT));
|
||||
}
|
||||
}
|
||||
if (processedRange == false)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Sending complete file content...");
|
||||
|
||||
// set mimetype for the content and the character encoding for the stream
|
||||
res.setContentType(mimetype);
|
||||
res.setCharacterEncoding(reader.getEncoding());
|
||||
|
||||
// MNT-10642 Alfresco Explorer has javascript vulnerability opening HTML files
|
||||
if (req.getRequestURI().contains("/d/d/") && (mimetype.equals("text/html") || mimetype.equals("application/xhtml+xml") || mimetype.equals("text/xml")))
|
||||
{
|
||||
String content = reader.getContentString();
|
||||
|
||||
if (mimetype.equals("text/html") || mimetype.equals("application/xhtml+xml"))
|
||||
{
|
||||
// process with HTML stripper
|
||||
content = StringUtils.stripUnsafeHTMLTags(content, false);
|
||||
}
|
||||
else if (mimetype.equals("text/xml") && mimetype.equals("text/x-component"))
|
||||
{
|
||||
// IE supports "behaviour" which means that css can load a .htc file that could
|
||||
// contain XSS code in the form of jscript, vbscript etc, to stop it form being
|
||||
// evaluated we set the contient type to text/plain
|
||||
res.setContentType("text/plain");
|
||||
}
|
||||
|
||||
String encoding = reader.getEncoding();
|
||||
byte[] bytes = encoding != null ? content.getBytes(encoding) : content.getBytes();
|
||||
res.setContentLength(bytes.length);
|
||||
res.getOutputStream().write(bytes);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// return the complete entity range
|
||||
long size = reader.getSize();
|
||||
res.setHeader(HEADER_CONTENT_RANGE, "bytes 0-" + Long.toString(size-1L) + "/" + Long.toString(size));
|
||||
res.setHeader(HEADER_CONTENT_LENGTH, Long.toString(size));
|
||||
reader.getContent( res.getOutputStream() );
|
||||
}
|
||||
}
|
||||
catch (SocketException e1)
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader);
|
||||
}
|
||||
catch (ContentIOException e2)
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Failed stream read:\n\tnode: " + nodeRef + " due to: " + e2.getMessage());
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
if (err.getCause() instanceof SocketException)
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader);
|
||||
}
|
||||
else throw err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("HEAD request processed - no content sent.");
|
||||
res.getOutputStream().close();
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during download content servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHeaderContentDisposition(HttpServletRequest req, HttpServletResponse res, String filename)
|
||||
{
|
||||
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
|
||||
// this is better than the default response of the browser trying to display the contents
|
||||
|
||||
// IE requires that "Content-Disposition" header in case of "attachment" type should include
|
||||
// "filename" part. See MNT-9900
|
||||
String userAgent = req.getHeader(HEADER_USER_AGENT);
|
||||
if (userAgent != null && (userAgent.toLowerCase().contains("firefox") || userAgent.toLowerCase().contains("safari")))
|
||||
{
|
||||
res.setHeader(HEADER_CONTENT_DISPOSITION, "attachment; filename=\"" + URLDecoder.decode(filename) + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
res.setHeader(HEADER_CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
*
|
||||
* @param pattern The pattern to use for the URL
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
protected final static String generateUrl(String pattern, NodeRef ref, String name)
|
||||
{
|
||||
return MessageFormat.format(pattern, new Object[] {
|
||||
ref.getStoreRef().getProtocol(),
|
||||
ref.getStoreRef().getIdentifier(),
|
||||
ref.getId(),
|
||||
URLEncoder.encode(name) } );
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.repo.web.util.HttpRangeProcessor;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.surf.util.URLEncoder;
|
||||
import org.springframework.extensions.webscripts.ui.common.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for the download content servlets. Provides common
|
||||
* processing for the request.
|
||||
*
|
||||
* @see org.alfresco.web.app.servlet.DownloadContentServlet
|
||||
* @see org.alfresco.web.app.servlet.GuestDownloadContentServlet
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class BaseDownloadContentServlet extends BaseServlet
|
||||
{
|
||||
private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
|
||||
private static final long serialVersionUID = -4558907921887235967L;
|
||||
|
||||
private static final String POWER_POINT_DOCUMENT_MIMETYPE = "application/vnd.ms-powerpoint";
|
||||
private static final String POWER_POINT_2007_DOCUMENT_MIMETYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||||
|
||||
private static final String HEADER_CONTENT_RANGE = "Content-Range";
|
||||
private static final String HEADER_CONTENT_LENGTH = "Content-Length";
|
||||
private static final String HEADER_ACCEPT_RANGES = "Accept-Ranges";
|
||||
private static final String HEADER_RANGE = "Range";
|
||||
private static final String HEADER_ETAG = "ETag";
|
||||
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
|
||||
private static final String HEADER_LAST_MODIFIED = "Last-Modified";
|
||||
private static final String HEADER_USER_AGENT = "User-Agent";
|
||||
private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||
|
||||
protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
protected static final String MSG_ERROR_CONTENT_MISSING = "error_content_missing";
|
||||
protected static final String MSG_ERROR_NOT_FOUND = "error_not_found";
|
||||
|
||||
protected static final String URL_DIRECT = "d";
|
||||
protected static final String URL_DIRECT_LONG = "direct";
|
||||
protected static final String URL_ATTACH = "a";
|
||||
protected static final String URL_ATTACH_LONG = "attach";
|
||||
protected static final String ARG_PROPERTY = "property";
|
||||
protected static final String ARG_PATH = "path";
|
||||
|
||||
/**
|
||||
* Gets the logger to use for this request.
|
||||
* <p>
|
||||
* This will show all debug entries from this class as though they
|
||||
* came from the subclass.
|
||||
*
|
||||
* @return The logger
|
||||
*/
|
||||
protected abstract Log getLogger();
|
||||
|
||||
/**
|
||||
* Processes the download request using the current context i.e. no authentication checks are made, it is presumed
|
||||
* they have already been done.
|
||||
*
|
||||
* @param req
|
||||
* The HTTP request
|
||||
* @param res
|
||||
* The HTTP response
|
||||
* @param allowLogIn
|
||||
* Indicates whether guest users without access to the content should be redirected to the log in page. If
|
||||
* <code>false</code>, a status 403 forbidden page is displayed instead.
|
||||
*/
|
||||
protected void processDownloadRequest(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean allowLogIn, boolean transmitContent)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
Log logger = getLogger();
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// attachment mode (either 'attach' or 'direct')
|
||||
String attachToken = t.nextToken();
|
||||
boolean attachment = URL_ATTACH.equals(attachToken) || URL_ATTACH_LONG.equals(attachToken);
|
||||
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
|
||||
// get or calculate the noderef and filename to download as
|
||||
NodeRef nodeRef;
|
||||
String filename;
|
||||
|
||||
// do we have a path parameter instead of a NodeRef?
|
||||
String path = req.getParameter(ARG_PATH);
|
||||
if (path != null && path.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef and the Filename element
|
||||
try
|
||||
{
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), path);
|
||||
nodeRef = pathInfo.NodeRef;
|
||||
filename = pathInfo.Filename;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// a NodeRef must have been specified if no path has been found
|
||||
if (tokenCount < 6)
|
||||
{
|
||||
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
// assume 'workspace' or other NodeRef based protocol for remaining URL elements
|
||||
StoreRef storeRef = new StoreRef(URLDecoder.decode(t.nextToken()), URLDecoder.decode(t.nextToken()));
|
||||
String id = URLDecoder.decode(t.nextToken());
|
||||
|
||||
// build noderef from the appropriate URL elements
|
||||
nodeRef = new NodeRef(storeRef, id);
|
||||
|
||||
if (tokenCount > 6)
|
||||
{
|
||||
// found additional relative path elements i.e. noderefid/images/file.txt
|
||||
// this allows a url to reference siblings nodes via a cm:name based relative path
|
||||
// solves the issue with opening HTML content containing relative URLs in HREF or IMG tags etc.
|
||||
List<String> paths = new ArrayList<String>(tokenCount - 5);
|
||||
while (t.hasMoreTokens())
|
||||
{
|
||||
paths.add(URLDecoder.decode(t.nextToken()));
|
||||
}
|
||||
filename = paths.get(paths.size() - 1);
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef parentRef = serviceRegistry.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
||||
FileInfo fileInfo = serviceRegistry.getFileFolderService().resolveNamePath(parentRef, paths);
|
||||
nodeRef = fileInfo.getNodeRef();
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// filename is last remaining token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
// get qualified of the property to get content from - default to ContentModel.PROP_CONTENT
|
||||
QName propertyQName = ContentModel.PROP_CONTENT;
|
||||
String property = req.getParameter(ARG_PROPERTY);
|
||||
if (property != null && property.length() != 0)
|
||||
{
|
||||
propertyQName = QName.createQName(property);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Found NodeRef: " + nodeRef);
|
||||
logger.debug("Will use filename: " + filename);
|
||||
logger.debug("For property: " + propertyQName);
|
||||
logger.debug("With attachment mode: " + attachment);
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
ContentService contentService = serviceRegistry.getContentService();
|
||||
|
||||
// Check that the node still exists
|
||||
if (!nodeService.exists(nodeRef))
|
||||
{
|
||||
Application.handleSystemError(getServletContext(), req, res, MSG_ERROR_NOT_FOUND,
|
||||
HttpServletResponse.SC_NOT_FOUND, logger);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// check that the user has at least READ_CONTENT access - else redirect to an error or login page
|
||||
if (!checkAccess(req, res, nodeRef, PermissionService.READ_CONTENT, allowLogIn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check If-Modified-Since header and set Last-Modified header as appropriate
|
||||
Date modified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
|
||||
if (modified != null)
|
||||
{
|
||||
long modifiedSince = req.getDateHeader(HEADER_IF_MODIFIED_SINCE);
|
||||
if (modifiedSince > 0L)
|
||||
{
|
||||
// round the date to the ignore millisecond value which is not supplied by header
|
||||
long modDate = (modified.getTime() / 1000L) * 1000L;
|
||||
if (modDate <= modifiedSince)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 304 Not Modified.");
|
||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.setDateHeader(HEADER_LAST_MODIFIED, modified.getTime());
|
||||
res.setHeader(HEADER_CACHE_CONTROL, "must-revalidate, max-age=0");
|
||||
res.setHeader(HEADER_ETAG, "\"" + Long.toString(modified.getTime()) + "\"");
|
||||
}
|
||||
|
||||
if (attachment == true)
|
||||
{
|
||||
setHeaderContentDisposition(req, res, filename);
|
||||
}
|
||||
|
||||
// get the content reader
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
// ensure that it is safe to use
|
||||
reader = FileContentReader.getSafeContentReader(
|
||||
reader,
|
||||
Application.getMessage(req.getSession(), MSG_ERROR_CONTENT_MISSING),
|
||||
nodeRef, reader);
|
||||
|
||||
String mimetype = reader.getMimetype();
|
||||
// fall back if unable to resolve mimetype property
|
||||
if (mimetype == null || mimetype.length() == 0)
|
||||
{
|
||||
MimetypeService mimetypeMap = serviceRegistry.getMimetypeService();
|
||||
mimetype = MIMETYPE_OCTET_STREAM;
|
||||
int extIndex = filename.lastIndexOf('.');
|
||||
if (extIndex != -1)
|
||||
{
|
||||
String ext = filename.substring(extIndex + 1);
|
||||
mimetype = mimetypeMap.getMimetype(ext);
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly set the content disposition header if the content is powerpoint
|
||||
if (!attachment && (mimetype.equals(POWER_POINT_2007_DOCUMENT_MIMETYPE) ||
|
||||
mimetype.equals(POWER_POINT_DOCUMENT_MIMETYPE)))
|
||||
{
|
||||
setHeaderContentDisposition(req, res, filename);
|
||||
}
|
||||
|
||||
// get the content and stream directly to the response output stream
|
||||
// assuming the repo is capable of streaming in chunks, this should allow large files
|
||||
// to be streamed directly to the browser response stream.
|
||||
res.setHeader(HEADER_ACCEPT_RANGES, "bytes");
|
||||
|
||||
// for a GET request, transmit the content else just the headers are sent
|
||||
if (transmitContent)
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean processedRange = false;
|
||||
String range = req.getHeader(HEADER_CONTENT_RANGE);
|
||||
if (range == null)
|
||||
{
|
||||
range = req.getHeader(HEADER_RANGE);
|
||||
}
|
||||
if (range != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found content range header: " + range);
|
||||
|
||||
// ensure the range header is starts with "bytes=" and process the range(s)
|
||||
if (range.length() > 6)
|
||||
{
|
||||
HttpRangeProcessor rangeProcessor = new HttpRangeProcessor(contentService);
|
||||
processedRange = rangeProcessor.processRange(
|
||||
res, reader, range.substring(6), nodeRef, propertyQName,
|
||||
mimetype, req.getHeader(HEADER_USER_AGENT));
|
||||
}
|
||||
}
|
||||
if (processedRange == false)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Sending complete file content...");
|
||||
|
||||
// set mimetype for the content and the character encoding for the stream
|
||||
res.setContentType(mimetype);
|
||||
res.setCharacterEncoding(reader.getEncoding());
|
||||
|
||||
// MNT-10642 Alfresco Explorer has javascript vulnerability opening HTML files
|
||||
if (req.getRequestURI().contains("/d/d/") && (mimetype.equals("text/html") || mimetype.equals("application/xhtml+xml") || mimetype.equals("text/xml")))
|
||||
{
|
||||
String content = reader.getContentString();
|
||||
|
||||
if (mimetype.equals("text/html") || mimetype.equals("application/xhtml+xml"))
|
||||
{
|
||||
// process with HTML stripper
|
||||
content = StringUtils.stripUnsafeHTMLTags(content, false);
|
||||
}
|
||||
else if (mimetype.equals("text/xml") && mimetype.equals("text/x-component"))
|
||||
{
|
||||
// IE supports "behaviour" which means that css can load a .htc file that could
|
||||
// contain XSS code in the form of jscript, vbscript etc, to stop it form being
|
||||
// evaluated we set the contient type to text/plain
|
||||
res.setContentType("text/plain");
|
||||
}
|
||||
|
||||
String encoding = reader.getEncoding();
|
||||
byte[] bytes = encoding != null ? content.getBytes(encoding) : content.getBytes();
|
||||
res.setContentLength(bytes.length);
|
||||
res.getOutputStream().write(bytes);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// return the complete entity range
|
||||
long size = reader.getSize();
|
||||
res.setHeader(HEADER_CONTENT_RANGE, "bytes 0-" + Long.toString(size-1L) + "/" + Long.toString(size));
|
||||
res.setHeader(HEADER_CONTENT_LENGTH, Long.toString(size));
|
||||
reader.getContent( res.getOutputStream() );
|
||||
}
|
||||
}
|
||||
catch (SocketException e1)
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader);
|
||||
}
|
||||
catch (ContentIOException e2)
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Failed stream read:\n\tnode: " + nodeRef + " due to: " + e2.getMessage());
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
if (err.getCause() instanceof SocketException)
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Client aborted stream read:\n\tnode: " + nodeRef + "\n\tcontent: " + reader);
|
||||
}
|
||||
else throw err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("HEAD request processed - no content sent.");
|
||||
res.getOutputStream().close();
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during download content servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHeaderContentDisposition(HttpServletRequest req, HttpServletResponse res, String filename)
|
||||
{
|
||||
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
|
||||
// this is better than the default response of the browser trying to display the contents
|
||||
|
||||
// IE requires that "Content-Disposition" header in case of "attachment" type should include
|
||||
// "filename" part. See MNT-9900
|
||||
String userAgent = req.getHeader(HEADER_USER_AGENT);
|
||||
if (userAgent != null && (userAgent.toLowerCase().contains("firefox") || userAgent.toLowerCase().contains("safari")))
|
||||
{
|
||||
res.setHeader(HEADER_CONTENT_DISPOSITION, "attachment; filename=\"" + URLDecoder.decode(filename) + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
res.setHeader(HEADER_CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
*
|
||||
* @param pattern The pattern to use for the URL
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
protected final static String generateUrl(String pattern, NodeRef ref, String name)
|
||||
{
|
||||
return MessageFormat.format(pattern, new Object[] {
|
||||
ref.getStoreRef().getProtocol(),
|
||||
ref.getStoreRef().getIdentifier(),
|
||||
ref.getId(),
|
||||
URLEncoder.encode(name) } );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,481 +1,481 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
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.namespace.NamespaceService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.LoginOutcomeBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Base servlet class containing useful constant values and common methods for Alfresco servlets.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = -826295358696861789L;
|
||||
|
||||
public static final String FACES_SERVLET = "/faces";
|
||||
public static final String KEY_STORE = "store";
|
||||
public static final String KEY_ROOT_PATH = "rootPath";
|
||||
|
||||
/** an existing Ticket can be passed to most servlet for non-session based authentication */
|
||||
private static final String ARG_TICKET = "ticket";
|
||||
|
||||
/** forcing guess access is available on most servlets */
|
||||
private static final String ARG_GUEST = "guest";
|
||||
|
||||
private static final String MSG_ERROR_PERMISSIONS = "error_permissions";
|
||||
|
||||
/** list of valid JSPs for redirect after a clean login */
|
||||
// TODO: make this list configurable
|
||||
private static Set<String> validRedirectJSPs = new HashSet<String>();
|
||||
static
|
||||
{
|
||||
validRedirectJSPs.add("/jsp/browse/browse.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/admin-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/avm-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/node-browser.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/store-browser.jsp");
|
||||
validRedirectJSPs.add("/jsp/users/user-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/categories/categories.jsp");
|
||||
validRedirectJSPs.add("/jsp/dialog/about.jsp");
|
||||
validRedirectJSPs.add("/jsp/search/advanced-search.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/system-info.jsp");
|
||||
validRedirectJSPs.add("/jsp/forums/forums.jsp");
|
||||
validRedirectJSPs.add("/jsp/users/users.jsp");
|
||||
validRedirectJSPs.add("/jsp/trashcan/trash-list.jsp");
|
||||
}
|
||||
|
||||
private static Log logger = LogFactory.getLog(BaseServlet.class);
|
||||
|
||||
|
||||
/**
|
||||
* Return the ServiceRegistry helper instance
|
||||
*
|
||||
* @param sc ServletContext
|
||||
*
|
||||
* @return ServiceRegistry
|
||||
*/
|
||||
public static ServiceRegistry getServiceRegistry(ServletContext sc)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
|
||||
return (ServiceRegistry)wc.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication for the servlet request URI. Processing any "ticket" or
|
||||
* "guest" URL arguments.
|
||||
*
|
||||
* @return AuthenticationStatus
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res)
|
||||
throws IOException
|
||||
{
|
||||
return servletAuthenticate(req, res, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication for the servlet request URI. Processing any "ticket" or
|
||||
* "guest" URL arguments.
|
||||
*
|
||||
* @return AuthenticationStatus
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean redirectToLoginPage) throws IOException
|
||||
{
|
||||
AuthenticationStatus status;
|
||||
|
||||
// see if a ticket or a force Guest parameter has been supplied
|
||||
String ticket = req.getParameter(ARG_TICKET);
|
||||
if (ticket != null && ticket.length() != 0)
|
||||
{
|
||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, ticket);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean forceGuest = false;
|
||||
String guest = req.getParameter(ARG_GUEST);
|
||||
if (guest != null)
|
||||
{
|
||||
forceGuest = Boolean.parseBoolean(guest);
|
||||
}
|
||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest);
|
||||
}
|
||||
if (status == AuthenticationStatus.Failure && redirectToLoginPage)
|
||||
{
|
||||
// authentication failed - now need to display the login page to the user, if asked to
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the user has the given permission on the given node. If they do not either force a log on if this is a guest
|
||||
* user or forward to an error page.
|
||||
*
|
||||
* @param req
|
||||
* the request
|
||||
* @param res
|
||||
* the response
|
||||
* @param nodeRef
|
||||
* the node in question
|
||||
* @param allowLogIn
|
||||
* Indicates whether guest users without access to the node should be redirected to the log in page. If
|
||||
* <code>false</code>, a status 403 forbidden page is displayed instead.
|
||||
* @return <code>true</code>, if the user has access
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
* @throws ServletException
|
||||
* On other errors
|
||||
*/
|
||||
public boolean checkAccess(HttpServletRequest req, HttpServletResponse res, NodeRef nodeRef, String permission,
|
||||
boolean allowLogIn) throws IOException, ServletException
|
||||
{
|
||||
ServletContext sc = getServletContext();
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(sc);
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
|
||||
// check that the user has the permission
|
||||
if (permissionService.hasPermission(nodeRef, permission) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("User does not have " + permission + " permission for NodeRef: " + nodeRef.toString());
|
||||
|
||||
if (allowLogIn && serviceRegistry.getAuthorityService().hasGuestAuthority())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
redirectToLoginPage(req, res, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Forwarding to error page...");
|
||||
Application
|
||||
.handleSystemError(sc, req, res, MSG_ERROR_PERMISSIONS, HttpServletResponse.SC_FORBIDDEN, logger);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the Login page - saving the current URL which can be redirected back later
|
||||
* once the user has successfully completed the authentication process.
|
||||
*/
|
||||
public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc)
|
||||
throws IOException
|
||||
{
|
||||
redirectToLoginPage(req, res, sc, AuthenticationHelper.getRemoteUserMapper(sc) == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the Login page - saving the current URL which can be redirected back later
|
||||
* once the user has successfully completed the authentication process.
|
||||
* @param sendRedirect allow a redirect status code to be set? If <code>false</code> redirect
|
||||
* will be via markup rather than status code (to allow the status code to be used for handshake
|
||||
* responses etc.
|
||||
*/
|
||||
public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc, boolean sendRedirect)
|
||||
throws IOException
|
||||
{
|
||||
// Pass the full requested URL as a parameter so the login page knows where to redirect to later
|
||||
final String uri = req.getRequestURI();
|
||||
String redirectURL = uri;
|
||||
|
||||
// authentication failed - so end servlet execution and redirect to login page
|
||||
if (WebApplicationContextUtils.getRequiredWebApplicationContext(sc).containsBean(Application.BEAN_CONFIG_SERVICE))
|
||||
{
|
||||
StringBuilder redirect = new StringBuilder(128)
|
||||
.append(req.getContextPath()).append(FACES_SERVLET).append(Application.getLoginPage(sc));
|
||||
|
||||
// if we find a JSF servlet reference in the URI then we need to check if the rest of the
|
||||
// JSP specified is valid for a redirect operation after Login has occured.
|
||||
int jspIndex;
|
||||
if (uri.indexOf(req.getContextPath() + FACES_SERVLET) == -1
|
||||
|| uri.length() > (jspIndex = uri.indexOf(BaseServlet.FACES_SERVLET) + BaseServlet.FACES_SERVLET.length())
|
||||
&& BaseServlet.validRedirectJSP(uri.substring(jspIndex)))
|
||||
{
|
||||
if (redirect.indexOf("?") == -1)
|
||||
{
|
||||
redirect.append('?');
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect.append('&');
|
||||
}
|
||||
redirect.append(LoginOutcomeBean.PARAM_REDIRECT_URL);
|
||||
redirect.append('=');
|
||||
String url = uri;
|
||||
|
||||
// Append the query string if necessary
|
||||
String queryString = req.getQueryString();
|
||||
if (queryString != null)
|
||||
{
|
||||
// Strip out leading ticket arguments
|
||||
queryString = queryString.replaceAll("(?<=^|&)" + ARG_TICKET + "(=[^&=]*)?&", "");
|
||||
// Strip out trailing ticket arguments
|
||||
queryString = queryString.replaceAll("(^|&)" + ARG_TICKET + "(=[^&=]*)?(?=&|$)", "");
|
||||
if (queryString.length() != 0)
|
||||
{
|
||||
url += "?" + queryString;
|
||||
}
|
||||
}
|
||||
redirect.append(URLEncoder.encode(url, "UTF-8"));
|
||||
}
|
||||
redirectURL = redirect.toString();
|
||||
}
|
||||
// If external authentication isn't in use (e.g. proxied share authentication), it's safe to return a redirect to the client
|
||||
if (sendRedirect)
|
||||
{
|
||||
res.sendRedirect(redirectURL);
|
||||
}
|
||||
// Otherwise, we must signal to the client with an unauthorized status code and rely on a browser refresh to do
|
||||
// the redirect for failover login (as we do with NTLM, Kerberos)
|
||||
else
|
||||
{
|
||||
res.setContentType("text/html; charset=UTF-8");
|
||||
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
|
||||
final PrintWriter out = res.getWriter();
|
||||
out.println("<html><head>");
|
||||
out.println("<meta http-equiv=\"Refresh\" content=\"0; url=" + redirectURL + "\">");
|
||||
out.println("</head><body><p>Please <a href=\"" + redirectURL + "\">log in</a>.</p>");
|
||||
out.println("</body></html>");
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the headers required to disallow caching of the response in the browser
|
||||
*/
|
||||
public static void setNoCacheHeaders(HttpServletResponse res)
|
||||
{
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified JSP file is valid for a redirect after login.
|
||||
* Only a specific sub-set of the available JSPs are valid to jump directly too after a
|
||||
* clean login attempt - e.g. those that do not require JSF bean context setup. This is
|
||||
* a limitation of the JSP architecture. The ExternalAccessServlet provides a mechanism to
|
||||
* setup the JSF bean context directly for some specific cases.
|
||||
*
|
||||
* @param jsp Filename of JSP to check, for example "/jsp/browse/browse.jsp"
|
||||
*
|
||||
* @return true if the JSP is in the list of valid direct URLs, false otherwise
|
||||
*/
|
||||
public static boolean validRedirectJSP(String jsp)
|
||||
{
|
||||
return validRedirectJSPs.contains(jsp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param args The elements of the path to lookup
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(FacesContext context, String[] args)
|
||||
{
|
||||
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(FacesContext context, String[] args, boolean decode)
|
||||
{
|
||||
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, decode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context ServletContext context
|
||||
* @param args The elements of the path to lookup
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(ServletContext context, String[] args)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context ServletContext context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(ServletContext context, String[] args, boolean decode)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, decode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param wc WebApplicationContext Context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
private static NodeRef resolveWebDAVPath(final WebApplicationContext wc, final String[] args, final boolean decode)
|
||||
{
|
||||
return AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
|
||||
{
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
NodeRef nodeRef = null;
|
||||
|
||||
List<String> paths = new ArrayList<String>(args.length - 1);
|
||||
|
||||
FileInfo file = null;
|
||||
try
|
||||
{
|
||||
// create a list of path elements (decode the URL as we go)
|
||||
for (int x = 1; x < args.length; x++)
|
||||
{
|
||||
paths.add(decode ? URLDecoder.decode(args[x]) : args[x]);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to resolve webdav path: " + paths);
|
||||
|
||||
// get the company home node to start the search from
|
||||
nodeRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||
|
||||
TenantService tenantService = (TenantService)wc.getBean("tenantService");
|
||||
if (tenantService != null && tenantService.isEnabled())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("MT is enabled.");
|
||||
|
||||
NodeService nodeService = (NodeService) wc.getBean("NodeService");
|
||||
SearchService searchService = (SearchService) wc.getBean("SearchService");
|
||||
NamespaceService namespaceService = (NamespaceService) wc.getBean("NamespaceService");
|
||||
|
||||
// TODO: since these constants are used more widely than just the WebDAVServlet,
|
||||
// they should be defined somewhere other than in that servlet
|
||||
String rootPath = wc.getServletContext().getInitParameter(BaseServlet.KEY_ROOT_PATH);
|
||||
|
||||
// note: rootNodeRef is required (for storeRef part)
|
||||
nodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, nodeRef);
|
||||
}
|
||||
|
||||
if (paths.size() != 0)
|
||||
{
|
||||
FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService");
|
||||
file = ffs.resolveNamePath(nodeRef, paths);
|
||||
nodeRef = file.getNodeRef();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Resolved webdav path to NodeRef: " + nodeRef);
|
||||
}
|
||||
catch (FileNotFoundException fne)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Failed to resolve webdav path", fne);
|
||||
|
||||
nodeRef = null;
|
||||
}
|
||||
return nodeRef;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a name based into a NodeRef and Filename string
|
||||
*
|
||||
* @param sc ServletContext
|
||||
* @param path 'cm:name' based path using the '/' character as a separator
|
||||
*
|
||||
* @return PathRefInfo structure containing the resolved NodeRef and filename
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public final static PathRefInfo resolveNamePath(ServletContext sc, String path)
|
||||
{
|
||||
StringTokenizer t = new StringTokenizer(path, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
String[] elements = new String[tokenCount];
|
||||
for (int i=0; i<tokenCount; i++)
|
||||
{
|
||||
elements[i] = t.nextToken();
|
||||
}
|
||||
|
||||
// process name based path tokens using the webdav path resolving helper
|
||||
NodeRef nodeRef = resolveWebDAVPath(sc, elements, false);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
// unable to resolve path - output helpful error to the user
|
||||
throw new IllegalArgumentException("Unable to resolve item Path: " + path);
|
||||
}
|
||||
|
||||
return new PathRefInfo(nodeRef, elements[tokenCount - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple structure class for returning both a NodeRef and Filename String
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public static class PathRefInfo
|
||||
{
|
||||
PathRefInfo(NodeRef ref, String filename)
|
||||
{
|
||||
this.NodeRef = ref;
|
||||
this.Filename = filename;
|
||||
}
|
||||
public NodeRef NodeRef;
|
||||
public String Filename;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
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.namespace.NamespaceService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.LoginOutcomeBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Base servlet class containing useful constant values and common methods for Alfresco servlets.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = -826295358696861789L;
|
||||
|
||||
public static final String FACES_SERVLET = "/faces";
|
||||
public static final String KEY_STORE = "store";
|
||||
public static final String KEY_ROOT_PATH = "rootPath";
|
||||
|
||||
/** an existing Ticket can be passed to most servlet for non-session based authentication */
|
||||
private static final String ARG_TICKET = "ticket";
|
||||
|
||||
/** forcing guess access is available on most servlets */
|
||||
private static final String ARG_GUEST = "guest";
|
||||
|
||||
private static final String MSG_ERROR_PERMISSIONS = "error_permissions";
|
||||
|
||||
/** list of valid JSPs for redirect after a clean login */
|
||||
// TODO: make this list configurable
|
||||
private static Set<String> validRedirectJSPs = new HashSet<String>();
|
||||
static
|
||||
{
|
||||
validRedirectJSPs.add("/jsp/browse/browse.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/admin-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/avm-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/node-browser.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/store-browser.jsp");
|
||||
validRedirectJSPs.add("/jsp/users/user-console.jsp");
|
||||
validRedirectJSPs.add("/jsp/categories/categories.jsp");
|
||||
validRedirectJSPs.add("/jsp/dialog/about.jsp");
|
||||
validRedirectJSPs.add("/jsp/search/advanced-search.jsp");
|
||||
validRedirectJSPs.add("/jsp/admin/system-info.jsp");
|
||||
validRedirectJSPs.add("/jsp/forums/forums.jsp");
|
||||
validRedirectJSPs.add("/jsp/users/users.jsp");
|
||||
validRedirectJSPs.add("/jsp/trashcan/trash-list.jsp");
|
||||
}
|
||||
|
||||
private static Log logger = LogFactory.getLog(BaseServlet.class);
|
||||
|
||||
|
||||
/**
|
||||
* Return the ServiceRegistry helper instance
|
||||
*
|
||||
* @param sc ServletContext
|
||||
*
|
||||
* @return ServiceRegistry
|
||||
*/
|
||||
public static ServiceRegistry getServiceRegistry(ServletContext sc)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
|
||||
return (ServiceRegistry)wc.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication for the servlet request URI. Processing any "ticket" or
|
||||
* "guest" URL arguments.
|
||||
*
|
||||
* @return AuthenticationStatus
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res)
|
||||
throws IOException
|
||||
{
|
||||
return servletAuthenticate(req, res, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication for the servlet request URI. Processing any "ticket" or
|
||||
* "guest" URL arguments.
|
||||
*
|
||||
* @return AuthenticationStatus
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean redirectToLoginPage) throws IOException
|
||||
{
|
||||
AuthenticationStatus status;
|
||||
|
||||
// see if a ticket or a force Guest parameter has been supplied
|
||||
String ticket = req.getParameter(ARG_TICKET);
|
||||
if (ticket != null && ticket.length() != 0)
|
||||
{
|
||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, ticket);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean forceGuest = false;
|
||||
String guest = req.getParameter(ARG_GUEST);
|
||||
if (guest != null)
|
||||
{
|
||||
forceGuest = Boolean.parseBoolean(guest);
|
||||
}
|
||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest);
|
||||
}
|
||||
if (status == AuthenticationStatus.Failure && redirectToLoginPage)
|
||||
{
|
||||
// authentication failed - now need to display the login page to the user, if asked to
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the user has the given permission on the given node. If they do not either force a log on if this is a guest
|
||||
* user or forward to an error page.
|
||||
*
|
||||
* @param req
|
||||
* the request
|
||||
* @param res
|
||||
* the response
|
||||
* @param nodeRef
|
||||
* the node in question
|
||||
* @param allowLogIn
|
||||
* Indicates whether guest users without access to the node should be redirected to the log in page. If
|
||||
* <code>false</code>, a status 403 forbidden page is displayed instead.
|
||||
* @return <code>true</code>, if the user has access
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
* @throws ServletException
|
||||
* On other errors
|
||||
*/
|
||||
public boolean checkAccess(HttpServletRequest req, HttpServletResponse res, NodeRef nodeRef, String permission,
|
||||
boolean allowLogIn) throws IOException, ServletException
|
||||
{
|
||||
ServletContext sc = getServletContext();
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(sc);
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
|
||||
// check that the user has the permission
|
||||
if (permissionService.hasPermission(nodeRef, permission) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("User does not have " + permission + " permission for NodeRef: " + nodeRef.toString());
|
||||
|
||||
if (allowLogIn && serviceRegistry.getAuthorityService().hasGuestAuthority())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
redirectToLoginPage(req, res, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Forwarding to error page...");
|
||||
Application
|
||||
.handleSystemError(sc, req, res, MSG_ERROR_PERMISSIONS, HttpServletResponse.SC_FORBIDDEN, logger);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the Login page - saving the current URL which can be redirected back later
|
||||
* once the user has successfully completed the authentication process.
|
||||
*/
|
||||
public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc)
|
||||
throws IOException
|
||||
{
|
||||
redirectToLoginPage(req, res, sc, AuthenticationHelper.getRemoteUserMapper(sc) == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the Login page - saving the current URL which can be redirected back later
|
||||
* once the user has successfully completed the authentication process.
|
||||
* @param sendRedirect allow a redirect status code to be set? If <code>false</code> redirect
|
||||
* will be via markup rather than status code (to allow the status code to be used for handshake
|
||||
* responses etc.
|
||||
*/
|
||||
public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc, boolean sendRedirect)
|
||||
throws IOException
|
||||
{
|
||||
// Pass the full requested URL as a parameter so the login page knows where to redirect to later
|
||||
final String uri = req.getRequestURI();
|
||||
String redirectURL = uri;
|
||||
|
||||
// authentication failed - so end servlet execution and redirect to login page
|
||||
if (WebApplicationContextUtils.getRequiredWebApplicationContext(sc).containsBean(Application.BEAN_CONFIG_SERVICE))
|
||||
{
|
||||
StringBuilder redirect = new StringBuilder(128)
|
||||
.append(req.getContextPath()).append(FACES_SERVLET).append(Application.getLoginPage(sc));
|
||||
|
||||
// if we find a JSF servlet reference in the URI then we need to check if the rest of the
|
||||
// JSP specified is valid for a redirect operation after Login has occured.
|
||||
int jspIndex;
|
||||
if (uri.indexOf(req.getContextPath() + FACES_SERVLET) == -1
|
||||
|| uri.length() > (jspIndex = uri.indexOf(BaseServlet.FACES_SERVLET) + BaseServlet.FACES_SERVLET.length())
|
||||
&& BaseServlet.validRedirectJSP(uri.substring(jspIndex)))
|
||||
{
|
||||
if (redirect.indexOf("?") == -1)
|
||||
{
|
||||
redirect.append('?');
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect.append('&');
|
||||
}
|
||||
redirect.append(LoginOutcomeBean.PARAM_REDIRECT_URL);
|
||||
redirect.append('=');
|
||||
String url = uri;
|
||||
|
||||
// Append the query string if necessary
|
||||
String queryString = req.getQueryString();
|
||||
if (queryString != null)
|
||||
{
|
||||
// Strip out leading ticket arguments
|
||||
queryString = queryString.replaceAll("(?<=^|&)" + ARG_TICKET + "(=[^&=]*)?&", "");
|
||||
// Strip out trailing ticket arguments
|
||||
queryString = queryString.replaceAll("(^|&)" + ARG_TICKET + "(=[^&=]*)?(?=&|$)", "");
|
||||
if (queryString.length() != 0)
|
||||
{
|
||||
url += "?" + queryString;
|
||||
}
|
||||
}
|
||||
redirect.append(URLEncoder.encode(url, "UTF-8"));
|
||||
}
|
||||
redirectURL = redirect.toString();
|
||||
}
|
||||
// If external authentication isn't in use (e.g. proxied share authentication), it's safe to return a redirect to the client
|
||||
if (sendRedirect)
|
||||
{
|
||||
res.sendRedirect(redirectURL);
|
||||
}
|
||||
// Otherwise, we must signal to the client with an unauthorized status code and rely on a browser refresh to do
|
||||
// the redirect for failover login (as we do with NTLM, Kerberos)
|
||||
else
|
||||
{
|
||||
res.setContentType("text/html; charset=UTF-8");
|
||||
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
|
||||
final PrintWriter out = res.getWriter();
|
||||
out.println("<html><head>");
|
||||
out.println("<meta http-equiv=\"Refresh\" content=\"0; url=" + redirectURL + "\">");
|
||||
out.println("</head><body><p>Please <a href=\"" + redirectURL + "\">log in</a>.</p>");
|
||||
out.println("</body></html>");
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the headers required to disallow caching of the response in the browser
|
||||
*/
|
||||
public static void setNoCacheHeaders(HttpServletResponse res)
|
||||
{
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified JSP file is valid for a redirect after login.
|
||||
* Only a specific sub-set of the available JSPs are valid to jump directly too after a
|
||||
* clean login attempt - e.g. those that do not require JSF bean context setup. This is
|
||||
* a limitation of the JSP architecture. The ExternalAccessServlet provides a mechanism to
|
||||
* setup the JSF bean context directly for some specific cases.
|
||||
*
|
||||
* @param jsp Filename of JSP to check, for example "/jsp/browse/browse.jsp"
|
||||
*
|
||||
* @return true if the JSP is in the list of valid direct URLs, false otherwise
|
||||
*/
|
||||
public static boolean validRedirectJSP(String jsp)
|
||||
{
|
||||
return validRedirectJSPs.contains(jsp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param args The elements of the path to lookup
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(FacesContext context, String[] args)
|
||||
{
|
||||
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(FacesContext context, String[] args, boolean decode)
|
||||
{
|
||||
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, decode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context ServletContext context
|
||||
* @param args The elements of the path to lookup
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(ServletContext context, String[] args)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param context ServletContext context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
public static NodeRef resolveWebDAVPath(ServletContext context, String[] args, boolean decode)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||
return resolveWebDAVPath(wc, args, decode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given path elements to a NodeRef in the current repository
|
||||
*
|
||||
* @param wc WebApplicationContext Context
|
||||
* @param args The elements of the path to lookup
|
||||
* @param decode True to decode the arg from UTF-8 format, false for no decoding
|
||||
*/
|
||||
private static NodeRef resolveWebDAVPath(final WebApplicationContext wc, final String[] args, final boolean decode)
|
||||
{
|
||||
return AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
|
||||
{
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
NodeRef nodeRef = null;
|
||||
|
||||
List<String> paths = new ArrayList<String>(args.length - 1);
|
||||
|
||||
FileInfo file = null;
|
||||
try
|
||||
{
|
||||
// create a list of path elements (decode the URL as we go)
|
||||
for (int x = 1; x < args.length; x++)
|
||||
{
|
||||
paths.add(decode ? URLDecoder.decode(args[x]) : args[x]);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to resolve webdav path: " + paths);
|
||||
|
||||
// get the company home node to start the search from
|
||||
nodeRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||
|
||||
TenantService tenantService = (TenantService)wc.getBean("tenantService");
|
||||
if (tenantService != null && tenantService.isEnabled())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("MT is enabled.");
|
||||
|
||||
NodeService nodeService = (NodeService) wc.getBean("NodeService");
|
||||
SearchService searchService = (SearchService) wc.getBean("SearchService");
|
||||
NamespaceService namespaceService = (NamespaceService) wc.getBean("NamespaceService");
|
||||
|
||||
// TODO: since these constants are used more widely than just the WebDAVServlet,
|
||||
// they should be defined somewhere other than in that servlet
|
||||
String rootPath = wc.getServletContext().getInitParameter(BaseServlet.KEY_ROOT_PATH);
|
||||
|
||||
// note: rootNodeRef is required (for storeRef part)
|
||||
nodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, nodeRef);
|
||||
}
|
||||
|
||||
if (paths.size() != 0)
|
||||
{
|
||||
FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService");
|
||||
file = ffs.resolveNamePath(nodeRef, paths);
|
||||
nodeRef = file.getNodeRef();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Resolved webdav path to NodeRef: " + nodeRef);
|
||||
}
|
||||
catch (FileNotFoundException fne)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
logger.warn("Failed to resolve webdav path", fne);
|
||||
|
||||
nodeRef = null;
|
||||
}
|
||||
return nodeRef;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a name based into a NodeRef and Filename string
|
||||
*
|
||||
* @param sc ServletContext
|
||||
* @param path 'cm:name' based path using the '/' character as a separator
|
||||
*
|
||||
* @return PathRefInfo structure containing the resolved NodeRef and filename
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public final static PathRefInfo resolveNamePath(ServletContext sc, String path)
|
||||
{
|
||||
StringTokenizer t = new StringTokenizer(path, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
String[] elements = new String[tokenCount];
|
||||
for (int i=0; i<tokenCount; i++)
|
||||
{
|
||||
elements[i] = t.nextToken();
|
||||
}
|
||||
|
||||
// process name based path tokens using the webdav path resolving helper
|
||||
NodeRef nodeRef = resolveWebDAVPath(sc, elements, false);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
// unable to resolve path - output helpful error to the user
|
||||
throw new IllegalArgumentException("Unable to resolve item Path: " + path);
|
||||
}
|
||||
|
||||
return new PathRefInfo(nodeRef, elements[tokenCount - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple structure class for returning both a NodeRef and Filename String
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public static class PathRefInfo
|
||||
{
|
||||
PathRefInfo(NodeRef ref, String filename)
|
||||
{
|
||||
this.NodeRef = ref;
|
||||
this.Filename = filename;
|
||||
}
|
||||
public NodeRef NodeRef;
|
||||
public String Filename;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,363 +1,363 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateException;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.repository.TemplateService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
/**
|
||||
* Base class for the template content servlets. Provides common
|
||||
* processing for the request.
|
||||
*
|
||||
* @see org.alfresco.web.app.servlet.TemplateContentServlet
|
||||
* @see org.alfresco.web.app.servlet.GuestTemplateContentServlet
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author gavinc
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class BaseTemplateContentServlet extends BaseServlet
|
||||
{
|
||||
private static final String MIMETYPE_HTML = "text/html;charset=utf-8";
|
||||
|
||||
private static final long serialVersionUID = -4123407921997235977L;
|
||||
|
||||
private static final String ARG_MIMETYPE = "mimetype";
|
||||
private static final String ARG_TEMPLATE_PATH = "templatePath";
|
||||
private static final String ARG_CONTEXT_PATH = "contextPath";
|
||||
|
||||
/**
|
||||
* Gets the logger to use for this request.
|
||||
* <p>
|
||||
* This will show all debug entries from this class as though they
|
||||
* came from the subclass.
|
||||
*
|
||||
* @return The logger
|
||||
*/
|
||||
protected abstract Log getLogger();
|
||||
|
||||
/**
|
||||
* Builds the FreeMarker model
|
||||
*
|
||||
* @param services Service Registry instance
|
||||
* @param req Http request
|
||||
* @param templateRef The node ref of the template to process
|
||||
* @return The FreeMarker model
|
||||
*/
|
||||
protected abstract Map<String, Object> buildModel(ServiceRegistry services,
|
||||
HttpServletRequest req, NodeRef templateRef);
|
||||
|
||||
/**
|
||||
* Processes the template request using the current context i.e. no
|
||||
* authentication checks are made, it is presumed they have already
|
||||
* been done.
|
||||
*
|
||||
* @param req The HTTP request
|
||||
* @param res The HTTP response
|
||||
* @param redirectToLogin Flag to determine whether to redirect to the login
|
||||
* page if the user does not have the correct permissions
|
||||
*/
|
||||
protected void processTemplateRequest(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean redirectToLogin) throws ServletException, IOException
|
||||
{
|
||||
Log logger = getLogger();
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
NodeRef nodeRef = null;
|
||||
NodeRef templateRef = null;
|
||||
|
||||
try
|
||||
{
|
||||
String contentPath = req.getParameter(ARG_CONTEXT_PATH);
|
||||
if (contentPath != null && contentPath.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), contentPath);
|
||||
|
||||
nodeRef = pathInfo.NodeRef;
|
||||
}
|
||||
else if (tokenCount > 3)
|
||||
{
|
||||
// get NodeRef to the content from the URL elements
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
nodeRef = new NodeRef(storeRef, t.nextToken());
|
||||
}
|
||||
|
||||
// get NodeRef to the template if supplied
|
||||
String templatePath = req.getParameter(ARG_TEMPLATE_PATH);
|
||||
if (templatePath != null && templatePath.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), templatePath);
|
||||
|
||||
templateRef = pathInfo.NodeRef;
|
||||
}
|
||||
else if (tokenCount >= 7)
|
||||
{
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
templateRef = new NodeRef(storeRef, t.nextToken());
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException err)
|
||||
{
|
||||
if (redirectToLogin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if no context is specified, use the template itself
|
||||
// TODO: should this default to something else?
|
||||
if (nodeRef == null && templateRef != null)
|
||||
{
|
||||
nodeRef = templateRef;
|
||||
}
|
||||
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new TemplateException("Not enough elements supplied in URL or no 'path' argument specified.");
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
TemplateService templateService = serviceRegistry.getTemplateService();
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
|
||||
// check that the user has at least READ access on any nodes - else redirect to the login page
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED ||
|
||||
(templateRef != null && permissionService.hasPermission(templateRef, PermissionService.READ) == AccessStatus.DENIED))
|
||||
{
|
||||
if (redirectToLogin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String mimetype = MIMETYPE_HTML;
|
||||
if (req.getParameter(ARG_MIMETYPE) != null)
|
||||
{
|
||||
mimetype = req.getParameter(ARG_MIMETYPE);
|
||||
}
|
||||
res.setContentType(mimetype);
|
||||
|
||||
try
|
||||
{
|
||||
UserTransaction txn = null;
|
||||
try
|
||||
{
|
||||
txn = serviceRegistry.getTransactionService().getUserTransaction(true);
|
||||
txn.begin();
|
||||
|
||||
// if template not supplied, then use the default against the node
|
||||
if (templateRef == null)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPLATABLE))
|
||||
{
|
||||
templateRef = (NodeRef)nodeService.getProperty(nodeRef, ContentModel.PROP_TEMPLATE);
|
||||
}
|
||||
if (templateRef == null)
|
||||
{
|
||||
throw new TemplateException("Template reference not set against node or not supplied in URL.");
|
||||
}
|
||||
}
|
||||
|
||||
// create the model - put the supplied noderef in as space/document as appropriate
|
||||
Map<String, Object> model = getModel(serviceRegistry, req, templateRef, nodeRef);
|
||||
|
||||
// process the template against the node content directly to the response output stream
|
||||
// assuming the repo is capable of streaming in chunks, this should allow large files
|
||||
// to be streamed directly to the browser response stream.
|
||||
try
|
||||
{
|
||||
templateService.processTemplate(
|
||||
templateRef.toString(),
|
||||
model,
|
||||
res.getWriter());
|
||||
|
||||
// commit the transaction
|
||||
txn.commit();
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.getMessage().contains("ClientAbortException"))
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
logger.error("Client aborted stream read:\n node: " + nodeRef + "\n template: " + templateRef);
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
res.getWriter().close();
|
||||
}
|
||||
}
|
||||
catch (Throwable txnErr)
|
||||
{
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
throw txnErr;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during template servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the model that to process the template against.
|
||||
* <p>
|
||||
* The model includes the usual template root objects such as 'companyhome', 'userhome',
|
||||
* 'person' and also includes the node specified on the servlet URL as 'space' and 'document'
|
||||
*
|
||||
* @param services ServiceRegistry
|
||||
* @param req Http request - for accessing Session and url args
|
||||
* @param templateRef NodeRef of the template itself
|
||||
* @param nodeRef NodeRef of the space/document to process template against
|
||||
*
|
||||
* @return an object model ready for executing template against
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getModel(ServiceRegistry services, HttpServletRequest req, NodeRef templateRef, NodeRef nodeRef)
|
||||
{
|
||||
// build FreeMarker default model and merge
|
||||
Map<String, Object> root = buildModel(services, req, templateRef);
|
||||
|
||||
// put the current NodeRef in as "space" and "document"
|
||||
root.put("space", nodeRef);
|
||||
root.put("document", nodeRef);
|
||||
|
||||
// add URL arguments as a map called 'args' to the root of the model
|
||||
Map<String, String> args = new HashMap<String, String>(8, 1.0f);
|
||||
Enumeration names = req.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
try
|
||||
{
|
||||
args.put(name, new String(req.getParameter(name).getBytes(), "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException err) {}
|
||||
}
|
||||
root.put("args", args);
|
||||
|
||||
// Add the image resolver
|
||||
root.put(TemplateService.KEY_IMAGE_RESOLVER, imageResolver);
|
||||
|
||||
// method to allow client urls to be generated
|
||||
root.put("url", new URLHelper(req));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
protected TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(getServletContext(), filename, size);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to return context path for generating urls
|
||||
*/
|
||||
public static class URLHelper
|
||||
{
|
||||
String contextPath;
|
||||
String serverPath;
|
||||
|
||||
public URLHelper(HttpServletRequest request)
|
||||
{
|
||||
this.contextPath = request.getContextPath();
|
||||
this.serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
|
||||
}
|
||||
|
||||
public URLHelper(FacesContext context)
|
||||
{
|
||||
this.contextPath = context.getExternalContext().getRequestContextPath();
|
||||
final Object request = context.getExternalContext().getRequest();
|
||||
if (request instanceof HttpServletRequest)
|
||||
{
|
||||
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
this.serverPath = httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName() + ":" + httpServletRequest.getServerPort();
|
||||
}
|
||||
}
|
||||
|
||||
public String getContext()
|
||||
{
|
||||
return this.contextPath;
|
||||
}
|
||||
|
||||
public String getServerPath()
|
||||
{
|
||||
return this.serverPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateException;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.repository.TemplateService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
/**
|
||||
* Base class for the template content servlets. Provides common
|
||||
* processing for the request.
|
||||
*
|
||||
* @see org.alfresco.web.app.servlet.TemplateContentServlet
|
||||
* @see org.alfresco.web.app.servlet.GuestTemplateContentServlet
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author gavinc
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class BaseTemplateContentServlet extends BaseServlet
|
||||
{
|
||||
private static final String MIMETYPE_HTML = "text/html;charset=utf-8";
|
||||
|
||||
private static final long serialVersionUID = -4123407921997235977L;
|
||||
|
||||
private static final String ARG_MIMETYPE = "mimetype";
|
||||
private static final String ARG_TEMPLATE_PATH = "templatePath";
|
||||
private static final String ARG_CONTEXT_PATH = "contextPath";
|
||||
|
||||
/**
|
||||
* Gets the logger to use for this request.
|
||||
* <p>
|
||||
* This will show all debug entries from this class as though they
|
||||
* came from the subclass.
|
||||
*
|
||||
* @return The logger
|
||||
*/
|
||||
protected abstract Log getLogger();
|
||||
|
||||
/**
|
||||
* Builds the FreeMarker model
|
||||
*
|
||||
* @param services Service Registry instance
|
||||
* @param req Http request
|
||||
* @param templateRef The node ref of the template to process
|
||||
* @return The FreeMarker model
|
||||
*/
|
||||
protected abstract Map<String, Object> buildModel(ServiceRegistry services,
|
||||
HttpServletRequest req, NodeRef templateRef);
|
||||
|
||||
/**
|
||||
* Processes the template request using the current context i.e. no
|
||||
* authentication checks are made, it is presumed they have already
|
||||
* been done.
|
||||
*
|
||||
* @param req The HTTP request
|
||||
* @param res The HTTP response
|
||||
* @param redirectToLogin Flag to determine whether to redirect to the login
|
||||
* page if the user does not have the correct permissions
|
||||
*/
|
||||
protected void processTemplateRequest(HttpServletRequest req, HttpServletResponse res,
|
||||
boolean redirectToLogin) throws ServletException, IOException
|
||||
{
|
||||
Log logger = getLogger();
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
NodeRef nodeRef = null;
|
||||
NodeRef templateRef = null;
|
||||
|
||||
try
|
||||
{
|
||||
String contentPath = req.getParameter(ARG_CONTEXT_PATH);
|
||||
if (contentPath != null && contentPath.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), contentPath);
|
||||
|
||||
nodeRef = pathInfo.NodeRef;
|
||||
}
|
||||
else if (tokenCount > 3)
|
||||
{
|
||||
// get NodeRef to the content from the URL elements
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
nodeRef = new NodeRef(storeRef, t.nextToken());
|
||||
}
|
||||
|
||||
// get NodeRef to the template if supplied
|
||||
String templatePath = req.getParameter(ARG_TEMPLATE_PATH);
|
||||
if (templatePath != null && templatePath.length() != 0)
|
||||
{
|
||||
// process the name based path to resolve the NodeRef
|
||||
PathRefInfo pathInfo = resolveNamePath(getServletContext(), templatePath);
|
||||
|
||||
templateRef = pathInfo.NodeRef;
|
||||
}
|
||||
else if (tokenCount >= 7)
|
||||
{
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
templateRef = new NodeRef(storeRef, t.nextToken());
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException err)
|
||||
{
|
||||
if (redirectToLogin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if no context is specified, use the template itself
|
||||
// TODO: should this default to something else?
|
||||
if (nodeRef == null && templateRef != null)
|
||||
{
|
||||
nodeRef = templateRef;
|
||||
}
|
||||
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new TemplateException("Not enough elements supplied in URL or no 'path' argument specified.");
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
TemplateService templateService = serviceRegistry.getTemplateService();
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
|
||||
// check that the user has at least READ access on any nodes - else redirect to the login page
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED ||
|
||||
(templateRef != null && permissionService.hasPermission(templateRef, PermissionService.READ) == AccessStatus.DENIED))
|
||||
{
|
||||
if (redirectToLogin)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to login page...");
|
||||
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String mimetype = MIMETYPE_HTML;
|
||||
if (req.getParameter(ARG_MIMETYPE) != null)
|
||||
{
|
||||
mimetype = req.getParameter(ARG_MIMETYPE);
|
||||
}
|
||||
res.setContentType(mimetype);
|
||||
|
||||
try
|
||||
{
|
||||
UserTransaction txn = null;
|
||||
try
|
||||
{
|
||||
txn = serviceRegistry.getTransactionService().getUserTransaction(true);
|
||||
txn.begin();
|
||||
|
||||
// if template not supplied, then use the default against the node
|
||||
if (templateRef == null)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPLATABLE))
|
||||
{
|
||||
templateRef = (NodeRef)nodeService.getProperty(nodeRef, ContentModel.PROP_TEMPLATE);
|
||||
}
|
||||
if (templateRef == null)
|
||||
{
|
||||
throw new TemplateException("Template reference not set against node or not supplied in URL.");
|
||||
}
|
||||
}
|
||||
|
||||
// create the model - put the supplied noderef in as space/document as appropriate
|
||||
Map<String, Object> model = getModel(serviceRegistry, req, templateRef, nodeRef);
|
||||
|
||||
// process the template against the node content directly to the response output stream
|
||||
// assuming the repo is capable of streaming in chunks, this should allow large files
|
||||
// to be streamed directly to the browser response stream.
|
||||
try
|
||||
{
|
||||
templateService.processTemplate(
|
||||
templateRef.toString(),
|
||||
model,
|
||||
res.getWriter());
|
||||
|
||||
// commit the transaction
|
||||
txn.commit();
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.getMessage().contains("ClientAbortException"))
|
||||
{
|
||||
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||
logger.error("Client aborted stream read:\n node: " + nodeRef + "\n template: " + templateRef);
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
res.getWriter().close();
|
||||
}
|
||||
}
|
||||
catch (Throwable txnErr)
|
||||
{
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
throw txnErr;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during template servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the model that to process the template against.
|
||||
* <p>
|
||||
* The model includes the usual template root objects such as 'companyhome', 'userhome',
|
||||
* 'person' and also includes the node specified on the servlet URL as 'space' and 'document'
|
||||
*
|
||||
* @param services ServiceRegistry
|
||||
* @param req Http request - for accessing Session and url args
|
||||
* @param templateRef NodeRef of the template itself
|
||||
* @param nodeRef NodeRef of the space/document to process template against
|
||||
*
|
||||
* @return an object model ready for executing template against
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getModel(ServiceRegistry services, HttpServletRequest req, NodeRef templateRef, NodeRef nodeRef)
|
||||
{
|
||||
// build FreeMarker default model and merge
|
||||
Map<String, Object> root = buildModel(services, req, templateRef);
|
||||
|
||||
// put the current NodeRef in as "space" and "document"
|
||||
root.put("space", nodeRef);
|
||||
root.put("document", nodeRef);
|
||||
|
||||
// add URL arguments as a map called 'args' to the root of the model
|
||||
Map<String, String> args = new HashMap<String, String>(8, 1.0f);
|
||||
Enumeration names = req.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
try
|
||||
{
|
||||
args.put(name, new String(req.getParameter(name).getBytes(), "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException err) {}
|
||||
}
|
||||
root.put("args", args);
|
||||
|
||||
// Add the image resolver
|
||||
root.put(TemplateService.KEY_IMAGE_RESOLVER, imageResolver);
|
||||
|
||||
// method to allow client urls to be generated
|
||||
root.put("url", new URLHelper(req));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
protected TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(getServletContext(), filename, size);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to return context path for generating urls
|
||||
*/
|
||||
public static class URLHelper
|
||||
{
|
||||
String contextPath;
|
||||
String serverPath;
|
||||
|
||||
public URLHelper(HttpServletRequest request)
|
||||
{
|
||||
this.contextPath = request.getContextPath();
|
||||
this.serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
|
||||
}
|
||||
|
||||
public URLHelper(FacesContext context)
|
||||
{
|
||||
this.contextPath = context.getExternalContext().getRequestContextPath();
|
||||
final Object request = context.getExternalContext().getRequest();
|
||||
if (request instanceof HttpServletRequest)
|
||||
{
|
||||
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
this.serverPath = httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName() + ":" + httpServletRequest.getServerPort();
|
||||
}
|
||||
}
|
||||
|
||||
public String getContext()
|
||||
{
|
||||
return this.contextPath;
|
||||
}
|
||||
|
||||
public String getServerPath()
|
||||
{
|
||||
return this.serverPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,248 +1,248 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.command.CommandFactory;
|
||||
import org.alfresco.web.app.servlet.command.CommandProcessor;
|
||||
import org.alfresco.web.app.servlet.command.ExtCommandProcessor;
|
||||
import org.alfresco.web.config.CommandServletConfigElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for executing commands upon node(s).
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/command/processor-name/command-name/args/...</pre>
|
||||
* <p>
|
||||
* The 'processor-name' identifies the command processor to execute the command. For example the
|
||||
* 'workflow' processor will execute workflow commands upon a node (e.g. "approve" or "reject").
|
||||
* For example:
|
||||
* <pre>/alfresco/command/workflow/approve/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* The store protocol, followed by the store ID, followed by the content Node Id used to
|
||||
* identify the node to execute the workflow action upon.
|
||||
* <p>
|
||||
* A 'return-page' URL argument can be specified as the redirect page to navigate too after processing.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* And/or also followed by the "?guest=true" argument to force guest access login for the URL.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class CommandServlet extends BaseServlet
|
||||
{
|
||||
private static final long serialVersionUID = -5432407921038376133L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(CommandServlet.class);
|
||||
|
||||
private static CommandFactory commandfactory = CommandFactory.getInstance();
|
||||
|
||||
public static final String ARG_RETURNPAGE = "return-page";
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||
|
||||
AuthenticationStatus status = servletAuthenticate(req, res);
|
||||
if (status == AuthenticationStatus.Failure)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setNoCacheHeaders(res);
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
if (tokenCount < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Command Servlet URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// get the command processor to execute the command e.g. "workflow"
|
||||
String procName = t.nextToken();
|
||||
|
||||
// get the command to perform
|
||||
String command = t.nextToken();
|
||||
|
||||
// get any remaining uri elements to pass to the processor
|
||||
String[] urlElements = new String[tokenCount - 3];
|
||||
for (int i=0; i<tokenCount-3; i++)
|
||||
{
|
||||
urlElements[i] = t.nextToken();
|
||||
}
|
||||
|
||||
// retrieve the URL arguments to pass to the processor
|
||||
Map<String, String> args = new HashMap<String, String>(8, 1.0f);
|
||||
Enumeration names = req.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
args.put(name, req.getParameter(name));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// get configured command processor by name from Config Service
|
||||
CommandProcessor processor = createCommandProcessor(procName);
|
||||
|
||||
// validate that the processor has everything it needs to run the command
|
||||
if (processor.validateArguments(getServletContext(), command, args, urlElements) == false)
|
||||
{
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
UserTransaction txn = null;
|
||||
try
|
||||
{
|
||||
txn = serviceRegistry.getTransactionService().getUserTransaction();
|
||||
txn.begin();
|
||||
|
||||
// inform the processor to execute the specified command
|
||||
if (processor instanceof ExtCommandProcessor)
|
||||
{
|
||||
((ExtCommandProcessor)processor).process(serviceRegistry, req, res, command);
|
||||
}
|
||||
else
|
||||
{
|
||||
processor.process(serviceRegistry, req, command);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
txn.commit();
|
||||
}
|
||||
catch (Throwable txnErr)
|
||||
{
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
throw txnErr;
|
||||
}
|
||||
|
||||
String returnPage = req.getParameter(ARG_RETURNPAGE);
|
||||
if (returnPage != null && returnPage.length() != 0)
|
||||
{
|
||||
validateReturnPage(returnPage, req);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to specified return page: " + returnPage);
|
||||
|
||||
res.sendRedirect(returnPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("No return page specified, displaying status output.");
|
||||
|
||||
if (res.getContentType() == null && !res.isCommitted())
|
||||
{
|
||||
res.setContentType("text/html");
|
||||
|
||||
// request that the processor output a useful status message
|
||||
PrintWriter out = res.getWriter();
|
||||
processor.outputStatus(out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during command servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ALF-9113 CommandServlet.java, line 179 (Header Manipulation)
|
||||
*
|
||||
* Validates that the redirect page is within the current context.
|
||||
*
|
||||
* Examples of valid redirect pages:
|
||||
* <ul>
|
||||
* <li>/alfresco/faces/jsp/browse/browse.jsp</li>
|
||||
* <li>../../browse/browse.jsp</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param pageUrl
|
||||
* @param req
|
||||
* @throws MalformedURLException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private void validateReturnPage(String pageUrl, HttpServletRequest req) throws MalformedURLException
|
||||
{
|
||||
if (pageUrl.indexOf(':') != -1)
|
||||
{
|
||||
// ':' only allowed in a URL as part of a scheme prefix
|
||||
throw new IllegalArgumentException("The redirect URL doesn't support absolute URls");
|
||||
}
|
||||
// Evaluate it relative to the request URL and strip out .. and .
|
||||
pageUrl = new URL(new URL(req.getRequestURL().toString()), pageUrl).getPath();
|
||||
if (!pageUrl.startsWith(req.getContextPath()))
|
||||
{
|
||||
throw new IllegalArgumentException("The redirect URL must be in the same context.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created the specified CommandProcessor instance. The name of the processor is looked up
|
||||
* in the client config, it should find a valid class impl and then create it.
|
||||
*
|
||||
* @param procName Name of the CommandProcessor to lookup in the client config.
|
||||
*
|
||||
* @return CommandProcessor
|
||||
*
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private CommandProcessor createCommandProcessor(String procName)
|
||||
throws InstantiationException, IllegalAccessException
|
||||
{
|
||||
Config config = Application.getConfigService(getServletContext()).getConfig("Command Servlet");
|
||||
if (config == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("No command processors configured - unable to process any commands.");
|
||||
}
|
||||
|
||||
CommandServletConfigElement configElement = (CommandServletConfigElement)
|
||||
config.getConfigElement(CommandServletConfigElement.CONFIG_ELEMENT_ID);
|
||||
if (configElement == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("No command processors configured - unable to process any commands.");
|
||||
}
|
||||
|
||||
Class clazz = configElement.getCommandProcessor(procName);
|
||||
Object obj = clazz.newInstance();
|
||||
if (obj instanceof CommandProcessor == false)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Configured command processor '" + procName + "' is does not implement interface CommandProcessor!");
|
||||
}
|
||||
|
||||
return (CommandProcessor)obj;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.command.CommandFactory;
|
||||
import org.alfresco.web.app.servlet.command.CommandProcessor;
|
||||
import org.alfresco.web.app.servlet.command.ExtCommandProcessor;
|
||||
import org.alfresco.web.config.CommandServletConfigElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for executing commands upon node(s).
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/command/processor-name/command-name/args/...</pre>
|
||||
* <p>
|
||||
* The 'processor-name' identifies the command processor to execute the command. For example the
|
||||
* 'workflow' processor will execute workflow commands upon a node (e.g. "approve" or "reject").
|
||||
* For example:
|
||||
* <pre>/alfresco/command/workflow/approve/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* The store protocol, followed by the store ID, followed by the content Node Id used to
|
||||
* identify the node to execute the workflow action upon.
|
||||
* <p>
|
||||
* A 'return-page' URL argument can be specified as the redirect page to navigate too after processing.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* And/or also followed by the "?guest=true" argument to force guest access login for the URL.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class CommandServlet extends BaseServlet
|
||||
{
|
||||
private static final long serialVersionUID = -5432407921038376133L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(CommandServlet.class);
|
||||
|
||||
private static CommandFactory commandfactory = CommandFactory.getInstance();
|
||||
|
||||
public static final String ARG_RETURNPAGE = "return-page";
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String uri = req.getRequestURI();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||
|
||||
AuthenticationStatus status = servletAuthenticate(req, res);
|
||||
if (status == AuthenticationStatus.Failure)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setNoCacheHeaders(res);
|
||||
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
if (tokenCount < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Command Servlet URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// get the command processor to execute the command e.g. "workflow"
|
||||
String procName = t.nextToken();
|
||||
|
||||
// get the command to perform
|
||||
String command = t.nextToken();
|
||||
|
||||
// get any remaining uri elements to pass to the processor
|
||||
String[] urlElements = new String[tokenCount - 3];
|
||||
for (int i=0; i<tokenCount-3; i++)
|
||||
{
|
||||
urlElements[i] = t.nextToken();
|
||||
}
|
||||
|
||||
// retrieve the URL arguments to pass to the processor
|
||||
Map<String, String> args = new HashMap<String, String>(8, 1.0f);
|
||||
Enumeration names = req.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
args.put(name, req.getParameter(name));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// get configured command processor by name from Config Service
|
||||
CommandProcessor processor = createCommandProcessor(procName);
|
||||
|
||||
// validate that the processor has everything it needs to run the command
|
||||
if (processor.validateArguments(getServletContext(), command, args, urlElements) == false)
|
||||
{
|
||||
redirectToLoginPage(req, res, getServletContext());
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
UserTransaction txn = null;
|
||||
try
|
||||
{
|
||||
txn = serviceRegistry.getTransactionService().getUserTransaction();
|
||||
txn.begin();
|
||||
|
||||
// inform the processor to execute the specified command
|
||||
if (processor instanceof ExtCommandProcessor)
|
||||
{
|
||||
((ExtCommandProcessor)processor).process(serviceRegistry, req, res, command);
|
||||
}
|
||||
else
|
||||
{
|
||||
processor.process(serviceRegistry, req, command);
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
txn.commit();
|
||||
}
|
||||
catch (Throwable txnErr)
|
||||
{
|
||||
try { if (txn != null) {txn.rollback();} } catch (Exception tex) {}
|
||||
throw txnErr;
|
||||
}
|
||||
|
||||
String returnPage = req.getParameter(ARG_RETURNPAGE);
|
||||
if (returnPage != null && returnPage.length() != 0)
|
||||
{
|
||||
validateReturnPage(returnPage, req);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Redirecting to specified return page: " + returnPage);
|
||||
|
||||
res.sendRedirect(returnPage);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("No return page specified, displaying status output.");
|
||||
|
||||
if (res.getContentType() == null && !res.isCommitted())
|
||||
{
|
||||
res.setContentType("text/html");
|
||||
|
||||
// request that the processor output a useful status message
|
||||
PrintWriter out = res.getWriter();
|
||||
processor.outputStatus(out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Error during command servlet processing: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ALF-9113 CommandServlet.java, line 179 (Header Manipulation)
|
||||
*
|
||||
* Validates that the redirect page is within the current context.
|
||||
*
|
||||
* Examples of valid redirect pages:
|
||||
* <ul>
|
||||
* <li>/alfresco/faces/jsp/browse/browse.jsp</li>
|
||||
* <li>../../browse/browse.jsp</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param pageUrl
|
||||
* @param req
|
||||
* @throws MalformedURLException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private void validateReturnPage(String pageUrl, HttpServletRequest req) throws MalformedURLException
|
||||
{
|
||||
if (pageUrl.indexOf(':') != -1)
|
||||
{
|
||||
// ':' only allowed in a URL as part of a scheme prefix
|
||||
throw new IllegalArgumentException("The redirect URL doesn't support absolute URls");
|
||||
}
|
||||
// Evaluate it relative to the request URL and strip out .. and .
|
||||
pageUrl = new URL(new URL(req.getRequestURL().toString()), pageUrl).getPath();
|
||||
if (!pageUrl.startsWith(req.getContextPath()))
|
||||
{
|
||||
throw new IllegalArgumentException("The redirect URL must be in the same context.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created the specified CommandProcessor instance. The name of the processor is looked up
|
||||
* in the client config, it should find a valid class impl and then create it.
|
||||
*
|
||||
* @param procName Name of the CommandProcessor to lookup in the client config.
|
||||
*
|
||||
* @return CommandProcessor
|
||||
*
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private CommandProcessor createCommandProcessor(String procName)
|
||||
throws InstantiationException, IllegalAccessException
|
||||
{
|
||||
Config config = Application.getConfigService(getServletContext()).getConfig("Command Servlet");
|
||||
if (config == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("No command processors configured - unable to process any commands.");
|
||||
}
|
||||
|
||||
CommandServletConfigElement configElement = (CommandServletConfigElement)
|
||||
config.getConfigElement(CommandServletConfigElement.CONFIG_ELEMENT_ID);
|
||||
if (configElement == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("No command processors configured - unable to process any commands.");
|
||||
}
|
||||
|
||||
Class clazz = configElement.getCommandProcessor(procName);
|
||||
Object obj = clazz.newInstance();
|
||||
if (obj instanceof CommandProcessor == false)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Configured command processor '" + procName + "' is does not implement interface CommandProcessor!");
|
||||
}
|
||||
|
||||
return (CommandProcessor)obj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,320 +1,320 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.bean.generator.IComponentGenerator;
|
||||
import org.alfresco.web.ui.repo.RepoConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class FacesHelper
|
||||
{
|
||||
/** Root browse screen JSF view ID */
|
||||
public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||
|
||||
private static Log logger = LogFactory.getLog(FacesHelper.class);
|
||||
|
||||
/**
|
||||
* Mask for hex encoding
|
||||
*/
|
||||
private static final int MASK = (1 << 4) - 1;
|
||||
|
||||
/**
|
||||
* Digits used for hex string encoding
|
||||
*/
|
||||
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private FacesHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context ServletContext
|
||||
* @param request ServletRequest
|
||||
* @param response ServletReponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(ServletRequest request, ServletResponse response, ServletContext context)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context ServletContext
|
||||
* @param request ServletRequest
|
||||
* @param response ServletReponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(ServletRequest request, ServletResponse response, ServletContext context, String viewRoot)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, viewRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context PortletContext
|
||||
* @param request PortletRequest
|
||||
* @param response PortletResponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(Object request, Object response, Object context)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet and Portlet use.
|
||||
*
|
||||
* @param context ServletContext or PortletContext
|
||||
* @param request ServletRequest or PortletRequest
|
||||
* @param response ServletReponse or PortletResponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
private static FacesContext getFacesContextImpl(Object request, Object response, Object context, String viewRoot)
|
||||
{
|
||||
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
|
||||
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
|
||||
FacesContext facesContext = contextFactory.getFacesContext(context, request, response, lifecycle);
|
||||
|
||||
// Set using our inner class
|
||||
InnerFacesContext.setFacesContextAsCurrent(facesContext);
|
||||
|
||||
// set a new viewRoot, otherwise context.getViewRoot returns null
|
||||
if (viewRoot == null)
|
||||
{
|
||||
viewRoot = FacesHelper.BROWSE_VIEW_ID;
|
||||
}
|
||||
|
||||
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, viewRoot);
|
||||
facesContext.setViewRoot(view);
|
||||
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSF managed bean reference.
|
||||
*
|
||||
* @param fc FacesContext
|
||||
* @param name Name of the managed bean to return
|
||||
*
|
||||
* @return the managed bean or null if not found
|
||||
*/
|
||||
public static Object getManagedBean(FacesContext fc, String name)
|
||||
{
|
||||
Object obj = null;
|
||||
|
||||
try
|
||||
{
|
||||
ValueBinding vb = fc.getApplication().createValueBinding("#{" + name + "}");
|
||||
obj = vb.getValue(fc);
|
||||
}
|
||||
catch (EvaluationException ee)
|
||||
{
|
||||
// catch exception to resolve ADB-158/ACT-7343
|
||||
// not much we can do here, just make sure return is null
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to resolve managed bean: " + name, ee);
|
||||
obj = null;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the id for the given component, if the id is null a unique one
|
||||
* is generated using the standard Faces algorithm. If an id is present it
|
||||
* is checked for illegal characters.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param component The component to set the id for
|
||||
* @param id The id to set
|
||||
*/
|
||||
public static void setupComponentId(FacesContext context, UIComponent component, String id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
id = context.getViewRoot().createUniqueId();
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we do not have illegal characters in the id
|
||||
id = makeLegalId(id);
|
||||
}
|
||||
|
||||
component.setId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given id a legal JSF component id by replacing illegal characters
|
||||
* with ISO9075 encoding - which itself a subset of valid HTML ID characters.
|
||||
*
|
||||
* @param id The id to make legal
|
||||
*
|
||||
* @return the legalised id
|
||||
*/
|
||||
public static String makeLegalId(String id)
|
||||
{
|
||||
return (id != null ? validFacesId(id) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the named component generator implementation.
|
||||
* If the named generator is not found the TextFieldGenerator is looked up
|
||||
* as a default, if this is also not found an AlfrescoRuntimeException is thrown.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param generatorName The name of the component generator to retrieve
|
||||
* @return The component generator instance
|
||||
*/
|
||||
public static IComponentGenerator getComponentGenerator(FacesContext context, String generatorName)
|
||||
{
|
||||
IComponentGenerator generator = lookupComponentGenerator(context, generatorName);
|
||||
|
||||
if (generator == null)
|
||||
{
|
||||
// create a text field if we can't find a component generator (a warning should have already been
|
||||
// displayed on the appserver console)
|
||||
|
||||
logger.warn("Attempting to find default component generator '" + RepoConstants.GENERATOR_TEXT_FIELD + "'");
|
||||
generator = lookupComponentGenerator(context, RepoConstants.GENERATOR_TEXT_FIELD);
|
||||
}
|
||||
|
||||
// if we still don't have a component generator we should abort as vital configuration is missing
|
||||
if (generator == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to find a component generator, please ensure the '" +
|
||||
RepoConstants.GENERATOR_TEXT_FIELD + "' bean is present in your configuration");
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
private static IComponentGenerator lookupComponentGenerator(FacesContext context, String generatorName)
|
||||
{
|
||||
IComponentGenerator generator = null;
|
||||
|
||||
Object obj = FacesHelper.getManagedBean(context, generatorName);
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj instanceof IComponentGenerator)
|
||||
{
|
||||
generator = (IComponentGenerator)obj;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found component generator for '" + generatorName + "': " + generator);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Bean '" + generatorName + "' does not implement IComponentGenerator");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Failed to find component generator with name of '" + generatorName + "'");
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need an inner class to be able to call FacesContext.setCurrentInstance
|
||||
* since it's a protected method
|
||||
*/
|
||||
private abstract static class InnerFacesContext extends FacesContext
|
||||
{
|
||||
protected static void setFacesContextAsCurrent(FacesContext facesContext)
|
||||
{
|
||||
FacesContext.setCurrentInstance(facesContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to ensure only valid and acceptable characters are output as Faces component IDs.
|
||||
* Based on ISO9075 encoding - which itself a subset of valid HTML ID characters.
|
||||
*/
|
||||
private static String validFacesId(String id)
|
||||
{
|
||||
int len = id.length();
|
||||
StringBuilder buf = new StringBuilder(len + (len>>1));
|
||||
for (int i = 0; i<len; i++)
|
||||
{
|
||||
char c = id.charAt(i);
|
||||
int ci = (int)c;
|
||||
if (i == 0)
|
||||
{
|
||||
if ((ci >= 65 && ci <= 90) || // A-Z
|
||||
(ci >= 97 && ci <= 122)) // a-z
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(c, buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ci >= 65 && ci <= 90) || // A-Z
|
||||
(ci >= 97 && ci <= 122) || // a-z
|
||||
(ci >= 48 && ci <= 57) || // 0-9
|
||||
ci == 45 || ci == 95) // - and _
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(c, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static void encode(char c, StringBuilder builder)
|
||||
{
|
||||
char[] buf = new char[] { 'x', '0', '0', '0', '0', '_' };
|
||||
int charPos = 5;
|
||||
do
|
||||
{
|
||||
buf[--charPos] = DIGITS[c & MASK];
|
||||
c >>>= 4;
|
||||
}
|
||||
while (c != 0);
|
||||
builder.append(buf);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.bean.generator.IComponentGenerator;
|
||||
import org.alfresco.web.ui.repo.RepoConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class FacesHelper
|
||||
{
|
||||
/** Root browse screen JSF view ID */
|
||||
public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||
|
||||
private static Log logger = LogFactory.getLog(FacesHelper.class);
|
||||
|
||||
/**
|
||||
* Mask for hex encoding
|
||||
*/
|
||||
private static final int MASK = (1 << 4) - 1;
|
||||
|
||||
/**
|
||||
* Digits used for hex string encoding
|
||||
*/
|
||||
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private FacesHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context ServletContext
|
||||
* @param request ServletRequest
|
||||
* @param response ServletReponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(ServletRequest request, ServletResponse response, ServletContext context)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context ServletContext
|
||||
* @param request ServletRequest
|
||||
* @param response ServletReponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(ServletRequest request, ServletResponse response, ServletContext context, String viewRoot)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, viewRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet use.
|
||||
*
|
||||
* @param context PortletContext
|
||||
* @param request PortletRequest
|
||||
* @param response PortletResponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
public static FacesContext getFacesContext(Object request, Object response, Object context)
|
||||
{
|
||||
return getFacesContextImpl(request, response, context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a valid FacesContext for the specific context, request and response.
|
||||
* The FacesContext can be constructor for Servlet and Portlet use.
|
||||
*
|
||||
* @param context ServletContext or PortletContext
|
||||
* @param request ServletRequest or PortletRequest
|
||||
* @param response ServletReponse or PortletResponse
|
||||
*
|
||||
* @return FacesContext
|
||||
*/
|
||||
private static FacesContext getFacesContextImpl(Object request, Object response, Object context, String viewRoot)
|
||||
{
|
||||
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
|
||||
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
|
||||
FacesContext facesContext = contextFactory.getFacesContext(context, request, response, lifecycle);
|
||||
|
||||
// Set using our inner class
|
||||
InnerFacesContext.setFacesContextAsCurrent(facesContext);
|
||||
|
||||
// set a new viewRoot, otherwise context.getViewRoot returns null
|
||||
if (viewRoot == null)
|
||||
{
|
||||
viewRoot = FacesHelper.BROWSE_VIEW_ID;
|
||||
}
|
||||
|
||||
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, viewRoot);
|
||||
facesContext.setViewRoot(view);
|
||||
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSF managed bean reference.
|
||||
*
|
||||
* @param fc FacesContext
|
||||
* @param name Name of the managed bean to return
|
||||
*
|
||||
* @return the managed bean or null if not found
|
||||
*/
|
||||
public static Object getManagedBean(FacesContext fc, String name)
|
||||
{
|
||||
Object obj = null;
|
||||
|
||||
try
|
||||
{
|
||||
ValueBinding vb = fc.getApplication().createValueBinding("#{" + name + "}");
|
||||
obj = vb.getValue(fc);
|
||||
}
|
||||
catch (EvaluationException ee)
|
||||
{
|
||||
// catch exception to resolve ADB-158/ACT-7343
|
||||
// not much we can do here, just make sure return is null
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Failed to resolve managed bean: " + name, ee);
|
||||
obj = null;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the id for the given component, if the id is null a unique one
|
||||
* is generated using the standard Faces algorithm. If an id is present it
|
||||
* is checked for illegal characters.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param component The component to set the id for
|
||||
* @param id The id to set
|
||||
*/
|
||||
public static void setupComponentId(FacesContext context, UIComponent component, String id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
id = context.getViewRoot().createUniqueId();
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we do not have illegal characters in the id
|
||||
id = makeLegalId(id);
|
||||
}
|
||||
|
||||
component.setId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given id a legal JSF component id by replacing illegal characters
|
||||
* with ISO9075 encoding - which itself a subset of valid HTML ID characters.
|
||||
*
|
||||
* @param id The id to make legal
|
||||
*
|
||||
* @return the legalised id
|
||||
*/
|
||||
public static String makeLegalId(String id)
|
||||
{
|
||||
return (id != null ? validFacesId(id) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the named component generator implementation.
|
||||
* If the named generator is not found the TextFieldGenerator is looked up
|
||||
* as a default, if this is also not found an AlfrescoRuntimeException is thrown.
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param generatorName The name of the component generator to retrieve
|
||||
* @return The component generator instance
|
||||
*/
|
||||
public static IComponentGenerator getComponentGenerator(FacesContext context, String generatorName)
|
||||
{
|
||||
IComponentGenerator generator = lookupComponentGenerator(context, generatorName);
|
||||
|
||||
if (generator == null)
|
||||
{
|
||||
// create a text field if we can't find a component generator (a warning should have already been
|
||||
// displayed on the appserver console)
|
||||
|
||||
logger.warn("Attempting to find default component generator '" + RepoConstants.GENERATOR_TEXT_FIELD + "'");
|
||||
generator = lookupComponentGenerator(context, RepoConstants.GENERATOR_TEXT_FIELD);
|
||||
}
|
||||
|
||||
// if we still don't have a component generator we should abort as vital configuration is missing
|
||||
if (generator == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to find a component generator, please ensure the '" +
|
||||
RepoConstants.GENERATOR_TEXT_FIELD + "' bean is present in your configuration");
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
private static IComponentGenerator lookupComponentGenerator(FacesContext context, String generatorName)
|
||||
{
|
||||
IComponentGenerator generator = null;
|
||||
|
||||
Object obj = FacesHelper.getManagedBean(context, generatorName);
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj instanceof IComponentGenerator)
|
||||
{
|
||||
generator = (IComponentGenerator)obj;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found component generator for '" + generatorName + "': " + generator);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Bean '" + generatorName + "' does not implement IComponentGenerator");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Failed to find component generator with name of '" + generatorName + "'");
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need an inner class to be able to call FacesContext.setCurrentInstance
|
||||
* since it's a protected method
|
||||
*/
|
||||
private abstract static class InnerFacesContext extends FacesContext
|
||||
{
|
||||
protected static void setFacesContextAsCurrent(FacesContext facesContext)
|
||||
{
|
||||
FacesContext.setCurrentInstance(facesContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to ensure only valid and acceptable characters are output as Faces component IDs.
|
||||
* Based on ISO9075 encoding - which itself a subset of valid HTML ID characters.
|
||||
*/
|
||||
private static String validFacesId(String id)
|
||||
{
|
||||
int len = id.length();
|
||||
StringBuilder buf = new StringBuilder(len + (len>>1));
|
||||
for (int i = 0; i<len; i++)
|
||||
{
|
||||
char c = id.charAt(i);
|
||||
int ci = (int)c;
|
||||
if (i == 0)
|
||||
{
|
||||
if ((ci >= 65 && ci <= 90) || // A-Z
|
||||
(ci >= 97 && ci <= 122)) // a-z
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(c, buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ci >= 65 && ci <= 90) || // A-Z
|
||||
(ci >= 97 && ci <= 122) || // a-z
|
||||
(ci >= 48 && ci <= 57) || // 0-9
|
||||
ci == 45 || ci == 95) // - and _
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(c, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static void encode(char c, StringBuilder builder)
|
||||
{
|
||||
char[] buf = new char[] { 'x', '0', '0', '0', '0', '_' };
|
||||
int charPos = 5;
|
||||
do
|
||||
{
|
||||
buf[--charPos] = DIGITS[c & MASK];
|
||||
c >>>= 4;
|
||||
}
|
||||
while (c != 0);
|
||||
builder.append(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +1,130 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming node content from the repo directly to the response stream.
|
||||
* The appropriate mimetype is calculated based on filename extension.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/guestDownload/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/guestDownload/direct/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/guestDownload/[direct|attach]?path=/Company%20Home/MyFolder/myfile.pdf</pre>
|
||||
* The protocol, followed by either the store and Id (NodeRef) or instead specify a name based
|
||||
* encoded Path to the content, note that the filename element is used for mimetype lookup and
|
||||
* as the returning filename for the response stream.
|
||||
* <p>
|
||||
* The 'attach' or 'direct' element is used to indicate whether to display the stream directly
|
||||
* in the browser or download it as a file attachment.
|
||||
* <p>
|
||||
* By default, the download assumes that the content is on the
|
||||
* {@link org.alfresco.model.ContentModel#PROP_CONTENT content property}.<br>
|
||||
* To retrieve the content of a specific model property, use a 'property' arg, providing the workspace,
|
||||
* node ID AND the qualified name of the property.
|
||||
* <p>
|
||||
* This servlet only accesses content available to the guest user. If the guest user does not
|
||||
* have access to the requested a 403 Forbidden response is returned to the caller.
|
||||
* <p>
|
||||
* This servlet does not effect the current session, therefore if guest access is required to a
|
||||
* resource this servlet can be used without logging out the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class GuestDownloadContentServlet extends BaseDownloadContentServlet
|
||||
{
|
||||
private static final long serialVersionUID = -5258137503339817457L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(GuestDownloadContentServlet.class);
|
||||
|
||||
private static final String DOWNLOAD_URL = "/gd/" + URL_ATTACH + "/{0}/{1}/{2}/{3}";
|
||||
private static final String BROWSER_URL = "/gd/" + URL_DIRECT + "/{0}/{1}/{2}/{3}";
|
||||
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Setting up guest access to URL: " + req.getRequestURI() +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
DownloadContentWork dcw = new DownloadContentWork(req, res);
|
||||
AuthenticationUtil.runAs(dcw, AuthenticationUtil.getGuestUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
* The content is supplied as an HTTP1.1 attachment to the response. This generally means
|
||||
* a browser should prompt the user to save the content to specified location.
|
||||
*
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
public final static String generateDownloadURL(NodeRef ref, String name)
|
||||
{
|
||||
return generateUrl(DOWNLOAD_URL, ref, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
* The content is supplied directly in the reponse. This generally means a browser will
|
||||
* attempt to open the content directly if possible, else it will prompt to save the file.
|
||||
*
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
public final static String generateBrowserURL(NodeRef ref, String name)
|
||||
{
|
||||
return generateUrl(BROWSER_URL, ref, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to wrap the call to processDownloadRequest.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DownloadContentWork implements RunAsWork<Object>
|
||||
{
|
||||
private HttpServletRequest req = null;
|
||||
private HttpServletResponse res = null;
|
||||
|
||||
public DownloadContentWork(HttpServletRequest req, HttpServletResponse res)
|
||||
{
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
processDownloadRequest(this.req, this.res, false, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming node content from the repo directly to the response stream.
|
||||
* The appropriate mimetype is calculated based on filename extension.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/guestDownload/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/guestDownload/direct/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/guestDownload/[direct|attach]?path=/Company%20Home/MyFolder/myfile.pdf</pre>
|
||||
* The protocol, followed by either the store and Id (NodeRef) or instead specify a name based
|
||||
* encoded Path to the content, note that the filename element is used for mimetype lookup and
|
||||
* as the returning filename for the response stream.
|
||||
* <p>
|
||||
* The 'attach' or 'direct' element is used to indicate whether to display the stream directly
|
||||
* in the browser or download it as a file attachment.
|
||||
* <p>
|
||||
* By default, the download assumes that the content is on the
|
||||
* {@link org.alfresco.model.ContentModel#PROP_CONTENT content property}.<br>
|
||||
* To retrieve the content of a specific model property, use a 'property' arg, providing the workspace,
|
||||
* node ID AND the qualified name of the property.
|
||||
* <p>
|
||||
* This servlet only accesses content available to the guest user. If the guest user does not
|
||||
* have access to the requested a 403 Forbidden response is returned to the caller.
|
||||
* <p>
|
||||
* This servlet does not effect the current session, therefore if guest access is required to a
|
||||
* resource this servlet can be used without logging out the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class GuestDownloadContentServlet extends BaseDownloadContentServlet
|
||||
{
|
||||
private static final long serialVersionUID = -5258137503339817457L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(GuestDownloadContentServlet.class);
|
||||
|
||||
private static final String DOWNLOAD_URL = "/gd/" + URL_ATTACH + "/{0}/{1}/{2}/{3}";
|
||||
private static final String BROWSER_URL = "/gd/" + URL_DIRECT + "/{0}/{1}/{2}/{3}";
|
||||
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Setting up guest access to URL: " + req.getRequestURI() +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
DownloadContentWork dcw = new DownloadContentWork(req, res);
|
||||
AuthenticationUtil.runAs(dcw, AuthenticationUtil.getGuestUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
* The content is supplied as an HTTP1.1 attachment to the response. This generally means
|
||||
* a browser should prompt the user to save the content to specified location.
|
||||
*
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
public final static String generateDownloadURL(NodeRef ref, String name)
|
||||
{
|
||||
return generateUrl(DOWNLOAD_URL, ref, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to a content node for downloading content from the server.
|
||||
* The content is supplied directly in the reponse. This generally means a browser will
|
||||
* attempt to open the content directly if possible, else it will prompt to save the file.
|
||||
*
|
||||
* @param ref NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param name File name to return in the URL (cannot be null)
|
||||
*
|
||||
* @return URL to download the content from the specified node
|
||||
*/
|
||||
public final static String generateBrowserURL(NodeRef ref, String name)
|
||||
{
|
||||
return generateUrl(BROWSER_URL, ref, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to wrap the call to processDownloadRequest.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DownloadContentWork implements RunAsWork<Object>
|
||||
{
|
||||
private HttpServletRequest req = null;
|
||||
private HttpServletResponse res = null;
|
||||
|
||||
public DownloadContentWork(HttpServletRequest req, HttpServletResponse res)
|
||||
{
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
processDownloadRequest(this.req, this.res, false, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,171 +1,171 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming content from a template processed against a node directly
|
||||
* to the response stream.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/template/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* or
|
||||
* <pre>/alfresco/template/workspace/SpacesStore/0000-0000-0000-0000/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* or
|
||||
* <pre>/alfresco/template?templatePath=/Company%20Home/Data%20Dictionary/Presentation%20Templates/doc_info.ftl&contextPath=/Company%20Home/mydoc.txt</pre>
|
||||
* <p>
|
||||
* The store protocol, followed by the store ID, followed by the content Node Id used to
|
||||
* identify the node to execute the default template for. The second set of elements encode
|
||||
* the store and node Id of the template to used if a default is not set or not requested. Instead
|
||||
* of using NodeRef references to the template and context, path arguments can be used. The URL args
|
||||
* of 'templatePath' and 'contextPath' can be used instead to specify name based encoded Paths to the
|
||||
* template and its context.
|
||||
* <p>
|
||||
* The URL may be followed by a 'mimetype' argument specifying the mimetype to return the result as
|
||||
* on the stream. Otherwise it is assumed that HTML is the default response mimetype.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* And/or also followed by the "?guest=true" argument to force guest access login for the URL. If the
|
||||
* guest=true parameter is used the current session will be logged out and the guest user logged in.
|
||||
* Therefore upon completion of this request the current user will be "guest".
|
||||
* <p>
|
||||
* This servlet only accesses content available to the guest user. If the guest user does not
|
||||
* have access to the requested a 401 Forbidden response is returned to the caller.
|
||||
* <p>
|
||||
* This servlet does not effect the current session, therefore if guest access is required to a
|
||||
* resource this servlet can be used without logging out the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class GuestTemplateContentServlet extends BaseTemplateContentServlet
|
||||
{
|
||||
private static final long serialVersionUID = -2510767849932627519L;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(GuestTemplateContentServlet.class);
|
||||
|
||||
private static final String DEFAULT_URL = "/guestTemplate/{0}/{1}/{2}";
|
||||
private static final String TEMPLATE_URL = "/guestTemplate/{0}/{1}/{2}/{3}/{4}/{5}";
|
||||
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> buildModel(ServiceRegistry services, HttpServletRequest req,
|
||||
NodeRef templateRef)
|
||||
{
|
||||
// setup the guest user to pass to the build model helper method
|
||||
AuthenticationService auth = (AuthenticationService)services.getAuthenticationService();
|
||||
PersonService personService = (PersonService)services.getPersonService();
|
||||
NodeService nodeService = (NodeService)services.getNodeService();
|
||||
|
||||
NodeRef guestRef = personService.getPerson(AuthenticationUtil.getGuestUserName());
|
||||
User guestUser = new User(AuthenticationUtil.getGuestUserName(), auth.getCurrentTicket(), guestRef);
|
||||
NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
|
||||
if (nodeService.exists(guestHomeRef) == false)
|
||||
{
|
||||
throw new InvalidNodeRefException(guestHomeRef);
|
||||
}
|
||||
guestUser.setHomeSpaceId(guestHomeRef.getId());
|
||||
|
||||
// build the default model
|
||||
return DefaultModelHelper.buildDefaultModel(services, guestUser, templateRef, this.imageResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Setting up guest access to URL: " + req.getRequestURI() +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
TemplateContentWork tcw = new TemplateContentWork(req, res);
|
||||
AuthenticationUtil.runAs(tcw, AuthenticationUtil.getGuestUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to process a template against a node.
|
||||
* <p>
|
||||
* The result of the template is supplied returned as the response.
|
||||
*
|
||||
* @param nodeRef NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param templateRef NodeRef of the template to process against, or null to use default
|
||||
*
|
||||
* @return URL to process the template
|
||||
*/
|
||||
public final static String generateURL(NodeRef nodeRef, NodeRef templateRef)
|
||||
{
|
||||
if (templateRef == null)
|
||||
{
|
||||
return MessageFormat.format(DEFAULT_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId() } );
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(TEMPLATE_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
templateRef.getStoreRef().getProtocol(),
|
||||
templateRef.getStoreRef().getIdentifier(),
|
||||
templateRef.getId()} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to wrap the call to processTemplateRequest.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class TemplateContentWork implements RunAsWork<Object>
|
||||
{
|
||||
private HttpServletRequest req = null;
|
||||
private HttpServletResponse res = null;
|
||||
|
||||
public TemplateContentWork(HttpServletRequest req, HttpServletResponse res)
|
||||
{
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
processTemplateRequest(this.req, this.res, false);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming content from a template processed against a node directly
|
||||
* to the response stream.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/template/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* or
|
||||
* <pre>/alfresco/template/workspace/SpacesStore/0000-0000-0000-0000/workspace/SpacesStore/0000-0000-0000-0000</pre>
|
||||
* or
|
||||
* <pre>/alfresco/template?templatePath=/Company%20Home/Data%20Dictionary/Presentation%20Templates/doc_info.ftl&contextPath=/Company%20Home/mydoc.txt</pre>
|
||||
* <p>
|
||||
* The store protocol, followed by the store ID, followed by the content Node Id used to
|
||||
* identify the node to execute the default template for. The second set of elements encode
|
||||
* the store and node Id of the template to used if a default is not set or not requested. Instead
|
||||
* of using NodeRef references to the template and context, path arguments can be used. The URL args
|
||||
* of 'templatePath' and 'contextPath' can be used instead to specify name based encoded Paths to the
|
||||
* template and its context.
|
||||
* <p>
|
||||
* The URL may be followed by a 'mimetype' argument specifying the mimetype to return the result as
|
||||
* on the stream. Otherwise it is assumed that HTML is the default response mimetype.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* And/or also followed by the "?guest=true" argument to force guest access login for the URL. If the
|
||||
* guest=true parameter is used the current session will be logged out and the guest user logged in.
|
||||
* Therefore upon completion of this request the current user will be "guest".
|
||||
* <p>
|
||||
* This servlet only accesses content available to the guest user. If the guest user does not
|
||||
* have access to the requested a 401 Forbidden response is returned to the caller.
|
||||
* <p>
|
||||
* This servlet does not effect the current session, therefore if guest access is required to a
|
||||
* resource this servlet can be used without logging out the current user.
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class GuestTemplateContentServlet extends BaseTemplateContentServlet
|
||||
{
|
||||
private static final long serialVersionUID = -2510767849932627519L;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(GuestTemplateContentServlet.class);
|
||||
|
||||
private static final String DEFAULT_URL = "/guestTemplate/{0}/{1}/{2}";
|
||||
private static final String TEMPLATE_URL = "/guestTemplate/{0}/{1}/{2}/{3}/{4}/{5}";
|
||||
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> buildModel(ServiceRegistry services, HttpServletRequest req,
|
||||
NodeRef templateRef)
|
||||
{
|
||||
// setup the guest user to pass to the build model helper method
|
||||
AuthenticationService auth = (AuthenticationService)services.getAuthenticationService();
|
||||
PersonService personService = (PersonService)services.getPersonService();
|
||||
NodeService nodeService = (NodeService)services.getNodeService();
|
||||
|
||||
NodeRef guestRef = personService.getPerson(AuthenticationUtil.getGuestUserName());
|
||||
User guestUser = new User(AuthenticationUtil.getGuestUserName(), auth.getCurrentTicket(), guestRef);
|
||||
NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
|
||||
if (nodeService.exists(guestHomeRef) == false)
|
||||
{
|
||||
throw new InvalidNodeRefException(guestHomeRef);
|
||||
}
|
||||
guestUser.setHomeSpaceId(guestHomeRef.getId());
|
||||
|
||||
// build the default model
|
||||
return DefaultModelHelper.buildDefaultModel(services, guestUser, templateRef, this.imageResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(HttpServletRequest req, HttpServletResponse res)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Setting up guest access to URL: " + req.getRequestURI() +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
TemplateContentWork tcw = new TemplateContentWork(req, res);
|
||||
AuthenticationUtil.runAs(tcw, AuthenticationUtil.getGuestUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a URL to process a template against a node.
|
||||
* <p>
|
||||
* The result of the template is supplied returned as the response.
|
||||
*
|
||||
* @param nodeRef NodeRef of the content node to generate URL for (cannot be null)
|
||||
* @param templateRef NodeRef of the template to process against, or null to use default
|
||||
*
|
||||
* @return URL to process the template
|
||||
*/
|
||||
public final static String generateURL(NodeRef nodeRef, NodeRef templateRef)
|
||||
{
|
||||
if (templateRef == null)
|
||||
{
|
||||
return MessageFormat.format(DEFAULT_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId() } );
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(TEMPLATE_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
templateRef.getStoreRef().getProtocol(),
|
||||
templateRef.getStoreRef().getIdentifier(),
|
||||
templateRef.getId()} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to wrap the call to processTemplateRequest.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class TemplateContentWork implements RunAsWork<Object>
|
||||
{
|
||||
private HttpServletRequest req = null;
|
||||
private HttpServletResponse res = null;
|
||||
|
||||
public TemplateContentWork(HttpServletRequest req, HttpServletResponse res)
|
||||
{
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
processTemplateRequest(this.req, this.res, false);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,146 +1,146 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.UnavailableException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.fileupload.DiskFileUpload;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileUpload;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Servlet for handling process deployments from jBPM process designer.
|
||||
*
|
||||
* @author davidc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class JBPMDeployProcessServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 8002539291245090187L;
|
||||
private static final String BEAN_GLOBAL_PROPERTIES = "global-properties";
|
||||
private static final String PROP_ENABLED = "system.workflow.deployservlet.enabled";
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException
|
||||
{
|
||||
// Render this servlet permanently unavailable if its enablement property is not set
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
||||
Properties globalProperties = (Properties) wc.getBean(BEAN_GLOBAL_PROPERTIES);
|
||||
String enabled = globalProperties.getProperty(PROP_ENABLED);
|
||||
if (!PropertyCheck.isValidPropertyString(enabled) || !Boolean.parseBoolean(enabled))
|
||||
{
|
||||
throw new UnavailableException("system.workflow.deployservlet.enabled=false");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
response.setContentType("text/html");
|
||||
InputStream deploymentArchive = getDeploymentArchive(request);
|
||||
WorkflowDefinition workflowDef = deployArchive(deploymentArchive);
|
||||
response.getWriter().println("Deployed archive " + workflowDef.title + " successfully");
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
// NOTE: according to original jBPM deployment servlet
|
||||
response.getWriter().println("IOException");
|
||||
}
|
||||
catch(FileUploadException e)
|
||||
{
|
||||
// NOTE: according to original jBPM deployment servlet
|
||||
response.getWriter().println("FileUploadException");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the JBPM Process Designer deployment archive from the request
|
||||
*
|
||||
* @param request the request
|
||||
* @return the input stream onto the deployment archive
|
||||
* @throws WorkflowException
|
||||
* @throws FileUploadException
|
||||
* @throws IOException
|
||||
*/
|
||||
private InputStream getDeploymentArchive(HttpServletRequest request)
|
||||
throws FileUploadException, IOException
|
||||
{
|
||||
if (!FileUpload.isMultipartContent(request))
|
||||
{
|
||||
throw new FileUploadException("Not a multipart request");
|
||||
}
|
||||
|
||||
GPDUpload fileUpload = new GPDUpload();
|
||||
List list = fileUpload.parseRequest(request);
|
||||
Iterator iterator = list.iterator();
|
||||
if (!iterator.hasNext())
|
||||
{
|
||||
throw new FileUploadException("No process file in the request");
|
||||
}
|
||||
|
||||
FileItem fileItem = (FileItem) iterator.next();
|
||||
if (fileItem.getContentType().indexOf("application/x-zip-compressed") == -1)
|
||||
{
|
||||
throw new FileUploadException("Not a process archive");
|
||||
}
|
||||
|
||||
return fileItem.getInputStream();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deploy the jBPM process archive to the Alfresco Repository
|
||||
*
|
||||
* @param deploymentArchive the archive to deploy
|
||||
* @return the deployed workflow definition
|
||||
*/
|
||||
private WorkflowDefinition deployArchive(InputStream deploymentArchive)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
||||
WorkflowService workflowService = (WorkflowService)wc.getBean(ServiceRegistry.WORKFLOW_SERVICE.getLocalName());
|
||||
WorkflowDeployment deployment = workflowService.deployDefinition(JBPMEngine.ENGINE_ID, deploymentArchive, MimetypeMap.MIMETYPE_ZIP);
|
||||
return deployment.definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: Workaround...
|
||||
*
|
||||
* The JBPM process designer (as of 3.1.2) issues a request with a multi-part line
|
||||
* delimited by ",". It should be ":" according to the HTTP specification which
|
||||
* the commons file-upload is adhering to.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private class GPDUpload extends DiskFileUpload
|
||||
{
|
||||
@Override
|
||||
protected byte[] getBoundary(String contentType)
|
||||
{
|
||||
return super.getBoundary(contentType.replace(",", ";"));
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.UnavailableException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.fileupload.DiskFileUpload;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileUpload;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Servlet for handling process deployments from jBPM process designer.
|
||||
*
|
||||
* @author davidc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class JBPMDeployProcessServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 8002539291245090187L;
|
||||
private static final String BEAN_GLOBAL_PROPERTIES = "global-properties";
|
||||
private static final String PROP_ENABLED = "system.workflow.deployservlet.enabled";
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException
|
||||
{
|
||||
// Render this servlet permanently unavailable if its enablement property is not set
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
||||
Properties globalProperties = (Properties) wc.getBean(BEAN_GLOBAL_PROPERTIES);
|
||||
String enabled = globalProperties.getProperty(PROP_ENABLED);
|
||||
if (!PropertyCheck.isValidPropertyString(enabled) || !Boolean.parseBoolean(enabled))
|
||||
{
|
||||
throw new UnavailableException("system.workflow.deployservlet.enabled=false");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
response.setContentType("text/html");
|
||||
InputStream deploymentArchive = getDeploymentArchive(request);
|
||||
WorkflowDefinition workflowDef = deployArchive(deploymentArchive);
|
||||
response.getWriter().println("Deployed archive " + workflowDef.title + " successfully");
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
// NOTE: according to original jBPM deployment servlet
|
||||
response.getWriter().println("IOException");
|
||||
}
|
||||
catch(FileUploadException e)
|
||||
{
|
||||
// NOTE: according to original jBPM deployment servlet
|
||||
response.getWriter().println("FileUploadException");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the JBPM Process Designer deployment archive from the request
|
||||
*
|
||||
* @param request the request
|
||||
* @return the input stream onto the deployment archive
|
||||
* @throws WorkflowException
|
||||
* @throws FileUploadException
|
||||
* @throws IOException
|
||||
*/
|
||||
private InputStream getDeploymentArchive(HttpServletRequest request)
|
||||
throws FileUploadException, IOException
|
||||
{
|
||||
if (!FileUpload.isMultipartContent(request))
|
||||
{
|
||||
throw new FileUploadException("Not a multipart request");
|
||||
}
|
||||
|
||||
GPDUpload fileUpload = new GPDUpload();
|
||||
List list = fileUpload.parseRequest(request);
|
||||
Iterator iterator = list.iterator();
|
||||
if (!iterator.hasNext())
|
||||
{
|
||||
throw new FileUploadException("No process file in the request");
|
||||
}
|
||||
|
||||
FileItem fileItem = (FileItem) iterator.next();
|
||||
if (fileItem.getContentType().indexOf("application/x-zip-compressed") == -1)
|
||||
{
|
||||
throw new FileUploadException("Not a process archive");
|
||||
}
|
||||
|
||||
return fileItem.getInputStream();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deploy the jBPM process archive to the Alfresco Repository
|
||||
*
|
||||
* @param deploymentArchive the archive to deploy
|
||||
* @return the deployed workflow definition
|
||||
*/
|
||||
private WorkflowDefinition deployArchive(InputStream deploymentArchive)
|
||||
{
|
||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
||||
WorkflowService workflowService = (WorkflowService)wc.getBean(ServiceRegistry.WORKFLOW_SERVICE.getLocalName());
|
||||
WorkflowDeployment deployment = workflowService.deployDefinition(JBPMEngine.ENGINE_ID, deploymentArchive, MimetypeMap.MIMETYPE_ZIP);
|
||||
return deployment.definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: Workaround...
|
||||
*
|
||||
* The JBPM process designer (as of 3.1.2) issues a request with a multi-part line
|
||||
* delimited by ",". It should be ":" according to the HTTP specification which
|
||||
* the commons file-upload is adhering to.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private class GPDUpload extends DiskFileUpload
|
||||
{
|
||||
@Override
|
||||
protected byte[] getBoundary(String contentType)
|
||||
{
|
||||
return super.getBoundary(contentType.replace(",", ";"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,259 +1,259 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming content directly into the repository from the PUT request.
|
||||
* The appropriate mimetype is calculated based on filename extension.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/upload/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/upload/myfile.pdf</pre>
|
||||
* <p>
|
||||
* If the store and node id are specified in the URL then the content provided will be streamed onto the node
|
||||
* using an updating writer, updating the content property value accordingly.
|
||||
* <p>
|
||||
* If only the file name is specified the content will be streamed into the content store and the content data
|
||||
* will be returned in the reposonse. This can then be used to update the value of a content property manually.
|
||||
* Any used content will be cleared up in the usual manner.
|
||||
* <p>
|
||||
* By default, the download assumes that the content is on the
|
||||
* {@link org.alfresco.model.ContentModel#PROP_CONTENT content property}.<br>
|
||||
* To set the content of a specific model property, use a 'property' arg, providing the qualified name of the property.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* Guest access is currently disabled for this servlet.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class UploadContentServlet extends BaseServlet
|
||||
{
|
||||
/** Serial version UID */
|
||||
private static final long serialVersionUID = 1055960980867420355L;
|
||||
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(UploadContentServlet.class);
|
||||
|
||||
/** Default mime type */
|
||||
protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
/** Argument properties */
|
||||
protected static final String ARG_PROPERTY = "property";
|
||||
protected static final String ARG_MIMETYPE = "mimetype";
|
||||
protected static final String ARG_ENCODING = "encoding";
|
||||
protected static final String ARG_LOCALE = "locale";
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Authenticating request to URL: " + req.getRequestURI()
|
||||
+ ((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
AuthenticationStatus status = servletAuthenticate(req, res, false);
|
||||
if (status == AuthenticationStatus.Failure || status == AuthenticationStatus.Guest)
|
||||
{
|
||||
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tokenise the URI
|
||||
String uri = req.getRequestURI();
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// get or calculate the noderef and filename to download as
|
||||
NodeRef nodeRef = null;
|
||||
String filename = null;
|
||||
QName propertyQName = null;
|
||||
|
||||
if (tokenCount == 2)
|
||||
{
|
||||
// filename is the only token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
else if (tokenCount == 4 || tokenCount == 5)
|
||||
{
|
||||
// assume 'workspace' or other NodeRef based protocol for remaining URL
|
||||
// elements
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
String id = t.nextToken();
|
||||
// build noderef from the appropriate URL elements
|
||||
nodeRef = new NodeRef(storeRef, id);
|
||||
|
||||
if (tokenCount == 5)
|
||||
{
|
||||
// filename is last remaining token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
|
||||
// get qualified of the property to get content from - default to
|
||||
// ContentModel.PROP_CONTENT
|
||||
propertyQName = ContentModel.PROP_CONTENT;
|
||||
String property = req.getParameter(ARG_PROPERTY);
|
||||
if (property != null && property.length() != 0)
|
||||
{
|
||||
propertyQName = QName.createQName(property);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug("Upload URL did not contain all required args: " + uri);
|
||||
res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
ContentService contentService = serviceRegistry.getContentService();
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
MimetypeService mimetypeService = serviceRegistry.getMimetypeService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
|
||||
InputStream is = req.getInputStream();
|
||||
BufferedInputStream inputStream = new BufferedInputStream(is);
|
||||
|
||||
// Sort out the mimetype
|
||||
String mimetype = req.getParameter(ARG_MIMETYPE);
|
||||
if (mimetype == null || mimetype.length() == 0)
|
||||
{
|
||||
mimetype = MIMETYPE_OCTET_STREAM;
|
||||
if (filename != null)
|
||||
{
|
||||
MimetypeService mimetypeMap = serviceRegistry.getMimetypeService();
|
||||
int extIndex = filename.lastIndexOf('.');
|
||||
if (extIndex != -1)
|
||||
{
|
||||
String ext = filename.substring(extIndex + 1);
|
||||
mimetype = mimetypeService.getMimetype(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the encoding
|
||||
String encoding = req.getParameter(ARG_ENCODING);
|
||||
if (encoding == null || encoding.length() == 0)
|
||||
{
|
||||
// Get the encoding
|
||||
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
|
||||
Charset charset = charsetFinder.getCharset(inputStream, mimetype);
|
||||
encoding = charset.name();
|
||||
}
|
||||
|
||||
// Get the locale
|
||||
Locale locale = I18NUtil.parseLocale(req.getParameter(ARG_LOCALE));
|
||||
if (locale == null)
|
||||
{
|
||||
locale = I18NUtil.getContentLocale();
|
||||
if (nodeRef != null)
|
||||
{
|
||||
ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (contentData != null)
|
||||
{
|
||||
locale = contentData.getLocale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
if (nodeRef != null) {logger.debug("Found NodeRef: " + nodeRef.toString());}
|
||||
logger.debug("For property: " + propertyQName);
|
||||
logger.debug("File name: " + filename);
|
||||
logger.debug("Mimetype: " + mimetype);
|
||||
logger.debug("Encoding: " + encoding);
|
||||
logger.debug("Locale: " + locale);
|
||||
}
|
||||
|
||||
// Check that the user has the permissions to write the content
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.WRITE_CONTENT) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("User does not have permissions to wrtie content for NodeRef: " + nodeRef.toString());
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
}
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try and get the content writer
|
||||
ContentWriter writer = contentService.getWriter(nodeRef, propertyQName, true);
|
||||
if (writer == null)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Content writer cannot be obtained for NodeRef: " + nodeRef.toString());
|
||||
}
|
||||
res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the mimetype, encoding and locale
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding(encoding);
|
||||
if (locale != null)
|
||||
{
|
||||
writer.setLocale(locale);
|
||||
}
|
||||
|
||||
// Stream the content into the repository
|
||||
writer.putContent(inputStream);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Content details: " + writer.getContentData().toString());
|
||||
}
|
||||
|
||||
// Set return status
|
||||
res.getWriter().write(writer.getContentData().toString());
|
||||
res.flushBuffer();
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("UploadContentServlet done");
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Servlet responsible for streaming content directly into the repository from the PUT request.
|
||||
* The appropriate mimetype is calculated based on filename extension.
|
||||
* <p>
|
||||
* The URL to the servlet should be generated thus:
|
||||
* <pre>/alfresco/upload/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf</pre>
|
||||
* or
|
||||
* <pre>/alfresco/upload/myfile.pdf</pre>
|
||||
* <p>
|
||||
* If the store and node id are specified in the URL then the content provided will be streamed onto the node
|
||||
* using an updating writer, updating the content property value accordingly.
|
||||
* <p>
|
||||
* If only the file name is specified the content will be streamed into the content store and the content data
|
||||
* will be returned in the reposonse. This can then be used to update the value of a content property manually.
|
||||
* Any used content will be cleared up in the usual manner.
|
||||
* <p>
|
||||
* By default, the download assumes that the content is on the
|
||||
* {@link org.alfresco.model.ContentModel#PROP_CONTENT content property}.<br>
|
||||
* To set the content of a specific model property, use a 'property' arg, providing the qualified name of the property.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
* <p>
|
||||
* Guest access is currently disabled for this servlet.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class UploadContentServlet extends BaseServlet
|
||||
{
|
||||
/** Serial version UID */
|
||||
private static final long serialVersionUID = 1055960980867420355L;
|
||||
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(UploadContentServlet.class);
|
||||
|
||||
/** Default mime type */
|
||||
protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
/** Argument properties */
|
||||
protected static final String ARG_PROPERTY = "property";
|
||||
protected static final String ARG_MIMETYPE = "mimetype";
|
||||
protected static final String ARG_ENCODING = "encoding";
|
||||
protected static final String ARG_LOCALE = "locale";
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
String queryString = req.getQueryString();
|
||||
logger.debug("Authenticating request to URL: " + req.getRequestURI()
|
||||
+ ((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
AuthenticationStatus status = servletAuthenticate(req, res, false);
|
||||
if (status == AuthenticationStatus.Failure || status == AuthenticationStatus.Guest)
|
||||
{
|
||||
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tokenise the URI
|
||||
String uri = req.getRequestURI();
|
||||
uri = uri.substring(req.getContextPath().length());
|
||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
|
||||
t.nextToken(); // skip servlet name
|
||||
|
||||
// get or calculate the noderef and filename to download as
|
||||
NodeRef nodeRef = null;
|
||||
String filename = null;
|
||||
QName propertyQName = null;
|
||||
|
||||
if (tokenCount == 2)
|
||||
{
|
||||
// filename is the only token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
else if (tokenCount == 4 || tokenCount == 5)
|
||||
{
|
||||
// assume 'workspace' or other NodeRef based protocol for remaining URL
|
||||
// elements
|
||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||
String id = t.nextToken();
|
||||
// build noderef from the appropriate URL elements
|
||||
nodeRef = new NodeRef(storeRef, id);
|
||||
|
||||
if (tokenCount == 5)
|
||||
{
|
||||
// filename is last remaining token
|
||||
filename = t.nextToken();
|
||||
}
|
||||
|
||||
// get qualified of the property to get content from - default to
|
||||
// ContentModel.PROP_CONTENT
|
||||
propertyQName = ContentModel.PROP_CONTENT;
|
||||
String property = req.getParameter(ARG_PROPERTY);
|
||||
if (property != null && property.length() != 0)
|
||||
{
|
||||
propertyQName = QName.createQName(property);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug("Upload URL did not contain all required args: " + uri);
|
||||
res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the services we need to retrieve the content
|
||||
ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext());
|
||||
ContentService contentService = serviceRegistry.getContentService();
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
MimetypeService mimetypeService = serviceRegistry.getMimetypeService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
|
||||
InputStream is = req.getInputStream();
|
||||
BufferedInputStream inputStream = new BufferedInputStream(is);
|
||||
|
||||
// Sort out the mimetype
|
||||
String mimetype = req.getParameter(ARG_MIMETYPE);
|
||||
if (mimetype == null || mimetype.length() == 0)
|
||||
{
|
||||
mimetype = MIMETYPE_OCTET_STREAM;
|
||||
if (filename != null)
|
||||
{
|
||||
MimetypeService mimetypeMap = serviceRegistry.getMimetypeService();
|
||||
int extIndex = filename.lastIndexOf('.');
|
||||
if (extIndex != -1)
|
||||
{
|
||||
String ext = filename.substring(extIndex + 1);
|
||||
mimetype = mimetypeService.getMimetype(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the encoding
|
||||
String encoding = req.getParameter(ARG_ENCODING);
|
||||
if (encoding == null || encoding.length() == 0)
|
||||
{
|
||||
// Get the encoding
|
||||
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
|
||||
Charset charset = charsetFinder.getCharset(inputStream, mimetype);
|
||||
encoding = charset.name();
|
||||
}
|
||||
|
||||
// Get the locale
|
||||
Locale locale = I18NUtil.parseLocale(req.getParameter(ARG_LOCALE));
|
||||
if (locale == null)
|
||||
{
|
||||
locale = I18NUtil.getContentLocale();
|
||||
if (nodeRef != null)
|
||||
{
|
||||
ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (contentData != null)
|
||||
{
|
||||
locale = contentData.getLocale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
if (nodeRef != null) {logger.debug("Found NodeRef: " + nodeRef.toString());}
|
||||
logger.debug("For property: " + propertyQName);
|
||||
logger.debug("File name: " + filename);
|
||||
logger.debug("Mimetype: " + mimetype);
|
||||
logger.debug("Encoding: " + encoding);
|
||||
logger.debug("Locale: " + locale);
|
||||
}
|
||||
|
||||
// Check that the user has the permissions to write the content
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.WRITE_CONTENT) == AccessStatus.DENIED)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("User does not have permissions to wrtie content for NodeRef: " + nodeRef.toString());
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Returning 403 Forbidden error...");
|
||||
}
|
||||
|
||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try and get the content writer
|
||||
ContentWriter writer = contentService.getWriter(nodeRef, propertyQName, true);
|
||||
if (writer == null)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Content writer cannot be obtained for NodeRef: " + nodeRef.toString());
|
||||
}
|
||||
res.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the mimetype, encoding and locale
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding(encoding);
|
||||
if (locale != null)
|
||||
{
|
||||
writer.setLocale(locale);
|
||||
}
|
||||
|
||||
// Stream the content into the repository
|
||||
writer.putContent(inputStream);
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Content details: " + writer.getContentData().toString());
|
||||
}
|
||||
|
||||
// Set return status
|
||||
res.getWriter().write(writer.getContentData().toString());
|
||||
res.flushBuffer();
|
||||
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("UploadContentServlet done");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +1,107 @@
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
|
||||
import org.alfresco.repo.webdav.auth.BaseAuthenticationFilter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
|
||||
import org.springframework.extensions.webscripts.Match;
|
||||
import org.springframework.extensions.webscripts.RuntimeContainer;
|
||||
|
||||
/**
|
||||
* WebScript aware Authentication Filter Class. Takes into account the authentication setting in the descriptor for the
|
||||
* webscript before chaining to the downstream authentication filters. If authentication is not required then chains
|
||||
* with the NO_AUTH_REQUIRED request attribute set, which should cause any downstream authentication filter to bypass
|
||||
* authentication checks.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author dward
|
||||
*/
|
||||
public class WebScriptSSOAuthenticationFilter extends BaseAuthenticationFilter implements DependencyInjectedFilter,
|
||||
ActivateableBean
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(WebScriptSSOAuthenticationFilter.class);
|
||||
private RuntimeContainer container;
|
||||
private boolean isActive = true;
|
||||
|
||||
/**
|
||||
* @param container the container to set
|
||||
*/
|
||||
public void setContainer(RuntimeContainer container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates or deactivates the bean
|
||||
*
|
||||
* @param active
|
||||
* <code>true</code> if the bean is active and initialization should complete
|
||||
*/
|
||||
public final void setActive(boolean active)
|
||||
{
|
||||
this.isActive = active;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
||||
*/
|
||||
public final boolean isActive()
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#doFilter(javax.servlet.ServletContext, javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletContext context, ServletRequest sreq, ServletResponse sresp, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
// Get the HTTP request/response
|
||||
HttpServletRequest req = (HttpServletRequest)sreq;
|
||||
|
||||
// find a webscript match for the requested URI
|
||||
String requestURI = req.getRequestURI();
|
||||
String pathInfo = requestURI.substring((req.getContextPath() + req.getServletPath()).length());
|
||||
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Processing request: " + requestURI + " SID:" +
|
||||
(req.getSession(false) != null ? req.getSession().getId() : null));
|
||||
|
||||
Match match = container.getRegistry().findWebScript(req.getMethod(), URLDecoder.decode(pathInfo));
|
||||
if (match != null && match.getWebScript() != null)
|
||||
{
|
||||
// check the authentication required - if none then we don't want any of
|
||||
// the filters down the chain to require any authentication checks
|
||||
if (RequiredAuthentication.none == match.getWebScript().getDescription().getRequiredAuthentication())
|
||||
{
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Found webscript with no authentication - set NO_AUTH_REQUIRED flag.");
|
||||
req.setAttribute(NO_AUTH_REQUIRED, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
chain.doFilter(sreq, sresp);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webdav.auth.BaseAuthenticationFilter#getLogger()
|
||||
*/
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
|
||||
import org.alfresco.repo.webdav.auth.BaseAuthenticationFilter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
|
||||
import org.springframework.extensions.webscripts.Match;
|
||||
import org.springframework.extensions.webscripts.RuntimeContainer;
|
||||
|
||||
/**
|
||||
* WebScript aware Authentication Filter Class. Takes into account the authentication setting in the descriptor for the
|
||||
* webscript before chaining to the downstream authentication filters. If authentication is not required then chains
|
||||
* with the NO_AUTH_REQUIRED request attribute set, which should cause any downstream authentication filter to bypass
|
||||
* authentication checks.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
* @author dward
|
||||
*/
|
||||
public class WebScriptSSOAuthenticationFilter extends BaseAuthenticationFilter implements DependencyInjectedFilter,
|
||||
ActivateableBean
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(WebScriptSSOAuthenticationFilter.class);
|
||||
private RuntimeContainer container;
|
||||
private boolean isActive = true;
|
||||
|
||||
/**
|
||||
* @param container the container to set
|
||||
*/
|
||||
public void setContainer(RuntimeContainer container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates or deactivates the bean
|
||||
*
|
||||
* @param active
|
||||
* <code>true</code> if the bean is active and initialization should complete
|
||||
*/
|
||||
public final void setActive(boolean active)
|
||||
{
|
||||
this.isActive = active;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
||||
*/
|
||||
public final boolean isActive()
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#doFilter(javax.servlet.ServletContext, javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletContext context, ServletRequest sreq, ServletResponse sresp, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
// Get the HTTP request/response
|
||||
HttpServletRequest req = (HttpServletRequest)sreq;
|
||||
|
||||
// find a webscript match for the requested URI
|
||||
String requestURI = req.getRequestURI();
|
||||
String pathInfo = requestURI.substring((req.getContextPath() + req.getServletPath()).length());
|
||||
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Processing request: " + requestURI + " SID:" +
|
||||
(req.getSession(false) != null ? req.getSession().getId() : null));
|
||||
|
||||
Match match = container.getRegistry().findWebScript(req.getMethod(), URLDecoder.decode(pathInfo));
|
||||
if (match != null && match.getWebScript() != null)
|
||||
{
|
||||
// check the authentication required - if none then we don't want any of
|
||||
// the filters down the chain to require any authentication checks
|
||||
if (RequiredAuthentication.none == match.getWebScript().getDescription().getRequiredAuthentication())
|
||||
{
|
||||
if (getLogger().isDebugEnabled())
|
||||
getLogger().debug("Found webscript with no authentication - set NO_AUTH_REQUIRED flag.");
|
||||
req.setAttribute(NO_AUTH_REQUIRED, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
chain.doFilter(sreq, sresp);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.webdav.auth.BaseAuthenticationFilter#getLogger()
|
||||
*/
|
||||
@Override
|
||||
protected Log getLogger()
|
||||
{
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Interface for all Ajax commands executed by this servlet.
|
||||
*
|
||||
* The method is responsible for invoking the underlying managed bean
|
||||
* and dealing with the response.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public interface AjaxCommand
|
||||
{
|
||||
/**
|
||||
* Invokes the relevant method on the bean represented by the given
|
||||
* expression. Parameters required to call the method can be retrieved
|
||||
* from the request.
|
||||
*
|
||||
* Currently the content type of the response will always be text/xml, in the
|
||||
* future sublcasses may provide a mechanism to allow the content type to be set
|
||||
* dynamically.
|
||||
*
|
||||
* @param facesContext FacesContext
|
||||
* @param expression The binding expression
|
||||
* @param request The request
|
||||
* @param response The response
|
||||
*/
|
||||
public abstract void execute(FacesContext facesContext, String expression,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException;
|
||||
}
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Interface for all Ajax commands executed by this servlet.
|
||||
*
|
||||
* The method is responsible for invoking the underlying managed bean
|
||||
* and dealing with the response.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public interface AjaxCommand
|
||||
{
|
||||
/**
|
||||
* Invokes the relevant method on the bean represented by the given
|
||||
* expression. Parameters required to call the method can be retrieved
|
||||
* from the request.
|
||||
*
|
||||
* Currently the content type of the response will always be text/xml, in the
|
||||
* future sublcasses may provide a mechanism to allow the content type to be set
|
||||
* dynamically.
|
||||
*
|
||||
* @param facesContext FacesContext
|
||||
* @param expression The binding expression
|
||||
* @param request The request
|
||||
* @param response The response
|
||||
*/
|
||||
public abstract void execute(FacesContext facesContext, String expression,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException;
|
||||
}
|
||||
|
||||
@@ -1,197 +1,197 @@
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.acegisecurity.context.ContextHolder;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.app.servlet.AuthenticationStatus;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for processing AJAX requests.
|
||||
*
|
||||
* The URL to the servlet should be in the form:
|
||||
* <pre>/alfresco/ajax/command/Bean.binding.expression</pre>
|
||||
* <p>
|
||||
* See http://wiki.alfresco.com/wiki/AJAX_Support for details.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class AjaxServlet extends BaseServlet
|
||||
{
|
||||
public static final String AJAX_LOG_KEY = "alfresco.ajax";
|
||||
|
||||
protected enum Command { invoke, get, set};
|
||||
|
||||
private static final long serialVersionUID = -7654769105419391840L;
|
||||
private static Log logger = LogFactory.getLog(AJAX_LOG_KEY);
|
||||
private static Log headersLogger = LogFactory.getLog(AJAX_LOG_KEY + ".headers");
|
||||
private static Log perfLogger = LogFactory.getLog(AJAX_LOG_KEY + ".performance");
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(final HttpServletRequest request,
|
||||
final HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
request.setCharacterEncoding("utf-8");
|
||||
// set default character encoding for the response
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/xml;charset=UTF-8");
|
||||
|
||||
long startTime = 0;
|
||||
String uri = request.getRequestURI();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
final String queryString = request.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
// dump the request headers
|
||||
if (headersLogger.isDebugEnabled())
|
||||
{
|
||||
final Enumeration<?> headers = request.getHeaderNames();
|
||||
while (headers.hasMoreElements())
|
||||
{
|
||||
final String name = (String)headers.nextElement();
|
||||
headersLogger.debug(name + ": " + request.getHeader(name));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Make sure the user is authenticated, if not throw an error to return the
|
||||
// 500 Internal Server Error code back to the client
|
||||
AuthenticationStatus status = servletAuthenticate(request, response, false);
|
||||
if (status == AuthenticationStatus.Failure)
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
|
||||
"Access Denied: User not authenticated");
|
||||
return;
|
||||
}
|
||||
|
||||
setNoCacheHeaders(response);
|
||||
|
||||
uri = uri.substring(request.getContextPath().length() + "/".length());
|
||||
final String[] tokens = uri.split("/");
|
||||
if (tokens.length < 3)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Servlet URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
// retrieve the command from the URL
|
||||
final String commandName = tokens[1];
|
||||
// retrieve the binding expression from the URL
|
||||
final String expression = tokens[2];
|
||||
|
||||
// setup the faces context
|
||||
final FacesContext facesContext = FacesHelper.getFacesContext(request, response, getServletContext());
|
||||
|
||||
// start a timer
|
||||
if (perfLogger.isDebugEnabled())
|
||||
startTime = System.currentTimeMillis();
|
||||
|
||||
// instantiate the relevant command
|
||||
AjaxCommand command = null;
|
||||
if (Command.invoke.toString().equals(commandName))
|
||||
{
|
||||
command = new InvokeCommand();
|
||||
}
|
||||
else if (Command.get.toString().equals(commandName))
|
||||
{
|
||||
command = new GetCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unrecognised command received: " + commandName);
|
||||
}
|
||||
|
||||
// execute the command
|
||||
command.execute(facesContext, expression, request, response);
|
||||
}
|
||||
catch (RuntimeException error)
|
||||
{
|
||||
handleError(response, error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// measure the time taken
|
||||
if (perfLogger.isDebugEnabled())
|
||||
{
|
||||
perfLogger.debug("Time to execute command: " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
ContextHolder.setContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles any error that occurs during the execution of the servlet
|
||||
*
|
||||
* @param response The response
|
||||
* @param cause The cause of the error
|
||||
*/
|
||||
protected void handleError(HttpServletResponse response, RuntimeException cause)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
// if we can send back the 500 error with the error from the top of the
|
||||
// stack as the error status message.
|
||||
|
||||
// NOTE: if we use the built in support for generating error pages for
|
||||
// 500 errors we can tailor the output for AJAX calls so that the
|
||||
// body of the response can be used to show the error details.
|
||||
|
||||
if (!response.isCommitted())
|
||||
{
|
||||
// dump the error if debugging is enabled
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error(cause);
|
||||
Throwable theCause = cause.getCause();
|
||||
if (theCause != null)
|
||||
{
|
||||
logger.error("caused by: ", theCause);
|
||||
}
|
||||
}
|
||||
|
||||
// extract a message from the exception
|
||||
String msg = cause.getMessage();
|
||||
if (msg == null)
|
||||
{
|
||||
msg = cause.toString();
|
||||
}
|
||||
// ALF-9036. We need to trap incomplete sessions
|
||||
if (cause instanceof IllegalStateException)
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, cause.getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the response has already been comitted, not much we can do but
|
||||
// let the error through and let the container deal with it
|
||||
throw cause;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.acegisecurity.context.ContextHolder;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.app.servlet.AuthenticationStatus;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Servlet responsible for processing AJAX requests.
|
||||
*
|
||||
* The URL to the servlet should be in the form:
|
||||
* <pre>/alfresco/ajax/command/Bean.binding.expression</pre>
|
||||
* <p>
|
||||
* See http://wiki.alfresco.com/wiki/AJAX_Support for details.
|
||||
* <p>
|
||||
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||
* ?ticket=1234567890
|
||||
*
|
||||
* @author gavinc
|
||||
* @deprecated 5.0 not exposed in web-client web.xml
|
||||
*/
|
||||
public class AjaxServlet extends BaseServlet
|
||||
{
|
||||
public static final String AJAX_LOG_KEY = "alfresco.ajax";
|
||||
|
||||
protected enum Command { invoke, get, set};
|
||||
|
||||
private static final long serialVersionUID = -7654769105419391840L;
|
||||
private static Log logger = LogFactory.getLog(AJAX_LOG_KEY);
|
||||
private static Log headersLogger = LogFactory.getLog(AJAX_LOG_KEY + ".headers");
|
||||
private static Log perfLogger = LogFactory.getLog(AJAX_LOG_KEY + ".performance");
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void service(final HttpServletRequest request,
|
||||
final HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
request.setCharacterEncoding("utf-8");
|
||||
// set default character encoding for the response
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/xml;charset=UTF-8");
|
||||
|
||||
long startTime = 0;
|
||||
String uri = request.getRequestURI();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
final String queryString = request.getQueryString();
|
||||
logger.debug("Processing URL: " + uri +
|
||||
((queryString != null && queryString.length() > 0) ? ("?" + queryString) : ""));
|
||||
}
|
||||
|
||||
// dump the request headers
|
||||
if (headersLogger.isDebugEnabled())
|
||||
{
|
||||
final Enumeration<?> headers = request.getHeaderNames();
|
||||
while (headers.hasMoreElements())
|
||||
{
|
||||
final String name = (String)headers.nextElement();
|
||||
headersLogger.debug(name + ": " + request.getHeader(name));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Make sure the user is authenticated, if not throw an error to return the
|
||||
// 500 Internal Server Error code back to the client
|
||||
AuthenticationStatus status = servletAuthenticate(request, response, false);
|
||||
if (status == AuthenticationStatus.Failure)
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
|
||||
"Access Denied: User not authenticated");
|
||||
return;
|
||||
}
|
||||
|
||||
setNoCacheHeaders(response);
|
||||
|
||||
uri = uri.substring(request.getContextPath().length() + "/".length());
|
||||
final String[] tokens = uri.split("/");
|
||||
if (tokens.length < 3)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Servlet URL did not contain all required args: " + uri);
|
||||
}
|
||||
|
||||
// retrieve the command from the URL
|
||||
final String commandName = tokens[1];
|
||||
// retrieve the binding expression from the URL
|
||||
final String expression = tokens[2];
|
||||
|
||||
// setup the faces context
|
||||
final FacesContext facesContext = FacesHelper.getFacesContext(request, response, getServletContext());
|
||||
|
||||
// start a timer
|
||||
if (perfLogger.isDebugEnabled())
|
||||
startTime = System.currentTimeMillis();
|
||||
|
||||
// instantiate the relevant command
|
||||
AjaxCommand command = null;
|
||||
if (Command.invoke.toString().equals(commandName))
|
||||
{
|
||||
command = new InvokeCommand();
|
||||
}
|
||||
else if (Command.get.toString().equals(commandName))
|
||||
{
|
||||
command = new GetCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unrecognised command received: " + commandName);
|
||||
}
|
||||
|
||||
// execute the command
|
||||
command.execute(facesContext, expression, request, response);
|
||||
}
|
||||
catch (RuntimeException error)
|
||||
{
|
||||
handleError(response, error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// measure the time taken
|
||||
if (perfLogger.isDebugEnabled())
|
||||
{
|
||||
perfLogger.debug("Time to execute command: " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
ContextHolder.setContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles any error that occurs during the execution of the servlet
|
||||
*
|
||||
* @param response The response
|
||||
* @param cause The cause of the error
|
||||
*/
|
||||
protected void handleError(HttpServletResponse response, RuntimeException cause)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
// if we can send back the 500 error with the error from the top of the
|
||||
// stack as the error status message.
|
||||
|
||||
// NOTE: if we use the built in support for generating error pages for
|
||||
// 500 errors we can tailor the output for AJAX calls so that the
|
||||
// body of the response can be used to show the error details.
|
||||
|
||||
if (!response.isCommitted())
|
||||
{
|
||||
// dump the error if debugging is enabled
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.error(cause);
|
||||
Throwable theCause = cause.getCause();
|
||||
if (theCause != null)
|
||||
{
|
||||
logger.error("caused by: ", theCause);
|
||||
}
|
||||
}
|
||||
|
||||
// extract a message from the exception
|
||||
String msg = cause.getMessage();
|
||||
if (msg == null)
|
||||
{
|
||||
msg = cause.toString();
|
||||
}
|
||||
// ALF-9036. We need to trap incomplete sessions
|
||||
if (cause instanceof IllegalStateException)
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, cause.getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the response has already been comitted, not much we can do but
|
||||
// let the error through and let the container deal with it
|
||||
throw cause;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base class for all Ajax based commands
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class BaseAjaxCommand implements AjaxCommand
|
||||
{
|
||||
protected static Log logger = LogFactory.getLog(AjaxServlet.AJAX_LOG_KEY);
|
||||
|
||||
public String makeBindingExpression(String expression)
|
||||
{
|
||||
return "#{" + expression + "}";
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base class for all Ajax based commands
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public abstract class BaseAjaxCommand implements AjaxCommand
|
||||
{
|
||||
protected static Log logger = LogFactory.getLog(AjaxServlet.AJAX_LOG_KEY);
|
||||
|
||||
public String makeBindingExpression(String expression)
|
||||
{
|
||||
return "#{" + expression + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Command that executes the given value binding expression.
|
||||
* <p>
|
||||
* This command is intended to be used for calling existing managed
|
||||
* bean methods. The result of the value binding is added to
|
||||
* the response as is i.e. by calling toString().
|
||||
* The content type of the response is always text/html.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class GetCommand extends BaseAjaxCommand
|
||||
{
|
||||
public void execute(FacesContext facesContext, String expression,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
// create the JSF binding expression
|
||||
String bindingExpr = makeBindingExpression(expression);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Retrieving value from value binding: " + bindingExpr);
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
// create the value binding
|
||||
ValueBinding binding = facesContext.getApplication().
|
||||
createValueBinding(bindingExpr);
|
||||
|
||||
if (binding != null)
|
||||
{
|
||||
// setup the transaction
|
||||
tx = Repository.getUserTransaction(facesContext, true);
|
||||
tx.begin();
|
||||
|
||||
// get the value from the value binding
|
||||
Object value = binding.getValue(facesContext);
|
||||
if (value != null)
|
||||
{
|
||||
response.getWriter().write(value.toString());
|
||||
}
|
||||
|
||||
// commit
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
// rollback the transaction
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
|
||||
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve value: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Command that executes the given value binding expression.
|
||||
* <p>
|
||||
* This command is intended to be used for calling existing managed
|
||||
* bean methods. The result of the value binding is added to
|
||||
* the response as is i.e. by calling toString().
|
||||
* The content type of the response is always text/html.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class GetCommand extends BaseAjaxCommand
|
||||
{
|
||||
public void execute(FacesContext facesContext, String expression,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
// create the JSF binding expression
|
||||
String bindingExpr = makeBindingExpression(expression);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Retrieving value from value binding: " + bindingExpr);
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
// create the value binding
|
||||
ValueBinding binding = facesContext.getApplication().
|
||||
createValueBinding(bindingExpr);
|
||||
|
||||
if (binding != null)
|
||||
{
|
||||
// setup the transaction
|
||||
tx = Repository.getUserTransaction(facesContext, true);
|
||||
tx.begin();
|
||||
|
||||
// get the value from the value binding
|
||||
Object value = binding.getValue(facesContext);
|
||||
if (value != null)
|
||||
{
|
||||
response.getWriter().write(value.toString());
|
||||
}
|
||||
|
||||
// commit
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
// rollback the transaction
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
|
||||
|
||||
throw new AlfrescoRuntimeException("Failed to retrieve value: " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,218 +1,218 @@
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Command that invokes the method represented by the expression.
|
||||
* <p>
|
||||
* The managed bean method called is responsible for writing the response
|
||||
* by getting hold of the JSF ResponseWriter. Parameters can also be
|
||||
* retrieved via the JSF ExternalContext object.
|
||||
* <p>
|
||||
* In a future release (if required) annotations may be used to state
|
||||
* what content type to use for the response.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class InvokeCommand extends BaseAjaxCommand
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Annotation for a bean method that handles an ajax request.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ResponseMimetype
|
||||
{
|
||||
// NOTE: replaced Mimetype.MIMETYPE_XML with string literal due to bug
|
||||
// http://bugs.sun.com/view_bug.do?bug_id=6512707 - causing build to fail
|
||||
public String value() default "text/xml";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void execute(final FacesContext facesContext,
|
||||
final String expression,
|
||||
final HttpServletRequest request,
|
||||
final HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
ResponseWriter writer = null;
|
||||
try
|
||||
{
|
||||
final int indexOfDot = expression.indexOf('.');
|
||||
final String variableName = expression.substring(0, indexOfDot);
|
||||
final String methodName = expression.substring(indexOfDot + 1);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Invoking method represented by " + expression +
|
||||
" on variable " + variableName +
|
||||
" with method " + methodName);
|
||||
|
||||
Object bean = null;
|
||||
if (Application.inPortalServer())
|
||||
{
|
||||
// retrieve the managed bean, this is really weak but if the
|
||||
// request comes from a portal server the bean we need to get
|
||||
// is in the session with a prefix chosen by the portal vendor,
|
||||
// to cover this scenario we have to go through the names of
|
||||
// all the objects in the session to find the bean we want.
|
||||
|
||||
String beanNameSuffix = "?" + variableName;
|
||||
Enumeration<?> enumNames = request.getSession().getAttributeNames();
|
||||
while (enumNames.hasMoreElements())
|
||||
{
|
||||
String name = (String)enumNames.nextElement();
|
||||
if (name.endsWith(beanNameSuffix))
|
||||
{
|
||||
bean = request.getSession().getAttribute(name);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found bean " + bean + " in the session");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have the bean yet try and get it via the variable resolver
|
||||
if (bean == null)
|
||||
{
|
||||
VariableResolver vr = facesContext.getApplication().getVariableResolver();
|
||||
bean = vr.resolveVariable(facesContext, variableName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created bean " + bean + " via the variable resolver");
|
||||
}
|
||||
|
||||
final Method method = bean.getClass().getMethod(methodName);
|
||||
|
||||
final String responseMimetype =
|
||||
(method.isAnnotationPresent(ResponseMimetype.class)
|
||||
? method.getAnnotation(ResponseMimetype.class).value()
|
||||
: MimetypeMap.MIMETYPE_XML);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("invoking method " + method +
|
||||
" with repsonse mimetype " + responseMimetype);
|
||||
|
||||
writer = this.setupResponseWriter(responseMimetype,
|
||||
response,
|
||||
facesContext);
|
||||
|
||||
// setup the transaction
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(FacesContext.getCurrentInstance());
|
||||
final Object beanFinal = bean;
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
// invoke the method
|
||||
try
|
||||
{
|
||||
method.invoke(beanFinal);
|
||||
return null;
|
||||
}
|
||||
// Let's prevent RuntimeExceptions being wrapped twice by unwrapping InvocationTargetExceptions
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
if (e.getCause() != null)
|
||||
{
|
||||
throw e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
}
|
||||
catch (EvaluationException e)
|
||||
{
|
||||
Throwable err = e.getCause();
|
||||
if (err == null)
|
||||
{
|
||||
logger.error("Failed to execute method " + expression + ": " + e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
if (err instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)err;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RuntimeException err)
|
||||
{
|
||||
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
throw err;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
throw new AlfrescoRuntimeException("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
}
|
||||
|
||||
// force the output back to the client
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/** setup the JSF response writer. */
|
||||
private ResponseWriter setupResponseWriter(final String mimetype,
|
||||
final HttpServletResponse response,
|
||||
final FacesContext facesContext)
|
||||
throws IOException
|
||||
{
|
||||
final OutputStream os = response.getOutputStream();
|
||||
final UIViewRoot viewRoot = facesContext.getViewRoot();
|
||||
final RenderKitFactory renderFactory = (RenderKitFactory)
|
||||
FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
final RenderKit renderKit =
|
||||
renderFactory.getRenderKit(facesContext, viewRoot.getRenderKitId());
|
||||
final ResponseWriter writer =
|
||||
renderKit.createResponseWriter(new OutputStreamWriter(os, "UTF-8"),
|
||||
mimetype,
|
||||
"UTF-8");
|
||||
facesContext.setResponseWriter(writer);
|
||||
// must be text/xml otherwise IE doesn't parse the response properly into responseXML
|
||||
response.setContentType(mimetype);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Command that invokes the method represented by the expression.
|
||||
* <p>
|
||||
* The managed bean method called is responsible for writing the response
|
||||
* by getting hold of the JSF ResponseWriter. Parameters can also be
|
||||
* retrieved via the JSF ExternalContext object.
|
||||
* <p>
|
||||
* In a future release (if required) annotations may be used to state
|
||||
* what content type to use for the response.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class InvokeCommand extends BaseAjaxCommand
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Annotation for a bean method that handles an ajax request.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ResponseMimetype
|
||||
{
|
||||
// NOTE: replaced Mimetype.MIMETYPE_XML with string literal due to bug
|
||||
// http://bugs.sun.com/view_bug.do?bug_id=6512707 - causing build to fail
|
||||
public String value() default "text/xml";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void execute(final FacesContext facesContext,
|
||||
final String expression,
|
||||
final HttpServletRequest request,
|
||||
final HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
ResponseWriter writer = null;
|
||||
try
|
||||
{
|
||||
final int indexOfDot = expression.indexOf('.');
|
||||
final String variableName = expression.substring(0, indexOfDot);
|
||||
final String methodName = expression.substring(indexOfDot + 1);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Invoking method represented by " + expression +
|
||||
" on variable " + variableName +
|
||||
" with method " + methodName);
|
||||
|
||||
Object bean = null;
|
||||
if (Application.inPortalServer())
|
||||
{
|
||||
// retrieve the managed bean, this is really weak but if the
|
||||
// request comes from a portal server the bean we need to get
|
||||
// is in the session with a prefix chosen by the portal vendor,
|
||||
// to cover this scenario we have to go through the names of
|
||||
// all the objects in the session to find the bean we want.
|
||||
|
||||
String beanNameSuffix = "?" + variableName;
|
||||
Enumeration<?> enumNames = request.getSession().getAttributeNames();
|
||||
while (enumNames.hasMoreElements())
|
||||
{
|
||||
String name = (String)enumNames.nextElement();
|
||||
if (name.endsWith(beanNameSuffix))
|
||||
{
|
||||
bean = request.getSession().getAttribute(name);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found bean " + bean + " in the session");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have the bean yet try and get it via the variable resolver
|
||||
if (bean == null)
|
||||
{
|
||||
VariableResolver vr = facesContext.getApplication().getVariableResolver();
|
||||
bean = vr.resolveVariable(facesContext, variableName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created bean " + bean + " via the variable resolver");
|
||||
}
|
||||
|
||||
final Method method = bean.getClass().getMethod(methodName);
|
||||
|
||||
final String responseMimetype =
|
||||
(method.isAnnotationPresent(ResponseMimetype.class)
|
||||
? method.getAnnotation(ResponseMimetype.class).value()
|
||||
: MimetypeMap.MIMETYPE_XML);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("invoking method " + method +
|
||||
" with repsonse mimetype " + responseMimetype);
|
||||
|
||||
writer = this.setupResponseWriter(responseMimetype,
|
||||
response,
|
||||
facesContext);
|
||||
|
||||
// setup the transaction
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(FacesContext.getCurrentInstance());
|
||||
final Object beanFinal = bean;
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
// invoke the method
|
||||
try
|
||||
{
|
||||
method.invoke(beanFinal);
|
||||
return null;
|
||||
}
|
||||
// Let's prevent RuntimeExceptions being wrapped twice by unwrapping InvocationTargetExceptions
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
if (e.getCause() != null)
|
||||
{
|
||||
throw e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
}
|
||||
catch (EvaluationException e)
|
||||
{
|
||||
Throwable err = e.getCause();
|
||||
if (err == null)
|
||||
{
|
||||
logger.error("Failed to execute method " + expression + ": " + e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
if (err instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)err;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RuntimeException err)
|
||||
{
|
||||
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
throw err;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
|
||||
logger.error("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
throw new AlfrescoRuntimeException("Failed to execute method " + expression + ": " + err.getMessage(), err);
|
||||
}
|
||||
|
||||
// force the output back to the client
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/** setup the JSF response writer. */
|
||||
private ResponseWriter setupResponseWriter(final String mimetype,
|
||||
final HttpServletResponse response,
|
||||
final FacesContext facesContext)
|
||||
throws IOException
|
||||
{
|
||||
final OutputStream os = response.getOutputStream();
|
||||
final UIViewRoot viewRoot = facesContext.getViewRoot();
|
||||
final RenderKitFactory renderFactory = (RenderKitFactory)
|
||||
FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
final RenderKit renderKit =
|
||||
renderFactory.getRenderKit(facesContext, viewRoot.getRenderKitId());
|
||||
final ResponseWriter writer =
|
||||
renderKit.createResponseWriter(new OutputStreamWriter(os, "UTF-8"),
|
||||
mimetype,
|
||||
"UTF-8");
|
||||
facesContext.setResponseWriter(writer);
|
||||
// must be text/xml otherwise IE doesn't parse the response properly into responseXML
|
||||
response.setContentType(mimetype);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
|
||||
/**
|
||||
* Approve Workflow command implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ApproveWorkflowCommand implements Command
|
||||
{
|
||||
public static final String PROP_TARGET = "target";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TARGET};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Node for the command
|
||||
NodeRef nodeRef = (NodeRef)properties.get(PROP_TARGET);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ApproveCommand - mandatory parameter not supplied: " + PROP_TARGET);
|
||||
}
|
||||
|
||||
WorkflowUtil.approve(nodeRef, serviceRegistry.getNodeService(), serviceRegistry.getCopyService());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
|
||||
/**
|
||||
* Approve Workflow command implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ApproveWorkflowCommand implements Command
|
||||
{
|
||||
public static final String PROP_TARGET = "target";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TARGET};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Node for the command
|
||||
NodeRef nodeRef = (NodeRef)properties.get(PROP_TARGET);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ApproveCommand - mandatory parameter not supplied: " + PROP_TARGET);
|
||||
}
|
||||
|
||||
WorkflowUtil.approve(nodeRef, serviceRegistry.getNodeService(), serviceRegistry.getCopyService());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Initial implementation of a Command Processor that is always passed enough URL elements
|
||||
* to construct a single NodeRef argument. The NodeRef is checked against READ permissions
|
||||
* for the current user during the validateArguments() call.
|
||||
* <p>
|
||||
* This class should be enough to form the base of Command Processor objects that only require
|
||||
* a single NodeRef passed on the URL.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseNodeCommandProcessor implements CommandProcessor
|
||||
{
|
||||
protected NodeRef targetRef;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
if (urlElements.length < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
|
||||
// get NodeRef to the node with the workflow attached to it
|
||||
StoreRef storeRef = new StoreRef(urlElements[0], urlElements[1]);
|
||||
this.targetRef = new NodeRef(storeRef, urlElements[2]);
|
||||
|
||||
// get the services we need to execute the workflow command
|
||||
PermissionService permissionService = Repository.getServiceRegistry(sc).getPermissionService();
|
||||
|
||||
// check that the user has at least READ access on the node - else redirect to the login page
|
||||
return (permissionService.hasPermission(this.targetRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Initial implementation of a Command Processor that is always passed enough URL elements
|
||||
* to construct a single NodeRef argument. The NodeRef is checked against READ permissions
|
||||
* for the current user during the validateArguments() call.
|
||||
* <p>
|
||||
* This class should be enough to form the base of Command Processor objects that only require
|
||||
* a single NodeRef passed on the URL.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseNodeCommandProcessor implements CommandProcessor
|
||||
{
|
||||
protected NodeRef targetRef;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
if (urlElements.length < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
|
||||
// get NodeRef to the node with the workflow attached to it
|
||||
StoreRef storeRef = new StoreRef(urlElements[0], urlElements[1]);
|
||||
this.targetRef = new NodeRef(storeRef, urlElements[2]);
|
||||
|
||||
// get the services we need to execute the workflow command
|
||||
PermissionService permissionService = Repository.getServiceRegistry(sc).getPermissionService();
|
||||
|
||||
// check that the user has at least READ access on the node - else redirect to the login page
|
||||
return (permissionService.hasPermission(this.targetRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseUIActionCommand implements Command
|
||||
{
|
||||
public static final String PROP_SERVLETCONTEXT = "ServletContext";
|
||||
public static final String PROP_REQUEST = "Request";
|
||||
public static final String PROP_RESPONSE = "Response";
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public abstract class BaseUIActionCommand implements Command
|
||||
{
|
||||
public static final String PROP_SERVLETCONTEXT = "ServletContext";
|
||||
public static final String PROP_REQUEST = "Request";
|
||||
public static final String PROP_RESPONSE = "Response";
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Simple servlet command pattern interface.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface Command
|
||||
{
|
||||
/**
|
||||
* Execute the command
|
||||
*
|
||||
* @param serviceRegistry The ServiceRegistry instance
|
||||
* @param properties Bag of named properties for the command
|
||||
*
|
||||
* @return return value from the command if any
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties);
|
||||
|
||||
/**
|
||||
* @return the names of the properties required for this command
|
||||
*/
|
||||
public String[] getPropertyNames();
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Simple servlet command pattern interface.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface Command
|
||||
{
|
||||
/**
|
||||
* Execute the command
|
||||
*
|
||||
* @param serviceRegistry The ServiceRegistry instance
|
||||
* @param properties Bag of named properties for the command
|
||||
*
|
||||
* @return return value from the command if any
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties);
|
||||
|
||||
/**
|
||||
* @return the names of the properties required for this command
|
||||
*/
|
||||
public String[] getPropertyNames();
|
||||
}
|
||||
|
||||
@@ -1,81 +1,81 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Command Factory helper
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class CommandFactory
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(CommandFactory.class);
|
||||
|
||||
private static CommandFactory instance = new CommandFactory();
|
||||
|
||||
private static Map<String, Class> registry = new HashMap<String, Class>(16, 1.0f);
|
||||
|
||||
/**
|
||||
* Private constructor - protect the singleton instance
|
||||
*/
|
||||
private CommandFactory()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton CommandFactory instance
|
||||
*/
|
||||
public static CommandFactory getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command name against an implementation
|
||||
*
|
||||
* @param name Unique name of the command
|
||||
* @param clazz Class implementation of the command
|
||||
*/
|
||||
public void registerCommand(String name, Class clazz)
|
||||
{
|
||||
registry.put(name, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a command instance of the specified command name
|
||||
*
|
||||
* @param name Name of the command to create (must be registered)
|
||||
*
|
||||
* @return the Command instance or null if not found
|
||||
*/
|
||||
public Command createCommand(String name)
|
||||
{
|
||||
Command result = null;
|
||||
|
||||
// lookup command by name in the registry
|
||||
Class clazz = registry.get(name);
|
||||
if (clazz != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object obj = clazz.newInstance();
|
||||
if (obj instanceof Command)
|
||||
{
|
||||
result = (Command)obj;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
// return default if this occurs
|
||||
logger.warn("Unable to create workflow command instance '" + name +
|
||||
"' with classname '" + clazz.getName() + "' due to error: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Command Factory helper
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class CommandFactory
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(CommandFactory.class);
|
||||
|
||||
private static CommandFactory instance = new CommandFactory();
|
||||
|
||||
private static Map<String, Class> registry = new HashMap<String, Class>(16, 1.0f);
|
||||
|
||||
/**
|
||||
* Private constructor - protect the singleton instance
|
||||
*/
|
||||
private CommandFactory()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton CommandFactory instance
|
||||
*/
|
||||
public static CommandFactory getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command name against an implementation
|
||||
*
|
||||
* @param name Unique name of the command
|
||||
* @param clazz Class implementation of the command
|
||||
*/
|
||||
public void registerCommand(String name, Class clazz)
|
||||
{
|
||||
registry.put(name, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a command instance of the specified command name
|
||||
*
|
||||
* @param name Name of the command to create (must be registered)
|
||||
*
|
||||
* @return the Command instance or null if not found
|
||||
*/
|
||||
public Command createCommand(String name)
|
||||
{
|
||||
Command result = null;
|
||||
|
||||
// lookup command by name in the registry
|
||||
Class clazz = registry.get(name);
|
||||
if (clazz != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object obj = clazz.newInstance();
|
||||
if (obj instanceof Command)
|
||||
{
|
||||
result = (Command)obj;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
// return default if this occurs
|
||||
logger.warn("Unable to create workflow command instance '" + name +
|
||||
"' with classname '" + clazz.getName() + "' due to error: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* This interfaces defines the contract and lifecycle of a Servlet Command Processor.
|
||||
* <p>
|
||||
* A command processor is defined as a class capable of executing a set of related Command
|
||||
* objects. It performs the bulk of the work for the command servlet. The processor impl
|
||||
* is responsible for validating that the command can be processed (given the supplied remaining
|
||||
* URL arguments from the servlet) and processing the command. It is also responsible for
|
||||
* supply an output status page on successfuly execution of the command.
|
||||
* <p>
|
||||
* The arguments passed to a Command Processor are the remaining URL elements from the command
|
||||
* servlet URL after removing the web-app name, servlet name and command processor name.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface CommandProcessor
|
||||
{
|
||||
/**
|
||||
* Pass and validate URL arguments for the command processor. Validate if the command can be
|
||||
* executed given the arguments supplied. Generally at this post a Command Processor will
|
||||
* convert the supplied arguments to the objects it expects, and also check any permissions
|
||||
* that are required by the current user to execute the command.
|
||||
*
|
||||
* @param sc ServletContext, can be used to retrieve ServiceRegistry instance
|
||||
* from the Repository bean.
|
||||
* @param command Name of the command the arguments are for
|
||||
* @param args Map of URL args passed to the command servlet
|
||||
* @param urlElements String[] of the remaining URL arguments to the command servlet
|
||||
*
|
||||
* @return true if the command can be executed by the current user given the supplied args.
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements);
|
||||
|
||||
/**
|
||||
* Process the supplied command name. It is the responsibility of the Command Processor
|
||||
* to lookup the specified command name using the CommandFactory registry. For that reason
|
||||
* it also has the responsiblity to initially register commands it is responsible for so
|
||||
* they can be constructed later. If the supplied command is unknown to it then an
|
||||
* exception should be thrown to indicate this.
|
||||
*
|
||||
* @param serviceRegistry ServiceRegistry
|
||||
* @param request HttpServletRequest
|
||||
* @param command Name of the command to construct and execute
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command);
|
||||
|
||||
/**
|
||||
* Output a simple status message to the supplied PrintWriter.
|
||||
* It can be assumed that the process() method was successful if this method is called.
|
||||
*
|
||||
* @param out PrintWriter
|
||||
*/
|
||||
public void outputStatus(PrintWriter out);
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* This interfaces defines the contract and lifecycle of a Servlet Command Processor.
|
||||
* <p>
|
||||
* A command processor is defined as a class capable of executing a set of related Command
|
||||
* objects. It performs the bulk of the work for the command servlet. The processor impl
|
||||
* is responsible for validating that the command can be processed (given the supplied remaining
|
||||
* URL arguments from the servlet) and processing the command. It is also responsible for
|
||||
* supply an output status page on successfuly execution of the command.
|
||||
* <p>
|
||||
* The arguments passed to a Command Processor are the remaining URL elements from the command
|
||||
* servlet URL after removing the web-app name, servlet name and command processor name.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface CommandProcessor
|
||||
{
|
||||
/**
|
||||
* Pass and validate URL arguments for the command processor. Validate if the command can be
|
||||
* executed given the arguments supplied. Generally at this post a Command Processor will
|
||||
* convert the supplied arguments to the objects it expects, and also check any permissions
|
||||
* that are required by the current user to execute the command.
|
||||
*
|
||||
* @param sc ServletContext, can be used to retrieve ServiceRegistry instance
|
||||
* from the Repository bean.
|
||||
* @param command Name of the command the arguments are for
|
||||
* @param args Map of URL args passed to the command servlet
|
||||
* @param urlElements String[] of the remaining URL arguments to the command servlet
|
||||
*
|
||||
* @return true if the command can be executed by the current user given the supplied args.
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements);
|
||||
|
||||
/**
|
||||
* Process the supplied command name. It is the responsibility of the Command Processor
|
||||
* to lookup the specified command name using the CommandFactory registry. For that reason
|
||||
* it also has the responsiblity to initially register commands it is responsible for so
|
||||
* they can be constructed later. If the supplied command is unknown to it then an
|
||||
* exception should be thrown to indicate this.
|
||||
*
|
||||
* @param serviceRegistry ServiceRegistry
|
||||
* @param request HttpServletRequest
|
||||
* @param command Name of the command to construct and execute
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command);
|
||||
|
||||
/**
|
||||
* Output a simple status message to the supplied PrintWriter.
|
||||
* It can be assumed that the process() method was successful if this method is called.
|
||||
*
|
||||
* @param out PrintWriter
|
||||
*/
|
||||
public void outputStatus(PrintWriter out);
|
||||
}
|
||||
|
||||
+72
-72
@@ -1,72 +1,72 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.BrowseBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Command to execute the Edit Content Properties dialog via url.
|
||||
* <p>
|
||||
* Arguments: noderef - of the document to show the edit props dialog for
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditContentPropertiesCommand extends BaseUIActionCommand
|
||||
{
|
||||
public static final String PROP_NODEREF = "noderef";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {
|
||||
PROP_SERVLETCONTEXT, PROP_REQUEST, PROP_RESPONSE, PROP_NODEREF};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
ServletContext sc = (ServletContext)properties.get(PROP_SERVLETCONTEXT);
|
||||
ServletRequest req = (ServletRequest)properties.get(PROP_REQUEST);
|
||||
ServletResponse res = (ServletResponse)properties.get(PROP_RESPONSE);
|
||||
FacesContext fc = FacesHelper.getFacesContext(req, res, sc, "/jsp/close.jsp");
|
||||
BrowseBean browseBean = (BrowseBean)FacesHelper.getManagedBean(fc, BrowseBean.BEAN_NAME);
|
||||
|
||||
// setup context from url args in properties map
|
||||
String strNodeRef = (String)properties.get(PROP_NODEREF);
|
||||
ParameterCheck.mandatoryString(PROP_NODEREF, strNodeRef);
|
||||
browseBean.setDocument(new Node(new NodeRef(strNodeRef)));
|
||||
|
||||
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
|
||||
navigationHandler.handleNavigation(fc, null, "dialog:editContentProperties");
|
||||
String viewId = fc.getViewRoot().getViewId();
|
||||
try
|
||||
{
|
||||
sc.getRequestDispatcher(BaseServlet.FACES_SERVLET + viewId).forward(req, res);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to forward to viewId: " + viewId, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.BrowseBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Command to execute the Edit Content Properties dialog via url.
|
||||
* <p>
|
||||
* Arguments: noderef - of the document to show the edit props dialog for
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class EditContentPropertiesCommand extends BaseUIActionCommand
|
||||
{
|
||||
public static final String PROP_NODEREF = "noderef";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {
|
||||
PROP_SERVLETCONTEXT, PROP_REQUEST, PROP_RESPONSE, PROP_NODEREF};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
ServletContext sc = (ServletContext)properties.get(PROP_SERVLETCONTEXT);
|
||||
ServletRequest req = (ServletRequest)properties.get(PROP_REQUEST);
|
||||
ServletResponse res = (ServletResponse)properties.get(PROP_RESPONSE);
|
||||
FacesContext fc = FacesHelper.getFacesContext(req, res, sc, "/jsp/close.jsp");
|
||||
BrowseBean browseBean = (BrowseBean)FacesHelper.getManagedBean(fc, BrowseBean.BEAN_NAME);
|
||||
|
||||
// setup context from url args in properties map
|
||||
String strNodeRef = (String)properties.get(PROP_NODEREF);
|
||||
ParameterCheck.mandatoryString(PROP_NODEREF, strNodeRef);
|
||||
browseBean.setDocument(new Node(new NodeRef(strNodeRef)));
|
||||
|
||||
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
|
||||
navigationHandler.handleNavigation(fc, null, "dialog:editContentProperties");
|
||||
String viewId = fc.getViewRoot().getViewId();
|
||||
try
|
||||
{
|
||||
sc.getRequestDispatcher(BaseServlet.FACES_SERVLET + viewId).forward(req, res);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to forward to viewId: " + viewId, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
|
||||
/**
|
||||
* End Task command implementation
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public final class EndTaskCommand implements Command
|
||||
{
|
||||
public static final String PROP_TASK_ID = "taskId";
|
||||
public static final String PROP_TRANSITION = "transition";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TASK_ID, PROP_TRANSITION};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
String taskId = (String)properties.get(PROP_TASK_ID);
|
||||
if (taskId == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to execute EndTaskCommand - mandatory parameter not supplied: " + PROP_TASK_ID);
|
||||
}
|
||||
String transition = (String)properties.get(PROP_TRANSITION);
|
||||
|
||||
// end task
|
||||
WorkflowService workflowService = serviceRegistry.getWorkflowService();
|
||||
return workflowService.endTask(taskId, transition);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
|
||||
/**
|
||||
* End Task command implementation
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public final class EndTaskCommand implements Command
|
||||
{
|
||||
public static final String PROP_TASK_ID = "taskId";
|
||||
public static final String PROP_TRANSITION = "transition";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TASK_ID, PROP_TRANSITION};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
String taskId = (String)properties.get(PROP_TASK_ID);
|
||||
if (taskId == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to execute EndTaskCommand - mandatory parameter not supplied: " + PROP_TASK_ID);
|
||||
}
|
||||
String transition = (String)properties.get(PROP_TRANSITION);
|
||||
|
||||
// end task
|
||||
WorkflowService workflowService = serviceRegistry.getWorkflowService();
|
||||
return workflowService.endTask(taskId, transition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,81 +1,81 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Execute Script command implementation.
|
||||
* <p>
|
||||
* Executes the supplied script against the default data-model.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ExecuteScriptCommand implements Command
|
||||
{
|
||||
public static final String PROP_SCRIPT = "script";
|
||||
public static final String PROP_DOCUMENT = "document";
|
||||
public static final String PROP_USERPERSON = "person";
|
||||
public static final String PROP_ARGS = "args";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_SCRIPT, PROP_DOCUMENT, PROP_USERPERSON, PROP_ARGS};
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Script node for the command
|
||||
NodeRef scriptRef = (NodeRef)properties.get(PROP_SCRIPT);
|
||||
if (scriptRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ExecuteScriptCommand - mandatory parameter not supplied: " + PROP_SCRIPT);
|
||||
}
|
||||
|
||||
NodeRef personRef = (NodeRef)properties.get(PROP_USERPERSON);
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ExecuteScriptCommand - mandatory parameter not supplied: " + PROP_USERPERSON);
|
||||
}
|
||||
|
||||
// get the optional document and space context ref
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
NodeRef docRef = (NodeRef)properties.get(PROP_DOCUMENT);
|
||||
NodeRef spaceRef = null;
|
||||
if (docRef != null)
|
||||
{
|
||||
spaceRef = nodeService.getPrimaryParent(docRef).getParentRef();
|
||||
}
|
||||
|
||||
// build the model needed to execute the script
|
||||
Map<String, Object> model = serviceRegistry.getScriptService().buildDefaultModel(
|
||||
personRef,
|
||||
new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()),
|
||||
(NodeRef)nodeService.getProperty(personRef, ContentModel.PROP_HOMEFOLDER),
|
||||
scriptRef,
|
||||
docRef,
|
||||
spaceRef);
|
||||
|
||||
// add the url arguments map
|
||||
model.put("args", properties.get(PROP_ARGS));
|
||||
|
||||
// execute the script and return the result
|
||||
return serviceRegistry.getScriptService().executeScript(scriptRef, null, model);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Execute Script command implementation.
|
||||
* <p>
|
||||
* Executes the supplied script against the default data-model.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ExecuteScriptCommand implements Command
|
||||
{
|
||||
public static final String PROP_SCRIPT = "script";
|
||||
public static final String PROP_DOCUMENT = "document";
|
||||
public static final String PROP_USERPERSON = "person";
|
||||
public static final String PROP_ARGS = "args";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_SCRIPT, PROP_DOCUMENT, PROP_USERPERSON, PROP_ARGS};
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Script node for the command
|
||||
NodeRef scriptRef = (NodeRef)properties.get(PROP_SCRIPT);
|
||||
if (scriptRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ExecuteScriptCommand - mandatory parameter not supplied: " + PROP_SCRIPT);
|
||||
}
|
||||
|
||||
NodeRef personRef = (NodeRef)properties.get(PROP_USERPERSON);
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute ExecuteScriptCommand - mandatory parameter not supplied: " + PROP_USERPERSON);
|
||||
}
|
||||
|
||||
// get the optional document and space context ref
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
NodeRef docRef = (NodeRef)properties.get(PROP_DOCUMENT);
|
||||
NodeRef spaceRef = null;
|
||||
if (docRef != null)
|
||||
{
|
||||
spaceRef = nodeService.getPrimaryParent(docRef).getParentRef();
|
||||
}
|
||||
|
||||
// build the model needed to execute the script
|
||||
Map<String, Object> model = serviceRegistry.getScriptService().buildDefaultModel(
|
||||
personRef,
|
||||
new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()),
|
||||
(NodeRef)nodeService.getProperty(personRef, ContentModel.PROP_HOMEFOLDER),
|
||||
scriptRef,
|
||||
docRef,
|
||||
spaceRef);
|
||||
|
||||
// add the url arguments map
|
||||
model.put("args", properties.get(PROP_ARGS));
|
||||
|
||||
// execute the script and return the result
|
||||
return serviceRegistry.getScriptService().executeScript(scriptRef, null, model);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* This interfaces defines the contract and lifecycle of a Servlet Command Processor.
|
||||
* <p>
|
||||
* The ExtCommandProcessor adds an overloaded process() method to allow the
|
||||
* HttpServletResponse to be passed.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface ExtCommandProcessor extends CommandProcessor
|
||||
{
|
||||
/**
|
||||
* Process the supplied command name. It is the responsibility of the Command Processor
|
||||
* to lookup the specified command name using the CommandFactory registry. For that reason
|
||||
* it also has the responsiblity to initially register commands it is responsible for so
|
||||
* they can be constructed later. If the supplied command is unknown to it then an
|
||||
* exception should be thrown to indicate this.
|
||||
*
|
||||
* @param serviceRegistry ServiceRegistry
|
||||
* @param request HttpServletRequest
|
||||
* @param response HttpServletResponse
|
||||
* @param command Name of the command to construct and execute
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, HttpServletResponse response, String command);
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* This interfaces defines the contract and lifecycle of a Servlet Command Processor.
|
||||
* <p>
|
||||
* The ExtCommandProcessor adds an overloaded process() method to allow the
|
||||
* HttpServletResponse to be passed.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface ExtCommandProcessor extends CommandProcessor
|
||||
{
|
||||
/**
|
||||
* Process the supplied command name. It is the responsibility of the Command Processor
|
||||
* to lookup the specified command name using the CommandFactory registry. For that reason
|
||||
* it also has the responsiblity to initially register commands it is responsible for so
|
||||
* they can be constructed later. If the supplied command is unknown to it then an
|
||||
* exception should be thrown to indicate this.
|
||||
*
|
||||
* @param serviceRegistry ServiceRegistry
|
||||
* @param request HttpServletRequest
|
||||
* @param response HttpServletResponse
|
||||
* @param command Name of the command to construct and execute
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, HttpServletResponse response, String command);
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.workflow.WorkflowBean;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
|
||||
/**
|
||||
* Command to execute the Manage Task dialog via url.
|
||||
* <p>
|
||||
* Arguments: id = the id of the task
|
||||
* type = the qname type of the task
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ManageTaskDialogCommand extends BaseUIActionCommand
|
||||
{
|
||||
public static final String PROP_TASKID = "id";
|
||||
public static final String PROP_TASKTYPE = "type";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {
|
||||
PROP_SERVLETCONTEXT, PROP_REQUEST, PROP_RESPONSE, PROP_TASKID, PROP_TASKTYPE};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
ServletContext sc = (ServletContext)properties.get(PROP_SERVLETCONTEXT);
|
||||
ServletRequest req = (ServletRequest)properties.get(PROP_REQUEST);
|
||||
ServletResponse res = (ServletResponse)properties.get(PROP_RESPONSE);
|
||||
FacesContext fc = FacesHelper.getFacesContext(req, res, sc, "/jsp/close.jsp");
|
||||
WorkflowBean wfBean = (WorkflowBean)FacesHelper.getManagedBean(fc, WorkflowBean.BEAN_NAME);
|
||||
|
||||
// setup dialog context from url args in properties map
|
||||
String taskId = (String)properties.get(PROP_TASKID);
|
||||
ParameterCheck.mandatoryString(PROP_TASKID, taskId);
|
||||
String taskType = (String)properties.get(PROP_TASKTYPE);
|
||||
ParameterCheck.mandatoryString(PROP_TASKTYPE, taskType);
|
||||
|
||||
wfBean.setupTaskDialog(taskId, taskType);
|
||||
|
||||
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
|
||||
navigationHandler.handleNavigation(fc, null, "dialog:manageTask");
|
||||
String viewId = fc.getViewRoot().getViewId();
|
||||
try
|
||||
{
|
||||
sc.getRequestDispatcher(BaseServlet.FACES_SERVLET + viewId).forward(req, res);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to forward to viewId: " + viewId, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.workflow.WorkflowBean;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
|
||||
/**
|
||||
* Command to execute the Manage Task dialog via url.
|
||||
* <p>
|
||||
* Arguments: id = the id of the task
|
||||
* type = the qname type of the task
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ManageTaskDialogCommand extends BaseUIActionCommand
|
||||
{
|
||||
public static final String PROP_TASKID = "id";
|
||||
public static final String PROP_TASKTYPE = "type";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {
|
||||
PROP_SERVLETCONTEXT, PROP_REQUEST, PROP_RESPONSE, PROP_TASKID, PROP_TASKTYPE};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
ServletContext sc = (ServletContext)properties.get(PROP_SERVLETCONTEXT);
|
||||
ServletRequest req = (ServletRequest)properties.get(PROP_REQUEST);
|
||||
ServletResponse res = (ServletResponse)properties.get(PROP_RESPONSE);
|
||||
FacesContext fc = FacesHelper.getFacesContext(req, res, sc, "/jsp/close.jsp");
|
||||
WorkflowBean wfBean = (WorkflowBean)FacesHelper.getManagedBean(fc, WorkflowBean.BEAN_NAME);
|
||||
|
||||
// setup dialog context from url args in properties map
|
||||
String taskId = (String)properties.get(PROP_TASKID);
|
||||
ParameterCheck.mandatoryString(PROP_TASKID, taskId);
|
||||
String taskType = (String)properties.get(PROP_TASKTYPE);
|
||||
ParameterCheck.mandatoryString(PROP_TASKTYPE, taskType);
|
||||
|
||||
wfBean.setupTaskDialog(taskId, taskType);
|
||||
|
||||
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
|
||||
navigationHandler.handleNavigation(fc, null, "dialog:manageTask");
|
||||
String viewId = fc.getViewRoot().getViewId();
|
||||
try
|
||||
{
|
||||
sc.getRequestDispatcher(BaseServlet.FACES_SERVLET + viewId).forward(req, res);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to forward to viewId: " + viewId, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
|
||||
/**
|
||||
* Reject Workflow command implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class RejectWorkflowCommand implements Command
|
||||
{
|
||||
public static final String PROP_TARGET = "target";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TARGET};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Node for the command
|
||||
NodeRef nodeRef = (NodeRef)properties.get(PROP_TARGET);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute RejectCommand - mandatory parameter not supplied: " + PROP_TARGET);
|
||||
}
|
||||
|
||||
WorkflowUtil.reject(nodeRef, serviceRegistry.getNodeService(), serviceRegistry.getCopyService());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
|
||||
/**
|
||||
* Reject Workflow command implementation
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class RejectWorkflowCommand implements Command
|
||||
{
|
||||
public static final String PROP_TARGET = "target";
|
||||
|
||||
private static final String[] PROPERTIES = new String[] {PROP_TARGET};
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#getPropertyNames()
|
||||
*/
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.Command#execute(org.alfresco.service.ServiceRegistry, java.util.Map)
|
||||
*/
|
||||
public Object execute(ServiceRegistry serviceRegistry, Map<String, Object> properties)
|
||||
{
|
||||
// get the target Node for the command
|
||||
NodeRef nodeRef = (NodeRef)properties.get(PROP_TARGET);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute RejectCommand - mandatory parameter not supplied: " + PROP_TARGET);
|
||||
}
|
||||
|
||||
WorkflowUtil.reject(nodeRef, serviceRegistry.getNodeService(), serviceRegistry.getCopyService());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,143 +1,143 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.config.ClientConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
|
||||
/**
|
||||
* Script command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing 'execute' script commands on a Node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ScriptCommandProcessor implements CommandProcessor
|
||||
{
|
||||
private static final String ARG_SCRIPT_PATH = "scriptPath";
|
||||
private static final String ARG_CONTEXT_PATH = "contextPath";
|
||||
|
||||
private NodeRef scriptRef;
|
||||
private NodeRef docRef;
|
||||
private Object result;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("execute", ExecuteScriptCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
boolean allowed = false;
|
||||
String scriptPath = args.get(ARG_SCRIPT_PATH);
|
||||
if (scriptPath != null)
|
||||
{
|
||||
// resolve path to a node
|
||||
this.scriptRef = BaseServlet.resolveNamePath(sc, scriptPath).NodeRef;
|
||||
|
||||
// same for the document context path if specified
|
||||
String docPath = args.get(ARG_CONTEXT_PATH);
|
||||
if (docPath != null)
|
||||
{
|
||||
this.docRef = BaseServlet.resolveNamePath(sc, docPath).NodeRef;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (urlElements.length < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
|
||||
// get NodeRef to the node script to execute
|
||||
StoreRef storeRef = new StoreRef(urlElements[0], urlElements[1]);
|
||||
this.scriptRef = new NodeRef(storeRef, urlElements[2]);
|
||||
|
||||
if (urlElements.length >= 6)
|
||||
{
|
||||
storeRef = new StoreRef(urlElements[3], urlElements[4]);
|
||||
this.docRef = new NodeRef(storeRef, urlElements[5]);
|
||||
}
|
||||
}
|
||||
|
||||
// check we can READ access the nodes specified
|
||||
PermissionService ps = Repository.getServiceRegistry(sc).getPermissionService();
|
||||
allowed = (ps.hasPermission(this.scriptRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
if (this.docRef != null)
|
||||
{
|
||||
allowed &= (ps.hasPermission(this.docRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
}
|
||||
|
||||
// check to see if user is allowed to execute arbituary javascript
|
||||
// by default only an admin authority can perform this action
|
||||
ConfigService configService = Application.getConfigService(sc);
|
||||
ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client");
|
||||
boolean allowScriptExecute = configElement.getAllowUserScriptExecute();
|
||||
AuthorityService authService = Repository.getServiceRegistry(sc).getAuthorityService();
|
||||
allowed &= (allowScriptExecute || authService.isAdminAuthority(AuthenticationUtil.getFullyAuthenticatedUser()));
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(4, 1.0f);
|
||||
|
||||
properties.put(ExecuteScriptCommand.PROP_SCRIPT, this.scriptRef);
|
||||
properties.put(ExecuteScriptCommand.PROP_DOCUMENT, this.docRef);
|
||||
User user = Application.getCurrentUser(request.getSession());
|
||||
properties.put(ExecuteScriptCommand.PROP_USERPERSON, user.getPerson());
|
||||
|
||||
// add URL arguments as a special Scriptable Map property called 'args'
|
||||
Map<String, String> args = new ScriptableHashMap<String, String>();
|
||||
Enumeration names = request.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
args.put(name, request.getParameter(name));
|
||||
}
|
||||
properties.put(ExecuteScriptCommand.PROP_ARGS, args);
|
||||
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered script command specified: " + command);
|
||||
}
|
||||
this.result = cmd.execute(serviceRegistry, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.write(this.result != null ? this.result.toString() : "Successfully executed script.");
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.config.ClientConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
|
||||
/**
|
||||
* Script command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing 'execute' script commands on a Node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class ScriptCommandProcessor implements CommandProcessor
|
||||
{
|
||||
private static final String ARG_SCRIPT_PATH = "scriptPath";
|
||||
private static final String ARG_CONTEXT_PATH = "contextPath";
|
||||
|
||||
private NodeRef scriptRef;
|
||||
private NodeRef docRef;
|
||||
private Object result;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("execute", ExecuteScriptCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
boolean allowed = false;
|
||||
String scriptPath = args.get(ARG_SCRIPT_PATH);
|
||||
if (scriptPath != null)
|
||||
{
|
||||
// resolve path to a node
|
||||
this.scriptRef = BaseServlet.resolveNamePath(sc, scriptPath).NodeRef;
|
||||
|
||||
// same for the document context path if specified
|
||||
String docPath = args.get(ARG_CONTEXT_PATH);
|
||||
if (docPath != null)
|
||||
{
|
||||
this.docRef = BaseServlet.resolveNamePath(sc, docPath).NodeRef;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (urlElements.length < 3)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
|
||||
// get NodeRef to the node script to execute
|
||||
StoreRef storeRef = new StoreRef(urlElements[0], urlElements[1]);
|
||||
this.scriptRef = new NodeRef(storeRef, urlElements[2]);
|
||||
|
||||
if (urlElements.length >= 6)
|
||||
{
|
||||
storeRef = new StoreRef(urlElements[3], urlElements[4]);
|
||||
this.docRef = new NodeRef(storeRef, urlElements[5]);
|
||||
}
|
||||
}
|
||||
|
||||
// check we can READ access the nodes specified
|
||||
PermissionService ps = Repository.getServiceRegistry(sc).getPermissionService();
|
||||
allowed = (ps.hasPermission(this.scriptRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
if (this.docRef != null)
|
||||
{
|
||||
allowed &= (ps.hasPermission(this.docRef, PermissionService.READ) == AccessStatus.ALLOWED);
|
||||
}
|
||||
|
||||
// check to see if user is allowed to execute arbituary javascript
|
||||
// by default only an admin authority can perform this action
|
||||
ConfigService configService = Application.getConfigService(sc);
|
||||
ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client");
|
||||
boolean allowScriptExecute = configElement.getAllowUserScriptExecute();
|
||||
AuthorityService authService = Repository.getServiceRegistry(sc).getAuthorityService();
|
||||
allowed &= (allowScriptExecute || authService.isAdminAuthority(AuthenticationUtil.getFullyAuthenticatedUser()));
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(4, 1.0f);
|
||||
|
||||
properties.put(ExecuteScriptCommand.PROP_SCRIPT, this.scriptRef);
|
||||
properties.put(ExecuteScriptCommand.PROP_DOCUMENT, this.docRef);
|
||||
User user = Application.getCurrentUser(request.getSession());
|
||||
properties.put(ExecuteScriptCommand.PROP_USERPERSON, user.getPerson());
|
||||
|
||||
// add URL arguments as a special Scriptable Map property called 'args'
|
||||
Map<String, String> args = new ScriptableHashMap<String, String>();
|
||||
Enumeration names = request.getParameterNames();
|
||||
while (names.hasMoreElements())
|
||||
{
|
||||
String name = (String)names.nextElement();
|
||||
args.put(name, request.getParameter(name));
|
||||
}
|
||||
properties.put(ExecuteScriptCommand.PROP_ARGS, args);
|
||||
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered script command specified: " + command);
|
||||
}
|
||||
this.result = cmd.execute(serviceRegistry, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.write(this.result != null ? this.result.toString() : "Successfully executed script.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Task specific command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing workflow task operations.
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public final class TaskCommandProcessor implements CommandProcessor
|
||||
{
|
||||
private String taskId;
|
||||
private String transition = null;
|
||||
private String command;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("end", EndTaskCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String cmd, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
if (urlElements.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
taskId = urlElements[0];
|
||||
if (urlElements.length == 2)
|
||||
{
|
||||
transition = urlElements[1];
|
||||
}
|
||||
return WorkflowUtil.isTaskEditable(taskId, sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String commandName)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(1, 1.0f);
|
||||
// all workflow commands use a "target" Node property as an argument
|
||||
properties.put(EndTaskCommand.PROP_TASK_ID, taskId);
|
||||
if (transition != null)
|
||||
{
|
||||
properties.put(EndTaskCommand.PROP_TRANSITION, transition);
|
||||
}
|
||||
Command cmd = CommandFactory.getInstance().createCommand(commandName);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered workflow command specified: " + commandName);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
this.command = commandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("Task command: '");
|
||||
out.print(Utils.encode(command));
|
||||
out.print("' executed against task: ");
|
||||
out.println(Utils.encode(taskId));
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Task specific command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing workflow task operations.
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public final class TaskCommandProcessor implements CommandProcessor
|
||||
{
|
||||
private String taskId;
|
||||
private String transition = null;
|
||||
private String command;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("end", EndTaskCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String cmd, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
if (urlElements.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Not enough URL arguments passed to command servlet.");
|
||||
}
|
||||
taskId = urlElements[0];
|
||||
if (urlElements.length == 2)
|
||||
{
|
||||
transition = urlElements[1];
|
||||
}
|
||||
return WorkflowUtil.isTaskEditable(taskId, sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String commandName)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(1, 1.0f);
|
||||
// all workflow commands use a "target" Node property as an argument
|
||||
properties.put(EndTaskCommand.PROP_TASK_ID, taskId);
|
||||
if (transition != null)
|
||||
{
|
||||
properties.put(EndTaskCommand.PROP_TRANSITION, transition);
|
||||
}
|
||||
Command cmd = CommandFactory.getInstance().createCommand(commandName);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered workflow command specified: " + commandName);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
this.command = commandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("Task command: '");
|
||||
out.print(Utils.encode(command));
|
||||
out.print("' executed against task: ");
|
||||
out.println(Utils.encode(taskId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,112 +1,112 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* UI action command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing specific UI actions via a REST style URL interface.
|
||||
* <p>
|
||||
* The URL postfix for each specific command depends on the context that is required
|
||||
* for that command. For example, a command to launch the Create Web Content dialog may
|
||||
* require the current sandbox and the current web project as its context e.g.
|
||||
* <br>
|
||||
* http://server/alfresco/command/ui/createwebcontent?sandbox=website1&webproject=1234567890
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UIActionCommandProcessor implements ExtCommandProcessor
|
||||
{
|
||||
private static final String MANAGE_TASK = "managetask";
|
||||
|
||||
public static final String PARAM_CONTAINER = "container";
|
||||
|
||||
private ServletContext sc = null;
|
||||
private String command = null;
|
||||
private Map<String, String> args = null;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand(MANAGE_TASK, ManageTaskDialogCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("editcontentprops", EditContentPropertiesCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("userprofile", UserProfileDialogCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("editspace", EditSpaceCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
this.sc = sc;
|
||||
if (args.size() != 0)
|
||||
{
|
||||
this.args = new HashMap<String, String>(args);
|
||||
}
|
||||
if (MANAGE_TASK.equals(command))
|
||||
{
|
||||
String taskId = args.get(ManageTaskDialogCommand.PROP_TASKID);
|
||||
return WorkflowUtil.isTaskEditable(taskId, sc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
// not implemented in ExtCommandProcessor!
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.ExtCommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, HttpServletResponse response, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(this.args);
|
||||
|
||||
properties.put(BaseUIActionCommand.PROP_SERVLETCONTEXT, this.sc);
|
||||
properties.put(BaseUIActionCommand.PROP_REQUEST, request);
|
||||
properties.put(BaseUIActionCommand.PROP_RESPONSE, response);
|
||||
|
||||
// if the container parameter is present and equal to "plain" add the
|
||||
// external container object to the session
|
||||
String container = request.getParameter(PARAM_CONTAINER);
|
||||
if (container != null && container.equalsIgnoreCase("plain"))
|
||||
{
|
||||
request.getSession().setAttribute(
|
||||
AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION, Boolean.TRUE);
|
||||
}
|
||||
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered UI Action command specified: " + command);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("UI Action command: '");
|
||||
out.print(Utils.encode(this.command));
|
||||
out.print("' executed with args: ");
|
||||
out.println(this.args != null ? (Utils.encode(this.args.toString())) : "");
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.bean.workflow.WorkflowUtil;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* UI action command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing specific UI actions via a REST style URL interface.
|
||||
* <p>
|
||||
* The URL postfix for each specific command depends on the context that is required
|
||||
* for that command. For example, a command to launch the Create Web Content dialog may
|
||||
* require the current sandbox and the current web project as its context e.g.
|
||||
* <br>
|
||||
* http://server/alfresco/command/ui/createwebcontent?sandbox=website1&webproject=1234567890
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UIActionCommandProcessor implements ExtCommandProcessor
|
||||
{
|
||||
private static final String MANAGE_TASK = "managetask";
|
||||
|
||||
public static final String PARAM_CONTAINER = "container";
|
||||
|
||||
private ServletContext sc = null;
|
||||
private String command = null;
|
||||
private Map<String, String> args = null;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand(MANAGE_TASK, ManageTaskDialogCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("editcontentprops", EditContentPropertiesCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("userprofile", UserProfileDialogCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("editspace", EditSpaceCommand.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#validateArguments(javax.servlet.ServletContext, java.lang.String, java.util.Map, java.lang.String[])
|
||||
*/
|
||||
public boolean validateArguments(ServletContext sc, String command, Map<String, String> args, String[] urlElements)
|
||||
{
|
||||
this.sc = sc;
|
||||
if (args.size() != 0)
|
||||
{
|
||||
this.args = new HashMap<String, String>(args);
|
||||
}
|
||||
if (MANAGE_TASK.equals(command))
|
||||
{
|
||||
String taskId = args.get(ManageTaskDialogCommand.PROP_TASKID);
|
||||
return WorkflowUtil.isTaskEditable(taskId, sc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
// not implemented in ExtCommandProcessor!
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.ExtCommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, HttpServletResponse response, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(this.args);
|
||||
|
||||
properties.put(BaseUIActionCommand.PROP_SERVLETCONTEXT, this.sc);
|
||||
properties.put(BaseUIActionCommand.PROP_REQUEST, request);
|
||||
properties.put(BaseUIActionCommand.PROP_RESPONSE, response);
|
||||
|
||||
// if the container parameter is present and equal to "plain" add the
|
||||
// external container object to the session
|
||||
String container = request.getParameter(PARAM_CONTAINER);
|
||||
if (container != null && container.equalsIgnoreCase("plain"))
|
||||
{
|
||||
request.getSession().setAttribute(
|
||||
AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION, Boolean.TRUE);
|
||||
}
|
||||
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered UI Action command specified: " + command);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("UI Action command: '");
|
||||
out.print(Utils.encode(this.command));
|
||||
out.print("' executed with args: ");
|
||||
out.println(this.args != null ? (Utils.encode(this.args.toString())) : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Workflow specific command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing 'approve' and 'reject' workflow commands on a Node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class WorkflowCommandProcessor extends BaseNodeCommandProcessor
|
||||
{
|
||||
private String command;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("approve", ApproveWorkflowCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("reject", RejectWorkflowCommand.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(1, 1.0f);
|
||||
// all workflow commands use a "target" Node property as an argument
|
||||
properties.put(ApproveWorkflowCommand.PROP_TARGET, this.targetRef);
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered workflow command specified: " + command);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("Workflow command: '");
|
||||
out.print(Utils.encode(this.command));
|
||||
out.print("' executed against node: ");
|
||||
out.println(Utils.encode(this.targetRef.toString()));
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.app.servlet.command;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Workflow specific command processor implementation.
|
||||
* <p>
|
||||
* Responsible for executing 'approve' and 'reject' workflow commands on a Node.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public final class WorkflowCommandProcessor extends BaseNodeCommandProcessor
|
||||
{
|
||||
private String command;
|
||||
|
||||
static
|
||||
{
|
||||
// add our commands to the command registry
|
||||
CommandFactory.getInstance().registerCommand("approve", ApproveWorkflowCommand.class);
|
||||
CommandFactory.getInstance().registerCommand("reject", RejectWorkflowCommand.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#process(org.alfresco.service.ServiceRegistry, javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command)
|
||||
{
|
||||
Map<String, Object> properties = new HashMap<String, Object>(1, 1.0f);
|
||||
// all workflow commands use a "target" Node property as an argument
|
||||
properties.put(ApproveWorkflowCommand.PROP_TARGET, this.targetRef);
|
||||
Command cmd = CommandFactory.getInstance().createCommand(command);
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unregistered workflow command specified: " + command);
|
||||
}
|
||||
cmd.execute(serviceRegistry, properties);
|
||||
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.servlet.command.CommandProcessor#outputStatus(java.io.PrintWriter)
|
||||
*/
|
||||
public void outputStatus(PrintWriter out)
|
||||
{
|
||||
out.print("Workflow command: '");
|
||||
out.print(Utils.encode(this.command));
|
||||
out.print("' executed against node: ");
|
||||
out.println(Utils.encode(this.targetRef.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Simple backing bean used by the about page to display the version.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AboutBean extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -3777479360531145878L;
|
||||
|
||||
private final static String MSG_VERSION = "version";
|
||||
private final static String MSG_CLOSE = "close";
|
||||
|
||||
transient private DescriptorService descriptorService;
|
||||
|
||||
/**
|
||||
* Retrieves the version of the repository.
|
||||
*
|
||||
* @return The version string
|
||||
*/
|
||||
public String getVersion()
|
||||
{
|
||||
return this.getDescriptorService().getServerDescriptor().getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the edition of the repository.
|
||||
*
|
||||
* @return The edition
|
||||
*/
|
||||
public String getEdition()
|
||||
{
|
||||
return this.getDescriptorService().getServerDescriptor().getEdition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DescriptorService.
|
||||
*
|
||||
* @param descriptorService The DescriptorService
|
||||
*/
|
||||
public void setDescriptorService(DescriptorService descriptorService)
|
||||
{
|
||||
this.descriptorService = descriptorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerDescription()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_VERSION) + " :" + getEdition() + " - v" + getVersion();
|
||||
}
|
||||
|
||||
DescriptorService getDescriptorService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (descriptorService == null)
|
||||
{
|
||||
descriptorService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDescriptorService();
|
||||
}
|
||||
return descriptorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultCancelOutcome()
|
||||
{
|
||||
return "dialog:close:browse";
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
/**
|
||||
* Simple backing bean used by the about page to display the version.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AboutBean extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -3777479360531145878L;
|
||||
|
||||
private final static String MSG_VERSION = "version";
|
||||
private final static String MSG_CLOSE = "close";
|
||||
|
||||
transient private DescriptorService descriptorService;
|
||||
|
||||
/**
|
||||
* Retrieves the version of the repository.
|
||||
*
|
||||
* @return The version string
|
||||
*/
|
||||
public String getVersion()
|
||||
{
|
||||
return this.getDescriptorService().getServerDescriptor().getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the edition of the repository.
|
||||
*
|
||||
* @return The edition
|
||||
*/
|
||||
public String getEdition()
|
||||
{
|
||||
return this.getDescriptorService().getServerDescriptor().getEdition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DescriptorService.
|
||||
*
|
||||
* @param descriptorService The DescriptorService
|
||||
*/
|
||||
public void setDescriptorService(DescriptorService descriptorService)
|
||||
{
|
||||
this.descriptorService = descriptorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerDescription()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_VERSION) + " :" + getEdition() + " - v" + getVersion();
|
||||
}
|
||||
|
||||
DescriptorService getDescriptorService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (descriptorService == null)
|
||||
{
|
||||
descriptorService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDescriptorService();
|
||||
}
|
||||
return descriptorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultCancelOutcome()
|
||||
{
|
||||
return "dialog:close:browse";
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +1,144 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
|
||||
public class CategoriesProperties
|
||||
{
|
||||
|
||||
protected CategoryService categoryService;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
/** RichList view mode */
|
||||
private String viewMode = "icons";
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
public CategoryService getCategoryService()
|
||||
{
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
public void setActionCategory(Node actionCategory)
|
||||
{
|
||||
this.actionCategory = actionCategory;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getViewMode()
|
||||
{
|
||||
return viewMode;
|
||||
}
|
||||
|
||||
public void setViewMode(String viewMode)
|
||||
{
|
||||
this.viewMode = viewMode;
|
||||
}
|
||||
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
|
||||
public class CategoriesProperties
|
||||
{
|
||||
|
||||
protected CategoryService categoryService;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
/** RichList view mode */
|
||||
private String viewMode = "icons";
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
public CategoryService getCategoryService()
|
||||
{
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
public void setActionCategory(Node actionCategory)
|
||||
{
|
||||
this.actionCategory = actionCategory;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getViewMode()
|
||||
{
|
||||
return viewMode;
|
||||
}
|
||||
|
||||
public void setViewMode(String viewMode)
|
||||
{
|
||||
this.viewMode = viewMode;
|
||||
}
|
||||
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.bean.search.SearchContext;
|
||||
|
||||
public class CategoryBrowserBean
|
||||
{
|
||||
public static String BEAN_NAME = "CategoryBrowserBean";
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
private NodeRef currentCategory = null;
|
||||
|
||||
private boolean includeSubcategories = false;
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setCurrentCategory(NodeRef currentCategory)
|
||||
{
|
||||
this.currentCategory = currentCategory;
|
||||
}
|
||||
|
||||
public String getCurrentCategoryName()
|
||||
{
|
||||
String currentCategoryName = null;
|
||||
if (currentCategory != null)
|
||||
currentCategoryName = (String) this.nodeService.getProperty(currentCategory, ContentModel.PROP_NAME);
|
||||
|
||||
return currentCategoryName;
|
||||
}
|
||||
|
||||
public boolean isIncludeSubcategories()
|
||||
{
|
||||
return includeSubcategories;
|
||||
}
|
||||
|
||||
public void setIncludeSubcategories(boolean includeSubcategories)
|
||||
{
|
||||
this.includeSubcategories = includeSubcategories;
|
||||
}
|
||||
|
||||
public SearchContext generateCategorySearchContext()
|
||||
{
|
||||
SearchContext categorySearch = new SearchContext();
|
||||
|
||||
String[] categories = new String[1];
|
||||
categories[0] = SearchContext.getPathFromSpaceRef(currentCategory, includeSubcategories);
|
||||
|
||||
categorySearch.setText("");
|
||||
categorySearch.setCategories(categories);
|
||||
|
||||
return categorySearch;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.bean.search.SearchContext;
|
||||
|
||||
public class CategoryBrowserBean
|
||||
{
|
||||
public static String BEAN_NAME = "CategoryBrowserBean";
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
private NodeRef currentCategory = null;
|
||||
|
||||
private boolean includeSubcategories = false;
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setCurrentCategory(NodeRef currentCategory)
|
||||
{
|
||||
this.currentCategory = currentCategory;
|
||||
}
|
||||
|
||||
public String getCurrentCategoryName()
|
||||
{
|
||||
String currentCategoryName = null;
|
||||
if (currentCategory != null)
|
||||
currentCategoryName = (String) this.nodeService.getProperty(currentCategory, ContentModel.PROP_NAME);
|
||||
|
||||
return currentCategoryName;
|
||||
}
|
||||
|
||||
public boolean isIncludeSubcategories()
|
||||
{
|
||||
return includeSubcategories;
|
||||
}
|
||||
|
||||
public void setIncludeSubcategories(boolean includeSubcategories)
|
||||
{
|
||||
this.includeSubcategories = includeSubcategories;
|
||||
}
|
||||
|
||||
public SearchContext generateCategorySearchContext()
|
||||
{
|
||||
SearchContext categorySearch = new SearchContext();
|
||||
|
||||
String[] categories = new String[1];
|
||||
categories[0] = SearchContext.getPathFromSpaceRef(currentCategory, includeSubcategories);
|
||||
|
||||
categorySearch.setText("");
|
||||
categorySearch.setCategories(categories);
|
||||
|
||||
return categorySearch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,229 +1,229 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.Utils.URLMode;
|
||||
|
||||
/**
|
||||
* Backing bean for the edit link properties dialog
|
||||
*
|
||||
* @author kevinr
|
||||
* @author YanO
|
||||
*/
|
||||
public class LinkPropertiesDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -167326851073011187L;
|
||||
|
||||
private Node editableNode = null;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
// reset node instance for next dialog invocation
|
||||
this.editableNode = null;
|
||||
}
|
||||
|
||||
public Map<String, Object> getProperties()
|
||||
{
|
||||
return getEditableNode().getProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node being edited
|
||||
*
|
||||
* @return The node being edited
|
||||
*/
|
||||
public Node getEditableNode()
|
||||
{
|
||||
if (this.editableNode == null)
|
||||
{
|
||||
if (this.parameters.containsKey("nodeRef"))
|
||||
{
|
||||
this.editableNode = new Node(new NodeRef(this.parameters.get("nodeRef")));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Dialog has not been initialised with noderef or setup action event called.");
|
||||
}
|
||||
}
|
||||
return this.editableNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler called to setup the link object for property editing
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
public void setupFileLinkForAction(ActionEvent event)
|
||||
{
|
||||
this.editableNode = new Node(this.browseBean.getDocument().getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler called to setup the link object for property editing
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
public void setupFolderLinkForAction(ActionEvent event)
|
||||
{
|
||||
this.editableNode = new Node(this.browseBean.getActionSpace().getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Human readable version of the Path to the destination object
|
||||
*/
|
||||
public String getDestinationPath()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)getEditableNode().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Repository.getNamePath(
|
||||
this.getNodeService(), this.getNodeService().getPath(destRef), null, "/", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to access the details page for the current document link object
|
||||
*
|
||||
* @return The bookmark URL
|
||||
*/
|
||||
public String getFileLinkBookmarkUrl()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)this.browseBean.getDocument().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.SHOW_DETAILS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to access the details page for the current document link object
|
||||
*
|
||||
* @return The bookmark URL
|
||||
*/
|
||||
public String getSpaceLinkDestinationUrl()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)this.browseBean.getActionSpace().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.SHOW_DETAILS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = getEditableNode().getNodeRef();
|
||||
Map<String, Object> props = getEditableNode().getProperties();
|
||||
|
||||
//get the name and move the node as necessary
|
||||
String name = (String) props.get(ContentModel.PROP_NAME);
|
||||
if (name != null)
|
||||
{
|
||||
getFileFolderService().rename(nodeRef, name);
|
||||
}
|
||||
|
||||
Map<QName, Serializable> properties = this.getNodeService().getProperties(nodeRef);
|
||||
|
||||
// we need to put all the properties from the editable bag back into
|
||||
// the format expected by the repository
|
||||
|
||||
// deal with adding the "titled" aspect if required
|
||||
String title = (String)props.get(ContentModel.PROP_TITLE);
|
||||
String description = (String)props.get(ContentModel.PROP_DESCRIPTION);
|
||||
if (title != null || description != null)
|
||||
{
|
||||
// add the aspect to be sure it's present
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
|
||||
// other props will get added later in setProperties()
|
||||
}
|
||||
|
||||
// add the remaining properties
|
||||
Iterator<String> iterProps = props.keySet().iterator();
|
||||
while (iterProps.hasNext())
|
||||
{
|
||||
String propName = iterProps.next();
|
||||
QName qname = QName.createQName(propName);
|
||||
|
||||
// make sure the property is represented correctly
|
||||
Serializable propValue = (Serializable)props.get(propName);
|
||||
|
||||
// check for empty strings when using number types, set to null in this case
|
||||
if ((propValue != null) && (propValue instanceof String) &&
|
||||
(propValue.toString().length() == 0))
|
||||
{
|
||||
PropertyDefinition propDef = this.getDictionaryService().getProperty(qname);
|
||||
if (propDef != null)
|
||||
{
|
||||
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
|
||||
{
|
||||
propValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
properties.put(qname, propValue);
|
||||
}
|
||||
|
||||
// send the properties back to the repository
|
||||
this.getNodeService().setProperties(nodeRef, properties);
|
||||
}
|
||||
catch (InvalidNodeRefException err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_NODEREF), new Object[] {this.browseBean.getDocument().getId()}));
|
||||
|
||||
// this failure means the node no longer exists - we cannot show the doc properties screen
|
||||
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_GENERIC), e.getMessage()), e);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(e);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
if (this.browseBean.getDocument() != null)
|
||||
{
|
||||
this.browseBean.getDocument().reset();
|
||||
}
|
||||
else if (this.browseBean.getActionSpace() != null)
|
||||
{
|
||||
this.browseBean.getActionSpace().reset();
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.Utils.URLMode;
|
||||
|
||||
/**
|
||||
* Backing bean for the edit link properties dialog
|
||||
*
|
||||
* @author kevinr
|
||||
* @author YanO
|
||||
*/
|
||||
public class LinkPropertiesDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -167326851073011187L;
|
||||
|
||||
private Node editableNode = null;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
// reset node instance for next dialog invocation
|
||||
this.editableNode = null;
|
||||
}
|
||||
|
||||
public Map<String, Object> getProperties()
|
||||
{
|
||||
return getEditableNode().getProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node being edited
|
||||
*
|
||||
* @return The node being edited
|
||||
*/
|
||||
public Node getEditableNode()
|
||||
{
|
||||
if (this.editableNode == null)
|
||||
{
|
||||
if (this.parameters.containsKey("nodeRef"))
|
||||
{
|
||||
this.editableNode = new Node(new NodeRef(this.parameters.get("nodeRef")));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Dialog has not been initialised with noderef or setup action event called.");
|
||||
}
|
||||
}
|
||||
return this.editableNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler called to setup the link object for property editing
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
public void setupFileLinkForAction(ActionEvent event)
|
||||
{
|
||||
this.editableNode = new Node(this.browseBean.getDocument().getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler called to setup the link object for property editing
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
public void setupFolderLinkForAction(ActionEvent event)
|
||||
{
|
||||
this.editableNode = new Node(this.browseBean.getActionSpace().getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Human readable version of the Path to the destination object
|
||||
*/
|
||||
public String getDestinationPath()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)getEditableNode().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Repository.getNamePath(
|
||||
this.getNodeService(), this.getNodeService().getPath(destRef), null, "/", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to access the details page for the current document link object
|
||||
*
|
||||
* @return The bookmark URL
|
||||
*/
|
||||
public String getFileLinkBookmarkUrl()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)this.browseBean.getDocument().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.SHOW_DETAILS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to access the details page for the current document link object
|
||||
*
|
||||
* @return The bookmark URL
|
||||
*/
|
||||
public String getSpaceLinkDestinationUrl()
|
||||
{
|
||||
NodeRef destRef = (NodeRef)this.browseBean.getActionSpace().getProperties().get(ContentModel.PROP_LINK_DESTINATION);
|
||||
return Utils.generateURL(FacesContext.getCurrentInstance(), new Node(destRef), URLMode.SHOW_DETAILS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = getEditableNode().getNodeRef();
|
||||
Map<String, Object> props = getEditableNode().getProperties();
|
||||
|
||||
//get the name and move the node as necessary
|
||||
String name = (String) props.get(ContentModel.PROP_NAME);
|
||||
if (name != null)
|
||||
{
|
||||
getFileFolderService().rename(nodeRef, name);
|
||||
}
|
||||
|
||||
Map<QName, Serializable> properties = this.getNodeService().getProperties(nodeRef);
|
||||
|
||||
// we need to put all the properties from the editable bag back into
|
||||
// the format expected by the repository
|
||||
|
||||
// deal with adding the "titled" aspect if required
|
||||
String title = (String)props.get(ContentModel.PROP_TITLE);
|
||||
String description = (String)props.get(ContentModel.PROP_DESCRIPTION);
|
||||
if (title != null || description != null)
|
||||
{
|
||||
// add the aspect to be sure it's present
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
|
||||
// other props will get added later in setProperties()
|
||||
}
|
||||
|
||||
// add the remaining properties
|
||||
Iterator<String> iterProps = props.keySet().iterator();
|
||||
while (iterProps.hasNext())
|
||||
{
|
||||
String propName = iterProps.next();
|
||||
QName qname = QName.createQName(propName);
|
||||
|
||||
// make sure the property is represented correctly
|
||||
Serializable propValue = (Serializable)props.get(propName);
|
||||
|
||||
// check for empty strings when using number types, set to null in this case
|
||||
if ((propValue != null) && (propValue instanceof String) &&
|
||||
(propValue.toString().length() == 0))
|
||||
{
|
||||
PropertyDefinition propDef = this.getDictionaryService().getProperty(qname);
|
||||
if (propDef != null)
|
||||
{
|
||||
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
|
||||
{
|
||||
propValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
properties.put(qname, propValue);
|
||||
}
|
||||
|
||||
// send the properties back to the repository
|
||||
this.getNodeService().setProperties(nodeRef, properties);
|
||||
}
|
||||
catch (InvalidNodeRefException err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_NODEREF), new Object[] {this.browseBean.getDocument().getId()}));
|
||||
|
||||
// this failure means the node no longer exists - we cannot show the doc properties screen
|
||||
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
context, Repository.ERROR_GENERIC), e.getMessage()), e);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(e);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
if (this.browseBean.getDocument() != null)
|
||||
{
|
||||
this.browseBean.getDocument().reset();
|
||||
}
|
||||
else if (this.browseBean.getActionSpace() != null)
|
||||
{
|
||||
this.browseBean.getActionSpace().reset();
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper bean used to temporarily store the last item added in a multi
|
||||
* value editor component.
|
||||
*
|
||||
* A Map is used so that multiple components on the same page can use the
|
||||
* same backing bean.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class MultiValueEditorBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -5180578793877515158L;
|
||||
|
||||
private Map<String, Object> lastItemsAdded = new HashMap<String, Object>(10);
|
||||
|
||||
public Map<String, Object> getLastItemsAdded()
|
||||
{
|
||||
return lastItemsAdded;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper bean used to temporarily store the last item added in a multi
|
||||
* value editor component.
|
||||
*
|
||||
* A Map is used so that multiple components on the same page can use the
|
||||
* same backing bean.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class MultiValueEditorBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -5180578793877515158L;
|
||||
|
||||
private Map<String, Object> lastItemsAdded = new HashMap<String, Object>(10);
|
||||
|
||||
public Map<String, Object> getLastItemsAdded()
|
||||
{
|
||||
return lastItemsAdded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface NodeEventListener extends Serializable
|
||||
{
|
||||
/**
|
||||
* Callback executed when a Node wrapped object is created. This is generally used
|
||||
* to add additional property resolvers to the Node for a specific model type.
|
||||
*
|
||||
* @param node The Node wrapper that has been created
|
||||
* @param type Type of the Node that has been created
|
||||
*/
|
||||
public void created(Node node, QName type);
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public interface NodeEventListener extends Serializable
|
||||
{
|
||||
/**
|
||||
* Callback executed when a Node wrapped object is created. This is generally used
|
||||
* to add additional property resolvers to the Node for a specific model type.
|
||||
*
|
||||
* @param node The Node wrapper that has been created
|
||||
* @param type Type of the Node that has been created
|
||||
*/
|
||||
public void created(Node node, QName type);
|
||||
}
|
||||
|
||||
@@ -1,292 +1,292 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.executer.MailActionExecuter;
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.UrlUtil;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.mail.javamail.MimeMessagePreparator;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TemplateMailHelperBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 9117248002321651339L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(TemplateMailHelperBean.class);
|
||||
|
||||
/** JavaMailSender bean reference */
|
||||
transient private JavaMailSender mailSender;
|
||||
|
||||
/** NodeService bean reference */
|
||||
transient private NodeService nodeService;
|
||||
|
||||
/** dialog state */
|
||||
private String subject = null;
|
||||
private String body = null;
|
||||
private String automaticText = null;
|
||||
private String template = null;
|
||||
private String usingTemplate = null;
|
||||
private String finalBody;
|
||||
|
||||
/**
|
||||
* @param mailSender The JavaMailSender to set.
|
||||
*/
|
||||
public void setMailSender(JavaMailSender mailSender)
|
||||
{
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
protected JavaMailSender getMailSender()
|
||||
{
|
||||
if (mailSender == null)
|
||||
{
|
||||
mailSender = (JavaMailSender) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "mailService");
|
||||
}
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService The nodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
protected NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the bean
|
||||
*/
|
||||
public TemplateMailHelperBean()
|
||||
{
|
||||
subject = "";
|
||||
body = "";
|
||||
automaticText = "";
|
||||
template = null;
|
||||
usingTemplate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email notification to the specified User authority
|
||||
*
|
||||
* @param person Person node representing the user
|
||||
* @param node Node they are invited too
|
||||
* @param from From text message
|
||||
* @param roleText The role display label for the user invite notification
|
||||
*/
|
||||
public void notifyUser(NodeRef person, NodeRef node, final String from, String roleText)
|
||||
{
|
||||
final String to = (String)this.getNodeService().getProperty(person, ContentModel.PROP_EMAIL);
|
||||
|
||||
if (to != null && to.length() != 0)
|
||||
{
|
||||
String body = this.body;
|
||||
if (this.usingTemplate != null)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// use template service to format the email
|
||||
NodeRef templateRef = new NodeRef(Repository.getStoreRef(), this.usingTemplate);
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
Map<String, Object> model = DefaultModelHelper.buildDefaultModel(
|
||||
services, Application.getCurrentUser(fc), templateRef);
|
||||
model.put("role", roleText);
|
||||
model.put("space", node);
|
||||
// object to allow client urls to be generated in emails
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(fc));
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("document", node);
|
||||
if (nodeService.getType(node).equals(ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
NodeRef parentNodeRef = nodeService.getParentAssocs(node).get(0).getParentRef();
|
||||
if (parentNodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Parent folder doesn't exists for node: " + node);
|
||||
}
|
||||
model.put("space", parentNodeRef);
|
||||
}
|
||||
model.put("shareUrl", UrlUtil.getShareUrl(services.getSysAdminParams()));
|
||||
|
||||
body = services.getTemplateService().processTemplate("freemarker", templateRef.toString(), model);
|
||||
}
|
||||
this.finalBody = body;
|
||||
|
||||
MimeMessagePreparator mailPreparer = new MimeMessagePreparator()
|
||||
{
|
||||
public void prepare(MimeMessage mimeMessage) throws MessagingException
|
||||
{
|
||||
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
|
||||
message.setTo(to);
|
||||
message.setSubject(subject);
|
||||
message.setText(finalBody, MailActionExecuter.isHTML(finalBody));
|
||||
message.setFrom(from);
|
||||
}
|
||||
};
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Sending notification email to: " + to + "\n...with subject:\n" + subject + "\n...with body:\n" + body);
|
||||
|
||||
try
|
||||
{
|
||||
// Send the message
|
||||
this.getMailSender().send(mailPreparer);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// don't stop the action but let admins know email is not getting sent
|
||||
logger.error("Failed to send email to " + to, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called to insert a template as the email body
|
||||
*/
|
||||
public void insertTemplate(ActionEvent event)
|
||||
{
|
||||
if (this.template != null && this.template.equals(TemplateSupportBean.NO_SELECTION) == false)
|
||||
{
|
||||
// get the content of the template so the user can get a basic preview of it
|
||||
try
|
||||
{
|
||||
NodeRef templateRef = new NodeRef(Repository.getStoreRef(), this.template);
|
||||
ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService();
|
||||
ContentReader reader = cs.getReader(templateRef, ContentModel.PROP_CONTENT);
|
||||
if (reader != null && reader.exists())
|
||||
{
|
||||
this.body = reader.getContentString();
|
||||
|
||||
this.usingTemplate = this.template;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called to discard the template from the email body
|
||||
*/
|
||||
public void discardTemplate(ActionEvent event)
|
||||
{
|
||||
this.body = this.automaticText;
|
||||
usingTemplate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email body text.
|
||||
*/
|
||||
public String getBody()
|
||||
{
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body The email body text to set.
|
||||
*/
|
||||
public void setBody(String body)
|
||||
{
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email subject text.
|
||||
*/
|
||||
public String getSubject()
|
||||
{
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param subject The email subject text to set.
|
||||
*/
|
||||
public void setSubject(String subject)
|
||||
{
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the automatic text.
|
||||
*/
|
||||
public String getAutomaticText()
|
||||
{
|
||||
return this.automaticText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param automaticText The automatic text to set.
|
||||
*/
|
||||
public void setAutomaticText(String automaticText)
|
||||
{
|
||||
this.automaticText = automaticText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email template Id
|
||||
*/
|
||||
public String getTemplate()
|
||||
{
|
||||
return this.template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template The email template to set.
|
||||
*/
|
||||
public void setTemplate(String template)
|
||||
{
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns if a template has been inserted by a user for email body.
|
||||
*/
|
||||
public String getUsingTemplate()
|
||||
{
|
||||
return this.usingTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param usingTemplate Template that has been inserted by a user for the email body.
|
||||
*/
|
||||
public void setUsingTemplate(String usingTemplate)
|
||||
{
|
||||
this.usingTemplate = usingTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.executer.MailActionExecuter;
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.UrlUtil;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.mail.javamail.MimeMessagePreparator;
|
||||
|
||||
/**
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TemplateMailHelperBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 9117248002321651339L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(TemplateMailHelperBean.class);
|
||||
|
||||
/** JavaMailSender bean reference */
|
||||
transient private JavaMailSender mailSender;
|
||||
|
||||
/** NodeService bean reference */
|
||||
transient private NodeService nodeService;
|
||||
|
||||
/** dialog state */
|
||||
private String subject = null;
|
||||
private String body = null;
|
||||
private String automaticText = null;
|
||||
private String template = null;
|
||||
private String usingTemplate = null;
|
||||
private String finalBody;
|
||||
|
||||
/**
|
||||
* @param mailSender The JavaMailSender to set.
|
||||
*/
|
||||
public void setMailSender(JavaMailSender mailSender)
|
||||
{
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
protected JavaMailSender getMailSender()
|
||||
{
|
||||
if (mailSender == null)
|
||||
{
|
||||
mailSender = (JavaMailSender) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "mailService");
|
||||
}
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService The nodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
protected NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the bean
|
||||
*/
|
||||
public TemplateMailHelperBean()
|
||||
{
|
||||
subject = "";
|
||||
body = "";
|
||||
automaticText = "";
|
||||
template = null;
|
||||
usingTemplate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email notification to the specified User authority
|
||||
*
|
||||
* @param person Person node representing the user
|
||||
* @param node Node they are invited too
|
||||
* @param from From text message
|
||||
* @param roleText The role display label for the user invite notification
|
||||
*/
|
||||
public void notifyUser(NodeRef person, NodeRef node, final String from, String roleText)
|
||||
{
|
||||
final String to = (String)this.getNodeService().getProperty(person, ContentModel.PROP_EMAIL);
|
||||
|
||||
if (to != null && to.length() != 0)
|
||||
{
|
||||
String body = this.body;
|
||||
if (this.usingTemplate != null)
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// use template service to format the email
|
||||
NodeRef templateRef = new NodeRef(Repository.getStoreRef(), this.usingTemplate);
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
Map<String, Object> model = DefaultModelHelper.buildDefaultModel(
|
||||
services, Application.getCurrentUser(fc), templateRef);
|
||||
model.put("role", roleText);
|
||||
model.put("space", node);
|
||||
// object to allow client urls to be generated in emails
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(fc));
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("document", node);
|
||||
if (nodeService.getType(node).equals(ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
NodeRef parentNodeRef = nodeService.getParentAssocs(node).get(0).getParentRef();
|
||||
if (parentNodeRef == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Parent folder doesn't exists for node: " + node);
|
||||
}
|
||||
model.put("space", parentNodeRef);
|
||||
}
|
||||
model.put("shareUrl", UrlUtil.getShareUrl(services.getSysAdminParams()));
|
||||
|
||||
body = services.getTemplateService().processTemplate("freemarker", templateRef.toString(), model);
|
||||
}
|
||||
this.finalBody = body;
|
||||
|
||||
MimeMessagePreparator mailPreparer = new MimeMessagePreparator()
|
||||
{
|
||||
public void prepare(MimeMessage mimeMessage) throws MessagingException
|
||||
{
|
||||
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
|
||||
message.setTo(to);
|
||||
message.setSubject(subject);
|
||||
message.setText(finalBody, MailActionExecuter.isHTML(finalBody));
|
||||
message.setFrom(from);
|
||||
}
|
||||
};
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Sending notification email to: " + to + "\n...with subject:\n" + subject + "\n...with body:\n" + body);
|
||||
|
||||
try
|
||||
{
|
||||
// Send the message
|
||||
this.getMailSender().send(mailPreparer);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// don't stop the action but let admins know email is not getting sent
|
||||
logger.error("Failed to send email to " + to, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called to insert a template as the email body
|
||||
*/
|
||||
public void insertTemplate(ActionEvent event)
|
||||
{
|
||||
if (this.template != null && this.template.equals(TemplateSupportBean.NO_SELECTION) == false)
|
||||
{
|
||||
// get the content of the template so the user can get a basic preview of it
|
||||
try
|
||||
{
|
||||
NodeRef templateRef = new NodeRef(Repository.getStoreRef(), this.template);
|
||||
ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService();
|
||||
ContentReader reader = cs.getReader(templateRef, ContentModel.PROP_CONTENT);
|
||||
if (reader != null && reader.exists())
|
||||
{
|
||||
this.body = reader.getContentString();
|
||||
|
||||
this.usingTemplate = this.template;
|
||||
}
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called to discard the template from the email body
|
||||
*/
|
||||
public void discardTemplate(ActionEvent event)
|
||||
{
|
||||
this.body = this.automaticText;
|
||||
usingTemplate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email body text.
|
||||
*/
|
||||
public String getBody()
|
||||
{
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body The email body text to set.
|
||||
*/
|
||||
public void setBody(String body)
|
||||
{
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email subject text.
|
||||
*/
|
||||
public String getSubject()
|
||||
{
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param subject The email subject text to set.
|
||||
*/
|
||||
public void setSubject(String subject)
|
||||
{
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the automatic text.
|
||||
*/
|
||||
public String getAutomaticText()
|
||||
{
|
||||
return this.automaticText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param automaticText The automatic text to set.
|
||||
*/
|
||||
public void setAutomaticText(String automaticText)
|
||||
{
|
||||
this.automaticText = automaticText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the email template Id
|
||||
*/
|
||||
public String getTemplate()
|
||||
{
|
||||
return this.template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template The email template to set.
|
||||
*/
|
||||
public void setTemplate(String template)
|
||||
{
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns if a template has been inserted by a user for email body.
|
||||
*/
|
||||
public String getUsingTemplate()
|
||||
{
|
||||
return this.usingTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param usingTemplate Template that has been inserted by a user for the email body.
|
||||
*/
|
||||
public void setUsingTemplate(String usingTemplate)
|
||||
{
|
||||
this.usingTemplate = usingTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,272 +1,272 @@
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.util.ExpiringValueCache;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Provide access to commonly used lists of templates and script files.
|
||||
* <p>
|
||||
* The lists are cached for a small period of time to help performance in the client,
|
||||
* as generally the contents of the template folders are not changed frequently.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TemplateSupportBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 6698338879903536081L;
|
||||
|
||||
private static final String MSG_SELECT_TEMPLATE = "select_a_template";
|
||||
private static final String MSG_SELECT_SCRIPT = "select_a_script";
|
||||
|
||||
/** "no selection" marker for SelectItem lists */
|
||||
public static final String NO_SELECTION = "none";
|
||||
|
||||
/** NodeService instance */
|
||||
transient private NodeService nodeService;
|
||||
|
||||
/** The SearchService instance */
|
||||
transient private SearchService searchService;
|
||||
|
||||
/** cache of content templates that lasts 30 seconds - enough for a couple of page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> contentTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of email templates that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> emailTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of RSS templates that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> rssTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of JavaScript files that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> scriptFiles = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
|
||||
/**
|
||||
* @param nodeService The NodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param searchService The SearchService to set.
|
||||
*/
|
||||
public void setSearchService(SearchService searchService)
|
||||
{
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
private SearchService getSearchService()
|
||||
{
|
||||
if (searchService == null)
|
||||
{
|
||||
searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService();
|
||||
}
|
||||
return searchService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Content Templates that can be applied to the current document.
|
||||
*/
|
||||
public List<SelectItem> getContentTemplates()
|
||||
{
|
||||
List<SelectItem> templates = contentTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Content Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getContentTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
contentTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Email Templates.
|
||||
*/
|
||||
public List<SelectItem> getEmailTemplates()
|
||||
{
|
||||
List<SelectItem> templates = emailTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
emailTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Notify Email Templates.
|
||||
*/
|
||||
public List<SelectItem> getNotifyEmailTemplates()
|
||||
{
|
||||
List<SelectItem> templates = null;
|
||||
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "/" +
|
||||
Application.getNotifyEmailTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available RSS Templates.
|
||||
*/
|
||||
public List<SelectItem> getRSSTemplates()
|
||||
{
|
||||
List<SelectItem> templates = rssTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getRSSTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
rssTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available JavaScript files that can be applied to the current document.
|
||||
*/
|
||||
public List<SelectItem> getScriptFiles()
|
||||
{
|
||||
List<SelectItem> scripts = this.scriptFiles.get();
|
||||
if (scripts == null)
|
||||
{
|
||||
// get the scripts from the special Scripts folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getScriptsFolderName(fc) + "//*";
|
||||
|
||||
scripts = selectDictionaryNodes(fc, xpath, MSG_SELECT_SCRIPT, MimetypeMap.MIMETYPE_JAVASCRIPT);
|
||||
|
||||
scriptFiles.put(scripts);
|
||||
}
|
||||
|
||||
return scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fc FacesContext
|
||||
* @param xpath XPath to the nodes to select
|
||||
* @param noSelectionLabel Label to add to the list if no items are found in the search
|
||||
*
|
||||
* @return List of SelectItem wrapper objects for the nodes found at the XPath
|
||||
*/
|
||||
private List<SelectItem> selectDictionaryNodes(FacesContext fc, String xpath, String noSelectionLabel)
|
||||
{
|
||||
return selectDictionaryNodes(fc, xpath, noSelectionLabel, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fc FacesContext
|
||||
* @param xpath XPath to the nodes to select
|
||||
* @param noSelectionLabel Label to add to the list if no items are found in the search
|
||||
* @param mimetype Optional mimetype of items to add, will not add to list if mimetype does not match
|
||||
*
|
||||
* @return List of SelectItem wrapper objects for the nodes found at the XPath
|
||||
*/
|
||||
private List<SelectItem> selectDictionaryNodes(FacesContext fc, String xpath, String noSelectionLabel, String mimetype)
|
||||
{
|
||||
List<SelectItem> wrappers = null;
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef rootNodeRef = this.getNodeService().getRootNode(Repository.getStoreRef());
|
||||
NamespaceService resolver = Repository.getServiceRegistry(fc).getNamespaceService();
|
||||
List<NodeRef> results = this.getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false);
|
||||
|
||||
wrappers = new ArrayList<SelectItem>(results.size() + 1);
|
||||
if (results.size() != 0)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
for (NodeRef ref : results)
|
||||
{
|
||||
if (this.getNodeService().exists(ref) == true)
|
||||
{
|
||||
Node childNode = new Node(ref);
|
||||
ContentData content = (ContentData)childNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
(mimetype == null || mimetype.equals(content.getMimetype())))
|
||||
{
|
||||
wrappers.add(new SelectItem(childNode.getId(), childNode.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the label
|
||||
QuickSort sorter = new QuickSort(wrappers, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException accessErr)
|
||||
{
|
||||
// ignore the result if we cannot access the root
|
||||
}
|
||||
|
||||
// add an entry (at the start) to instruct the user to select an item
|
||||
if (wrappers == null)
|
||||
{
|
||||
wrappers = new ArrayList<SelectItem>(1);
|
||||
}
|
||||
wrappers.add(0, new SelectItem(NO_SELECTION, Application.getMessage(FacesContext.getCurrentInstance(), noSelectionLabel)));
|
||||
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.util.ExpiringValueCache;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Provide access to commonly used lists of templates and script files.
|
||||
* <p>
|
||||
* The lists are cached for a small period of time to help performance in the client,
|
||||
* as generally the contents of the template folders are not changed frequently.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TemplateSupportBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 6698338879903536081L;
|
||||
|
||||
private static final String MSG_SELECT_TEMPLATE = "select_a_template";
|
||||
private static final String MSG_SELECT_SCRIPT = "select_a_script";
|
||||
|
||||
/** "no selection" marker for SelectItem lists */
|
||||
public static final String NO_SELECTION = "none";
|
||||
|
||||
/** NodeService instance */
|
||||
transient private NodeService nodeService;
|
||||
|
||||
/** The SearchService instance */
|
||||
transient private SearchService searchService;
|
||||
|
||||
/** cache of content templates that lasts 30 seconds - enough for a couple of page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> contentTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of email templates that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> emailTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of RSS templates that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> rssTemplates = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
/** cache of JavaScript files that lasts 30 seconds - enough for a few page refreshes */
|
||||
private ExpiringValueCache<List<SelectItem>> scriptFiles = new ExpiringValueCache<List<SelectItem>>(1000*30);
|
||||
|
||||
|
||||
/**
|
||||
* @param nodeService The NodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param searchService The SearchService to set.
|
||||
*/
|
||||
public void setSearchService(SearchService searchService)
|
||||
{
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
private SearchService getSearchService()
|
||||
{
|
||||
if (searchService == null)
|
||||
{
|
||||
searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService();
|
||||
}
|
||||
return searchService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Content Templates that can be applied to the current document.
|
||||
*/
|
||||
public List<SelectItem> getContentTemplates()
|
||||
{
|
||||
List<SelectItem> templates = contentTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Content Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getContentTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
contentTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Email Templates.
|
||||
*/
|
||||
public List<SelectItem> getEmailTemplates()
|
||||
{
|
||||
List<SelectItem> templates = emailTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
emailTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available Notify Email Templates.
|
||||
*/
|
||||
public List<SelectItem> getNotifyEmailTemplates()
|
||||
{
|
||||
List<SelectItem> templates = null;
|
||||
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "/" +
|
||||
Application.getNotifyEmailTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available RSS Templates.
|
||||
*/
|
||||
public List<SelectItem> getRSSTemplates()
|
||||
{
|
||||
List<SelectItem> templates = rssTemplates.get();
|
||||
if (templates == null)
|
||||
{
|
||||
// get the template from the special Email Templates folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getRSSTemplatesFolderName(fc) + "//*";
|
||||
|
||||
templates = selectDictionaryNodes(fc, xpath, MSG_SELECT_TEMPLATE, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
|
||||
rssTemplates.put(templates);
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of available JavaScript files that can be applied to the current document.
|
||||
*/
|
||||
public List<SelectItem> getScriptFiles()
|
||||
{
|
||||
List<SelectItem> scripts = this.scriptFiles.get();
|
||||
if (scripts == null)
|
||||
{
|
||||
// get the scripts from the special Scripts folder
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getScriptsFolderName(fc) + "//*";
|
||||
|
||||
scripts = selectDictionaryNodes(fc, xpath, MSG_SELECT_SCRIPT, MimetypeMap.MIMETYPE_JAVASCRIPT);
|
||||
|
||||
scriptFiles.put(scripts);
|
||||
}
|
||||
|
||||
return scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fc FacesContext
|
||||
* @param xpath XPath to the nodes to select
|
||||
* @param noSelectionLabel Label to add to the list if no items are found in the search
|
||||
*
|
||||
* @return List of SelectItem wrapper objects for the nodes found at the XPath
|
||||
*/
|
||||
private List<SelectItem> selectDictionaryNodes(FacesContext fc, String xpath, String noSelectionLabel)
|
||||
{
|
||||
return selectDictionaryNodes(fc, xpath, noSelectionLabel, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fc FacesContext
|
||||
* @param xpath XPath to the nodes to select
|
||||
* @param noSelectionLabel Label to add to the list if no items are found in the search
|
||||
* @param mimetype Optional mimetype of items to add, will not add to list if mimetype does not match
|
||||
*
|
||||
* @return List of SelectItem wrapper objects for the nodes found at the XPath
|
||||
*/
|
||||
private List<SelectItem> selectDictionaryNodes(FacesContext fc, String xpath, String noSelectionLabel, String mimetype)
|
||||
{
|
||||
List<SelectItem> wrappers = null;
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef rootNodeRef = this.getNodeService().getRootNode(Repository.getStoreRef());
|
||||
NamespaceService resolver = Repository.getServiceRegistry(fc).getNamespaceService();
|
||||
List<NodeRef> results = this.getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false);
|
||||
|
||||
wrappers = new ArrayList<SelectItem>(results.size() + 1);
|
||||
if (results.size() != 0)
|
||||
{
|
||||
DictionaryService dd = Repository.getServiceRegistry(fc).getDictionaryService();
|
||||
for (NodeRef ref : results)
|
||||
{
|
||||
if (this.getNodeService().exists(ref) == true)
|
||||
{
|
||||
Node childNode = new Node(ref);
|
||||
ContentData content = (ContentData)childNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT) &&
|
||||
(mimetype == null || mimetype.equals(content.getMimetype())))
|
||||
{
|
||||
wrappers.add(new SelectItem(childNode.getId(), childNode.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the label
|
||||
QuickSort sorter = new QuickSort(wrappers, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException accessErr)
|
||||
{
|
||||
// ignore the result if we cannot access the root
|
||||
}
|
||||
|
||||
// add an entry (at the start) to instruct the user to select an item
|
||||
if (wrappers == null)
|
||||
{
|
||||
wrappers = new ArrayList<SelectItem>(1);
|
||||
}
|
||||
wrappers.add(0, new SelectItem(NO_SELECTION, Application.getMessage(FacesContext.getCurrentInstance(), noSelectionLabel)));
|
||||
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
package org.alfresco.web.bean.admin;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
|
||||
public class AdminConsoleDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -2520599525975495006L;
|
||||
|
||||
private static final String BUTTON_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), BUTTON_CLOSE);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.admin;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
|
||||
public class AdminConsoleDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -2520599525975495006L;
|
||||
|
||||
private static final String BUTTON_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), BUTTON_CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
package org.alfresco.web.bean.admin;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.AboutBean;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
|
||||
/**
|
||||
* Implementation for the SystemInfo dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ShowSystemInfoDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 1328587489092603676L;
|
||||
|
||||
private static final String MSG_CURRENT_USER = "current_user";
|
||||
private static final String MSG_CLOSE = "close";
|
||||
private static final String MSG_VERSION = "version";
|
||||
|
||||
protected AboutBean aboutBean;
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAboutBean(AboutBean aboutBean)
|
||||
{
|
||||
this.aboutBean = aboutBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerSubTitle()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CURRENT_USER) + ": " +
|
||||
this.navigator.getCurrentUser().getUserName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerDescription()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), MSG_VERSION));
|
||||
builder.append(": ");
|
||||
builder.append(this.aboutBean.getEdition());
|
||||
builder.append(" - v");
|
||||
builder.append(this.aboutBean.getVersion());
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE);
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.admin;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.AboutBean;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
|
||||
/**
|
||||
* Implementation for the SystemInfo dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class ShowSystemInfoDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 1328587489092603676L;
|
||||
|
||||
private static final String MSG_CURRENT_USER = "current_user";
|
||||
private static final String MSG_CLOSE = "close";
|
||||
private static final String MSG_VERSION = "version";
|
||||
|
||||
protected AboutBean aboutBean;
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAboutBean(AboutBean aboutBean)
|
||||
{
|
||||
this.aboutBean = aboutBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerSubTitle()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CURRENT_USER) + ": " +
|
||||
this.navigator.getCurrentUser().getUserName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerDescription()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), MSG_VERSION));
|
||||
builder.append(": ");
|
||||
builder.append(this.aboutBean.getEdition());
|
||||
builder.append(" - v");
|
||||
builder.append(this.aboutBean.getVersion());
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,329 +1,329 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.repo.component.UITree.TreeNode;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CategoryBrowserPluginBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -1493808456969763500L;
|
||||
|
||||
public static final String BEAN_NAME = "CategoryBrowserPluginBean";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CategoryBrowserPluginBean.class);
|
||||
|
||||
transient private CategoryService categoryService;
|
||||
transient private NodeService nodeService;
|
||||
|
||||
private List<TreeNode> categoryRootNodes;
|
||||
private Map<String, TreeNode> categoryNodes;
|
||||
protected NodeRef previouslySelectedNode;
|
||||
|
||||
/**
|
||||
* @param categoryService
|
||||
* the categoryService to set
|
||||
*/
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService
|
||||
* the nodeService to set
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodeService
|
||||
*/
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
public List<TreeNode> getCategoryRootNodes()
|
||||
{
|
||||
if (this.categoryRootNodes == null)
|
||||
{
|
||||
this.categoryRootNodes = new ArrayList<TreeNode>();
|
||||
this.categoryNodes = new HashMap<String, TreeNode>();
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
|
||||
tx.begin();
|
||||
|
||||
Collection<ChildAssociationRef> childRefs = this.getCategoryService().getRootCategories(
|
||||
Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE);
|
||||
|
||||
for (ChildAssociationRef ref : childRefs)
|
||||
{
|
||||
NodeRef child = ref.getChildRef();
|
||||
TreeNode node = createTreeNode(child);
|
||||
this.categoryRootNodes.add(node);
|
||||
this.categoryNodes.put(node.getNodeRef(), node);
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage("NavigatorPluginBean exception in getCompanyHomeRootNodes()", err);
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception tex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.categoryRootNodes;
|
||||
}
|
||||
|
||||
protected Map<String, TreeNode> getNodesMap()
|
||||
{
|
||||
return this.categoryNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the child folders for the noderef given in the 'noderef' parameter and caches the nodes against the area
|
||||
* in the 'area' parameter.
|
||||
*/
|
||||
public void retrieveChildren() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(context, true);
|
||||
tx.begin();
|
||||
|
||||
Map params = context.getExternalContext().getRequestParameterMap();
|
||||
String nodeRefStr = (String) params.get("nodeRef");
|
||||
|
||||
// work out which list to cache the nodes in
|
||||
Map<String, TreeNode> currentNodes = getNodesMap();
|
||||
|
||||
if (nodeRefStr != null && currentNodes != null)
|
||||
{
|
||||
// get the given node's details
|
||||
NodeRef parentNodeRef = new NodeRef(nodeRefStr);
|
||||
TreeNode parentNode = currentNodes.get(parentNodeRef.toString());
|
||||
parentNode.setExpanded(true);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("retrieving children for noderef: " + parentNodeRef);
|
||||
|
||||
// remove any existing children as the latest ones will be added
|
||||
// below
|
||||
parentNode.removeChildren();
|
||||
|
||||
// get all the child folder objects for the parent
|
||||
List<ChildAssociationRef> childRefs = this.getNodeService().getChildAssocs(parentNodeRef,
|
||||
ContentModel.ASSOC_SUBCATEGORIES, RegexQNamePattern.MATCH_ALL);
|
||||
List<TreeNode> sortedNodes = new ArrayList<TreeNode>();
|
||||
for (ChildAssociationRef ref : childRefs)
|
||||
{
|
||||
NodeRef nodeRef = ref.getChildRef();
|
||||
logger.debug("retrieving child : " + nodeRef);
|
||||
// build the XML representation of the child node
|
||||
TreeNode childNode = createTreeNode(nodeRef);
|
||||
parentNode.addChild(childNode);
|
||||
currentNodes.put(childNode.getNodeRef(), childNode);
|
||||
sortedNodes.add(childNode);
|
||||
}
|
||||
|
||||
// order the tree nodes by the tree label
|
||||
if (sortedNodes.size() > 1)
|
||||
{
|
||||
QuickSort sorter = new QuickSort(sortedNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
|
||||
// generate the XML representation
|
||||
StringBuilder xml = new StringBuilder(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><nodes>");
|
||||
for (TreeNode childNode : sortedNodes)
|
||||
{
|
||||
xml.append(childNode.toXML());
|
||||
}
|
||||
xml.append("</nodes>");
|
||||
|
||||
// send the generated XML back to the tree
|
||||
out.write(xml.toString());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("returning XML: " + xml.toString());
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception tex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the node given in the 'nodeRef' parameter to collapsed
|
||||
*/
|
||||
public void nodeCollapsed() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
Map params = context.getExternalContext().getRequestParameterMap();
|
||||
String nodeRefStr = (String) params.get("nodeRef");
|
||||
|
||||
// work out which list to cache the nodes in
|
||||
Map<String, TreeNode> currentNodes = getNodesMap();
|
||||
|
||||
if (nodeRefStr != null && currentNodes != null)
|
||||
{
|
||||
TreeNode treeNode = currentNodes.get(nodeRefStr);
|
||||
if (treeNode != null)
|
||||
{
|
||||
treeNode.setExpanded(false);
|
||||
|
||||
// we need to return something for the client to be happy!
|
||||
out.write("<ok/>");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Set node " + treeNode + " to collapsed state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void selectNode(NodeRef selectedNode, String area)
|
||||
{
|
||||
// if there is a currently selected node, get hold of
|
||||
// it (from any of the areas) and reset to unselected
|
||||
if (this.previouslySelectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
// find the node just selected and set its state to selected
|
||||
if (selectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(selectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
this.previouslySelectedNode = selectedNode;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Selected node: " + selectedNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the selected node
|
||||
*/
|
||||
public void resetSelectedNode()
|
||||
{
|
||||
if (this.previouslySelectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(false);
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Reset selected node: " + this.previouslySelectedNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all the caches held by the bean.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
this.categoryNodes = null;
|
||||
this.categoryRootNodes = null;
|
||||
|
||||
resetSelectedNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TreeNode object from the given NodeRef
|
||||
*
|
||||
* @param nodeRef
|
||||
* The NodeRef to create the TreeNode from
|
||||
*/
|
||||
protected TreeNode createTreeNode(NodeRef nodeRef)
|
||||
{
|
||||
TreeNode node = new TreeNode(nodeRef.toString(), Repository.getNameForNode(this.getNodeService(), nodeRef),
|
||||
(String) this.getNodeService().getProperty(nodeRef, ApplicationModel.PROP_ICON));
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.repo.component.UITree.TreeNode;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CategoryBrowserPluginBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -1493808456969763500L;
|
||||
|
||||
public static final String BEAN_NAME = "CategoryBrowserPluginBean";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CategoryBrowserPluginBean.class);
|
||||
|
||||
transient private CategoryService categoryService;
|
||||
transient private NodeService nodeService;
|
||||
|
||||
private List<TreeNode> categoryRootNodes;
|
||||
private Map<String, TreeNode> categoryNodes;
|
||||
protected NodeRef previouslySelectedNode;
|
||||
|
||||
/**
|
||||
* @param categoryService
|
||||
* the categoryService to set
|
||||
*/
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService
|
||||
* the nodeService to set
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodeService
|
||||
*/
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
public List<TreeNode> getCategoryRootNodes()
|
||||
{
|
||||
if (this.categoryRootNodes == null)
|
||||
{
|
||||
this.categoryRootNodes = new ArrayList<TreeNode>();
|
||||
this.categoryNodes = new HashMap<String, TreeNode>();
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
|
||||
tx.begin();
|
||||
|
||||
Collection<ChildAssociationRef> childRefs = this.getCategoryService().getRootCategories(
|
||||
Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE);
|
||||
|
||||
for (ChildAssociationRef ref : childRefs)
|
||||
{
|
||||
NodeRef child = ref.getChildRef();
|
||||
TreeNode node = createTreeNode(child);
|
||||
this.categoryRootNodes.add(node);
|
||||
this.categoryNodes.put(node.getNodeRef(), node);
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage("NavigatorPluginBean exception in getCompanyHomeRootNodes()", err);
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception tex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.categoryRootNodes;
|
||||
}
|
||||
|
||||
protected Map<String, TreeNode> getNodesMap()
|
||||
{
|
||||
return this.categoryNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the child folders for the noderef given in the 'noderef' parameter and caches the nodes against the area
|
||||
* in the 'area' parameter.
|
||||
*/
|
||||
public void retrieveChildren() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(context, true);
|
||||
tx.begin();
|
||||
|
||||
Map params = context.getExternalContext().getRequestParameterMap();
|
||||
String nodeRefStr = (String) params.get("nodeRef");
|
||||
|
||||
// work out which list to cache the nodes in
|
||||
Map<String, TreeNode> currentNodes = getNodesMap();
|
||||
|
||||
if (nodeRefStr != null && currentNodes != null)
|
||||
{
|
||||
// get the given node's details
|
||||
NodeRef parentNodeRef = new NodeRef(nodeRefStr);
|
||||
TreeNode parentNode = currentNodes.get(parentNodeRef.toString());
|
||||
parentNode.setExpanded(true);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("retrieving children for noderef: " + parentNodeRef);
|
||||
|
||||
// remove any existing children as the latest ones will be added
|
||||
// below
|
||||
parentNode.removeChildren();
|
||||
|
||||
// get all the child folder objects for the parent
|
||||
List<ChildAssociationRef> childRefs = this.getNodeService().getChildAssocs(parentNodeRef,
|
||||
ContentModel.ASSOC_SUBCATEGORIES, RegexQNamePattern.MATCH_ALL);
|
||||
List<TreeNode> sortedNodes = new ArrayList<TreeNode>();
|
||||
for (ChildAssociationRef ref : childRefs)
|
||||
{
|
||||
NodeRef nodeRef = ref.getChildRef();
|
||||
logger.debug("retrieving child : " + nodeRef);
|
||||
// build the XML representation of the child node
|
||||
TreeNode childNode = createTreeNode(nodeRef);
|
||||
parentNode.addChild(childNode);
|
||||
currentNodes.put(childNode.getNodeRef(), childNode);
|
||||
sortedNodes.add(childNode);
|
||||
}
|
||||
|
||||
// order the tree nodes by the tree label
|
||||
if (sortedNodes.size() > 1)
|
||||
{
|
||||
QuickSort sorter = new QuickSort(sortedNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
|
||||
// generate the XML representation
|
||||
StringBuilder xml = new StringBuilder(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><nodes>");
|
||||
for (TreeNode childNode : sortedNodes)
|
||||
{
|
||||
xml.append(childNode.toXML());
|
||||
}
|
||||
xml.append("</nodes>");
|
||||
|
||||
// send the generated XML back to the tree
|
||||
out.write(xml.toString());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("returning XML: " + xml.toString());
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tx != null)
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
catch (Exception tex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the node given in the 'nodeRef' parameter to collapsed
|
||||
*/
|
||||
public void nodeCollapsed() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
Map params = context.getExternalContext().getRequestParameterMap();
|
||||
String nodeRefStr = (String) params.get("nodeRef");
|
||||
|
||||
// work out which list to cache the nodes in
|
||||
Map<String, TreeNode> currentNodes = getNodesMap();
|
||||
|
||||
if (nodeRefStr != null && currentNodes != null)
|
||||
{
|
||||
TreeNode treeNode = currentNodes.get(nodeRefStr);
|
||||
if (treeNode != null)
|
||||
{
|
||||
treeNode.setExpanded(false);
|
||||
|
||||
// we need to return something for the client to be happy!
|
||||
out.write("<ok/>");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Set node " + treeNode + " to collapsed state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void selectNode(NodeRef selectedNode, String area)
|
||||
{
|
||||
// if there is a currently selected node, get hold of
|
||||
// it (from any of the areas) and reset to unselected
|
||||
if (this.previouslySelectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
// find the node just selected and set its state to selected
|
||||
if (selectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(selectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
this.previouslySelectedNode = selectedNode;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Selected node: " + selectedNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the selected node
|
||||
*/
|
||||
public void resetSelectedNode()
|
||||
{
|
||||
if (this.previouslySelectedNode != null)
|
||||
{
|
||||
TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString());
|
||||
if (node != null)
|
||||
{
|
||||
node.setSelected(false);
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Reset selected node: " + this.previouslySelectedNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all the caches held by the bean.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
this.categoryNodes = null;
|
||||
this.categoryRootNodes = null;
|
||||
|
||||
resetSelectedNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TreeNode object from the given NodeRef
|
||||
*
|
||||
* @param nodeRef
|
||||
* The NodeRef to create the TreeNode from
|
||||
*/
|
||||
protected TreeNode createTreeNode(NodeRef nodeRef)
|
||||
{
|
||||
TreeNode node = new TreeNode(nodeRef.toString(), Repository.getNameForNode(this.getNodeService(), nodeRef),
|
||||
(String) this.getNodeService().getProperty(nodeRef, ApplicationModel.PROP_ICON));
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +1,126 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.util.XMLUtil;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Bean managing the ajax servlet upload of a multi-part form containing file content
|
||||
* to replace the content of a node within the repository.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class ContentUpdateBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -7209326198823950952L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(ContentUpdateBean.class);
|
||||
|
||||
/**
|
||||
* Ajax method to update file content. A multi-part form is required as the input.
|
||||
*
|
||||
* "return-page" = javascript to execute on return from the upload request
|
||||
* "nodeRef" = the nodeRef of the item to update the content of
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void updateFile() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ExternalContext externalContext = fc.getExternalContext();
|
||||
HttpServletRequest request = (HttpServletRequest)externalContext.getRequest();
|
||||
|
||||
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
|
||||
upload.setHeaderEncoding("UTF-8");
|
||||
|
||||
List<FileItem> fileItems = upload.parseRequest(request);
|
||||
String strNodeRef = null;
|
||||
String strFilename = null;
|
||||
String strReturnPage = null;
|
||||
File file = null;
|
||||
|
||||
for (FileItem item : fileItems)
|
||||
{
|
||||
if (item.isFormField() && item.getFieldName().equals("return-page"))
|
||||
{
|
||||
strReturnPage = item.getString();
|
||||
}
|
||||
else if (item.isFormField() && item.getFieldName().equals("nodeRef"))
|
||||
{
|
||||
strNodeRef = item.getString();
|
||||
}
|
||||
else
|
||||
{
|
||||
strFilename = FilenameUtils.getName(item.getName());
|
||||
file = TempFileProvider.createTempFile("alfresco", ".upload");
|
||||
item.write(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ajax content update request: " + strFilename + " to nodeRef: " + strNodeRef + " return page: " + strReturnPage);
|
||||
|
||||
try
|
||||
{
|
||||
if (file != null && strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef(strNodeRef);
|
||||
if (nodeRef != null)
|
||||
{
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
|
||||
// get a writer for the content and put the file
|
||||
ContentWriter writer = services.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.putContent(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
strReturnPage = strReturnPage.replace("${UPLOAD_ERROR}", e.getMessage());
|
||||
}
|
||||
|
||||
Document result = XMLUtil.newDocument();
|
||||
Element htmlEl = result.createElement("html");
|
||||
result.appendChild(htmlEl);
|
||||
Element bodyEl = result.createElement("body");
|
||||
htmlEl.appendChild(bodyEl);
|
||||
|
||||
Element scriptEl = result.createElement("script");
|
||||
bodyEl.appendChild(scriptEl);
|
||||
scriptEl.setAttribute("type", "text/javascript");
|
||||
Node scriptText = result.createTextNode(strReturnPage);
|
||||
scriptEl.appendChild(scriptText);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Content update request complete.");
|
||||
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
XMLUtil.print(result, out);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.util.XMLUtil;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Bean managing the ajax servlet upload of a multi-part form containing file content
|
||||
* to replace the content of a node within the repository.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class ContentUpdateBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -7209326198823950952L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(ContentUpdateBean.class);
|
||||
|
||||
/**
|
||||
* Ajax method to update file content. A multi-part form is required as the input.
|
||||
*
|
||||
* "return-page" = javascript to execute on return from the upload request
|
||||
* "nodeRef" = the nodeRef of the item to update the content of
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void updateFile() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ExternalContext externalContext = fc.getExternalContext();
|
||||
HttpServletRequest request = (HttpServletRequest)externalContext.getRequest();
|
||||
|
||||
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
|
||||
upload.setHeaderEncoding("UTF-8");
|
||||
|
||||
List<FileItem> fileItems = upload.parseRequest(request);
|
||||
String strNodeRef = null;
|
||||
String strFilename = null;
|
||||
String strReturnPage = null;
|
||||
File file = null;
|
||||
|
||||
for (FileItem item : fileItems)
|
||||
{
|
||||
if (item.isFormField() && item.getFieldName().equals("return-page"))
|
||||
{
|
||||
strReturnPage = item.getString();
|
||||
}
|
||||
else if (item.isFormField() && item.getFieldName().equals("nodeRef"))
|
||||
{
|
||||
strNodeRef = item.getString();
|
||||
}
|
||||
else
|
||||
{
|
||||
strFilename = FilenameUtils.getName(item.getName());
|
||||
file = TempFileProvider.createTempFile("alfresco", ".upload");
|
||||
item.write(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ajax content update request: " + strFilename + " to nodeRef: " + strNodeRef + " return page: " + strReturnPage);
|
||||
|
||||
try
|
||||
{
|
||||
if (file != null && strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef(strNodeRef);
|
||||
if (nodeRef != null)
|
||||
{
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
|
||||
// get a writer for the content and put the file
|
||||
ContentWriter writer = services.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.putContent(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
strReturnPage = strReturnPage.replace("${UPLOAD_ERROR}", e.getMessage());
|
||||
}
|
||||
|
||||
Document result = XMLUtil.newDocument();
|
||||
Element htmlEl = result.createElement("html");
|
||||
result.appendChild(htmlEl);
|
||||
Element bodyEl = result.createElement("body");
|
||||
htmlEl.appendChild(bodyEl);
|
||||
|
||||
Element scriptEl = result.createElement("script");
|
||||
bodyEl.appendChild(scriptEl);
|
||||
scriptEl.setAttribute("type", "text/javascript");
|
||||
Node scriptText = result.createTextNode(strReturnPage);
|
||||
scriptEl.appendChild(scriptText);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Content update request complete.");
|
||||
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
XMLUtil.print(result, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,229 +1,229 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.util.XMLUtil;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Bean managing the ajax servlet upload of a multi-part form containing file content
|
||||
* to be added at a specific path in the server.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class FileUploadBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 4555828718375916674L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(FileUploadBean.class);
|
||||
|
||||
/**
|
||||
* Ajax method to upload file content. A multi-part form is required as the input.
|
||||
*
|
||||
* "return-page" = javascript to execute on return from the upload request
|
||||
* "currentPath" = the cm:name based server path to upload the content into
|
||||
* and the file item content.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void uploadFile() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ExternalContext externalContext = fc.getExternalContext();
|
||||
HttpServletRequest request = (HttpServletRequest)externalContext.getRequest();
|
||||
|
||||
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
|
||||
upload.setHeaderEncoding("UTF-8");
|
||||
|
||||
List<FileItem> fileItems = upload.parseRequest(request);
|
||||
FileUploadBean bean = new FileUploadBean();
|
||||
String currentPath = null;
|
||||
String filename = null;
|
||||
String returnPage = null;
|
||||
File file = null;
|
||||
|
||||
for (FileItem item : fileItems)
|
||||
{
|
||||
if (item.isFormField() && item.getFieldName().equals("return-page"))
|
||||
{
|
||||
returnPage = item.getString();
|
||||
}
|
||||
else if (item.isFormField() && item.getFieldName().equals("currentPath"))
|
||||
{
|
||||
currentPath = URLDecoder.decode(item.getString());
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = FilenameUtils.getName(item.getName());
|
||||
file = TempFileProvider.createTempFile("alfresco", ".upload");
|
||||
item.write(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ajax file upload request: " + filename + " to path: " + currentPath + " return page: " + returnPage);
|
||||
|
||||
try
|
||||
{
|
||||
if (file != null && currentPath != null && currentPath.length() != 0)
|
||||
{
|
||||
NodeRef containerRef = pathToNodeRef(fc, currentPath);
|
||||
if (containerRef != null)
|
||||
{
|
||||
// Guess the mimetype
|
||||
String mimetype = Repository.getMimeTypeForFileName(fc, filename);
|
||||
|
||||
// Now guess the encoding
|
||||
String encoding = "UTF-8";
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
is = new BufferedInputStream(new FileInputStream(file));
|
||||
encoding = Repository.guessEncoding(fc, is, mimetype);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// Bad as it is, it's not terminal
|
||||
logger.error("Failed to guess character encoding of file: " + file, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
{
|
||||
try { is.close(); } catch (Throwable e) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Try and extract metadata from the file
|
||||
ContentReader cr = new FileContentReader(file);
|
||||
cr.setMimetype(mimetype);
|
||||
|
||||
// create properties for content type
|
||||
String author = null;
|
||||
String title = null;
|
||||
String description = null;
|
||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(5, 1.0f);
|
||||
if (Repository.extractMetadata(fc, cr, contentProps))
|
||||
{
|
||||
author = (String)(contentProps.get(ContentModel.PROP_AUTHOR));
|
||||
title = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_TITLE));
|
||||
description = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_DESCRIPTION));
|
||||
}
|
||||
|
||||
// default the title to the file name if not set
|
||||
if (title == null)
|
||||
{
|
||||
title = filename;
|
||||
}
|
||||
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
FileInfo fileInfo = services.getFileFolderService().create(
|
||||
containerRef, filename, ContentModel.TYPE_CONTENT);
|
||||
NodeRef fileNodeRef = fileInfo.getNodeRef();
|
||||
|
||||
// set the author aspect
|
||||
if (author != null)
|
||||
{
|
||||
Map<QName, Serializable> authorProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
authorProps.put(ContentModel.PROP_AUTHOR, author);
|
||||
services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_AUTHOR, authorProps);
|
||||
}
|
||||
|
||||
// apply the titled aspect - title and description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, title);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, description);
|
||||
services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
|
||||
// get a writer for the content and put the file
|
||||
ContentWriter writer = services.getContentService().getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding(encoding);
|
||||
writer.putContent(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
returnPage = returnPage.replace("${UPLOAD_ERROR}", e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(file != null)
|
||||
{
|
||||
logger.debug("delete temporary file:" + file.getPath());
|
||||
// Delete the temporary file
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
Document result = XMLUtil.newDocument();
|
||||
Element htmlEl = result.createElement("html");
|
||||
result.appendChild(htmlEl);
|
||||
Element bodyEl = result.createElement("body");
|
||||
htmlEl.appendChild(bodyEl);
|
||||
|
||||
Element scriptEl = result.createElement("script");
|
||||
bodyEl.appendChild(scriptEl);
|
||||
scriptEl.setAttribute("type", "text/javascript");
|
||||
Node scriptText = result.createTextNode(returnPage);
|
||||
scriptEl.appendChild(scriptText);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("File upload request complete.");
|
||||
}
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
XMLUtil.print(result, out);
|
||||
}
|
||||
|
||||
static NodeRef pathToNodeRef(FacesContext fc, String path)
|
||||
{
|
||||
// convert cm:name based path to a NodeRef
|
||||
StringTokenizer t = new StringTokenizer(path, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
String[] elements = new String[tokenCount];
|
||||
for (int i=0; i<tokenCount; i++)
|
||||
{
|
||||
elements[i] = t.nextToken();
|
||||
}
|
||||
return BaseServlet.resolveWebDAVPath(fc, elements, false);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.alfresco.web.app.servlet.BaseServlet;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.util.XMLUtil;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Bean managing the ajax servlet upload of a multi-part form containing file content
|
||||
* to be added at a specific path in the server.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class FileUploadBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 4555828718375916674L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(FileUploadBean.class);
|
||||
|
||||
/**
|
||||
* Ajax method to upload file content. A multi-part form is required as the input.
|
||||
*
|
||||
* "return-page" = javascript to execute on return from the upload request
|
||||
* "currentPath" = the cm:name based server path to upload the content into
|
||||
* and the file item content.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void uploadFile() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ExternalContext externalContext = fc.getExternalContext();
|
||||
HttpServletRequest request = (HttpServletRequest)externalContext.getRequest();
|
||||
|
||||
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
|
||||
upload.setHeaderEncoding("UTF-8");
|
||||
|
||||
List<FileItem> fileItems = upload.parseRequest(request);
|
||||
FileUploadBean bean = new FileUploadBean();
|
||||
String currentPath = null;
|
||||
String filename = null;
|
||||
String returnPage = null;
|
||||
File file = null;
|
||||
|
||||
for (FileItem item : fileItems)
|
||||
{
|
||||
if (item.isFormField() && item.getFieldName().equals("return-page"))
|
||||
{
|
||||
returnPage = item.getString();
|
||||
}
|
||||
else if (item.isFormField() && item.getFieldName().equals("currentPath"))
|
||||
{
|
||||
currentPath = URLDecoder.decode(item.getString());
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = FilenameUtils.getName(item.getName());
|
||||
file = TempFileProvider.createTempFile("alfresco", ".upload");
|
||||
item.write(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ajax file upload request: " + filename + " to path: " + currentPath + " return page: " + returnPage);
|
||||
|
||||
try
|
||||
{
|
||||
if (file != null && currentPath != null && currentPath.length() != 0)
|
||||
{
|
||||
NodeRef containerRef = pathToNodeRef(fc, currentPath);
|
||||
if (containerRef != null)
|
||||
{
|
||||
// Guess the mimetype
|
||||
String mimetype = Repository.getMimeTypeForFileName(fc, filename);
|
||||
|
||||
// Now guess the encoding
|
||||
String encoding = "UTF-8";
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
is = new BufferedInputStream(new FileInputStream(file));
|
||||
encoding = Repository.guessEncoding(fc, is, mimetype);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// Bad as it is, it's not terminal
|
||||
logger.error("Failed to guess character encoding of file: " + file, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (is != null)
|
||||
{
|
||||
try { is.close(); } catch (Throwable e) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Try and extract metadata from the file
|
||||
ContentReader cr = new FileContentReader(file);
|
||||
cr.setMimetype(mimetype);
|
||||
|
||||
// create properties for content type
|
||||
String author = null;
|
||||
String title = null;
|
||||
String description = null;
|
||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(5, 1.0f);
|
||||
if (Repository.extractMetadata(fc, cr, contentProps))
|
||||
{
|
||||
author = (String)(contentProps.get(ContentModel.PROP_AUTHOR));
|
||||
title = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_TITLE));
|
||||
description = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_DESCRIPTION));
|
||||
}
|
||||
|
||||
// default the title to the file name if not set
|
||||
if (title == null)
|
||||
{
|
||||
title = filename;
|
||||
}
|
||||
|
||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||
FileInfo fileInfo = services.getFileFolderService().create(
|
||||
containerRef, filename, ContentModel.TYPE_CONTENT);
|
||||
NodeRef fileNodeRef = fileInfo.getNodeRef();
|
||||
|
||||
// set the author aspect
|
||||
if (author != null)
|
||||
{
|
||||
Map<QName, Serializable> authorProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
authorProps.put(ContentModel.PROP_AUTHOR, author);
|
||||
services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_AUTHOR, authorProps);
|
||||
}
|
||||
|
||||
// apply the titled aspect - title and description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, title);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, description);
|
||||
services.getNodeService().addAspect(fileNodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
|
||||
// get a writer for the content and put the file
|
||||
ContentWriter writer = services.getContentService().getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding(encoding);
|
||||
writer.putContent(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
returnPage = returnPage.replace("${UPLOAD_ERROR}", e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(file != null)
|
||||
{
|
||||
logger.debug("delete temporary file:" + file.getPath());
|
||||
// Delete the temporary file
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
Document result = XMLUtil.newDocument();
|
||||
Element htmlEl = result.createElement("html");
|
||||
result.appendChild(htmlEl);
|
||||
Element bodyEl = result.createElement("body");
|
||||
htmlEl.appendChild(bodyEl);
|
||||
|
||||
Element scriptEl = result.createElement("script");
|
||||
bodyEl.appendChild(scriptEl);
|
||||
scriptEl.setAttribute("type", "text/javascript");
|
||||
Node scriptText = result.createTextNode(returnPage);
|
||||
scriptEl.appendChild(scriptText);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("File upload request complete.");
|
||||
}
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
XMLUtil.print(result, out);
|
||||
}
|
||||
|
||||
static NodeRef pathToNodeRef(FacesContext fc, String path)
|
||||
{
|
||||
// convert cm:name based path to a NodeRef
|
||||
StringTokenizer t = new StringTokenizer(path, "/");
|
||||
int tokenCount = t.countTokens();
|
||||
String[] elements = new String[tokenCount];
|
||||
for (int i=0; i<tokenCount; i++)
|
||||
{
|
||||
elements[i] = t.nextToken();
|
||||
}
|
||||
return BaseServlet.resolveWebDAVPath(fc, elements, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.spaces.CreateSpaceWizard;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean backing the ajax requests from the MySpaces portlet webscript.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class MySpacesBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -5684182834188359483L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(MySpacesBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void createSpace() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String path = (String)requestMap.get("path");
|
||||
String name = (String)requestMap.get("name");
|
||||
String title = (String)requestMap.get("title");
|
||||
String description = (String)requestMap.get("description");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("MySpacesBean.createSpace() path=" + path + " name=" + name +
|
||||
" title=" + title + " description=" + description);
|
||||
|
||||
try
|
||||
{
|
||||
if (path != null && name != null)
|
||||
{
|
||||
NodeRef containerRef = FileUploadBean.pathToNodeRef(fc, path);
|
||||
if (containerRef != null)
|
||||
{
|
||||
NodeService nodeService = Repository.getServiceRegistry(fc).getNodeService();
|
||||
FileFolderService ffService = Repository.getServiceRegistry(fc).getFileFolderService();
|
||||
FileInfo folderInfo = ffService.create(containerRef, name, ContentModel.TYPE_FOLDER);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created new folder: " + folderInfo.getNodeRef().toString());
|
||||
|
||||
// apply the uifacets aspect - icon, title and description properties
|
||||
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4, 1.0f);
|
||||
uiFacetsProps.put(ApplicationModel.PROP_ICON, CreateSpaceWizard.DEFAULT_SPACE_ICON_NAME);
|
||||
uiFacetsProps.put(ContentModel.PROP_TITLE, title);
|
||||
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, description);
|
||||
nodeService.addAspect(folderInfo.getNodeRef(), ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||
|
||||
out.write("OK: " + folderInfo.getNodeRef().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileExistsException ferr)
|
||||
{
|
||||
out.write("ERROR: A file with that name already exists.");
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.spaces.CreateSpaceWizard;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean backing the ajax requests from the MySpaces portlet webscript.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class MySpacesBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -5684182834188359483L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(MySpacesBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void createSpace() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String path = (String)requestMap.get("path");
|
||||
String name = (String)requestMap.get("name");
|
||||
String title = (String)requestMap.get("title");
|
||||
String description = (String)requestMap.get("description");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("MySpacesBean.createSpace() path=" + path + " name=" + name +
|
||||
" title=" + title + " description=" + description);
|
||||
|
||||
try
|
||||
{
|
||||
if (path != null && name != null)
|
||||
{
|
||||
NodeRef containerRef = FileUploadBean.pathToNodeRef(fc, path);
|
||||
if (containerRef != null)
|
||||
{
|
||||
NodeService nodeService = Repository.getServiceRegistry(fc).getNodeService();
|
||||
FileFolderService ffService = Repository.getServiceRegistry(fc).getFileFolderService();
|
||||
FileInfo folderInfo = ffService.create(containerRef, name, ContentModel.TYPE_FOLDER);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created new folder: " + folderInfo.getNodeRef().toString());
|
||||
|
||||
// apply the uifacets aspect - icon, title and description properties
|
||||
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4, 1.0f);
|
||||
uiFacetsProps.put(ApplicationModel.PROP_ICON, CreateSpaceWizard.DEFAULT_SPACE_ICON_NAME);
|
||||
uiFacetsProps.put(ContentModel.PROP_TITLE, title);
|
||||
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, description);
|
||||
nodeService.addAspect(folderInfo.getNodeRef(), ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||
|
||||
out.write("OK: " + folderInfo.getNodeRef().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileExistsException ferr)
|
||||
{
|
||||
out.write("ERROR: A file with that name already exists.");
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +1,160 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.alfresco.repo.content.transform.TransformerInfoException;
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TemplateException;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean used by an AJAX control to send information back on the
|
||||
* requested node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class NodeInfoBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 137294178658919187L;
|
||||
|
||||
transient private NodeService nodeService;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(NodeInfoBean.class);
|
||||
|
||||
/**
|
||||
* Returns information on the node identified by the 'noderef'
|
||||
* parameter found in the ExternalContext. If no noderef is supplied, then the template
|
||||
* is executed without context.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendNodeInfo() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
String strTemplate = (String)requestMap.get("template");
|
||||
if (strTemplate == null || strTemplate.length() == 0)
|
||||
{
|
||||
strTemplate = "node_summary_panel.ftl";
|
||||
}
|
||||
|
||||
NodeRef nodeRef = null;
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
nodeRef = new NodeRef(strNodeRef);
|
||||
if (this.getNodeService().exists(nodeRef) == false)
|
||||
{
|
||||
out.write("<span class='errorMessage'>Node could not be found in the repository!</span>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/" + strTemplate, getModel(nodeRef, requestMap), out);
|
||||
}
|
||||
catch (TemplateException ex)
|
||||
{
|
||||
// Try to catch TransformerInfoException to display it in NodeInfo pane.
|
||||
// Fix bug reported in https://issues.alfresco.com/jira/browse/ETWOTWO-440
|
||||
Throwable cause = ex.getCause();
|
||||
while (cause != null)
|
||||
{
|
||||
cause = cause.getCause();
|
||||
if (cause instanceof TransformerInfoException)
|
||||
{
|
||||
out.write("<tr><td colspan=\"2\"><span class='errorMessage'>" + cause.getMessage() + "</span></td></tr>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @param nodeService The NodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
private Map<String, Object> getModel(NodeRef nodeRef, Map<String, String> requestMap) throws ContentIOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
||||
|
||||
I18NUtil.registerResourceBundle("alfresco.messages.webclient");
|
||||
// create api methods
|
||||
model.put("date", new Date());
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(context));
|
||||
model.put("locale", I18NUtil.getLocale());
|
||||
if (nodeRef != null)
|
||||
{
|
||||
model.put("node", new TemplateNode(
|
||||
nodeRef,
|
||||
Repository.getServiceRegistry(context),
|
||||
this.imageResolver));
|
||||
}
|
||||
|
||||
// add URL arguments as a map called 'args' to the root of the model
|
||||
Map<String, String> args = new HashMap<String, String>(4, 1.0f);
|
||||
for (String name : requestMap.keySet())
|
||||
{
|
||||
args.put(name, requestMap.get(name));
|
||||
}
|
||||
model.put("args", args);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
private TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.alfresco.repo.content.transform.TransformerInfoException;
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TemplateException;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean used by an AJAX control to send information back on the
|
||||
* requested node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class NodeInfoBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 137294178658919187L;
|
||||
|
||||
transient private NodeService nodeService;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(NodeInfoBean.class);
|
||||
|
||||
/**
|
||||
* Returns information on the node identified by the 'noderef'
|
||||
* parameter found in the ExternalContext. If no noderef is supplied, then the template
|
||||
* is executed without context.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendNodeInfo() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
String strTemplate = (String)requestMap.get("template");
|
||||
if (strTemplate == null || strTemplate.length() == 0)
|
||||
{
|
||||
strTemplate = "node_summary_panel.ftl";
|
||||
}
|
||||
|
||||
NodeRef nodeRef = null;
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
nodeRef = new NodeRef(strNodeRef);
|
||||
if (this.getNodeService().exists(nodeRef) == false)
|
||||
{
|
||||
out.write("<span class='errorMessage'>Node could not be found in the repository!</span>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/" + strTemplate, getModel(nodeRef, requestMap), out);
|
||||
}
|
||||
catch (TemplateException ex)
|
||||
{
|
||||
// Try to catch TransformerInfoException to display it in NodeInfo pane.
|
||||
// Fix bug reported in https://issues.alfresco.com/jira/browse/ETWOTWO-440
|
||||
Throwable cause = ex.getCause();
|
||||
while (cause != null)
|
||||
{
|
||||
cause = cause.getCause();
|
||||
if (cause instanceof TransformerInfoException)
|
||||
{
|
||||
out.write("<tr><td colspan=\"2\"><span class='errorMessage'>" + cause.getMessage() + "</span></td></tr>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @param nodeService The NodeService to set.
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
private NodeService getNodeService()
|
||||
{
|
||||
if (nodeService == null)
|
||||
{
|
||||
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
|
||||
}
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
private Map<String, Object> getModel(NodeRef nodeRef, Map<String, String> requestMap) throws ContentIOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
||||
|
||||
I18NUtil.registerResourceBundle("alfresco.messages.webclient");
|
||||
// create api methods
|
||||
model.put("date", new Date());
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(context));
|
||||
model.put("locale", I18NUtil.getLocale());
|
||||
if (nodeRef != null)
|
||||
{
|
||||
model.put("node", new TemplateNode(
|
||||
nodeRef,
|
||||
Repository.getServiceRegistry(context),
|
||||
this.imageResolver));
|
||||
}
|
||||
|
||||
// add URL arguments as a map called 'args' to the root of the model
|
||||
Map<String, String> args = new HashMap<String, String>(4, 1.0f);
|
||||
for (String name : requestMap.keySet())
|
||||
{
|
||||
args.put(name, requestMap.get(name));
|
||||
}
|
||||
model.put("args", args);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
private TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean backing the ajax requests from various Portlet webscripts.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class PortletActionsBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -8230154592621310289L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(PortletActionsBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void deleteItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(fc).getFileFolderService().delete(new NodeRef(strNodeRef));
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void checkoutItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(fc).getCheckOutCheckInService().checkout(new NodeRef(strNodeRef));
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void checkinItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, Serializable> props = new HashMap<String, Serializable>(2, 1.0f);
|
||||
props.put(Version.PROP_DESCRIPTION, "");
|
||||
props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
Repository.getServiceRegistry(fc).getCheckOutCheckInService().checkin(new NodeRef(strNodeRef), props);
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean backing the ajax requests from various Portlet webscripts.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class PortletActionsBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -8230154592621310289L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(PortletActionsBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void deleteItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(fc).getFileFolderService().delete(new NodeRef(strNodeRef));
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void checkoutItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Repository.getServiceRegistry(fc).getCheckOutCheckInService().checkout(new NodeRef(strNodeRef));
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void checkinItem() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String strNodeRef = (String)requestMap.get("noderef");
|
||||
if (strNodeRef != null && strNodeRef.length() != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, Serializable> props = new HashMap<String, Serializable>(2, 1.0f);
|
||||
props.put(Version.PROP_DESCRIPTION, "");
|
||||
props.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
Repository.getServiceRegistry(fc).getCheckOutCheckInService().checkin(new NodeRef(strNodeRef), props);
|
||||
out.write("OK: " + strNodeRef);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
out.write("ERROR: " + err.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,90 +1,90 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean which proxies requests to online presence servers.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class PresenceProxyBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -3041576848188629589L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(PresenceProxyBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void proxyRequest() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String url = (String)requestMap.get("url");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("PresenceProxyBean.proxyRequest() url=" + url);
|
||||
|
||||
if (url != null)
|
||||
{
|
||||
String response = getUrlResponse(url);
|
||||
out.write(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform request
|
||||
*/
|
||||
public String getUrlResponse(String requestUrl)
|
||||
{
|
||||
String response = "";
|
||||
HttpClient client = new HttpClient();
|
||||
HttpMethod method = new GetMethod(requestUrl);
|
||||
method.setRequestHeader("Accept", "*/*");
|
||||
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
|
||||
try
|
||||
{
|
||||
int statusCode = client.executeMethod(method);
|
||||
if (statusCode == HttpStatus.SC_OK)
|
||||
{
|
||||
response = method.getResponseBodyAsString();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = method.getStatusText();
|
||||
}
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
response = e.getMessage();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
response = e.getMessage();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release the connection.
|
||||
method.releaseConnection();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.web.app.servlet.ajax.InvokeCommand;
|
||||
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean which proxies requests to online presence servers.
|
||||
*
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class PresenceProxyBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -3041576848188629589L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(PresenceProxyBean.class);
|
||||
|
||||
@InvokeCommand.ResponseMimetype(value=MimetypeMap.MIMETYPE_HTML)
|
||||
public void proxyRequest() throws Exception
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
Map<String, String> requestMap = fc.getExternalContext().getRequestParameterMap();
|
||||
String url = (String)requestMap.get("url");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("PresenceProxyBean.proxyRequest() url=" + url);
|
||||
|
||||
if (url != null)
|
||||
{
|
||||
String response = getUrlResponse(url);
|
||||
out.write(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform request
|
||||
*/
|
||||
public String getUrlResponse(String requestUrl)
|
||||
{
|
||||
String response = "";
|
||||
HttpClient client = new HttpClient();
|
||||
HttpMethod method = new GetMethod(requestUrl);
|
||||
method.setRequestHeader("Accept", "*/*");
|
||||
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
|
||||
try
|
||||
{
|
||||
int statusCode = client.executeMethod(method);
|
||||
if (statusCode == HttpStatus.SC_OK)
|
||||
{
|
||||
response = method.getResponseBodyAsString();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = method.getStatusText();
|
||||
}
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
response = e.getMessage();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
response = e.getMessage();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release the connection.
|
||||
method.releaseConnection();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,144 +1,144 @@
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.repo.template.Workflow;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Bean used by an AJAX control to send information back on the requested workflow task.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TaskInfoBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -6627537519541525897L;
|
||||
|
||||
transient private WorkflowService workflowService;
|
||||
|
||||
/**
|
||||
* Returns information for the workflow task identified by the 'taskId'
|
||||
* parameter found in the ExternalContext.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendTaskInfo() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
String taskId = (String)context.getExternalContext().getRequestParameterMap().get("taskId");
|
||||
if (taskId == null || taskId.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("'taskId' parameter is missing");
|
||||
}
|
||||
|
||||
WorkflowTask task = this.getWorkflowService().getTaskById(taskId);
|
||||
if (task != null)
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/task_summary_panel.ftl", getModel(task), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<span class='errorMessage'>Task could not be found.</span>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource list for the workflow task identified by the 'taskId'
|
||||
* parameter found in the ExternalContext.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendTaskResources() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
String taskId = (String)context.getExternalContext().getRequestParameterMap().get("taskId");
|
||||
if (taskId == null || taskId.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("'taskId' parameter is missing");
|
||||
}
|
||||
|
||||
WorkflowTask task = this.getWorkflowService().getTaskById(taskId);
|
||||
if (task != null)
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/task_resource_panel.ftl", getModel(task), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<span class='errorMessage'>Task could not be found.</span>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @param workflowService The WorkflowService to set.
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
private WorkflowService getWorkflowService()
|
||||
{
|
||||
if (workflowService == null)
|
||||
{
|
||||
workflowService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWorkflowService();
|
||||
}
|
||||
return workflowService;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
private Map<String, Object> getModel(WorkflowTask task)
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
||||
|
||||
I18NUtil.registerResourceBundle("alfresco.messages.webclient");
|
||||
// create template api methods and objects
|
||||
model.put("date", new Date());
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(context));
|
||||
model.put("locale", I18NUtil.getLocale());
|
||||
model.put("task", new Workflow.WorkflowTaskItem(
|
||||
Repository.getServiceRegistry(context),
|
||||
this.imageResolver,
|
||||
task));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
private TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
}
|
||||
package org.alfresco.web.bean.ajax;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.template.I18NMessageMethod;
|
||||
import org.alfresco.repo.template.Workflow;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Bean used by an AJAX control to send information back on the requested workflow task.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class TaskInfoBean implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -6627537519541525897L;
|
||||
|
||||
transient private WorkflowService workflowService;
|
||||
|
||||
/**
|
||||
* Returns information for the workflow task identified by the 'taskId'
|
||||
* parameter found in the ExternalContext.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendTaskInfo() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
String taskId = (String)context.getExternalContext().getRequestParameterMap().get("taskId");
|
||||
if (taskId == null || taskId.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("'taskId' parameter is missing");
|
||||
}
|
||||
|
||||
WorkflowTask task = this.getWorkflowService().getTaskById(taskId);
|
||||
if (task != null)
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/task_summary_panel.ftl", getModel(task), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<span class='errorMessage'>Task could not be found.</span>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource list for the workflow task identified by the 'taskId'
|
||||
* parameter found in the ExternalContext.
|
||||
* <p>
|
||||
* The result is the formatted HTML to show on the client.
|
||||
*/
|
||||
public void sendTaskResources() throws IOException
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
String taskId = (String)context.getExternalContext().getRequestParameterMap().get("taskId");
|
||||
if (taskId == null || taskId.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("'taskId' parameter is missing");
|
||||
}
|
||||
|
||||
WorkflowTask task = this.getWorkflowService().getTaskById(taskId);
|
||||
if (task != null)
|
||||
{
|
||||
Repository.getServiceRegistry(context).getTemplateService().processTemplate(
|
||||
"/alfresco/templates/client/task_resource_panel.ftl", getModel(task), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<span class='errorMessage'>Task could not be found.</span>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @param workflowService The WorkflowService to set.
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
private WorkflowService getWorkflowService()
|
||||
{
|
||||
if (workflowService == null)
|
||||
{
|
||||
workflowService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWorkflowService();
|
||||
}
|
||||
return workflowService;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
private Map<String, Object> getModel(WorkflowTask task)
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
||||
|
||||
I18NUtil.registerResourceBundle("alfresco.messages.webclient");
|
||||
// create template api methods and objects
|
||||
model.put("date", new Date());
|
||||
model.put("msg", new I18NMessageMethod());
|
||||
model.put("url", new BaseTemplateContentServlet.URLHelper(context));
|
||||
model.put("locale", I18NUtil.getLocale());
|
||||
model.put("task", new Workflow.WorkflowTaskItem(
|
||||
Repository.getServiceRegistry(context),
|
||||
this.imageResolver,
|
||||
task));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
private TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,166 +1,166 @@
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
public class CreateCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 1905920932992642119L;
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
|
||||
// retrieve parameters
|
||||
String ref = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
|
||||
if (ref != null)
|
||||
{
|
||||
categoryRef = new NodeRef(ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
finishCreate();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), "new_category");
|
||||
}
|
||||
|
||||
public String finishCreate()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
try
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
// create category using categoryservice
|
||||
NodeRef ref;
|
||||
if (getCategoryRef() == null || getCategoryRef().getId().equals("null"))
|
||||
{
|
||||
ref = getCategoryService().createRootCategory(Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
ref = getCategoryService().createCategory(getCategoryRef(), getName());
|
||||
}
|
||||
|
||||
// apply the titled aspect - for description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
getNodeService().addAspect(ref, ContentModel.ASPECT_TITLED, titledProps);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
public class CreateCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 1905920932992642119L;
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
|
||||
// retrieve parameters
|
||||
String ref = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
|
||||
if (ref != null)
|
||||
{
|
||||
categoryRef = new NodeRef(ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
finishCreate();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), "new_category");
|
||||
}
|
||||
|
||||
public String finishCreate()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
try
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
||||
RetryingTransactionCallback<Object> callback = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
// create category using categoryservice
|
||||
NodeRef ref;
|
||||
if (getCategoryRef() == null || getCategoryRef().getId().equals("null"))
|
||||
{
|
||||
ref = getCategoryService().createRootCategory(Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
ref = getCategoryService().createCategory(getCategoryRef(), getName());
|
||||
}
|
||||
|
||||
// apply the titled aspect - for description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
getNodeService().addAspect(ref, ContentModel.ASPECT_TITLED, titledProps);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,395 +1,395 @@
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Depth;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Mode;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.context.UIContextService;
|
||||
import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
|
||||
public class DeleteCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -8929785826091612856L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(DeleteCategoryDialog.class);
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
private final static String MSG_DELETE_CATEGORY = "delete_category";
|
||||
private final static String MSG_DELETE = "delete";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
private static final String MSG_CATEGORIES = "categories";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
private Boolean categoryFlag = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
this.categoryFlag = false;
|
||||
|
||||
// retrieve parameters
|
||||
String categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
// make sure nodeRef was supplied
|
||||
ParameterCheck.mandatoryString(CategoriesDialog.PARAM_CATEGORY_REF, categoryRef);
|
||||
|
||||
// create the node
|
||||
this.category = new Node(new NodeRef(categoryRef));
|
||||
|
||||
setActionCategory(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// add the category to the request object so it gets picked up by
|
||||
// category dialog, this will allow it to be removed from the breadcrumb
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY, this.category.getName());
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public int getMembersSize()
|
||||
{
|
||||
return getMembers().size();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public Boolean getCategoryFlag()
|
||||
{
|
||||
return categoryFlag;
|
||||
}
|
||||
|
||||
public void setCategoryFlag(Boolean categoryFlag)
|
||||
{
|
||||
this.categoryFlag = categoryFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node Set the Node to be used for the current category screen action.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setActionCategory(Node node)
|
||||
{
|
||||
this.actionCategory = node;
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// setup form properties
|
||||
setName(node.getName());
|
||||
setDescription((String)node.getProperties().get(ContentModel.PROP_DESCRIPTION));
|
||||
setMembers(getCategoryService().getChildren(node.getNodeRef(), Mode.MEMBERS, Depth.ANY));
|
||||
}
|
||||
else
|
||||
{
|
||||
setName(null);
|
||||
setDescription(null);
|
||||
Object emptyCollection = Collections.emptyList();
|
||||
setMembers((Collection<ChildAssociationRef>) emptyCollection);
|
||||
}
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Breadcrumb location list
|
||||
*/
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
finishDelete();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_DELETE_CATEGORY) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ getActionCategory().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE);
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.context.IContextListener#contextUpdated()
|
||||
*/
|
||||
public void contextUpdated()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Invalidating Category Management Components...");
|
||||
|
||||
// force a requery of the current category ref properties
|
||||
setCategory(null);
|
||||
|
||||
// force a requery of the richlist dataset
|
||||
if (this.categoriesRichList != null)
|
||||
{
|
||||
this.categoriesRichList.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ID of the currently displayed category or null if at the root.
|
||||
*/
|
||||
public String getCurrentCategoryId()
|
||||
{
|
||||
if (getCategoryRef() != null)
|
||||
{
|
||||
return getCategoryRef().getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current category node.
|
||||
* <p>
|
||||
* Setting this value causes the UI to update and display the specified node as current.
|
||||
*
|
||||
* @param ref The current category node.
|
||||
*/
|
||||
public void setCurrentCategory(NodeRef ref)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Setting current category: " + ref);
|
||||
|
||||
// set the current NodeRef for our UI context operations
|
||||
setCategoryRef(ref);
|
||||
|
||||
// clear current node context
|
||||
setCategory(null);
|
||||
|
||||
// inform that the UI needs updating after this change
|
||||
contextUpdated();
|
||||
}
|
||||
|
||||
|
||||
public String finishDelete()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
if (getActionCategory() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
||||
RetryingTransactionCallback<NodeRef> callback = new RetryingTransactionCallback<NodeRef>()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
public NodeRef execute() throws Throwable
|
||||
{
|
||||
// delete the category node using the nodeservice
|
||||
NodeRef categoryNodeRef = getActionCategory().getNodeRef();
|
||||
getCategoryService().deleteCategory(categoryNodeRef);
|
||||
|
||||
// if there are other items in the repository using this category
|
||||
// all the associations to the category should be removed too
|
||||
if (getMembers() != null && getMembers().size() > 0)
|
||||
{
|
||||
for (ChildAssociationRef childRef : getMembers())
|
||||
{
|
||||
List<NodeRef> list = new ArrayList<NodeRef>(getMembers().size());
|
||||
|
||||
NodeRef member = childRef.getChildRef();
|
||||
Collection<NodeRef> categories = (Collection<NodeRef>)getNodeService().getProperty(member, ContentModel.PROP_CATEGORIES);
|
||||
|
||||
for (NodeRef category : categories)
|
||||
{
|
||||
if (category.equals(categoryNodeRef) == false)
|
||||
{
|
||||
list.add(category);
|
||||
}
|
||||
}
|
||||
|
||||
// persist the list back to the repository
|
||||
getNodeService().setProperty(member, ContentModel.PROP_CATEGORIES, (Serializable) list);
|
||||
}
|
||||
}
|
||||
return categoryNodeRef;
|
||||
}
|
||||
};
|
||||
NodeRef categoryNodeRef = txnHelper.doInTransaction(callback);
|
||||
|
||||
// Figure out if the deletion is made by an icon or by a list of actions
|
||||
CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
|
||||
.getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
|
||||
setLocation(categoriesDialog.getLocation());
|
||||
List<IBreadcrumbHandler> location = getLocation();
|
||||
CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
|
||||
setCategoryFlag(!handler.toString().equals(getCategory().getName()));
|
||||
|
||||
// clear action context
|
||||
setActionCategory(null);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Depth;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Mode;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.context.UIContextService;
|
||||
import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
|
||||
public class DeleteCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -8929785826091612856L;
|
||||
|
||||
private static Log logger = LogFactory.getLog(DeleteCategoryDialog.class);
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
private final static String MSG_DELETE_CATEGORY = "delete_category";
|
||||
private final static String MSG_DELETE = "delete";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
private static final String MSG_CATEGORIES = "categories";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Current category ref */
|
||||
private NodeRef categoryRef = null;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
private Boolean categoryFlag = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
this.categoryFlag = false;
|
||||
|
||||
// retrieve parameters
|
||||
String categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
// make sure nodeRef was supplied
|
||||
ParameterCheck.mandatoryString(CategoriesDialog.PARAM_CATEGORY_REF, categoryRef);
|
||||
|
||||
// create the node
|
||||
this.category = new Node(new NodeRef(categoryRef));
|
||||
|
||||
setActionCategory(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// add the category to the request object so it gets picked up by
|
||||
// category dialog, this will allow it to be removed from the breadcrumb
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY, this.category.getName());
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public int getMembersSize()
|
||||
{
|
||||
return getMembers().size();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public NodeRef getCategoryRef()
|
||||
{
|
||||
return categoryRef;
|
||||
}
|
||||
|
||||
public void setCategoryRef(NodeRef categoryRef)
|
||||
{
|
||||
this.categoryRef = categoryRef;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public Boolean getCategoryFlag()
|
||||
{
|
||||
return categoryFlag;
|
||||
}
|
||||
|
||||
public void setCategoryFlag(Boolean categoryFlag)
|
||||
{
|
||||
this.categoryFlag = categoryFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node Set the Node to be used for the current category screen action.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setActionCategory(Node node)
|
||||
{
|
||||
this.actionCategory = node;
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// setup form properties
|
||||
setName(node.getName());
|
||||
setDescription((String)node.getProperties().get(ContentModel.PROP_DESCRIPTION));
|
||||
setMembers(getCategoryService().getChildren(node.getNodeRef(), Mode.MEMBERS, Depth.ANY));
|
||||
}
|
||||
else
|
||||
{
|
||||
setName(null);
|
||||
setDescription(null);
|
||||
Object emptyCollection = Collections.emptyList();
|
||||
setMembers((Collection<ChildAssociationRef>) emptyCollection);
|
||||
}
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Breadcrumb location list
|
||||
*/
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
finishDelete();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_DELETE_CATEGORY) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ getActionCategory().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE);
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.app.context.IContextListener#contextUpdated()
|
||||
*/
|
||||
public void contextUpdated()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Invalidating Category Management Components...");
|
||||
|
||||
// force a requery of the current category ref properties
|
||||
setCategory(null);
|
||||
|
||||
// force a requery of the richlist dataset
|
||||
if (this.categoriesRichList != null)
|
||||
{
|
||||
this.categoriesRichList.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ID of the currently displayed category or null if at the root.
|
||||
*/
|
||||
public String getCurrentCategoryId()
|
||||
{
|
||||
if (getCategoryRef() != null)
|
||||
{
|
||||
return getCategoryRef().getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current category node.
|
||||
* <p>
|
||||
* Setting this value causes the UI to update and display the specified node as current.
|
||||
*
|
||||
* @param ref The current category node.
|
||||
*/
|
||||
public void setCurrentCategory(NodeRef ref)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Setting current category: " + ref);
|
||||
|
||||
// set the current NodeRef for our UI context operations
|
||||
setCategoryRef(ref);
|
||||
|
||||
// clear current node context
|
||||
setCategory(null);
|
||||
|
||||
// inform that the UI needs updating after this change
|
||||
contextUpdated();
|
||||
}
|
||||
|
||||
|
||||
public String finishDelete()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
if (getActionCategory() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
||||
RetryingTransactionCallback<NodeRef> callback = new RetryingTransactionCallback<NodeRef>()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
public NodeRef execute() throws Throwable
|
||||
{
|
||||
// delete the category node using the nodeservice
|
||||
NodeRef categoryNodeRef = getActionCategory().getNodeRef();
|
||||
getCategoryService().deleteCategory(categoryNodeRef);
|
||||
|
||||
// if there are other items in the repository using this category
|
||||
// all the associations to the category should be removed too
|
||||
if (getMembers() != null && getMembers().size() > 0)
|
||||
{
|
||||
for (ChildAssociationRef childRef : getMembers())
|
||||
{
|
||||
List<NodeRef> list = new ArrayList<NodeRef>(getMembers().size());
|
||||
|
||||
NodeRef member = childRef.getChildRef();
|
||||
Collection<NodeRef> categories = (Collection<NodeRef>)getNodeService().getProperty(member, ContentModel.PROP_CATEGORIES);
|
||||
|
||||
for (NodeRef category : categories)
|
||||
{
|
||||
if (category.equals(categoryNodeRef) == false)
|
||||
{
|
||||
list.add(category);
|
||||
}
|
||||
}
|
||||
|
||||
// persist the list back to the repository
|
||||
getNodeService().setProperty(member, ContentModel.PROP_CATEGORIES, (Serializable) list);
|
||||
}
|
||||
}
|
||||
return categoryNodeRef;
|
||||
}
|
||||
};
|
||||
NodeRef categoryNodeRef = txnHelper.doInTransaction(callback);
|
||||
|
||||
// Figure out if the deletion is made by an icon or by a list of actions
|
||||
CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
|
||||
.getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
|
||||
setLocation(categoriesDialog.getLocation());
|
||||
List<IBreadcrumbHandler> location = getLocation();
|
||||
CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
|
||||
setCategoryFlag(!handler.toString().equals(getCategory().getName()));
|
||||
|
||||
// clear action context
|
||||
setActionCategory(null);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,307 +1,307 @@
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Depth;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Mode;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.context.UIContextService;
|
||||
import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler;
|
||||
|
||||
public class EditCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 3316665625854694278L;
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
private final static String MSG_EDIT_CATEGORY = "edit_category";
|
||||
private final static String MSG_FINISH = "finish_button";
|
||||
private static final String MSG_CATEGORIES = "categories";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
private Boolean categoryFlag = false;
|
||||
|
||||
String categoryRef = null;
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
this.categoryFlag = false;
|
||||
|
||||
// retrieve parameters
|
||||
categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
// make sure nodeRef was supplied
|
||||
ParameterCheck.mandatoryString(CategoriesDialog.PARAM_CATEGORY_REF, categoryRef);
|
||||
|
||||
// create the node
|
||||
this.category = new Node(new NodeRef(categoryRef));
|
||||
|
||||
setActionCategory(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// add the category to the request object so it gets picked up by
|
||||
// category dialog, this will allow it to be edited in the breadcrumb
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY, this.category.getName());
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public Boolean getCategoryFlag()
|
||||
{
|
||||
return categoryFlag;
|
||||
}
|
||||
|
||||
public void setCategoryFlag(Boolean categoryFlag)
|
||||
{
|
||||
this.categoryFlag = categoryFlag;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setActionCategory(Node node)
|
||||
{
|
||||
this.actionCategory = node;
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// setup form properties
|
||||
setName(node.getName());
|
||||
setDescription((String) node.getProperties().get(ContentModel.PROP_DESCRIPTION));
|
||||
setMembers(getCategoryService().getChildren(node.getNodeRef(), Mode.MEMBERS, Depth.ANY));
|
||||
}
|
||||
else
|
||||
{
|
||||
setName(null);
|
||||
setDescription(null);
|
||||
Object emptyCollection = Collections.emptyList();
|
||||
setMembers((Collection<ChildAssociationRef>) emptyCollection);
|
||||
}
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
|
||||
finishEdit();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_EDIT_CATEGORY) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ getActionCategory().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_FINISH);
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Breadcrumb location list
|
||||
*/
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String finishEdit()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// update the category node
|
||||
NodeRef nodeRef = getActionCategory().getNodeRef();
|
||||
getNodeService().setProperty(nodeRef, ContentModel.PROP_NAME, getName());
|
||||
|
||||
// ALF-1788 Need to rename the association
|
||||
ChildAssociationRef assocRef = getNodeService().getPrimaryParent(nodeRef);
|
||||
QName qname = QName.createQName(
|
||||
assocRef.getQName().getNamespaceURI(),
|
||||
QName.createValidLocalName(name));
|
||||
getNodeService().moveNode(
|
||||
assocRef.getChildRef(),
|
||||
assocRef.getParentRef(),
|
||||
assocRef.getTypeQName(),
|
||||
qname);
|
||||
|
||||
// apply the titled aspect - for description
|
||||
if (getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
|
||||
{
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
}
|
||||
else
|
||||
{
|
||||
getNodeService().setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
}
|
||||
|
||||
//Figure out if the editing is made by an icon or by a list of actions
|
||||
CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
|
||||
.getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
|
||||
setLocation(categoriesDialog.getLocation());
|
||||
List<IBreadcrumbHandler> location = getLocation();
|
||||
CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
|
||||
if (!handler.toString().equals(getCategory().getName()))
|
||||
{
|
||||
setCategoryFlag(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCategoryFlag(false);
|
||||
}
|
||||
Node categoryNode = new Node(nodeRef);
|
||||
setCategory(categoryNode);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.categories;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Depth;
|
||||
import org.alfresco.service.cmr.search.CategoryService.Mode;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.context.UIContextService;
|
||||
import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||
import org.alfresco.web.ui.common.component.data.UIRichList;
|
||||
import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler;
|
||||
|
||||
public class EditCategoryDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 3316665625854694278L;
|
||||
|
||||
private static final String DEFAULT_OUTCOME = "finish";
|
||||
private final static String MSG_EDIT_CATEGORY = "edit_category";
|
||||
private final static String MSG_FINISH = "finish_button";
|
||||
private static final String MSG_CATEGORIES = "categories";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
transient protected CategoryService categoryService;
|
||||
|
||||
/** Action category node */
|
||||
private Node actionCategory = null;
|
||||
|
||||
/** Currently visible category Node */
|
||||
private Node category = null;
|
||||
|
||||
private Boolean categoryFlag = false;
|
||||
|
||||
String categoryRef = null;
|
||||
|
||||
/** Category path breadcrumb location */
|
||||
private List<IBreadcrumbHandler> location = null;
|
||||
|
||||
/** Members of the linked items of a category */
|
||||
private Collection<ChildAssociationRef> members = null;
|
||||
|
||||
/** Component references */
|
||||
protected UIRichList categoriesRichList;
|
||||
|
||||
/** Dialog properties */
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
this.isFinished = false;
|
||||
this.categoryFlag = false;
|
||||
|
||||
// retrieve parameters
|
||||
categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
|
||||
|
||||
// make sure nodeRef was supplied
|
||||
ParameterCheck.mandatoryString(CategoriesDialog.PARAM_CATEGORY_REF, categoryRef);
|
||||
|
||||
// create the node
|
||||
this.category = new Node(new NodeRef(categoryRef));
|
||||
|
||||
setActionCategory(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// add the category to the request object so it gets picked up by
|
||||
// category dialog, this will allow it to be edited in the breadcrumb
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY, this.category.getName());
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public UIRichList getCategoriesRichList()
|
||||
{
|
||||
return categoriesRichList;
|
||||
}
|
||||
|
||||
public void setCategoriesRichList(UIRichList categoriesRichList)
|
||||
{
|
||||
this.categoriesRichList = categoriesRichList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categoryService
|
||||
*/
|
||||
private CategoryService getCategoryService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if(categoryService == null)
|
||||
{
|
||||
categoryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCategoryService();
|
||||
}
|
||||
return categoryService;
|
||||
}
|
||||
|
||||
public void setCategoryService(CategoryService categoryService)
|
||||
{
|
||||
this.categoryService = categoryService;
|
||||
}
|
||||
|
||||
public Node getCategory()
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Node category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public Boolean getCategoryFlag()
|
||||
{
|
||||
return categoryFlag;
|
||||
}
|
||||
|
||||
public void setCategoryFlag(Boolean categoryFlag)
|
||||
{
|
||||
this.categoryFlag = categoryFlag;
|
||||
}
|
||||
|
||||
public Collection<ChildAssociationRef> getMembers()
|
||||
{
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(Collection<ChildAssociationRef> members)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setActionCategory(Node node)
|
||||
{
|
||||
this.actionCategory = node;
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// setup form properties
|
||||
setName(node.getName());
|
||||
setDescription((String) node.getProperties().get(ContentModel.PROP_DESCRIPTION));
|
||||
setMembers(getCategoryService().getChildren(node.getNodeRef(), Mode.MEMBERS, Depth.ANY));
|
||||
}
|
||||
else
|
||||
{
|
||||
setName(null);
|
||||
setDescription(null);
|
||||
Object emptyCollection = Collections.emptyList();
|
||||
setMembers((Collection<ChildAssociationRef>) emptyCollection);
|
||||
}
|
||||
}
|
||||
|
||||
public Node getActionCategory()
|
||||
{
|
||||
return actionCategory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
|
||||
finishEdit();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_EDIT_CATEGORY) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ getActionCategory().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_FINISH);
|
||||
}
|
||||
|
||||
public void setLocation(List<IBreadcrumbHandler> location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Breadcrumb location list
|
||||
*/
|
||||
public List<IBreadcrumbHandler> getLocation()
|
||||
{
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String finishEdit()
|
||||
{
|
||||
String outcome = DEFAULT_OUTCOME;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// update the category node
|
||||
NodeRef nodeRef = getActionCategory().getNodeRef();
|
||||
getNodeService().setProperty(nodeRef, ContentModel.PROP_NAME, getName());
|
||||
|
||||
// ALF-1788 Need to rename the association
|
||||
ChildAssociationRef assocRef = getNodeService().getPrimaryParent(nodeRef);
|
||||
QName qname = QName.createQName(
|
||||
assocRef.getQName().getNamespaceURI(),
|
||||
QName.createValidLocalName(name));
|
||||
getNodeService().moveNode(
|
||||
assocRef.getChildRef(),
|
||||
assocRef.getParentRef(),
|
||||
assocRef.getTypeQName(),
|
||||
qname);
|
||||
|
||||
// apply the titled aspect - for description
|
||||
if (getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
|
||||
{
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
}
|
||||
else
|
||||
{
|
||||
getNodeService().setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, getDescription());
|
||||
}
|
||||
|
||||
//Figure out if the editing is made by an icon or by a list of actions
|
||||
CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
|
||||
.getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
|
||||
setLocation(categoriesDialog.getLocation());
|
||||
List<IBreadcrumbHandler> location = getLocation();
|
||||
CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
|
||||
if (!handler.toString().equals(getCategory().getName()))
|
||||
{
|
||||
setCategoryFlag(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setCategoryFlag(false);
|
||||
}
|
||||
Node categoryNode = new Node(nodeRef);
|
||||
setCategory(categoryNode);
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||
outcome = null;
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,193 +1,193 @@
|
||||
package org.alfresco.web.bean.clipboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.search.QueryParameterDefImpl;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.QueryParameterDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base class representing a single item added to the clipboard.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
abstract class AbstractClipboardItem implements ClipboardItem
|
||||
{
|
||||
protected static Log logger = LogFactory.getLog(ClipboardBean.class);
|
||||
|
||||
protected static final String MSG_COPY_OF = "copy_of";
|
||||
|
||||
/** Shallow search for nodes with a name pattern */
|
||||
private static final String XPATH_QUERY_NODE_MATCH = "./*[like(@cm:name, $cm:name, false)]";
|
||||
|
||||
transient private ServiceRegistry services = null;
|
||||
|
||||
protected NodeRef ref;
|
||||
protected NodeRef parent;
|
||||
protected ClipboardStatus mode;
|
||||
|
||||
// cached values
|
||||
private String name;
|
||||
private QName type;
|
||||
private String icon;
|
||||
|
||||
private List<String> customPasteViewIds;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ref The ref of the item on the clipboard
|
||||
* @param mode The ClipboardStatus enum value
|
||||
*/
|
||||
public AbstractClipboardItem(NodeRef ref, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
this.ref = ref;
|
||||
this.mode = mode;
|
||||
this.customPasteViewIds = customPasteViewIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ref The ref of the item on the clipboard
|
||||
* @param parent The parent of the item on the clipboard
|
||||
* @param mode The ClipboardStatus enum value
|
||||
*/
|
||||
public AbstractClipboardItem(NodeRef ref, NodeRef parent, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
this.ref = ref;
|
||||
this.mode = mode;
|
||||
this.parent = parent;
|
||||
this.customPasteViewIds = customPasteViewIds;
|
||||
}
|
||||
|
||||
public ClipboardStatus getMode()
|
||||
{
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
if (this.name == null)
|
||||
{
|
||||
this.name = (String)getServiceRegistry().getNodeService().getProperty(
|
||||
this.ref, ContentModel.PROP_NAME);
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public QName getType()
|
||||
{
|
||||
if (this.type == null)
|
||||
{
|
||||
this.type = getServiceRegistry().getNodeService().getType(this.ref);
|
||||
}
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getIcon()
|
||||
{
|
||||
if (this.icon == null)
|
||||
{
|
||||
this.icon = (String)getServiceRegistry().getNodeService().getProperty(
|
||||
this.ref, ApplicationModel.PROP_ICON);
|
||||
}
|
||||
return this.icon;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.ref;
|
||||
}
|
||||
|
||||
public NodeRef getParent()
|
||||
{
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override equals() to compare NodeRefs
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof ClipboardItem)
|
||||
{
|
||||
return ((ClipboardItem)obj).getNodeRef().equals(this.ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override hashCode() to use the internal NodeRef hashcode instead
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return ref.hashCode();
|
||||
}
|
||||
|
||||
protected ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
public boolean canCopyToViewId(String viewId)
|
||||
{
|
||||
if (this.customPasteViewIds != null)
|
||||
{
|
||||
return this.customPasteViewIds.contains(viewId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canMoveToViewId(String viewId)
|
||||
{
|
||||
if (this.customPasteViewIds != null)
|
||||
{
|
||||
return this.customPasteViewIds.contains(viewId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean checkExists(String name, NodeRef parent)
|
||||
{
|
||||
QueryParameterDefinition[] params = new QueryParameterDefinition[1];
|
||||
params[0] = new QueryParameterDefImpl(
|
||||
ContentModel.PROP_NAME,
|
||||
getServiceRegistry().getDictionaryService().getDataType(
|
||||
DataTypeDefinition.TEXT),
|
||||
true,
|
||||
name);
|
||||
|
||||
// execute the query
|
||||
List<NodeRef> nodeRefs = getServiceRegistry().getSearchService().selectNodes(
|
||||
parent,
|
||||
XPATH_QUERY_NODE_MATCH,
|
||||
params,
|
||||
getServiceRegistry().getNamespaceService(),
|
||||
false);
|
||||
|
||||
return (nodeRefs.size() != 0);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.clipboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.search.QueryParameterDefImpl;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.search.QueryParameterDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base class representing a single item added to the clipboard.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
abstract class AbstractClipboardItem implements ClipboardItem
|
||||
{
|
||||
protected static Log logger = LogFactory.getLog(ClipboardBean.class);
|
||||
|
||||
protected static final String MSG_COPY_OF = "copy_of";
|
||||
|
||||
/** Shallow search for nodes with a name pattern */
|
||||
private static final String XPATH_QUERY_NODE_MATCH = "./*[like(@cm:name, $cm:name, false)]";
|
||||
|
||||
transient private ServiceRegistry services = null;
|
||||
|
||||
protected NodeRef ref;
|
||||
protected NodeRef parent;
|
||||
protected ClipboardStatus mode;
|
||||
|
||||
// cached values
|
||||
private String name;
|
||||
private QName type;
|
||||
private String icon;
|
||||
|
||||
private List<String> customPasteViewIds;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ref The ref of the item on the clipboard
|
||||
* @param mode The ClipboardStatus enum value
|
||||
*/
|
||||
public AbstractClipboardItem(NodeRef ref, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
this.ref = ref;
|
||||
this.mode = mode;
|
||||
this.customPasteViewIds = customPasteViewIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ref The ref of the item on the clipboard
|
||||
* @param parent The parent of the item on the clipboard
|
||||
* @param mode The ClipboardStatus enum value
|
||||
*/
|
||||
public AbstractClipboardItem(NodeRef ref, NodeRef parent, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
this.ref = ref;
|
||||
this.mode = mode;
|
||||
this.parent = parent;
|
||||
this.customPasteViewIds = customPasteViewIds;
|
||||
}
|
||||
|
||||
public ClipboardStatus getMode()
|
||||
{
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
if (this.name == null)
|
||||
{
|
||||
this.name = (String)getServiceRegistry().getNodeService().getProperty(
|
||||
this.ref, ContentModel.PROP_NAME);
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public QName getType()
|
||||
{
|
||||
if (this.type == null)
|
||||
{
|
||||
this.type = getServiceRegistry().getNodeService().getType(this.ref);
|
||||
}
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getIcon()
|
||||
{
|
||||
if (this.icon == null)
|
||||
{
|
||||
this.icon = (String)getServiceRegistry().getNodeService().getProperty(
|
||||
this.ref, ApplicationModel.PROP_ICON);
|
||||
}
|
||||
return this.icon;
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return this.ref;
|
||||
}
|
||||
|
||||
public NodeRef getParent()
|
||||
{
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override equals() to compare NodeRefs
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof ClipboardItem)
|
||||
{
|
||||
return ((ClipboardItem)obj).getNodeRef().equals(this.ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override hashCode() to use the internal NodeRef hashcode instead
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return ref.hashCode();
|
||||
}
|
||||
|
||||
protected ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
public boolean canCopyToViewId(String viewId)
|
||||
{
|
||||
if (this.customPasteViewIds != null)
|
||||
{
|
||||
return this.customPasteViewIds.contains(viewId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canMoveToViewId(String viewId)
|
||||
{
|
||||
if (this.customPasteViewIds != null)
|
||||
{
|
||||
return this.customPasteViewIds.contains(viewId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean checkExists(String name, NodeRef parent)
|
||||
{
|
||||
QueryParameterDefinition[] params = new QueryParameterDefinition[1];
|
||||
params[0] = new QueryParameterDefImpl(
|
||||
ContentModel.PROP_NAME,
|
||||
getServiceRegistry().getDictionaryService().getDataType(
|
||||
DataTypeDefinition.TEXT),
|
||||
true,
|
||||
name);
|
||||
|
||||
// execute the query
|
||||
List<NodeRef> nodeRefs = getServiceRegistry().getSearchService().selectNodes(
|
||||
parent,
|
||||
XPATH_QUERY_NODE_MATCH,
|
||||
params,
|
||||
getServiceRegistry().getNamespaceService(),
|
||||
false);
|
||||
|
||||
return (nodeRefs.size() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,319 +1,319 @@
|
||||
package org.alfresco.web.bean.clipboard;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.CopyService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem;
|
||||
|
||||
/**
|
||||
* Class representing a 'workspace' store protocol clipboard item
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
private static final long serialVersionUID = -1686557602737846009L;
|
||||
|
||||
private static final String WORKSPACE_PASTE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||
private static final String FORUMS_PASTE_VIEW_ID = "/jsp/forums/forums.jsp";
|
||||
private static final String FORUM_PASTE_VIEW_ID = "/jsp/forums/forum.jsp";
|
||||
|
||||
private static final String MSG_LINK_TO = "link_to";
|
||||
|
||||
// File extension to use for link nodes
|
||||
private static final String LINK_NODE_EXTENSION = ".url";
|
||||
|
||||
|
||||
/**
|
||||
* @param ref
|
||||
* @param mode
|
||||
*/
|
||||
public WorkspaceClipboardItem(NodeRef ref, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
super(ref, mode, customPasteViewIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ref
|
||||
* @param mode
|
||||
*/
|
||||
public WorkspaceClipboardItem(NodeRef ref, NodeRef parent, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
super(ref, parent, mode, customPasteViewIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#supportsLink()
|
||||
*/
|
||||
public boolean supportsLink()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#canCopyToViewId(java.lang.String)
|
||||
*/
|
||||
public boolean canCopyToViewId(String viewId)
|
||||
{
|
||||
return super.canCopyToViewId(viewId) || (WORKSPACE_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUMS_PASTE_VIEW_ID.equals(viewId) || FORUM_PASTE_VIEW_ID.equals(viewId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#canMoveToViewId(java.lang.String)
|
||||
*/
|
||||
public boolean canMoveToViewId(String viewId)
|
||||
{
|
||||
return super.canMoveToViewId(viewId) || (WORKSPACE_PASTE_VIEW_ID.equals(viewId) || FORUMS_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUM_PASTE_VIEW_ID.equals(viewId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#paste(javax.faces.context.FacesContext, java.lang.String, int)
|
||||
*/
|
||||
public boolean paste(final FacesContext fc, String viewId, final int action)
|
||||
{
|
||||
final ServiceRegistry serviceRegistry = getServiceRegistry();
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getTransactionService().getRetryingTransactionHelper();
|
||||
if (super.canCopyToViewId(viewId) || WORKSPACE_PASTE_VIEW_ID.equals(viewId) || FORUMS_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUM_PASTE_VIEW_ID.equals(viewId))
|
||||
{
|
||||
NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);
|
||||
final NodeRef destRef = new NodeRef(Repository.getStoreRef(), navigator.getCurrentNodeId());
|
||||
|
||||
final DictionaryService dd = serviceRegistry.getDictionaryService();
|
||||
final NodeService nodeService = serviceRegistry.getNodeService();
|
||||
final FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
|
||||
final CopyService copyService = serviceRegistry.getCopyService();
|
||||
final MultilingualContentService multilingualContentService = serviceRegistry.getMultilingualContentService();
|
||||
|
||||
final boolean isPrimaryParent;
|
||||
|
||||
final ChildAssociationRef assocRef;
|
||||
|
||||
if (getParent() == null)
|
||||
{
|
||||
assocRef = nodeService.getPrimaryParent(getNodeRef());
|
||||
isPrimaryParent = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef parentNodeRef = getParent();
|
||||
List<ChildAssociationRef> assocList = nodeService.getParentAssocs(getNodeRef());
|
||||
ChildAssociationRef foundRef = null;
|
||||
if (assocList != null)
|
||||
{
|
||||
for (ChildAssociationRef assocListEntry : assocList)
|
||||
{
|
||||
if (parentNodeRef.equals(assocListEntry.getParentRef()))
|
||||
{
|
||||
foundRef = assocListEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assocRef = foundRef;
|
||||
isPrimaryParent = parentNodeRef.equals(nodeService.getPrimaryParent(getNodeRef()).getParentRef());
|
||||
}
|
||||
|
||||
// initial name to attempt the copy of the item with
|
||||
String name = getName();
|
||||
String translationPrefix = "";
|
||||
|
||||
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
|
||||
{
|
||||
// copy as link was specifically requested by the user
|
||||
String linkTo = Application.getMessage(fc, MSG_LINK_TO);
|
||||
name = linkTo + ' ' + name;
|
||||
}
|
||||
|
||||
// Loop until we find a target name that doesn't exist
|
||||
for(;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
final String currentTranslationPrefix = translationPrefix;
|
||||
final String currentName = name;
|
||||
|
||||
// attempt each copy/paste in its own transaction
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
if (getMode() == ClipboardStatus.COPY)
|
||||
{
|
||||
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
|
||||
{
|
||||
// LINK operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to link node ID: " + getNodeRef() + " into node: " + destRef.toString());
|
||||
|
||||
// we create a special Link Object node that has a property to reference the original
|
||||
// create the node using the nodeService (can only use FileFolderService for content)
|
||||
if (checkExists(currentName + LINK_NODE_EXTENSION, destRef) == false)
|
||||
{
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
String newName = currentName + LINK_NODE_EXTENSION;
|
||||
props.put(ContentModel.PROP_NAME, newName);
|
||||
props.put(ContentModel.PROP_LINK_DESTINATION, getNodeRef());
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
// create File Link node
|
||||
ChildAssociationRef childRef = nodeService.createNode(
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(assocRef.getQName().getNamespaceURI(), newName),
|
||||
ApplicationModel.TYPE_FILELINK,
|
||||
props);
|
||||
|
||||
// apply the titled aspect - title and description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, currentName);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, currentName);
|
||||
nodeService.addAspect(childRef.getChildRef(), ContentModel.ASPECT_TITLED, titledProps);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create Folder link node
|
||||
ChildAssociationRef childRef = nodeService.createNode(
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
assocRef.getQName(),
|
||||
ApplicationModel.TYPE_FOLDERLINK,
|
||||
props);
|
||||
|
||||
// apply the uifacets aspect - icon, title and description props
|
||||
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4, 1.0f);
|
||||
uiFacetsProps.put(ApplicationModel.PROP_ICON, "space-icon-link");
|
||||
uiFacetsProps.put(ContentModel.PROP_TITLE, currentName);
|
||||
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, currentName);
|
||||
nodeService.addAspect(childRef.getChildRef(), ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// COPY operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
// first check that we are not attempting to copy a duplicate into the same parent
|
||||
if (destRef.equals(assocRef.getParentRef()) && currentName.equals(getName()))
|
||||
{
|
||||
// manually change the name if this occurs
|
||||
throw new FileExistsException(destRef, currentName);
|
||||
}
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
// copy the file/folder
|
||||
fileFolderService.copy(
|
||||
getNodeRef(),
|
||||
destRef,
|
||||
currentName);
|
||||
}
|
||||
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// copy the mlContainer and its translations
|
||||
multilingualContentService.copyTranslationContainer(getNodeRef(), destRef, currentTranslationPrefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy the node
|
||||
if (checkExists(currentName, destRef) == false)
|
||||
{
|
||||
copyService.copyAndRename(
|
||||
getNodeRef(),
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
assocRef.getQName(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MOVE operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to move node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
// move the file/folder
|
||||
fileFolderService.moveFrom(getNodeRef(), getParent(), destRef, currentName);
|
||||
}
|
||||
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// copy the mlContainer and its translations
|
||||
multilingualContentService.moveTranslationContainer(getNodeRef(), destRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isPrimaryParent)
|
||||
{
|
||||
// move the node
|
||||
nodeService.moveNode(getNodeRef(), destRef, ContentModel.ASSOC_CONTAINS, assocRef.getQName());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeService.removeChild(getParent(), getNodeRef());
|
||||
nodeService.addChild(destRef, getNodeRef(), assocRef.getTypeQName(), assocRef.getQName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// We got here without error, so no need to loop with a new name
|
||||
break;
|
||||
}
|
||||
catch (FileExistsException fileExistsErr)
|
||||
{
|
||||
// If mode is COPY, have another go around the loop with a new name
|
||||
if (getMode() == ClipboardStatus.COPY)
|
||||
{
|
||||
String copyOf = Application.getMessage(fc, MSG_COPY_OF);
|
||||
name = copyOf + ' ' + name;
|
||||
translationPrefix = copyOf + ' ' + translationPrefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we should not rename an item when it is being moved - so exit
|
||||
throw fileExistsErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.clipboard;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.CopyService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem;
|
||||
|
||||
/**
|
||||
* Class representing a 'workspace' store protocol clipboard item
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
private static final long serialVersionUID = -1686557602737846009L;
|
||||
|
||||
private static final String WORKSPACE_PASTE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||
private static final String FORUMS_PASTE_VIEW_ID = "/jsp/forums/forums.jsp";
|
||||
private static final String FORUM_PASTE_VIEW_ID = "/jsp/forums/forum.jsp";
|
||||
|
||||
private static final String MSG_LINK_TO = "link_to";
|
||||
|
||||
// File extension to use for link nodes
|
||||
private static final String LINK_NODE_EXTENSION = ".url";
|
||||
|
||||
|
||||
/**
|
||||
* @param ref
|
||||
* @param mode
|
||||
*/
|
||||
public WorkspaceClipboardItem(NodeRef ref, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
super(ref, mode, customPasteViewIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ref
|
||||
* @param mode
|
||||
*/
|
||||
public WorkspaceClipboardItem(NodeRef ref, NodeRef parent, ClipboardStatus mode, List<String> customPasteViewIds)
|
||||
{
|
||||
super(ref, parent, mode, customPasteViewIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#supportsLink()
|
||||
*/
|
||||
public boolean supportsLink()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#canCopyToViewId(java.lang.String)
|
||||
*/
|
||||
public boolean canCopyToViewId(String viewId)
|
||||
{
|
||||
return super.canCopyToViewId(viewId) || (WORKSPACE_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUMS_PASTE_VIEW_ID.equals(viewId) || FORUM_PASTE_VIEW_ID.equals(viewId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#canMoveToViewId(java.lang.String)
|
||||
*/
|
||||
public boolean canMoveToViewId(String viewId)
|
||||
{
|
||||
return super.canMoveToViewId(viewId) || (WORKSPACE_PASTE_VIEW_ID.equals(viewId) || FORUMS_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUM_PASTE_VIEW_ID.equals(viewId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#paste(javax.faces.context.FacesContext, java.lang.String, int)
|
||||
*/
|
||||
public boolean paste(final FacesContext fc, String viewId, final int action)
|
||||
{
|
||||
final ServiceRegistry serviceRegistry = getServiceRegistry();
|
||||
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getTransactionService().getRetryingTransactionHelper();
|
||||
if (super.canCopyToViewId(viewId) || WORKSPACE_PASTE_VIEW_ID.equals(viewId) || FORUMS_PASTE_VIEW_ID.equals(viewId) ||
|
||||
FORUM_PASTE_VIEW_ID.equals(viewId))
|
||||
{
|
||||
NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);
|
||||
final NodeRef destRef = new NodeRef(Repository.getStoreRef(), navigator.getCurrentNodeId());
|
||||
|
||||
final DictionaryService dd = serviceRegistry.getDictionaryService();
|
||||
final NodeService nodeService = serviceRegistry.getNodeService();
|
||||
final FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
|
||||
final CopyService copyService = serviceRegistry.getCopyService();
|
||||
final MultilingualContentService multilingualContentService = serviceRegistry.getMultilingualContentService();
|
||||
|
||||
final boolean isPrimaryParent;
|
||||
|
||||
final ChildAssociationRef assocRef;
|
||||
|
||||
if (getParent() == null)
|
||||
{
|
||||
assocRef = nodeService.getPrimaryParent(getNodeRef());
|
||||
isPrimaryParent = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef parentNodeRef = getParent();
|
||||
List<ChildAssociationRef> assocList = nodeService.getParentAssocs(getNodeRef());
|
||||
ChildAssociationRef foundRef = null;
|
||||
if (assocList != null)
|
||||
{
|
||||
for (ChildAssociationRef assocListEntry : assocList)
|
||||
{
|
||||
if (parentNodeRef.equals(assocListEntry.getParentRef()))
|
||||
{
|
||||
foundRef = assocListEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assocRef = foundRef;
|
||||
isPrimaryParent = parentNodeRef.equals(nodeService.getPrimaryParent(getNodeRef()).getParentRef());
|
||||
}
|
||||
|
||||
// initial name to attempt the copy of the item with
|
||||
String name = getName();
|
||||
String translationPrefix = "";
|
||||
|
||||
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
|
||||
{
|
||||
// copy as link was specifically requested by the user
|
||||
String linkTo = Application.getMessage(fc, MSG_LINK_TO);
|
||||
name = linkTo + ' ' + name;
|
||||
}
|
||||
|
||||
// Loop until we find a target name that doesn't exist
|
||||
for(;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
final String currentTranslationPrefix = translationPrefix;
|
||||
final String currentName = name;
|
||||
|
||||
// attempt each copy/paste in its own transaction
|
||||
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
if (getMode() == ClipboardStatus.COPY)
|
||||
{
|
||||
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
|
||||
{
|
||||
// LINK operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to link node ID: " + getNodeRef() + " into node: " + destRef.toString());
|
||||
|
||||
// we create a special Link Object node that has a property to reference the original
|
||||
// create the node using the nodeService (can only use FileFolderService for content)
|
||||
if (checkExists(currentName + LINK_NODE_EXTENSION, destRef) == false)
|
||||
{
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
String newName = currentName + LINK_NODE_EXTENSION;
|
||||
props.put(ContentModel.PROP_NAME, newName);
|
||||
props.put(ContentModel.PROP_LINK_DESTINATION, getNodeRef());
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
// create File Link node
|
||||
ChildAssociationRef childRef = nodeService.createNode(
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(assocRef.getQName().getNamespaceURI(), newName),
|
||||
ApplicationModel.TYPE_FILELINK,
|
||||
props);
|
||||
|
||||
// apply the titled aspect - title and description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, currentName);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, currentName);
|
||||
nodeService.addAspect(childRef.getChildRef(), ContentModel.ASPECT_TITLED, titledProps);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create Folder link node
|
||||
ChildAssociationRef childRef = nodeService.createNode(
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
assocRef.getQName(),
|
||||
ApplicationModel.TYPE_FOLDERLINK,
|
||||
props);
|
||||
|
||||
// apply the uifacets aspect - icon, title and description props
|
||||
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4, 1.0f);
|
||||
uiFacetsProps.put(ApplicationModel.PROP_ICON, "space-icon-link");
|
||||
uiFacetsProps.put(ContentModel.PROP_TITLE, currentName);
|
||||
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, currentName);
|
||||
nodeService.addAspect(childRef.getChildRef(), ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// COPY operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
// first check that we are not attempting to copy a duplicate into the same parent
|
||||
if (destRef.equals(assocRef.getParentRef()) && currentName.equals(getName()))
|
||||
{
|
||||
// manually change the name if this occurs
|
||||
throw new FileExistsException(destRef, currentName);
|
||||
}
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
// copy the file/folder
|
||||
fileFolderService.copy(
|
||||
getNodeRef(),
|
||||
destRef,
|
||||
currentName);
|
||||
}
|
||||
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// copy the mlContainer and its translations
|
||||
multilingualContentService.copyTranslationContainer(getNodeRef(), destRef, currentTranslationPrefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy the node
|
||||
if (checkExists(currentName, destRef) == false)
|
||||
{
|
||||
copyService.copyAndRename(
|
||||
getNodeRef(),
|
||||
destRef,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
assocRef.getQName(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MOVE operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to move node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
// move the file/folder
|
||||
fileFolderService.moveFrom(getNodeRef(), getParent(), destRef, currentName);
|
||||
}
|
||||
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
// copy the mlContainer and its translations
|
||||
multilingualContentService.moveTranslationContainer(getNodeRef(), destRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isPrimaryParent)
|
||||
{
|
||||
// move the node
|
||||
nodeService.moveNode(getNodeRef(), destRef, ContentModel.ASSOC_CONTAINS, assocRef.getQName());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeService.removeChild(getParent(), getNodeRef());
|
||||
nodeService.addChild(destRef, getNodeRef(), assocRef.getTypeQName(), assocRef.getQName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// We got here without error, so no need to loop with a new name
|
||||
break;
|
||||
}
|
||||
catch (FileExistsException fileExistsErr)
|
||||
{
|
||||
// If mode is COPY, have another go around the loop with a new name
|
||||
if (getMode() == ClipboardStatus.COPY)
|
||||
{
|
||||
String copyOf = Application.getMessage(fc, MSG_COPY_OF);
|
||||
name = copyOf + ' ' + name;
|
||||
translationPrefix = copyOf + ' ' + translationPrefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we should not rename an item when it is being moved - so exit
|
||||
throw fileExistsErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,175 +1,175 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.DownloadContentServlet;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCCheckoutFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 1137163500648349730L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
public static final String LBL_CHECKOUT = "check_out";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CCCheckoutFileDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return checkoutFile(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CHECKOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
final Node document = property.getDocument();
|
||||
if (document != null){
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, LBL_CHECKOUT) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ document.getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action called upon completion of the Check Out file page
|
||||
*/
|
||||
public String checkoutFile(FacesContext context, String outcome)
|
||||
{
|
||||
boolean checkoutSuccessful = false;
|
||||
final Node node = property.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to checkout content node Id: " + node.getId());
|
||||
|
||||
// checkout the node content to create a working copy
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Checkout copy location: " + property.getCopyLocation());
|
||||
logger.debug("Selected Space Id: " + property.getSelectedSpaceId());
|
||||
}
|
||||
NodeRef workingCopyRef = null;
|
||||
if (property.getCopyLocation().equals(CCProperties.COPYLOCATION_OTHER) && property.getSelectedSpaceId() != null)
|
||||
{
|
||||
// checkout to a arbituary parent Space
|
||||
NodeRef destRef = property.getSelectedSpaceId();
|
||||
|
||||
ChildAssociationRef childAssocRef = getNodeService().getPrimaryParent(destRef);
|
||||
workingCopyRef = property.getVersionOperationsService().checkout(node.getNodeRef(), destRef, ContentModel.ASSOC_CONTAINS, childAssocRef.getQName());
|
||||
}
|
||||
else
|
||||
{
|
||||
// checkout the content to the current space
|
||||
workingCopyRef = property.getVersionOperationsService().checkout(node.getNodeRef());
|
||||
|
||||
// if this is a workflow action and there is a task id
|
||||
// present we need
|
||||
// to also link the working copy to the workflow package so
|
||||
// it appears
|
||||
// in the resources panel in the manage task dialog
|
||||
if (property.isWorkflowAction() && property.getWorkflowTaskId() != null && (property.getWorkflowTaskId().equals("null") == false))
|
||||
{
|
||||
WorkflowTask task = property.getWorkflowService().getTaskById(property.getWorkflowTaskId());
|
||||
if (task != null)
|
||||
{
|
||||
NodeRef workflowPackage = (NodeRef) task.properties.get(WorkflowModel.ASSOC_PACKAGE);
|
||||
if (workflowPackage != null)
|
||||
{
|
||||
getNodeService().addChild(workflowPackage, workingCopyRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName
|
||||
.createValidLocalName((String) getNodeService().getProperty(workingCopyRef, ContentModel.PROP_NAME))));
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Added working copy to workflow package: " + workflowPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the working copy Node instance
|
||||
Node workingCopy = new Node(workingCopyRef);
|
||||
property.setWorkingDocument(workingCopy);
|
||||
|
||||
// create content URL to the content download servlet with ID
|
||||
// and expected filename
|
||||
// the myfile part will be ignored by the servlet but gives the
|
||||
// browser a hint
|
||||
String url = DownloadContentServlet.generateDownloadURL(workingCopyRef, workingCopy.getName());
|
||||
|
||||
workingCopy.getProperties().put("url", url);
|
||||
workingCopy.getProperties().put("fileType32", FileTypeImageUtils.getFileTypeImage(workingCopy.getName(), false));
|
||||
|
||||
// mark as successful
|
||||
checkoutSuccessful = true;
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(context, MSG_ERROR_CHECKOUT) + err.getMessage(), err);
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: checkoutFile called without a current Document!");
|
||||
}
|
||||
|
||||
// determine which page to show next if the checkout was successful.
|
||||
if (checkoutSuccessful)
|
||||
{
|
||||
// If a check-in rule is present in the space
|
||||
// the document was checked out to the working copy would have
|
||||
// already disappeared!
|
||||
if (getNodeService().exists(property.getWorkingDocument().getNodeRef()))
|
||||
{
|
||||
// go to the page that allows the user to download the content
|
||||
// for editing
|
||||
outcome = "dialog:checkoutFileLink"; // "checkoutFileLink";
|
||||
// //checkout-file-link.jsp
|
||||
// currentAction = Action.CHECKOUT_FILE_LINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// show a page telling the user that the content has already
|
||||
// been checked in
|
||||
outcome = "dialog:workingCopyMissing";// "workingCopyMissing";
|
||||
// //
|
||||
// working-copy-missing.jsp
|
||||
// currentAction = Action.WORKING_COPY_MISSING;
|
||||
}
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.DownloadContentServlet;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCCheckoutFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 1137163500648349730L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
public static final String LBL_CHECKOUT = "check_out";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CCCheckoutFileDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return checkoutFile(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CHECKOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
final Node document = property.getDocument();
|
||||
if (document != null){
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, LBL_CHECKOUT) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ document.getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action called upon completion of the Check Out file page
|
||||
*/
|
||||
public String checkoutFile(FacesContext context, String outcome)
|
||||
{
|
||||
boolean checkoutSuccessful = false;
|
||||
final Node node = property.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to checkout content node Id: " + node.getId());
|
||||
|
||||
// checkout the node content to create a working copy
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Checkout copy location: " + property.getCopyLocation());
|
||||
logger.debug("Selected Space Id: " + property.getSelectedSpaceId());
|
||||
}
|
||||
NodeRef workingCopyRef = null;
|
||||
if (property.getCopyLocation().equals(CCProperties.COPYLOCATION_OTHER) && property.getSelectedSpaceId() != null)
|
||||
{
|
||||
// checkout to a arbituary parent Space
|
||||
NodeRef destRef = property.getSelectedSpaceId();
|
||||
|
||||
ChildAssociationRef childAssocRef = getNodeService().getPrimaryParent(destRef);
|
||||
workingCopyRef = property.getVersionOperationsService().checkout(node.getNodeRef(), destRef, ContentModel.ASSOC_CONTAINS, childAssocRef.getQName());
|
||||
}
|
||||
else
|
||||
{
|
||||
// checkout the content to the current space
|
||||
workingCopyRef = property.getVersionOperationsService().checkout(node.getNodeRef());
|
||||
|
||||
// if this is a workflow action and there is a task id
|
||||
// present we need
|
||||
// to also link the working copy to the workflow package so
|
||||
// it appears
|
||||
// in the resources panel in the manage task dialog
|
||||
if (property.isWorkflowAction() && property.getWorkflowTaskId() != null && (property.getWorkflowTaskId().equals("null") == false))
|
||||
{
|
||||
WorkflowTask task = property.getWorkflowService().getTaskById(property.getWorkflowTaskId());
|
||||
if (task != null)
|
||||
{
|
||||
NodeRef workflowPackage = (NodeRef) task.properties.get(WorkflowModel.ASSOC_PACKAGE);
|
||||
if (workflowPackage != null)
|
||||
{
|
||||
getNodeService().addChild(workflowPackage, workingCopyRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName
|
||||
.createValidLocalName((String) getNodeService().getProperty(workingCopyRef, ContentModel.PROP_NAME))));
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Added working copy to workflow package: " + workflowPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the working copy Node instance
|
||||
Node workingCopy = new Node(workingCopyRef);
|
||||
property.setWorkingDocument(workingCopy);
|
||||
|
||||
// create content URL to the content download servlet with ID
|
||||
// and expected filename
|
||||
// the myfile part will be ignored by the servlet but gives the
|
||||
// browser a hint
|
||||
String url = DownloadContentServlet.generateDownloadURL(workingCopyRef, workingCopy.getName());
|
||||
|
||||
workingCopy.getProperties().put("url", url);
|
||||
workingCopy.getProperties().put("fileType32", FileTypeImageUtils.getFileTypeImage(workingCopy.getName(), false));
|
||||
|
||||
// mark as successful
|
||||
checkoutSuccessful = true;
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(context, MSG_ERROR_CHECKOUT) + err.getMessage(), err);
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: checkoutFile called without a current Document!");
|
||||
}
|
||||
|
||||
// determine which page to show next if the checkout was successful.
|
||||
if (checkoutSuccessful)
|
||||
{
|
||||
// If a check-in rule is present in the space
|
||||
// the document was checked out to the working copy would have
|
||||
// already disappeared!
|
||||
if (getNodeService().exists(property.getWorkingDocument().getNodeRef()))
|
||||
{
|
||||
// go to the page that allows the user to download the content
|
||||
// for editing
|
||||
outcome = "dialog:checkoutFileLink"; // "checkoutFileLink";
|
||||
// //checkout-file-link.jsp
|
||||
// currentAction = Action.CHECKOUT_FILE_LINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// show a page telling the user that the content has already
|
||||
// been checked in
|
||||
outcome = "dialog:workingCopyMissing";// "workingCopyMissing";
|
||||
// //
|
||||
// working-copy-missing.jsp
|
||||
// currentAction = Action.WORKING_COPY_MISSING;
|
||||
}
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,90 +1,90 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCCheckoutFileLinkDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -4732775752517417543L;
|
||||
|
||||
public static final String MSG_CHECKOUT_OF = "check_out_of";
|
||||
public static final String LBL_UNDO_CHECKOUT = "undo_checkout";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CCCheckoutFileLinkDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return checkoutFileOK(context, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_CHECKOUT_OF) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_UNDO_CHECKOUT);
|
||||
}
|
||||
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), "ok");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
undoCheckout();
|
||||
resetState();
|
||||
super.cancel();
|
||||
return "browse";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action called upon completion of the Check Out file Link download page
|
||||
*/
|
||||
public String checkoutFileOK(FacesContext context, String outcome)
|
||||
{
|
||||
Node node = property.getWorkingDocument();
|
||||
if (node != null)
|
||||
{
|
||||
// reset the underlying node
|
||||
if (this.browseBean.getDocument() != null)
|
||||
{
|
||||
this.browseBean.getDocument().reset();
|
||||
}
|
||||
|
||||
// clean up and clear action context
|
||||
resetState();
|
||||
property.setDocument(null);
|
||||
property.setWorkingDocument(null);
|
||||
// currentAction = Action.NONE;
|
||||
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + ":browse";
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: checkoutFileOK called without a current WorkingDocument!");
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCCheckoutFileLinkDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -4732775752517417543L;
|
||||
|
||||
public static final String MSG_CHECKOUT_OF = "check_out_of";
|
||||
public static final String LBL_UNDO_CHECKOUT = "undo_checkout";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CCCheckoutFileLinkDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return checkoutFileOK(context, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_CHECKOUT_OF) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_UNDO_CHECKOUT);
|
||||
}
|
||||
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), "ok");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
undoCheckout();
|
||||
resetState();
|
||||
super.cancel();
|
||||
return "browse";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action called upon completion of the Check Out file Link download page
|
||||
*/
|
||||
public String checkoutFileOK(FacesContext context, String outcome)
|
||||
{
|
||||
Node node = property.getWorkingDocument();
|
||||
if (node != null)
|
||||
{
|
||||
// reset the underlying node
|
||||
if (this.browseBean.getDocument() != null)
|
||||
{
|
||||
this.browseBean.getDocument().reset();
|
||||
}
|
||||
|
||||
// clean up and clear action context
|
||||
resetState();
|
||||
property.setDocument(null);
|
||||
property.setWorkingDocument(null);
|
||||
// currentAction = Action.NONE;
|
||||
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + ":browse";
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: checkoutFileOK called without a current WorkingDocument!");
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -1145049277343144264L;
|
||||
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
public static final String LBL_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
property.setDocument(null);
|
||||
property.setWorkingDocument(null);
|
||||
resetState();
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CLOSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_LEFT_QUOTE) + property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -1145049277343144264L;
|
||||
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
public static final String LBL_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
property.setDocument(null);
|
||||
property.setWorkingDocument(null);
|
||||
resetState();
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CLOSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_LEFT_QUOTE) + property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditHtmlInlineDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 5971155828037579931L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return editInline(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_SAVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
return property.getDocument().getName();
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditHtmlInlineDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 5971155828037579931L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return editInline(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_SAVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
return property.getDocument().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditTextInlineDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 4657371875928010937L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return editInline(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_SAVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
return property.getDocument().getName();
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCEditTextInlineDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 4657371875928010937L;
|
||||
|
||||
public static final String LBL_SAVE = "save";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return editInline(context, outcome);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_SAVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
return property.getDocument().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,406 +1,406 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
public class CCProperties implements Serializable
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -79530354521757202L;
|
||||
|
||||
/** The VersionOperationsService to be used by the bean */
|
||||
transient protected CheckOutCheckInService versionOperationsService;
|
||||
|
||||
/** The VersionQueryService to be used by the bean */
|
||||
transient protected VersionService versionQueryService;
|
||||
|
||||
/** The ContentService to be used by the bean */
|
||||
transient protected ContentService contentService;
|
||||
|
||||
/** The WorkflowService to be used by the bean */
|
||||
transient protected WorkflowService workflowService;
|
||||
|
||||
/** Content of the document returned from in-line editing */
|
||||
private String editorOutput;
|
||||
|
||||
/** Content of the document used for HTML in-line editing */
|
||||
private String documentContent;
|
||||
|
||||
/** The working copy of the document we are checking out */
|
||||
private Node workingDocument;
|
||||
|
||||
/** The current document */
|
||||
private Node document;
|
||||
|
||||
/** transient form and upload properties */
|
||||
private File file;
|
||||
private String fileName;
|
||||
private String webdavUrl;
|
||||
private String cifsPath;
|
||||
private boolean keepCheckedOut = false;
|
||||
private boolean minorChange = true;
|
||||
private boolean isWorkflowAction = false;
|
||||
private String workflowTaskId;
|
||||
private NodeRef selectedSpaceId = null;
|
||||
|
||||
/** constants for copy location selection */
|
||||
public static final String COPYLOCATION_CURRENT = "current";
|
||||
public static final String COPYLOCATION_OTHER = "other";
|
||||
|
||||
private String versionNotes = "";
|
||||
private String copyLocation = COPYLOCATION_CURRENT;
|
||||
|
||||
/**
|
||||
* @return Returns the VersionOperationsService.
|
||||
*/
|
||||
public CheckOutCheckInService getVersionOperationsService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (versionOperationsService == null)
|
||||
{
|
||||
versionOperationsService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCheckOutCheckInService();
|
||||
}
|
||||
return versionOperationsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionOperationsService
|
||||
* The VersionOperationsService to set.
|
||||
*/
|
||||
public void setVersionOperationsService(CheckOutCheckInService versionOperationsService)
|
||||
{
|
||||
this.versionOperationsService = versionOperationsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the VersionQueryService.
|
||||
*/
|
||||
public VersionService getVersionQueryService()
|
||||
{
|
||||
if (this.versionQueryService == null)
|
||||
{
|
||||
this.versionQueryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getVersionService();
|
||||
}
|
||||
|
||||
return this.versionQueryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionQueryService
|
||||
* The VersionQueryService to set.
|
||||
*/
|
||||
public void setVersionQueryService(VersionService versionQueryService)
|
||||
{
|
||||
this.versionQueryService = versionQueryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the ContentService.
|
||||
*/
|
||||
public ContentService getContentService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (contentService == null)
|
||||
{
|
||||
contentService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService();
|
||||
}
|
||||
return contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentService
|
||||
* The ContentService to set.
|
||||
*/
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workflowService
|
||||
* The WorkflowService to set.
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the workflowService
|
||||
*/
|
||||
public WorkflowService getWorkflowService()
|
||||
{
|
||||
//check for null for cluster environment
|
||||
if (workflowService == null)
|
||||
{
|
||||
workflowService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWorkflowService();
|
||||
}
|
||||
return workflowService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns output from the in-line editor page.
|
||||
*/
|
||||
public String getEditorOutput()
|
||||
{
|
||||
return this.editorOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param editorOutput
|
||||
* The output from the in-line editor page
|
||||
*/
|
||||
public void setEditorOutput(String editorOutput)
|
||||
{
|
||||
this.editorOutput = editorOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the document content used for HTML in-line editing.
|
||||
*/
|
||||
public String getDocumentContent()
|
||||
{
|
||||
return this.documentContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param documentContent
|
||||
* The document content for HTML in-line editing.
|
||||
*/
|
||||
public void setDocumentContent(String documentContent)
|
||||
{
|
||||
this.documentContent = documentContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the working copy Document.
|
||||
*/
|
||||
public Node getWorkingDocument()
|
||||
{
|
||||
return this.workingDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workingDocument
|
||||
* The working copy Document to set.
|
||||
*/
|
||||
public void setWorkingDocument(Node workingDocument)
|
||||
{
|
||||
this.workingDocument = workingDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The document node being used for the current operation
|
||||
*/
|
||||
public Node getDocument()
|
||||
{
|
||||
return this.document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param document
|
||||
* The document node to be used for the current operation
|
||||
*/
|
||||
public void setDocument(Node document)
|
||||
{
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the selected Space Id.
|
||||
*/
|
||||
public NodeRef getSelectedSpaceId()
|
||||
{
|
||||
return this.selectedSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param selectedSpaceId
|
||||
* The selected Space Id to set.
|
||||
*/
|
||||
public void setSelectedSpaceId(NodeRef selectedSpaceId)
|
||||
{
|
||||
this.selectedSpaceId = selectedSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file
|
||||
*/
|
||||
public File getFile()
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file the file to set
|
||||
*/
|
||||
public void setFile(File file)
|
||||
{
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fileName
|
||||
*/
|
||||
public String getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName the fileName to set
|
||||
*/
|
||||
public void setFileName(String fileName)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keepCheckedOut
|
||||
* The keepCheckedOut to set.
|
||||
*/
|
||||
public void setKeepCheckedOut(boolean keepCheckedOut)
|
||||
{
|
||||
this.keepCheckedOut = keepCheckedOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the keepCheckedOut.
|
||||
*/
|
||||
public boolean getKeepCheckedOut()
|
||||
{
|
||||
return this.keepCheckedOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param minorChange
|
||||
* The minorChange to set.
|
||||
*/
|
||||
public void setMinorChange(boolean minorChange)
|
||||
{
|
||||
this.minorChange = minorChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the minorChange flag.
|
||||
*/
|
||||
public boolean getMinorChange()
|
||||
{
|
||||
return this.minorChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isWorkflowAction
|
||||
*/
|
||||
public boolean isWorkflowAction()
|
||||
{
|
||||
return isWorkflowAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isWorkflowAction the isWorkflowAction to set
|
||||
*/
|
||||
public void setWorkflowAction(boolean isWorkflowAction)
|
||||
{
|
||||
this.isWorkflowAction = isWorkflowAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the workflowTaskId
|
||||
*/
|
||||
public String getWorkflowTaskId()
|
||||
{
|
||||
return workflowTaskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workflowTaskId the workflowTaskId to set
|
||||
*/
|
||||
public void setWorkflowTaskId(String workflowTaskId)
|
||||
{
|
||||
this.workflowTaskId = workflowTaskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the version history notes.
|
||||
*/
|
||||
public String getVersionNotes()
|
||||
{
|
||||
return this.versionNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionNotes
|
||||
* The version history notes to set.
|
||||
*/
|
||||
public void setVersionNotes(String versionNotes)
|
||||
{
|
||||
this.versionNotes = versionNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the copy location. Either the current or other space.
|
||||
*/
|
||||
public String getCopyLocation()
|
||||
{
|
||||
if (this.getFileName() == null || this.getFileName().length() == 0)
|
||||
{
|
||||
return this.copyLocation;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CCProperties.COPYLOCATION_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param copyLocation
|
||||
* The copy location. Either the current or other space.
|
||||
*/
|
||||
public void setCopyLocation(String copyLocation)
|
||||
{
|
||||
this.copyLocation = copyLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns WebDav url for online editing. If webdav online editing didn't yet started, returns null
|
||||
*/
|
||||
public String getWebdavUrl()
|
||||
{
|
||||
return webdavUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param webdavUrl The webdav url. Using only for online editing
|
||||
*/
|
||||
public void setWebdavUrl(String webdavUrl)
|
||||
{
|
||||
this.webdavUrl = webdavUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns CIFS path for online editing. If cifs online editing didn't yet started, returns null
|
||||
*/
|
||||
public String getCifsPath()
|
||||
{
|
||||
return cifsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cifsPath The cifs path. Using only for online editing
|
||||
*/
|
||||
public void setCifsPath(String cifsPath)
|
||||
{
|
||||
this.cifsPath = cifsPath;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
|
||||
public class CCProperties implements Serializable
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -79530354521757202L;
|
||||
|
||||
/** The VersionOperationsService to be used by the bean */
|
||||
transient protected CheckOutCheckInService versionOperationsService;
|
||||
|
||||
/** The VersionQueryService to be used by the bean */
|
||||
transient protected VersionService versionQueryService;
|
||||
|
||||
/** The ContentService to be used by the bean */
|
||||
transient protected ContentService contentService;
|
||||
|
||||
/** The WorkflowService to be used by the bean */
|
||||
transient protected WorkflowService workflowService;
|
||||
|
||||
/** Content of the document returned from in-line editing */
|
||||
private String editorOutput;
|
||||
|
||||
/** Content of the document used for HTML in-line editing */
|
||||
private String documentContent;
|
||||
|
||||
/** The working copy of the document we are checking out */
|
||||
private Node workingDocument;
|
||||
|
||||
/** The current document */
|
||||
private Node document;
|
||||
|
||||
/** transient form and upload properties */
|
||||
private File file;
|
||||
private String fileName;
|
||||
private String webdavUrl;
|
||||
private String cifsPath;
|
||||
private boolean keepCheckedOut = false;
|
||||
private boolean minorChange = true;
|
||||
private boolean isWorkflowAction = false;
|
||||
private String workflowTaskId;
|
||||
private NodeRef selectedSpaceId = null;
|
||||
|
||||
/** constants for copy location selection */
|
||||
public static final String COPYLOCATION_CURRENT = "current";
|
||||
public static final String COPYLOCATION_OTHER = "other";
|
||||
|
||||
private String versionNotes = "";
|
||||
private String copyLocation = COPYLOCATION_CURRENT;
|
||||
|
||||
/**
|
||||
* @return Returns the VersionOperationsService.
|
||||
*/
|
||||
public CheckOutCheckInService getVersionOperationsService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (versionOperationsService == null)
|
||||
{
|
||||
versionOperationsService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getCheckOutCheckInService();
|
||||
}
|
||||
return versionOperationsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionOperationsService
|
||||
* The VersionOperationsService to set.
|
||||
*/
|
||||
public void setVersionOperationsService(CheckOutCheckInService versionOperationsService)
|
||||
{
|
||||
this.versionOperationsService = versionOperationsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the VersionQueryService.
|
||||
*/
|
||||
public VersionService getVersionQueryService()
|
||||
{
|
||||
if (this.versionQueryService == null)
|
||||
{
|
||||
this.versionQueryService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getVersionService();
|
||||
}
|
||||
|
||||
return this.versionQueryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionQueryService
|
||||
* The VersionQueryService to set.
|
||||
*/
|
||||
public void setVersionQueryService(VersionService versionQueryService)
|
||||
{
|
||||
this.versionQueryService = versionQueryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the ContentService.
|
||||
*/
|
||||
public ContentService getContentService()
|
||||
{
|
||||
//check for null in cluster environment
|
||||
if (contentService == null)
|
||||
{
|
||||
contentService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService();
|
||||
}
|
||||
return contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentService
|
||||
* The ContentService to set.
|
||||
*/
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workflowService
|
||||
* The WorkflowService to set.
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the workflowService
|
||||
*/
|
||||
public WorkflowService getWorkflowService()
|
||||
{
|
||||
//check for null for cluster environment
|
||||
if (workflowService == null)
|
||||
{
|
||||
workflowService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getWorkflowService();
|
||||
}
|
||||
return workflowService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns output from the in-line editor page.
|
||||
*/
|
||||
public String getEditorOutput()
|
||||
{
|
||||
return this.editorOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param editorOutput
|
||||
* The output from the in-line editor page
|
||||
*/
|
||||
public void setEditorOutput(String editorOutput)
|
||||
{
|
||||
this.editorOutput = editorOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the document content used for HTML in-line editing.
|
||||
*/
|
||||
public String getDocumentContent()
|
||||
{
|
||||
return this.documentContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param documentContent
|
||||
* The document content for HTML in-line editing.
|
||||
*/
|
||||
public void setDocumentContent(String documentContent)
|
||||
{
|
||||
this.documentContent = documentContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the working copy Document.
|
||||
*/
|
||||
public Node getWorkingDocument()
|
||||
{
|
||||
return this.workingDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workingDocument
|
||||
* The working copy Document to set.
|
||||
*/
|
||||
public void setWorkingDocument(Node workingDocument)
|
||||
{
|
||||
this.workingDocument = workingDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The document node being used for the current operation
|
||||
*/
|
||||
public Node getDocument()
|
||||
{
|
||||
return this.document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param document
|
||||
* The document node to be used for the current operation
|
||||
*/
|
||||
public void setDocument(Node document)
|
||||
{
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the selected Space Id.
|
||||
*/
|
||||
public NodeRef getSelectedSpaceId()
|
||||
{
|
||||
return this.selectedSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param selectedSpaceId
|
||||
* The selected Space Id to set.
|
||||
*/
|
||||
public void setSelectedSpaceId(NodeRef selectedSpaceId)
|
||||
{
|
||||
this.selectedSpaceId = selectedSpaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file
|
||||
*/
|
||||
public File getFile()
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file the file to set
|
||||
*/
|
||||
public void setFile(File file)
|
||||
{
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fileName
|
||||
*/
|
||||
public String getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName the fileName to set
|
||||
*/
|
||||
public void setFileName(String fileName)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keepCheckedOut
|
||||
* The keepCheckedOut to set.
|
||||
*/
|
||||
public void setKeepCheckedOut(boolean keepCheckedOut)
|
||||
{
|
||||
this.keepCheckedOut = keepCheckedOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the keepCheckedOut.
|
||||
*/
|
||||
public boolean getKeepCheckedOut()
|
||||
{
|
||||
return this.keepCheckedOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param minorChange
|
||||
* The minorChange to set.
|
||||
*/
|
||||
public void setMinorChange(boolean minorChange)
|
||||
{
|
||||
this.minorChange = minorChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the minorChange flag.
|
||||
*/
|
||||
public boolean getMinorChange()
|
||||
{
|
||||
return this.minorChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isWorkflowAction
|
||||
*/
|
||||
public boolean isWorkflowAction()
|
||||
{
|
||||
return isWorkflowAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isWorkflowAction the isWorkflowAction to set
|
||||
*/
|
||||
public void setWorkflowAction(boolean isWorkflowAction)
|
||||
{
|
||||
this.isWorkflowAction = isWorkflowAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the workflowTaskId
|
||||
*/
|
||||
public String getWorkflowTaskId()
|
||||
{
|
||||
return workflowTaskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workflowTaskId the workflowTaskId to set
|
||||
*/
|
||||
public void setWorkflowTaskId(String workflowTaskId)
|
||||
{
|
||||
this.workflowTaskId = workflowTaskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the version history notes.
|
||||
*/
|
||||
public String getVersionNotes()
|
||||
{
|
||||
return this.versionNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param versionNotes
|
||||
* The version history notes to set.
|
||||
*/
|
||||
public void setVersionNotes(String versionNotes)
|
||||
{
|
||||
this.versionNotes = versionNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the copy location. Either the current or other space.
|
||||
*/
|
||||
public String getCopyLocation()
|
||||
{
|
||||
if (this.getFileName() == null || this.getFileName().length() == 0)
|
||||
{
|
||||
return this.copyLocation;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CCProperties.COPYLOCATION_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param copyLocation
|
||||
* The copy location. Either the current or other space.
|
||||
*/
|
||||
public void setCopyLocation(String copyLocation)
|
||||
{
|
||||
this.copyLocation = copyLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns WebDav url for online editing. If webdav online editing didn't yet started, returns null
|
||||
*/
|
||||
public String getWebdavUrl()
|
||||
{
|
||||
return webdavUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param webdavUrl The webdav url. Using only for online editing
|
||||
*/
|
||||
public void setWebdavUrl(String webdavUrl)
|
||||
{
|
||||
this.webdavUrl = webdavUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns CIFS path for online editing. If cifs online editing didn't yet started, returns null
|
||||
*/
|
||||
public String getCifsPath()
|
||||
{
|
||||
return cifsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cifsPath The cifs path. Using only for online editing
|
||||
*/
|
||||
public void setCifsPath(String cifsPath)
|
||||
{
|
||||
this.cifsPath = cifsPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,101 +1,101 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCUndoCheckoutFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -6957120889259486975L;
|
||||
|
||||
public static final String LBL_UNDO_CHECKOUT = "undo_checkout";
|
||||
public static final String MSG_UNDO_CHECKOUT_FOR = "undo_checkout_for";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CheckinCheckoutDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return undoCheckoutFile(context, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_UNDO_CHECKOUT_FOR) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_UNDO_CHECKOUT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to undo the checkout of a locked document. This document may
|
||||
* either by the original copy or the working copy node. Therefore calculate
|
||||
* which it is, if the working copy is found then we simply cancel checkout
|
||||
* on that document. If the original copy is found then we need to find the
|
||||
* appropriate working copy and perform the action on that node.
|
||||
*/
|
||||
public String undoCheckoutFile(FacesContext context, String outcome)
|
||||
{
|
||||
Node node = property.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
this.property.getVersionOperationsService().cancelCheckout(node.getNodeRef());
|
||||
}
|
||||
else if (node.hasAspect(ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
// TODO: find the working copy for this document and cancel
|
||||
// the checkout on it
|
||||
// is this possible? as currently only the workingcopy
|
||||
// aspect has the copyReference
|
||||
// attribute - this means we cannot find out where the copy
|
||||
// is to cancel it!
|
||||
// can we construct an XPath node lookup?
|
||||
throw new RuntimeException("NOT IMPLEMENTED");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Node supplied for undo checkout has neither Working Copy or Locked aspect!");
|
||||
}
|
||||
|
||||
resetState();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_CANCELCHECKOUT) + err.getMessage(), err);
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: undoCheckout called without a current WorkingDocument!");
|
||||
}
|
||||
|
||||
return outcome + ":browse";
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class CCUndoCheckoutFileDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = -6957120889259486975L;
|
||||
|
||||
public static final String LBL_UNDO_CHECKOUT = "undo_checkout";
|
||||
public static final String MSG_UNDO_CHECKOUT_FOR = "undo_checkout_for";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
|
||||
private static Log logger = LogFactory.getLog(CheckinCheckoutDialog.class);
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
return undoCheckoutFile(context, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_UNDO_CHECKOUT_FOR) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_UNDO_CHECKOUT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to undo the checkout of a locked document. This document may
|
||||
* either by the original copy or the working copy node. Therefore calculate
|
||||
* which it is, if the working copy is found then we simply cancel checkout
|
||||
* on that document. If the original copy is found then we need to find the
|
||||
* appropriate working copy and perform the action on that node.
|
||||
*/
|
||||
public String undoCheckoutFile(FacesContext context, String outcome)
|
||||
{
|
||||
Node node = property.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (node.hasAspect(ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
this.property.getVersionOperationsService().cancelCheckout(node.getNodeRef());
|
||||
}
|
||||
else if (node.hasAspect(ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
// TODO: find the working copy for this document and cancel
|
||||
// the checkout on it
|
||||
// is this possible? as currently only the workingcopy
|
||||
// aspect has the copyReference
|
||||
// attribute - this means we cannot find out where the copy
|
||||
// is to cancel it!
|
||||
// can we construct an XPath node lookup?
|
||||
throw new RuntimeException("NOT IMPLEMENTED");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Node supplied for undo checkout has neither Working Copy or Locked aspect!");
|
||||
}
|
||||
|
||||
resetState();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_CANCELCHECKOUT) + err.getMessage(), err);
|
||||
ReportedException.throwIfNecessary(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: undoCheckout called without a current WorkingDocument!");
|
||||
}
|
||||
|
||||
return outcome + ":browse";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCWorkingCopyMissingDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 8067485292477557683L;
|
||||
|
||||
public static final String MSG_WORKING_COPY_FOR = "working_copy_for";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
public static final String LBL_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION);
|
||||
|
||||
return getDefaultCancelOutcome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION);
|
||||
|
||||
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + ":browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_WORKING_COPY_FOR) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CLOSE);
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.coci;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
|
||||
public class CCWorkingCopyMissingDialog extends CheckinCheckoutDialog
|
||||
{
|
||||
private static final long serialVersionUID = 8067485292477557683L;
|
||||
|
||||
public static final String MSG_WORKING_COPY_FOR = "working_copy_for";
|
||||
private final static String MSG_LEFT_QUOTE = "left_qoute";
|
||||
private final static String MSG_RIGHT_QUOTE = "right_quote";
|
||||
public static final String LBL_CLOSE = "close";
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION);
|
||||
|
||||
return getDefaultCancelOutcome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cancel()
|
||||
{
|
||||
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AlfrescoNavigationHandler.EXTERNAL_CONTAINER_SESSION);
|
||||
|
||||
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + ":browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainerTitle()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
return Application.getMessage(fc, MSG_WORKING_COPY_FOR) + " " + Application.getMessage(fc, MSG_LEFT_QUOTE)
|
||||
+ property.getDocument().getName() + Application.getMessage(fc, MSG_RIGHT_QUOTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCancelButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), LBL_CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,330 +1,330 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.FileUploadBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Add Content" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AddContentDialog extends BaseContentWizard
|
||||
{
|
||||
private final static String MSG_OK = "ok";
|
||||
private static final long serialVersionUID = 3593557546118692687L;
|
||||
|
||||
protected List<String> inlineEditableMimeTypes;
|
||||
protected File file;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
// Try and extract metadata from the file
|
||||
ContentReader cr = new FileContentReader(this.file);
|
||||
cr.setMimetype(this.mimeType);
|
||||
cr.setEncoding(this.encoding);
|
||||
// create properties for content type
|
||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(5, 1.0f);
|
||||
|
||||
if (Repository.extractMetadata(FacesContext.getCurrentInstance(), cr, contentProps))
|
||||
{
|
||||
this.author = (String)(contentProps.get(ContentModel.PROP_AUTHOR));
|
||||
this.title = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_TITLE));
|
||||
this.description = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_DESCRIPTION));
|
||||
}
|
||||
|
||||
// default the title to the file name if not set
|
||||
if (this.title == null)
|
||||
{
|
||||
this.title = this.fileName;
|
||||
}
|
||||
|
||||
// determine whether inline editing should be enabled by default.
|
||||
// if the mime type of the added file is in the list of mime types
|
||||
// configured in "Content Wizards" then enable inline editing
|
||||
List<String> mimeTypes = getInlineEditableMimeTypes();
|
||||
if (mimeTypes.contains(this.mimeType))
|
||||
{
|
||||
this.inlineEdit = true;
|
||||
}
|
||||
|
||||
saveContent(this.file, null);
|
||||
|
||||
// return default outcome
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
clearUpload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
clearUpload();
|
||||
|
||||
// as we were successful, go to the set properties dialog if asked
|
||||
// to otherwise just return
|
||||
if (this.showOtherProperties)
|
||||
{
|
||||
// check whether the created node is checked out, if a 'check out'
|
||||
// rule is present in the space the new node will be and an
|
||||
// attempt to modify the properties will cause an error (ALF-438)
|
||||
if (getNodeService().hasAspect(this.createdNode, ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_NODE_LOCKED));
|
||||
return outcome;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are going to immediately edit the properties so we need
|
||||
// to setup the BrowseBean context appropriately
|
||||
this.browseBean.setDocument(new Node(this.createdNode));
|
||||
|
||||
return "dialog:setContentProperties";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultFinishOutcome()
|
||||
{
|
||||
// as we are using this dialog outside the dialog framework
|
||||
// just go back to the main page
|
||||
|
||||
return "dialog:close:browse";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @return Returns the message to display when a file has been uploaded
|
||||
*/
|
||||
public String getFileUploadSuccessMsg()
|
||||
{
|
||||
// NOTE: This is a far from ideal solution but will do until we have
|
||||
// a pure JSF upload solution working. This method is only called
|
||||
// after a file is uploaded, so we can calculate the mime type and
|
||||
// determine whether to enable inline editing in here.
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// Identify the mimetype as best as we can
|
||||
this.mimeType = Repository.getMimeTypeForFile(fc, this.fileName, this.file);
|
||||
|
||||
// Identify the encoding as best we can (only really important for text based formats)
|
||||
this.encoding = "UTF-8";
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
if (this.file != null)
|
||||
{
|
||||
is = new BufferedInputStream(new FileInputStream(this.file));
|
||||
this.encoding = Repository.guessEncoding(fc, is, this.mimeType);
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// Not terminal
|
||||
logger.error("Failed to get encoding from file: " + this.fileName, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { is.close(); } catch (Throwable e) {} // Includes NPE
|
||||
}
|
||||
|
||||
// Offer inline editing for HTML only
|
||||
this.inlineEdit = (this.mimeType.equals(MimetypeMap.MIMETYPE_HTML));
|
||||
|
||||
// get the file upload message
|
||||
String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success");
|
||||
return MessageFormat.format(msg, new Object[] {Utils.encode(getFileName())});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the name of the file
|
||||
*/
|
||||
public String getFileName()
|
||||
{
|
||||
// try and retrieve the file and filename from the file upload bean
|
||||
// representing the file we previously uploaded.
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
|
||||
get(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
if (fileBean != null)
|
||||
{
|
||||
this.file = fileBean.getFile();
|
||||
this.fileName = fileBean.getFileName();
|
||||
}
|
||||
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName The name of the file
|
||||
*/
|
||||
public void setFileName(String fileName)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
|
||||
// we also need to keep the file upload bean in sync
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
|
||||
get(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
if (fileBean != null)
|
||||
{
|
||||
fileBean.setFileName(this.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Action event handlers
|
||||
|
||||
/**
|
||||
* Action listener called when the add content dialog is called
|
||||
*/
|
||||
public void start(ActionEvent event)
|
||||
{
|
||||
// NOTE: this is a temporary solution to allow us to use the new dialog
|
||||
// framework beans outside of the dialog framework, we need to do
|
||||
// this because the uploading requires a separate non-JSF form, this
|
||||
// approach can not be used in the current dialog framework. Until
|
||||
// we have a pure JSF upload solution we need this initialisation
|
||||
|
||||
init(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called when the user wishes to remove an uploaded file
|
||||
*/
|
||||
public String removeUploadedFile()
|
||||
{
|
||||
clearUpload();
|
||||
|
||||
// also clear the file name
|
||||
this.fileName = null;
|
||||
|
||||
// refresh the current page
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called when the dialog is cancelled
|
||||
*/
|
||||
public String cancel()
|
||||
{
|
||||
clearUpload();
|
||||
return "dialog:close";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper Methods
|
||||
|
||||
/**
|
||||
* Deletes the uploaded file and removes the FileUploadBean from the session
|
||||
*/
|
||||
protected void clearUpload()
|
||||
{
|
||||
// delete the temporary file we uploaded earlier
|
||||
if (this.file != null)
|
||||
{
|
||||
this.file.delete();
|
||||
}
|
||||
|
||||
this.file = null;
|
||||
|
||||
// remove the file upload bean from the session
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
}
|
||||
|
||||
protected List<String> getInlineEditableMimeTypes()
|
||||
{
|
||||
if ((this.inlineEditableMimeTypes == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.inlineEditableMimeTypes = new ArrayList<String>(8);
|
||||
|
||||
// get the create mime types list from the config
|
||||
ConfigService svc = Application.getConfigService(FacesContext.getCurrentInstance());
|
||||
Config wizardCfg = svc.getConfig("Content Wizards");
|
||||
if (wizardCfg != null)
|
||||
{
|
||||
ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types");
|
||||
if (typesCfg != null)
|
||||
{
|
||||
for (ConfigElement child : typesCfg.getChildren())
|
||||
{
|
||||
String currentMimeType = child.getAttribute("name");
|
||||
this.inlineEditableMimeTypes.add(currentMimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.inlineEditableMimeTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), "error_content"),
|
||||
exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.FileUploadBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Add Content" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class AddContentDialog extends BaseContentWizard
|
||||
{
|
||||
private final static String MSG_OK = "ok";
|
||||
private static final long serialVersionUID = 3593557546118692687L;
|
||||
|
||||
protected List<String> inlineEditableMimeTypes;
|
||||
protected File file;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
// Try and extract metadata from the file
|
||||
ContentReader cr = new FileContentReader(this.file);
|
||||
cr.setMimetype(this.mimeType);
|
||||
cr.setEncoding(this.encoding);
|
||||
// create properties for content type
|
||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(5, 1.0f);
|
||||
|
||||
if (Repository.extractMetadata(FacesContext.getCurrentInstance(), cr, contentProps))
|
||||
{
|
||||
this.author = (String)(contentProps.get(ContentModel.PROP_AUTHOR));
|
||||
this.title = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_TITLE));
|
||||
this.description = DefaultTypeConverter.INSTANCE.convert(String.class, contentProps.get(ContentModel.PROP_DESCRIPTION));
|
||||
}
|
||||
|
||||
// default the title to the file name if not set
|
||||
if (this.title == null)
|
||||
{
|
||||
this.title = this.fileName;
|
||||
}
|
||||
|
||||
// determine whether inline editing should be enabled by default.
|
||||
// if the mime type of the added file is in the list of mime types
|
||||
// configured in "Content Wizards" then enable inline editing
|
||||
List<String> mimeTypes = getInlineEditableMimeTypes();
|
||||
if (mimeTypes.contains(this.mimeType))
|
||||
{
|
||||
this.inlineEdit = true;
|
||||
}
|
||||
|
||||
saveContent(this.file, null);
|
||||
|
||||
// return default outcome
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
clearUpload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
clearUpload();
|
||||
|
||||
// as we were successful, go to the set properties dialog if asked
|
||||
// to otherwise just return
|
||||
if (this.showOtherProperties)
|
||||
{
|
||||
// check whether the created node is checked out, if a 'check out'
|
||||
// rule is present in the space the new node will be and an
|
||||
// attempt to modify the properties will cause an error (ALF-438)
|
||||
if (getNodeService().hasAspect(this.createdNode, ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_NODE_LOCKED));
|
||||
return outcome;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are going to immediately edit the properties so we need
|
||||
// to setup the BrowseBean context appropriately
|
||||
this.browseBean.setDocument(new Node(this.createdNode));
|
||||
|
||||
return "dialog:setContentProperties";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultFinishOutcome()
|
||||
{
|
||||
// as we are using this dialog outside the dialog framework
|
||||
// just go back to the main page
|
||||
|
||||
return "dialog:close:browse";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* @return Returns the message to display when a file has been uploaded
|
||||
*/
|
||||
public String getFileUploadSuccessMsg()
|
||||
{
|
||||
// NOTE: This is a far from ideal solution but will do until we have
|
||||
// a pure JSF upload solution working. This method is only called
|
||||
// after a file is uploaded, so we can calculate the mime type and
|
||||
// determine whether to enable inline editing in here.
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
// Identify the mimetype as best as we can
|
||||
this.mimeType = Repository.getMimeTypeForFile(fc, this.fileName, this.file);
|
||||
|
||||
// Identify the encoding as best we can (only really important for text based formats)
|
||||
this.encoding = "UTF-8";
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
if (this.file != null)
|
||||
{
|
||||
is = new BufferedInputStream(new FileInputStream(this.file));
|
||||
this.encoding = Repository.guessEncoding(fc, is, this.mimeType);
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// Not terminal
|
||||
logger.error("Failed to get encoding from file: " + this.fileName, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { is.close(); } catch (Throwable e) {} // Includes NPE
|
||||
}
|
||||
|
||||
// Offer inline editing for HTML only
|
||||
this.inlineEdit = (this.mimeType.equals(MimetypeMap.MIMETYPE_HTML));
|
||||
|
||||
// get the file upload message
|
||||
String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success");
|
||||
return MessageFormat.format(msg, new Object[] {Utils.encode(getFileName())});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the name of the file
|
||||
*/
|
||||
public String getFileName()
|
||||
{
|
||||
// try and retrieve the file and filename from the file upload bean
|
||||
// representing the file we previously uploaded.
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
|
||||
get(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
if (fileBean != null)
|
||||
{
|
||||
this.file = fileBean.getFile();
|
||||
this.fileName = fileBean.getFileName();
|
||||
}
|
||||
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName The name of the file
|
||||
*/
|
||||
public void setFileName(String fileName)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
|
||||
// we also need to keep the file upload bean in sync
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
|
||||
get(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
if (fileBean != null)
|
||||
{
|
||||
fileBean.setFileName(this.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Action event handlers
|
||||
|
||||
/**
|
||||
* Action listener called when the add content dialog is called
|
||||
*/
|
||||
public void start(ActionEvent event)
|
||||
{
|
||||
// NOTE: this is a temporary solution to allow us to use the new dialog
|
||||
// framework beans outside of the dialog framework, we need to do
|
||||
// this because the uploading requires a separate non-JSF form, this
|
||||
// approach can not be used in the current dialog framework. Until
|
||||
// we have a pure JSF upload solution we need this initialisation
|
||||
|
||||
init(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called when the user wishes to remove an uploaded file
|
||||
*/
|
||||
public String removeUploadedFile()
|
||||
{
|
||||
clearUpload();
|
||||
|
||||
// also clear the file name
|
||||
this.fileName = null;
|
||||
|
||||
// refresh the current page
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler called when the dialog is cancelled
|
||||
*/
|
||||
public String cancel()
|
||||
{
|
||||
clearUpload();
|
||||
return "dialog:close";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper Methods
|
||||
|
||||
/**
|
||||
* Deletes the uploaded file and removes the FileUploadBean from the session
|
||||
*/
|
||||
protected void clearUpload()
|
||||
{
|
||||
// delete the temporary file we uploaded earlier
|
||||
if (this.file != null)
|
||||
{
|
||||
this.file.delete();
|
||||
}
|
||||
|
||||
this.file = null;
|
||||
|
||||
// remove the file upload bean from the session
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME);
|
||||
}
|
||||
|
||||
protected List<String> getInlineEditableMimeTypes()
|
||||
{
|
||||
if ((this.inlineEditableMimeTypes == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
this.inlineEditableMimeTypes = new ArrayList<String>(8);
|
||||
|
||||
// get the create mime types list from the config
|
||||
ConfigService svc = Application.getConfigService(FacesContext.getCurrentInstance());
|
||||
Config wizardCfg = svc.getConfig("Content Wizards");
|
||||
if (wizardCfg != null)
|
||||
{
|
||||
ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types");
|
||||
if (typesCfg != null)
|
||||
{
|
||||
for (ConfigElement child : typesCfg.getChildren())
|
||||
{
|
||||
String currentMimeType = child.getAttribute("name");
|
||||
this.inlineEditableMimeTypes.add(currentMimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.inlineEditableMimeTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), "error_content"),
|
||||
exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,260 +1,260 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ValueChangeEvent;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Create Content Wizard" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class CreateContentWizard extends BaseContentWizard
|
||||
{
|
||||
private static final long serialVersionUID = -2740634368271194418L;
|
||||
|
||||
protected String content = null;
|
||||
protected List<SelectItem> createMimeTypes;
|
||||
|
||||
private static Log logger = LogFactory.getLog(CreateContentWizard.class);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Wizard implementation
|
||||
|
||||
|
||||
@Override
|
||||
public String finish()
|
||||
{
|
||||
String result = super.finish();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
saveContent(null, this.content);
|
||||
|
||||
// return the default outcome
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
this.content = null;
|
||||
this.inlineEdit = true;
|
||||
this.mimeType = MimetypeMap.MIMETYPE_HTML;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNextButtonDisabled()
|
||||
{
|
||||
// TODO: Allow the next button state to be configured so that
|
||||
// wizard implementations don't have to worry about
|
||||
// checking step numbers
|
||||
|
||||
boolean disabled = false;
|
||||
int step = Application.getWizardManager().getCurrentStep();
|
||||
switch(step)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
disabled = (this.fileName == null || this.fileName.length() == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
boolean disabled = false;
|
||||
int step = Application.getWizardManager().getCurrentStep();
|
||||
switch(step)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
disabled = (this.fileName == null || this.fileName.length() == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// as we were successful, go to the set properties dialog if asked
|
||||
// to otherwise just return
|
||||
if (this.showOtherProperties)
|
||||
{
|
||||
// check whether the created node is checked out, if a 'check out'
|
||||
// rule is present in the space the new node will be and an
|
||||
// attempt to modify the properties will cause an error (ALF-438)
|
||||
if (getNodeService().hasAspect(this.createdNode, ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_NODE_LOCKED));
|
||||
return outcome;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are going to immediately edit the properties so we need
|
||||
// to setup the BrowseBean context appropriately
|
||||
this.browseBean.setDocument(new Node(this.createdNode));
|
||||
|
||||
return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"dialog:setContentProperties";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
/**
|
||||
* @return Returns the content from the edited form.
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content The content to edit (should be clear initially)
|
||||
*/
|
||||
public void setContent(String content)
|
||||
{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns a list of mime types to allow the user to select from
|
||||
*/
|
||||
public List<SelectItem> getCreateMimeTypes()
|
||||
{
|
||||
if ((this.createMimeTypes == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
|
||||
// add the well known object type to start with
|
||||
this.createMimeTypes = new ArrayList<SelectItem>(5);
|
||||
|
||||
// add the configured create mime types to the list
|
||||
ConfigService svc = Application.getConfigService(context);
|
||||
Config wizardCfg = svc.getConfig("Content Wizards");
|
||||
if (wizardCfg != null)
|
||||
{
|
||||
ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types");
|
||||
if (typesCfg != null)
|
||||
{
|
||||
for (ConfigElement child : typesCfg.getChildren())
|
||||
{
|
||||
String currentMimeType = child.getAttribute("name");
|
||||
if (currentMimeType != null)
|
||||
{
|
||||
String label = getSummaryMimeType(currentMimeType);
|
||||
this.createMimeTypes.add(new SelectItem(currentMimeType, label));
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the label
|
||||
QuickSort sorter = new QuickSort(this.objectTypes, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Could not find 'create-mime-types' configuration element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Could not find 'Content Wizards' configuration section");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this.createMimeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the summary data for the wizard.
|
||||
*/
|
||||
public String getSummary()
|
||||
{
|
||||
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
|
||||
|
||||
// TODO: show first few lines of content here?
|
||||
return buildSummary(
|
||||
new String[] {bundle.getString("file_name"),
|
||||
bundle.getString("type"),
|
||||
bundle.getString("content_type")},
|
||||
new String[] {Utils.encode(this.fileName), getSummaryObjectType(),
|
||||
getSummaryMimeType(this.mimeType)});
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Action event handlers
|
||||
|
||||
/**
|
||||
* Create content type value changed by the user
|
||||
*/
|
||||
public void createContentChanged(ValueChangeEvent event)
|
||||
{
|
||||
// clear the content as HTML is not compatible with the plain text box etc.
|
||||
this.content = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), "error_content"),
|
||||
exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ValueChangeEvent;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigElement;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Create Content Wizard" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class CreateContentWizard extends BaseContentWizard
|
||||
{
|
||||
private static final long serialVersionUID = -2740634368271194418L;
|
||||
|
||||
protected String content = null;
|
||||
protected List<SelectItem> createMimeTypes;
|
||||
|
||||
private static Log logger = LogFactory.getLog(CreateContentWizard.class);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Wizard implementation
|
||||
|
||||
|
||||
@Override
|
||||
public String finish()
|
||||
{
|
||||
String result = super.finish();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
saveContent(null, this.content);
|
||||
|
||||
// return the default outcome
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
this.content = null;
|
||||
this.inlineEdit = true;
|
||||
this.mimeType = MimetypeMap.MIMETYPE_HTML;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNextButtonDisabled()
|
||||
{
|
||||
// TODO: Allow the next button state to be configured so that
|
||||
// wizard implementations don't have to worry about
|
||||
// checking step numbers
|
||||
|
||||
boolean disabled = false;
|
||||
int step = Application.getWizardManager().getCurrentStep();
|
||||
switch(step)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
disabled = (this.fileName == null || this.fileName.length() == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
boolean disabled = false;
|
||||
int step = Application.getWizardManager().getCurrentStep();
|
||||
switch(step)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
disabled = (this.fileName == null || this.fileName.length() == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// as we were successful, go to the set properties dialog if asked
|
||||
// to otherwise just return
|
||||
if (this.showOtherProperties)
|
||||
{
|
||||
// check whether the created node is checked out, if a 'check out'
|
||||
// rule is present in the space the new node will be and an
|
||||
// attempt to modify the properties will cause an error (ALF-438)
|
||||
if (getNodeService().hasAspect(this.createdNode, ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_NODE_LOCKED));
|
||||
return outcome;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are going to immediately edit the properties so we need
|
||||
// to setup the BrowseBean context appropriately
|
||||
this.browseBean.setDocument(new Node(this.createdNode));
|
||||
|
||||
return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"dialog:setContentProperties";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
/**
|
||||
* @return Returns the content from the edited form.
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content The content to edit (should be clear initially)
|
||||
*/
|
||||
public void setContent(String content)
|
||||
{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns a list of mime types to allow the user to select from
|
||||
*/
|
||||
public List<SelectItem> getCreateMimeTypes()
|
||||
{
|
||||
if ((this.createMimeTypes == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
|
||||
// add the well known object type to start with
|
||||
this.createMimeTypes = new ArrayList<SelectItem>(5);
|
||||
|
||||
// add the configured create mime types to the list
|
||||
ConfigService svc = Application.getConfigService(context);
|
||||
Config wizardCfg = svc.getConfig("Content Wizards");
|
||||
if (wizardCfg != null)
|
||||
{
|
||||
ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types");
|
||||
if (typesCfg != null)
|
||||
{
|
||||
for (ConfigElement child : typesCfg.getChildren())
|
||||
{
|
||||
String currentMimeType = child.getAttribute("name");
|
||||
if (currentMimeType != null)
|
||||
{
|
||||
String label = getSummaryMimeType(currentMimeType);
|
||||
this.createMimeTypes.add(new SelectItem(currentMimeType, label));
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the label
|
||||
QuickSort sorter = new QuickSort(this.objectTypes, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Could not find 'create-mime-types' configuration element");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Could not find 'Content Wizards' configuration section");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this.createMimeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the summary data for the wizard.
|
||||
*/
|
||||
public String getSummary()
|
||||
{
|
||||
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
|
||||
|
||||
// TODO: show first few lines of content here?
|
||||
return buildSummary(
|
||||
new String[] {bundle.getString("file_name"),
|
||||
bundle.getString("type"),
|
||||
bundle.getString("content_type")},
|
||||
new String[] {Utils.encode(this.fileName), getSummaryObjectType(),
|
||||
getSummaryMimeType(this.mimeType)});
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Action event handlers
|
||||
|
||||
/**
|
||||
* Create content type value changed by the user
|
||||
*/
|
||||
public void createContentChanged(ValueChangeEvent event)
|
||||
{
|
||||
// clear the content as HTML is not compatible with the plain text box etc.
|
||||
this.content = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), "error_content"),
|
||||
exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,155 +1,155 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Delete Content" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DeleteContentDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 4199496011879649213L;
|
||||
|
||||
transient private MultilingualContentService multilingualContentService;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DeleteContentDialog.class);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
// get the content to delete
|
||||
Node node = this.browseBean.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(node.getType()))
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to delete multilingual container: " + node.getId() + " and its translations" );
|
||||
|
||||
// delete the mlContainer and its translations
|
||||
getMultilingualContentService().deleteTranslationContainer(node.getNodeRef());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to delete content node: " + node.getId());
|
||||
|
||||
// delete the node
|
||||
this.getNodeService().deleteNode(node.getNodeRef());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: delete called without a current Document!");
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// clear action context
|
||||
this.browseBean.setDocument(null);
|
||||
|
||||
// setting the outcome will show the browse view again
|
||||
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getErrorMessageId()
|
||||
{
|
||||
return "error_delete_file";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
/**
|
||||
* Returns the confirmation to display to the user before deleting the content.
|
||||
*
|
||||
* @return The formatted message to display
|
||||
*/
|
||||
public String getConfirmMessage()
|
||||
{
|
||||
String fileConfirmMsg = null;
|
||||
|
||||
Node document = this.browseBean.getDocument();
|
||||
|
||||
if(document.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_ml_container_confirm");
|
||||
}
|
||||
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_empty_translation_confirm");
|
||||
}
|
||||
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_translation_confirm");
|
||||
}
|
||||
else
|
||||
{
|
||||
String strHasMultipleParents = this.parameters.get("hasMultipleParents");
|
||||
if (strHasMultipleParents != null && "true".equals(strHasMultipleParents))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_file_multiple_parents_confirm");
|
||||
}
|
||||
else
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_file_confirm");
|
||||
}
|
||||
}
|
||||
|
||||
return MessageFormat.format(fileConfirmMsg,
|
||||
new Object[] {document.getName()});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param multilingualContentService the Multilingual Content Service to set
|
||||
*/
|
||||
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
|
||||
{
|
||||
this.multilingualContentService = multilingualContentService;
|
||||
}
|
||||
|
||||
protected MultilingualContentService getMultilingualContentService()
|
||||
{
|
||||
if (multilingualContentService == null)
|
||||
{
|
||||
multilingualContentService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getMultilingualContentService();
|
||||
}
|
||||
return multilingualContentService;
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.ml.MultilingualContentService;
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Delete Content" dialog
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DeleteContentDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = 4199496011879649213L;
|
||||
|
||||
transient private MultilingualContentService multilingualContentService;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DeleteContentDialog.class);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
// get the content to delete
|
||||
Node node = this.browseBean.getDocument();
|
||||
if (node != null)
|
||||
{
|
||||
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(node.getType()))
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to delete multilingual container: " + node.getId() + " and its translations" );
|
||||
|
||||
// delete the mlContainer and its translations
|
||||
getMultilingualContentService().deleteTranslationContainer(node.getNodeRef());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Trying to delete content node: " + node.getId());
|
||||
|
||||
// delete the node
|
||||
this.getNodeService().deleteNode(node.getNodeRef());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: delete called without a current Document!");
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// clear action context
|
||||
this.browseBean.setDocument(null);
|
||||
|
||||
// setting the outcome will show the browse view again
|
||||
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getErrorMessageId()
|
||||
{
|
||||
return "error_delete_file";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
/**
|
||||
* Returns the confirmation to display to the user before deleting the content.
|
||||
*
|
||||
* @return The formatted message to display
|
||||
*/
|
||||
public String getConfirmMessage()
|
||||
{
|
||||
String fileConfirmMsg = null;
|
||||
|
||||
Node document = this.browseBean.getDocument();
|
||||
|
||||
if(document.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_ml_container_confirm");
|
||||
}
|
||||
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_empty_translation_confirm");
|
||||
}
|
||||
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_translation_confirm");
|
||||
}
|
||||
else
|
||||
{
|
||||
String strHasMultipleParents = this.parameters.get("hasMultipleParents");
|
||||
if (strHasMultipleParents != null && "true".equals(strHasMultipleParents))
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_file_multiple_parents_confirm");
|
||||
}
|
||||
else
|
||||
{
|
||||
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_file_confirm");
|
||||
}
|
||||
}
|
||||
|
||||
return MessageFormat.format(fileConfirmMsg,
|
||||
new Object[] {document.getName()});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param multilingualContentService the Multilingual Content Service to set
|
||||
*/
|
||||
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
|
||||
{
|
||||
this.multilingualContentService = multilingualContentService;
|
||||
}
|
||||
|
||||
protected MultilingualContentService getMultilingualContentService()
|
||||
{
|
||||
if (multilingualContentService == null)
|
||||
{
|
||||
multilingualContentService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getMultilingualContentService();
|
||||
}
|
||||
return multilingualContentService;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,306 +1,306 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Bean implementation of the "Edit Content Properties" dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class EditContentPropertiesDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -5681296528149487178L;
|
||||
|
||||
protected static final String TEMP_PROP_MIMETYPE = "mimetype";
|
||||
protected static final String TEMP_PROP_ENCODING = "encoding";
|
||||
|
||||
protected Node editableNode;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
// setup the editable node
|
||||
this.editableNode = initEditableNode();
|
||||
|
||||
if(editableNode != null)
|
||||
{
|
||||
|
||||
// special case for Mimetype - since this is a sub-property of the ContentData object
|
||||
// we must extract it so it can be edited in the client, then we check for it later
|
||||
// and create a new ContentData object to wrap it and it's associated URL
|
||||
ContentData content = (ContentData)this.editableNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
this.editableNode.getProperties().put(TEMP_PROP_MIMETYPE, content.getMimetype());
|
||||
this.editableNode.getProperties().put(TEMP_PROP_ENCODING, content.getEncoding());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the editable Node
|
||||
*/
|
||||
protected Node initEditableNode()
|
||||
{
|
||||
final Node document = this.browseBean.getDocument();
|
||||
if (document != null)
|
||||
{
|
||||
return new Node(document.getNodeRef());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
NodeRef nodeRef = this.editableNode.getNodeRef();
|
||||
Map<String, Object> editedProps = this.editableNode.getProperties();
|
||||
|
||||
// get the name and move the node as necessary
|
||||
String name = (String) editedProps.get(ContentModel.PROP_NAME);
|
||||
if (name != null)
|
||||
{
|
||||
getFileFolderService().rename(nodeRef, name);
|
||||
}
|
||||
|
||||
// we need to put all the properties from the editable bag back into
|
||||
// the format expected by the repository
|
||||
Map<QName, Serializable> repoProps = this.getNodeService().getProperties(nodeRef);
|
||||
|
||||
// Extract and deal with the special mimetype property for ContentData
|
||||
String mimetype = (String) editedProps.get(TEMP_PROP_MIMETYPE);
|
||||
if (mimetype != null)
|
||||
{
|
||||
// remove temporary prop from list so it isn't saved with the others
|
||||
editedProps.remove(TEMP_PROP_MIMETYPE);
|
||||
ContentData contentData = (ContentData)editedProps.get(ContentModel.PROP_CONTENT);
|
||||
if (contentData != null)
|
||||
{
|
||||
contentData = ContentData.setMimetype(contentData, mimetype);
|
||||
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
|
||||
}
|
||||
}
|
||||
// Extract and deal with the special encoding property for ContentData
|
||||
String encoding = (String) editedProps.get(TEMP_PROP_ENCODING);
|
||||
if (encoding != null)
|
||||
{
|
||||
// remove temporary prop from list so it isn't saved with the others
|
||||
editedProps.remove(TEMP_PROP_ENCODING);
|
||||
ContentData contentData = (ContentData) editedProps.get(ContentModel.PROP_CONTENT);
|
||||
if (contentData != null)
|
||||
{
|
||||
contentData = ContentData.setEncoding(contentData, encoding);
|
||||
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
|
||||
}
|
||||
}
|
||||
|
||||
// add the "author" aspect if required, properties will get set below
|
||||
if (this.getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_AUTHOR) == false)
|
||||
{
|
||||
this.getNodeService().addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, null);
|
||||
}
|
||||
|
||||
// add the "titled" aspect if required, properties will get set below
|
||||
if (this.getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
|
||||
{
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
|
||||
}
|
||||
|
||||
// add the remaining properties
|
||||
Iterator<String> iterProps = editedProps.keySet().iterator();
|
||||
while (iterProps.hasNext())
|
||||
{
|
||||
String propName = iterProps.next();
|
||||
QName qname = QName.createQName(propName);
|
||||
|
||||
// make sure the property is represented correctly
|
||||
Serializable propValue = (Serializable)editedProps.get(propName);
|
||||
|
||||
// check for empty strings when using number types, set to null in this case
|
||||
if (propValue instanceof String)
|
||||
{
|
||||
PropertyDefinition propDef = this.getDictionaryService().getProperty(qname);
|
||||
if (((String)propValue).length() == 0)
|
||||
{
|
||||
if (propDef != null)
|
||||
{
|
||||
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
|
||||
{
|
||||
propValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle locale strings to Locale objects
|
||||
else if (propDef != null && propDef.getDataType().getName().equals(DataTypeDefinition.LOCALE))
|
||||
{
|
||||
propValue = I18NUtil.parseLocale((String)propValue);
|
||||
}
|
||||
}
|
||||
|
||||
repoProps.put(qname, propValue);
|
||||
}
|
||||
|
||||
// send the properties back to the repository
|
||||
this.getNodeService().setProperties(nodeRef, repoProps);
|
||||
|
||||
// we also need to persist any association changes that may have been made
|
||||
|
||||
// add any associations added in the UI
|
||||
Map<String, Map<String, AssociationRef>> addedAssocs = this.editableNode.getAddedAssociations();
|
||||
for (Map<String, AssociationRef> typedAssoc : addedAssocs.values())
|
||||
{
|
||||
for (AssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().createAssociation(assoc.getSourceRef(), assoc.getTargetRef(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// remove any association removed in the UI
|
||||
Map<String, Map<String, AssociationRef>> removedAssocs = this.editableNode.getRemovedAssociations();
|
||||
for (Map<String, AssociationRef> typedAssoc : removedAssocs.values())
|
||||
{
|
||||
for (AssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().removeAssociation(assoc.getSourceRef(), assoc.getTargetRef(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// add any child associations added in the UI
|
||||
Map<String, Map<String, ChildAssociationRef>> addedChildAssocs = this.editableNode.getAddedChildAssociations();
|
||||
for (Map<String, ChildAssociationRef> typedAssoc : addedChildAssocs.values())
|
||||
{
|
||||
for (ChildAssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().addChild(assoc.getParentRef(), assoc.getChildRef(), assoc.getTypeQName(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// remove any child association removed in the UI
|
||||
Map<String, Map<String, ChildAssociationRef>> removedChildAssocs = this.editableNode.getRemovedChildAssociations();
|
||||
for (Map<String, ChildAssociationRef> typedAssoc : removedChildAssocs.values())
|
||||
{
|
||||
for (ChildAssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().removeChild(assoc.getParentRef(), assoc.getChildRef());
|
||||
}
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// reset the document held by the browse bean as it's just been updated
|
||||
this.browseBean.getDocument().reset();
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the error message to display if an error occurs during finish processing
|
||||
*
|
||||
* @param exception The exception
|
||||
* @return The formatted message
|
||||
*/
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if(editableNode != null)
|
||||
{
|
||||
|
||||
// special case for Mimetype - since this is a sub-property of the ContentData object
|
||||
// we must extract it so it can be edited in the client, then we check for it later
|
||||
// and create a new ContentData object to wrap it and it's associated URL
|
||||
ContentData content = (ContentData)this.editableNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
this.editableNode.getProperties().put(TEMP_PROP_MIMETYPE, content.getMimetype());
|
||||
this.editableNode.getProperties().put(TEMP_PROP_ENCODING, content.getEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else if (exception instanceof InvalidNodeRefException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF),
|
||||
new Object[] {this.browseBean.getDocument().getId()});
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.formatErrorMessage(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getErrorOutcome(Throwable exception)
|
||||
{
|
||||
if (exception instanceof InvalidNodeRefException)
|
||||
{
|
||||
// this failure means the node no longer exists - we cannot show
|
||||
// the content properties screen again so go back to the main page
|
||||
return "browse";
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.getErrorOutcome(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* Returns the node being edited
|
||||
*
|
||||
* @return The node being edited
|
||||
*/
|
||||
public Node getEditableNode()
|
||||
{
|
||||
return this.editableNode;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
/**
|
||||
* Bean implementation of the "Edit Content Properties" dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class EditContentPropertiesDialog extends BaseDialogBean
|
||||
{
|
||||
private static final long serialVersionUID = -5681296528149487178L;
|
||||
|
||||
protected static final String TEMP_PROP_MIMETYPE = "mimetype";
|
||||
protected static final String TEMP_PROP_ENCODING = "encoding";
|
||||
|
||||
protected Node editableNode;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
// setup the editable node
|
||||
this.editableNode = initEditableNode();
|
||||
|
||||
if(editableNode != null)
|
||||
{
|
||||
|
||||
// special case for Mimetype - since this is a sub-property of the ContentData object
|
||||
// we must extract it so it can be edited in the client, then we check for it later
|
||||
// and create a new ContentData object to wrap it and it's associated URL
|
||||
ContentData content = (ContentData)this.editableNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
this.editableNode.getProperties().put(TEMP_PROP_MIMETYPE, content.getMimetype());
|
||||
this.editableNode.getProperties().put(TEMP_PROP_ENCODING, content.getEncoding());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the editable Node
|
||||
*/
|
||||
protected Node initEditableNode()
|
||||
{
|
||||
final Node document = this.browseBean.getDocument();
|
||||
if (document != null)
|
||||
{
|
||||
return new Node(document.getNodeRef());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
NodeRef nodeRef = this.editableNode.getNodeRef();
|
||||
Map<String, Object> editedProps = this.editableNode.getProperties();
|
||||
|
||||
// get the name and move the node as necessary
|
||||
String name = (String) editedProps.get(ContentModel.PROP_NAME);
|
||||
if (name != null)
|
||||
{
|
||||
getFileFolderService().rename(nodeRef, name);
|
||||
}
|
||||
|
||||
// we need to put all the properties from the editable bag back into
|
||||
// the format expected by the repository
|
||||
Map<QName, Serializable> repoProps = this.getNodeService().getProperties(nodeRef);
|
||||
|
||||
// Extract and deal with the special mimetype property for ContentData
|
||||
String mimetype = (String) editedProps.get(TEMP_PROP_MIMETYPE);
|
||||
if (mimetype != null)
|
||||
{
|
||||
// remove temporary prop from list so it isn't saved with the others
|
||||
editedProps.remove(TEMP_PROP_MIMETYPE);
|
||||
ContentData contentData = (ContentData)editedProps.get(ContentModel.PROP_CONTENT);
|
||||
if (contentData != null)
|
||||
{
|
||||
contentData = ContentData.setMimetype(contentData, mimetype);
|
||||
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
|
||||
}
|
||||
}
|
||||
// Extract and deal with the special encoding property for ContentData
|
||||
String encoding = (String) editedProps.get(TEMP_PROP_ENCODING);
|
||||
if (encoding != null)
|
||||
{
|
||||
// remove temporary prop from list so it isn't saved with the others
|
||||
editedProps.remove(TEMP_PROP_ENCODING);
|
||||
ContentData contentData = (ContentData) editedProps.get(ContentModel.PROP_CONTENT);
|
||||
if (contentData != null)
|
||||
{
|
||||
contentData = ContentData.setEncoding(contentData, encoding);
|
||||
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
|
||||
}
|
||||
}
|
||||
|
||||
// add the "author" aspect if required, properties will get set below
|
||||
if (this.getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_AUTHOR) == false)
|
||||
{
|
||||
this.getNodeService().addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, null);
|
||||
}
|
||||
|
||||
// add the "titled" aspect if required, properties will get set below
|
||||
if (this.getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
|
||||
{
|
||||
getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
|
||||
}
|
||||
|
||||
// add the remaining properties
|
||||
Iterator<String> iterProps = editedProps.keySet().iterator();
|
||||
while (iterProps.hasNext())
|
||||
{
|
||||
String propName = iterProps.next();
|
||||
QName qname = QName.createQName(propName);
|
||||
|
||||
// make sure the property is represented correctly
|
||||
Serializable propValue = (Serializable)editedProps.get(propName);
|
||||
|
||||
// check for empty strings when using number types, set to null in this case
|
||||
if (propValue instanceof String)
|
||||
{
|
||||
PropertyDefinition propDef = this.getDictionaryService().getProperty(qname);
|
||||
if (((String)propValue).length() == 0)
|
||||
{
|
||||
if (propDef != null)
|
||||
{
|
||||
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
|
||||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
|
||||
{
|
||||
propValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle locale strings to Locale objects
|
||||
else if (propDef != null && propDef.getDataType().getName().equals(DataTypeDefinition.LOCALE))
|
||||
{
|
||||
propValue = I18NUtil.parseLocale((String)propValue);
|
||||
}
|
||||
}
|
||||
|
||||
repoProps.put(qname, propValue);
|
||||
}
|
||||
|
||||
// send the properties back to the repository
|
||||
this.getNodeService().setProperties(nodeRef, repoProps);
|
||||
|
||||
// we also need to persist any association changes that may have been made
|
||||
|
||||
// add any associations added in the UI
|
||||
Map<String, Map<String, AssociationRef>> addedAssocs = this.editableNode.getAddedAssociations();
|
||||
for (Map<String, AssociationRef> typedAssoc : addedAssocs.values())
|
||||
{
|
||||
for (AssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().createAssociation(assoc.getSourceRef(), assoc.getTargetRef(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// remove any association removed in the UI
|
||||
Map<String, Map<String, AssociationRef>> removedAssocs = this.editableNode.getRemovedAssociations();
|
||||
for (Map<String, AssociationRef> typedAssoc : removedAssocs.values())
|
||||
{
|
||||
for (AssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().removeAssociation(assoc.getSourceRef(), assoc.getTargetRef(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// add any child associations added in the UI
|
||||
Map<String, Map<String, ChildAssociationRef>> addedChildAssocs = this.editableNode.getAddedChildAssociations();
|
||||
for (Map<String, ChildAssociationRef> typedAssoc : addedChildAssocs.values())
|
||||
{
|
||||
for (ChildAssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().addChild(assoc.getParentRef(), assoc.getChildRef(), assoc.getTypeQName(), assoc.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
// remove any child association removed in the UI
|
||||
Map<String, Map<String, ChildAssociationRef>> removedChildAssocs = this.editableNode.getRemovedChildAssociations();
|
||||
for (Map<String, ChildAssociationRef> typedAssoc : removedChildAssocs.values())
|
||||
{
|
||||
for (ChildAssociationRef assoc : typedAssoc.values())
|
||||
{
|
||||
this.getNodeService().removeChild(assoc.getParentRef(), assoc.getChildRef());
|
||||
}
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// reset the document held by the browse bean as it's just been updated
|
||||
this.browseBean.getDocument().reset();
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the error message to display if an error occurs during finish processing
|
||||
*
|
||||
* @param exception The exception
|
||||
* @return The formatted message
|
||||
*/
|
||||
@Override
|
||||
protected String formatErrorMessage(Throwable exception)
|
||||
{
|
||||
if(editableNode != null)
|
||||
{
|
||||
|
||||
// special case for Mimetype - since this is a sub-property of the ContentData object
|
||||
// we must extract it so it can be edited in the client, then we check for it later
|
||||
// and create a new ContentData object to wrap it and it's associated URL
|
||||
ContentData content = (ContentData)this.editableNode.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
this.editableNode.getProperties().put(TEMP_PROP_MIMETYPE, content.getMimetype());
|
||||
this.editableNode.getProperties().put(TEMP_PROP_ENCODING, content.getEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
if (exception instanceof FileExistsException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_EXISTS),
|
||||
((FileExistsException)exception).getName());
|
||||
}
|
||||
else if (exception instanceof InvalidNodeRefException)
|
||||
{
|
||||
return MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF),
|
||||
new Object[] {this.browseBean.getDocument().getId()});
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.formatErrorMessage(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getErrorOutcome(Throwable exception)
|
||||
{
|
||||
if (exception instanceof InvalidNodeRefException)
|
||||
{
|
||||
// this failure means the node no longer exists - we cannot show
|
||||
// the content properties screen again so go back to the main page
|
||||
return "browse";
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.getErrorOutcome(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean getters and setters
|
||||
|
||||
/**
|
||||
* Returns the node being edited
|
||||
*
|
||||
* @return The node being edited
|
||||
*/
|
||||
public Node getEditableNode()
|
||||
{
|
||||
return this.editableNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +1,160 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.actions.handlers.SimpleWorkflowHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
public class EditSimpleWorkflowDialog extends BaseDialogBean
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 7203447561571625990L;
|
||||
|
||||
private static final String MSG_ERROR_UPDATE_SIMPLEWORKFLOW = "error_update_simpleworkflow";
|
||||
|
||||
protected Map<String, Serializable> workflowProperties;
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
saveWorkflow();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Node getNode()
|
||||
{
|
||||
return this.browseBean.getDocument();
|
||||
}
|
||||
|
||||
public Node getDocument()
|
||||
{
|
||||
return this.getNode();
|
||||
}
|
||||
|
||||
public String saveWorkflow()
|
||||
{
|
||||
String outcome = "cancel";
|
||||
|
||||
try
|
||||
{
|
||||
Map<QName, Serializable> updateProps = getNodeService().getProperties(getNode().getNodeRef());
|
||||
|
||||
// update the simple workflow properties
|
||||
|
||||
// set the approve step name
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_STEP, workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME));
|
||||
|
||||
// specify whether the approve step will copy or move the content
|
||||
boolean approveMove = true;
|
||||
String approveAction = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_ACTION);
|
||||
if (approveAction != null && approveAction.equals("copy"))
|
||||
{
|
||||
approveMove = false;
|
||||
}
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_MOVE, Boolean.valueOf(approveMove));
|
||||
|
||||
// create node ref representation of the destination folder
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_FOLDER, workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_FOLDER));
|
||||
|
||||
// determine whether there should be a reject step
|
||||
boolean requireReject = true;
|
||||
String rejectStepPresent = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT);
|
||||
if (rejectStepPresent != null && rejectStepPresent.equals("no"))
|
||||
{
|
||||
requireReject = false;
|
||||
}
|
||||
|
||||
if (requireReject)
|
||||
{
|
||||
// set the reject step name
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_STEP, workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME));
|
||||
|
||||
// specify whether the reject step will copy or move the content
|
||||
boolean rejectMove = true;
|
||||
String rejectAction = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_ACTION);
|
||||
if (rejectAction != null && rejectAction.equals("copy"))
|
||||
{
|
||||
rejectMove = false;
|
||||
}
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_MOVE, Boolean.valueOf(rejectMove));
|
||||
|
||||
// create node ref representation of the destination folder
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_FOLDER, workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_FOLDER));
|
||||
}
|
||||
else
|
||||
{
|
||||
// set all the reject properties to null to signify there should
|
||||
// be no reject step
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_STEP, null);
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_MOVE, null);
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_FOLDER, null);
|
||||
}
|
||||
|
||||
// set the properties on the node
|
||||
getNodeService().setProperties(getNode().getNodeRef(), updateProps);
|
||||
getNode().reset();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_SIMPLEWORKFLOW), e.getMessage()), e);
|
||||
ReportedException.throwIfNecessary(e);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public Map<String, Serializable> getWorkflowProperties()
|
||||
{
|
||||
if (this.workflowProperties == null && getNode().hasAspect(ApplicationModel.ASPECT_SIMPLE_WORKFLOW))
|
||||
{
|
||||
// get the exisiting properties for the node
|
||||
Map<String, Object> props = getNode().getProperties();
|
||||
|
||||
String approveStepName = (String) props.get(ApplicationModel.PROP_APPROVE_STEP.toString());
|
||||
String rejectStepName = (String) props.get(ApplicationModel.PROP_REJECT_STEP.toString());
|
||||
|
||||
Boolean approveMove = (Boolean) props.get(ApplicationModel.PROP_APPROVE_MOVE.toString());
|
||||
Boolean rejectMove = (Boolean) props.get(ApplicationModel.PROP_REJECT_MOVE.toString());
|
||||
|
||||
NodeRef approveFolder = (NodeRef) props.get(ApplicationModel.PROP_APPROVE_FOLDER.toString());
|
||||
NodeRef rejectFolder = (NodeRef) props.get(ApplicationModel.PROP_REJECT_FOLDER.toString());
|
||||
|
||||
// put the workflow properties in a separate map for use by the JSP
|
||||
this.workflowProperties = new HashMap<String, Serializable>(7);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME, approveStepName);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_ACTION, approveMove ? "move" : "copy");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_FOLDER, approveFolder);
|
||||
|
||||
if (rejectStepName == null || rejectMove == null || rejectFolder == null)
|
||||
{
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "no");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "yes");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME, rejectStepName);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_ACTION, rejectMove ? "move" : "copy");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_FOLDER, rejectFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return this.workflowProperties;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.actions.handlers.SimpleWorkflowHandler;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.ReportedException;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
|
||||
public class EditSimpleWorkflowDialog extends BaseDialogBean
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 7203447561571625990L;
|
||||
|
||||
private static final String MSG_ERROR_UPDATE_SIMPLEWORKFLOW = "error_update_simpleworkflow";
|
||||
|
||||
protected Map<String, Serializable> workflowProperties;
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
saveWorkflow();
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Node getNode()
|
||||
{
|
||||
return this.browseBean.getDocument();
|
||||
}
|
||||
|
||||
public Node getDocument()
|
||||
{
|
||||
return this.getNode();
|
||||
}
|
||||
|
||||
public String saveWorkflow()
|
||||
{
|
||||
String outcome = "cancel";
|
||||
|
||||
try
|
||||
{
|
||||
Map<QName, Serializable> updateProps = getNodeService().getProperties(getNode().getNodeRef());
|
||||
|
||||
// update the simple workflow properties
|
||||
|
||||
// set the approve step name
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_STEP, workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME));
|
||||
|
||||
// specify whether the approve step will copy or move the content
|
||||
boolean approveMove = true;
|
||||
String approveAction = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_ACTION);
|
||||
if (approveAction != null && approveAction.equals("copy"))
|
||||
{
|
||||
approveMove = false;
|
||||
}
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_MOVE, Boolean.valueOf(approveMove));
|
||||
|
||||
// create node ref representation of the destination folder
|
||||
updateProps.put(ApplicationModel.PROP_APPROVE_FOLDER, workflowProperties.get(SimpleWorkflowHandler.PROP_APPROVE_FOLDER));
|
||||
|
||||
// determine whether there should be a reject step
|
||||
boolean requireReject = true;
|
||||
String rejectStepPresent = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT);
|
||||
if (rejectStepPresent != null && rejectStepPresent.equals("no"))
|
||||
{
|
||||
requireReject = false;
|
||||
}
|
||||
|
||||
if (requireReject)
|
||||
{
|
||||
// set the reject step name
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_STEP, workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME));
|
||||
|
||||
// specify whether the reject step will copy or move the content
|
||||
boolean rejectMove = true;
|
||||
String rejectAction = (String) workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_ACTION);
|
||||
if (rejectAction != null && rejectAction.equals("copy"))
|
||||
{
|
||||
rejectMove = false;
|
||||
}
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_MOVE, Boolean.valueOf(rejectMove));
|
||||
|
||||
// create node ref representation of the destination folder
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_FOLDER, workflowProperties.get(SimpleWorkflowHandler.PROP_REJECT_FOLDER));
|
||||
}
|
||||
else
|
||||
{
|
||||
// set all the reject properties to null to signify there should
|
||||
// be no reject step
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_STEP, null);
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_MOVE, null);
|
||||
updateProps.put(ApplicationModel.PROP_REJECT_FOLDER, null);
|
||||
}
|
||||
|
||||
// set the properties on the node
|
||||
getNodeService().setProperties(getNode().getNodeRef(), updateProps);
|
||||
getNode().reset();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_SIMPLEWORKFLOW), e.getMessage()), e);
|
||||
ReportedException.throwIfNecessary(e);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
public Map<String, Serializable> getWorkflowProperties()
|
||||
{
|
||||
if (this.workflowProperties == null && getNode().hasAspect(ApplicationModel.ASPECT_SIMPLE_WORKFLOW))
|
||||
{
|
||||
// get the exisiting properties for the node
|
||||
Map<String, Object> props = getNode().getProperties();
|
||||
|
||||
String approveStepName = (String) props.get(ApplicationModel.PROP_APPROVE_STEP.toString());
|
||||
String rejectStepName = (String) props.get(ApplicationModel.PROP_REJECT_STEP.toString());
|
||||
|
||||
Boolean approveMove = (Boolean) props.get(ApplicationModel.PROP_APPROVE_MOVE.toString());
|
||||
Boolean rejectMove = (Boolean) props.get(ApplicationModel.PROP_REJECT_MOVE.toString());
|
||||
|
||||
NodeRef approveFolder = (NodeRef) props.get(ApplicationModel.PROP_APPROVE_FOLDER.toString());
|
||||
NodeRef rejectFolder = (NodeRef) props.get(ApplicationModel.PROP_REJECT_FOLDER.toString());
|
||||
|
||||
// put the workflow properties in a separate map for use by the JSP
|
||||
this.workflowProperties = new HashMap<String, Serializable>(7);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_STEP_NAME, approveStepName);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_ACTION, approveMove ? "move" : "copy");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_APPROVE_FOLDER, approveFolder);
|
||||
|
||||
if (rejectStepName == null || rejectMove == null || rejectFolder == null)
|
||||
{
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "no");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_PRESENT, "yes");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_STEP_NAME, rejectStepName);
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_ACTION, rejectMove ? "move" : "copy");
|
||||
this.workflowProperties.put(SimpleWorkflowHandler.PROP_REJECT_FOLDER, rejectFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return this.workflowProperties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.wizard.BaseInviteUsersWizard;
|
||||
|
||||
/**
|
||||
* Concrete implementation providing the ability to invite users to content.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class InviteContentUsersWizard extends BaseInviteUsersWizard
|
||||
{
|
||||
private static final long serialVersionUID = 9198783146031469545L;
|
||||
|
||||
@Override
|
||||
protected Set<String> getPermissionsForType()
|
||||
{
|
||||
// Let the permission service do the caching to allow for dynamic model updates, etc.
|
||||
return this.permissionService.getSettablePermissions(getNode().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node getNode()
|
||||
{
|
||||
return this.browseBean.getDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEmailTemplateXPath()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "/" +
|
||||
Application.getNotifyEmailTemplatesFolderName(fc) + "//*";
|
||||
return xpath;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.wizard.BaseInviteUsersWizard;
|
||||
|
||||
/**
|
||||
* Concrete implementation providing the ability to invite users to content.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class InviteContentUsersWizard extends BaseInviteUsersWizard
|
||||
{
|
||||
private static final long serialVersionUID = 9198783146031469545L;
|
||||
|
||||
@Override
|
||||
protected Set<String> getPermissionsForType()
|
||||
{
|
||||
// Let the permission service do the caching to allow for dynamic model updates, etc.
|
||||
return this.permissionService.getSettablePermissions(getNode().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node getNode()
|
||||
{
|
||||
return this.browseBean.getDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEmailTemplateXPath()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
String xpath = Application.getRootPath(fc) + "/" +
|
||||
Application.getGlossaryFolderName(fc) + "/" +
|
||||
Application.getEmailTemplatesFolderName(fc) + "/" +
|
||||
Application.getNotifyEmailTemplatesFolderName(fc) + "//*";
|
||||
return xpath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
|
||||
/**
|
||||
* Bean implementation of the "Set Content Properties" dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class SetContentPropertiesDialog extends EditContentPropertiesDialog
|
||||
{
|
||||
private static final long serialVersionUID = -7705362669371767349L;
|
||||
|
||||
@Override
|
||||
protected String getDefaultCancelOutcome()
|
||||
{
|
||||
return super.getDefaultCancelOutcome() +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultFinishOutcome()
|
||||
{
|
||||
return super.getDefaultFinishOutcome() +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"browse";
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.bean.content;
|
||||
|
||||
import org.alfresco.web.app.AlfrescoNavigationHandler;
|
||||
|
||||
/**
|
||||
* Bean implementation of the "Set Content Properties" dialog.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class SetContentPropertiesDialog extends EditContentPropertiesDialog
|
||||
{
|
||||
private static final long serialVersionUID = -7705362669371767349L;
|
||||
|
||||
@Override
|
||||
protected String getDefaultCancelOutcome()
|
||||
{
|
||||
return super.getDefaultCancelOutcome() +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"browse";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultFinishOutcome()
|
||||
{
|
||||
return super.getDefaultFinishOutcome() +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
|
||||
"browse";
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user