package org.dainst.gazetteer.helpers;

import org.dainst.gazetteer.domain.Place;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.Document;

public class MongoBasedIncrementingIdGenerator implements IdGenerator {
	
	private MongoTemplate mongoTemplate;
	
	private int blockSize = 100;
	
	private long nextId = 0;

	private Counter counter;
	
	public MongoBasedIncrementingIdGenerator(MongoTemplate mongoTemplate, String counterId, long start) {
		this.mongoTemplate = mongoTemplate;
		counter = mongoTemplate.findById(counterId, Counter.class);
		if (counter == null) {
			counter = new Counter();
			counter.setId(counterId);
			counter.setValue(start);
		}
		nextId = counter.getValue();
		allocateBlock();
	}

	@Override
	public String generate(Place place) {
		if (nextId >= counter.getValue()) {
			allocateBlock();
		}
		return String.valueOf(nextId++);
	}
	
	private void allocateBlock() {
		counter.inc(blockSize);
		mongoTemplate.save(counter);
	}

	public void setBlockSize(int step) {
		this.blockSize = step;
	}
	
	@Document
	public static class Counter {
		
		@Id
		private String id;
		
		private long value = 1;
		
		public Counter() {
			
		}
		
		public void inc(int step) {
			this.value += step;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public long getValue() {
			return value;
		}

		public void setValue(long value) {
			this.value = value;
		}
		
	}

}

@@ -74,16 +74,73 @@
 .Place;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -300,16 +300,81 @@
 ocument;
+%0Aimport org.springframework.transaction.annotation.Transactional;
 %0A%0Apublic
@@ -441,16 +441,122 @@
 tor %7B%0A%09%0A
+%09private static final Logger LOGGER = LoggerFactory.getLogger(MongoBasedIncrementingIdGenerator.class);%0A%09%0A
 %09private
@@ -987,16 +987,48 @@
 start);%0A
+%09%09%09mongoTemplate.save(counter);%0A
 %09%09%7D%0A%09%09ne
@@ -1195,394 +1195,1145 @@
 %7D%0A%09%09
-return String.valueOf(nextId++);%0A%09%7D%0A%09%0A%09private void allocateBlock() %7B%0A%09%09counter.inc(blockSize);%0A%09%09mongoTemplate.save(counter);%0A%09%7D%0A%0A%09public void setBlockSize(int step) %7B%0A%09%09this.blockSize = step;%0A%09%7D%0A%09%0A%09@Document%0A%09public static class Counter %7B%0A%09%09%0A%09%09@Id%0A%09%09private String id;%0A%09%09%0A%09%09private long value = 1;%0A%09%09%0A%09%09public Counter() %7B%0A%09%09%09%0A%09%09%7D%0A%09%09%0A%09%09public void inc(int step) %7B%0A%09%09%09this.value += step
+LOGGER.debug(Thread.currentThread().getName() + %22 - generated ID %22 + (nextId));%0A%09%09return String.valueOf(nextId++);%0A%09%7D%0A%09%0A%09@Transactional%0A%09private synchronized void allocateBlock() %7B%0A%09%09LOGGER.debug(Thread.currentThread().getName() + %22 - start allocateBlock()%22);%0A%09%09counter = mongoTemplate.findById(counter.getId(), Counter.class);%0A%09%09counter.inc(blockSize);%0A%09%09mongoTemplate.save(counter);%0A%09%09LOGGER.debug(Thread.currentThread().getName() + %22 - allocated IDs up to %22 + counter.getValue());%0A%09%09LOGGER.debug(Thread.currentThread().getName() + %22 - end allocateBlock()%22);%0A%09%7D%0A%0A%09public void setBlockSize(int step) %7B%0A%09%09this.blockSize = step;%0A%09%7D%0A%09%0A%09@Document%0A%09public static class Counter %7B%0A%09%09%0A%09%09@Id%0A%09%09private String id;%0A%09%09%0A%09%09private long value = 1;%0A%09%09%0A%09%09public Counter() %7B%0A%09%09%09%0A%09%09%7D%0A%09%09%0A%09%09// copy constructor%0A%09%09public Counter(Counter counter) %7B%0A%09%09%09this.id = counter.getId();%0A%09%09%09this.value = counter.getValue();%0A%09%09%09LOGGER.debug(Thread.currentThread().getName() + %22 - created counter with %22 + getValue());%0A%09%09%7D%0A%0A%09%09public void inc(int step) %7B%0A%09%09%09this.value += step;%0A%09%09%09LOGGER.debug(Thread.currentThread().getName() + %22 - incremented counter to %22 + getValue())
 ;%0A%09%09

fix bug in mongo based id generator