001/*
002  Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag.
003
004  Licensed under the Apache License, Version 2.0 (the "License"); you may not
005  use this file except in compliance with the License. You may obtain a copy of
006  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, WITHOUT
012  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013  License for the specific language governing permissions and limitations under
014  the License.
015 */
016package org.javamoney.moneta.spi;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.net.URI;
021import java.util.Map;
022import java.util.Set;
023import java.util.concurrent.Future;
024
025/**
026 * This interface defines an updatable/reloadable data cache for providing data
027 * sources that are updatable by any remote {@link URI}s. Initial version are
028 * loaded from the classpath, or other fallback URL.
029 *
030 * This class is used for managing/updating/reloading of data sources, e.g. data
031 * streams for exchange rates, additional currency data, historical currency
032 * data and so on.
033 *
034 * Note: this class is implementation specific and not part of the official
035 * JSR's API.
036 *
037 * @author Anatole Tresch
038 */
039public interface LoaderService {
040
041    /**
042     * Platform RI: The update policy defines how and when the
043     * {@link LoaderService} tries to update the local cache with newest version of
044     * the registered data resources, accessing the configured remote
045     * {@link URI}s. By default no remote connections are done (
046     * {@link UpdatePolicy#NEVER} ).
047     *
048     * @author Anatole Tresch
049     */
050    enum UpdatePolicy {
051        /**
052         * The resource will never be updated from remote, only the fallback URL
053         * will be evaluated.
054         */
055        NEVER,
056        /**
057         * The resource will be loaded automatically from remote only once on
058         * startup.
059         */
060        ONSTARTUP,
061        /**
062         * The resource will be loaded automatically from remote only once, when
063         * accessed the first time.
064         */
065        LAZY,
066        /**
067         * The resource should be regularly reloaded based on a schedule.
068         */
069        SCHEDULED
070    }
071
072    /**
073     * Callback that can be registered to be informed, when a data item was
074     * loaded/updated or resetToFallback.
075     *
076     * @author Anatole Tresch
077     * @see #resetData(String)
078     * @see #loadData(String)
079     */
080    interface LoaderListener {
081        /**
082         * Callback called from the {@link LoaderService}, when new data was
083         * read for a given data item.
084         *
085         * @param resourceId the resource id
086         * @param is         the input stream for accessing the data
087         */
088        void newDataLoaded(String resourceId, InputStream is);
089    }
090
091    /**
092     * Programmatically registers a remote resource {@code resourceLocation},
093     * backed up by a classpath resource {@code backupResource}, reachable as
094     * {@code dataId}.
095     *
096     *resourceId        The unique identifier of the resource that must also be used
097     *                          for accessing the resource, not {@code null}.
098     *resourceLocations The remote resource locations, not {@code null}.
099     *backupResource    The backup resource location in the classpath, not
100     *                          {@code null}.
101     *loaderListener    An (optional) LoaderListener to be registered.
102     */
103    void registerData(LoadDataInformation loadDataInformation);
104
105    @Deprecated
106    void registerData(String resourceId, UpdatePolicy updatePolicy,
107                             Map<String, String> properties, LoaderListener loaderListener,
108                             URI backupResource,
109                             URI... resourceLocations);
110
111    /**
112     * Programmatically registers a remote resource {@code resourceLocation},
113     * backed up by a classpath resource {@code backupResource}, reachable as
114     * {@code dataId} and (synchronously) loads the data.
115     *
116     * resourceId        The unique identifier of the resource that must also be used
117     *                          for accessing the resource, not {@code null}.
118     * resourceLocations The remote resource locations, not {@code null}.
119     * backupResource    The backup resource location in the classpath, not
120     *                          {@code null}.
121     * loaderListener    An (optional) LoaderListener to be registered.
122     */
123    void registerAndLoadData(LoadDataInformation loadDataInformation);
124
125    @Deprecated
126    void registerAndLoadData(String resourceId, UpdatePolicy updatePolicy,
127                                    Map<String, String> properties, LoaderListener loaderListener,
128                                    URI backupResource,
129                                    URI... resourceLocations);
130
131    /**
132     * Get the {@link UpdatePolicy} in place for the given dataId.
133     *
134     * @param resourceId the resource's id, not {@code null}
135     * @return the {@link UpdatePolicy}, not {@code null}
136     * @throws IllegalArgumentException if no such dataId is available.
137     */
138    UpdatePolicy getUpdatePolicy(String resourceId);
139
140    /**
141     * Get the update configuration for the given dataId.
142     *
143     * @param resourceId the dataId, not {@code null}
144     * @return the update configuration properties, not {@code null}
145     * @throws IllegalArgumentException if no such dataId is available.
146     */
147    Map<String, String> getUpdateConfiguration(String resourceId);
148
149    /**
150     * Add a {@link LoaderListener} callback that is informed when a data
151     * resource was update from remote, or resetToFallback. Passing an empty String or
152     * {@code null} sa {@code dataId} allows to register a listener for all data
153     * resources registered. {@link #loadData(String)}
154     * {@link #resetData(String)}
155     *
156     * @param resourceIds The unique identifiers of the resource, not {@code null}.
157     * @param l           The listener to be added
158     * @see #removeLoaderListener(LoaderListener, String...)
159     */
160    void addLoaderListener(LoaderListener l, String... resourceIds);
161
162    /**
163     * Remove a registered {@link LoaderListener} callback.
164     *
165     * @param resourceIds The unique identifier of the resource, not {@code null}.
166     * @param l           The listener to be removed
167     * @see #addLoaderListener(LoaderListener, String...)
168     */
169    void removeLoaderListener(LoaderListener l, String... resourceIds);
170
171    /**
172     * Allows to check if a data resource with the given dataId is registered.
173     *
174     * @param resourceId The unique identifier of the resource, not {@code null}.
175     * @return {@code true}, if such a data resource is registered.
176     */
177    boolean isResourceRegistered(String resourceId);
178
179    /**
180     * Get a {@link Set} of all registered data resource identifiers.
181     *
182     * @return a {@link Set} of all registered data resource identifiers, never
183     * {@code null}.
184     */
185    Set<String> getResourceIds();
186
187    /**
188     * Access the input stream of the given data resource.
189     * This method is called by the modules that depend on the given data
190     * item. The method always returns the most current data, either from the
191     * classpath or the local cache, depending which flavors are available
192     * and recently updated.
193     * The method must be thread safe and can be accessed in parallel. Hereby it
194     * is possible that, when an intermediate update of the data by update
195     * occurs, that different input stream content is returned.
196     *
197     * @param resourceId The unique identifier of the resource, not {@code null}.
198     * @return The {@link InputStream} for reading the data.
199     * @throws IOException if a problem occurred.
200     */
201    InputStream getData(String resourceId) throws IOException;
202
203    /**
204     * Explicitly triggers the loading of the registered data, regardless of its
205     * current {@link UpdatePolicy} configured, from the fallback/local
206     * resource.
207     *
208     * @param resourceId The unique identifier of the resource, not {@code null}.
209     * @return true if load was successful.
210     */
211    boolean loadDataLocal(String resourceId);
212
213    /**
214     * Explicitly triggers the remote loading of the registered data, regardless
215     * of its current {@link UpdatePolicy} configured.
216     *
217     * @param resourceId The unique identifier of the resource, not {@code null}.
218     * @return true if load was successful.
219     * @throws IOException if a problem occurred.
220     */
221    boolean loadData(String resourceId) throws IOException;
222
223    /**
224     * Explicitly asynchronously triggers the remote loading of the registered
225     * data, regardless of its current {@link UpdatePolicy} configured.
226     *
227     * @param resourceId The unique identifier of the resource, not {@code null}.
228     * @return the Future of the load task started, returns Boolean.TRUE if the
229     * load was successful (either from remote or from the fallback
230     * resource).
231     */
232    Future<Boolean> loadDataAsync(String resourceId);
233
234    /**
235     * Explicitly triggers the resetToFallback (loading of the registered data from the
236     * classpath backup resource).
237     *
238     * @param resourceId The unique identifier of the resource, not {@code null}.
239     * @throws IOException if a problem occurred.
240     */
241    void resetData(String resourceId) throws IOException;
242
243}