package polly.rx.core.orion.datasource; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import polly.rx.core.orion.QuadrantProvider; import polly.rx.core.orion.WormholeProvider; import polly.rx.core.orion.model.LoadRequired; import polly.rx.core.orion.model.OrionObjectUtil; import polly.rx.core.orion.model.Quadrant; import polly.rx.core.orion.model.Sector; import polly.rx.core.orion.model.Wormhole; import polly.rx.parsing.RegexUtils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import de.skuzzle.polly.tools.EqualsHelper; import de.skuzzle.polly.tools.Equatable; import de.skuzzle.polly.tools.io.WebUtils; public class WLSWormholeProvider implements WormholeProvider { private final static String BASE_URL = "http://wls.nullpointer.at/"; //$NON-NLS-1$ private final static String API_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; //$NON-NLS-1$ private final static Pattern UNLOAD_PATTERN = Pattern.compile("(\\d+)-(\\d+) Min"); //$NON-NLS-1$ private final static Pattern COMMENT = Pattern.compile("<!--.*-->"); //$NON-NLS-1$ @SuppressWarnings("unused") private class WLSQuadrant { public int id; public String name; public String url; } @SuppressWarnings("unused") public static class WLSWormhole implements Wormhole { /* filled by json deserialization */ private int id; private String von_quadrant; private int von_x; private int von_y; private String nach_quadrant; private int nach_x; private int nach_y; private String name; private String geladen; private String entladung; private boolean expired; private Date date; private transient int minUnload; private transient int maxUnload; private transient LoadRequired loadRequired; private transient Sector source; private transient Sector target; @Override public String getName() { return this.name; } @Override public Date getDate() { return date; } @Override public int getMinUnload() { return this.minUnload; } @Override public int getMaxUnload() { return this.maxUnload; } @Override public Sector getTarget() { return this.target; } @Override public Sector getSource() { return this.source; } @Override public LoadRequired requiresLoad() { return this.loadRequired; } @Override public String toString() { return OrionObjectUtil.wormholeString(this); } @Override public int hashCode() { return OrionObjectUtil.wormholeHash(this); } @Override public final boolean equals(Object obj) { return EqualsHelper.testEquality(this, obj); } @Override public Class<?> getEquivalenceClass() { return Wormhole.class; } @Override public boolean actualEquals(Equatable o) { return OrionObjectUtil.wormholesEquals(this, (Wormhole) o); } } private final Map<String, WLSQuadrant> quadrants; private final Map<String, List<Wormhole>> quadHoleCache; public WLSWormholeProvider() { this.quadrants = new HashMap<>(); this.quadHoleCache = new HashMap<>(); this.findQuadrants(this.quadrants); } private String performRequest(String query) { try { final String response = WebUtils.getString(BASE_URL + query).toString(); final String result = COMMENT.matcher(response.toString()).replaceAll(""); //$NON-NLS-1$ return result; } catch (IOException e) { return ""; //$NON-NLS-1$ } } private void findQuadrants(Map<String, WLSQuadrant> r) { r.clear(); final String QUERY = "quadranten/json"; //$NON-NLS-1$ final String result = this.performRequest(QUERY); if (result.equals("")) { //$NON-NLS-1$ return; } final Gson gson = new GsonBuilder().create(); final WLSQuadrant[] quads = gson.fromJson(result, WLSQuadrant[].class); for (WLSQuadrant quad : quads) { r.put(quad.name, quad); } } private synchronized void refreshWormholes( Map<String, List<Wormhole>> r, QuadrantProvider quads) { r.clear(); final String QUERY = "v/0/alle/json/"; //$NON-NLS-1$ final String result = this.performRequest(QUERY); if (result == "") { //$NON-NLS-1$ return; } final Gson gson = new GsonBuilder().setDateFormat(API_DATE_FORMAT).create(); final WLSWormhole[] holes = gson.fromJson(result, WLSWormhole[].class); for (final WLSWormhole hole : holes) { final Quadrant sourceQuadrant = quads.getQuadrant(hole.von_quadrant); final Quadrant targetQuadrant = quads.getQuadrant(hole.nach_quadrant); hole.source = sourceQuadrant.getSector(hole.von_x, hole.von_y); hole.target = targetQuadrant.getSector(hole.nach_x, hole.nach_y); hole.loadRequired = LoadRequired.parse(hole.geladen); final Matcher m = UNLOAD_PATTERN.matcher(hole.entladung); if (m.matches()) { hole.minUnload = RegexUtils.subint(hole.entladung, m, 1); hole.maxUnload = RegexUtils.subint(hole.entladung, m, 2); } List<Wormhole> list = r.get(hole.von_quadrant); if (list == null) { list = new ArrayList<>(); r.put(hole.von_quadrant, list); } list.add(hole); } } @Override public List<Wormhole> getWormholes(Quadrant quadrant, QuadrantProvider quads) { if (this.quadHoleCache.isEmpty()) { this.refreshWormholes(this.quadHoleCache, quads); } final List<Wormhole> wormholes = this.quadHoleCache.get(quadrant.getName()); if (wormholes == null) { return Collections.emptyList(); } return wormholes; } @Override public List<Wormhole> getWormholes(Sector sector, QuadrantProvider quads) { if (this.quadHoleCache.isEmpty()) { this.refreshWormholes(this.quadHoleCache, quads); } final String quadName = sector.getQuadName(); final List<Wormhole> wlsHoles = this.quadHoleCache.get(quadName); if (wlsHoles == null) { return Collections.emptyList(); } final List<Wormhole> result = new ArrayList<>(wlsHoles.size()); for (final Wormhole hole : wlsHoles) { if (hole.getSource().equals(sector)) { result.add(hole); } } return result; } }