001/*
002 *  Copyright 2010 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.explorer.resources.generators;
017
018import java.io.IOException;
019
020import javax.jcr.RepositoryException;
021
022import org.apache.cocoon.ProcessingException;
023import org.apache.cocoon.environment.ObjectModelHelper;
024import org.apache.cocoon.environment.Request;
025import org.apache.cocoon.xml.AttributesImpl;
026import org.apache.cocoon.xml.XMLUtils;
027import org.apache.commons.lang.StringUtils;
028import org.apache.jackrabbit.util.ISO9075;
029import org.xml.sax.SAXException;
030
031import org.ametys.plugins.explorer.ExplorerNode;
032import org.ametys.plugins.explorer.resources.Resource;
033import org.ametys.plugins.explorer.resources.ResourceCollection;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.AmetysObjectIterable;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.plugins.repository.jcr.JCRAmetysObject;
038import org.ametys.plugins.repository.query.expression.Expression;
039import org.ametys.plugins.repository.query.expression.Expression.Operator;
040import org.ametys.plugins.repository.query.expression.ExpressionContext;
041import org.ametys.plugins.repository.query.expression.OrExpression;
042import org.ametys.plugins.repository.query.expression.StringExpression;
043import org.ametys.plugins.repository.query.expression.UserExpression;
044
045/**
046 * Search resources
047 *
048 */
049public class SearchGenerator extends ResourcesExplorerGenerator
050{
051    @Override
052    public void generate() throws IOException, SAXException, ProcessingException
053    {
054        Request request = ObjectModelHelper.getRequest(objectModel);
055        
056        String id = request.getParameter("id");
057        ExplorerNode node = _resolver.resolveById(id);
058        
059        Expression metaExpr = getMetadataExpression (request);
060        
061        String predicat = metaExpr != null ? metaExpr.build() : null;
062        
063        // File name
064        String name = request.getParameter("name");
065        if (StringUtils.isNotEmpty(name))
066        {
067            String namePredicate = "jcr:like(fn:lower-case(fn:name()),'%" + name.toLowerCase() + "%')";
068            predicat = predicat == null ? namePredicate : predicat + " or " + namePredicate;
069        }
070        
071        // Full text
072        String fulltext = request.getParameter("fulltext");
073        if (StringUtils.isNotEmpty(fulltext))
074        {
075            String xpath = "jcr:contains(jcr:content, '*" + fulltext + "*')";
076            predicat = predicat == null ? xpath : predicat + " or " + xpath;
077        }
078        
079        contentHandler.startDocument();
080        XMLUtils.startElement(contentHandler, "resources");
081        
082        try
083        {
084            if (node instanceof JCRAmetysObject)
085            {
086                String jcrPath = ((JCRAmetysObject) node).getNode().getPath();
087                String relativeJcrPath = jcrPath.substring(AmetysObjectResolver.ROOT_REPO.length() + 1);
088                String xpathQuery = "/" + ISO9075.encodePath(relativeJcrPath) + "//element(*, ametys:resource)" + (predicat != null ? "[" + predicat + "]" : "");
089                
090                try (AmetysObjectIterable<Resource> it = _resolver.query(xpathQuery))
091                {
092                    for (Resource resource : it)
093                    {
094                        saxResource(resource);
095                    }
096                }
097            }
098        }
099        catch (RepositoryException e)
100        {
101            getLogger().error("Error getting the JCR path of the explorer node of id " + id, e);
102            throw new ProcessingException("Error getting the JCR path of the explorer node of id " + id, e);
103        }
104        
105        XMLUtils.endElement(contentHandler, "resources");
106        contentHandler.endDocument();
107    }
108    
109    /**
110     * Get the {@link Expression}
111     * @param request The request
112     * @return the {@link Expression}
113     */
114    protected Expression getMetadataExpression (Request request)
115    {
116        Expression expr = null;
117        
118        String keywords = request.getParameter("keywords");
119        if (StringUtils.isNotEmpty(keywords))
120        {
121            String[] words = StringUtils.split(keywords);
122            for (String word : words)
123            {
124                ExpressionContext context = ExpressionContext.newInstance().withUnversioned(true);
125                Expression subjectExpr = new StringExpression("dc/dc_subject", Operator.WD, word, context);
126                Expression descExpr = new StringExpression("dc/dc_description",  Operator.WD, word, context);
127                
128                expr = expr == null ? new OrExpression(subjectExpr, descExpr) : new OrExpression(expr, subjectExpr, descExpr);
129            }
130        }
131        
132        String author = request.getParameter("author");
133        if (StringUtils.isNotEmpty(author))
134        {
135            Expression authorExpr = new UserExpression("author", Operator.EQ, author, true);
136            expr = expr == null ? authorExpr : new OrExpression(expr, authorExpr);
137        }
138        
139        return expr;
140    }
141
142    @Override
143    protected AttributesImpl getResourceAttributes(Resource resource)
144    {
145        AttributesImpl atts = super.getResourceAttributes(resource);
146        
147        AmetysObject parent = resource.getParent();
148        AmetysObject object = resource;
149        while (parent instanceof ResourceCollection)
150        {
151            object = parent;
152            parent = object.getParent();
153        }
154        
155        atts.addCDATAAttribute("rootId", object.getId());
156        
157        return atts;
158    }
159}