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">
<param name="selectable_types">wcm:avmcontent,wcm:avmfolder</param>
<!--
Uncomment parameter and set to absolute path of AVM folder to
restrict file picker to.
<param name="folder_restriction">some-absolute-AVM-folder-path</param>
Uncomment parameter and set to relative path of AVM folder
to restrict file picker to.
<param name="folder_restriction">some-relative-folder-path</param>
-->
</widget>
<widget xforms-type="xf:upload"
appearance="search_restricted_file_picker"
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
of this saved search
<param name="saved_search_name">some-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>
of this configured search
<param name="config_search_name">some-configured-search-name</param>
-->
</widget>
<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.
*/
public class FilePickerBean implements Serializable {
public class FilePickerBean implements Serializable
{
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_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
private static final String PARAM_FOLDER_RESTRICTION = "folderRestriction";
private static final String PARAM_SAVED_SEARCH_NAME = "savedSearchName";
private static final String PARAM_SAVED_SEARCH_CONTEXT = "savedSearchContext";
private static final String PARAM_CONFIGURED_SEARCH_NAME = "configSearchName";
private static final String PARAM_SELECTABLE_TYPES = "selectableTypes";
private static final String PARAM_FILTER_MIME_TYPES = "filterMimetypes";
private static final String PARAM_CURRENT_PATH = "currentPath";
@@ -120,20 +116,24 @@ public class FilePickerBean implements Serializable {
transient private DictionaryService dictionaryService;
transient private ContentService contentService;
/** cached reference to the global saved searches folder */
private NodeRef globalSearchesRef = null;
// cached reference to the public saved searches folder
private NodeRef publicSearchesRef = null;
/** cached reference to the current users saved searches folder */
private NodeRef userSearchesRef = null;
// initial current folder - the current folder path which the
// 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();
}
public NodeRef[] getUploadedFiles() {
public NodeRef[] getUploadedFiles()
{
return (NodeRef[]) this.uploads.toArray(new NodeRef[this.uploads.size()]);
}
@@ -143,7 +143,8 @@ public class FilePickerBean implements Serializable {
* @param avmBrowseBean
* the AVMBrowseBean object to pass into this property
*/
public void setAvmBrowseBean(final AVMBrowseBean avmBrowseBean) {
public void setAvmBrowseBean(final AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean;
}
@@ -152,7 +153,8 @@ public class FilePickerBean implements Serializable {
*
* @return avmBrowseBean property value for this bean
*/
public AVMBrowseBean getAvmBrowseBean() {
public AVMBrowseBean getAvmBrowseBean()
{
return this.avmBrowseBean;
}
@@ -162,7 +164,8 @@ public class FilePickerBean implements Serializable {
* @param avmService
* the avmService object to pass into this property
*/
public void setAvmService(final AVMService avmService) {
public void setAvmService(final AVMService avmService)
{
this.avmService = avmService;
}
@@ -171,8 +174,10 @@ public class FilePickerBean implements Serializable {
*
* @return avmService property value for this bean
*/
public AVMService getAvmService() {
if (this.avmService == null) {
public AVMService getAvmService()
{
if (this.avmService == null)
{
this.avmService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getAVMService();
}
@@ -185,7 +190,8 @@ public class FilePickerBean implements Serializable {
* @param nodeService
* the NodeService object to pass into this property
*/
public void setNodeService(final NodeService nodeService) {
public void setNodeService(final NodeService nodeService)
{
this.nodeService = nodeService;
}
@@ -194,8 +200,10 @@ public class FilePickerBean implements Serializable {
*
* @return nodeService property value for this bean
*/
public NodeService getNodeService() {
if (this.nodeService == null) {
public NodeService getNodeService()
{
if (this.nodeService == null)
{
this.nodeService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getNodeService();
}
@@ -208,7 +216,8 @@ public class FilePickerBean implements Serializable {
* @param searchService
* the SearchService object to pass into this property
*/
public void setSearchService(final SearchService searchService) {
public void setSearchService(final SearchService searchService)
{
this.searchService = searchService;
}
@@ -217,8 +226,10 @@ public class FilePickerBean implements Serializable {
*
* @return searchService property value for this bean
*/
public SearchService getSearchService() {
if (this.searchService == null) {
public SearchService getSearchService()
{
if (this.searchService == null)
{
this.searchService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getSearchService();
}
@@ -231,7 +242,8 @@ public class FilePickerBean implements Serializable {
* @param dictionaryService
* the DictionaryService object to pass into this property
*/
public void setDictionaryService(final DictionaryService dictionaryService) {
public void setDictionaryService(final DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
@@ -240,8 +252,10 @@ public class FilePickerBean implements Serializable {
*
* @return dictionaryService property value for this bean
*/
public DictionaryService getDictionaryService() {
if (this.dictionaryService == null) {
public DictionaryService getDictionaryService()
{
if (this.dictionaryService == null)
{
this.dictionaryService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getDictionaryService();
}
@@ -254,7 +268,8 @@ public class FilePickerBean implements Serializable {
* @param namespaceService
* the NamespaceService object to pass into this property
*/
public void setNamespaceService(final NamespaceService namespaceService) {
public void setNamespaceService(final NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
@@ -263,8 +278,10 @@ public class FilePickerBean implements Serializable {
*
* @return namespaceService property value for this bean
*/
public NamespaceService getNamespaceService() {
if (this.namespaceService == null) {
public NamespaceService getNamespaceService()
{
if (this.namespaceService == null)
{
this.namespaceService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getNamespaceService();
}
@@ -277,7 +294,8 @@ public class FilePickerBean implements Serializable {
* @param contentService
* the ContentService object to pass into this property
*/
public void setContentService(final ContentService contentService) {
public void setContentService(final ContentService contentService)
{
this.contentService = contentService;
}
@@ -286,8 +304,10 @@ public class FilePickerBean implements Serializable {
*
* @return contentService property value for this bean
*/
public ContentService getContentService() {
if (this.contentService == null) {
public ContentService getContentService()
{
if (this.contentService == null)
{
this.contentService = Repository.getServiceRegistry(
FacesContext.getCurrentInstance()).getContentService();
}
@@ -298,63 +318,19 @@ public class FilePickerBean implements Serializable {
* Provides data for a file picker widget.
*/
@InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_XML)
public void getFilePickerData() throws Exception {
public void getFilePickerData() throws Exception
{
final FacesContext facesContext = FacesContext.getCurrentInstance();
final ExternalContext externalContext = facesContext.getExternalContext();
String currentPath = null;
// get 'folderRestriction' parameter value
// - expecting an absolute AVM folder path to be held in this parameter
String folderPathRestriction = null;
String[] folderPathRestrictionParam = (String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_FOLDER_RESTRICTION);
if ((folderPathRestrictionParam != null)
&& (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 configured search name parameter value
String configSearchName = null;
String[] configSearchNameParam = (String[]) externalContext
.getRequestParameterValuesMap().get(PARAM_CONFIGURED_SEARCH_NAME);
if ((configSearchNameParam != null)
&& (configSearchNameParam.length != 0))
{
configSearchName = configSearchNameParam[0];
}
// get selectableTypes parameter value
@@ -367,7 +343,78 @@ public class FilePickerBean implements Serializable {
.getFilterMimetypes((String[]) externalContext
.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
+ ", selectableTypes = ["
+ StringUtils.join(selectableTypes, ",")
@@ -387,7 +434,11 @@ public class FilePickerBean implements Serializable {
// the file picker data element
final AVMNodeDescriptor currentNode = this.getAvmService().lookup(-1,
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);
filePickerDataElement.setAttribute("error", MessageFormat.format(
@@ -397,24 +448,48 @@ public class FilePickerBean implements Serializable {
(currentPath.lastIndexOf("/") == 0 ? "/" : currentPath
.substring(0, currentPath.lastIndexOf("/")))));
// TODO (Glen): Ariel's code - What on earth is this doing here?
// It is overriding the value assigned two statements above!!!
// If folder restriction has been set, since the derived
// 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();
}
// 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
// just the directory part of the path
else if (!currentNode.isDirectory()) {
if (!currentNode.isDirectory())
{
currentPath = AVMNodeConverter.SplitBase(currentPath)[0];
}
}
// create current-node element representing node for current path
// and append it to the file picker data element
org.w3c.dom.Element currentNodeElement = filePickerDataDoc
.createElement("current-node");
if (currentPath == null)
{
currentNodeElement.setAttribute("avmPath", "");
currentNodeElement.setAttribute("webappRelativePath", "");
} else
{
currentNodeElement.setAttribute("avmPath", currentPath);
currentNodeElement.setAttribute("webappRelativePath", AVMUtil
.getWebappRelativePath(currentPath));
}
currentNodeElement.setAttribute("type", "directory");
// TODO (Glen): This was in Ariel's code. Is this the correct
@@ -423,29 +498,32 @@ public class FilePickerBean implements Serializable {
filePickerDataElement.appendChild(currentNodeElement);
// if saved search name and saved search context parameters supplied (i.e.
// not null),
// then get saved saved search node matching given name and context
if ((savedSearchName != null) && (savedSearchName.length() != 0)
&& (savedSearchContext != null)
&& (savedSearchContext.length() != 0)) {
// get node reference for named saved search in the given saved search
// context
NodeRef savedSearchNodeRef = getSavedSearches(savedSearchName,
savedSearchContext);
// if configured search name supplied (i.e. not null),
// then get configured search node matching given name
// and add the nodes from the search result to the file
// picker data
if ((configSearchName != null) && (configSearchName.length() != 0))
{
// get node reference for named configured search
NodeRef configuredSearchNodeRef = getConfiguredSearches(configSearchName);
// 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
// of the file picker data element.
addAVMNodesToElement(filePickerDataDoc, filePickerDataElement,
searchResultNodes, selectableTypes, facesContext);
} else {
} else
{
// add elements for child nodes of current path to file picker
// data element
addPathChildNodesToElement(filePickerDataDoc, filePickerDataElement,
currentPath, selectableTypes, filterMimetypes, facesContext);
// data element if current path is not null
if (currentPath != null)
{
addPathChildNodesToElement(filePickerDataDoc,
filePickerDataElement, currentPath, selectableTypes,
filterMimetypes, facesContext);
}
}
final ResponseWriter out = facesContext.getResponseWriter();
@@ -453,7 +531,8 @@ public class FilePickerBean implements Serializable {
}
@InvokeCommand.ResponseMimetype(value = MimetypeMap.MIMETYPE_HTML)
public void uploadFile() throws Exception {
public void uploadFile() throws Exception
{
LOGGER.debug(this + ".uploadFile()");
final FacesContext facesContext = FacesContext.getCurrentInstance();
final ExternalContext externalContext = facesContext.getExternalContext();
@@ -470,45 +549,57 @@ public class FilePickerBean implements Serializable {
String filename = null;
String returnPage = null;
InputStream fileInputStream = null;
for (FileItem item : fileItems) {
if (LOGGER.isDebugEnabled()) {
for (FileItem item : fileItems)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("item = " + item);
}
if (item.isFormField() && item.getFieldName().equals("upload-id")) {
if (item.isFormField() && item.getFieldName().equals("upload-id"))
{
uploadId = item.getString();
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("uploadId is " + uploadId);
}
}
if (item.isFormField() && item.getFieldName().equals("return-page")) {
if (item.isFormField() && item.getFieldName().equals("return-page"))
{
returnPage = item.getString();
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("returnPage is " + returnPage);
}
} else if (item.isFormField()
&& item.getFieldName().equals("currentPath")) {
&& item.getFieldName().equals("currentPath"))
{
final String previewStorePath = AVMUtil
.getCorrespondingPathInPreviewStore(this.getCurrentAVMPath());
currentPath = AVMUtil.buildPath(previewStorePath, item.getString(),
AVMUtil.PathRelation.WEBAPP_RELATIVE);
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("currentPath is " + currentPath);
}
} else {
} else
{
filename = FilenameUtils.getName(item.getName());
fileInputStream = item.getInputStream();
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("uploading file " + filename);
}
}
}
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("saving file " + filename + " to " + currentPath);
}
try {
try
{
FileCopyUtils.copy(fileInputStream, this.getAvmService().createFile(
currentPath, filename));
final Map<QName, PropertyValue> props = new HashMap<QName, PropertyValue>(
@@ -527,7 +618,8 @@ public class FilePickerBean implements Serializable {
+ filename));
returnPage = returnPage.replace("${_FILE_TYPE_IMAGE}", Utils
.getFileTypeImage(facesContext, filename, true));
} catch (Exception e) {
} catch (Exception e)
{
LOGGER.debug(e.getMessage(), e);
returnPage = returnPage.replace("${_UPLOAD_ERROR}", e.getMessage());
}
@@ -549,9 +641,11 @@ public class FilePickerBean implements Serializable {
XMLUtil.print(result, out);
}
private String getCurrentAVMPath() {
private String getCurrentAVMPath()
{
final AVMNode node = this.getAvmBrowseBean().getAvmActionNode();
if (node == null) {
if (node == null)
{
return this.getAvmBrowseBean().getCurrentPath();
}
@@ -560,13 +654,16 @@ public class FilePickerBean implements Serializable {
: AVMNodeConverter.SplitBase(result)[0];
}
private QName[] getSelectableTypes(final String[] selectableTypes) {
final QName[] result = (selectableTypes == null ? new QName[] {
WCMModel.TYPE_AVM_CONTENT, WCMModel.TYPE_AVM_FOLDER }
private QName[] getSelectableTypes(final String[] selectableTypes)
{
final QName[] result = (selectableTypes == null ? new QName[]
{ WCMModel.TYPE_AVM_CONTENT, WCMModel.TYPE_AVM_FOLDER }
: new QName[selectableTypes.length]);
if (selectableTypes != null) {
for (int i = 0; i < selectableTypes.length; i++) {
if (selectableTypes != null)
{
for (int i = 0; i < selectableTypes.length; i++)
{
result[i] = QName.resolveToQName(this.getNamespaceService(),
selectableTypes[i]);
}
@@ -574,11 +671,14 @@ public class FilePickerBean implements Serializable {
return result;
}
private Pattern[] getFilterMimetypes(final String[] filterMimetypes) {
private Pattern[] getFilterMimetypes(final String[] filterMimetypes)
{
final Pattern[] result = filterMimetypes == null ? new Pattern[0]
: new Pattern[filterMimetypes.length];
if (filterMimetypes != null) {
for (int i = 0; i < filterMimetypes.length; i++) {
if (filterMimetypes != null)
{
for (int i = 0; i < filterMimetypes.length; i++)
{
result[i] = Pattern.compile(filterMimetypes[i].replaceAll("\\*",
"\\.*").replaceAll("\\/", "\\\\/"));
}
@@ -610,26 +710,32 @@ public class FilePickerBean implements Serializable {
*/
private void addPathChildNodesToElement(org.w3c.dom.Document doc,
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
// to parent element
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
// has been set, then only add child element for AVM node if it matches
// 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()
.getContentDataForRead(entry.getValue()).getMimetype();
boolean matched = false;
for (final Pattern p : filterMimetypes) {
for (final Pattern p : filterMimetypes)
{
matched = p.matcher(contentMimetype).matches();
if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug(p + ".matches(" + contentMimetype + ") = "
+ matched);
}
if (matched) {
if (matched)
{
break;
}
}
@@ -637,7 +743,8 @@ public class FilePickerBean implements Serializable {
// 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
// on it and jump back to the start of the AVM node traversal loop
if (!matched) {
if (!matched)
{
continue;
}
}
@@ -666,8 +773,10 @@ public class FilePickerBean implements Serializable {
*/
private void addAVMNodesToElement(org.w3c.dom.Document doc,
org.w3c.dom.Element parent, List<AVMNodeDescriptor> nodes,
QName[] selectableTypes, FacesContext facesContext) {
for (AVMNodeDescriptor node : nodes) {
QName[] selectableTypes, FacesContext facesContext)
{
for (AVMNodeDescriptor node : nodes)
{
// create child element representing AVM node and add to file picker
// data element
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
* web project the XForm is currently within
* Run a configured search represented by the given node reference, against
* the web project the XForm is currently within
*
* @param savedQueryNodRef
* NodeRef of the saved query with which to run the search
* @param configuredQueryNodRef
* NodeRef of the configured query with which to run the search
*
* @return content nodes returned by the search
*/
private List<AVMNodeDescriptor> runSavedSearch(NodeRef savedSearchNodeRef) {
// get the store id used to run the saved search query
private List<AVMNodeDescriptor> runConfiguredSearch(
NodeRef configSearchNodeRef)
{
// get the store id used to run the configured search query
WebProject webProject = this.getAvmBrowseBean().getWebProject();
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(
savedSearchNodeRef, ContentModel.PROP_CONTENT);
configSearchNodeRef, ContentModel.PROP_CONTENT);
InputStream queryInpStream = contentReader.getContentInputStream();
SAXReader reader = new SAXReader();
Document savedQueryDoc = null;
try {
savedQueryDoc = reader.read(queryInpStream);
} catch (DocumentException de) {
Document queryDoc = null;
try
{
queryDoc = reader.read(queryInpStream);
} catch (DocumentException de)
{
// ignore exception and return null
return null;
}
// extract search query from saved search XML document
// extract search query from configured search XML document
String query = null;
XPath queryXPath = DocumentHelper.createXPath(SAVED_SEARCH_QUERY_XPATH);
List xpathResult = queryXPath.selectNodes(savedQueryDoc);
if ((xpathResult != null) && (xpathResult.size() != 0)) {
XPath queryXPath = DocumentHelper
.createXPath(CONFIGURED_SEARCH_QUERY_XPATH);
List xpathResult = queryXPath.selectNodes(queryDoc);
if ((xpathResult != null) && (xpathResult.size() != 0))
{
// get the text from the query element
Element queryElement = (Element) xpathResult.get(0);
String queryElemText = queryElement.getText();
@@ -722,26 +837,31 @@ public class FilePickerBean implements Serializable {
// extract
// the query string from the CDATA section
if ((cdataStartDelimIndex > -1)
&& ((cdataStartDelimIndex + CDATA_START_DELIM.length()) < cdataEndDelimIndex)) {
&& ((cdataStartDelimIndex + CDATA_START_DELIM.length()) < cdataEndDelimIndex))
{
query = queryElemText.substring(cdataStartDelimIndex
+ CDATA_START_DELIM.length(), cdataEndDelimIndex);
}
}
// 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)
List<AVMNodeDescriptor> resultNodeDescriptors = null;
if ((query != null) && (query.length() != 0)) {
if ((query != null) && (query.length() != 0))
{
ResultSet results = null;
try {
try
{
results = this.getSearchService().query(
new StoreRef(StoreRef.PROTOCOL_AVM, storeID),
SearchService.LANGUAGE_LUCENE, query);
if (results.length() != 0) {
if (results.length() != 0)
{
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);
NodeRef resultNodeRef = row.getNodeRef();
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
// in the search results
if (getDictionaryService().isSubClass(resultNode.getType(),
ContentModel.TYPE_CONTENT)) {
ContentModel.TYPE_CONTENT))
{
Pair<Integer, String> pair = AVMNodeConverter
.ToAVMVersionPath(resultNodeRef);
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: "
+ query, err);
} finally {
if (results != null) {
} finally
{
if (results != null)
{
results.close();
}
}
@@ -774,126 +898,86 @@ public class FilePickerBean implements Serializable {
}
/**
* Get the cached reference to the current user's saved searches folder. This
* method will first get a reference to the current user's saved searches
* 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
* Get the cached reference to the public saved searches folder. This method
* will first get a reference to the public saved searches folder and assign
* 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
// global saved searches folder to assign to it
if (globalSearchesRef == null) {
// public saved searches folder to assign to it
if (publicSearchesRef == null)
{
// Use the search service get a reference to the
// global saved searches folder.
// public saved searches folder.
FacesContext fc = FacesContext.getCurrentInstance();
String xpath = Application.getRootPath(fc) + "/"
+ Application.getGlossaryFolderName(fc) + "/"
+ Application.getSavedSearchesFolderName(fc);
List<NodeRef> results = null;
try {
try
{
results = getSearchService().selectNodes(
getNodeService().getRootNode(Repository.getStoreRef()),
xpath, null, getNamespaceService(), false);
} catch (AccessDeniedException err) {
} catch (AccessDeniedException err)
{
// ignore and return null
}
if (results != null && results.size() != 0) {
globalSearchesRef = results.get(0);
if (results != null && results.size() != 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
* name of saved search for which to get node
* @param savedSearchContext
* 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
* @param configSearchName
* name of configured search for which to get node
* @return node reference for configured search
*/
public NodeRef getSavedSearches(String savedSearchName,
String savedSearchContext) {
NodeRef savedSearchNodeRef = null;
public NodeRef getConfiguredSearches(String configSearchName)
{
NodeRef configSearchNodeRef = null;
// get the saved searches folder reference from the
// current user or global searches location
NodeRef savedSearchesFolderRef = null;
if (SAVED_SEARCHES_CONTEXT_USER.equals(savedSearchContext)) {
savedSearchesFolderRef = getUserSearchesRef();
} else if (SAVED_SEARCHES_CONTEXT_GLOBAL.equals(savedSearchContext)) {
savedSearchesFolderRef = getGlobalSearchesRef();
}
// get the folder reference from the
// public searches location
NodeRef publicSearchesFolderRef = getPublicSearchesRef();
// read the content nodes under the folder
List<ChildAssociationRef> childRefs = getNodeService().getChildAssocs(
savedSearchesFolderRef, ContentModel.ASSOC_CONTAINS,
publicSearchesFolderRef, ContentModel.ASSOC_CONTAINS,
RegexQNamePattern.MATCH_ALL);
// return content node with name matching given saved search name
if (childRefs.size() != 0) {
for (ChildAssociationRef ref : childRefs) {
// return content node with name matching given configured search name
if (childRefs.size() != 0)
{
for (ChildAssociationRef ref : childRefs)
{
NodeRef childNodeRef = ref.getChildRef();
Node childNode = new Node(childNodeRef);
if (getDictionaryService().isSubClass(childNode.getType(),
ContentModel.TYPE_CONTENT)) {
ContentModel.TYPE_CONTENT))
{
String childNodeName = childNode.getName();
if (childNodeName.equals(savedSearchName)) {
savedSearchNodeRef = childNodeRef;
if (childNodeName.equals(configSearchName))
{
configSearchNodeRef = childNodeRef;
break;
}
}
}
}
return savedSearchNodeRef;
return configSearchNodeRef;
}
/**
@@ -913,7 +997,8 @@ public class FilePickerBean implements Serializable {
*/
private void addAVMChildNodeToParentElement(org.w3c.dom.Document doc,
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
org.w3c.dom.Element childNodeElement = doc.createElement("child-node");
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
// efficiently get the type
// qname from the avmservice
for (final QName typeQName : selectableTypes) {
for (final QName typeQName : selectableTypes)
{
selectable = selectable
|| (WCMModel.TYPE_AVM_FOLDER.equals(typeQName) && node
.isDirectory());

View File

@@ -52,8 +52,7 @@ alfresco.FilePickerWidget = function(uploadId,
selectableTypes,
filterMimetypes,
folderRestriction,
savedSearchName,
savedSearchContext)
configSearchName)
{
this.uploadId = uploadId;
this.node = node;
@@ -65,8 +64,7 @@ alfresco.FilePickerWidget = function(uploadId,
this.selectableTypes = selectableTypes;
this.filterMimetypes = filterMimetypes;
this.folderRestriction = folderRestriction;
this.savedSearchName = savedSearchName;
this.savedSearchContext = savedSearchContext;
this.configSearchName = configSearchName;
}
// static methods and properties
@@ -266,13 +264,9 @@ _navigateToNode: function(path)
{
req.content.folderRestriction = this.folderRestriction;
}
if (this.savedSearchName)
if (this.configSearchName)
{
req.content.savedSearchName = this.savedSearchName;
}
if (this.savedSearchContext)
{
req.content.savedSearchContext = this.savedSearchContext;
req.content.configSearchName = this.configSearchName;
}
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._filterMimetypes = "filter_mimetypes" in params ? params["filter_mimetypes"].split(",") : [];
this._folderRestriction = "folder_restriction" in params ? params["folder_restriction"] : null;
this._savedSearchName = "saved_search_name" in params ? params["saved_search_name"] : null;
this._savedSearchContext = "saved_search_context" in params ? params["saved_search_context"] : null;
},
this._configSearchName = "config_search_name" in params ? params["config_search_name"] : null; },
/////////////////////////////////////////////////////////////////
// overridden methods
@@ -532,8 +530,7 @@ alfresco.xforms.FilePicker = alfresco.xforms.Widget.extend({
this._selectableTypes,
this._filterMimetypes,
this._folderRestriction,
this._savedSearchName,
this._savedSearchContext);
this._configSearchName);
this.widget.render();
},