From c6cec94b865c1dc50ef1699aa4e73e1fc519198b Mon Sep 17 00:00:00 2001 From: gotty Date: Wed, 15 Jan 2020 22:51:09 +0300 Subject: [PATCH] [LIB-13] Lazy scanners init, scan by URL and rename API functions --- .../hedgecode/chess/scanner/ChessHogScanner.java | 82 +++++++++++++++++----- .../chess/scanner/ChessHogScannerConsole.java | 4 +- .../chess/scanner/ChessHogScannerConstants.java | 18 +++-- .../chess/scanner/ChessHogScannerProperties.java | 31 +++++++- .../java/org/hedgecode/chess/scanner/Scanner.java | 8 ++- .../org/hedgecode/chess/scanner/ScannerType.java | 30 ++++++-- .../chess/scanner/portal/ChessBombScanner.java | 15 ++-- .../chess/scanner/portal/ChessGamesScanner.java | 15 ++-- .../chess/scanner/portal/LiChessScanner.java | 13 ++-- src/main/resources/scanner.properties | 2 + 10 files changed, 169 insertions(+), 49 deletions(-) diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java index 9b90990..fdb5036 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java @@ -16,9 +16,14 @@ package org.hedgecode.chess.scanner; +import java.net.MalformedURLException; +import java.net.URL; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import org.hedgecode.chess.scanner.entity.PGNGame; import org.hedgecode.chess.scanner.portal.ChessBombScanner; import org.hedgecode.chess.scanner.portal.ChessGamesScanner; import org.hedgecode.chess.scanner.portal.LiChessScanner; @@ -30,9 +35,9 @@ import org.hedgecode.chess.scanner.portal.LiChessScanner; */ public final class ChessHogScanner { - private static ChessHogScanner _instance; + private static ChessHogScanner singleton; - private final Map SCANNERS = new HashMap() { + private final Map scanners = new HashMap() { { put( ScannerType.CHESSGAMES, new ChessGamesScanner() ); put( ScannerType.LICHESS, new LiChessScanner() ); @@ -40,36 +45,81 @@ public final class ChessHogScanner { } }; - public static Scanner get(ScannerType type) { - return getInstance().scanner(type); + private final Set initScanners = new HashSet<>(); + + /** + * Get Scanner by {@code ScannerType}. + * + * @param type Scanner type (binding to specific chess portal). + * @return Implementation of {@code Scanner} for specific portal. + */ + public static Scanner scanner(ScannerType type) { + return getStore().getScanner(type); + } + + /** + * Scan PGN game by URL (for all scanner types). + * + * @param url URL string for scan. + * @return PGN game. + * @throws ChessHogScannerException Incorrect URL or unknown chess portal. + */ + public static PGNGame scan(String url) throws ChessHogScannerException { + String hostName; + try { + hostName = new URL(url).getHost(); + } catch (MalformedURLException cause) { + throw new ChessHogScannerException( + String.format("Incorrect URL: %s", url), cause + ); + } + ScannerType type = ScannerType.byHost(hostName); + if (type == null) { + throw new ChessHogScannerException( + String.format("Host %s is not among the known for the scanner", hostName) + ); + } + return scanner(type).scanUrl(url); } private void init() { + for (ScannerType type : scanners.keySet()) { + init(type); + } + } + + private void init(ScannerType type) { + Scanner scanner = scanners.get(type); try { - for (Scanner scanner : SCANNERS.values()) { - if (scanner instanceof Initiable) { - Initiable initiableScanner = (Initiable) scanner; - initiableScanner.init(); - } + if (scanner instanceof Initiable) { + Initiable initiableScanner = (Initiable) scanner; + initiableScanner.init(); } + initScanners.add(type); } catch (ChessHogScannerException e) { throw new RuntimeException(e); } } - private Scanner scanner(ScannerType type) { - return SCANNERS.get(type); + + private Scanner getScanner(ScannerType type) { + if (!initScanners.contains(type)) { + init(type); + } + return scanners.get(type); } private ChessHogScanner() { + if (!ChessHogScannerProperties.is("scanner.lazy.init")) { + init(); + } } - private static ChessHogScanner getInstance() { - if (_instance == null) { - _instance = new ChessHogScanner(); - _instance.init(); + private static ChessHogScanner getStore() { + if (singleton == null) { + singleton = new ChessHogScanner(); } - return _instance; + return singleton; } } diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConsole.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConsole.java index b3becd9..4b824fb 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConsole.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConsole.java @@ -78,9 +78,7 @@ public class ChessHogScannerConsole { } private static void copyright() { - int inceptionYear = Integer.parseInt( - ChessHogScannerProperties.get("scanner.inception.year") - ); + int inceptionYear = ChessHogScannerProperties.getInt("scanner.inception.year"); int currentYear = Calendar.getInstance().get(Calendar.YEAR); String copyright = currentYear > inceptionYear ? String.format("%s-%s %s", inceptionYear, currentYear, COPYRIGHT) diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConstants.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConstants.java index 651a3e4..50eb391 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConstants.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerConstants.java @@ -30,11 +30,17 @@ public final class ChessHogScannerConstants { public static final String CRLF = System.getProperty("line.separator"); - public static final String PORTAL_CHESSGAMES = "chessgames"; - public static final String PORTAL_LICHESS = "lichess"; - public static final String PORTAL_CHESSBOMB = "chessbomb"; - public static final String PORTAL_CHESS24 = "chess24"; - public static final String PORTAL_CHESSCOM = "chesscom"; + public static final String TYPE_CHESSGAMES = "chessgames"; + public static final String TYPE_LICHESS = "lichess"; + public static final String TYPE_CHESSBOMB = "chessbomb"; + public static final String TYPE_CHESS24 = "chess24"; + public static final String TYPE_CHESSCOM = "chesscom"; + + public static final String DOMAIN_CHESSGAMES = "chessgames.com"; + public static final String DOMAIN_LICHESS = "lichess.org"; + public static final String DOMAIN_CHESSBOMB = "www.chessbomb.com"; + public static final String DOMAIN_CHESS24 = "chess24.com"; + public static final String DOMAIN_CHESSCOM = "chess.com"; public static final String PROXY_UNDEFINED = "undefined"; public static final String PROXY_HTTP = "http"; @@ -42,7 +48,7 @@ public final class ChessHogScannerConstants { private ChessHogScannerConstants() { throw new AssertionError( - String.format("No %s instances!", ChessHogScannerConstants.class.getName()) + String.format("No %s instances!", getClass().getName()) ); } diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerProperties.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerProperties.java index e7565bc..fdead40 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerProperties.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerProperties.java @@ -73,7 +73,7 @@ public class ChessHogScannerProperties { private static final String EMPTY = ""; /** - * Gets property value. + * Gets string property value. * * @param key Property key. * @return Property value (possibly empty string, but never {@code null}). @@ -83,6 +83,35 @@ public class ChessHogScannerProperties { } /** + * Gets boolean property value. + * + * @param key Property key. + * @return Property value ({@code false} by default). + */ + public static boolean is(String key) { + return Boolean.parseBoolean( + PROPERTIES.getProperty(key, Boolean.FALSE.toString()) + ); + } + + /** + * Zero integer for not found properties. + */ + private static final String ZERO = "0"; + + /** + * Gets integer property value. + * + * @param key Property key. + * @return Property value ({@code 0} by default). + */ + public static int getInt(String key) { + return Integer.parseInt( + PROPERTIES.getProperty(key, ZERO) + ); + } + + /** * Private constructor. */ private ChessHogScannerProperties() { diff --git a/src/main/java/org/hedgecode/chess/scanner/Scanner.java b/src/main/java/org/hedgecode/chess/scanner/Scanner.java index 0192f2b..2c6095a 100644 --- a/src/main/java/org/hedgecode/chess/scanner/Scanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/Scanner.java @@ -26,12 +26,14 @@ import org.hedgecode.chess.scanner.entity.PGNTournament; */ public interface Scanner { - PGNTournament getTournament(String tournamentId) throws ChessHogScannerException; + PGNTournament scanTournament(String tournamentId) throws ChessHogScannerException; PGNTournament findTournament(String tournamentName) throws ChessHogScannerException; - PGNGame getGame(String gameId) throws ChessHogScannerException; + PGNGame scanGame(String gameId) throws ChessHogScannerException; - PGNGame getGame(String gameId, String tournamentId) throws ChessHogScannerException; + PGNGame scanGame(String gameId, String tournamentId) throws ChessHogScannerException; + + PGNGame scanUrl(String gameUrl) throws ChessHogScannerException; } diff --git a/src/main/java/org/hedgecode/chess/scanner/ScannerType.java b/src/main/java/org/hedgecode/chess/scanner/ScannerType.java index f0a6495..306c316 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ScannerType.java +++ b/src/main/java/org/hedgecode/chess/scanner/ScannerType.java @@ -16,6 +16,8 @@ package org.hedgecode.chess.scanner; +import static org.hedgecode.chess.scanner.ChessHogScannerConstants.*; + /** * ScannerType * @@ -23,22 +25,28 @@ package org.hedgecode.chess.scanner; */ public enum ScannerType { - CHESSGAMES (ChessHogScannerConstants.PORTAL_CHESSGAMES), - LICHESS (ChessHogScannerConstants.PORTAL_LICHESS), - CHESSBOMB (ChessHogScannerConstants.PORTAL_CHESSBOMB), - CHESS24 (ChessHogScannerConstants.PORTAL_CHESS24), - CHESSCOM (ChessHogScannerConstants.PORTAL_CHESSCOM); + CHESSGAMES ( TYPE_CHESSGAMES, DOMAIN_CHESSGAMES ), + LICHESS ( TYPE_LICHESS, DOMAIN_LICHESS ), + CHESSBOMB ( TYPE_CHESSBOMB, DOMAIN_CHESSBOMB ), + CHESS24 ( TYPE_CHESS24, DOMAIN_CHESS24 ), + CHESSCOM ( TYPE_CHESSCOM, DOMAIN_CHESSCOM ); private String type; + private String domain; - ScannerType(String type) { + ScannerType(String type, String domain) { this.type = type; + this.domain = domain; } public String type() { return type; } + public String domain() { + return domain; + } + public static ScannerType byType(String type) { for (ScannerType scannerType : ScannerType.values()) { if (scannerType.type.equals(type)) @@ -47,4 +55,14 @@ public enum ScannerType { return null; } + public static ScannerType byHost(String host) { + if (host != null) { + for (ScannerType scannerType : ScannerType.values()) { + if (host.contains(scannerType.domain)) + return scannerType; + } + } + return null; + } + } diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java index d8b6ed0..7b19256 100644 --- a/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/portal/ChessBombScanner.java @@ -41,7 +41,7 @@ public class ChessBombScanner extends AbstractSettingsScanner { } @Override - public PGNTournament getTournament(String tournamentId) throws ChessHogScannerException { + public PGNTournament scanTournament(String tournamentId) throws ChessHogScannerException { String decodeTournament = decodeUrlByRegex( assignUrl(tournamentId, null), getSettings().getTournamentGamesUrlRegex() @@ -55,7 +55,7 @@ public class ChessBombScanner extends AbstractSettingsScanner { for (String gameId : tournamentFormat.gameUrls()) { tournament.addGame( - getGame(gameId, tournamentId) + scanGame(gameId, tournamentId) ); } @@ -74,19 +74,19 @@ public class ChessBombScanner extends AbstractSettingsScanner { String tournamentId = arenaFormat.findTournament(tournamentName); return tournamentId != null - ? getTournament(tournamentId) + ? scanTournament(tournamentId) : null; } @Override - public PGNGame getGame(String gameId) throws ChessHogScannerException { + public PGNGame scanGame(String gameId) throws ChessHogScannerException { throw new ChessHogScannerException( "ChessBomb does not support searching game without a tournament name!" ); } @Override - public PGNGame getGame(String gameId, String tournamentId) throws ChessHogScannerException { + public PGNGame scanGame(String gameId, String tournamentId) throws ChessHogScannerException { String decodeGame = decodeUrlByRegex( assignUrl(gameId, tournamentId, true), getSettings().getGameUrlRegex() @@ -100,6 +100,11 @@ public class ChessBombScanner extends AbstractSettingsScanner { ); } + @Override + public PGNGame scanUrl(String gameUrl) throws ChessHogScannerException { + return null; + } + private String decodeUrlByRegex(String url, String regex) throws ChessHogScannerException { String encodeString = match( url, diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/ChessGamesScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/ChessGamesScanner.java index 6346929..7658ba1 100644 --- a/src/main/java/org/hedgecode/chess/scanner/portal/ChessGamesScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/portal/ChessGamesScanner.java @@ -39,7 +39,7 @@ public class ChessGamesScanner extends AbstractSettingsScanner { } @Override - public PGNTournament getTournament(String tournamentId) throws ChessHogScannerException { + public PGNTournament scanTournament(String tournamentId) throws ChessHogScannerException { PGNTournament tournament = new PGNTournament(tournamentId); assignTournamentGames(tournament); return tournament; @@ -70,7 +70,7 @@ public class ChessGamesScanner extends AbstractSettingsScanner { } @Override - public PGNGame getGame(String gameId) throws ChessHogScannerException { + public PGNGame scanGame(String gameId) throws ChessHogScannerException { String pgn = request( assignUrl(gameId) ); @@ -80,8 +80,13 @@ public class ChessGamesScanner extends AbstractSettingsScanner { } @Override - public PGNGame getGame(String gameId, String tournamentId) throws ChessHogScannerException { - return getGame(gameId); + public PGNGame scanGame(String gameId, String tournamentId) throws ChessHogScannerException { + return scanGame(gameId); + } + + @Override + public PGNGame scanUrl(String gameUrl) throws ChessHogScannerException { + return null; } private void assignTournamentGames(PGNTournament tournament) throws ChessHogScannerException { @@ -106,7 +111,7 @@ public class ChessGamesScanner extends AbstractSettingsScanner { for (String gameId : gamesId) { tournament.addGame( - getGame(gameId) + scanGame(gameId) ); } } diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/LiChessScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/LiChessScanner.java index 1449392..134180e 100644 --- a/src/main/java/org/hedgecode/chess/scanner/portal/LiChessScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/portal/LiChessScanner.java @@ -43,7 +43,7 @@ public class LiChessScanner extends AbstractSettingsScanner { } @Override - public PGNTournament getTournament(String tournamentId) throws ChessHogScannerException { + public PGNTournament scanTournament(String tournamentId) throws ChessHogScannerException { PGNTournament tournament = new PGNTournament(tournamentId); assignTournamentGames(tournament); return tournament; @@ -57,7 +57,7 @@ public class LiChessScanner extends AbstractSettingsScanner { } @Override - public PGNGame getGame(String gameId) throws ChessHogScannerException { + public PGNGame scanGame(String gameId) throws ChessHogScannerException { String pgn = request( assignUrl(gameId) ); @@ -67,8 +67,13 @@ public class LiChessScanner extends AbstractSettingsScanner { } @Override - public PGNGame getGame(String gameId, String tournamentId) throws ChessHogScannerException { - return getGame(gameId); + public PGNGame scanGame(String gameId, String tournamentId) throws ChessHogScannerException { + return scanGame(gameId); + } + + @Override + public PGNGame scanUrl(String gameUrl) throws ChessHogScannerException { + return null; } private void assignTournamentGames(PGNTournament tournament) throws ChessHogScannerException { diff --git a/src/main/resources/scanner.properties b/src/main/resources/scanner.properties index ea03876..bb0415e 100644 --- a/src/main/resources/scanner.properties +++ b/src/main/resources/scanner.properties @@ -16,6 +16,8 @@ scanner.name=chesshog-scanner scanner.version=0.1-SNAPSHOT scanner.inception.year=2019 +scanner.lazy.init=true + scanner.use.proxy=false scanner.proxy.server= scanner.proxy.auth= -- 2.10.0