Merged V1.3 to HEAD (3068:3083, 3084:3086)

svn merge svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3068 svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3083 .
   svn merge svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3084 svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3086 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3342 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-07-18 15:42:28 +00:00
parent 383c8028a0
commit 70cdb203e0
8 changed files with 499 additions and 17 deletions

View File

@@ -29,6 +29,7 @@ modify_content_user_roles_description=Modify the permissions granted to a user f
advancedsearch_description=Perform a more detailed search of the repository.
edit_content_description=Modify the content properties then click OK.
editcategory_description=Set the category for the document then click OK.
editcategory_space_description=Set the category for the space then click OK.
editworkflow_description=Modify the simple workflow properties then click OK.
editspace_description=Modify the space properties then click OK.
editlink_description=Modify the link object properties then click OK.
@@ -86,6 +87,8 @@ change=Change
set=Set
no_categories_applied=This document does not yet have any categories applied.
has_following_categories=This document has the following categories applied...
no_categories_applied_space=This space does not yet have any categories applied.
has_following_categories_space=This space has the following categories applied...
moved=moved
copied=copied
document_action=The document will be {0} to ''{1}'' if the ''{2}'' action is taken.
@@ -511,6 +514,7 @@ not_inline_editable=This document is not inline editable.
allow_inline_editing=Allow Inline Editing
not_in_workflow=This document is not part of any workflow.
not_in_category=This document is not categorized.
not_in_category_space=This space is not categorized.
not_versioned=This document has no version history.
allow_categorization=Allow Categorization
allow_versioning=Allow Versioning
@@ -997,6 +1001,7 @@ error_update_simpleworkflow=Failed to update simple workflow due to system error
error_workflow_approve=Failed to approve the document due to system error: {0}
error_workflow_reject=Failed to reject the document due to system error: {0}
error_aspect_classify=Failed to apply the ''classifiable'' aspect to the document due to system error: {0}
error_aspect_classify_space=Failed to apply the ''classifiable'' aspect to the space due to system error: {0}
error_aspect_versioning=Failed to apply the ''versionable'' aspect to the document due to system error: {0}
error_aspect_inlineeditable=Failed to apply the ''inlineeditable'' aspect to the document due to system error: {0}
error_content_missing=The node''s content is missing: \n node: {0} \n reader: {1} \nPlease contact your system administrator.

View File

@@ -16,9 +16,17 @@
*/
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.action.ActionEvaluator;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
/**
* UI Action Evaluator - Discuss a node.
@@ -32,7 +40,24 @@ public final class DiscussNodeEvaluator implements ActionEvaluator
*/
public boolean evaluate(Node node)
{
return (node.hasAspect(ForumModel.ASPECT_DISCUSSABLE) == true);
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;
}
}
/*

View File

@@ -225,7 +225,11 @@ public final class SearchContext implements Serializable
}
// special case for AND all terms if set (apply after operator character removed)
// note that we can't force AND if NOT operator has been set
if (operatorNOT == false)
{
operatorAND = operatorAND | this.forceAndTerms;
}
if (term.length() != 0)
{

View File

@@ -16,31 +16,28 @@
*/
package org.alfresco.web.bean;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
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.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
/**
* Backing bean provided access to the details of a Space
@@ -51,9 +48,18 @@ public class SpaceDetailsBean extends BaseDetailsBean
{
private static final String OUTCOME_RETURN = "showSpaceDetails";
private static final String MSG_HAS_FOLLOWING_CATEGORIES = "has_following_categories_space";
private static final String MSG_NO_CATEGORIES_APPLIED = "no_categories_applied_space";
private static final String MSG_ERROR_UPDATE_CATEGORY = "error_update_category";
private static final String MSG_ERROR_ASPECT_CLASSIFY = "error_aspect_classify_space";
/** PermissionService bean reference */
protected PermissionService permissionService;
/** Category details */
private NodeRef addedCategory;
private List categories;
// ------------------------------------------------------------------------------
// Construction
@@ -161,6 +167,7 @@ public class SpaceDetailsBean extends BaseDetailsBean
*/
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -191,9 +198,22 @@ public class SpaceDetailsBean extends BaseDetailsBean
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
}
}
}
@@ -202,6 +222,7 @@ public class SpaceDetailsBean extends BaseDetailsBean
*/
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -229,9 +250,22 @@ public class SpaceDetailsBean extends BaseDetailsBean
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
}
}
}
@@ -244,4 +278,200 @@ public class SpaceDetailsBean extends BaseDetailsBean
this.navigator.resetCurrentNodeProperties();
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
// ------------------------------------------------------------------------------
// Categorised Details
/**
* Determines whether the current space has any categories applied
*
* @return true if the document has categories attached
*/
public boolean isCategorised()
{
return getSpace().hasAspect(ContentModel.ASPECT_GEN_CLASSIFIABLE);
}
/**
* Returns a list of objects representing the categories applied to the
* current space
*
* @return List of categories
*/
public String getCategoriesOverviewHTML()
{
String html = null;
if (isCategorised())
{
// we know for now that the general classifiable aspect only will be
// applied so we can retrive the categories property direclty
Collection categories = (Collection)this.nodeService.getProperty(getSpace().getNodeRef(),
ContentModel.PROP_CATEGORIES);
if (categories == null || categories.size() == 0)
{
html = Application.getMessage(FacesContext.getCurrentInstance(), MSG_NO_CATEGORIES_APPLIED);
}
else
{
StringBuilder builder = new StringBuilder(Application.getMessage(FacesContext.getCurrentInstance(),
MSG_HAS_FOLLOWING_CATEGORIES));
builder.append("<ul>");
for (Object obj : categories)
{
if (obj instanceof NodeRef)
{
if (this.nodeService.exists((NodeRef)obj))
{
builder.append("<li>");
builder.append(Repository.getNameForNode(this.nodeService, (NodeRef)obj));
builder.append("</li>");
}
}
}
builder.append("</ul>");
html = builder.toString();
}
}
return html;
}
/**
* Event handler called to setup the categories for editing
*
* @param event The event
*/
public void setupCategoriesForEdit(ActionEvent event)
{
this.categories = (List)this.nodeService.getProperty(getSpace().getNodeRef(),
ContentModel.PROP_CATEGORIES);
}
/**
* Returns a Map of the initial categories on the node keyed by the NodeRef
*
* @return Map of initial categories
*/
public List getCategories()
{
return this.categories;
}
/**
* Sets the categories Map
*
* @param categories
*/
public void setCategories(List categories)
{
this.categories = categories;
}
/**
* Returns the last category added from the multi value editor
*
* @return The last category added
*/
public NodeRef getAddedCategory()
{
return this.addedCategory;
}
/**
* Sets the category added from the multi value editor
*
* @param addedCategory The added category
*/
public void setAddedCategory(NodeRef addedCategory)
{
this.addedCategory = addedCategory;
}
/**
* Updates the categories for the current document
*
* @return The outcome
*/
public String saveCategories()
{
String outcome = "cancel";
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// firstly retrieve all the properties for the current node
Map<QName, Serializable> updateProps = this.nodeService.getProperties(
getSpace().getNodeRef());
// create a node ref representation of the selected id and set the new properties
updateProps.put(ContentModel.PROP_CATEGORIES, (Serializable)this.categories);
// set the properties on the node
this.nodeService.setProperties(getSpace().getNodeRef(), updateProps);
// commit the transaction
tx.commit();
// reset the state of the current document so it reflects the changes just made
getSpace().reset();
outcome = "finish";
}
catch (Throwable e)
{
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_CATEGORY), e.getMessage()), e);
}
return outcome;
}
/**
* Applies the classifiable aspect to the current document
*/
public void applyClassifiable()
{
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// add the general classifiable aspect to the node
this.nodeService.addAspect(getSpace().getNodeRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, null);
// commit the transaction
tx.commit();
// reset the state of the current document
getSpace().reset();
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_CLASSIFY), e.getMessage()), e);
}
}
/**
* Returns whether the current sapce is locked
*
* @return true if the document is checked out
*/
public boolean isLocked()
{
return getSpace().isLocked();
}
}

View File

@@ -697,17 +697,21 @@ public class ForumsBean implements IContextListener
ForumModel.ASSOC_DISCUSSION, RegexQNamePattern.MATCH_ALL);
// there should only be one child, retrieve it if there is
if (children.size() != 1)
if (children.size() == 1)
{
throw new IllegalStateException("Node has the discussable aspect but does not have 1 child, it has " +
children.size() + " children!");
}
// show the forum for the discussion
NodeRef forumNodeRef = children.get(0).getChildRef();
this.browseBean.clickSpace(forumNodeRef);
context.getApplication().getNavigationHandler().handleNavigation(context, null, "showForum");
}
else
{
// this should never happen as the action evaluator should stop the action
// from displaying, just in case print a warning to the console
logger.warn("Node has the discussable aspect but does not have 1 child, it has " +
children.size() + " children!");
}
}
/**
* Called when the user confirms they wish to delete a forum space

View File

@@ -287,6 +287,10 @@
<from-outcome>showForum</from-outcome>
<to-view-id>/jsp/forums/forum.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editCategories</from-outcome>
<to-view-id>/jsp/dialog/edit-space-category.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
@@ -377,6 +381,18 @@
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/jsp/dialog/edit-space-category.jsp</from-view-id>
<navigation-case>
<from-outcome>cancel</from-outcome>
<to-view-id>/jsp/dialog/space-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>finish</from-outcome>
<to-view-id>/jsp/dialog/space-details.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/jsp/dialog/rules.jsp</from-view-id>
<navigation-case>

View File

@@ -0,0 +1,169 @@
<%--
Copyright (C) 2005 Alfresco, Inc.
Licensed under the Mozilla Public License version 1.1
with a permitted attribution clause. You may obtain a
copy of the License at
http://www.alfresco.org/legal/license.txt
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific
language governing permissions and limitations under the
License.
--%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
<%@ page isELIgnored="false" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<r:page titleId="title_edit_categories">
<f:view>
<%-- load a bundle of properties with I18N strings --%>
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
<h:form acceptCharset="UTF-8" id="edit-category">
<%-- Main outer table --%>
<table cellspacing="0" cellpadding="2">
<%-- Title bar --%>
<tr>
<td colspan="2">
<%@ include file="../parts/titlebar.jsp" %>
</td>
</tr>
<%-- Main area --%>
<tr valign="top">
<%-- Shelf --%>
<td>
<%@ include file="../parts/shelf.jsp" %>
</td>
<%-- Work Area --%>
<td width="100%">
<table cellspacing="0" cellpadding="0" width="100%">
<%-- Breadcrumb --%>
<%@ include file="../parts/breadcrumb.jsp" %>
<%-- Status and Actions --%>
<tr>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)" width="4"></td>
<td bgcolor="#EEEEEE">
<%-- Status and Actions inner contents table --%>
<%-- Generally this consists of an icon, textual summary and actions for the current object --%>
<table cellspacing="4" cellpadding="0" width="100%">
<tr>
<td width="32">
<h:graphicImage id="wizard-logo" url="/images/icons/edit_large.gif" />
</td>
<td>
<div class="mainTitle"><h:outputText value="#{msg.modify_categories_of}" /> '<h:outputText value="#{BrowseBean.actionSpace.name}" />'</div>
<div class="mainSubText"><h:outputText value="#{msg.editcategory_space_description}" /></div>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with gradient shadow --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif" width="4" height="9"></td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif" width="4" height="9"></td>
</tr>
<%-- Details --%>
<tr valign=top>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
<td>
<table cellspacing="0" cellpadding="3" border="0" width="100%">
<tr>
<td width="100%" valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
<table cellpadding="2" cellspacing="2" border="0" width="100%">
<tr><td colspan="2" class="paddingRow"></td></tr>
<tr>
<td><h:outputText value="#{msg.categories}" />:</td>
<td width="98%">
<r:multiValueSelector id="multi-category-selector"
value="#{SpaceDetailsBean.categories}"
lastItemAdded="#{SpaceDetailsBean.addedCategory}"
selectItemMsg="#{msg.select_category}"
selectedItemsMsg="#{msg.selected_categories}"
noSelectedItemsMsg="#{msg.no_selected_categories}"
styleClass="selector">
<r:categorySelector id="category-selector" label="#{msg.select_category_prompt}"
styleClass="selector"
value="#{SpaceDetailsBean.addedCategory}"/>
</r:multiValueSelector>
</td>
</tr>
<tr><td colspan="2" class="paddingRow"></td></tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
</td>
<td valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
<table cellpadding="1" cellspacing="1" border="0">
<tr>
<td align="center">
<h:commandButton value="#{msg.ok}" action="#{SpaceDetailsBean.saveCategories}" styleClass="wizardButton" />
</td>
</tr>
<tr><td class="wizardButtonSpacing"></td></tr>
<tr>
<td align="center">
<h:commandButton value="#{msg.cancel}" action="cancel" styleClass="wizardButton" />
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
</tr>
<%-- Error Messages --%>
<tr valign="top">
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
<td>
<%-- messages tag to show messages not handled by other specific message tags --%>
<h:messages globalOnly="true" styleClass="errorMessage" layout="table" />
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with bottom panel graphics --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif" width="4" height="4"></td>
<td width="100%" align="center" style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif" width="4" height="4"></td>
</tr>
</table>
</td>
</tr>
</table>
</h:form>
</f:view>
</r:page>

View File

@@ -202,6 +202,35 @@
<div style="padding:4px"></div>
<h:panelGroup id="category-panel-facets">
<f:facet name="title">
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write">
<a:actionLink id="titleLink3" value="#{msg.change_category}" showLink="false" image="/images/icons/Change_details.gif"
action="editCategories" actionListener="#{SpaceDetailsBean.setupCategoriesForEdit}" />
</r:permissionEvaluator>
</f:facet>
</h:panelGroup>
<a:panel label="#{msg.category}" id="category-panel" facetsId="category-panel-facets" progressive="true"
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE" rendered="#{SpaceDetailsBean.categorised}"
expanded='#{SpaceDetailsBean.panels["category-panel"]}' expandedActionListener="#{SpaceDetailsBean.expandPanel}">
<h:outputText id="category-overview" value="#{SpaceDetailsBean.categoriesOverviewHTML}"
escape="false" />
</a:panel>
<a:panel label="#{msg.category}" id="no-category-panel" progressive="true"
border="white" bgcolor="white" titleBorder="blue" titleBgcolor="#D3E6FE"
rendered="#{SpaceDetailsBean.categorised == false}"
expanded='#{SpaceDetailsBean.panels["category-panel"]}' expandedActionListener="#{SpaceDetailsBean.expandPanel}">
<h:outputText id="no-category-msg" value="#{msg.not_in_category_space}<br/><br/>"
escape="false"/>
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write" id="eval_cat">
<a:actionLink id="make-classifiable" value="#{msg.allow_categorization}"
action="#{SpaceDetailsBean.applyClassifiable}"
rendered="#{SpaceDetailsBean.locked == false}" />
</r:permissionEvaluator>
</a:panel>
<div style="padding:4px"></div>
<h:column id="rules-panel-facets">
<f:facet name="title">
<r:permissionEvaluator value="#{SpaceDetailsBean.space}" allow="Write">