Merged V2.2 to HEAD

7495: Various fixes for restriction in WCM File Picker
         Fixed line endings


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8382 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-02-26 14:55:40 +00:00
parent 4780da35d5
commit 225eca438c
4 changed files with 6408 additions and 6335 deletions

View File

@@ -86,25 +86,21 @@
javascript-class-name="alfresco.xforms.FilePicker"> javascript-class-name="alfresco.xforms.FilePicker">
<param name="selectable_types">wcm:avmcontent,wcm:avmfolder</param> <param name="selectable_types">wcm:avmcontent,wcm:avmfolder</param>
<!-- <!--
Uncomment parameter and set to absolute path of AVM folder to Uncomment parameter and set to relative path of AVM folder
restrict file picker to. to restrict file picker to.
<param name="folder_restriction">some-absolute-AVM-folder-path</param>
<param name="folder_restriction">some-relative-folder-path</param>
--> -->
</widget> </widget>
<widget xforms-type="xf:upload" <widget xforms-type="xf:upload"
appearance="search_restricted_file_picker" appearance="search_restricted_file_picker"
javascript-class-name="alfresco.xforms.FilePicker"> javascript-class-name="alfresco.xforms.FilePicker">
<!-- <!--
Uncomment parameter and set to name of a saved Uncomment parameter and set to name of a configured
search. The file picker will be restricted to the results search. The file picker will be restricted to the results
of this saved search of this configured search
<param name="saved_search_name">some-search-name</param>
--> <param name="config_search_name">some-configured-search-name</param>
<!--
Uncomment and set to user or global. If set to user, then named saved search
is retrieved from the current user's saved search folder. If set to global
then named saved search is retrieved from the global saved seaches folder
<param name="saved_search_context">some-search-context</param>
--> -->
</widget> </widget>
<widget xforms-type="xf:upload" <widget xforms-type="xf:upload"

View File

@@ -90,21 +90,17 @@ import org.springframework.util.FileCopyUtils;
/** /**
* Bean for interacting with the file picker widget using ajax requests. * Bean for interacting with the file picker widget using ajax requests.
*/ */
public class FilePickerBean implements Serializable { public class FilePickerBean implements Serializable
{
private static final Log LOGGER = LogFactory.getLog(FilePickerBean.class); private static final Log LOGGER = LogFactory.getLog(FilePickerBean.class);
private static final String SAVED_SEARCH_QUERY_XPATH = "/search/query"; private static final String CONFIGURED_SEARCH_QUERY_XPATH = "/search/query";
private static final String CDATA_START_DELIM = "![CDATA["; private static final String CDATA_START_DELIM = "![CDATA[";
private static final String CDATA_END_DELIM = "]]"; private static final String CDATA_END_DELIM = "]]";
// possible values for the saved_search_context parameter
private static final String SAVED_SEARCHES_CONTEXT_USER = "user";
private static final String SAVED_SEARCHES_CONTEXT_GLOBAL = "global";
// parameter names // parameter names
private static final String PARAM_FOLDER_RESTRICTION = "folderRestriction"; private static final String PARAM_FOLDER_RESTRICTION = "folderRestriction";
private static final String PARAM_SAVED_SEARCH_NAME = "savedSearchName"; private static final String PARAM_CONFIGURED_SEARCH_NAME = "configSearchName";
private static final String PARAM_SAVED_SEARCH_CONTEXT = "savedSearchContext";
private static final String PARAM_SELECTABLE_TYPES = "selectableTypes"; private static final String PARAM_SELECTABLE_TYPES = "selectableTypes";
private static final String PARAM_FILTER_MIME_TYPES = "filterMimetypes"; private static final String PARAM_FILTER_MIME_TYPES = "filterMimetypes";
private static final String PARAM_CURRENT_PATH = "currentPath"; private static final String PARAM_CURRENT_PATH = "currentPath";
@@ -120,20 +116,24 @@ public class FilePickerBean implements Serializable {
transient private DictionaryService dictionaryService; transient private DictionaryService dictionaryService;
transient private ContentService contentService; transient private ContentService contentService;
/** cached reference to the global saved searches folder */ // cached reference to the public saved searches folder
private NodeRef globalSearchesRef = null; private NodeRef publicSearchesRef = null;
/** cached reference to the current users saved searches folder */ // initial current folder - the current folder path which the
private NodeRef userSearchesRef = null; // the file picker opens at when first selected in the form
private String initialCurrentPath = null;
public FilePickerBean() { public FilePickerBean()
{
} }
public void clearUploadedFiles() { public void clearUploadedFiles()
{
this.uploads.clear(); this.uploads.clear();
} }
public NodeRef[] getUploadedFiles() { public NodeRef[] getUploadedFiles()
{
return (NodeRef[]) this.uploads.toArray(new NodeRef[this.uploads.size()]); return (NodeRef[]) this.uploads.toArray(new NodeRef[this.uploads.size()]);
} }
@@ -143,7 +143,8 @@ public class FilePickerBean implements Serializable {
* @param avmBrowseBean * @param avmBrowseBean
* the AVMBrowseBean object to pass into this property * the AVMBrowseBean object to pass into this property
*/ */
public void setAvmBrowseBean(final AVMBrowseBean avmBrowseBean) { public void setAvmBrowseBean(final AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean; this.avmBrowseBean = avmBrowseBean;
} }
@@ -152,7 +153,8 @@ public class FilePickerBean implements Serializable {
* *
* @return avmBrowseBean property value for this bean * @return avmBrowseBean property value for this bean
*/ */
public AVMBrowseBean getAvmBrowseBean() { public AVMBrowseBean getAvmBrowseBean()
{
return this.avmBrowseBean; return this.avmBrowseBean;
} }
@@ -162,7 +164,8 @@ public class FilePickerBean implements Serializable {
* @param avmService * @param avmService
* the avmService object to pass into this property * the avmService object to pass into this property
*/ */
public void setAvmService(final AVMService avmService) { public void setAvmService(final AVMService avmService)
{
this.avmService = avmService; this.avmService = avmService;
} }
@@ -171,8 +174,10 @@ public class FilePickerBean implements Serializable {
* *
* @return avmService property value for this bean * @return avmService property value for this bean
*/ */
public AVMService getAvmService() { public AVMService getAvmService()
if (this.avmService == null) { {
if (this.avmService == null)
{
this.avmService = Repository.getServiceRegistry( this.avmService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getAVMService(); FacesContext.getCurrentInstance()).getAVMService();
} }
@@ -185,7 +190,8 @@ public class FilePickerBean implements Serializable {
* @param nodeService * @param nodeService
* the NodeService object to pass into this property * the NodeService object to pass into this property
*/ */
public void setNodeService(final NodeService nodeService) { public void setNodeService(final NodeService nodeService)
{
this.nodeService = nodeService; this.nodeService = nodeService;
} }
@@ -194,8 +200,10 @@ public class FilePickerBean implements Serializable {
* *
* @return nodeService property value for this bean * @return nodeService property value for this bean
*/ */
public NodeService getNodeService() { public NodeService getNodeService()
if (this.nodeService == null) { {
if (this.nodeService == null)
{
this.nodeService = Repository.getServiceRegistry( this.nodeService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getNodeService(); FacesContext.getCurrentInstance()).getNodeService();
} }
@@ -208,7 +216,8 @@ public class FilePickerBean implements Serializable {
* @param searchService * @param searchService
* the SearchService object to pass into this property * the SearchService object to pass into this property
*/ */
public void setSearchService(final SearchService searchService) { public void setSearchService(final SearchService searchService)
{
this.searchService = searchService; this.searchService = searchService;
} }
@@ -217,8 +226,10 @@ public class FilePickerBean implements Serializable {
* *
* @return searchService property value for this bean * @return searchService property value for this bean
*/ */
public SearchService getSearchService() { public SearchService getSearchService()
if (this.searchService == null) { {
if (this.searchService == null)
{
this.searchService = Repository.getServiceRegistry( this.searchService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getSearchService(); FacesContext.getCurrentInstance()).getSearchService();
} }
@@ -231,7 +242,8 @@ public class FilePickerBean implements Serializable {
* @param dictionaryService * @param dictionaryService
* the DictionaryService object to pass into this property * the DictionaryService object to pass into this property
*/ */
public void setDictionaryService(final DictionaryService dictionaryService) { public void setDictionaryService(final DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
} }
@@ -240,8 +252,10 @@ public class FilePickerBean implements Serializable {
* *
* @return dictionaryService property value for this bean * @return dictionaryService property value for this bean
*/ */
public DictionaryService getDictionaryService() { public DictionaryService getDictionaryService()
if (this.dictionaryService == null) { {
if (this.dictionaryService == null)
{
this.dictionaryService = Repository.getServiceRegistry( this.dictionaryService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getDictionaryService(); FacesContext.getCurrentInstance()).getDictionaryService();
} }
@@ -254,7 +268,8 @@ public class FilePickerBean implements Serializable {
* @param namespaceService * @param namespaceService
* the NamespaceService object to pass into this property * the NamespaceService object to pass into this property
*/ */
public void setNamespaceService(final NamespaceService namespaceService) { public void setNamespaceService(final NamespaceService namespaceService)
{
this.namespaceService = namespaceService; this.namespaceService = namespaceService;
} }
@@ -263,8 +278,10 @@ public class FilePickerBean implements Serializable {
* *
* @return namespaceService property value for this bean * @return namespaceService property value for this bean
*/ */
public NamespaceService getNamespaceService() { public NamespaceService getNamespaceService()
if (this.namespaceService == null) { {
if (this.namespaceService == null)
{
this.namespaceService = Repository.getServiceRegistry( this.namespaceService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getNamespaceService(); FacesContext.getCurrentInstance()).getNamespaceService();
} }
@@ -277,7 +294,8 @@ public class FilePickerBean implements Serializable {
* @param contentService * @param contentService
* the ContentService object to pass into this property * the ContentService object to pass into this property
*/ */
public void setContentService(final ContentService contentService) { public void setContentService(final ContentService contentService)
{
this.contentService = contentService; this.contentService = contentService;
} }
@@ -286,8 +304,10 @@ public class FilePickerBean implements Serializable {
* *
* @return contentService property value for this bean * @return contentService property value for this bean
*/ */
public ContentService getContentService() { public ContentService getContentService()
if (this.contentService == null) { {
if (this.contentService == null)
{
this.contentService = Repository.getServiceRegistry( this.contentService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getContentService(); FacesContext.getCurrentInstance()).getContentService();
} }
@@ -298,63 +318,19 @@ public class FilePickerBean implements Serializable {
* Provides data for a file picker widget. * Provides data for a file picker widget.
*/ */
@InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_XML) @InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_XML)
public void getFilePickerData() throws Exception { public void getFilePickerData() throws Exception
{
final FacesContext facesContext = FacesContext.getCurrentInstance(); final FacesContext facesContext = FacesContext.getCurrentInstance();
final ExternalContext externalContext = facesContext.getExternalContext(); final ExternalContext externalContext = facesContext.getExternalContext();
String currentPath = null; // get configured search name parameter value
String configSearchName = null;
// get 'folderRestriction' parameter value String[] configSearchNameParam = (String[]) externalContext
// - expecting an absolute AVM folder path to be held in this parameter .getRequestParameterValuesMap().get(PARAM_CONFIGURED_SEARCH_NAME);
String folderPathRestriction = null; if ((configSearchNameParam != null)
String[] folderPathRestrictionParam = (String[]) externalContext && (configSearchNameParam.length != 0))
.getRequestParameterValuesMap().get(PARAM_FOLDER_RESTRICTION); {
if ((folderPathRestrictionParam != null) configSearchName = configSearchNameParam[0];
&& (folderPathRestrictionParam.length != 0)) {
folderPathRestriction = folderPathRestrictionParam[0];
}
// if folder restriction path is neither null nor an empty string, then
// assign it to current path
if ((folderPathRestriction != null)
&& (folderPathRestriction.length() > 0)) {
currentPath = folderPathRestriction;
}
// else set current path to current path parameter
else {
String currentPathParam = (String) externalContext
.getRequestParameterMap().get(PARAM_CURRENT_PATH);
// if current path parameter null then set current path to the current
// AVM path
if ((currentPathParam == null)) {
currentPath = this.getCurrentAVMPath();
}
// else set current path to value help in current path
// parameter (converted to absolute AVM path)
else {
final String previewStorePath = AVMUtil
.getCorrespondingPathInPreviewStore(this.getCurrentAVMPath());
currentPath = AVMUtil.buildPath(previewStorePath, currentPathParam,
AVMUtil.PathRelation.WEBAPP_RELATIVE);
}
}
// get savedSearchName parameter value
String savedSearchName = null;
String[] savedSearchNameParam = (String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_SAVED_SEARCH_NAME);
if ((savedSearchNameParam != null) && (savedSearchNameParam.length != 0)) {
savedSearchName = savedSearchNameParam[0];
}
// get savedSearchContext parameter value
String savedSearchContext = null;
String[] savedSearchContextParam = (String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_SAVED_SEARCH_CONTEXT);
if ((savedSearchContextParam != null)
&& (savedSearchContextParam.length != 0)) {
savedSearchContext = savedSearchContextParam[0];
} }
// get selectableTypes parameter value // get selectableTypes parameter value
@@ -367,7 +343,78 @@ public class FilePickerBean implements Serializable {
.getFilterMimetypes((String[]) externalContext .getFilterMimetypes((String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_FILTER_MIME_TYPES)); .getRequestParameterValuesMap().get(PARAM_FILTER_MIME_TYPES));
if (LOGGER.isDebugEnabled()) { // get 'folderRestriction' parameter value
// expecting a relative AVM folder path to be held in this parameter
// (relative to web project webapp root)
String folderPathRestriction = null;
String[] folderPathRestrictionParam = (String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_FOLDER_RESTRICTION);
if ((folderPathRestrictionParam != null)
&& (folderPathRestrictionParam.length != 0))
{
folderPathRestriction = folderPathRestrictionParam[0];
// remove leading '/' or '\' (if present) from path restriction
if ((folderPathRestriction.charAt(0) == '/')
|| (folderPathRestriction.charAt(0) == '\\'))
{
folderPathRestriction = folderPathRestriction.substring(1);
}
}
// ###
// the following section sets file picker current path (the folder that
// file picker
// is opened at when selected/changed in the form)
String currentPath = null;
// get current path request parameter
String currentPathReqParam = (String) externalContext
.getRequestParameterMap().get(PARAM_CURRENT_PATH);
// if current path request parameter null then set current path to the
// current AVM path
if ((currentPathReqParam == null))
{
currentPath = this.getCurrentAVMPath();
}
// else set current path to current path request parameter converted to
// AVM preview
// store path
else
{
final String previewStorePath = AVMUtil
.getCorrespondingPathInPreviewStore(this.getCurrentAVMPath());
currentPath = AVMUtil.buildPath(previewStorePath, currentPathReqParam,
AVMUtil.PathRelation.WEBAPP_RELATIVE);
}
// if initial current path not set then set it to the current path
if (initialCurrentPath == null)
{
initialCurrentPath = currentPath;
// insert '/' at end of initial current path if there isn't one
if (initialCurrentPath.charAt(initialCurrentPath.length() - 1) != '/')
{
initialCurrentPath = initialCurrentPath + "/";
}
}
// if folder path restriction (relative path) is set,
// then calculate the absolute restriction path (in context of file
// picker's
// initial current path - the path at which it was opened the first time)
// and set file picker current path to that
if ((folderPathRestriction != null)
&& (folderPathRestriction.length() != 0))
{
currentPath = initialCurrentPath + folderPathRestriction;
}
if (LOGGER.isDebugEnabled())
{
LOGGER.debug(this + ".getFilePickerData(path = " + currentPath LOGGER.debug(this + ".getFilePickerData(path = " + currentPath
+ ", selectableTypes = [" + ", selectableTypes = ["
+ StringUtils.join(selectableTypes, ",") + StringUtils.join(selectableTypes, ",")
@@ -387,7 +434,11 @@ public class FilePickerBean implements Serializable {
// the file picker data element // the file picker data element
final AVMNodeDescriptor currentNode = this.getAvmService().lookup(-1, final AVMNodeDescriptor currentNode = this.getAvmService().lookup(-1,
currentPath); currentPath);
if (currentNode == null) {
// if the current node is null (path held in current path variable is
// invalid), then add an error attribute to the file picker data
if (currentNode == null)
{
currentPath = AVMUtil.getWebappRelativePath(currentPath); currentPath = AVMUtil.getWebappRelativePath(currentPath);
filePickerDataElement.setAttribute("error", MessageFormat.format( filePickerDataElement.setAttribute("error", MessageFormat.format(
@@ -397,24 +448,48 @@ public class FilePickerBean implements Serializable {
(currentPath.lastIndexOf("/") == 0 ? "/" : currentPath (currentPath.lastIndexOf("/") == 0 ? "/" : currentPath
.substring(0, currentPath.lastIndexOf("/"))))); .substring(0, currentPath.lastIndexOf("/")))));
// TODO (Glen): Ariel's code - What on earth is this doing here? // If folder restriction has been set, since the derived
// It is overriding the value assigned two statements above!!! // current path is invalid just set it to null
if ((folderPathRestriction != null)
&& (folderPathRestriction.length() != 0))
{
currentPath = null;
} else
// otherwise folder restriction has not been set, so it should be safe
// to fall back to setting the current path to the current AVM path
// (as was the behaviour before the folder restriction feature
// was added)
{
currentPath = this.getCurrentAVMPath(); currentPath = this.getCurrentAVMPath();
} }
// if the path points to a file instead of a directory, }
// else current node is not null (path held in current path variable is
// valid)
else
{
// if node for current path points to a file instead of a directory,
// then make sure that the current path points to // then make sure that the current path points to
// just the directory part of the path // just the directory part of the path
else if (!currentNode.isDirectory()) { if (!currentNode.isDirectory())
{
currentPath = AVMNodeConverter.SplitBase(currentPath)[0]; currentPath = AVMNodeConverter.SplitBase(currentPath)[0];
} }
}
// create current-node element representing node for current path // create current-node element representing node for current path
// and append it to the file picker data element // and append it to the file picker data element
org.w3c.dom.Element currentNodeElement = filePickerDataDoc org.w3c.dom.Element currentNodeElement = filePickerDataDoc
.createElement("current-node"); .createElement("current-node");
if (currentPath == null)
{
currentNodeElement.setAttribute("avmPath", "");
currentNodeElement.setAttribute("webappRelativePath", "");
} else
{
currentNodeElement.setAttribute("avmPath", currentPath); currentNodeElement.setAttribute("avmPath", currentPath);
currentNodeElement.setAttribute("webappRelativePath", AVMUtil currentNodeElement.setAttribute("webappRelativePath", AVMUtil
.getWebappRelativePath(currentPath)); .getWebappRelativePath(currentPath));
}
currentNodeElement.setAttribute("type", "directory"); currentNodeElement.setAttribute("type", "directory");
// TODO (Glen): This was in Ariel's code. Is this the correct // TODO (Glen): This was in Ariel's code. Is this the correct
@@ -423,29 +498,32 @@ public class FilePickerBean implements Serializable {
filePickerDataElement.appendChild(currentNodeElement); filePickerDataElement.appendChild(currentNodeElement);
// if saved search name and saved search context parameters supplied (i.e. // if configured search name supplied (i.e. not null),
// not null), // then get configured search node matching given name
// then get saved saved search node matching given name and context // and add the nodes from the search result to the file
if ((savedSearchName != null) && (savedSearchName.length() != 0) // picker data
&& (savedSearchContext != null) if ((configSearchName != null) && (configSearchName.length() != 0))
&& (savedSearchContext.length() != 0)) { {
// get node reference for named saved search in the given saved search // get node reference for named configured search
// context NodeRef configuredSearchNodeRef = getConfiguredSearches(configSearchName);
NodeRef savedSearchNodeRef = getSavedSearches(savedSearchName,
savedSearchContext);
// run search to get content nodes returned in search result // run search to get content nodes returned in search result
List<AVMNodeDescriptor> searchResultNodes = runSavedSearch(savedSearchNodeRef); List<AVMNodeDescriptor> searchResultNodes = runConfiguredSearch(configuredSearchNodeRef);
// add elements for content nodes from search results as child nodes // add elements for content nodes from search results as child nodes
// of the file picker data element. // of the file picker data element.
addAVMNodesToElement(filePickerDataDoc, filePickerDataElement, addAVMNodesToElement(filePickerDataDoc, filePickerDataElement,
searchResultNodes, selectableTypes, facesContext); searchResultNodes, selectableTypes, facesContext);
} else { } else
{
// add elements for child nodes of current path to file picker // add elements for child nodes of current path to file picker
// data element // data element if current path is not null
addPathChildNodesToElement(filePickerDataDoc, filePickerDataElement, if (currentPath != null)
currentPath, selectableTypes, filterMimetypes, facesContext); {
addPathChildNodesToElement(filePickerDataDoc,
filePickerDataElement, currentPath, selectableTypes,
filterMimetypes, facesContext);
}
} }
final ResponseWriter out = facesContext.getResponseWriter(); final ResponseWriter out = facesContext.getResponseWriter();
@@ -453,7 +531,8 @@ public class FilePickerBean implements Serializable {
} }
@InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_HTML) @InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_HTML)
public void uploadFile() throws Exception { public void uploadFile() throws Exception
{
LOGGER.debug(this + ".uploadFile()"); LOGGER.debug(this + ".uploadFile()");
final FacesContext facesContext = FacesContext.getCurrentInstance(); final FacesContext facesContext = FacesContext.getCurrentInstance();
final ExternalContext externalContext = facesContext.getExternalContext(); final ExternalContext externalContext = facesContext.getExternalContext();
@@ -470,45 +549,57 @@ public class FilePickerBean implements Serializable {
String filename = null; String filename = null;
String returnPage = null; String returnPage = null;
InputStream fileInputStream = null; InputStream fileInputStream = null;
for (FileItem item : fileItems) { for (FileItem item : fileItems)
if (LOGGER.isDebugEnabled()) { {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("item = " + item); LOGGER.debug("item = " + item);
} }
if (item.isFormField() && item.getFieldName().equals("upload-id")) { if (item.isFormField() && item.getFieldName().equals("upload-id"))
{
uploadId = item.getString(); uploadId = item.getString();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug("uploadId is " + uploadId); LOGGER.debug("uploadId is " + uploadId);
} }
} }
if (item.isFormField() && item.getFieldName().equals("return-page")) { if (item.isFormField() && item.getFieldName().equals("return-page"))
{
returnPage = item.getString(); returnPage = item.getString();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug("returnPage is " + returnPage); LOGGER.debug("returnPage is " + returnPage);
} }
} else if (item.isFormField() } else if (item.isFormField()
&& item.getFieldName().equals("currentPath")) { && item.getFieldName().equals("currentPath"))
{
final String previewStorePath = AVMUtil final String previewStorePath = AVMUtil
.getCorrespondingPathInPreviewStore(this.getCurrentAVMPath()); .getCorrespondingPathInPreviewStore(this.getCurrentAVMPath());
currentPath = AVMUtil.buildPath(previewStorePath, item.getString(), currentPath = AVMUtil.buildPath(previewStorePath, item.getString(),
AVMUtil.PathRelation.WEBAPP_RELATIVE); AVMUtil.PathRelation.WEBAPP_RELATIVE);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug("currentPath is " + currentPath); LOGGER.debug("currentPath is " + currentPath);
} }
} else { } else
{
filename = FilenameUtils.getName(item.getName()); filename = FilenameUtils.getName(item.getName());
fileInputStream = item.getInputStream(); fileInputStream = item.getInputStream();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug("uploading file " + filename); LOGGER.debug("uploading file " + filename);
} }
} }
} }
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug("saving file " + filename + " to " + currentPath); LOGGER.debug("saving file " + filename + " to " + currentPath);
} }
try { try
{
FileCopyUtils.copy(fileInputStream, this.getAvmService().createFile( FileCopyUtils.copy(fileInputStream, this.getAvmService().createFile(
currentPath, filename)); currentPath, filename));
final Map<QName, PropertyValue> props = new HashMap<QName, PropertyValue>( final Map<QName, PropertyValue> props = new HashMap<QName, PropertyValue>(
@@ -527,7 +618,8 @@ public class FilePickerBean implements Serializable {
+ filename)); + filename));
returnPage = returnPage.replace("${_FILE_TYPE_IMAGE}", Utils returnPage = returnPage.replace("${_FILE_TYPE_IMAGE}", Utils
.getFileTypeImage(facesContext, filename, true)); .getFileTypeImage(facesContext, filename, true));
} catch (Exception e) { } catch (Exception e)
{
LOGGER.debug(e.getMessage(), e); LOGGER.debug(e.getMessage(), e);
returnPage = returnPage.replace("${_UPLOAD_ERROR}", e.getMessage()); returnPage = returnPage.replace("${_UPLOAD_ERROR}", e.getMessage());
} }
@@ -549,9 +641,11 @@ public class FilePickerBean implements Serializable {
XMLUtil.print(result, out); XMLUtil.print(result, out);
} }
private String getCurrentAVMPath() { private String getCurrentAVMPath()
{
final AVMNode node = this.getAvmBrowseBean().getAvmActionNode(); final AVMNode node = this.getAvmBrowseBean().getAvmActionNode();
if (node == null) { if (node == null)
{
return this.getAvmBrowseBean().getCurrentPath(); return this.getAvmBrowseBean().getCurrentPath();
} }
@@ -560,13 +654,16 @@ public class FilePickerBean implements Serializable {
: AVMNodeConverter.SplitBase(result)[0]; : AVMNodeConverter.SplitBase(result)[0];
} }
private QName[] getSelectableTypes(final String[] selectableTypes) { private QName[] getSelectableTypes(final String[] selectableTypes)
final QName[] result = (selectableTypes == null ? new QName[] { {
WCMModel.TYPE_AVM_CONTENT, WCMModel.TYPE_AVM_FOLDER } final QName[] result = (selectableTypes == null ? new QName[]
{ WCMModel.TYPE_AVM_CONTENT, WCMModel.TYPE_AVM_FOLDER }
: new QName[selectableTypes.length]); : new QName[selectableTypes.length]);
if (selectableTypes != null) { if (selectableTypes != null)
for (int i = 0; i < selectableTypes.length; i++) { {
for (int i = 0; i < selectableTypes.length; i++)
{
result[i] = QName.resolveToQName(this.getNamespaceService(), result[i] = QName.resolveToQName(this.getNamespaceService(),
selectableTypes[i]); selectableTypes[i]);
} }
@@ -574,11 +671,14 @@ public class FilePickerBean implements Serializable {
return result; return result;
} }
private Pattern[] getFilterMimetypes(final String[] filterMimetypes) { private Pattern[] getFilterMimetypes(final String[] filterMimetypes)
{
final Pattern[] result = filterMimetypes == null ? new Pattern[0] final Pattern[] result = filterMimetypes == null ? new Pattern[0]
: new Pattern[filterMimetypes.length]; : new Pattern[filterMimetypes.length];
if (filterMimetypes != null) { if (filterMimetypes != null)
for (int i = 0; i < filterMimetypes.length; i++) { {
for (int i = 0; i < filterMimetypes.length; i++)
{
result[i] = Pattern.compile(filterMimetypes[i].replaceAll("\\*", result[i] = Pattern.compile(filterMimetypes[i].replaceAll("\\*",
"\\.*").replaceAll("\\/", "\\\\/")); "\\.*").replaceAll("\\/", "\\\\/"));
} }
@@ -610,26 +710,32 @@ public class FilePickerBean implements Serializable {
*/ */
private void addPathChildNodesToElement(org.w3c.dom.Document doc, private void addPathChildNodesToElement(org.w3c.dom.Document doc,
org.w3c.dom.Element parent, String path, QName[] selectableTypes, org.w3c.dom.Element parent, String path, QName[] selectableTypes,
Pattern[] filterMimetypes, FacesContext facesContext) { Pattern[] filterMimetypes, FacesContext facesContext)
{
// append elements for the child AVM nodes of the current path // append elements for the child AVM nodes of the current path
// to parent element // to parent element
for (final Map.Entry<String, AVMNodeDescriptor> entry : this for (final Map.Entry<String, AVMNodeDescriptor> entry : this
.getAvmService().getDirectoryListing(-1, path).entrySet()) { .getAvmService().getDirectoryListing(-1, path).entrySet())
{
// if AVM node is a content node and the filter MIME types parameter // if AVM node is a content node and the filter MIME types parameter
// has been set, then only add child element for AVM node if it matches // has been set, then only add child element for AVM node if it matches
// one of the specified MIME types in the parameter // one of the specified MIME types in the parameter
if (!entry.getValue().isDirectory() && filterMimetypes.length != 0) { if (!entry.getValue().isDirectory() && filterMimetypes.length != 0)
{
final String contentMimetype = this.getAvmService() final String contentMimetype = this.getAvmService()
.getContentDataForRead(entry.getValue()).getMimetype(); .getContentDataForRead(entry.getValue()).getMimetype();
boolean matched = false; boolean matched = false;
for (final Pattern p : filterMimetypes) { for (final Pattern p : filterMimetypes)
{
matched = p.matcher(contentMimetype).matches(); matched = p.matcher(contentMimetype).matches();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled())
{
LOGGER.debug(p + ".matches(" + contentMimetype + ") = " LOGGER.debug(p + ".matches(" + contentMimetype + ") = "
+ matched); + matched);
} }
if (matched) { if (matched)
{
break; break;
} }
} }
@@ -637,7 +743,8 @@ public class FilePickerBean implements Serializable {
// if AVM node MIME type doesn't match any of the types in the // if AVM node MIME type doesn't match any of the types in the
// filter MIME types parameter, then don't do any further processing // filter MIME types parameter, then don't do any further processing
// on it and jump back to the start of the AVM node traversal loop // on it and jump back to the start of the AVM node traversal loop
if (!matched) { if (!matched)
{
continue; continue;
} }
} }
@@ -666,8 +773,10 @@ public class FilePickerBean implements Serializable {
*/ */
private void addAVMNodesToElement(org.w3c.dom.Document doc, private void addAVMNodesToElement(org.w3c.dom.Document doc,
org.w3c.dom.Element parent, List<AVMNodeDescriptor> nodes, org.w3c.dom.Element parent, List<AVMNodeDescriptor> nodes,
QName[] selectableTypes, FacesContext facesContext) { QName[] selectableTypes, FacesContext facesContext)
for (AVMNodeDescriptor node : nodes) { {
for (AVMNodeDescriptor node : nodes)
{
// create child element representing AVM node and add to file picker // create child element representing AVM node and add to file picker
// data element // data element
addAVMChildNodeToParentElement(doc, parent, node, selectableTypes, addAVMChildNodeToParentElement(doc, parent, node, selectableTypes,
@@ -676,37 +785,43 @@ public class FilePickerBean implements Serializable {
} }
/** /**
* Run a saved search represented by the given node reference, against the * Run a configured search represented by the given node reference, against
* web project the XForm is currently within * the web project the XForm is currently within
* *
* @param savedQueryNodRef * @param configuredQueryNodRef
* NodeRef of the saved query with which to run the search * NodeRef of the configured query with which to run the search
* *
* @return content nodes returned by the search * @return content nodes returned by the search
*/ */
private List<AVMNodeDescriptor> runSavedSearch(NodeRef savedSearchNodeRef) { private List<AVMNodeDescriptor> runConfiguredSearch(
// get the store id used to run the saved search query NodeRef configSearchNodeRef)
{
// get the store id used to run the configured search query
WebProject webProject = this.getAvmBrowseBean().getWebProject(); WebProject webProject = this.getAvmBrowseBean().getWebProject();
String storeID = webProject.getStoreId(); String storeID = webProject.getStoreId();
// extract the content of saved search node to XML document // extract the content of configured search node to XML document
ContentReader contentReader = getContentService().getReader( ContentReader contentReader = getContentService().getReader(
savedSearchNodeRef, ContentModel.PROP_CONTENT); configSearchNodeRef, ContentModel.PROP_CONTENT);
InputStream queryInpStream = contentReader.getContentInputStream(); InputStream queryInpStream = contentReader.getContentInputStream();
SAXReader reader = new SAXReader(); SAXReader reader = new SAXReader();
Document savedQueryDoc = null; Document queryDoc = null;
try { try
savedQueryDoc = reader.read(queryInpStream); {
} catch (DocumentException de) { queryDoc = reader.read(queryInpStream);
} catch (DocumentException de)
{
// ignore exception and return null // ignore exception and return null
return null; return null;
} }
// extract search query from saved search XML document // extract search query from configured search XML document
String query = null; String query = null;
XPath queryXPath = DocumentHelper.createXPath(SAVED_SEARCH_QUERY_XPATH); XPath queryXPath = DocumentHelper
List xpathResult = queryXPath.selectNodes(savedQueryDoc); .createXPath(CONFIGURED_SEARCH_QUERY_XPATH);
if ((xpathResult != null) && (xpathResult.size() != 0)) { List xpathResult = queryXPath.selectNodes(queryDoc);
if ((xpathResult != null) && (xpathResult.size() != 0))
{
// get the text from the query element // get the text from the query element
Element queryElement = (Element) xpathResult.get(0); Element queryElement = (Element) xpathResult.get(0);
String queryElemText = queryElement.getText(); String queryElemText = queryElement.getText();
@@ -722,26 +837,31 @@ public class FilePickerBean implements Serializable {
// extract // extract
// the query string from the CDATA section // the query string from the CDATA section
if ((cdataStartDelimIndex > -1) if ((cdataStartDelimIndex > -1)
&& ((cdataStartDelimIndex + CDATA_START_DELIM.length()) < cdataEndDelimIndex)) { && ((cdataStartDelimIndex + CDATA_START_DELIM.length()) < cdataEndDelimIndex))
{
query = queryElemText.substring(cdataStartDelimIndex query = queryElemText.substring(cdataStartDelimIndex
+ CDATA_START_DELIM.length(), cdataEndDelimIndex); + CDATA_START_DELIM.length(), cdataEndDelimIndex);
} }
} }
// perform the search against the repository // perform the search against the repository
// if query was extracted from the saved search successfully // if query was extracted from the configured search successfully
// (extracted query non-null) // (extracted query non-null)
List<AVMNodeDescriptor> resultNodeDescriptors = null; List<AVMNodeDescriptor> resultNodeDescriptors = null;
if ((query != null) && (query.length() != 0)) { if ((query != null) && (query.length() != 0))
{
ResultSet results = null; ResultSet results = null;
try { try
{
results = this.getSearchService().query( results = this.getSearchService().query(
new StoreRef(StoreRef.PROTOCOL_AVM, storeID), new StoreRef(StoreRef.PROTOCOL_AVM, storeID),
SearchService.LANGUAGE_LUCENE, query); SearchService.LANGUAGE_LUCENE, query);
if (results.length() != 0) { if (results.length() != 0)
{
resultNodeDescriptors = new ArrayList<AVMNodeDescriptor>(); resultNodeDescriptors = new ArrayList<AVMNodeDescriptor>();
for (int i = 0; i < results.length(); i++) { for (int i = 0; i < results.length(); i++)
{
ResultSetRow row = results.getRow(i); ResultSetRow row = results.getRow(i);
NodeRef resultNodeRef = row.getNodeRef(); NodeRef resultNodeRef = row.getNodeRef();
Node resultNode = new Node(resultNodeRef); Node resultNode = new Node(resultNodeRef);
@@ -750,7 +870,8 @@ public class FilePickerBean implements Serializable {
// as we don't want the user to navigate down into folders // as we don't want the user to navigate down into folders
// in the search results // in the search results
if (getDictionaryService().isSubClass(resultNode.getType(), if (getDictionaryService().isSubClass(resultNode.getType(),
ContentModel.TYPE_CONTENT)) { ContentModel.TYPE_CONTENT))
{
Pair<Integer, String> pair = AVMNodeConverter Pair<Integer, String> pair = AVMNodeConverter
.ToAVMVersionPath(resultNodeRef); .ToAVMVersionPath(resultNodeRef);
Integer version = pair.getFirst(); Integer version = pair.getFirst();
@@ -760,11 +881,14 @@ public class FilePickerBean implements Serializable {
} }
} }
} }
} catch (Throwable err) { } catch (Throwable err)
{
throw new AlfrescoRuntimeException("Failed to execute search: " throw new AlfrescoRuntimeException("Failed to execute search: "
+ query, err); + query, err);
} finally { } finally
if (results != null) { {
if (results != null)
{
results.close(); results.close();
} }
} }
@@ -774,126 +898,86 @@ public class FilePickerBean implements Serializable {
} }
/** /**
* Get the cached reference to the current user's saved searches folder. This * Get the cached reference to the public saved searches folder. This method
* method will first get a reference to the current user's saved searches * will first get a reference to the public saved searches folder and assign
* folder and assign it to the cached reference if is it is null.
*
* @return the cached reference to the current user's Saved Searches folder
*/
private NodeRef getUserSearchesRef() {
// if the cached reference is null, then get a reference to the
// user's saved searches folder to assign to it
if (userSearchesRef == null) {
NodeRef globalRef = getGlobalSearchesRef();
if (globalRef != null) {
// Use the search service get a reference to the
// current user's saved searches folder.
// Search within the context of the global saved searches
// folder
FacesContext fc = FacesContext.getCurrentInstance();
User user = Application.getCurrentUser(fc);
String userName = ISO9075.encode(user.getUserName());
String xpath = NamespaceService.APP_MODEL_PREFIX + ":"
+ QName.createValidLocalName(userName);
List<NodeRef> results = null;
try {
results = getSearchService().selectNodes(globalRef, xpath, null,
getNamespaceService(), false);
} catch (AccessDeniedException err) {
// ignore and return null
}
if ((results != null) && (results.size() != 0)) {
userSearchesRef = results.get(0);
}
}
}
return userSearchesRef;
}
/**
* Get the cached reference to the global saved searches folder. This method
* will first get a reference to the global saved searches folder and assign
* it to the cached reference if is it is null. * it to the cached reference if is it is null.
* *
* @return the cached reference to the global Saved Searches folder * @return the cached reference to the public Saved Searches folder
*/ */
private NodeRef getGlobalSearchesRef() { private NodeRef getPublicSearchesRef()
{
// if the cached reference is null, then get a reference to the // if the cached reference is null, then get a reference to the
// global saved searches folder to assign to it // public saved searches folder to assign to it
if (globalSearchesRef == null) { if (publicSearchesRef == null)
{
// Use the search service get a reference to the // Use the search service get a reference to the
// global saved searches folder. // public saved searches folder.
FacesContext fc = FacesContext.getCurrentInstance(); FacesContext fc = FacesContext.getCurrentInstance();
String xpath = Application.getRootPath(fc) + "/" String xpath = Application.getRootPath(fc) + "/"
+ Application.getGlossaryFolderName(fc) + "/" + Application.getGlossaryFolderName(fc) + "/"
+ Application.getSavedSearchesFolderName(fc); + Application.getSavedSearchesFolderName(fc);
List<NodeRef> results = null; List<NodeRef> results = null;
try { try
{
results = getSearchService().selectNodes( results = getSearchService().selectNodes(
getNodeService().getRootNode(Repository.getStoreRef()), getNodeService().getRootNode(Repository.getStoreRef()),
xpath, null, getNamespaceService(), false); xpath, null, getNamespaceService(), false);
} catch (AccessDeniedException err) { } catch (AccessDeniedException err)
{
// ignore and return null // ignore and return null
} }
if (results != null && results.size() != 0) { if (results != null && results.size() != 0)
globalSearchesRef = results.get(0); {
publicSearchesRef = results.get(0);
} }
} }
return globalSearchesRef; return publicSearchesRef;
} }
/** /**
* Get node for saved search by name. * Get node for configured search by name.
* *
* @param savedSearchName * @param configSearchName
* name of saved search for which to get node * name of configured search for which to get node
* @param savedSearchContext * @return node reference for configured search
* either "user" or "global", which says whether to get saved
* search out of current user's saved searches folder or global
* saved searches folder respectively
* @return node reference for saved search
*/ */
public NodeRef getSavedSearches(String savedSearchName, public NodeRef getConfiguredSearches(String configSearchName)
String savedSearchContext) { {
NodeRef savedSearchNodeRef = null; NodeRef configSearchNodeRef = null;
// get the saved searches folder reference from the // get the folder reference from the
// current user or global searches location // public searches location
NodeRef savedSearchesFolderRef = null; NodeRef publicSearchesFolderRef = getPublicSearchesRef();
if (SAVED_SEARCHES_CONTEXT_USER.equals(savedSearchContext)) {
savedSearchesFolderRef = getUserSearchesRef();
} else if (SAVED_SEARCHES_CONTEXT_GLOBAL.equals(savedSearchContext)) {
savedSearchesFolderRef = getGlobalSearchesRef();
}
// read the content nodes under the folder // read the content nodes under the folder
List<ChildAssociationRef> childRefs = getNodeService().getChildAssocs( List<ChildAssociationRef> childRefs = getNodeService().getChildAssocs(
savedSearchesFolderRef, ContentModel.ASSOC_CONTAINS, publicSearchesFolderRef, ContentModel.ASSOC_CONTAINS,
RegexQNamePattern.MATCH_ALL); RegexQNamePattern.MATCH_ALL);
// return content node with name matching given saved search name // return content node with name matching given configured search name
if (childRefs.size() != 0) { if (childRefs.size() != 0)
for (ChildAssociationRef ref : childRefs) { {
for (ChildAssociationRef ref : childRefs)
{
NodeRef childNodeRef = ref.getChildRef(); NodeRef childNodeRef = ref.getChildRef();
Node childNode = new Node(childNodeRef); Node childNode = new Node(childNodeRef);
if (getDictionaryService().isSubClass(childNode.getType(), if (getDictionaryService().isSubClass(childNode.getType(),
ContentModel.TYPE_CONTENT)) { ContentModel.TYPE_CONTENT))
{
String childNodeName = childNode.getName(); String childNodeName = childNode.getName();
if (childNodeName.equals(savedSearchName)) { if (childNodeName.equals(configSearchName))
savedSearchNodeRef = childNodeRef; {
configSearchNodeRef = childNodeRef;
break; break;
} }
} }
} }
} }
return savedSearchNodeRef; return configSearchNodeRef;
} }
/** /**
@@ -913,7 +997,8 @@ public class FilePickerBean implements Serializable {
*/ */
private void addAVMChildNodeToParentElement(org.w3c.dom.Document doc, private void addAVMChildNodeToParentElement(org.w3c.dom.Document doc,
org.w3c.dom.Element parent, AVMNodeDescriptor node, org.w3c.dom.Element parent, AVMNodeDescriptor node,
QName[] selectableTypes, FacesContext facesContext) { QName[] selectableTypes, FacesContext facesContext)
{
// create child node element to add to file picker data // create child node element to add to file picker data
org.w3c.dom.Element childNodeElement = doc.createElement("child-node"); org.w3c.dom.Element childNodeElement = doc.createElement("child-node");
childNodeElement.setAttribute("avmPath", node.getPath()); childNodeElement.setAttribute("avmPath", node.getPath());
@@ -937,7 +1022,8 @@ public class FilePickerBean implements Serializable {
// TODO Ariel: faking this for now since i can't figure out how to // TODO Ariel: faking this for now since i can't figure out how to
// efficiently get the type // efficiently get the type
// qname from the avmservice // qname from the avmservice
for (final QName typeQName : selectableTypes) { for (final QName typeQName : selectableTypes)
{
selectable = selectable selectable = selectable
|| (WCMModel.TYPE_AVM_FOLDER.equals(typeQName) && node || (WCMModel.TYPE_AVM_FOLDER.equals(typeQName) && node
.isDirectory()); .isDirectory());

View File

@@ -52,8 +52,7 @@ alfresco.FilePickerWidget = function(uploadId,
selectableTypes, selectableTypes,
filterMimetypes, filterMimetypes,
folderRestriction, folderRestriction,
savedSearchName, configSearchName)
savedSearchContext)
{ {
this.uploadId = uploadId; this.uploadId = uploadId;
this.node = node; this.node = node;
@@ -65,8 +64,7 @@ alfresco.FilePickerWidget = function(uploadId,
this.selectableTypes = selectableTypes; this.selectableTypes = selectableTypes;
this.filterMimetypes = filterMimetypes; this.filterMimetypes = filterMimetypes;
this.folderRestriction = folderRestriction; this.folderRestriction = folderRestriction;
this.savedSearchName = savedSearchName; this.configSearchName = configSearchName;
this.savedSearchContext = savedSearchContext;
} }
// static methods and properties // static methods and properties
@@ -266,13 +264,9 @@ _navigateToNode: function(path)
{ {
req.content.folderRestriction = this.folderRestriction; req.content.folderRestriction = this.folderRestriction;
} }
if (this.savedSearchName) if (this.configSearchName)
{ {
req.content.savedSearchName = this.savedSearchName; req.content.configSearchName = this.configSearchName;
}
if (this.savedSearchContext)
{
req.content.savedSearchContext = this.savedSearchContext;
} }
alfresco.AjaxHelper.sendRequest("FilePickerBean.getFilePickerData", alfresco.AjaxHelper.sendRequest("FilePickerBean.getFilePickerData",

View File

@@ -509,9 +509,7 @@ alfresco.xforms.FilePicker = alfresco.xforms.Widget.extend({
this._selectableTypes = "selectable_types" in params ? params["selectable_types"].split(",") : null; this._selectableTypes = "selectable_types" in params ? params["selectable_types"].split(",") : null;
this._filterMimetypes = "filter_mimetypes" in params ? params["filter_mimetypes"].split(",") : []; this._filterMimetypes = "filter_mimetypes" in params ? params["filter_mimetypes"].split(",") : [];
this._folderRestriction = "folder_restriction" in params ? params["folder_restriction"] : null; this._folderRestriction = "folder_restriction" in params ? params["folder_restriction"] : null;
this._savedSearchName = "saved_search_name" in params ? params["saved_search_name"] : null; this._configSearchName = "config_search_name" in params ? params["config_search_name"] : null; },
this._savedSearchContext = "saved_search_context" in params ? params["saved_search_context"] : null;
},
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// overridden methods // overridden methods
@@ -532,8 +530,7 @@ alfresco.xforms.FilePicker = alfresco.xforms.Widget.extend({
this._selectableTypes, this._selectableTypes,
this._filterMimetypes, this._filterMimetypes,
this._folderRestriction, this._folderRestriction,
this._savedSearchName, this._configSearchName);
this._savedSearchContext);
this.widget.render(); this.widget.render();
}, },