001/*
002 *  Copyright 2019 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.queriesdirectory;
017
018import javax.jcr.ItemExistsException;
019import javax.jcr.Node;
020import javax.jcr.RepositoryException;
021import javax.jcr.Session;
022
023import org.ametys.plugins.repository.AmetysObject;
024import org.ametys.plugins.repository.AmetysRepositoryException;
025import org.ametys.plugins.repository.MovableAmetysObject;
026import org.ametys.plugins.repository.RepositoryIntegrityViolationException;
027import org.ametys.plugins.repository.jcr.SimpleAmetysObject;
028
029/**
030 * Common methods for {@link Query} and {@link QueryContainer}
031 */
032public final class QueryAndContainerCommonMethods
033{
034    private QueryAndContainerCommonMethods()
035    {
036    }
037    
038    /**
039     * Implementation of {@link MovableAmetysObject#canMoveTo(AmetysObject)}
040     * @param newParent See moveTo.
041     * @param queryOrQueryContainer The object to move
042     * @param queryDAO The Query DAO
043     * @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)
044     * @throws AmetysRepositoryException if an error occurs.
045     */
046    public static boolean canMoveTo(AmetysObject newParent, SimpleAmetysObject queryOrQueryContainer, QueryDAO queryDAO) throws AmetysRepositoryException
047    {
048        return newParent instanceof QueryContainer
049                && !queryOrQueryContainer.equals(queryDAO.getQueriesRootNode());
050    }
051    
052    /**
053     * Implementation of {@link MovableAmetysObject#moveTo(AmetysObject, boolean)}
054     * @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.
055     * @param renameIfExist true to rename moved page if a page with same name already exist
056     * @param queryOrQueryContainer The object to move
057     * @throws AmetysRepositoryException if an error occurs.
058     * @throws RepositoryIntegrityViolationException if a page with the same name already exists.
059     */
060    public static void moveTo(AmetysObject newParent, boolean renameIfExist, SimpleAmetysObject queryOrQueryContainer) throws AmetysRepositoryException, RepositoryIntegrityViolationException
061    {
062        Node srcNode = queryOrQueryContainer.getNode();
063        Node targetNode = ((QueryContainer) newParent).getNode(); // assume canMoveTo was called, so cast can be done
064        
065        try
066        {
067            if (queryOrQueryContainer.getParent().equals(newParent))
068            {
069                // Do nothing
070            }
071            else
072            {
073                String name = srcNode.getName();
074                if (renameIfExist)
075                {
076                    int index = 1;
077                    String origName = name;
078                    while (targetNode.hasNode(name))
079                    {
080                        name = origName + "-" + index++;
081                    }
082                }
083                String newPath = targetNode.getPath() + "/" + name;
084                
085                Session session = srcNode.getSession();
086                try
087                {
088                    session.move(srcNode.getPath(), newPath);
089                }
090                catch (ItemExistsException e)
091                {
092                    throw new AmetysRepositoryException("A query already exists for new path '" + newPath + "'", e);
093                }
094                session.save();
095            }
096        }
097        catch (RepositoryException e)
098        {
099            throw new AmetysRepositoryException("Unable to move query '" + queryOrQueryContainer + "' to node '" + newParent.getId() + "'", e);
100        }
101    }
102    
103    /**
104     * Implementation of {@link MovableAmetysObject#orderBefore(AmetysObject)}
105     * @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.
106     * @param queryOrQueryContainer The object to move
107     * @throws AmetysRepositoryException if an error occurs.
108     */
109    public static void orderBefore(AmetysObject siblingNode, SimpleAmetysObject queryOrQueryContainer) throws AmetysRepositoryException
110    {
111        throw new UnsupportedOperationException("Query ordering is not supported");
112    }
113}