/**
* Copyright (C) 2008 Kodeks d.o.o (iCodix).
*
* 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 Affero 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
* or see <http://www.gnu.org/licenses/>
*
* 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 Jibe
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.jibeframework.org
*/
/**
* NASA LICENCA
*/
package org.jibeframework.contentmanager.controller.action;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.type.TypeReference;
import org.jibeframework.alfresco.node.CMFolder;
import org.jibeframework.alfresco.node.CMObject;
import org.jibeframework.alfresco.util.AlfrescoUtil;
import org.jibeframework.contentmanager.controller.State;
import org.jibeframework.contentmanager.ui.contentgrid.FolderModel;
import org.jibeframework.core.JibeRuntimeException;
import org.jibeframework.core.annotation.ConditionFunction;
import org.jibeframework.core.annotation.Progress;
import org.jibeframework.core.annotation.Remote;
import org.jibeframework.core.util.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestParam;
public class ClipboardSupport {
@Autowired
private FolderModel folderModel;
@Autowired
private State state;
@Autowired
private ServiceRegistry serviceRegistry;
private ClipboardContainer clipboard;
@ConditionFunction("isClipboardEmpty")
public boolean evaluateClipboardManager() {
return clipboard == null || clipboard.isEmpty();
}
@Progress("progress.repo.copyDnD")
@Remote
public void dndCopy(@RequestParam("targetNode") NodeRef targetNode, @RequestParam("copiedNodes") String copiedNodes)
throws FileExistsException, FileNotFoundException {
if (copiedNodes != null) {
List<String> sr = JacksonUtil.fromJson(copiedNodes, new TypeReference<List<String>>() {
});
for (String copiedNr : sr) {
serviceRegistry.getFileFolderService().copy(new NodeRef(copiedNr), targetNode, null);
}
}
}
@Progress("progress.repo.moveDnD")
@Remote
public void dndMove(@RequestParam("targetNode") NodeRef targetNode, @RequestParam("movedNode") String movedNode,
@RequestParam("movedNodes") String movedNodes) throws FileNotFoundException {
List<String> targetPath = getPath(targetNode, null);
List<String> childrenNames = new ArrayList<String>();
List<FileInfo> fis = serviceRegistry.getFileFolderService().list(targetNode);
for (FileInfo fi : fis) {
childrenNames.add(fi.getName());
}
if (!StringUtils.isEmpty(movedNode)) {
moveNode(targetNode, targetPath, childrenNames, new NodeRef(movedNode));
// response.put("targetPath", getPath(targetNode,
// ContentModel.PROP_NAME));
} else {
// mutiple nodes move
NodeRef parentNodeId = null;
List<String> mnList = JacksonUtil.fromJson(movedNodes, new TypeReference<List<String>>() {
});
for (String nodeId : mnList) {
NodeRef nodeToMove = new NodeRef(nodeId);
if (parentNodeId == null) {
// cache parent ref
parentNodeId = serviceRegistry.getNodeService().getPrimaryParent(nodeToMove).getParentRef();
}
moveNode(targetNode, targetPath, childrenNames, nodeToMove);
}
// response.put("movedNodesParent", parentNodeId.toString());
}
}
private void moveNode(NodeRef targetRef, List<String> targetPath, List<String> childrenNames, NodeRef nodeRefToMove)
throws FileNotFoundException {
if (targetPath.contains(nodeRefToMove.toString())) {
throw new JibeRuntimeException(ClipboardSupport.class, "circularRef");
}
Serializable name = serviceRegistry.getNodeService().getProperty(nodeRefToMove, ContentModel.PROP_NAME);
if (childrenNames.contains(name)) {
throw new JibeRuntimeException(ClipboardSupport.class, "allreadyExists", name);
}
serviceRegistry.getFileFolderService().move(nodeRefToMove, targetRef, null);
}
private List<String> getPath(NodeRef nodeRef, QName property) {
List<String> l = new ArrayList<String>();
NodeRef companyHome = AlfrescoUtil.getInstance().getCompanyHome();
String ch = property != null ? (String) serviceRegistry.getNodeService().getProperty(companyHome, property)
: companyHome.toString();
l.add(ch);
if (!nodeRef.equals(companyHome)) {
List<FileInfo> fis = null;
try {
fis = serviceRegistry.getFileFolderService().getNamePath(companyHome, nodeRef);
} catch (Exception e) {
throw new JibeRuntimeException(e);
}
for (FileInfo fi : fis) {
String v = property != null ? (String) serviceRegistry.getNodeService().getProperty(fi.getNodeRef(),
property) : fi.getNodeRef().toString();
l.add(v);
}
}
return l;
}
@Progress("progress.repo.putToClipboard")
@Remote
public void copy(CMObject node, List<CMObject> nodes) {
if (clipboard == null) {
clipboard = new ClipboardContainer();
}
if (node != null) {
clipboard.put(state.getBrowsedFolder(), "copy", node);
} else if (nodes != null) {
clipboard.put(state.getBrowsedFolder(), "copy", nodes);
}
}
@Progress("progress.repo.putToClipboard")
@Remote
public void cut(CMObject node, List<CMObject> nodes) {
if (clipboard == null) {
clipboard = new ClipboardContainer();
}
if (node != null) {
clipboard.put(state.getBrowsedFolder(), "cut", node);
} else if (nodes != null) {
clipboard.put(state.getBrowsedFolder(), "cut", nodes);
}
}
@Progress("progress.repo.pasteFromClipboard")
@Remote
public void paste(CMObject target) throws FileExistsException, FileNotFoundException {
if (target == null) {
target = state.getBrowsedFolder();
}
if (clipboard.isCopy()) {
for (CMObject node : clipboard.data) {
serviceRegistry.getFileFolderService().copy(node.getNodeRef(), target.getNodeRef(), null);
}
} else {
for (CMObject node : clipboard.data) {
serviceRegistry.getFileFolderService().move(node.getNodeRef(), target.getNodeRef(), null);
}
}
folderModel.reloadModel();
// response.put("origin",
// clipboard.getOrigin().getNodeRef().toString());
// response.put("target", target.getNodeRef().toString());
}
public static class ClipboardContainer {
private String operation;
private List<CMObject> data = new ArrayList<CMObject>();
private CMFolder origin;
public boolean isEmpty() {
return data.isEmpty();
}
public void empty() {
data.clear();
operation = null;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getOperation() {
return operation;
}
public CMFolder getOrigin() {
return origin;
}
public void put(CMFolder origin, String operation, CMObject node) {
this.data.clear();
this.data.add(node);
this.operation = operation;
this.origin = origin;
}
public void put(CMFolder origin, String operation, List<CMObject> nodes) {
this.data.clear();
this.data.addAll(nodes);
this.operation = operation;
this.origin = origin;
}
public boolean isCopy() {
return "copy".equals(operation);
}
public boolean isCut() {
return "cut".equals(operation);
}
}
}