001/*
002 *  Copyright 2018 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.repository.data.holder;
017
018import java.io.IOException;
019import java.util.Collection;
020import java.util.Optional;
021
022import org.xml.sax.ContentHandler;
023import org.xml.sax.SAXException;
024
025import org.ametys.plugins.repository.data.holder.group.Composite;
026import org.ametys.plugins.repository.data.holder.impl.DataHolderHelper;
027import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
028import org.ametys.runtime.model.exception.BadItemTypeException;
029import org.ametys.runtime.model.exception.NotUniqueTypeException;
030import org.ametys.runtime.model.exception.UndefinedItemPathException;
031import org.ametys.runtime.model.exception.UnknownTypeException;
032import org.ametys.runtime.model.type.DataContext;
033
034/**
035 * Interface for data containers
036 */
037public interface DataHolder
038{
039    /**
040     * Retrieves the composite at the given path
041     * @param compositePath path of the composite to retrieve
042     * @return the composite or <code>null</code> if not exists or is empty
043     * @throws IllegalArgumentException if the given composite path is null or empty
044     * @throws BadItemTypeException if the stored value at the given path is not a composite
045     */
046    public Composite getComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException;
047    
048    /**
049     * Checks if there is a value for the data at the given path
050     * @param dataPath path of the data
051     * @return <code>true</code> if there is value (even empty) for the data, <code>false</code> otherwise
052     * @throws IllegalArgumentException if the given data path is null or empty
053     */
054    public boolean hasValue(String dataPath) throws IllegalArgumentException;
055    
056    /**
057     * Checks if there is a non empty value for the data at the given path
058     * @param dataPath path of the data
059     * @return <code>true</code> if there is a non empty value for the data, <code>false</code> otherwise
060     * @throws IllegalArgumentException if the given data path is null or empty
061     */
062    public boolean hasNonEmptyValue(String dataPath) throws IllegalArgumentException;
063    
064    /**
065     * Retrieves the names of data contained by this data holder
066     * Retrieves only the data at first level, does not check composite data 
067     * @return the names of all data contained by this data holder
068     */
069    public Collection<String> getDataNames();
070    
071    /**
072     * Copies the current {@link DataHolder} to the given {@link ModifiableModelAwareDataHolder}.
073     * @param dataHolder The destination dataHolder. Can not be null.
074     * @throws UndefinedItemPathException if one of the copied data is not defined by the model of the destination {@link ModifiableModelAwareDataHolder}
075     * @throws BadItemTypeException if the type defined by the model of the destination {@link ModifiableModelAwareDataHolder} doesn't match the copied value
076     * @throws UnknownTypeException if there is no available type compatible with the copied value for the type extension point of the destination {@link ModifiableModelLessDataHolder}
077     * @throws NotUniqueTypeException if there is more than one available types compatibles with the copied value for the type extension point of the destination {@link ModifiableModelLessDataHolder}
078     */
079    public default void copyTo(ModifiableDataHolder dataHolder) throws UndefinedItemPathException, BadItemTypeException, UnknownTypeException, NotUniqueTypeException
080    {
081        DataHolderHelper.copyTo(this, dataHolder);
082    }
083    
084    /**
085     * Generates SAX events for the data at the given data path in the current {@link DataHolder}
086     * Do not generate any event if there is no values at the given path
087     * @param contentHandler the {@link ContentHandler} that will receive the SAX events
088     * @param dataPath the path of the data to SAX
089     * @throws SAXException if an error occurs during the SAX events generation
090     * @throws IOException if an error occurs while reading a value using the I/O API
091     */
092    public default void dataToSAX(ContentHandler contentHandler, String dataPath) throws SAXException, IOException
093    {
094        dataToSAX(contentHandler, dataPath, DataContext.newInstance());
095    }
096    
097    /**
098     * Generates SAX events for the data at the given data path in the current {@link DataHolder}
099     * Do not generate any event if there is no values at the given path
100     * @param contentHandler the {@link ContentHandler} that will receive the SAX events
101     * @param dataPath the path of the data to SAX
102     * @param context The context of the data to SAX
103     * @throws SAXException if an error occurs during the SAX events generation
104     * @throws IOException if an error occurs while reading a value using the I/O API
105     */
106    public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException, IOException;
107    
108    /**
109     * Retrieves the repository data used by this {@link DataHolder}
110     * @return the repository data used by this {@link DataHolder}
111     */
112    public RepositoryData getRepositoryData();
113    
114    /**
115     * Retrieves the optional parent of the current {@link DataHolder}
116     * There can be no parent if the current {@link DataHolder} is the root
117     * @return the parent of the current {@link DataHolder}
118     */
119    public Optional<? extends DataHolder> getParentDataHolder();
120    
121    /**
122     * Retrieves the {@link DataHolder} that is the root of the current one
123     * @return the root {@link DataHolder}
124     */
125    public DataHolder getRootDataHolder();
126}