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.content;
017
018import java.util.HashSet;
019import java.util.Map;
020import java.util.Optional;
021import java.util.Set;
022
023import org.apache.avalon.framework.configuration.ConfigurationException;
024
025import org.ametys.cms.contenttype.ContentType;
026import org.ametys.cms.contenttype.ContentTypesParserHelper.ViewConfigurations;
027import org.ametys.cms.repository.Content;
028import org.ametys.runtime.model.View;
029import org.ametys.runtime.model.ViewParserContext;
030
031/**
032 * Component responsible to retrieve the view of a content
033 */
034public interface ContentViewProvider
035{
036    /** Avalon Role */
037    public static final String ROLE = ContentViewProvider.class.getName();
038    
039    /**
040     * Initializes the view configurations of the provider.
041     * This method is called once at application startup, after all content types have been configured.
042     * @throws ConfigurationException if an error occurs during the initialization of the view configurations
043     */
044    public default void initializeViewConfigurations() throws ConfigurationException
045    {
046        // Default - do nothing
047    }
048    
049    /**
050     * Parse the views of the provider
051     * This method is called once at application startup, after all content type's views have been parsed
052     * @throws ConfigurationException if an error occurs during the parse of the views
053     */
054    public default void parseViews() throws ConfigurationException
055    {
056        // Default - do nothing
057    }
058    
059    /**
060     * Resolve the temporary view references in overridden views
061     * @throws ConfigurationException if a view reference has a configuration error (the content attribute nesting the reference does not specify any content type, the view does not exist, ...)
062     */
063    public default void resolveViewReferences() throws ConfigurationException
064    {
065        // Default - do nothing
066    }
067    
068    /**
069     * Retrieves a Set of content types that have been overridden
070     * @return the set of overridden content types identifiers
071     */
072    public default Set<String> getOverriddenContentTypes()
073    {
074        return new HashSet<>();
075    }
076    
077    /**
078     * Retrieves all the views' configurations declared by the given content type
079     * @param contentType the content type
080     * @param context the context of view parsing
081     * @return the views' configurations
082     */
083    public Map<String, ViewConfigurations> getViewConfigurations(ContentType contentType, ViewParserContext context);
084    
085    /**
086     * Retrieves the optional view's configuration declared by the given content type
087     * @param contentType the content type
088     * @param viewName the name of the view to retrieve
089     * @param context the context of view parsing
090     * @return the view's configuration
091     */
092    public Optional<ViewConfigurations> getViewConfigurations(ContentType contentType, String viewName, ViewParserContext context);
093    
094    /**
095     * Retrieves the view of the given content type
096     * @param contentType the content type
097     * @param viewName the view name
098     * @param context the context of view parsing
099     * @return the view of the given content type
100     */
101    public default View getContentTypeView(ContentType contentType, String viewName, ViewParserContext context)
102    {
103        return contentType.getView(viewName);
104    }
105    
106    /**
107     * Get the view for view resulting of the concatenation of views of the given content.
108     * @param viewName the name of the view to retrieve
109     * @param content the given content
110     * @return The view or null if none matches.
111     */
112    public default View getView(String viewName, Content content)
113    {
114        return getView(viewName, content.getTypes(), content.getMixinTypes());
115    }
116    
117    /**
118     * Get the view for view resulting of the concatenation of views of the given content.
119     * @param viewName the name of the view to retrieve
120     * @param contentTypeIds the identifiers of the content types
121     * @param mixinIds the identifiers of the mixins
122     * @return The view or null if none matches.
123     */
124    public View getView(String viewName, String[] contentTypeIds, String[] mixinIds);
125    
126    /**
127     * Get the view for view resulting for a given content
128     * @param viewName the name of the view to retrieve. If null or empty, fallback view will be used.
129     * @param fallbackViewName the name of the view to retrieve if the initial was not found. If null or empty, "main" view view will be used as fallback view.
130     * @param content the content
131     * @return The view or null if none matches.
132     */
133    public default View getViewWithFallback(String viewName, String fallbackViewName, Content content)
134    {
135        return getViewWithFallback(viewName, fallbackViewName, content.getTypes(), content.getMixinTypes());
136    }
137    
138    /**
139     * Get the view for view resulting for a given content
140     * @param viewName the name of the view to retrieve. If null or empty, fallback view will be used.
141     * @param fallbackViewName the name of the view to retrieve if the initial was not found. If null or empty, "main" view view will be used as fallback view.
142     * @param contentTypeIds the identifiers of the content types
143     * @param mixinIds the identifiers of the mixins
144     * @return The view or null if none matches.
145     */
146    public View getViewWithFallback(String viewName, String fallbackViewName, String[] contentTypeIds, String[] mixinIds);
147}