package com.netifera.platform.internal.model; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.db4o.ObjectContainer; import com.netifera.platform.api.events.EventListenerManager; import com.netifera.platform.api.events.IEventHandler; import com.netifera.platform.api.log.ILogger; import com.netifera.platform.api.model.IEntity; import com.netifera.platform.api.model.ISpace; import com.netifera.platform.api.probe.IProbe; public class SpaceManager { private long currentSpaceId; private transient Set<ISpace> openSpaces; private Set<ISpace> allSpaces; private Map <Long, ISpace> taskIdToSpace; private Map <Long, ISpace> spaceIdToSpace; private transient ObjectContainer database; private transient Workspace workspace; private transient EventListenerManager changeListeners; private transient ILogger logger; public static SpaceManager getSpaceManager(final ObjectContainer db, final Workspace workspace) { final List<SpaceManager> result = db.query(SpaceManager.class); if(result.isEmpty()) { return new SpaceManager(db, workspace); } else if(result.size() == 1) { return result.get(0).initialize(db, workspace); } else { throw new IllegalStateException("Multiple SpaceManager objects found in database"); } } ObjectContainer getDatabase() { return database; } private SpaceManager(ObjectContainer db, Workspace workspace) { initialize(db, workspace); allSpaces = new HashSet<ISpace>(); taskIdToSpace = new HashMap<Long, ISpace>(); spaceIdToSpace = new HashMap<Long, ISpace>(); commit(); } private SpaceManager initialize(ObjectContainer db, Workspace workspace) { this.database = db; this.workspace = workspace; this.openSpaces = new HashSet<ISpace>(); if(workspace != null) { logger = workspace.getLogger(); } return this; } public Workspace getWorkspace() { return workspace; } public ILogger getLogger() { return logger; } public ISpace findSpaceById(long id) { return spaceIdToSpace.get(id); } public Set<ISpace> getAllSpaces() { return Collections.unmodifiableSet(allSpaces); } public synchronized Set<ISpace> getOpenSpaces() { return Collections.unmodifiableSet(openSpaces); } public synchronized ISpace findSpaceForTaskId(long taskId) { return taskIdToSpace.get(taskId); } public synchronized void notifySpaceChange(ISpace space) { fireSpaceChangeEvent(space); } public synchronized void addTaskToSpace(long taskId, ISpace space) { taskIdToSpace.put(taskId, space); database.store(taskIdToSpace); fireSpaceChangeEvent(space); } synchronized void openSpace(ISpace space) { openSpaces.add(space); fireSpaceChangeEvent(space); } synchronized void closeSpace(ISpace space) { openSpaces.remove(space); fireSpaceChangeEvent(space); } public synchronized ISpace createSpace(IEntity root, IProbe probe) { final long id = generateNewViewId(); final ISpace space = new Space(id, probe, "Space " + id, root, this); database.store(space); allSpaces.add(space); spaceIdToSpace.put(space.getId(), space); database.store(allSpaces); database.store(spaceIdToSpace); commit(); getEventManager().fireEvent(SpaceStatusChangeEvent.createNewEvent(space)); return space; } private synchronized long generateNewViewId() { currentSpaceId += 1; commit(); return currentSpaceId; } private void commit() { database.store(this); } private void fireSpaceChangeEvent(ISpace space) { getEventManager().fireEvent(SpaceStatusChangeEvent.createChangedEvent(space)); } public void addChangeListener(IEventHandler handler) { getEventManager().addListener(handler); } public void removeChangeListener(IEventHandler handler) { getEventManager().removeListener(handler); } private EventListenerManager getEventManager() { if(changeListeners == null) { changeListeners = new EventListenerManager(); } return changeListeners; } }