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