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