001/*
002 *  Copyright 2021 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.forms;
017
018import javax.jcr.ItemExistsException;
019import javax.jcr.Node;
020import javax.jcr.RepositoryException;
021import javax.jcr.Session;
022
023import org.ametys.plugins.forms.dao.FormDirectoryDAO;
024import org.ametys.plugins.forms.repository.Form;
025import org.ametys.plugins.forms.repository.FormDirectory;
026import org.ametys.plugins.repository.AmetysObject;
027import org.ametys.plugins.repository.AmetysRepositoryException;
028import org.ametys.plugins.repository.MovableAmetysObject;
029import org.ametys.plugins.repository.RepositoryIntegrityViolationException;
030import org.ametys.plugins.repository.jcr.SimpleAmetysObject;
031
032/**
033 * Common methods for {@link Form} and {@link FormDirectory}
034 */
035public final class FormAndDirectoryCommonMethods
036{
037    private FormAndDirectoryCommonMethods()
038    {
039    }
040    
041    /**
042     * Implementation of {@link MovableAmetysObject#canMoveTo(AmetysObject)}
043     * @param siteName Name of current site
044     * @param newParent See moveTo.
045     * @param formOrFormDirectory The object to move
046     * @param formDAO The Form DAO
047     * @return true if the move operation may succeed. If false is returned and you call moveTo anyway, you may encontered a RuntimeException (such as UnsupportedOperationException)
048     * @throws AmetysRepositoryException if an error occurs.
049     */
050    public static boolean canMoveTo(String siteName, AmetysObject newParent, SimpleAmetysObject formOrFormDirectory, FormDirectoryDAO formDAO) throws AmetysRepositoryException
051    {
052        return newParent instanceof FormDirectory
053                && !formOrFormDirectory.equals(formDAO.getFormDirectoriesRootNode(siteName));
054    }
055    
056    /**
057     * Implementation of {@link MovableAmetysObject#moveTo(AmetysObject, boolean)}
058     * @param newParent The new parent for the current object. Can not be null. Can not be a child of the current node. Must be a TraversableAmetyObject.
059     * @param renameIfExist true to rename moved page if a page with same name already exist
060     * @param formOrFormDirectory The object to move
061     * @throws AmetysRepositoryException if an error occurs.
062     * @throws RepositoryIntegrityViolationException if a page with the same name already exists.
063     */
064    public static void moveTo(AmetysObject newParent, boolean renameIfExist, SimpleAmetysObject formOrFormDirectory) throws AmetysRepositoryException, RepositoryIntegrityViolationException
065    {
066        Node srcNode = formOrFormDirectory.getNode();
067        Node targetNode = ((FormDirectory) newParent).getNode(); // assume canMoveTo was called, so cast can be done
068        
069        try
070        {
071            if (formOrFormDirectory.getParent().equals(newParent))
072            {
073                // Do nothing
074            }
075            else
076            {
077                String name = srcNode.getName();
078                if (renameIfExist)
079                {
080                    int index = 1;
081                    String origName = name;
082                    while (targetNode.hasNode(name))
083                    {
084                        name = origName + "-" + index++;
085                    }
086                }
087                String newPath = targetNode.getPath() + "/" + name;
088                
089                Session session = srcNode.getSession();
090                try
091                {
092                    session.move(srcNode.getPath(), newPath);
093                }
094                catch (ItemExistsException e)
095                {
096                    throw new AmetysRepositoryException("A form already exists for new path '" + newPath + "'", e);
097                }
098                session.save();
099            }
100        }
101        catch (RepositoryException e)
102        {
103            throw new AmetysRepositoryException("Unable to move form '" + formOrFormDirectory + "' to node '" + newParent.getId() + "'", e);
104        }
105    }
106    
107    /**
108     * Implementation of {@link MovableAmetysObject#orderBefore(AmetysObject)}
109     * @param siblingNode The node that will be the next sibling node of the current node. Must have the same parent as the current node. Can be null to set the current node as the last node.
110     * @param formOrFormDirectory The object to move
111     * @throws AmetysRepositoryException if an error occurs.
112     */
113    public static void orderBefore(AmetysObject siblingNode, SimpleAmetysObject formOrFormDirectory) throws AmetysRepositoryException
114    {
115        throw new UnsupportedOperationException("Form ordering is not supported");
116    }
117}