package <%=package%>;

import java.util.concurrent.locks.ReadWriteLock;

import com.hammurapi.eventbus.AbstractEventBus;
import com.hammurapi.eventbus.HandleExtractor;
import com.hammurapi.extract.Predicate;
import com.hammurapi.store.AbstractStore;
import com.hammurapi.store.DeputyStore;
import com.hammurapi.store.LiveView;
import com.hammurapi.store.UnmodifiableStore;
import com.hammurapi.store.local.LocalStoreBase;

/**
 * Implementation of event store.
 */
public class <%=domain%>EventStoreImpl extends LocalStoreBase<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=E%>, <%=domain%>EventStore> implements <%=domain%>EventStore {

	/**
	 * Config class with bound generic parameters. 
	 * @author Pavel Vlasov
	 *
	 */
	public static class Config extends LocalStoreBase.Config<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=E%>, <%=domain%>EventStore> {
		
		public Config() {
			// Comment out if events are mutable.
			setPrimaryKeyExtractor(new HandleExtractor<<%=E%>, <%=P%>, <%=C%>, Long, AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=domain%>EventStore>());
		}
	}

	public <%=domain%>EventStoreImpl(Config config) {
		super(config);
	}
	
	protected static class <%=domain%>EventDeputyStore extends DeputyStore<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=E%>, <%=domain%>EventStore> implements <%=domain%>EventStore {

		public <%=domain%>EventDeputyStore(
				AbstractStore<AbstractEventBus.Handle<<%=E%>, <%=P%>, <%=C%>, Long>, <%=E%>, <%=domain%>EventStore> master,
				ReadWriteLock masterLock) {
			super(master, masterLock);
		}

		@Override
		protected <%=domain%>EventStore createDeputy() {
			return new <%=domain%>EventDeputyStore(this, createMasterLock());
		}
		
		@Override
		public <%=domain%>EventStore createUnmodifiableFacade() {
			return new <%=domain%>EventUnmodifiableStore(this);
		}

		@Override
		protected <%=domain%>EventStore createLiveView(Predicate<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=domain%>EventStore> selector) {
			return new <%=domain%>EventLiveView(this, selector);
		}
		
	}
	
	protected static class <%=domain%>EventUnmodifiableStore extends UnmodifiableStore<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=E%>, <%=domain%>EventStore> implements <%=domain%>EventStore {

		public <%=domain%>EventUnmodifiableStore(<%=domain%>EventStore master) {
			super(master);
		}
		
	}
	
	protected static class <%=domain%>EventLiveView extends LiveView<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=E%>, <%=domain%>EventStore> implements <%=domain%>EventStore {
		
		public <%=domain%>EventLiveView(
				<%=domain%>EventStore master,
				Predicate<AbstractEventBus.Handle<<%=E%>, <%=P%>, <%=C%>, Long>, <%=domain%>EventStore> selector) {
			super(master, selector);
		}

		@Override
		public <%=domain%>EventStore createUnmodifiableFacade() {
			return new <%=domain%>EventUnmodifiableStore(this);
		}
		
	}

	@Override
	protected <%=domain%>EventStore createDeputy() {
		return new <%=domain%>EventDeputyStore(this, createMasterLock());
	}
	
	@Override
	public <%=domain%>EventStore createUnmodifiableFacade() {
		return new <%=domain%>EventUnmodifiableStore(this);
	}

	@Override
	protected <%=domain%>EventStore createLiveView(Predicate<AbstractEventBus.Handle<<%=E%>,<%=P%>,<%=C%>,Long>, <%=domain%>EventStore> selector) {
		return new <%=domain%>EventLiveView(this, selector);
	}

}
