package polly.rx.core.orion.datasource; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import polly.rx.core.orion.OrionException; import polly.rx.core.orion.QuadrantEvent; import polly.rx.core.orion.QuadrantListener; import polly.rx.core.orion.QuadrantUpdater; import polly.rx.core.orion.QuadrantUtils; import polly.rx.core.orion.model.Quadrant; import polly.rx.core.orion.model.Sector; import polly.rx.entities.DBQuadrant; import polly.rx.entities.DBSector; import de.skuzzle.jeve.EventProvider; import de.skuzzle.polly.sdk.PersistenceManagerV2; import de.skuzzle.polly.sdk.PersistenceManagerV2.Param; import de.skuzzle.polly.sdk.PersistenceManagerV2.Read; import de.skuzzle.polly.sdk.PersistenceManagerV2.Write; import de.skuzzle.polly.sdk.exceptions.DatabaseException; public class DBQuadrantUpdater implements QuadrantUpdater { private final PersistenceManagerV2 persistence; private final EventProvider eventProvider; public DBQuadrantUpdater(PersistenceManagerV2 persistence) { this.persistence = persistence; this.eventProvider = EventProvider.newDefaultEventProvider(); } public void addQuadrantListener(QuadrantListener listener) { this.eventProvider.addListener(QuadrantListener.class, listener); } public void removeQuadrantListener(QuadrantListener listener) { this.eventProvider.removeListener(QuadrantListener.class, listener); } private void fireQuadrantDeleted(Quadrant quad) { final QuadrantEvent e = new QuadrantEvent(this, quad, quad.getSectors()); this.eventProvider.dispatch(QuadrantListener.class, e, QuadrantListener::quadrantDeleted); } private void fireQuadrantAdded(Quadrant quad) { final QuadrantEvent e = new QuadrantEvent(this, quad, quad.getSectors()); this.eventProvider.dispatch(QuadrantListener.class, e, QuadrantListener::quadrantAdded); } private void fireSectorsAdded(Collection<? extends Sector> sectors) { final QuadrantEvent e = new QuadrantEvent(this, null, sectors); this.eventProvider.dispatch(QuadrantListener.class, e, QuadrantListener::sectorsAdded); } private void fireSectorsUpdated(Collection<? extends Sector> sectors) { final QuadrantEvent e = new QuadrantEvent(this, null, sectors); this.eventProvider.dispatch(QuadrantListener.class, e, QuadrantListener::sectorsUpdated); } @Override public void deleteQuadrant(String quadName) throws OrionException { quadName = quadName.trim(); try (final Write write = this.persistence.write()) { final Read read = write.read(); final DBQuadrant existing = read.findSingle(DBQuadrant.class, DBQuadrant.QUERY_QUADRANT_BY_NAME, new Param(quadName)); if (existing != null) { write.removeAll(existing.getSectors()); write.remove(existing); this.fireQuadrantDeleted(existing); } } catch (DatabaseException e) { throw new OrionException(e); } } @Override public void deleteQuadrant(Quadrant quadrant) throws OrionException { this.deleteQuadrant(quadrant.getName()); } @Override public synchronized Collection<DBSector> updateSectorInformation( Collection<? extends Sector> sectors) throws OrionException { if (sectors.isEmpty()) { return Collections.emptyList(); } final Map<String, DBQuadrant> quadCache = new HashMap<>(); final Map<String, DBSector> sectorCache = new HashMap<>(); final Collection<DBSector> updated = new HashSet<>(); try (final Write write = this.persistence.write()) { final Read read = write.read(); for (final Sector sector : sectors) { final DBSector existing = this.findSector(read, sectorCache, sector); if (existing != null) { existing.updateFrom(sector, write); updated.add(existing); } else { DBQuadrant quadrant = this.findQuadrant(read, quadCache, sector.getQuadName()); if (quadrant == null) { // create new quadrant quadrant = new DBQuadrant(sector.getQuadName()); quadCache.put(sector.getQuadName(), quadrant); write.single(quadrant); } final DBSector newSector = quadrant.updateFrom(sector, write); if (newSector != null) { sectorCache.put(QuadrantUtils.createMapKey(newSector), newSector); } } } } catch (DatabaseException e) { throw new OrionException(e); } for (final DBQuadrant quad : quadCache.values()) { this.fireQuadrantAdded(quad); } this.fireSectorsAdded(sectorCache.values()); this.fireSectorsUpdated(updated); final ArrayList<DBSector> result = new ArrayList<>( sectorCache.values().size() + updated.size()); result.addAll(sectorCache.values()); result.addAll(updated); return result; } private final DBSector findSector(Read read, Map<String, DBSector> tempCache, Sector s) { DBSector sector = tempCache.get(QuadrantUtils.createMapKey(s)); if (sector == null) { sector = read.findSingle(DBSector.class, DBSector.QUERY_FIND_SECTOR, new Param(s.getQuadName(), s.getX(), s.getY())); } return sector; } private DBQuadrant findQuadrant(Read read, Map<String, DBQuadrant> tempCache, String name) { DBQuadrant quad = tempCache.get(name); if (quad == null) { quad = read.findSingle(DBQuadrant.class, DBQuadrant.QUERY_QUADRANT_BY_NAME, new Param(name)); } return quad; } }