[LIB-13] Add common scanner functional
authorgotty <gotty@hedgecode.org>
Sun, 12 Jan 2020 00:37:29 +0000 (03:37 +0300)
committergotty <gotty@hedgecode.org>
Sun, 12 Jan 2020 00:37:29 +0000 (03:37 +0300)
src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/Initiable.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/Scanner.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/ScannerType.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java [new file with mode: 0644]

diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java
new file mode 100644 (file)
index 0000000..45a8064
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ChessHogScanner
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class ChessHogScanner {
+
+    private static ChessHogScanner _instance;
+
+    private final Map<ScannerType, Scanner> SCANNERS = new HashMap<ScannerType, Scanner>();
+
+    public static Scanner get(ScannerType type) {
+        return getInstance().scanner(type);
+    }
+
+    private void init() {
+        try {
+            for (Scanner scanner : SCANNERS.values()) {
+                if (scanner instanceof Initiable) {
+                    Initiable initiableScanner = (Initiable) scanner;
+                    initiableScanner.init();
+                }
+            }
+        } catch (ChessHogScannerException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private Scanner scanner(ScannerType type) {
+        return SCANNERS.get(type);
+    }
+
+    private ChessHogScanner() {
+    }
+
+    private static ChessHogScanner getInstance() {
+        if (_instance == null) {
+            _instance = new ChessHogScanner();
+            _instance.init();
+        }
+        return _instance;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/Initiable.java b/src/main/java/org/hedgecode/chess/scanner/Initiable.java
new file mode 100644 (file)
index 0000000..4fd24d6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner;
+
+/**
+ * Initiable
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Initiable {
+
+    void init() throws ChessHogScannerException;
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/Scanner.java b/src/main/java/org/hedgecode/chess/scanner/Scanner.java
new file mode 100644 (file)
index 0000000..8cc80eb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner;
+
+import org.hedgecode.chess.scanner.entity.PGNGame;
+import org.hedgecode.chess.scanner.entity.PGNTournament;
+
+/**
+ * Scanner
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Scanner {
+
+    PGNTournament getTournament(String tournamentId) throws ChessHogScannerException;
+
+    PGNTournament findTournament(String tournamentName) throws ChessHogScannerException;
+
+    PGNGame getGame(String gameId) throws ChessHogScannerException;
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/ScannerType.java b/src/main/java/org/hedgecode/chess/scanner/ScannerType.java
new file mode 100644 (file)
index 0000000..f0a6495
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner;
+
+/**
+ * ScannerType
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public enum ScannerType {
+
+    CHESSGAMES (ChessHogScannerConstants.PORTAL_CHESSGAMES),
+    LICHESS    (ChessHogScannerConstants.PORTAL_LICHESS),
+    CHESSBOMB  (ChessHogScannerConstants.PORTAL_CHESSBOMB),
+    CHESS24    (ChessHogScannerConstants.PORTAL_CHESS24),
+    CHESSCOM   (ChessHogScannerConstants.PORTAL_CHESSCOM);
+
+    private String type;
+
+    ScannerType(String type) {
+        this.type = type;
+    }
+
+    public String type() {
+        return type;
+    }
+
+    public static ScannerType byType(String type) {
+        for (ScannerType scannerType : ScannerType.values()) {
+            if (scannerType.type.equals(type))
+                return scannerType;
+        }
+        return null;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java
new file mode 100644 (file)
index 0000000..fd72e6e
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.portal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+import org.hedgecode.chess.scanner.ChessHogScannerConstants;
+import org.hedgecode.chess.scanner.ChessHogScannerException;
+import org.hedgecode.chess.scanner.Scanner;
+import org.hedgecode.chess.scanner.regex.RegexMatcher;
+import org.hedgecode.chess.scanner.regex.RegexMatcherResult;
+import org.hedgecode.chess.scanner.regex.RegexResult;
+
+/**
+ * AbstractRequestScanner
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public abstract class AbstractRequestScanner implements Scanner {
+
+    protected String request(String url) throws ChessHogScannerException {
+        HttpGet request = new HttpGet(url);
+        CloseableHttpResponse response = null;
+        StringBuilder sb = new StringBuilder();
+        try {
+            response = getClient().execute(request);
+            try (BufferedReader br = new BufferedReader(
+                    new InputStreamReader(
+                            response.getEntity().getContent(),
+                            ChessHogScannerConstants.CHARSET
+                    )
+            )) {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    sb.append(
+                            line
+                    ).append(
+                            ChessHogScannerConstants.CRLF
+                    );
+                }
+            }
+        } catch (IOException cause) {
+            throw new ChessHogScannerException(
+                    String.format("Error occurred for requesting URL: %s", url), cause
+            );
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException ignored) {}
+            }
+        }
+        return sb.toString();
+    }
+
+    protected String matchRequest(String url, String match)
+            throws ChessHogScannerException
+    {
+        List<String> result = matchRequest(url, match, true);
+        return result.isEmpty() ? null : result.get(0);
+    }
+
+    protected List<String> matchRequest(String url, String match, boolean isFirst)
+            throws ChessHogScannerException
+    {
+        RegexResult result = matchRequest(
+                url,
+                new RegexMatcherResult(
+                        match,
+                        isFirst,
+                        false
+                )
+        );
+        return result.resultList();
+    }
+
+    protected String matchRequest(String url, String startMatch, String endMatch)
+            throws ChessHogScannerException
+    {
+        return matchRequest(url, startMatch, endMatch, true);
+    }
+
+    protected String matchRequest(String url, String startMatch, String endMatch, boolean isFirst)
+            throws ChessHogScannerException
+    {
+        RegexResult result = matchRequest(
+                url,
+                new RegexMatcherResult(
+                        startMatch,
+                        endMatch,
+                        isFirst,
+                        false
+                )
+        );
+        return result.isEmpty() ? null : result.resultList().get(0);
+    }
+
+/*
+    protected String matchRequest(String url, String match)
+            throws ChessHogScannerException
+    {
+        List<String> result = matchRequest(url, match, true);
+        return result.isEmpty() ? null : result.get(0);
+    }
+
+    protected List<String> matchRequest(String url, String match, boolean isFirst)
+            throws ChessHogScannerException
+    {
+        HttpGet request = new HttpGet(url);
+        CloseableHttpResponse response = null;
+        List<String> result = new ArrayList<>();
+        try {
+            response = getClient().execute(request);
+            Pattern pattern = Pattern.compile(match);
+            try (BufferedReader br = new BufferedReader(
+                    new InputStreamReader(
+                            response.getEntity().getContent(),
+                            ChessHogScannerConstants.CHARSET
+                    )
+            )) {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    Matcher matcher = pattern.matcher(line);
+                    if (matcher.find()) {
+                        result.add(
+                                matcher.group(1)
+                        );
+                        if (isFirst) {
+                            break;
+                        }
+                    }
+                }
+            }
+        } catch (IOException cause) {
+            throw new ChessHogScannerException(
+                    String.format("Error occurred for requesting URL: %s", url), cause
+            );
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException ignored) {}
+            }
+        }
+        return result;
+    }
+
+    protected String matchRequest(String url, String startMatch, String endMatch)
+            throws ChessHogScannerException
+    {
+        return matchRequest(url, startMatch, endMatch, true);
+    }
+
+    protected String matchRequest(String url, String startMatch, String endMatch, boolean isFirst)
+            throws ChessHogScannerException
+    {
+        HttpGet request = new HttpGet(url);
+        CloseableHttpResponse response = null;
+        StringBuilder sb = new StringBuilder();
+        try {
+            response = getClient().execute(request);
+            Pattern startPattern = Pattern.compile(startMatch);
+            Pattern endPattern = Pattern.compile(endMatch);
+            try (BufferedReader br = new BufferedReader(
+                    new InputStreamReader(
+                            response.getEntity().getContent(),
+                            ChessHogScannerConstants.CHARSET
+                    )
+            )) {
+                String line;
+                boolean isMatch = false;
+                while ((line = br.readLine()) != null) {
+                    Matcher matcher = isMatch
+                            ? endPattern.matcher(line)
+                            : startPattern.matcher(line);
+                    if (matcher.find()) {
+                        sb.append(line);
+                        if (isMatch && isFirst) {
+                            break;
+                        }
+                        isMatch = !isMatch;
+                    } else {
+                        if (isMatch) {
+                            sb.append(line);
+                        }
+                    }
+                }
+            }
+        } catch (IOException cause) {
+            throw new ChessHogScannerException(
+                    String.format("Error occurred for requesting URL: %s", url), cause
+            );
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException ignored) {}
+            }
+        }
+        return sb.length() > 0 ? sb.toString() : null;
+    }
+*/
+
+    protected RegexResult matchRequest(String url, RegexMatcher matcher) throws ChessHogScannerException {
+        HttpGet request = new HttpGet(url);
+        CloseableHttpResponse response = null;
+        try {
+            response = getClient().execute(request);
+            try (BufferedReader br = new BufferedReader(
+                    new InputStreamReader(
+                            response.getEntity().getContent(),
+                            ChessHogScannerConstants.CHARSET
+                    )
+            )) {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    matcher.match(line);
+                    if (matcher.isBreak()) {
+                        break;
+                    }
+                }
+            }
+        } catch (IOException cause) {
+            throw new ChessHogScannerException(
+                    String.format("Error occurred for requesting URL: %s", url), cause
+            );
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException ignored) {}
+            }
+        }
+        return matcher.result();
+    }
+
+/*
+    protected String urlEncode(String query) throws ChessHogScannerException {
+        String encodeQuery;
+        try {
+            encodeQuery = URLEncoder.encode(
+                    query, ChessHogScannerConstants.CHARSET.name()
+            );
+        } catch (UnsupportedEncodingException cause) {
+            throw new ChessHogScannerException(
+                    String.format("Unsupported encoding: %s", ChessHogScannerConstants.CHARSET.name()),
+                    cause
+            );
+        }
+        return encodeQuery;
+    }
+*/
+
+    private CloseableHttpClient getClient() {
+        return HttpClients.createMinimal();
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java
new file mode 100644 (file)
index 0000000..871c778
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.portal;
+
+import org.hedgecode.chess.scanner.ChessHogScannerException;
+import org.hedgecode.chess.scanner.Initiable;
+import org.hedgecode.chess.scanner.Settings;
+import org.hedgecode.chess.scanner.SettingsBuilder;
+import org.hedgecode.chess.scanner.regex.RegexBuilder;
+import org.hedgecode.chess.scanner.regex.RegexParams;
+import org.hedgecode.chess.scanner.regex.RegexType;
+import org.hedgecode.chess.scanner.spi.ServiceRegistry;
+
+/**
+ * AbstractSettingsScanner
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public abstract class AbstractSettingsScanner extends AbstractRequestScanner implements Initiable {
+
+    private Settings settings;
+
+    protected abstract String getResourceName();
+
+    @Override
+    public void init() throws ChessHogScannerException {
+        SettingsBuilder settingsBuilder = ServiceRegistry.singleProvider(
+                SettingsBuilder.class
+        );
+        settings = settingsBuilder.build(
+                getResourceName()
+        );
+    }
+
+    protected Settings getSettings() {
+        return settings;
+    }
+
+    protected String assignUrl(String tournamentId, String pageId) {
+        return RegexBuilder.build(
+                RegexType.TOURNAMENT,
+                settings.getTournamentUrl(),
+                new RegexParams(
+                        tournamentId,
+                        settings.isTournamentMultiPage() ? pageId : null
+                )
+        );
+    }
+
+    protected String assignUrl(String gameId) {
+        String gameUrl = settings.getGamePgnUrl() != null
+                ? settings.getGamePgnUrl()
+                : settings.getGameUrl();
+        return RegexBuilder.build(
+                RegexType.GAME,
+                gameUrl,
+                new RegexParams(gameId)
+        );
+    }
+
+    protected String assignUrl(String query, boolean isUrlEncode) {
+        return RegexBuilder.build(
+                RegexType.QUERY,
+                settings.getTournamentQuery(),
+                new RegexParams(query, isUrlEncode)
+        );
+    }
+
+}