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.RepositoryException;
019
020import org.apache.avalon.framework.component.Component;
021import org.apache.jackrabbit.util.ISO9075;
022
023import org.ametys.plugins.forms.repository.Form;
024import org.ametys.plugins.forms.repository.FormDirectory;
025import org.ametys.plugins.forms.repository.FormDirectoryFactory;
026import org.ametys.plugins.forms.repository.FormFactory;
027import org.ametys.plugins.forms.repository.FormPage;
028import org.ametys.plugins.forms.repository.FormPageFactory;
029import org.ametys.plugins.repository.AmetysRepositoryException;
030import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
031import org.ametys.runtime.plugin.component.AbstractLogEnabled;
032
033/**
034 * Helper for manipulating xpath on {@link Form}, {@link FormDirectory} and {@link FormPage}
035 */
036public class FormXpathUtils extends AbstractLogEnabled implements Component
037{
038    /**
039     * Creates the XPath query to get all form directories
040     * @param formDirectory The {@link FormDirectory}, defining the context from which getting children 
041     * @return The XPath query
042     */
043    public static String getXPathForFormDirectories(FormDirectory formDirectory)
044    {
045        return _getXPathQuery(formDirectory, true, ObjectToReturn.FORM_DIRECTORY);
046    }
047    
048    /**
049     * Creates the XPath query to get all form pages
050     * @param form The {@link FormDirectory}, defining the context from which getting children 
051     * @param onlyDirectChildren <code>true</code> in order to have only direct child forms from parent path, <code>false</code> otherwise to have all forms at any level underneath the parent path
052     * @return The XPath query
053     */
054    public static String getXPathForFormPages(Form form, boolean onlyDirectChildren)
055    {
056        return _getXPathQuery(form, onlyDirectChildren, ObjectToReturn.FORM_PAGE);
057    }
058    
059    /**
060     * Creates the XPath query to get all forms 
061     * @param formdirectory The {@link Form}, defining the context from which getting children 
062     * @param onlyDirectChildren <code>true</code> in order to have only direct child forms from parent path, <code>false</code> otherwise to have all forms at any level underneath the parent path
063     * @return The XPath query
064     */
065    public static String getXPathForForms(FormDirectory formdirectory, boolean onlyDirectChildren)
066    {
067        return _getXPathQuery(formdirectory, onlyDirectChildren, ObjectToReturn.FORM);
068    }
069    
070    private static String _getXPathQuery(DefaultTraversableAmetysObject traversableAO, boolean onlyDirectChildren, ObjectToReturn objectToReturn)
071    {
072        StringBuilder parentPath = _getParentPath(traversableAO);
073        final String slashOrDoubleSlash = onlyDirectChildren ? "/" : "//";
074        StringBuilder query = parentPath
075                .append(slashOrDoubleSlash)
076                .append("element(*, ")
077                .append(objectToReturn.toNodetype())
078                .append(")");
079               
080        return query.toString();
081    }
082    
083    private static StringBuilder _getParentPath(DefaultTraversableAmetysObject traversableAO)
084    {
085        try
086        {
087            StringBuilder parentPath = new StringBuilder("/jcr:root")
088                    .append(ISO9075.encodePath(traversableAO.getNode().getPath()));
089            return parentPath;
090        }
091        catch (RepositoryException e)
092        {
093            throw new AmetysRepositoryException(e);
094        }
095    }
096    
097    private static enum ObjectToReturn
098    {
099        FORM,
100        FORM_PAGE,
101        FORM_DIRECTORY;
102        
103        private String _nodetype;
104        
105        static
106        {
107            FORM._nodetype = FormFactory.FORM_NODETYPE;
108            FORM_DIRECTORY._nodetype = FormDirectoryFactory.FORM_DIRECTORY_NODETYPE;
109            FORM_PAGE._nodetype = FormPageFactory.FORM_PAGE_NODETYPE;
110        }
111        
112        String toNodetype()
113        {
114            return _nodetype;
115        }
116    }
117}