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        copyTo(dataHolder, DataContext.newInstance());
081    }
082    
083    /**
084     * Copies the current {@link DataHolder} to the given {@link ModifiableModelAwareDataHolder}.
085     * @param dataHolder The destination dataHolder. Can not be null.
086     * @param context The context of the data to copy
087     * @throws UndefinedItemPathException if one of the copied data is not defined by the model of the destination {@link ModifiableModelAwareDataHolder}
088     * @throws BadItemTypeException if the type defined by the model of the destination {@link ModifiableModelAwareDataHolder} doesn't match the copied value
089     * @throws UnknownTypeException if there is no available type compatible with the copied value for the type extension point of the destination {@link ModifiableModelLessDataHolder}
090     * @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}
091     */
092    public default void copyTo(ModifiableDataHolder dataHolder, DataContext context) throws UndefinedItemPathException, BadItemTypeException, UnknownTypeException, NotUniqueTypeException
093    {
094        DataHolderHelper.copyTo(this, dataHolder, context);
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     * @throws SAXException if an error occurs during the SAX events generation
103     */
104    public default void dataToSAX(ContentHandler contentHandler, String dataPath) throws SAXException
105    {
106        dataToSAX(contentHandler, dataPath, DataContext.newInstance());
107    }
108    
109    /**
110     * Generates SAX events for the data at the given data path in the current {@link DataHolder}
111     * Do not generate any event if there is no values at the given path
112     * @param contentHandler the {@link ContentHandler} that will receive the SAX events
113     * @param dataPath the path of the data to SAX
114     * @param context The context of the data to SAX
115     * @throws SAXException if an error occurs during the SAX events generation
116     */
117    public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException;
118    
119    /**
120     * Convert the data at the given path into a JSON object
121     * @param dataPath the path of the data to convert
122     * @return The value as JSON
123     */
124    public default Object dataToJSON(String dataPath)
125    {
126        return dataToJSON(dataPath, DataContext.newInstance());
127    }
128    
129    /**
130     * Convert the data at the given path into a JSON object
131     * @param dataPath the path of the data to convert
132     * @param context The context of the data to convert
133     * @return The value as JSON
134     */
135    public Object dataToJSON(String dataPath, DataContext context);
136    
137    /**
138     * Retrieves the repository data used by this {@link DataHolder}
139     * @return the repository data used by this {@link DataHolder}
140     */
141    public RepositoryData getRepositoryData();
142    
143    /**
144     * Retrieves the optional parent of the current {@link DataHolder}
145     * There can be no parent if the current {@link DataHolder} is the root
146     * @return the parent of the current {@link DataHolder}
147     */
148    public Optional<? extends DataHolder> getParentDataHolder();
149    
150    /**
151     * Retrieves the {@link DataHolder} that is the root of the current one
152     * @return the root {@link DataHolder}
153     */
154    public DataHolder getRootDataHolder();
155}