001package org.cache2k;
002
003/*
004 * #%L
005 * cache2k API only package
006 * %%
007 * Copyright (C) 2000 - 2016 headissue GmbH, Munich
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import org.cache2k.spi.SingleProviderResolver;
024import org.cache2k.spi.StorageImplementation;
025import org.cache2k.storage.SimpleSingleFileStorage;
026
027import java.util.concurrent.TimeUnit;
028
029/**
030 * @author Jens Wilke; created: 2014-04-18
031 */
032public class StorageConfiguration<EX> {
033
034  boolean reliable;
035
036  boolean purgeOnStartup;
037
038  boolean ignoreModifications;
039
040  Class<? extends StorageImplementation> implementation = SimpleSingleFileStorage.class;
041
042  boolean passivation = false;
043
044  boolean readOnly = false;
045
046  String location;
047
048  String storageName;
049
050  int entryCapacity = -1;
051
052  int bytesCapacity;
053
054  long syncInterval = 7 * 1000;
055
056  EX extraConfiguration;
057
058  boolean flushOnClose = false;
059
060  /**
061   * @see Builder#reliable
062   */
063  public boolean isReliable() {
064    return reliable;
065  }
066
067  /**
068   * @see Builder#reliable
069   */
070  public void setReliable(boolean reliable) {
071    this.reliable = reliable;
072  }
073
074  /**
075   * @see Builder#purgeOnStartup
076   */
077  public void setPurgeOnStartup(boolean purgeOnStartup) {
078    this.purgeOnStartup = purgeOnStartup;
079  }
080
081  /**
082   * @see Builder#purgeOnStartup
083   */
084  public boolean isPurgeOnStartup() {
085    return purgeOnStartup;
086  }
087
088  public void setIgnoreModifications(boolean ignoreModifications) {
089    this.ignoreModifications = ignoreModifications;
090  }
091
092  public void setImplementation(Class<? extends StorageImplementation> c) {
093    implementation = c;
094  }
095
096  public void setPassivation(boolean passivation) {
097    this.passivation = passivation;
098  }
099
100  public void setLocation(String location) {
101    this.location = location;
102  }
103
104  /**
105   * Capacity limit for the number of entries. Default is -1, capacity is
106   * limited by other means.
107   */
108  public void setEntryCapacity(int entryCapacity) {
109    this.entryCapacity = entryCapacity;
110  }
111
112  public void setBytesCapacity(int bytesCapacity) {
113    this.bytesCapacity = bytesCapacity;
114  }
115
116  public void setSyncInterval(long v, TimeUnit u) {
117    this.syncInterval = u.toMillis(v);
118  }
119
120  public boolean isIgnoreModifications() {
121    return ignoreModifications;
122  }
123
124  public Class<?> getImplementation() {
125    return implementation;
126  }
127
128  public boolean isPassivation() {
129    return passivation;
130  }
131
132  public String getLocation() {
133    return location;
134  }
135
136  public int getEntryCapacity() {
137    return entryCapacity;
138  }
139
140  public int getBytesCapacity() {
141    return bytesCapacity;
142  }
143
144  /**
145   * Sync interval in milliseconds.
146   */
147  public long getFlushIntervalMillis() {
148    return syncInterval;
149  }
150
151  public EX getExtraConfiguration() {
152    return extraConfiguration;
153  }
154
155  public void setExtraConfiguration(EX extraConfiguration) {
156    this.extraConfiguration = extraConfiguration;
157  }
158
159  public boolean isFlushOnClose() {
160    return flushOnClose;
161  }
162
163  /**
164   * When closing flush data, if the storage does need this.
165   * The parameter is false by default. We prefer no delay on closing.
166   */
167  public void setFlushOnClose(boolean f) {
168    this.flushOnClose = f;
169  }
170
171  public String getStorageName() {
172    return storageName;
173  }
174
175  public void setStorageName(String v) {
176    storageName = v;
177  }
178
179  public boolean isReadOnly() {
180    return readOnly;
181  }
182
183  public void setReadOnly(boolean readOnly) {
184    this.readOnly = readOnly;
185  }
186
187  public static class Builder<K, T, OPT_EXTRA_CONFIG>
188    extends BaseAnyBuilder<K, T, StorageConfiguration> {
189
190    private StorageConfiguration<Object> config = new StorageConfiguration();
191    private AnyBuilder<K, T, ?> extraConfigurationBuilder = null;
192
193    /**
194     * Only store entries in the storage that don't live in the
195     * memory any more. E.g. when an entry gets evicted it is
196     * stored.
197     */
198    public Builder<K, T, OPT_EXTRA_CONFIG> passivation(boolean f) {
199      config.passivation = f;
200      return this;
201    }
202
203    /**
204     * False means single storage errors may be ignored.
205     * True will propagate errors and flush the contents on shutdown.
206     */
207    public Builder<K, T, OPT_EXTRA_CONFIG> reliable(boolean f) {
208      config.reliable = f;
209      return this;
210    }
211
212    public Builder<K, T, OPT_EXTRA_CONFIG> purgeOnStartup(boolean f) {
213      config.purgeOnStartup = f;
214      return this;
215    }
216
217    /**
218     * Flush contents on close. The default is off.
219     *
220     * <p>All defaults will be towards a "cache alike" behavior, not a
221     * reliable storage behavior.
222     */
223    public Builder<K, T, OPT_EXTRA_CONFIG> flushOnClose(boolean f) {
224      config.flushOnClose = f;
225      return this;
226    }
227
228    /**
229     * Switch storage to read only mode, e.g. to examine the contents.
230     * This parameter is not supported by all storage implementations.
231     */
232    public Builder<K, T, OPT_EXTRA_CONFIG> readOnly(boolean f) {
233      config.readOnly = f;
234      return this;
235    }
236
237    public Builder<K, T, OPT_EXTRA_CONFIG> location(String s) {
238      config.location = s;
239      return this;
240    }
241
242    public Builder<K, T, OPT_EXTRA_CONFIG> entryCapacity(int v) {
243      config.entryCapacity = v;
244      return this;
245    }
246
247    public Builder<K, T, OPT_EXTRA_CONFIG> bytesCapacity(int v) {
248      config.bytesCapacity = v;
249      return this;
250    }
251
252    public Builder<K, T, OPT_EXTRA_CONFIG> syncInterval(int v, TimeUnit u) {
253      config.syncInterval = (int) u.toMillis(v);
254      return this;
255    }
256
257    public Builder<K, T, OPT_EXTRA_CONFIG> storageName(String s) {
258      config.storageName = s;
259      return this;
260    }
261
262
263    public <EXTRA_CONFIG_BUILDER extends AnyBuilder<K, T, ?>> Builder<K, T, EXTRA_CONFIG_BUILDER> implementation(
264      Class<? extends StorageImplementation<EXTRA_CONFIG_BUILDER>> c) {
265      StorageImplementation<EXTRA_CONFIG_BUILDER> imp = SingleProviderResolver.getInstance().resolve(c);
266      config.setImplementation(c);
267      extraConfigurationBuilder = imp.createConfigurationBuilder(root());
268      return (Builder<K, T, EXTRA_CONFIG_BUILDER>) this;
269    }
270
271    public <EXTRA_CONFIG_BUILDER extends AnyBuilder<K, T, ?>> EXTRA_CONFIG_BUILDER extra(
272      Class<? extends StorageImplementation<EXTRA_CONFIG_BUILDER>> c) {
273      StorageImplementation<EXTRA_CONFIG_BUILDER> imp = SingleProviderResolver.getInstance().resolve(c);
274      config.setImplementation(c);
275      extraConfigurationBuilder = imp.createConfigurationBuilder(root());
276      return (EXTRA_CONFIG_BUILDER) extraConfigurationBuilder;
277    }
278
279    public OPT_EXTRA_CONFIG extra() {
280      if (extraConfigurationBuilder == null) {
281        throw new IllegalArgumentException("storage implementation has no extra configuration");
282      }
283      return (OPT_EXTRA_CONFIG) extraConfigurationBuilder;
284    }
285
286    @Override
287    public StorageConfiguration createConfiguration() {
288      if (extraConfigurationBuilder != null) {
289        config.setExtraConfiguration(
290          extraConfigurationBuilder.createConfiguration());
291      }
292      return config;
293    }
294
295  }
296
297}