[LIB-13] Lazy scanners init, scan by URL and rename API functions
[chesshog-scanner.git] / src / main / java / org / hedgecode / chess / scanner / ChessHogScanner.java
index 9b90990..fdb5036 100644 (file)
 
 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<ScannerType, Scanner> SCANNERS = new HashMap<ScannerType, Scanner>() {
+    private final Map<ScannerType, Scanner> scanners = new HashMap<ScannerType, Scanner>() {
         {
             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<ScannerType> 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;
     }
 
 }