Merged V2.1 to HEAD

6383: ML contributions
   6400: AR-1625 Empty translations track pivot translation


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6406 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-08-02 23:57:38 +00:00
parent 7c4ddd4fdd
commit 4ffc28f0bf
28 changed files with 2461 additions and 848 deletions

View File

@@ -38,6 +38,7 @@ deep_copy=Deep Copy
new_edition=New Edition
new_edition_from=New Edition from this
new_edition_tooltip=Create a new edition from this multilingual content.
properties_close=Edit multilingual properties when the dialog close
pivot_translation=Pivot translation
edition=Edition
editions=Editions
@@ -50,12 +51,16 @@ step1_choose_translation_desc=Step one, select the starting item from the list o
new_edition_choose_translation_title=Step One - Starting item
new_edition_choose_translation_desc=Choose the content item you want to create the new edition.
step2_edition_details=Edition Details
step1_edition_details_desc=Step one, edit the detail of the new edition
step2_edition_details_desc=Step two, edit the detail of the new edition
new_edition_details_title=Step Two - Edition Details
step1_new_edition_details_title=Step One - Edition Details
step2_new_edition_details_title=Step Two - Edition Details
new_edition_details_desc=Enter information about the new edition.
step3_edition_summary=Summary
step2_edition_summary_desc=Step two, view the summary of the new edition
step3_edition_summary_desc=Step three, view the summary of the new edition
new_edition_summary_title=Step Three - Summary
step2_new_edition_summary_title=Step Two - Summary
step3_new_edition_summary_title=Step Three - Summary
new_edition_summary_desc=The information you entered is shown below.
new_edition_finish_instruction=To close this wizard and apply your changes click Finish.
edition_properties=Edition Properties
@@ -69,8 +74,19 @@ create_new_edition_using=Create a new edition using
translations_checked_out_error=Cannot create a new edition because the following translations are checked out.
available_translations=Available translations
marker_tooltip=Change your Content Language to view or edit text in different languages.
checked_out_by=Checked out by
doc_name=Document name
title_mlcontainer_details=Multilingual Document Details
# Versioning of the metadatas
versioned_details_of=Versioned details of
versioned_documentdetails_description=View the details about the versioned content.
title_versioned_doc_details=Versioned Document Details
view_versioned_properties=Properties from a versioned content
view_versioned_properties_description=View the properties of a versioned content.
# Date Pattern
date_pattern=d MMMM yyyy
date_time_pattern=d MMMM yyyy HH:mm
@@ -1658,6 +1674,9 @@ delete_post_info=To remove this post from the topic, click OK.
delete_post_confirm=Are you sure you want to delete the post from \"{0}\"?
delete_file_info=To remove this file and any previous versions, click OK.
delete_file_confirm=Are you sure you want to delete \"{0}\" and all previous versions?
delete_translation_confirm=Are you sure you want to delete \"{0}\" and all previous versions? Its multilingual properties will not be recoverable.
delete_empty_translation_confirm=Are you sure you want to permanently delete \"{0}\"? This document will not be recovered.
delete_ml_container_confirm=Are you sure you want to delete \"{0}\" and all previous editions? Each translation will be deleted too.
delete_rule_info=To remove this rule from the space, click Yes.
delete_user_info=To delete this user from the system, click Yes.
delete_rule_confirm=Are you sure you want to delete \"{0}\"?

View File

@@ -590,9 +590,6 @@
<!-- Add a translation -->
<action id="add_translation">
<permissions>
<permission allow="true">Write</permission>
</permissions>
<evaluator>org.alfresco.web.action.evaluator.AddTranslationEvaluator</evaluator>
<label-id>add_translation</label-id>
<tooltip-id>add_translation_tooltip</tooltip-id>
@@ -606,9 +603,6 @@
<!-- Add a translation whithout content -->
<action id="add_translation_wc">
<permissions>
<permission allow="true">Write</permission>
</permissions>
<evaluator>org.alfresco.web.action.evaluator.AddTranslationEvaluator</evaluator>
<label-id>add_translation_wc</label-id>
<tooltip-id>add_translation_wc_tooltip</tooltip-id>
@@ -628,7 +622,7 @@
<label-id>manage_multilingual_details</label-id>
<tooltip-id>manage_multilingual_details_tooltip</tooltip-id>
<image>/images/icons/multilingual_details.gif</image>
<action-listener>#{BrowseBean.setupContentAction}</action-listener>
<action-listener>#{BrowseBean.setupMLContainerContentAction}</action-listener>
<action>dialog:showMLContainerDetails</action>
<params>
<param name="id">#{actionContext.id}</param>
@@ -640,6 +634,7 @@
<permissions>
<permission allow="true">Write</permission>
</permissions>
<evaluator>org.alfresco.web.action.evaluator.NewEditionEvaluator</evaluator>
<label-id>new_edition</label-id>
<tooltip-id>new_edition_tooltip</tooltip-id>
<image>/images/icons/new_edition_icon.gif</image>
@@ -761,6 +756,10 @@
<action-group id="multilingual_details_actions">
<action idref="add_translation" />
<action idref="add_translation_wc" />
<action idref="cut_node" />
<action idref="copy_node" />
<action idref="delete_doc" />
<action idref="take_ownership_doc" />
<action idref="new_edition" />
</action-group>

View File

@@ -489,25 +489,25 @@
</step>
</wizard>
<!-- Definition of the New Edition wizard -->
<!-- Definition of the 3 steps edition wizard -->
<wizard name="newEdition" managed-bean="NewEditionWizard"
title-id="new_edition_wizard_title"
description-id="new_edition_wizard_desc"
error-message-id="error_new_edition_wizard"
icon="/images/icons/new_edition_large.gif">
<step name="choose-translation"
title-id="step1_choose_translation"
description-id="step1_choose_translation_desc">
title-id="step1_choose_translation"
description-id="step1_choose_translation_desc">
<page path="/jsp/ml/new-edition-wizard/choose-translation.jsp"
title-id="new_edition_choose_translation_title"
description-id="new_edition_choose_translation_desc"
instruction-id="default_instruction" />
title-id="new_edition_choose_translation_title"
description-id="new_edition_choose_translation_desc"
instruction-id="default_instruction" />
</step>
<step name="edition-details"
title-id="step2_edition_details"
description-id="step2_edition_details_desc">
<page path="/jsp/ml/new-edition-wizard/edition-details.jsp"
title-id="new_edition_details_title"
title-id="step2_new_edition_details_title"
description-id="new_edition_details_desc"
instruction-id="default_instruction" />
</step>
@@ -515,11 +515,49 @@
title-id="step3_edition_summary"
description-id="step3_edition_summary_desc">
<page path="/jsp/ml/new-edition-wizard/edition-summary.jsp"
title-id="new_edition_summary_title"
title-id="step3_new_edition_summary_title"
description-id="new_edition_summary_desc"
instruction-id="new_edition_finish_instruction" />
</step>
</wizard>
<!--
Definition of the 2 steps edition wizard.
The first step is skiped to force the new edition to start with a translation selected by the user.
-->
<wizard name="newEditionFrom" managed-bean="NewEditionWizard"
title-id="new_edition_wizard_title"
description-id="new_edition_wizard_desc"
error-message-id="error_new_edition_wizard"
icon="/images/icons/new_edition_large.gif">
<step name="edition-details"
title-id="step2_edition_details"
description-id="step1_edition_details_desc">
<condition if="#{NewEditionWizard.hasTranslationCheckedOut == false}">
<page path="/jsp/ml/new-edition-wizard/edition-details.jsp"
title-id="step1_new_edition_details_title"
description-id="new_edition_details_desc"
instruction-id="default_instruction" />
</condition>
<condition if="#{NewEditionWizard.hasTranslationCheckedOut == true}">
<page path="/jsp/ml/new-edition-wizard/choose-translation.jsp"
title-id="new_edition_choose_translation_title"
description-id="new_edition_choose_translation_desc"
instruction-id="default_instruction" />
</condition>
</step>
<step name="edition-summary"
title-id="step3_edition_summary"
description-id="step2_edition_summary_desc">
<page path="/jsp/ml/new-edition-wizard/edition-summary.jsp"
title-id="step2_new_edition_summary_title"
description-id="new_edition_summary_desc"
instruction-id="new_edition_finish_instruction" />
</step>
</wizard>
</wizards>
</config>

View File

@@ -31,6 +31,7 @@ import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.UserPreferencesBean;
import org.alfresco.web.bean.ml.MultilingualUtils;
import org.alfresco.web.bean.repository.Node;
/**
@@ -39,28 +40,49 @@ import org.alfresco.web.bean.repository.Node;
* If the node is not already Multilingual, locked, or if a translation exists for each available
* filter language, don't allow the action.
*
* The current user can add a translation to a translation set only if he has enough right to add
* a content to the space where the pivot translation is located in.
*
* @author Yannick Pignot
*/
public class AddTranslationEvaluator implements ActionEvaluator
{
public boolean evaluate(Node node)
{
FacesContext fc = FacesContext.getCurrentInstance();
boolean isNodeMultililingal = node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
boolean isMLContainer = node.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER);
MultilingualContentService mlservice =
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
// the node must be multiligual (translation or ml container)
if(isNodeMultililingal || isMLContainer)
{
FacesContext fc = FacesContext.getCurrentInstance();
UserPreferencesBean userprefs =
(UserPreferencesBean) FacesHelper.getManagedBean(fc, "UserPreferencesBean");
// the current user must have enough right to add a content to the space
// where the pivot translation is located in
if(MultilingualUtils.canAddChildrenToPivotSpace(node, fc))
{
MultilingualContentService mlservice =
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
// the number of translation of this document
int availableTranslationCount = mlservice.getTranslations(node.getNodeRef()).size();
// the total number of available languages for the translation
int contentFilterLanguagesCount = userprefs.getContentFilterLanguages(false).length;
UserPreferencesBean userprefs =
(UserPreferencesBean) FacesHelper.getManagedBean(fc, "UserPreferencesBean");
return (node.isLocked() == false &&
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false &&
node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT) == true &&
availableTranslationCount < contentFilterLanguagesCount);
// the number of translation of this document
int availableTranslationCount = mlservice.getTranslations(node.getNodeRef()).size();
// the total number of available languages for the translation
int contentFilterLanguagesCount = userprefs.getContentFilterLanguages(false).length;
// the number of translation must be < to the total number of available language for the content filter
return (availableTranslationCount < contentFilterLanguagesCount);
}
else
{
return false;
}
}
else
{
return false;
}
}
}

View File

@@ -24,8 +24,11 @@
*/
package org.alfresco.web.action.evaluator;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.bean.ml.MultilingualUtils;
import org.alfresco.web.bean.repository.Node;
/**
@@ -38,12 +41,24 @@ import org.alfresco.web.bean.repository.Node;
* troublesome. Spreading translations of the same semantic message among several
* spaces could lead to confusion and problems.
*
* If the node to move is a mlContainer, the user must have enough right to delete each translation
*
* @author Yannick Pignot
*/
public class CutNodeEvaluator implements ActionEvaluator
{
public boolean evaluate(Node node)
{
FacesContext fc = FacesContext.getCurrentInstance();
// the node to delete is a ml container, test if the user has enought right on each translation
if(node.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
return MultilingualUtils.canMoveEachTranslation(node, fc);
}
boolean eval = true;
// impossible to cut/copy a translation without content.

View File

@@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.ml.MultilingualUtils;
import org.alfresco.web.bean.repository.Node;
/**
@@ -44,13 +45,19 @@ public class DeleteDocEvaluator implements ActionEvaluator
*/
public boolean evaluate(Node node)
{
FacesContext fc = FacesContext.getCurrentInstance();
// the node to delete is a ml container, test if the user has enought right on each translation
if(node.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
return MultilingualUtils.canDeleteEachTranslation(node, fc);
}
boolean isPivot = false;
// special case for multilingual documents
if (node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
{
FacesContext fc = FacesContext.getCurrentInstance();
MultilingualContentService mlservice =
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.web.action.evaluator;
import javax.faces.context.FacesContext;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.bean.ml.MultilingualUtils;
import org.alfresco.web.bean.repository.Node;
/**
* Evaluates whether the new edition wizard action should be visible.
*
* The creation of a new edtion implies the deletion of each translation and the creation
* of new content in the space
*
* @author Yanick Pignot
*/
public class NewEditionEvaluator implements ActionEvaluator
{
public boolean evaluate(Node node)
{
FacesContext fc = FacesContext.getCurrentInstance();
return MultilingualUtils.canStartNewEditon(node, fc);
}
}

View File

@@ -46,6 +46,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -164,6 +165,14 @@ public class BrowseBean implements IContextListener
this.dictionaryService = dictionaryService;
}
/**
* @param multilingualContentService The Multilingual Content Service to set.
*/
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
{
this.multilingualContentService = multilingualContentService;
}
/**
* @param fileFolderService The FileFolderService to set.
*/
@@ -1064,8 +1073,18 @@ public class BrowseBean implements IContextListener
if (node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
{
Locale locale = (Locale) node.getProperties().get(ContentModel.PROP_LOCALE);
Locale locale = null;
if(node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
// if the translation is empty, the lang of the content is the lang of it's pivot.
NodeRef pivot = multilingualContentService.getPivotTranslation(node.getNodeRef());
locale = (Locale) nodeService.getProperty(pivot, ContentModel.PROP_LOCALE);
}
else
{
locale = (Locale) node.getProperties().get(ContentModel.PROP_LOCALE);
}
// the content filter lang defined by the user
String userLang = userPreferencesBean.getContentFilterLanguage();
// the node lang
@@ -1374,6 +1393,30 @@ public class BrowseBean implements IContextListener
setupContentAction(params.get("id"), true);
}
/**
* Action event called by all actions that need to setup a <b>Multilingual</b> Content Document context on the
* BrowseBean before an action page/wizard is called. The context will be a Node in
* setDocument() which can be retrieved on the action page from BrowseBean.getDocument().
*/
public void setupMLContainerContentAction(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
NodeRef translation = new NodeRef(Repository.getStoreRef(), id);
// remember the bean from wich the action comes
DocumentDetailsBean docDetails = (DocumentDetailsBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("DocumentDetailsBean");
docDetails.setTranslationDocument(new Node(translation));
// set the ml container as the current document
NodeRef mlContainer = multilingualContentService.getTranslationContainer(translation);
setupContentAction(mlContainer.getId(), true);
}
/**
* Public helper to setup action pages with content context
*
@@ -1785,6 +1828,9 @@ public class BrowseBean implements IContextListener
/** The file folder service */
protected FileFolderService fileFolderService;
/** The Multilingual Content Service */
protected MultilingualContentService multilingualContentService;
/** Views configuration object */
protected ViewsConfigElement viewsConfig = null;

View File

@@ -29,7 +29,6 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -44,6 +43,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.version.common.VersionLabelComparator;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.ml.ContentFilterLanguagesService;
@@ -59,6 +59,7 @@ import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.ml.MultilingualUtils;
import org.alfresco.web.bean.repository.MapNode;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
@@ -95,6 +96,8 @@ public class DocumentDetailsBean extends BaseDetailsBean
private NodeRef addedCategory;
private List categories;
private Node translationDocument;
// ------------------------------------------------------------------------------
// Construction
@@ -252,8 +255,17 @@ public class DocumentDetailsBean extends BaseDetailsBean
clientVersion.put("notes", version.getDescription());
clientVersion.put("author", version.getCreator());
clientVersion.put("versionDate", version.getCreatedDate());
clientVersion.put("url", DownloadContentServlet.generateBrowserURL(version.getFrozenStateNodeRef(),
clientVersion.getName()));
if(getDocument().hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
clientVersion.put("url", null);
}
else
{
clientVersion.put("url", DownloadContentServlet.generateBrowserURL(version.getFrozenStateNodeRef(),
clientVersion.getName()));
}
// add the client side version to the list
versions.add(clientVersion);
@@ -264,23 +276,6 @@ public class DocumentDetailsBean extends BaseDetailsBean
return versions;
}
/**
* The comparator to sort a version list according their version label ascending
*
* TODO add this code in the repository as Version Util class ?
*/
private Comparator versionComparator = new Comparator()
{
public int compare(Object o1, Object o2)
{
String label01 = ((Version) o1).getVersionLabel();
String label02 = ((Version) o2).getVersionLabel();
// sort the list ascending
return label02.compareTo(label01);
}
};
/** List of client light weight edition histories */
private List<SingleEditionBean> editionHistory = null;
@@ -366,94 +361,103 @@ public class DocumentDetailsBean extends BaseDetailsBean
private List<SingleEditionBean> initEditionHistory()
{
// get the mlContainer
NodeRef mlContainer = getDocumentMlContainer().getNodeRef();
NodeRef mlContainer = getDocumentMlContainer().getNodeRef();
// get all editions and sort them ascending according their version label
List<Version> orderedEditionList = new ArrayList<Version>(editionService.getEditions(mlContainer).getAllVersions());
Collections.sort(orderedEditionList, versionComparator);
// get all editions and sort them ascending according their version label
List<Version> orderedEditionList = new ArrayList<Version>(editionService.getEditions(mlContainer).getAllVersions());
Collections.sort(orderedEditionList, new VersionLabelComparator());
// the list of Single Edition Bean to return
editionHistory = new ArrayList<SingleEditionBean>(orderedEditionList.size());
// the list of Single Edition Bean to return
editionHistory = new ArrayList<SingleEditionBean>(orderedEditionList.size());
boolean firstEdition = true;
boolean firstEdition = true;
// for each edition, init a SingleEditionBean
for (Version edition : orderedEditionList)
{
SingleEditionBean editionBean = new SingleEditionBean();
// for each edition, init a SingleEditionBean
for (Version edition : orderedEditionList)
{
SingleEditionBean editionBean = new SingleEditionBean();
MapNode clientEdition = new MapNode(edition.getFrozenStateNodeRef());
MapNode clientEdition = new MapNode(edition.getFrozenStateNodeRef());
String editionLabel = edition.getVersionLabel();
if (firstEdition)
{
editionLabel += " (" + Application.getMessage(FacesContext.getCurrentInstance(), MSG_CURRENT) + ")";
}
String editionLabel = edition.getVersionLabel();
if (firstEdition)
{
editionLabel += " (" + Application.getMessage(FacesContext.getCurrentInstance(), MSG_CURRENT) + ")";
}
clientEdition.put("editionLabel", editionLabel);
clientEdition.put("editionNotes", edition.getDescription());
clientEdition.put("editionAuthor", edition.getCreator());
clientEdition.put("editionDate", edition.getCreatedDate());
clientEdition.put("editionLabel", editionLabel);
clientEdition.put("editionNotes", edition.getDescription());
clientEdition.put("editionAuthor", edition.getCreator());
clientEdition.put("editionDate", edition.getCreatedDate());
// Set the edition of the edition bean
editionBean.setEdition(clientEdition);
// Set the edition of the edition bean
editionBean.setEdition(clientEdition);
// get translations
List<VersionHistory> translationHistories = null;
// get translations
List<VersionHistory> translationHistories = null;
if (firstEdition)
{
// Get the translations because the current edition doesn't content link with its
// translation in the version store.
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(mlContainer);
translationHistories = new ArrayList<VersionHistory>(translations.size());
for (NodeRef translation : translations.values())
{
translationHistories.add(versionService.getVersionHistory(translation));
}
}
else
{
if (firstEdition)
{
// Get the translations because the current edition doesn't content link with its
// translation in the version store.
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(mlContainer);
translationHistories = new ArrayList<VersionHistory>(translations.size());
for (NodeRef translation : translations.values())
{
translationHistories.add(versionService.getVersionHistory(translation));
}
}
else
{
translationHistories = editionService.getVersionedTranslations(edition);
}
}
// add each translation in the SingleEditionBean
for (VersionHistory versionHistory : translationHistories)
{
// get the list of versions and sort them ascending according their version label
List<Version> orderedVersions = new ArrayList<Version>(versionHistory.getAllVersions());
Collections.sort(orderedVersions, versionComparator);
// add each translation in the SingleEditionBean
for (VersionHistory versionHistory : translationHistories)
{
// get the list of versions and sort them ascending according their version label
List<Version> orderedVersions = new ArrayList<Version>(versionHistory.getAllVersions());
Collections.sort(orderedVersions, new VersionLabelComparator());
// the last version is the first version of the list
Version lastVersion = orderedVersions.get(0);
// the last version is the first version of the list
Version lastVersion = orderedVersions.get(0);
// get the properties of the lastVersion
Map<QName, Serializable> lastVersionProperties = editionService.getVersionedMetadatas(lastVersion);
Locale language = (Locale) lastVersionProperties.get(ContentModel.PROP_LOCALE);
// get the properties of the lastVersion
Map<QName, Serializable> lastVersionProperties = editionService.getVersionedMetadatas(lastVersion);
Locale language = (Locale) lastVersionProperties.get(ContentModel.PROP_LOCALE);
// create a map node representation of the last version
MapNode clientLastVersion = new MapNode(lastVersion.getFrozenStateNodeRef());
// create a map node representation of the last version
MapNode clientLastVersion = new MapNode(lastVersion.getFrozenStateNodeRef());
clientLastVersion.put("versionName", lastVersionProperties.get(ContentModel.PROP_NAME));
clientLastVersion.put("versionDescription", lastVersionProperties.get(ContentModel.PROP_DESCRIPTION));
clientLastVersion.put("versionAuthor", lastVersionProperties.get(ContentModel.PROP_AUTHOR));
clientLastVersion.put("versionCreatedDate", lastVersionProperties.get(ContentModel.PROP_CREATED));
clientLastVersion.put("versionModifiedDate", lastVersionProperties.get(ContentModel.PROP_MODIFIED));
clientLastVersion.put("versionLanguage", this.contentFilterLanguagesService.convertToNewISOCode(language.getLanguage()).toUpperCase());
clientLastVersion.put("versionUrl", DownloadContentServlet.generateBrowserURL(lastVersion.getFrozenStateNodeRef(), clientLastVersion.getName()));
clientLastVersion.put("versionName", lastVersionProperties.get(ContentModel.PROP_NAME));
// use the node service for the description to ensure that the returned value is a text and not a MLText
clientLastVersion.put("versionDescription", nodeService.getProperty(lastVersion.getFrozenStateNodeRef(), ContentModel.PROP_DESCRIPTION));
clientLastVersion.put("versionAuthor", lastVersionProperties.get(ContentModel.PROP_AUTHOR));
clientLastVersion.put("versionCreatedDate", lastVersionProperties.get(ContentModel.PROP_CREATED));
clientLastVersion.put("versionModifiedDate", lastVersionProperties.get(ContentModel.PROP_MODIFIED));
clientLastVersion.put("versionLanguage", this.contentFilterLanguagesService.convertToNewISOCode(language.getLanguage()).toUpperCase());
// add a translation of the editionBean
editionBean.addTranslations(clientLastVersion);
}
editionHistory.add(editionBean);
firstEdition = false;
}
if(nodeService.hasAspect(lastVersion.getFrozenStateNodeRef(), ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
clientLastVersion.put("versionUrl", null);
}
else
{
clientLastVersion.put("versionUrl", DownloadContentServlet.generateBrowserURL(lastVersion.getFrozenStateNodeRef(), clientLastVersion.getName()));
}
return editionHistory;
// add a translation of the editionBean
editionBean.addTranslations(clientLastVersion);
}
editionHistory.add(editionBean);
firstEdition = false;
}
return editionHistory;
}
/**
* Returns a list of objects representing the translations of the current document
* Returns a list of objects representing the translations of the current document
*
* @return List of translations
*/
@@ -461,7 +465,11 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
List<MapNode> translations = new ArrayList<MapNode>();
if (getDocument().hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
Node document = getDocument();
boolean canNewEdtion = MultilingualUtils.canStartNewEditon(document, FacesContext.getCurrentInstance());
if (document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT) || ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(document.getType()))
{
Map<Locale, NodeRef> translationsMap = this.multilingualContentService.getTranslations(getDocument().getNodeRef());
@@ -485,6 +493,8 @@ public class DocumentDetailsBean extends BaseDetailsBean
mapNode.put("language", lgge);
mapNode.put("url", DownloadContentServlet.generateBrowserURL(nodeRef, mapNode.getName()));
mapNode.put("notEmpty", new Boolean(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION)));
mapNode.put("userHasRight", new Boolean(canNewEdtion));
// add the client side version to the list
translations.add(mapNode);
}
@@ -617,13 +627,13 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
public Object execute() throws Throwable
{
// firstly retrieve all the properties for the current node
// firstly retrieve all the properties for the current node
Map<QName, Serializable> updateProps = nodeService.getProperties(getDocument().getNodeRef());
// create a node ref representation of the selected id and set the new properties
// create a node ref representation of the selected id and set the new properties
updateProps.put(ContentModel.PROP_CATEGORIES, (Serializable) categories);
// set the properties on the node
// set the properties on the node
nodeService.setProperties(getDocument().getNodeRef(), updateProps);
return null;
}
@@ -656,7 +666,7 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
public Object execute() throws Throwable
{
// add the general classifiable aspect to the node
// add the general classifiable aspect to the node
nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, null);
return null;
}
@@ -685,7 +695,7 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
public Object execute() throws Throwable
{
// add the versionable aspect to the node
// add the versionable aspect to the node
nodeService.addAspect(getDocument().getNodeRef(), ContentModel.ASPECT_VERSIONABLE, null);
return null;
}
@@ -718,12 +728,12 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
lockService.unlock(getNode().getNodeRef());
String msg = Application.getMessage(fc, MSG_SUCCESS_UNLOCK);
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
String formId = Utils.getParentForm(fc, event.getComponent()).getClientId(fc);
fc.addMessage(formId + ':' + getPropertiesPanelId(), facesMsg);
String msg = Application.getMessage(fc, MSG_SUCCESS_UNLOCK);
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
String formId = Utils.getParentForm(fc, event.getComponent()).getClientId(fc);
fc.addMessage(formId + ':' + getPropertiesPanelId(), facesMsg);
getNode().reset();
getNode().reset();
return null;
}
};
@@ -748,26 +758,26 @@ public class DocumentDetailsBean extends BaseDetailsBean
{
public Object execute() throws Throwable
{
// add the inlineeditable aspect to the node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
String contentType = null;
ContentData contentData = (ContentData)getDocument().getProperties().get(ContentModel.PROP_CONTENT);
if (contentData != null)
{
contentType = contentData.getMimetype();
}
if (contentType != null)
{
// set the property to true by default if the filetype is a known content type
if (MimetypeMap.MIMETYPE_HTML.equals(contentType) ||
MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(contentType) ||
MimetypeMap.MIMETYPE_XML.equals(contentType) ||
MimetypeMap.MIMETYPE_TEXT_CSS.equals(contentType) ||
MimetypeMap.MIMETYPE_JAVASCRIPT.equals(contentType))
{
props.put(ApplicationModel.PROP_EDITINLINE, true);
}
}
// add the inlineeditable aspect to the node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
String contentType = null;
ContentData contentData = (ContentData)getDocument().getProperties().get(ContentModel.PROP_CONTENT);
if (contentData != null)
{
contentType = contentData.getMimetype();
}
if (contentType != null)
{
// set the property to true by default if the filetype is a known content type
if (MimetypeMap.MIMETYPE_HTML.equals(contentType) ||
MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(contentType) ||
MimetypeMap.MIMETYPE_XML.equals(contentType) ||
MimetypeMap.MIMETYPE_TEXT_CSS.equals(contentType) ||
MimetypeMap.MIMETYPE_JAVASCRIPT.equals(contentType))
{
props.put(ApplicationModel.PROP_EDITINLINE, true);
}
}
nodeService.addAspect(getDocument().getNodeRef(), ApplicationModel.ASPECT_INLINEEDITABLE, props);
return null;
@@ -970,6 +980,27 @@ public class DocumentDetailsBean extends BaseDetailsBean
return this.getNode();
}
/**
* Before opening the ml container details, remeber the translation
* from which the action comes.
*
* @param node
*/
public void setTranslationDocument(Node node)
{
this.translationDocument = node;
}
/**
* Restore the translationf from which the ml container
* details dialog comes.
*/
public void resetMLDocument(ActionEvent event)
{
this.browseBean.setupCommonBindingProperties(this.translationDocument);
this.browseBean.setDocument(this.translationDocument);
}
/**
* Returns the ml container of the document this bean is currently representing
*
@@ -977,11 +1008,19 @@ public class DocumentDetailsBean extends BaseDetailsBean
*/
public Node getDocumentMlContainer()
{
NodeRef nodeRef = getNode().getNodeRef();
Node currentNode = getNode();
return new Node(multilingualContentService.getTranslationContainer(nodeRef));
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(currentNode.getType()))
{
return currentNode;
}
else
{
NodeRef nodeRef = getNode().getNodeRef();
return new Node(multilingualContentService.getTranslationContainer(nodeRef));
}
}
/**
* Sets the lock service instance the bean should use
*

View File

@@ -0,0 +1,530 @@
/*--+
| Copyright European Community 2006 - Licensed under the EUPL V.1.0
|
| http://ec.europa.eu/idabc/en/document/6523
|
+--*/
package org.alfresco.web.bean;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.version.common.VersionLabelComparator;
import org.alfresco.service.cmr.ml.ContentFilterLanguagesService;
import org.alfresco.service.cmr.ml.EditionService;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionHistory;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.repository.MapNode;
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.component.UIActionLink;
/**
* Bean with generic function helping the rendering of the versioned properties
*
* @author Yanick Pignot
*/
public class VersionedDocumentDetailsBean
{
/** Dependencies */
protected VersionService versionService;
protected EditionService editionService;
protected NodeService nodeService;
protected MultilingualContentService multilingualContentService;
protected ContentFilterLanguagesService contentFilterLanguagesService;
private static final Comparator VERSION_LABEL_COMPARATOR = new VersionLabelComparator();
/** Determine if the version is a translation of a old edition */
private boolean fromPreviousEditon;
/** The version selected by the user */
private Version documentVersion;
private VersionHistory versionHistory;
/** The multilingual information of the selected version selected by the user */
private Version documentEdition;
private VersionHistory editionHistory;
public void init()
{
fromPreviousEditon = false;
documentVersion = null;
versionHistory = null;
documentEdition = null;
editionHistory = null;
}
/**
* Set which version of the current node that the user want to display the properties
*/
public void setBrowsingVersion(ActionEvent event)
{
init();
// Get the properties of the action event
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String versionLabel = params.get("versionLabel");
String id = params.get("id");
String lang = params.get("lang");
setBrowsingVersion(id, versionLabel, lang);
}
/**
* Implementation of setBrowsingVersion action event to be use with the needed parameters.
*/
private void setBrowsingVersion(String id, String versionLabel, String lang)
{
// test if the mandatories parameter are valid
ParameterCheck.mandatoryString("The id of the node", id);
ParameterCheck.mandatoryString("The version of the node", versionLabel);
try
{
// try to get the nodeRef with the given ID. This node is not a versioned node.
NodeRef currentNodeRef = new NodeRef(Repository.getStoreRef(), id);
// the threatment is different if the node is a translation or a mlContainer
if(nodeService.getType(currentNodeRef).equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
// test if the lang parameter is valid
ParameterCheck.mandatoryString("The lang of the node", lang);
fromPreviousEditon = true;
versionLabel = cleanVersionLabel(versionLabel);
// set the edition information of the mlContainer of the selected translation version
this.editionHistory = editionService.getEditions(currentNodeRef);
this.documentEdition = editionHistory.getVersion(versionLabel);
// set the version to display
this.documentVersion = getBrowsingVersionForMLContainer(currentNodeRef, versionLabel, lang);
}
else
{
fromPreviousEditon = false;
// set the version history
this.versionHistory = versionService.getVersionHistory(currentNodeRef);
// set the version to display
this.documentVersion = getBrowsingVersionForDocument(currentNodeRef, versionLabel);
}
}
catch (InvalidNodeRefException refErr)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {id}) );
}
}
/**
* Navigates to next item in the list of versioned content for the current VersionHistory
*/
@SuppressWarnings("unchecked")
public void nextItem(ActionEvent event)
{
// Get the properties of the action event
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String versionLabel = params.get("versionLabel");
// if the version is not specified, get the next version
if(versionLabel == null)
{
List<Version> nextVersions = new ArrayList<Version>(this.versionHistory.getSuccessors(this.documentVersion));
// if the version history doesn't contains successor, get the root version (the first one)
if(nextVersions == null || nextVersions.size() < 1)
{
this.documentVersion = versionHistory.getRootVersion();
}
else
{
Collections.sort(nextVersions, VERSION_LABEL_COMPARATOR);
this.documentVersion = nextVersions.get(0);
}
}
else
{
this.documentVersion = this.versionHistory.getVersion(versionLabel);
}
}
/**
* Navigates to previous item in the list of versioned content for the current VersionHistory
*/
@SuppressWarnings("unchecked")
public void previousItem(ActionEvent event)
{
// Get the properties of the action event
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String versionLabel = params.get("versionLabel");
// if the version is not specified, get the next version
if(versionLabel == null)
{
Version prevVersion = this.versionHistory.getPredecessor(this.documentVersion);
// if the version history doesn't contains predecessor, get the last version
if(prevVersion == null)
{
List<Version> allVersions = new ArrayList<Version>(this.versionHistory.getAllVersions());
Collections.sort(allVersions, VERSION_LABEL_COMPARATOR);
this.documentVersion = allVersions.get(0);
}
else
{
this.documentVersion = prevVersion;
}
}
else
{
this.documentVersion = this.versionHistory.getVersion(versionLabel);
}
}
/**
* Returns a list of objects representing the translations of the given version of the mlContainer
*
* @return List of translations
*/
@SuppressWarnings("unchecked")
public List getTranslations()
{
// get the version of the mlContainer and its translations
List<VersionHistory> translationsList = editionService.getVersionedTranslations(this.documentEdition);
Map<Locale, NodeRef> translationNodeRef;
// if translation size == 0, the edition is the current edition and the translations are not yet attached.
if(translationsList.size() == 0)
{
// the selection edition is the current: use the multilingual content service
translationNodeRef = multilingualContentService.getTranslations(this.documentEdition.getVersionedNodeRef());
}
else
{
translationNodeRef = new HashMap<Locale, NodeRef>(translationsList.size());
// get the last version of the translation in the given lang of the edition
for (VersionHistory history : translationsList)
{
// get the list of versions and sort them ascending according their version label
List<Version> orderedVersions = new ArrayList<Version>(history.getAllVersions());
Collections.sort(orderedVersions, VERSION_LABEL_COMPARATOR);
// the last version is the first version of the list
Version lastVersion = orderedVersions.get(0);
// fill the list of translation
if(lastVersion != null)
{
NodeRef versionNodeRef = lastVersion.getFrozenStateNodeRef();
Locale locale = (Locale) nodeService.getProperty(versionNodeRef, ContentModel.PROP_LOCALE);
translationNodeRef.put(locale, versionNodeRef);
}
}
}
// the list of client-side translation to return
List<MapNode> translations = new ArrayList<MapNode>(translationNodeRef.size());
for (Map.Entry<Locale, NodeRef> entry : translationNodeRef.entrySet())
{
Locale locale = entry.getKey();
NodeRef nodeRef = entry.getValue();
// create a map node representation of the translation
MapNode mapNode = new MapNode(nodeRef);
String lgge = (locale != null) ?
// convert the locale into new ISO codes
contentFilterLanguagesService.convertToNewISOCode(locale.getLanguage()).toUpperCase()
: null;
mapNode.put("name", nodeService.getProperty(nodeRef, ContentModel.PROP_NAME));
mapNode.put("language", lgge);
mapNode.put("url", DownloadContentServlet.generateBrowserURL(nodeRef, mapNode.getName()));
mapNode.put("notEmpty", new Boolean(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION)));
// add the client side version to the list
translations.add(mapNode);
}
return translations;
}
/**
* Returns a list of objects representing the versions of the
* current document
*
* @return List of previous versions
*/
public List getVersionHistory()
{
List<MapNode> versions = new ArrayList<MapNode>();
for (Version version : this.versionHistory.getAllVersions())
{
// create a map node representation of the version
MapNode clientVersion = new MapNode(version.getFrozenStateNodeRef());
clientVersion.put("versionLabel", version.getVersionLabel());
clientVersion.put("notes", version.getDescription());
clientVersion.put("author", version.getCreator());
clientVersion.put("versionDate", version.getCreatedDate());
if(getFrozenStateDocument().hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
clientVersion.put("url", null);
}
else
{
clientVersion.put("url", DownloadContentServlet.generateBrowserURL(version.getFrozenStateNodeRef(),
clientVersion.getName()));
}
// add the client side version to the list
versions.add(clientVersion);
}
return versions;
}
/**
* @return true if the version is a translation of a previous edition
*/
public boolean isFromPreviousEditon()
{
return fromPreviousEditon;
}
/**
* Returns the URL to download content for the current document
*
* @return Content url to download the current document
*/
public String getUrl()
{
return DownloadContentServlet.generateBrowserURL(getFrozenStateNodeRef(), getName());
}
/**
* @return the versioned node selected by the user
*/
public Node getFrozenStateDocument()
{
return new Node(getFrozenStateNodeRef());
}
/**
* @return the versioned node ref selected by the user
*/
public NodeRef getFrozenStateNodeRef()
{
return documentVersion.getFrozenStateNodeRef();
}
/**
* @return the edition of the mlContainer of the selected verion of the translation
*/
public Node getMultilingualContainerDocument()
{
return new Node(documentEdition.getFrozenStateNodeRef());
}
/**
* @return the name of selected version
*/
public String getName()
{
String name = (String) nodeService.getProperty(getFrozenStateNodeRef(), ContentModel.PROP_NAME);
return name;
}
/**
* @return the file type image URL of the version
*/
public String getFileType32()
{
String fileType = Utils.getFileTypeImage(getName(), false);
return fileType;
}
public boolean isEmptyTranslation()
{
return nodeService.hasAspect(getFrozenStateNodeRef(), ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION);
}
/**
* @return the version to display of the document selected by the user
*/
public Version getVersion()
{
return this.documentVersion;
}
/**
* @return the next page to display according to which page the dialog is coming from
*/
public String getOutcome()
{
return (this.fromPreviousEditon) ? "showMLContainerDetails" : "showDocDetails";
}
/**
* Util method which remove the eventual '(actual)' label from the version label.
*/
private String cleanVersionLabel(String versionLabel)
{
// remove the (actual vesrion) label if needed
int idx = versionLabel.indexOf(' ');
if(idx > -1)
{
versionLabel = versionLabel.substring(0, idx);
}
return versionLabel;
}
/**
* Util method which returns the given version of a node
*/
private Version getBrowsingVersionForDocument(NodeRef document, String versionLabel)
{
return this.versionService.getVersionHistory(document).getVersion(versionLabel);
}
/**
* Util method which returns the current version of a node
*/
private Version getBrowsingCurrentVersionForMLContainer(NodeRef document, String lang)
{
NodeRef translation = multilingualContentService.getTranslationForLocale(document, I18NUtil.parseLocale(lang));
this.versionHistory = versionService.getVersionHistory(translation);
return versionService.getCurrentVersion(translation);
}
/**
* Util method which return the last version of a translation of a given edition of a mlContainer according its language
*/
@SuppressWarnings("unchecked")
private Version getBrowsingVersionForMLContainer(NodeRef document, String editionLabel, String lang)
{
// get the list of translations of the given edition of the mlContainer
List<VersionHistory> translations = editionService.getVersionedTranslations(this.documentEdition);
// if translation size == 0, the edition is the current edition and the translations are not yet attached.
if(translations.size() == 0)
{
// the selection edition is the current.
return getBrowsingCurrentVersionForMLContainer(document, lang);
}
else
{
Version versionToReturn = null;
// get the last version of the translation in the given lang of the edition
for (VersionHistory history : translations)
{
// get the list of versions and sort them ascending according their version label
List<Version> orderedVersions = new ArrayList<Version>(history.getAllVersions());
Collections.sort(orderedVersions, VERSION_LABEL_COMPARATOR);
// the last version is the first version of the list
Version lastVersion = orderedVersions.get(0);
if(lastVersion != null)
{
Map<QName, Serializable> properties = editionService.getVersionedMetadatas(lastVersion);
Locale locale = (Locale) properties.get(ContentModel.PROP_LOCALE);
if(locale.getLanguage().equalsIgnoreCase(lang))
{
versionToReturn = lastVersion;
this.versionHistory = history;
break;
}
}
}
return versionToReturn;
}
}
/**
* @param versionService the Version Service to set
*/
public void setVersionService(VersionService versionService)
{
this.versionService = versionService;
}
/**
* @param editionService the Edition Service to set
*/
public void setEditionService(EditionService editionService)
{
this.editionService = editionService;
}
/**
* @param nodeService the Node Service to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param contentFilterLanguagesService the Content Filter Languages Service to set
*/
public void setContentFilterLanguagesService(ContentFilterLanguagesService contentFilterLanguagesService)
{
this.contentFilterLanguagesService = contentFilterLanguagesService;
}
/**
* @param Multilingual Content Service the Multilingual Content Service to set
*/
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
{
this.multilingualContentService = multilingualContentService;
}
}

View File

@@ -35,6 +35,7 @@ import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -114,6 +115,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
NodeService nodeService = getServiceRegistry().getNodeService();
FileFolderService fileFolderService = getServiceRegistry().getFileFolderService();
CopyService copyService = getServiceRegistry().getCopyService();
MultilingualContentService multilingualContentService = getServiceRegistry().getMultilingualContentService();
// TODO: Should we be using primary parent here?
// We are assuming that the item exists in only a single parent and that the source for
@@ -124,6 +126,8 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
// initial name to attempt the copy of the item with
String name = getName();
String translationPrefix = "";
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
{
// copy as link was specifically requested by the user
@@ -216,6 +220,11 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
destRef,
name);
}
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
// copy the mlContainer and its translations
multilingualContentService.copyTranslationContainer(getNodeRef(), destRef, translationPrefix);
}
else
{
// copy the node
@@ -249,6 +258,11 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
destRef,
name);
}
else if(dd.isSubClass(getType(), ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
// copy the mlContainer and its translations
multilingualContentService.moveTranslationContainer(getNodeRef(), destRef);
}
else
{
// move the node
@@ -284,6 +298,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
String copyOf = Application.getMessage(fc, MSG_COPY_OF);
name = copyOf + ' ' + name;
translationPrefix = copyOf + ' ' + translationPrefix;
}
else
{

View File

@@ -28,6 +28,8 @@ import java.text.MessageFormat;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.BaseDialogBean;
@@ -42,6 +44,10 @@ import org.apache.commons.logging.LogFactory;
*/
public class DeleteContentDialog extends BaseDialogBean
{
protected MultilingualContentService multilingualContentService;
private static final Log logger = LogFactory.getLog(DeleteContentDialog.class);
// ------------------------------------------------------------------------------
@@ -55,11 +61,23 @@ public class DeleteContentDialog extends BaseDialogBean
Node node = this.browseBean.getDocument();
if (node != null)
{
if (logger.isDebugEnabled())
logger.debug("Trying to delete content node: " + node.getId());
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(node.getType()))
{
if (logger.isDebugEnabled())
logger.debug("Trying to delete multilingual container: " + node.getId() + " and its translations" );
// delete the mlContainer and its translations
multilingualContentService.deleteTranslationContainer(node.getNodeRef());
}
else
{
if (logger.isDebugEnabled())
logger.debug("Trying to delete content node: " + node.getId());
// delete the node
this.nodeService.deleteNode(node.getNodeRef());
}
// delete the node
this.nodeService.deleteNode(node.getNodeRef());
}
else
{
@@ -102,10 +120,40 @@ public class DeleteContentDialog extends BaseDialogBean
*/
public String getConfirmMessage()
{
String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_file_confirm");
String fileConfirmMsg = null;
Node document = this.browseBean.getDocument();
if(document.getType().equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
{
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_ml_container_confirm");
}
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_empty_translation_confirm");
}
else if(document.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT))
{
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_translation_confirm");
}
else
{
fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_file_confirm");
}
return MessageFormat.format(fileConfirmMsg,
new Object[] {this.browseBean.getDocument().getName()});
new Object[] {document.getName()});
}
/**
* @param multilingualContentService the Multilingual Content Service to set
*/
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
{
this.multilingualContentService = multilingualContentService;
}
}

View File

@@ -31,13 +31,9 @@ import javax.faces.model.SelectItem;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.UserPreferencesBean;
import org.alfresco.web.bean.content.AddContentDialog;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.ui.common.Utils;
/**
* Dialog bean to upload a new document and to add it to an existing MLContainer.
@@ -85,27 +81,7 @@ public class AddTranslationDialog extends AddContentDialog
// add a new translation
multilingualContentService.addTranslation(this.createdNode, this.mlTranslation, I18NUtil.parseLocale(this.language));
// Get the content data of the translation
ContentData contentData = fileFolderService.getReader(this.createdNode).getContentData();
Node createdNode = new Node(this.createdNode);
Map<String, Object> browseProp = createdNode.getProperties();
browseProp.put("size", contentData.getSize());
browseProp.put("mimetype", contentData.getMimetype());
browseProp.put("cm:content", contentData);
browseProp.put("fileType32", Utils.getFileTypeImage(createdNode.getName(), false));
browseProp.put("url", DownloadContentServlet.generateDownloadURL(this.createdNode, createdNode.getName()));
this.browseBean.setDocument(createdNode);
return outcome;
}
@Override
protected String getDefaultFinishOutcome()
{
return "showDocDetails";
return "browse";
}
@Override

View File

@@ -33,13 +33,10 @@ import javax.faces.model.SelectItem;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.UserPreferencesBean;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.ui.common.Utils;
/**
* Dialog bean to add a new translation without content. I means, a new node is created
@@ -55,23 +52,22 @@ public class AddTranslationWithoutContentDialog extends BaseDialogBean
// the translation being to be created
protected NodeRef newTranslation;
private String name;
private String title;
private String description;
private String author;
private String language;
private boolean showOtherProperties;
@Override
public void init(Map<String, String> parameters)
{
super.init(parameters);
name = null;
title = null;
description = null;
author = null;
language = null;
showOtherProperties = true;
}
@Override
@@ -84,29 +80,23 @@ public class AddTranslationWithoutContentDialog extends BaseDialogBean
Locale locale = I18NUtil.parseLocale(language);
// add the empty translation
newTranslation = multilingualContentService.addEmptyTranslation(refNode, name, locale);
newTranslation = multilingualContentService.addEmptyTranslation(refNode, null, locale);
// set the properties
nodeService.setProperty(newTranslation, ContentModel.PROP_DESCRIPTION, description);
nodeService.setProperty(newTranslation, ContentModel.PROP_AUTHOR, author);
nodeService.setProperty(newTranslation, ContentModel.PROP_TITLE, title);
// Get the content data of the new translation
ContentData newTranslationContentData = fileFolderService.getReader(newTranslation).getContentData();
// set the current browse node
Node browse = new Node(newTranslation);
Map<String, Object> browseProp = browse.getProperties();
browseProp.put("size", newTranslationContentData.getSize());
browseProp.put("mimetype", newTranslationContentData.getMimetype());
browseProp.put("cm:content", newTranslationContentData);
browseProp.put("fileType32", Utils.getFileTypeImage(name, false));
browseProp.put("url", DownloadContentServlet.generateDownloadURL(newTranslation, name));
this.browseBean.setDocument(browse);
return outcome;
// redirect the user according the value of (show other properties)
if(showOtherProperties)
{
this.browseBean.setDocument(new Node(this.newTranslation));
return "dialog:setContentProperties";
}
else
{
return "browse";
}
}
/**
@@ -173,22 +163,6 @@ public class AddTranslationWithoutContentDialog extends BaseDialogBean
this.language = language;
}
/**
* @return the name
*/
public String getName()
{
return name;
}
/**
* @param name the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return the title
*/
@@ -212,4 +186,20 @@ public class AddTranslationWithoutContentDialog extends BaseDialogBean
{
return userPreferencesBean.getAvailablesContentFilterLanguages(this.browseBean.getDocument().getNodeRef(), false);
}
/**
* @return the showOtherProperties
*/
public boolean isShowOtherProperties()
{
return showOtherProperties;
}
/**
* @param showOtherProperties the showOtherProperties to set
*/
public void setShowOtherProperties(boolean showOtherProperties)
{
this.showOtherProperties = showOtherProperties;
}
}

View File

@@ -29,6 +29,7 @@ import java.util.Map;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -92,10 +93,20 @@ public class EditMLContainerDialog extends BaseDialogBean
*/
protected Node initEditableNode()
{
return new Node(
multilingualContentService.getTranslationContainer(
this.browseBean.getDocument().getNodeRef())
);
Node currentNode = this.browseBean.getDocument();
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(currentNode.getType()))
{
return currentNode;
}
else
{
return new Node(
multilingualContentService.getTranslationContainer(
currentNode.getNodeRef())
);
}
}
/**

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.web.bean.ml;
import java.util.Locale;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.repository.Node;
/**
* Util class for the management of multilingual documents on the web client side
*
* @author yanipig
*/
public class MultilingualUtils
{
/**
* Returns true if the current user has enough right to add a content to the space
* where the pivot translation is located in.
*
* @param multlingualDocument
* @param fc
* @return
*/
public static boolean canAddChildrenToPivotSpace(Node multlingualDocument, FacesContext fc)
{
MultilingualContentService mlservice = getMultilingualContentService(fc);
NodeService nodeService = getNodeService(fc);
// get the pivot translation and get the space where it's located
NodeRef pivot = mlservice.getPivotTranslation(multlingualDocument.getNodeRef());
NodeRef space = nodeService.getPrimaryParent(pivot).getParentRef();
// return if the current user can add a content to the space of the pivot
return new Node(space).hasPermission(PermissionService.ADD_CHILDREN);
}
/**
* Returns true if the current user can delete each translation of the mlContainer of the given node
*
* @param multlingualDocument
* @param fc
* @return
*/
public static boolean canDeleteEachTranslation(Node multlingualDocument, FacesContext fc)
{
boolean can = true;
MultilingualContentService mlservice = getMultilingualContentService(fc);
Map<Locale, NodeRef> translations = mlservice.getTranslations(multlingualDocument.getNodeRef());
for (Map.Entry<Locale, NodeRef> entry : translations.entrySet())
{
Node translation = new Node(entry.getValue());
if(translation.hasPermission(PermissionService.DELETE_NODE) == false
|| translation.isLocked() == true
|| translation.hasAspect(ContentModel.ASPECT_WORKING_COPY) == true
)
{
can = false;
break;
}
}
return can;
}
/**
* Returns true if the current user can move each translation of the mlContainer of the given node
*
* @param multlingualDocument
* @param fc
* @return
*/
public static boolean canMoveEachTranslation(Node multlingualDocument, FacesContext fc)
{
boolean can = true;
MultilingualContentService mlservice = getMultilingualContentService(fc);
Map<Locale, NodeRef> translations = mlservice.getTranslations(multlingualDocument.getNodeRef());
for (Map.Entry<Locale, NodeRef> entry : translations.entrySet())
{
Node translation = new Node(entry.getValue());
if(translation.hasPermission(PermissionService.DELETE_NODE) == false)
{
can = false;
break;
}
}
return can;
}
/**
* Returns true if the current user can delete each translation and create
* * a new content in the space
*
* @param multlingualDocument
* @param fc
* @return
*/
public static boolean canStartNewEditon(Node multlingualDocument, FacesContext fc)
{
boolean canDelete = MultilingualUtils.canMoveEachTranslation(multlingualDocument, fc);
boolean canCreate = MultilingualUtils.canAddChildrenToPivotSpace(multlingualDocument, fc);
return canDelete && canCreate;
}
private static MultilingualContentService getMultilingualContentService(FacesContext fc)
{
return (MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
}
private static NodeService getNodeService(FacesContext fc)
{
return (NodeService) FacesHelper.getManagedBean(fc, "NodeService");
}
}

View File

@@ -32,8 +32,11 @@ import java.util.Locale;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.lock.LockService;
@@ -44,36 +47,47 @@ import org.alfresco.service.cmr.ml.MultilingualContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.version.VersionType;
import org.alfresco.util.ParameterCheck;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.wizard.BaseWizardBean;
import org.alfresco.web.ui.common.component.UIActionLink;
/**
* Wizard bean to create a new edition from an existing MLContainer.
*
* @author yanipig
* @author Yanick Pignot
*/
public class NewEditionWizard extends BaseWizardBean
{
public static final String ID_MESSAGE_MINOR_CHANGE = "minor_change";
public static final String ID_MESSAGE_MAJOR_CHANGE = "major_change";
protected EditionService editionService;
protected MultilingualContentService multilingualContentService;
protected ContentFilterLanguagesService contentFilterLanguagesService;
protected LockService lockService;
protected VersionService versionService;
protected NodeRef mlContainerToVersion;
private List<SelectItem> selectableTranslations;
private String startingItemNodeString;
private List<TranslationWrapper> selectableTranslations;
private List<TranslationWrapper> translationsCheckedOut;
private String editionNotes;
private boolean minorChange;
private boolean otherProperties;
private List<SelectItem> translationCheckedOut;
private boolean skipFirstStep;
private String language;
private String title;
private String author;
private boolean hasTranslationCheckedOut;
private NodeRef startingElement;
private String author;
private String selectedLanguage;
@Override
public void init(Map<String, String> parameters)
@@ -81,32 +95,50 @@ public class NewEditionWizard extends BaseWizardBean
super.init(parameters);
// reset the fileds
startingItemNodeString = null;
editionNotes = null;
minorChange = true;
otherProperties = false;
translationCheckedOut = null;
language = "lang";
title = "title";
author = "author";
translationsCheckedOut = null;
selectableTranslations = null;
// set the mlContainer to version
NodeRef currentNodeRef = this.browseBean.getDocument().getNodeRef();
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(currentNodeRef)))
if(!skipFirstStep)
{
mlContainerToVersion = currentNodeRef;
}
else
{
mlContainerToVersion = multilingualContentService.getTranslationContainer(currentNodeRef);
// this properties is set by the skipFirstStep action event method.
language = null;
title = null;
// set the current mlContainer
setMLContainer();
}
translationCheckedOut = getTranslationCheckedOut();
hasTranslationCheckedOut = getHasTranslationCheckedOut();
// init the list of the available translations and the list of translations checked out
initTranslationList();
// true if they are at leat one translation checked out
hasTranslationCheckedOut = this.translationsCheckedOut.size() > 0;
}
/**
* Force the the lang of the new pivot translation for the new edition and skip the first step
*/
public void skipFirstStep(ActionEvent event)
{
skipFirstStep = true;
// Get the lang of the new
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String lang = params.get("lang");
// test if the parameter is valid
ParameterCheck.mandatoryString("The lang of the node", lang);
// set the current mlContainer
setMLContainer();
setStartingItem(lang.toLowerCase());
}
@Override
@@ -127,6 +159,7 @@ public class NewEditionWizard extends BaseWizardBean
// create the edition and get the reference of the new starting translation
NodeRef newPivot = editionService.createEdition(startingElement, versionProperties);
// redirect the user at the 'modify translation properties' page if desire.
if (otherProperties == true)
{
this.browseBean.setDocument(new Node(newPivot));
@@ -137,9 +170,30 @@ public class NewEditionWizard extends BaseWizardBean
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
}
skipFirstStep = false;
return outcome;
}
/**
* Returns the properties for checked out translations JSF DataModel
*
* @return JSF DataModel representing the translations checked out
*/
public DataModel getTranslationsCheckedOutDataModel()
{
return getDataModel(this.translationsCheckedOut);
}
/**
* Returns the properties for available translations JSF DataModel
*
* @return JSF DataModel representing the available translation for a new edition
*/
public DataModel getAvailableTranslationsDataModel()
{
return getDataModel(this.selectableTranslations);
}
/**
* Determines whether there are any translation checked out.
@@ -148,8 +202,6 @@ public class NewEditionWizard extends BaseWizardBean
*/
public boolean getHasTranslationCheckedOut()
{
hasTranslationCheckedOut = getTranslationCheckedOut().size() > 0;
return hasTranslationCheckedOut;
}
@@ -165,117 +217,94 @@ public class NewEditionWizard extends BaseWizardBean
return super.getNextButtonDisabled() || hasTranslationCheckedOut;
}
/**
* @param language of the starting translation to set as the new pivot of the new edition
*/
private void setStartingItem(String language)
{
// get the starting point translation with its locale
startingElement = multilingualContentService.getTranslationForLocale(mlContainerToVersion, I18NUtil.parseLocale(language));
// set the futur properties of the new starting element (only usefull for the summary step)
setLanguage(language);
setTitle((String) nodeService.getProperty(startingElement, ContentModel.PROP_TITLE));
setAuthor((String) nodeService.getProperty(startingElement, ContentModel.PROP_AUTHOR));
}
/**
* Return the list of cecked out document found in the mlContainer.
*
* @return the list of checked out translation
* Util metho which construct a data model with rows passed in parameter
*/
public List<SelectItem> getTranslationCheckedOut()
private DataModel getDataModel(Object rows)
{
if(translationCheckedOut == null )
DataModel translationDataModel = new ListDataModel();
translationDataModel.setWrappedData(rows);
return translationDataModel;
}
/**
* Util method which init the lists of translations
*/
private void initTranslationList()
{
this.translationsCheckedOut = new ArrayList<TranslationWrapper>();
this.selectableTranslations = new ArrayList<TranslationWrapper>();
// get all translations of the mlContainer
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(mlContainerToVersion);
// fill the data table rows list
for(Map.Entry<Locale, NodeRef> entry : translations.entrySet())
{
// first call, init the list
NodeRef nodeRef = entry.getValue();
this.translationCheckedOut = new ArrayList<SelectItem>();
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
String langCode = ((Locale) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCALE)).getLanguage();
String langText = contentFilterLanguagesService.getLabelByCode(langCode);
String lockOwner = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_OWNER);
// get all translations of the mlContainer
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(mlContainerToVersion);
// create the row with the current translation
TranslationWrapper wrapper = new TranslationWrapper(name, langCode, lockOwner, langText);
// fill the select itms
for(Map.Entry<Locale, NodeRef> entry : translations.entrySet())
if(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
NodeRef nodeRef = entry.getValue();
if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE))
// add it to the selectable list if it is not empty
this.selectableTranslations.add(wrapper);
}
if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE))
{
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
if (lockStatus != LockStatus.NO_LOCK)
{
LockStatus lockStatus = lockService.getLockStatus(nodeRef);
if (lockStatus != LockStatus.NO_LOCK)
{
// if the node is locked, add it to the locked translation list
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
Locale lang = (Locale) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCALE);
String lockOwner = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_WORKING_COPY_OWNER);
this.translationCheckedOut.add(new SelectItem(
"(" + lang.getLanguage() + ")",
name,
lockOwner
));
}
// if the node is locked, add it to the locked translation list
this.translationsCheckedOut.add(wrapper);
}
}
}
return this.translationCheckedOut;
}
}
/**
* Return the list of available translations to begin the starting translations of the new edition.
*
* @return the list of available translations
*/
public List<SelectItem> getSelectableTranslations()
private void setMLContainer()
{
if(selectableTranslations == null)
// set the mlContainer to version
NodeRef currentNodeRef = this.browseBean.getDocument().getNodeRef();
if(ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(currentNodeRef)))
{
// first call, init the list
selectableTranslations = new ArrayList<SelectItem>();
// get all translations of the mlContainer
Map<Locale, NodeRef> translations = multilingualContentService.getTranslations(mlContainerToVersion);
// fill the select items
for(Map.Entry<Locale, NodeRef> entry : translations.entrySet())
{
NodeRef nodeRef = entry.getValue();
//add each non empty translation
if(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION))
{
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
Locale lang = (Locale) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCALE);
selectableTranslations.add(new SelectItem(
nodeRef.toString(),
name + " - " + contentFilterLanguagesService.getLabelByCode(lang.getLanguage())
));
}
}
mlContainerToVersion = currentNodeRef;
}
else
{
mlContainerToVersion = multilingualContentService.getTranslationContainer(currentNodeRef);
}
return selectableTranslations;
}
/**
* @param multilingualContentService the Multilingual Content Service to set
*/
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
{
this.multilingualContentService = multilingualContentService;
}
/**
* @param nodeService the Node Service to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param editionService the Edition Service to set
*/
public void setEditionService(EditionService editionService)
{
this.editionService = editionService;
if(!skipFirstStep)
{
// init the pivot language (it will be selected by default)
selectedLanguage = ((Locale) nodeService.getProperty(mlContainerToVersion, ContentModel.PROP_LOCALE)).getLanguage();
}
}
/**
@@ -326,49 +355,6 @@ public class NewEditionWizard extends BaseWizardBean
this.otherProperties = otherProperties;
}
/**
* @return the starting translation being the new pivot of tne new edition
*/
public String getStartingItemNodeString()
{
return startingItemNodeString;
}
/**
* @param startingItemNodeString the starting translation to set as the new pivot of tne new edition
*/
public void setStartingItemNodeString(String startingItemNodeString)
{
// get the starting point translation with its id
startingElement = new NodeRef(startingItemNodeString);
// set the futur properties of the new starting element (only usefull for the summary step)
setLanguage((Locale) nodeService.getProperty(startingElement, ContentModel.PROP_LOCALE));
setAuthor((String) nodeService.getProperty(startingElement, ContentModel.PROP_AUTHOR));
setTitle((String) nodeService.getProperty(startingElement, ContentModel.PROP_TITLE));
this.startingItemNodeString = startingItemNodeString;
}
/**
* @param contentFilterLanguagesService the Content Filter Languages Service to set
*/
public void setContentFilterLanguagesService(ContentFilterLanguagesService contentFilterLanguagesService)
{
this.contentFilterLanguagesService = contentFilterLanguagesService;
}
/**
* @param lockService the Lock Service to set
*/
public void setLockService(LockService lockService)
{
this.lockService = lockService;
}
/**
* @return the author
*/
@@ -378,21 +364,12 @@ public class NewEditionWizard extends BaseWizardBean
}
/**
* @param author the author to set
*/
public void setAuthor(String author)
{
this.author = author;
}
/**
* @return the language
*/
public String getLanguage()
{
return language;
return contentFilterLanguagesService.getLabelByCode(language);
}
@@ -429,19 +406,170 @@ public class NewEditionWizard extends BaseWizardBean
this.title = title;
}
/**
* @param author the author to set
*/
public void setAuthor(String author)
{
this.author = author;
}
/**
* @return the versionLabel
*/
public String getVersionLabel()
{
String toReturn = "Version Label";
String label = versionService.getCurrentVersion(mlContainerToVersion).getVersionLabel();
String nextLabel = null;
try
{
int dotPosition = label.indexOf('.');
int major = Integer.parseInt(label.substring(0, dotPosition));
int minor = Integer.parseInt(label.substring(dotPosition + 1));
if(minorChange)
{
nextLabel = major + "." + (minor + 1);
}
else
{
nextLabel = (major + 1) + ".0";
}
}
catch(Exception e)
{
nextLabel = "";
}
if(minorChange)
{
toReturn += " (minor change)";
String minorString = Application.getMessage(
FacesContext.getCurrentInstance(),
ID_MESSAGE_MINOR_CHANGE);
return nextLabel + " (" + minorString + ')' ;
}
else
{
return nextLabel;
}
}
/**
* @return the selectedTranslationLanguage
*/
public String getSelectedTranslationLanguage()
{
return selectedLanguage;
}
/**
* @param selectedTranslationLanguage the selectedTranslationLanguage to set
*/
public void setSelectedTranslationLanguage(String language)
{
// only the selected language is not set as null
if(language != null)
{
setStartingItem(language);
}
return toReturn;
}
/**
* @param multilingualContentService the Multilingual Content Service to set
*/
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
{
this.multilingualContentService = multilingualContentService;
}
/**
* @param nodeService the Node Service to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param contentFilterLanguagesService the Content Filter Languages Service to set
*/
public void setContentFilterLanguagesService(ContentFilterLanguagesService contentFilterLanguagesService)
{
this.contentFilterLanguagesService = contentFilterLanguagesService;
}
/**
* @param lockService the Lock Service to set
*/
public void setLockService(LockService lockService)
{
this.lockService = lockService;
}
/**
* @param editionService the Edition Service to set
*/
public void setEditionService(EditionService editionService)
{
this.editionService = editionService;
}
/**
* @param versionService the version Service to set
*/
public void setVersionService(VersionService versionService)
{
this.versionService = versionService;
}
/**
* Simple wrapper class to represent a translation in the data table
*/
public static class TranslationWrapper
{
private String language;
private String name;
private String checkedOutBy;
private String languageLabel;
public TranslationWrapper(String name, String language, String checkedOutBy, String languageLabel)
{
this.name = name;
this.language = language;
this.checkedOutBy = checkedOutBy;
this.languageLabel = languageLabel;
}
public String getCheckedOutBy()
{
return checkedOutBy;
}
public String getLanguage()
{
return language;
}
public String getName()
{
return name;
}
public String getLanguageLabel()
{
return this.languageLabel;
}
}
}

View File

@@ -2200,4 +2200,53 @@
</attribute>
</tag>
<!-- param -->
<!-- IMPORTANT NOTE: this is copied from the MyFaces tld definition so the ID attribute can use rtexprvalue=true -->
<tag>
<name>param</name>
<tag-class>org.apache.myfaces.taglib.core.ParamTag</tag-class>
<body-content>JSP</body-content>
<description>
Add a child UIParameter component to the UIComponent
associated with the closed parent UIComponent custom action.
</description>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<description>
Value binding expression to a backing bean property
bound to the component instance for the UIComponent
created by this custom action.
</description>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
Component identifier of the UIParameter component to be created.
</description>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
Name of the parameter to be created.
</description>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>Value of the parameter to be set.</description>
</attribute>
</tag>
</taglib>

View File

@@ -281,6 +281,10 @@
<property-name>userPreferencesBean</property-name>
<value>#{UserPreferencesBean}</value>
</managed-property>
<managed-property>
<property-name>multilingualContentService</property-name>
<value>#{MultilingualContentService}</value>
</managed-property>
</managed-bean>
<managed-bean>
@@ -775,6 +779,10 @@
<property-name>namespaceService</property-name>
<value>#{NamespaceService}</value>
</managed-property>
<managed-property>
<property-name>multilingualContentService</property-name>
<value>#{MultilingualContentService}</value>
</managed-property>
</managed-bean>
<managed-bean>
@@ -978,7 +986,7 @@
</managed-property>
<managed-property>
<property-name>authenticationService</property-name>
<value>#{AuthenticationService}</value>
<value>#{authenticationService}</value>
</managed-property>
<managed-property>
<property-name>permissionService</property-name>
@@ -2176,7 +2184,7 @@
<property-name>editionService</property-name>
<value>#{EditionService}</value>
</managed-property>
<managed-property>
<managed-property>
<property-name>multilingualContentService</property-name>
<value>#{MultilingualContentService}</value>
</managed-property>
@@ -2188,6 +2196,10 @@
<property-name>contentFilterLanguagesService</property-name>
<value>#{ContentFilterLanguagesService}</value>
</managed-property>
<managed-property>
<property-name>versionService</property-name>
<value>#{VersionService}</value>
</managed-property>
<managed-property>
<property-name>lockService</property-name>
<value>#{LockService}</value>
@@ -3884,4 +3896,36 @@
<value>#{AVMBrowseBean}</value>
</managed-property>
</managed-bean>
<!-- This is the bean for managing the profiles of one IG -->
<managed-bean>
<description>
The bean that backs up the view of the Versioned Properties
</description>
<managed-bean-name>VersionedDocumentDetailsBean</managed-bean-name>
<managed-bean-class>
org.alfresco.web.bean.VersionedDocumentDetailsBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>versionService</property-name>
<value>#{VersionService}</value>
</managed-property>
<managed-property>
<property-name>editionService</property-name>
<value>#{EditionService}</value>
</managed-property>
<managed-property>
<property-name>nodeService</property-name>
<value>#{NodeService}</value>
</managed-property>
<managed-property>
<property-name>multilingualContentService</property-name>
<value>#{MultilingualContentService}</value>
</managed-property>
<managed-property>
<property-name>contentFilterLanguagesService</property-name>
<value>#{ContentFilterLanguagesService}</value>
</managed-property>
</managed-bean>
</faces-config>

View File

@@ -53,6 +53,10 @@
<from-outcome>showMLContainerDetails</from-outcome>
<to-view-id>/jsp/ml/ml-container-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>showVersionedDetails</from-outcome>
<to-view-id>/jsp/dialog/versioned-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>showSpaceDetails</from-outcome>
<to-view-id>/jsp/dialog/space-details.jsp</to-view-id>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -337,7 +337,7 @@
<f:facet name="header">
<a:sortLink label="#{msg.language}" value="language" mode="case-insensitive" styleClass="header"/>
</f:facet>
<a:actionLink id="view-language" value="#{r.language}" href="#{r.url}" target="new" />
<h:outputText id="view-language" value="#{r.language}"/>
</a:column>
<%-- view actions --%>
@@ -346,19 +346,28 @@
<h:outputText value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" />
<%--
Start the new edition wizard from this translation
--%>
<h:outputText id="space" value=" " />
<a:actionLink id="new-edition-from" value="#{msg.new_edition}" action="wizard:newEditionFrom" actionListener="#{NewEditionWizard.skipFirstStep}" rendered="#{r.notEmpty && r.userHasRight}">
<f:param name="lang" value="#{r.language}" />
</a:actionLink>
</a:column>
<a:dataPager styleClass="pager" />
<a:dataPager styleClass="pager" id="pager-translations"/>
</a:richList>
</a:panel>
<%-- Actions - Add Translation, Add Translation with Content --%>
<div style="padding:16px">
<a:actionLink id="act-add-trans-with-c" value="#{msg.add_translation}" action="addTranslation" actionListener="#{AddTranslationDialog.start}" showLink="true" image="/images/icons/add_tranlsation.gif" />
<span style="padding-left:16px">
<a:actionLink id="act-add-trans-without-c" value="#{msg.add_translation_wc}" action="dialog:addTranslationWithoutContent" showLink="true" image="/images/icons/add_tranlsation_wc.gif" />
</span>
</div>
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write" id="evalApply">
<div style="padding:16px">
<a:actionLink id="act-add-trans-with-c" value="#{msg.add_translation}" action="addTranslation" actionListener="#{AddTranslationDialog.start}" showLink="true" image="/images/icons/add_tranlsation.gif" />
<span style="padding-left:16px">
<a:actionLink id="act-add-trans-without-c" value="#{msg.add_translation_wc}" action="dialog:addTranslationWithoutContent" showLink="true" image="/images/icons/add_tranlsation_wc.gif" />
</span>
</div>
</r:permissionEvaluator>
</a:panel>
<%-- Panel if the node has not the multilingual aspect--%>
@@ -368,7 +377,9 @@
expanded='#{DocumentDetailsBean.panels["ml-info-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<h:outputText id="no-ml-msg" value="#{msg.not_multilingual}" />
<%-- Action - Add Translation --%>
<div style="padding:16px"><a:actionLink id="act-make-multilingual" value="#{msg.make_multilingual}" action="dialog:makeMultilingual" showLink="true" image="/images/icons/make_ml.gif" /></div>
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write" id="evalApply">
<div style="padding:16px"><a:actionLink id="act-make-multilingual" value="#{msg.make_multilingual}" action="dialog:makeMultilingual" showLink="true" image="/images/icons/make_ml.gif" /></div>
</r:permissionEvaluator>
</a:panel>
<div style="padding:4px"></div>
@@ -433,11 +444,12 @@
<f:facet name="header">
<a:sortLink label="#{msg.version}" value="versionLabel" mode="case-insensitive" styleClass="header"/>
</f:facet>
<a:actionLink id="label" value="#{r.versionLabel}" href="#{r.url}" target="new" />
<a:actionLink id="label-link" value="#{r.versionLabel}" href="#{r.url}" target="new" rendered="#{r.url != null}"/>
<a:actionLink id="label-no-link" value="#{r.versionLabel}" rendered="#{r.url == null}"/>
</a:column>
<%-- Version notes columns --%>
<a:column id="col2" width="200" style="text-align:left">
<a:column id="col2" width="170" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{msg.notes}" value="notes" styleClass="header"/>
</f:facet>
@@ -467,10 +479,15 @@
<f:facet name="header">
<h:outputText value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" />
<a:actionLink id="view-version-props" value="#{msg.properties}" action="showVersionedDetails" actionListener="#{VersionedDocumentDetailsBean.setBrowsingVersion}" >
<f:param name="id" value="#{DocumentDetailsBean.document.id}" />
<f:param name="versionLabel" value="#{r.versionLabel}" />
</a:actionLink>
<h:outputText id="space" value=" " />
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" rendered="#{r.url != null}"/>
</a:column>
<a:dataPager styleClass="pager" />
<a:dataPager styleClass="pager" id="pager-version-history"/>
</a:richList>
</a:panel>
<a:panel label="#{msg.version_history}" id="no-version-history-panel" progressive="true"

View File

@@ -0,0 +1,335 @@
<%--
* Copyright (C) 2005-2007 Alfresco Software Limited.
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
--%>
<%@ 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="64kb" contentType="text/html;charset=UTF-8" %>
<%@ page isELIgnored="false" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<%@ page import="org.alfresco.web.app.Application" %>
<%@ page import="javax.faces.context.FacesContext" %>
<r:page titleId="title_versioned_doc_details">
<f:view>
<%
FacesContext fc = FacesContext.getCurrentInstance();
// set locale for JSF framework usage
fc.getViewRoot().setLocale(Application.getLanguage(fc));
%>
<%-- load a bundle of properties with I18N strings --%>
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
<h:form acceptcharset="UTF-8" id="versioned-document-details">
<%-- 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="#dfe6ed">
<%-- 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">
<img src="<%=request.getContextPath()%>/images/icons/details_large.gif" width=32 height=32>
</td>
<td>
<div class="mainTitle">
<h:outputText value="#{msg.versioned_details_of}" /> '<h:outputText value="#{VersionedDocumentDetailsBean.name}" />'
</div>
<div class="mainSubText">
<h:outputText value="#{msg.version}" />: <h:outputText value="#{VersionedDocumentDetailsBean.version.versionLabel}" />'
</div>
<div class="mainSubText"><h:outputText id="doc-details" value="#{msg.versioned_documentdetails_description}" /></div>
</td>
<%-- Navigation --%>
<td align=right>
<a:actionLink id="act-prev" value="#{msg.previous_item}" image="/images/icons/nav_prev.gif" showLink="false" actionListener="#{VersionedDocumentDetailsBean.previousItem}" action="showVersionedDetails"/>
<img src="<%=request.getContextPath()%>/images/icons/nav_file.gif" width=24 height=24 align=absmiddle>
<a:actionLink id="act-next" value="#{msg.next_item}" image="/images/icons/nav_next.gif" showLink="false" actionListener="#{VersionedDocumentDetailsBean.nextItem}" action="showVersionedDetails"/>
</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>
<%-- 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 --%>
<a:errors message="" infoClass="statusWarningText" errorClass="statusErrorText" />
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width=4></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">
<h:panelGroup id="props-panel-facets">
<f:facet name="title"/>
</h:panelGroup>
<a:panel label="#{msg.properties}" id="properties-panel" facetsId="props-panel-facets" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
expanded="true">
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td width=80 align=center>
<%-- icon image for the doc --%>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td>
<div style="border: thin solid #CCCCCC; padding:4px">
<a:actionLink id="doc-logo1-not-empty" value="#{VersionedDocumentDetailsBean.name}" href="#{VersionedDocumentDetailsBean.url}" target="new" image="#{VersionedDocumentDetailsBean.fileType32}" showLink="false" rendered="#{VersionedDocumentDetailsBean.emptyTranslation == false}"/>
<h:graphicImage id="doc-logo1-empty" value="#{VersionedDocumentDetailsBean.fileType32}" rendered="#{VersionedDocumentDetailsBean.emptyTranslation == true}"/>
</div>
</td>
<td><img src="<%=request.getContextPath()%>/images/parts/rightSideShadow42.gif" width=6 height=42></td>
</tr>
<tr>
<td colspan=2><img src="<%=request.getContextPath()%>/images/parts/bottomShadow42.gif" width=48 height=5></td>
</tr>
</table>
</td>
<td>
<%-- properties for the doc --%>
<r:propertySheetGrid id="document-props" value="#{VersionedDocumentDetailsBean.frozenStateDocument}" var="documentProps"
columns="1" mode="view" labelStyleClass="propertiesLabel"
externalConfig="true" />
<h:message id="msg1" for="document-props" styleClass="statusMessage" />
</td>
</tr>
</table>
</a:panel>
<div style="padding:4px"></div>
<%-- Multilingual properties --%>
<h:panelGroup id="ml-props-panel-facets">
<f:facet name="title"/>
</h:panelGroup>
<%-- Panel if the node has the multilingual aspect--%>
<a:panel label="#{msg.ml_content_info}" facetsId="ml-props-panel-facets" id="ml-info-panel" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white" rendered="#{VersionedDocumentDetailsBean.fromPreviousEditon}"
expanded='true' >
<%-- properties for Ml container --%>
<div style="padding:4px"></div>
<h:outputText value="#{msg.properties}" styleClass="nodeWorkflowInfoTitle" style="padding:20px;"/>
<div style="padding:4px"></div>
<r:propertySheetGrid id="ml-container-props-sheet" value="#{VersionedDocumentDetailsBean.multilingualContainerDocument}"
var="mlContainerProps" columns="1" labelStyleClass="propertiesLabel"
externalConfig="true" cellpadding="2" cellspacing="2" mode="view"/>
<div style="padding:8px"></div>
<a:panel label="#{msg.related_translations}" id="related-translation-panel" progressive="true" expanded='false' >
<div style="padding:4px"></div>
<%-- list of translations --%>
<a:richList id="TranslationList" viewMode="details" value="#{VersionedDocumentDetailsBean.translations}"
var="r" styleClass="recordSet" headerStyleClass="recordSetHeader"
rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
pageSize="10" initialSortColumn="Name" initialSortDescending="false">
<%-- Name and icon columns --%>
<a:column id="col21" primary="true" width="300" style="text-align:left">
<f:facet name="small-icon">
<h:graphicImage url="/images/filetypes/_default.gif" width="16" height="16"/>
</f:facet>
<f:facet name="header">
<a:sortLink label="#{msg.name}" value="Name" mode="case-insensitive" styleClass="header"/>
</f:facet>
<a:actionLink id="view-name" value="#{r.name}" href="#{r.url}" target="new" />
</a:column>
<%-- Language columns --%>
<a:column id="col22" width="50" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{msg.language}" value="language" mode="case-insensitive" styleClass="header"/>
</f:facet>
<h:outputText id="view-language" value="#{r.language}"/>
</a:column>
<%-- view actions --%>
<a:column id="col25" style="text-align: left">
<f:facet name="header">
<h:outputText value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" />
</a:column>
<a:dataPager styleClass="pager" />
</a:richList>
</a:panel>
</a:panel>
<div style="padding:4px"></div>
<a:panel label="#{msg.version_history}" id="version-history-panel" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white" rendered="#{VersionedDocumentDetailsBean.fromPreviousEditon}"
expanded="true">
<a:richList id="versionHistoryList" viewMode="details" value="#{VersionedDocumentDetailsBean.versionHistory}"
var="r" styleClass="recordSet" headerStyleClass="recordSetHeader"
rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
pageSize="10" initialSortColumn="versionLabel" initialSortDescending="false">
<%-- Primary column for details view mode --%>
<a:column id="col1" primary="true" width="100" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink label="#{msg.version}" value="versionLabel" mode="case-insensitive" styleClass="header"/>
</f:facet>
<a:actionLink id="label-link" value="#{r.versionLabel}" href="#{r.url}" target="new" rendered="#{r.url != null}"/>
<a:actionLink id="label-no-link" value="#{r.versionLabel}" rendered="#{r.url == null}"/>
</a:column>
<%-- Version notes columns --%>
<a:column id="col2" width="170" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{msg.notes}" value="notes" styleClass="header"/>
</f:facet>
<h:outputText id="notes" value="#{r.notes}" />
</a:column>
<%-- Description columns --%>
<a:column id="col3" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{msg.author}" value="author" styleClass="header"/>
</f:facet>
<h:outputText id="author" value="#{r.author}" />
</a:column>
<%-- Created Date column for details view mode --%>
<a:column id="col4" style="text-align:left; white-space:nowrap">
<f:facet name="header">
<a:sortLink label="#{msg.date}" value="versionDate" styleClass="header"/>
</f:facet>
<h:outputText id="date" value="#{r.versionDate}">
<a:convertXMLDate type="both" pattern="#{msg.date_time_pattern}" />
</h:outputText>
</a:column>
<%-- view the contents of the specific version --%>
<a:column id="col5" style="text-align: left">
<f:facet name="header">
<h:outputText value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="view-version-props" value="#{msg.properties}" actionListener="#{VersionedDocumentDetailsBean.nextItem}" action="showVersionedDetails">
<f:param name="versionLabel" value="#{r.versionLabel}" />
</a:actionLink>
<h:outputText id="space" value=" " />
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" rendered="#{r.url != null}"/>
</a:column>
<a:dataPager styleClass="pager" />
</a:richList> </a:panel>
</td>
<td valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "greyround", "#F5F5F5"); %>
<table cellpadding="1" cellspacing="1" border="0" width="100%">
<tr>
<td align="center">
<h:commandButton id="close-btn-mlc-details" value="#{msg.close}" action="showMLContainerDetails" styleClass="wizardButton" rendered="#{VersionedDocumentDetailsBean.fromPreviousEditon == true}" />
<h:commandButton id="close-btn-doc-details" value="#{msg.close}" action="showDocDetails" styleClass="wizardButton" rendered="#{VersionedDocumentDetailsBean.fromPreviousEditon == false}" />
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "greyround"); %>
<div style="padding:4px"></div>
</td>
</tr>
</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

@@ -31,13 +31,8 @@
<h:outputText value="#{msg.properties}" escape="false" />
</h:panelGrid>
<h:panelGrid columns="3" cellpadding="3" cellspacing="3" border="0">
<h:graphicImage value="/images/icons/required_field.gif" alt="#{msg.required_field}" />
<h:outputText value="#{msg.name}:"/>
<h:inputText id="name" value="#{DialogManager.bean.name}" maxlength="1024" size="35" immediate="false" onkeyup="checkButtonState();" onchange="checkButtonState();"/>
<h:graphicImage/>
<h:outputText value="#{msg.title}:"/>
<h:inputText id="title" value="#{DialogManager.bean.title}" maxlength="1024" size="35" immediate="false"/>
@@ -58,15 +53,21 @@
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="1" cellpadding="2" style="padding-top: 4px; padding-bottom: 4px;" width="100%" rowClasses="wizardSectionHeading">
<h:outputText value="#{msg.other_properties}" escape="false" />
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="3" cellspacing="3" border="0">
<h:selectBooleanCheckbox value="#{DialogManager.bean.showOtherProperties}" />
<h:outputText id="text10" value="#{msg.modify_props_when_page_closes}" />
</h:panelGrid>
<script type="text/javascript">
function checkButtonState()
{
if (document.getElementById("dialog:dialog-body:name").value.length == 0 ||
document.getElementById("dialog:dialog-body:author").value.length == 0 ||
if (document.getElementById("dialog:dialog-body:author").value.length == 0 ||
document.getElementById("dialog:dialog-body:language").selectedIndex == 0 )
{
document.getElementById("dialog:finish-button").disabled = true;

View File

@@ -32,14 +32,14 @@
<%@ page isELIgnored="false" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<r:page titleId="title_file_details">
<r:page titleId="title_mlcontainer_details">
<f:view>
<%-- load a bundle of properties with I18N strings --%>
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
<h:form acceptcharset="UTF-8" id="document-details">
<h:form acceptcharset="UTF-8" id="ml-container-details">
<%-- Main outer table --%>
<table cellspacing="0" cellpadding="2">
@@ -129,7 +129,7 @@
<%-- properties for Ml container --%>
<h:panelGroup id="ml-props-panel-facets">
<f:facet name="title">
<r:permissionEvaluator value="#{DocumentDetailsBean.documentMlContainer}" allow="Write">
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Write">
<a:actionLink id="titleLinkMl" value="#{msg.modify}" showLink="false" image="/images/icons/edit_properties.gif"
action="dialog:editMlContainer" />
</r:permissionEvaluator>
@@ -141,18 +141,18 @@
expanded='#{DocumentDetailsBean.panels["ml-properties-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<h:outputText styleClass="nodeWorkflowInfoTitle"/>
<r:propertySheetGrid id="ml-container-props-sheet" value="#{DocumentDetailsBean.documentMlContainer}"
var="mlContainerProps" columns="1" labelStyleClass="propertiesLabel"
externalConfig="true" cellpadding="2" cellspacing="2" mode="view"/>
<h:outputText styleClass="nodeWorkflowInfoTitle"/>
<r:propertySheetGrid id="ml-container-props-sheet" value="#{DocumentDetailsBean.document}"
var="mlContainerProps" columns="1" labelStyleClass="propertiesLabel"
externalConfig="true" cellpadding="2" cellspacing="2" mode="view"/>
</a:panel>
<div style="padding:4px"></div>
<%-- list of translations --%>
<a:panel label="#{msg.translations}" id="ml-translation-panel" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
expanded='#{DocumentDetailsBean.panels["ml-translation-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
expanded='#{DocumentDetailsBean.panels["ml-translation-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<a:richList id="TranslationList" viewMode="details" value="#{DocumentDetailsBean.translations}"
var="r" styleClass="recordSet" headerStyleClass="recordSetHeader"
@@ -189,6 +189,13 @@
<h:outputText value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="view-link" value="#{msg.view}" href="#{r.url}" target="new" />
<%--
Start the new edition wizard from this translation
--%>
<h:outputText id="space" value=" " />
<a:actionLink id="new-edition-from" value="#{msg.new_edition}" action="wizard:newEditionFrom" actionListener="#{NewEditionWizard.skipFirstStep}" rendered="#{r.notEmpty && r.userHasRight}">
<f:param name="lang" value="#{r.language}" />
</a:actionLink>
</a:column>
<a:dataPager styleClass="pager" />
@@ -201,7 +208,7 @@
Editions details
--%>
<a:panel label="#{msg.editions}" id="ml-editions-panel" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
expanded='#{DocumentDetailsBean.panels["ml-editions-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<a:richList id="EditionTitle" viewMode="details" value="#{DocumentDetailsBean.emptyListAndInitEditions}"
@@ -275,7 +282,7 @@
<%-- edition date --%>
<a:column id="column-edition-date${idx}" style="text-align:left; white-space:nowrap">
<a:outputText id="edition-date${idx}" value="#{ed.editionDate}">
<a:convertXMLDate type="both" pattern="#{msg.date_pattern}" />
<a:convertXMLDate type="both" pattern="#{msg.date_pattern}" />
</a:outputText>
</a:column>
</a:richList>
@@ -283,35 +290,35 @@
<div style="padding-left:25">
<a:panel label="#{msg.related_content}" id="ml-versions-panel${idx}" progressive="true" expanded="false"
expandedActionListener="#{DocumentDetailsBean.expandPanel}" styleClass="nodeWorkflowInfoTitle" >
expandedActionListener="#{DocumentDetailsBean.expandPanel}" styleClass="nodeWorkflowInfoTitle" >
<a:richList id="ml-versions-list${idx}" viewMode="details" value="#{DocumentDetailsBean.currentSingleEditionBean.translations}"
var="tr" styleClass="recordSet" headerStyleClass="recordSetHeader"
rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
pageSize="10" initialSortColumn="versionName" initialSortDescending="true" style="padding-left:12px;padding-top:10px;">
var="tr" styleClass="recordSet" headerStyleClass="recordSetHeader"
rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
pageSize="10" initialSortColumn="versionName" initialSortDescending="true" style="padding-left:12px;padding-top:10px;">
<%-- Icon details view mode --%>
<%-- Icon details view mode --%>
<a:column id="column-view-mode${idx}" primary="true" width="20" style="padding:2px;">
<a:graphicImageExprEnable id="translation-image${idx}" url="/images/filetypes/_default.gif" />
</a:column>
<%-- Versionned name --%>
<%-- Versioned name --%>
<a:column id="column-name${idx}" width="100" style="text-align:left">
<f:facet name="header">
<a:sortLink id="sort-name${idx}" label="#{msg.name}" value="versionName" mode="case-insensitive" styleClass="header"/>
</f:facet>
<a:outputText id="translation-name${idx}" value="#{tr.versionName}"/>
<a:actionLink id="translation-name${idx}" value="#{tr.versionName}" href="#{tr.versionUrl}" target="new" />
</a:column>
<%-- Versionned description --%>
<a:column id="column-description${idx}" width="200" style="text-align:left">
<%-- Versioned description --%>
<a:column id="column-description${idx}" width="170" style="text-align:left">
<f:facet name="header">
<a:outputText id="desc-title${idx}" value="#{msg.description}" styleClass="header"/>
</f:facet>
<a:outputText id="translation-description${idx}" value="#{tr.versionDescription}" />
</a:column>
<%-- Versionned creation date --%>
<%-- Versioned creation date --%>
<a:column id="column-creation-date${idx}" style="text-align:left; white-space:nowrap">
<f:facet name="header">
<a:sortLink id="sort-cr-date${idx}" label="#{msg.created}" value="versionCreatedDate" mode="case-insensitive" styleClass="header"/>
@@ -321,7 +328,7 @@
</a:outputText>
</a:column>
<%-- Versionned modified date --%>
<%-- Versioned modified date --%>
<a:column id="column-modified-date${idx}" style="text-align:left; white-space:nowrap">
<f:facet name="header">
<a:sortLink id="sort-mod-date${idx}" label="#{msg.modified}" value="versionModifiedDate" mode="case-insensitive" styleClass="header"/>
@@ -331,7 +338,7 @@
</a:outputText>
</a:column>
<%-- Versionned language --%>
<%-- Versioned language --%>
<a:column id="column-language${idx}" style="text-align:left">
<f:facet name="header">
<a:sortLink id="sort-lang${idx}" label="#{msg.language}" value="versionLanguage" mode="case-insensitive" styleClass="header"/>
@@ -344,7 +351,11 @@
<f:facet name="header">
<a:outputText id="translation-action${idx}" value="#{msg.actions}"/>
</f:facet>
<a:actionLink id="translation-link${idx}" value="#{msg.view}" href="#{tr.versionUrl}" target="new" />
<a:actionLink image="/images/icons/versioned_properties.gif" id="view-version-props${idx}" value="#{msg.properties}" showLink="false" action="showVersionedDetails" actionListener="#{VersionedDocumentDetailsBean.setBrowsingVersion}" >
<a:param id="param-id${idx}" name="id" value="#{DocumentDetailsBean.document.id}" />
<a:param id="param-vl${idx}" name="versionLabel" value="#{ed.editionLabel}" />
<a:param id="param-lg${idx}" name="lang" value="#{tr.versionLanguage}" />
</a:actionLink>
</a:column>
</a:richList>
</a:panel>
@@ -357,7 +368,7 @@
<table cellpadding="1" cellspacing="1" border="0" width="100%">
<tr>
<td align="center">
<h:commandButton id="close-btn" value="#{msg.close}" action="dialog:close" styleClass="wizardButton" />
<h:commandButton id="close-btn" value="#{msg.close}" actionListener="#{DocumentDetailsBean.resetMLDocument}" action="dialog:close" styleClass="wizardButton" />
</td>
</tr>
</table>

View File

@@ -45,10 +45,77 @@
</f:verbatim>
</h:panelGroup>
<h:panelGrid columns="1" styleClass="workflowSelection" rendered="#{WizardManager.bean.hasTranslationCheckedOut == false}">
<h:outputText value="#{msg.available_translations}:" style="font-weight:bold;"/>
<h:selectOneRadio id="selected-translations" value="#{WizardManager.bean.startingItemNodeString}"
layout="pageDirection">
<f:selectItems value="#{WizardManager.bean.selectableTranslations}" />
</h:selectOneRadio>
<h:panelGrid rendered="#{WizardManager.bean.hasTranslationCheckedOut == true}" style="padding-top:7px;">
<div style="padding:4px"/>
<h:dataTable value="#{WizardManager.bean.translationsCheckedOutDataModel}" var="row"
rowClasses="selectedItemsRow,selectedItemsRowAlt"
styleClass="selectedItems" headerClass="selectedItemsHeader"
cellspacing="0" cellpadding="4">
<h:column>
<f:facet name="header">
<h:outputText value="#{msg.language}" />
</f:facet>
<h:outputText value="(#{row.language})" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg.doc_name}" />
</f:facet>
<h:outputText value="#{row.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg.checked_out_by}" />
</f:facet>
<h:outputText value="#{row.checkedOutBy}" />
</h:column>
</h:dataTable>
</h:panelGrid>
<h:panelGrid columns="1" rendered="#{WizardManager.bean.hasTranslationCheckedOut == false}">
<h:dataTable value="#{WizardManager.bean.availableTranslationsDataModel}" var="row"
rowClasses="selectedItemsRow,selectedItemsRowAlt"
styleClass="selectedItems" headerClass="selectedItemsHeader"
cellspacing="0" cellpadding="4">
<h:column>
<f:facet name="header">
<h:outputText value=" " />
</f:facet>
<h:selectOneRadio value="#{WizardManager.bean.selectedTranslationLanguage}" onchange="dataTableSelectOneRadio(this);">
<f:selectItem itemValue="#{row.language}" itemLabel=""/>
</h:selectOneRadio>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg.doc_name}" />
</f:facet>
<h:outputText value="#{row.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg.language}" />
</f:facet>
<h:outputText value="#{row.languageLabel}" />
</h:column>
</h:dataTable>
</h:panelGrid>
<script type="text/javascript">
function dataTableSelectOneRadio(radio)
{
var id = radio.name.substring(radio.name.lastIndexOf(':'));
var el = radio.form.elements;
for (var i = 0; i < el.length; i++) {
if (el[i].name.substring(el[i].name.lastIndexOf(':')) == id) {
el[i].checked = false;
}
}
radio.checked = true;
}
</script>

View File

@@ -32,7 +32,7 @@
</h:panelGrid>
<h:panelGrid style="padding-top: 2px;" columns="1">
<h:outputText value="#{msg.edition_notes}" />
<h:outputText value="#{msg.edition_notes}" />
<h:inputTextarea value="#{WizardManager.bean.editionNotes}" rows="2" cols="50"/>
</h:panelGrid>
@@ -48,6 +48,6 @@
</h:panelGrid>
<h:panelGrid style="padding-top: 2px;" columns="2">
<h:selectBooleanCheckbox id="add_translation" value="#{WizardManager.bean.otherProperties}" immediate="false"/>
<h:selectBooleanCheckbox id="other_props" value="#{WizardManager.bean.otherProperties}" immediate="false"/>
<h:outputText value="#{msg.modify_translation_properties}" />
</h:panelGrid>