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