mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -15,11 +15,11 @@
|
||||
* 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:
|
||||
* 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;
|
||||
@@ -31,36 +31,58 @@ 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;
|
||||
|
||||
/**
|
||||
* Evaluates whether the Add Translation (with or without content) action should be visible.
|
||||
*
|
||||
* If the node is not already Multilingual, locked, or if a translation exists for each available
|
||||
* Evaluates whether the Add Translation (with or without content) action should be visible.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,35 +15,50 @@
|
||||
* 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:
|
||||
* 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.model.ContentModel;
|
||||
import org.alfresco.web.action.ActionEvaluator;
|
||||
import org.alfresco.web.bean.ml.MultilingualUtils;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Evaluates whether the Cut Node action should be visible.
|
||||
*
|
||||
* Among all available operations over non-multilingual documents (i.e. copy,
|
||||
* delete, start discussion, etc), there is a missing one: <b>Move</b>.
|
||||
* Translations cannot be moved due to the exiting link it has with the logical
|
||||
* document. Despite it is technically achievable, it could be functionally
|
||||
* troublesome. Spreading translations of the same semantic message among several
|
||||
* Evaluates whether the Cut Node action should be visible.
|
||||
*
|
||||
* Among all available operations over non-multilingual documents (i.e. copy,
|
||||
* delete, start discussion, etc), there is a missing one: <b>Move</b>.
|
||||
* Translations cannot be moved due to the exiting link it has with the logical
|
||||
* document. Despite it is technically achievable, it could be functionally
|
||||
* 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.
|
||||
@@ -53,9 +68,9 @@ public class CutNodeEvaluator implements ActionEvaluator
|
||||
}
|
||||
else
|
||||
{
|
||||
eval = !node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
eval = !node.getAspects().contains(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||
}
|
||||
|
||||
return eval;
|
||||
|
||||
return eval;
|
||||
}
|
||||
}
|
||||
|
@@ -15,11 +15,11 @@
|
||||
* 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:
|
||||
* 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;
|
||||
@@ -30,11 +30,12 @@ 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;
|
||||
|
||||
/**
|
||||
* UI Action Evaluator - Delete document.
|
||||
*
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DeleteDocEvaluator implements ActionEvaluator
|
||||
@@ -44,14 +45,20 @@ 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 mlservice =
|
||||
(MultilingualContentService) FacesHelper.getManagedBean(fc, "MultilingualContentService");
|
||||
|
||||
// if the translation is the last translation, user can delete it
|
||||
@@ -67,7 +74,7 @@ public class DeleteDocEvaluator implements ActionEvaluator
|
||||
}
|
||||
// finally, the node is not the pivot translation, user can delete it
|
||||
}
|
||||
|
||||
|
||||
return (node.isLocked() == false &&
|
||||
node.hasAspect(ContentModel.ASPECT_WORKING_COPY) == false &&
|
||||
isPivot == false);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -213,7 +216,7 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
{
|
||||
this.navigator.setupDispatchContext(getDocument());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save the state of the panel that was expanded/collapsed
|
||||
*/
|
||||
@@ -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,102 +361,115 @@ 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
|
||||
*/
|
||||
public List getTranslations()
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -593,23 +603,23 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
|
||||
/**
|
||||
* Sets the category added from the multi value editor
|
||||
*
|
||||
*
|
||||
* @param addedCategory The added category
|
||||
*/
|
||||
public void setAddedCategory(NodeRef addedCategory)
|
||||
{
|
||||
this.addedCategory = addedCategory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the categories for the current document
|
||||
*
|
||||
*
|
||||
* @return The outcome
|
||||
*/
|
||||
public String saveCategories()
|
||||
{
|
||||
String outcome = "cancel";
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(FacesContext.getCurrentInstance());
|
||||
@@ -617,22 +627,22 @@ 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;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
|
||||
|
||||
// reset the state of the current document so it reflects the changes just made
|
||||
getDocument().reset();
|
||||
|
||||
|
||||
outcome = "finish";
|
||||
}
|
||||
catch (Throwable e)
|
||||
@@ -640,10 +650,10 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||
FacesContext.getCurrentInstance(), MSG_ERROR_UPDATE_CATEGORY), e.getMessage()), e);
|
||||
}
|
||||
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the classifiable aspect to the current document
|
||||
*/
|
||||
@@ -656,13 +666,13 @@ 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;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
|
||||
|
||||
// reset the state of the current document
|
||||
getDocument().reset();
|
||||
}
|
||||
@@ -672,7 +682,7 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_CLASSIFY), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the versionable aspect to the current document
|
||||
*/
|
||||
@@ -685,13 +695,13 @@ 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;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
|
||||
|
||||
// reset the state of the current document
|
||||
getDocument().reset();
|
||||
}
|
||||
@@ -701,14 +711,14 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
FacesContext.getCurrentInstance(), MSG_ERROR_ASPECT_VERSIONING), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action Handler to unlock a locked document
|
||||
*/
|
||||
public void unlock(final ActionEvent event)
|
||||
{
|
||||
final FacesContext fc = FacesContext.getCurrentInstance();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(FacesContext.getCurrentInstance());
|
||||
@@ -717,13 +727,13 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
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);
|
||||
|
||||
getNode().reset();
|
||||
|
||||
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();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -735,7 +745,7 @@ public class DocumentDetailsBean extends BaseDetailsBean
|
||||
fc, Repository.ERROR_GENERIC), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the inlineeditable aspect to the current document
|
||||
*/
|
||||
@@ -748,33 +758,33 @@ 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;
|
||||
}
|
||||
};
|
||||
txnHelper.doInTransaction(callback);
|
||||
|
||||
|
||||
// reset the state of the current document
|
||||
getDocument().reset();
|
||||
}
|
||||
@@ -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
|
||||
*
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -15,11 +15,11 @@
|
||||
* 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:
|
||||
* 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.clipboard;
|
||||
@@ -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;
|
||||
@@ -52,20 +53,20 @@ import org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem;
|
||||
|
||||
/**
|
||||
* Class representing a 'workspace' store protocol clipboard item
|
||||
*
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
private static final String WORKSPACE_PASTE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||
private static final String AVM_PASTE_VIEW_ID = "/jsp/wcm/browse-sandbox.jsp";
|
||||
|
||||
|
||||
private static final String MSG_LINK_TO = "link_to";
|
||||
|
||||
|
||||
// File extension to use for link nodes
|
||||
private static final String LINK_NODE_EXTENSION = ".url";
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param ref
|
||||
* @param mode
|
||||
@@ -74,7 +75,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
super(ref, mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#supportsLink()
|
||||
*/
|
||||
@@ -82,7 +83,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.bean.clipboard.ClipboardItem#canCopyToViewId(java.lang.String)
|
||||
*/
|
||||
@@ -109,28 +110,31 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
{
|
||||
NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);
|
||||
NodeRef destRef = new NodeRef(Repository.getStoreRef(), navigator.getCurrentNodeId());
|
||||
|
||||
|
||||
DictionaryService dd = getServiceRegistry().getDictionaryService();
|
||||
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
|
||||
// the clipboard operation (e.g. the source folder) is specifically that parent node.
|
||||
// So does not allow for more than one possible parent node - or for linked objects!
|
||||
// This code should be refactored to use a parent ID when appropriate.
|
||||
// This code should be refactored to use a parent ID when appropriate.
|
||||
ChildAssociationRef assocRef = nodeService.getPrimaryParent(getNodeRef());
|
||||
|
||||
|
||||
// initial name to attempt the copy of the item with
|
||||
String name = getName();
|
||||
String translationPrefix = "";
|
||||
|
||||
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
|
||||
{
|
||||
// copy as link was specifically requested by the user
|
||||
String linkTo = Application.getMessage(fc, MSG_LINK_TO);
|
||||
String linkTo = Application.getMessage(fc, MSG_LINK_TO);
|
||||
name = linkTo + ' ' + name;
|
||||
}
|
||||
|
||||
|
||||
boolean operationComplete = false;
|
||||
while (operationComplete == false)
|
||||
{
|
||||
@@ -147,7 +151,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
// LINK operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to link node ID: " + getNodeRef() + " into node: " + destRef.toString());
|
||||
|
||||
|
||||
// we create a special Link Object node that has a property to reference the original
|
||||
// create the node using the nodeService (can only use FileFolderService for content)
|
||||
if (checkExists(name + LINK_NODE_EXTENSION, destRef) == false)
|
||||
@@ -164,7 +168,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
assocRef.getQName(),
|
||||
ApplicationModel.TYPE_FILELINK,
|
||||
props);
|
||||
|
||||
|
||||
// apply the titled aspect - title and description
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, name);
|
||||
@@ -180,7 +184,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
assocRef.getQName(),
|
||||
ApplicationModel.TYPE_FOLDERLINK,
|
||||
props);
|
||||
|
||||
|
||||
// apply the uifacets aspect - icon, title and description props
|
||||
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4, 1.0f);
|
||||
uiFacetsProps.put(ApplicationModel.PROP_ICON, "space-icon-link");
|
||||
@@ -188,7 +192,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, name);
|
||||
nodeService.addAspect(childRef.getChildRef(), ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||
}
|
||||
|
||||
|
||||
// if we get here without an exception, the clipboard link operation was successful
|
||||
operationComplete = true;
|
||||
}
|
||||
@@ -198,7 +202,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
// COPY operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
|
||||
// first check that we are not attempting to copy a duplicate into the same parent
|
||||
if (destRef.equals(assocRef.getParentRef()) && name.equals(getName()))
|
||||
{
|
||||
@@ -206,7 +210,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
String copyOf = Application.getMessage(fc, MSG_COPY_OF);
|
||||
name = copyOf + ' ' + name;
|
||||
}
|
||||
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
@@ -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
|
||||
@@ -229,7 +238,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if we get here without an exception, the clipboard copy operation was successful
|
||||
operationComplete = true;
|
||||
}
|
||||
@@ -239,7 +248,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
// MOVE operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to move node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
|
||||
if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) ||
|
||||
dd.isSubClass(getType(), ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
@@ -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
|
||||
@@ -258,7 +272,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
assocRef.getQName());
|
||||
}
|
||||
|
||||
|
||||
// if we get here without an exception, the clipboard move operation was successful
|
||||
operationComplete = true;
|
||||
}
|
||||
@@ -266,7 +280,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
catch (FileExistsException fileExistsErr)
|
||||
{
|
||||
if (getMode() != ClipboardStatus.COPY)
|
||||
{
|
||||
{
|
||||
// we should not rename an item when it is being moved - so exit
|
||||
throw fileExistsErr;
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
@@ -297,15 +312,15 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
else if (AVM_PASTE_VIEW_ID.equals(viewId))
|
||||
{
|
||||
AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME);
|
||||
|
||||
|
||||
String destPath = avmBrowseBean.getCurrentPath();
|
||||
NodeRef destRef = AVMNodeConverter.ToNodeRef(-1, destPath);
|
||||
|
||||
|
||||
CrossRepositoryCopyService crossRepoCopyService = getServiceRegistry().getCrossRepositoryCopyService();
|
||||
|
||||
|
||||
// initial name to attempt the copy of the item with
|
||||
String name = getName();
|
||||
|
||||
|
||||
boolean operationComplete = false;
|
||||
while (operationComplete == false)
|
||||
{
|
||||
@@ -320,10 +335,10 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
// COPY operation
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString());
|
||||
|
||||
|
||||
// inter-store copy operation
|
||||
crossRepoCopyService.copy(getNodeRef(), destRef, name);
|
||||
|
||||
|
||||
// if we get here without an exception, the clipboard copy operation was successful
|
||||
operationComplete = true;
|
||||
}
|
||||
@@ -336,7 +351,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
|
||||
catch (FileExistsException fileExistsErr)
|
||||
{
|
||||
if (getMode() != ClipboardStatus.COPY)
|
||||
{
|
||||
{
|
||||
// we should not rename an item when it is being moved - so exit
|
||||
throw fileExistsErr;
|
||||
}
|
||||
|
@@ -15,11 +15,11 @@
|
||||
* 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:
|
||||
* 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.content;
|
||||
@@ -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;
|
||||
@@ -37,16 +39,20 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Bean implementation for the "Delete Content" dialog
|
||||
*
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class DeleteContentDialog extends BaseDialogBean
|
||||
{
|
||||
|
||||
|
||||
protected MultilingualContentService multilingualContentService;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DeleteContentDialog.class);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
@@ -55,31 +61,43 @@ 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());
|
||||
|
||||
// delete the node
|
||||
this.nodeService.deleteNode(node.getNodeRef());
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("WARNING: delete called without a current Document!");
|
||||
}
|
||||
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String doPostCommitProcessing(FacesContext context, String outcome)
|
||||
{
|
||||
// clear action context
|
||||
this.browseBean.setDocument(null);
|
||||
|
||||
|
||||
// setting the outcome will show the browse view again
|
||||
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
|
||||
AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getErrorMessageId()
|
||||
{
|
||||
@@ -91,21 +109,51 @@ public class DeleteContentDialog extends BaseDialogBean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
/**
|
||||
* Returns the confirmation to display to the user before deleting the content.
|
||||
*
|
||||
*
|
||||
* @return The formatted message to display
|
||||
*/
|
||||
public String getConfirmMessage()
|
||||
{
|
||||
String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
|
||||
"delete_file_confirm");
|
||||
|
||||
return MessageFormat.format(fileConfirmMsg,
|
||||
new Object[] {this.browseBean.getDocument().getName()});
|
||||
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[] {document.getName()});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param multilingualContentService the Multilingual Content Service to set
|
||||
*/
|
||||
public void setMultilingualContentService(MultilingualContentService multilingualContentService)
|
||||
{
|
||||
this.multilingualContentService = multilingualContentService;
|
||||
}
|
||||
}
|
||||
|
@@ -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.
|
||||
@@ -81,31 +77,11 @@ public class AddTranslationDialog extends AddContentDialog
|
||||
{
|
||||
// add the new file to the repository
|
||||
outcome = super.finishImpl(context, outcome);
|
||||
|
||||
|
||||
// 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
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -15,11 +15,11 @@
|
||||
* 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:
|
||||
* 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;
|
||||
@@ -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;
|
||||
@@ -38,7 +39,7 @@ import org.alfresco.web.bean.repository.Node;
|
||||
|
||||
/**
|
||||
* Dialog bean to edit an existing multilingual container.
|
||||
*
|
||||
*
|
||||
* @author Yannick Pignot
|
||||
*/
|
||||
public class EditMLContainerDialog extends BaseDialogBean
|
||||
@@ -69,7 +70,7 @@ public class EditMLContainerDialog extends BaseDialogBean
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome) throws Exception
|
||||
{
|
||||
{
|
||||
// get the container node ref
|
||||
NodeRef container = editableNode.getNodeRef();
|
||||
|
||||
@@ -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())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
154
source/java/org/alfresco/web/bean/ml/MultilingualUtils.java
Normal file
154
source/java/org/alfresco/web/bean/ml/MultilingualUtils.java
Normal 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");
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user