package org.jtheque.films.services.impl.utils.web; import org.jtheque.core.managers.Managers; import org.jtheque.core.managers.beans.IBeansManager; import org.jtheque.core.managers.log.ILoggingManager; import org.jtheque.core.managers.update.UpdateListener; import org.jtheque.films.persistence.od.able.Film; import org.jtheque.films.services.able.IFilmsService; import org.jtheque.films.services.able.INotesService; import org.jtheque.films.services.impl.utils.EditArguments; import org.jtheque.films.services.impl.utils.web.analyzers.GenericFilmAnalyzer; import org.jtheque.films.services.impl.utils.web.analyzers.GenericFilmResultAnalyzer; import org.jtheque.films.utils.Constants.Site; import org.jtheque.primary.services.able.ISimpleDataService; import org.jtheque.primary.utils.web.analyzers.generic.GenericGenerator; import org.jtheque.primary.utils.web.analyzers.generic.Page; import org.jtheque.primary.utils.web.analyzers.generic.Pages; import org.jtheque.primary.utils.web.analyzers.generic.operation.ScannerPossessor; import org.jtheque.primary.utils.web.analyzers.generic.transform.Transformer; import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Collection; import java.util.Scanner; /* * Copyright JTheque (Baptiste Wicht) * * 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. */ /** * A generic web getter. * * @author Baptiste Wicht */ public final class GenericWebGetter extends AbstractWebGetter implements ScannerPossessor, UpdateListener { @Resource private ISimpleDataService typesService; @Resource private INotesService notesService; @Resource private ISimpleDataService languagesService; @Resource private ISimpleDataService kindsService; @Resource private IFilmsService filmsService; private Scanner scanner; private Pages pages; private final String xmlFile; private final Site site; /** * Construct a new GenericWebGetter. * * @param xmlFile The xml file path. * @param site The site of the generic web getter. */ public GenericWebGetter(String xmlFile, Site site) { super(); this.xmlFile = xmlFile; this.site = site; Managers.getManager(IBeansManager.class).inject(this); generate(); GettersUpdatable.getInstance().addUpdateListener(this); } /** * Fill the web getter using a generic generator. */ private void generate() { GenericGenerator generator = new GenericGenerator(this); generator.generate(new File(Managers.getCore().getFolders().getApplicationFolder(), "/analyzers/" + xmlFile)); pages = generator.getPages(); setAnalyzer(new GenericFilmAnalyzer(generator)); setResultAnalyzer(new GenericFilmResultAnalyzer(generator, site)); } @Override public boolean canGetOn(Site site) { return this.site == site; } @Override public Film getFilm(FilmResult search, Film filmToModify, EditArguments args) { Film film; boolean editActors = true; if (filmToModify == null) { film = filmsService.getEmptyFilm(); } else { film = filmToModify; if (args != null) { getAnalyzer().configureWithEditArgs(args); editActors = args.isEditActors(); } } getAnalyzer().setFilm(film); film.setTitle(search.getTitre()); film.setTheLanguage(languagesService.getDefaultSimpleData()); film.setNote(notesService.getDefaultNote()); film.setTheType(typesService.getDefaultSimpleData()); String index = search.getIndex(); boolean twoPhase = pages.getActorsPage() != null; launchFirstPhase(index, twoPhase); launchSecondPhaseIfNeeded(editActors, index, twoPhase); getAnalyzer().reset(); completeKinds(film); return film; } /** * Complete the kinds of the film. * * @param film The film to complete. */ private void completeKinds(Film film) { if (film.hasKinds()) { film.addKind(kindsService.getDefaultSimpleData()); } } /** * Launch the first phase of the web getting process. * * @param index The index url. * @param twoPhase Indicate if there is two phase or not. */ private void launchFirstPhase(String index, boolean twoPhase) { try { Page filmsPage = pages.getFilmsPage(); String url = filmsPage.getUrl() + index; for (Transformer transformer : filmsPage.getTransformers()) { url = transformer.transform(url); } openConnectionToURL(url); getAnalyzer().setScanner(scanner); if (twoPhase) { getAnalyzer().setActors(true); } while (scanner.hasNextLine() && getAnalyzer().isNotComplete()) { String line = scanner.nextLine().trim(); getAnalyzer().analyzeLine(line); } } catch (MalformedURLException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } catch (IOException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } finally { if (scanner != null) { scanner.close(); } } } /** * Launch the second phase if needed. * * @param editActors Indicate if we must edit actors. * @param index The index url. * @param twoPhase Indicate if we must make the second phase or not. */ private void launchSecondPhaseIfNeeded(boolean editActors, String index, boolean twoPhase) { if (twoPhase && editActors) { try { Page actorsPage = pages.getActorsPage(); String url = actorsPage.getUrl() + index; for (Transformer transformer : actorsPage.getTransformers()) { url = transformer.transform(url); } openConnectionToURL(url); getAnalyzer().setScanner(scanner); getAnalyzer().setActors(false); while (scanner.hasNextLine() && getAnalyzer().isNotComplete()) { String line = scanner.nextLine().trim(); getAnalyzer().analyzeLine(line); } } catch (MalformedURLException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } catch (IOException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } finally { if (scanner != null) { scanner.close(); } } } } @Override public Collection<FilmResult> getFilms(String search) { try { Page resultsPage = pages.getResultsPage(); String url = resultsPage.getUrl() + search; for (Transformer transformer : resultsPage.getTransformers()) { url = transformer.transform(url); } openConnectionToURL(url); getResultAnalyzer().setScanner(scanner); while (scanner.hasNextLine() && getResultAnalyzer().isNotComplete()) { String line = scanner.nextLine().trim(); getResultAnalyzer().analyzeLine(line); } } catch (MalformedURLException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } catch (IOException e) { Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); } finally { if (scanner != null) { scanner.close(); } } Collection<FilmResult> films = new ArrayList<FilmResult>(getResultAnalyzer().getResults()); getResultAnalyzer().reset(); return films; } /** * Open a connection to the URL. * * @param url The URL to open connection to. * * @throws IOException If an error occurs during opening the connection to the URL. */ private void openConnectionToURL(String url) throws IOException { URL fileUrl = new URL(url); URLConnection urlConnection = fileUrl.openConnection(); urlConnection.setUseCaches(false); urlConnection.connect(); scanner = new Scanner(urlConnection.getInputStream()); } @Override public Scanner getScanner() { return scanner; } @Override public void updated() { generate(); } }