001/*
002 *  Copyright 2026 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.repository;
017
018import java.util.List;
019import java.util.Optional;
020
021import javax.jcr.Node;
022
023import org.apache.commons.lang3.StringUtils;
024import org.apache.solr.common.SolrInputDocument;
025
026import org.ametys.cms.data.holder.ModifiableIndexableDataHolder;
027import org.ametys.cms.data.holder.group.ModifiableIndexableComposite;
028import org.ametys.cms.data.holder.group.ModifiableIndexableRepeater;
029import org.ametys.cms.data.holder.impl.DefaultModifiableIndexableDataHolder;
030import org.ametys.cms.data.holder.impl.IndexableDataHolderHelper;
031import org.ametys.cms.model.CMSDataContext;
032import org.ametys.cms.search.model.SystemProperty;
033import org.ametys.cms.search.model.SystemPropertyExtensionPoint;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData;
036import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData;
037import org.ametys.plugins.repository.jcr.SimpleModelAwareAmetysObject;
038import org.ametys.runtime.model.ModelViewItem;
039import org.ametys.runtime.model.ViewElement;
040import org.ametys.runtime.model.ViewHelper;
041import org.ametys.runtime.model.ViewItemAccessor;
042import org.ametys.runtime.model.exception.BadDataPathCardinalityException;
043import org.ametys.runtime.model.exception.BadItemTypeException;
044import org.ametys.runtime.model.exception.UndefinedItemPathException;
045
046/**
047 * Indexable implementation of an {@link AmetysObject}, backed by a JCR node.<br>
048 * @param <F> the actual type of factory.
049 */
050public class SimpleIndexableAmetysObject<F extends SimpleIndexableAmetysObjectFactory> extends SimpleModelAwareAmetysObject<F> implements IndexableJCRAmetysObject
051{
052    /**
053     * Creates an {@link SimpleIndexableAmetysObject}.
054     * @param node the node backing this {@link AmetysObject}
055     * @param parentPath the parentPath in the Ametys hierarchy
056     * @param factory the {@link SimpleIndexableAmetysObjectFactory} which created the AmetysObject
057     */
058    public SimpleIndexableAmetysObject(Node node, String parentPath, F factory)
059    {
060        super(node, parentPath, factory);
061    }
062    
063    @Override
064    protected ModifiableIndexableDataHolder getDataHolder()
065    {
066        ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode());
067        return new DefaultModifiableIndexableDataHolder(repositoryData, _getFactory().getModel(this), Optional.empty(), Optional.empty(), Optional.of(this));
068    }
069    
070    @SuppressWarnings("unchecked")
071    public List<SolrInputDocument> indexData(SolrInputDocument document, CMSDataContext context) throws BadItemTypeException
072    {
073        CMSDataContext newContext = context.cloneContext()
074                                           .withObject(this);
075        
076        // Create view with all model items
077        ViewItemAccessor viewItemAccessor = ViewHelper.createViewItemAccessor(getModel());
078        
079        // Add system properties to the view
080        if (getSystemPropertyExtensionPoint().isPresent())
081        {
082            SystemPropertyExtensionPoint systemPropertyExtensionPoint = getSystemPropertyExtensionPoint().get();
083            for (String systemPropertyId : systemPropertyExtensionPoint.getExtensionsIds())
084            {
085                SystemProperty systemProperty = systemPropertyExtensionPoint.getExtension(systemPropertyId);
086                ModelViewItem viewItem = new ViewElement();
087                viewItem.setDefinition(systemProperty);
088                viewItemAccessor.addViewItem(viewItem);
089            }
090        }
091        
092        // Index data
093        return IndexableDataHolderHelper.indexData(getDataHolder(), viewItemAccessor, document, document, StringUtils.EMPTY, newContext);
094    }
095    
096    @Override
097    public ModifiableIndexableComposite getComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
098    {
099        return getDataHolder().getComposite(compositePath);
100    }
101
102    @Override
103    public ModifiableIndexableComposite getComposite(String compositePath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
104    {
105        return getDataHolder().getComposite(compositePath, createNew);
106    }
107
108    @Override
109    public ModifiableIndexableComposite getLocalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
110    {
111        return getDataHolder().getLocalComposite(compositePath);
112    }
113
114    @Override
115    public ModifiableIndexableComposite getLocalComposite(String compositePath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
116    {
117        return getDataHolder().getLocalComposite(compositePath, createNew);
118    }
119
120    @Override
121    public ModifiableIndexableComposite getExternalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
122    {
123        return getDataHolder().getExternalComposite(compositePath);
124    }
125
126    @Override
127    public ModifiableIndexableComposite getExternalComposite(String compositePath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
128    {
129        return getDataHolder().getExternalComposite(compositePath, createNew);
130    }
131
132    @Override
133    public ModifiableIndexableRepeater getRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
134    {
135        return getDataHolder().getRepeater(repeaterPath);
136    }
137
138    @Override
139    public ModifiableIndexableRepeater getRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
140    {
141        return getDataHolder().getRepeater(repeaterPath, createNew);
142    }
143
144    @Override
145    public ModifiableIndexableRepeater getLocalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
146    {
147        return getDataHolder().getLocalRepeater(repeaterPath);
148    }
149
150    @Override
151    public ModifiableIndexableRepeater getLocalRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
152    {
153        return getDataHolder().getLocalRepeater(repeaterPath, createNew);
154    }
155    
156    @Override
157    public ModifiableIndexableRepeater getExternalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
158    {
159        return getDataHolder().getExternalRepeater(repeaterPath);
160    }
161
162    @Override
163    public ModifiableIndexableRepeater getExternalRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
164    {
165        return getDataHolder().getExternalRepeater(repeaterPath, createNew);
166    }
167    
168    @Override
169    public Optional<? extends ModifiableIndexableDataHolder> getParentDataHolder()
170    {
171        return getDataHolder().getParentDataHolder();
172    }
173    
174    @Override
175    public ModifiableIndexableDataHolder getRootDataHolder()
176    {
177        return getDataHolder().getRootDataHolder();
178    }
179}