package polly.rx.core.orion.http; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.List; import java.util.Map; import polly.rx.MSG; import polly.rx.core.TrainManagerV2; import polly.rx.core.TrainingEvent; import polly.rx.core.TrainingListener; import polly.rx.core.orion.FleetEvent; import polly.rx.core.orion.FleetListener; import polly.rx.core.orion.FleetTracker; import polly.rx.core.orion.Orion; import polly.rx.core.orion.PortalEvent; import polly.rx.core.orion.PortalListener; import polly.rx.core.orion.PortalUpdater; import polly.rx.core.orion.http.NewsEntry.NewsType; import polly.rx.core.orion.model.Fleet; import polly.rx.core.orion.model.Portal; import polly.rx.core.orion.model.json.OrionJsonAdapter; import de.skuzzle.polly.http.api.HttpEvent; import de.skuzzle.polly.http.api.HttpException; import de.skuzzle.polly.http.api.answers.HttpAnswer; import de.skuzzle.polly.http.api.answers.HttpAnswers; import de.skuzzle.polly.http.api.handler.HttpEventHandler; import de.skuzzle.polly.sdk.MyPolly; import de.skuzzle.polly.sdk.User; import de.skuzzle.polly.sdk.httpv2.GsonHttpAnswer; import de.skuzzle.polly.sdk.httpv2.SuccessResult; import de.skuzzle.polly.sdk.time.Time; public class OrionNewsProvider implements HttpEventHandler, FleetListener, PortalListener, TrainingListener { public final static String NEWS_URL = "/api/orion/json/news"; //$NON-NLS-1$ private final static int MAX_NEWS = 100; private final Deque<NewsEntry> entries; private final Map<String, Deque<NewsEntry>> forVenads; private final MyPolly myPolly; public OrionNewsProvider(MyPolly myPolly, FleetTracker fleetTracker, PortalUpdater portalUpdater, TrainManagerV2 trainManager) { this.myPolly = myPolly; this.entries = new ArrayDeque<>(); this.forVenads = new HashMap<>(); fleetTracker.addFleetListener(this); portalUpdater.addPortalListener(this); trainManager.addTrainListener(this); } private void addNews(NewsEntry e) { synchronized (this.entries) { this.addNews(this.entries, e); } } private void addNews(Deque<NewsEntry> entries, NewsEntry e) { if (entries.contains(e)) { entries.remove(e); } if (entries.size() == MAX_NEWS) { entries.removeLast(); } entries.addFirst(e); } private void addNews(String forVenad, NewsEntry e) { synchronized (this.forVenads) { Deque<NewsEntry> entries = this.forVenads.get(forVenad); if (entries == null) { entries = new ArrayDeque<>(); this.forVenads.put(forVenad, entries); } this.addNews(entries, e); } } private NewsEntry[] tailorFor(String venad) { synchronized (this.entries) { final List<NewsEntry> result = new ArrayList<>(this.entries); final Collection<NewsEntry> forVenad = this.forVenads.get(venad); if (forVenad != null) { result.addAll(forVenad); } // Manually add all orion fleets Orion.INSTANCE.getFleetTracker().getOrionUserFleets().forEach(f -> { result.add((new NewsEntry(f.getOwnerName(), NewsType.ORION_FLEET, f, f.getDate()))); }); for (final NewsEntry ne : this.entries) { if (!result.contains(ne)) { result.add(ne); } } Collections.sort(result); return result.toArray(new NewsEntry[result.size()]); } } @Override public void ownFleetsUpdated(FleetEvent e) { } @Override public void fleetsUpdated(FleetEvent e) { for (final Fleet fleet : e.getFleets()) { this.addNews(new NewsEntry(e.getReporter(), NewsType.FLEET_SPOTTED, fleet, fleet.getDate())); } } @Override public HttpAnswer handleHttpEvent(String registered, HttpEvent e, HttpEventHandler next) throws HttpException { final String userName = e.get("user"); //$NON-NLS-1$ final User user = this.myPolly.users().getUser(userName); final String password = e.get("pw"); //$NON-NLS-1$ if (user == null || !user.getHashedPassword().equalsIgnoreCase(password)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpIllegalLogin)); } else if (!this.myPolly.roles().hasPermission(user, OrionController.VIEW_ORION_PREMISSION)) { return new GsonHttpAnswer(200, new SuccessResult(false, MSG.httpNoPermission)); } synchronized (this.entries) { final String venad = e.get("venad"); //$NON-NLS-1$ final NewsEntry[] entryArray = this.tailorFor(venad); return HttpAnswers.newStringAnswer(OrionJsonAdapter.GSON.toJson(entryArray)); } } @Override public void portalsAdded(PortalEvent e) { for (final Portal p : e.getPortals()) { this.addNews(new NewsEntry(e.getReporter(), NewsType.PORTAL_ADDED, p, p.getDate())); } } @Override public void portalsMoved(PortalEvent e) { for (final Portal p : e.getPortals()) { this.addNews(new NewsEntry(e.getReporter(), NewsType.PORTAL_MOVED, p, p.getDate())); } } @Override public void portalsRemoved(PortalEvent e) { for (final Portal p : e.getPortals()) { this.addNews(new NewsEntry(e.getReporter(), NewsType.PORTAL_REMOVED, p, p.getDate())); } } @Override public void trainingAdded(TrainingEvent e) { final User trainer = e.getSource().getTrainer(e.getTraining().getTrainerId()); this.addNews(e.getTraining().getForUser(), new NewsEntry(trainer.getName(), NewsType.TRAINING_ADDED, e.getTraining(), e.getTraining().getTrainStart())); } @Override public void trainingFinished(TrainingEvent e) { final User trainer = e.getSource().getTrainer(e.getTraining().getTrainerId()); this.addNews(e.getTraining().getForUser(), new NewsEntry(trainer.getName(), NewsType.TRAINING_FINISHED, e.getTraining(), e.getTraining().getTrainFinished())); } @Override public void trainingClosed(TrainingEvent e) { } @Override public void billClosed(TrainingEvent e) { this.addNews("", new NewsEntry("", //$NON-NLS-1$ //$NON-NLS-2$ NewsType.BILL_CLOSED, null, Time.currentTime())); } }