001/*
002 *  Copyright 2025 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.cms.trash.element;
017
018import java.util.HashMap;
019import java.util.LinkedHashSet;
020import java.util.Map;
021import java.util.Optional;
022import java.util.Set;
023import java.util.stream.Collectors;
024import java.util.stream.Stream;
025
026import javax.jcr.Node;
027import javax.jcr.RepositoryException;
028
029import org.ametys.cms.repository.DefaultIndexableTraversableAmetysObject;
030import org.ametys.cms.trash.model.TrashElementModel;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.plugins.repository.AmetysRepositoryException;
033import org.ametys.plugins.repository.query.QueryHelper;
034import org.ametys.plugins.repository.query.expression.AndExpression;
035import org.ametys.plugins.repository.query.expression.BooleanExpression;
036import org.ametys.plugins.repository.query.expression.Expression;
037import org.ametys.plugins.repository.query.expression.Expression.Operator;
038import org.ametys.plugins.repository.query.expression.StringExpression;
039import org.ametys.plugins.repository.trash.TrashElement;
040import org.ametys.runtime.model.ViewItemAccessor;
041import org.ametys.runtime.model.exception.BadItemTypeException;
042import org.ametys.runtime.model.type.DataContext;
043
044/**
045 * Class representing a {@link DefaultTrashElement}
046 */
047public class DefaultTrashElement extends DefaultIndexableTraversableAmetysObject<TrashElementFactory> implements TrashElement
048{
049    /**
050     * Constructor.
051     * 
052     * @param node the JCR Node.
053     * @param parentPath the parent path
054     * @param factory the corresponding factory.
055     */
056    public DefaultTrashElement(Node node, String parentPath, TrashElementFactory factory)
057    {
058        super(node, parentPath, factory);
059    }
060    
061    @Override
062    public Map<String, Object> dataToJSON(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException
063    {
064        Map<String, Object> json = new HashMap<>(super.dataToJSON(viewItemAccessor, context));
065        json.put("id", getId());
066        return json;
067    }
068    
069    public String getAmetysObjectId()
070    {
071        return getValue(TrashElementModel.DELETED_OBJECT);
072    }
073
074    public Set<TrashElement> getLinkedElements(boolean hiddenOnly)
075    {
076        return Optional.<String[]> ofNullable(getValue(TrashElementModel.LINKED_OBJECTS))
077            .map(Stream::of)
078            .orElseGet(Stream::of)
079            .map(objectId -> {
080                Expression filter = new StringExpression(TrashElementModel.DELETED_OBJECT, Operator.EQ, objectId);
081                if (hiddenOnly)
082                {
083                    filter = new AndExpression(filter, new BooleanExpression(TrashElementModel.HIDDEN, true));
084                }
085                return QueryHelper.getXPathQuery(
086                        null, TrashElementFactory.TRASH_ELEMENT_NODETYPE,
087                        filter);
088            })
089            .map(query -> {
090                try
091                {
092                    return _getFactory()._getAOResolver().<TrashElement> query(query, getNode().getSession());
093                }
094                catch (RepositoryException e)
095                {
096                    throw new AmetysRepositoryException(e);
097                }
098            })
099            .flatMap(AmetysObjectIterable::stream)
100            .collect(Collectors.<TrashElement> toSet());
101    }
102
103    public void addLinkedObjects(String... linkedObjectsIds)
104    {
105        if (linkedObjectsIds == null || linkedObjectsIds.length == 0)
106        {
107            return;
108        }
109        
110        String[] previousObjects = getValue(TrashElementModel.LINKED_OBJECTS);
111        Set<String> objects = new LinkedHashSet<>();
112        if (previousObjects != null)
113        {
114            for (String id : previousObjects)
115            {
116                objects.add(id);
117            }
118        }
119        
120        for (String id : linkedObjectsIds)
121        {
122            objects.add(id);
123        }
124        
125        setValue(TrashElementModel.LINKED_OBJECTS, objects.toArray(new String[0]));
126    }
127
128    public void setHidden(boolean hidden)
129    {
130        setValue(TrashElementModel.HIDDEN, hidden);
131    }
132}