From c26e9e6ccd734c44467cb12f3d9087c1df73ceac Mon Sep 17 00:00:00 2001 From: gotty Date: Sun, 12 Jan 2020 03:37:29 +0300 Subject: [PATCH] [LIB-13] Add common scanner functional --- .../hedgecode/chess/scanner/ChessHogScanner.java | 65 +++++ .../org/hedgecode/chess/scanner/Initiable.java | 28 ++ .../java/org/hedgecode/chess/scanner/Scanner.java | 35 +++ .../org/hedgecode/chess/scanner/ScannerType.java | 50 ++++ .../scanner/portal/AbstractRequestScanner.java | 283 +++++++++++++++++++++ .../scanner/portal/AbstractSettingsScanner.java | 83 ++++++ 6 files changed, 544 insertions(+) create mode 100644 src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/Initiable.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/Scanner.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/ScannerType.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java 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 index 0000000..45a8064 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScanner.java @@ -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 SCANNERS = new HashMap(); + + 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 index 0000000..4fd24d6 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/Initiable.java @@ -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 index 0000000..8cc80eb --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/Scanner.java @@ -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 index 0000000..f0a6495 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/ScannerType.java @@ -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 index 0000000..fd72e6e --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java @@ -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 result = matchRequest(url, match, true); + return result.isEmpty() ? null : result.get(0); + } + + protected List 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 result = matchRequest(url, match, true); + return result.isEmpty() ? null : result.get(0); + } + + protected List matchRequest(String url, String match, boolean isFirst) + throws ChessHogScannerException + { + HttpGet request = new HttpGet(url); + CloseableHttpResponse response = null; + List 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 index 0000000..871c778 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java @@ -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) + ); + } + +} -- 2.10.0