/* * (c) Copyright 2009-2011 by Volker Bergmann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted under the terms of the * GNU General Public License. * * For redistributing this software or a derivative work under a license other * than the GPL-compatible Free Software License as defined by the Free * Software Foundation or approved by OSI, you must first obtain a commercial * license to this software product from Volker Bergmann. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS, * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package org.databene.benerator.primitive; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.databene.benerator.Generator; import org.databene.benerator.NonNullGenerator; import org.databene.benerator.wrapper.NonNullGeneratorProxy; import org.databene.commons.ConfigurationError; import org.databene.commons.FileUtil; import org.databene.commons.IOUtil; /** * Local implementation of an increment {@link Generator} that behaves like a database sequence.<br/> * <br/> * Created at 29.05.2009 19:35:27 * @since 0.6.0 * @author Volker Bergmann */ public class LocalSequenceGenerator extends NonNullGeneratorProxy<Long> { static final String FILENAME = LocalSequenceGenerator.class.getSimpleName() + ".properties"; private static final Map<String, IncrementalIdGenerator> MAP = new HashMap<String, IncrementalIdGenerator>(); private boolean cached; // Initialization -------------------------------------------------------------------------------------------------- static { init(); } public LocalSequenceGenerator() { this("default"); } public LocalSequenceGenerator(String name) { this(name, true); } public LocalSequenceGenerator(String name, boolean cached) { super(getOrCreateSource(name, 1)); this.cached = cached; } public boolean isCached() { return cached; } public void setCached(boolean cached) { this.cached = cached; } // Generator interface --------------------------------------------------------------------------------------------- @Override public Long generate() { Long result = super.generate(); if (!cached) persist(); return result; } @Override public void reset() { // ignore reset - we need to generate unique values! } @Override public void close() { persist(); super.close(); } // static methods -------------------------------------------------------------------------------------------------- public static void resetAll() { FileUtil.deleteIfExists(new File(FILENAME)); invalidateInstances(); } public static void invalidateInstances() { MAP.clear(); init(); } public static Long next(String sequenceName) { return next(sequenceName, 1); } public static Long next(String sequenceName, long min) { return getOrCreateSource(sequenceName, min).generate(); } public static void persist() { Map<String, String> values = new HashMap<String, String>(); for (Map.Entry<String, IncrementalIdGenerator> entry : MAP.entrySet()) values.put(entry.getKey(), String.valueOf(entry.getValue().getCursor())); try { IOUtil.writeProperties(values, FILENAME); } catch (IOException e) { throw new RuntimeException(e); } } // private helpers ------------------------------------------------------------------------------------------------- private static void init() { if (IOUtil.isURIAvailable(FILENAME)) { try { Map<String, String> values = IOUtil.readProperties(FILENAME); for (Map.Entry<String, String> entry : values.entrySet()) MAP.put(entry.getKey(), new IncrementalIdGenerator(Long.parseLong(entry.getValue()))); } catch (Exception e) { throw new ConfigurationError(e); } } } private static NonNullGenerator<Long> getOrCreateSource(String name, long min) { IncrementalIdGenerator generator = MAP.get(name); if (generator == null) { generator = new IncrementalIdGenerator(min); MAP.put(name, generator); } return generator; } }