Java tutorial
/* * Copyright 2015-206 NETHead <NETHead@gmx.net> * * 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.tinymediamanager.scraper.aebn; import java.io.InputStream; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinymediamanager.scraper.Certification; import org.tinymediamanager.scraper.MediaArtwork; import org.tinymediamanager.scraper.MediaArtwork.FanartSizes; import org.tinymediamanager.scraper.MediaArtwork.MediaArtworkType; import org.tinymediamanager.scraper.MediaCastMember; import org.tinymediamanager.scraper.MediaCastMember.CastType; import org.tinymediamanager.scraper.MediaGenres; import org.tinymediamanager.scraper.MediaMetadata; import org.tinymediamanager.scraper.MediaProviderInfo; import org.tinymediamanager.scraper.MediaScrapeOptions; import org.tinymediamanager.scraper.MediaSearchOptions; import org.tinymediamanager.scraper.MediaSearchResult; import org.tinymediamanager.scraper.MediaType; import org.tinymediamanager.scraper.http.Url; import org.tinymediamanager.scraper.mediaprovider.IMediaArtworkProvider; import org.tinymediamanager.scraper.mediaprovider.IMovieMetadataProvider; import org.tinymediamanager.scraper.util.MetadataUtil; import org.tinymediamanager.scraper.util.StrgUtils; import net.xeoh.plugins.base.annotations.PluginImplementation; /** * A meta data provider class for scraping aebn.net. * * Implements scraping of meta data, artwork and trailers. * * @author NETHead <NETHead@gmx.net> * @version 0.3 * @see IMediaMetadataProvider * @see IMediaArtworkProvider * @see IMediaTrailerProvider * */ @PluginImplementation public class AebnMetadataProvider implements IMovieMetadataProvider, IMediaArtworkProvider { private static AebnMetadataProvider instance; private static final String AEBNID = "AebnID"; private static MediaProviderInfo providerInfo = createMediaProviderInfo(); private static final Logger LOGGER = LoggerFactory.getLogger(AebnMetadataProvider.class); private static final String BASE_DATAURL = "http://theater.aebn.net"; private static final String BASE_IMGURL = "http://pic.aebn.net"; private static final Integer SEARCH_COUNT = 60; public static synchronized AebnMetadataProvider getInstance() { if (instance == null) { instance = new AebnMetadataProvider(); } return instance; } public AebnMetadataProvider() { } @Override public MediaProviderInfo getProviderInfo() { return providerInfo; } private static MediaProviderInfo createMediaProviderInfo() { MediaProviderInfo providerInfo = new MediaProviderInfo(AEBNID, "aebn.net", "<html><h3>Adult Entertainment Broadcast Network</h3><br />An adult movie database." + "This scraper is able to scrape metadata and artwork.</html>", AebnMetadataProvider.class.getResource("/aebn_net.png")); providerInfo.setVersion(AebnMetadataProvider.class); return providerInfo; } /** * Search for movies at aebn.net. * */ @Override public List<MediaSearchResult> search(MediaSearchOptions query) throws Exception { LOGGER.debug("AEBN: search() {}", query); List<MediaSearchResult> resultList = new ArrayList<MediaSearchResult>(); Elements movies = null; String searchString = ""; // Search for query if (StringUtils.isNotEmpty(query.get(MediaSearchOptions.SearchParam.QUERY))) { searchString = query.get(MediaSearchOptions.SearchParam.QUERY); } // Search String searchUrl = BASE_DATAURL + "/dispatcher/fts?userQuery=" + URLEncoder.encode(cleanSearchQuery(searchString), "UTF-8") + "&targetSearchMode=basic&isAdvancedSearch=true&isFlushAdvancedSearchCriteria=false" + "&count=" + SEARCH_COUNT.toString() + "&imageType=Large&sortType=Relevance"; try { LOGGER.info("========= BEGIN AEBN Scraper Search for: {}", searchString); Url url = new Url(searchUrl); InputStream in = url.getInputStream(); Document doc = Jsoup.parse(in, "UTF-8", ""); in.close(); // only look for movie links like // <a id="FTSMovieSearch_link_title_detail_30" ... </a> movies = doc.getElementsByAttributeValueMatching("id", "FTSMovieSearch_link_title_detail_\\d+"); LOGGER.debug("AEBN: found {} search results", movies.size()); } catch (Exception e) { LOGGER.error("AEBN: failed to search for {}: ", searchString, e); } if (movies == null || movies.isEmpty()) { LOGGER.debug("AEBN: no movie found"); return resultList; } // there are search results, so fill media data structure HashSet<String> foundResultUrls = new HashSet<String>(); for (Element anchor : movies) { try { String movieUrl = BASE_DATAURL + StrgUtils.substr(anchor.toString(), "href=\\\"(.*?)\\\""); String movieId = StrgUtils.substr(anchor.toString(), "movieId=(\\d+)"); String movieName = StringEscapeUtils.unescapeHtml4(anchor.text()); String posterUrl = BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + movieId + "_160w.jpg"; LOGGER.debug("AEBN: found movie {} (id{})", movieName, movieId); // check if it is a valid AEBN id if (!isValidAebnId(Integer.parseInt(movieId))) { LOGGER.error("AEBN: id({}) is not a valid aebn id", movieId); } MediaSearchResult sr = new MediaSearchResult(providerInfo.getId()); sr.setId(movieId); sr.setIMDBId(""); sr.setTitle(movieName); sr.setOriginalTitle(movieName); // sr.setYear not possible, no data at this point sr.setYear(null); sr.setMediaType(MediaType.MOVIE); sr.setUrl(movieUrl); sr.setPosterUrl(posterUrl); // compare score based on names float score = MetadataUtil.calculateScore(searchString, movieName); if (posterUrl.isEmpty() || posterUrl.contains("nopicture")) { LOGGER.debug("AEBN: no poster - downgrading score by 0.01"); score = score - 0.01f; } sr.setScore(score); // check if result has at least a title and id if (StringUtils.isBlank(sr.getTitle()) || StringUtils.isBlank(sr.getId())) { LOGGER.warn("AEBN: no title nor id, skipping"); continue; } // check if the movie has been already added to the search results if (foundResultUrls.contains(sr.getUrl())) { continue; } foundResultUrls.add(sr.getUrl()); // populate extra arguments (deprecated) // MetadataUtil.copySearchQueryToSearchResult(query, sr); resultList.add(sr); } catch (Exception e) { LOGGER.warn("AEBN: error parsing search result: {}", e); } } Collections.sort(resultList); Collections.reverse(resultList); return resultList; } /** * Get movie meta data from aebn.net. * */ @Override public MediaMetadata getMetadata(MediaScrapeOptions options) throws Exception { LOGGER.debug("AEBN: getMetadata() {}", options); // check if there is already meta data present in the result if ((options.getResult() != null) && (options.getResult().getMediaMetadata() != null)) { LOGGER.debug("AEBN: return metadata from cache"); return options.getResult().getMediaMetadata(); } MediaMetadata md = new MediaMetadata(providerInfo.getId()); Elements elements = null; Element element = null; Integer aebnId = 0; // get AebnId from previous search result if ((options.getResult() != null) && (options.getResult().getId() != null)) { aebnId = Integer.parseInt(options.getResult().getId()); LOGGER.debug("AEBN: aebnId() from previous search result = {}", aebnId); // preset some values from search result (if there is one) // Use core.Utils.RemoveSortableName() if you want e.g. "Bourne Legacy, The" -> "The Bourne Legacy". md.storeMetadata(MediaMetadata.ORIGINAL_TITLE, StrgUtils.removeCommonSortableName(options.getResult().getOriginalTitle())); md.storeMetadata(MediaMetadata.TITLE, StrgUtils.removeCommonSortableName(options.getResult().getTitle())); } // or get AebnId from options if (!isValidAebnId(aebnId) && (options.getId(AEBNID) != null)) { LOGGER.debug("AEBN: aebnId() from options = {}", options.getId(AEBNID)); aebnId = Integer.parseInt(options.getId(AEBNID)); } if (!isValidAebnId(aebnId)) { LOGGER.warn("AEBN: no or incorrect aebnId, aborting"); return md; } // ID md.setId(providerInfo.getId(), aebnId); LOGGER.debug("AEBN: aebnId({})", aebnId); // Base download url for data scraping String downloadUrl = BASE_DATAURL + "/dispatcher/movieDetail?movieId=" + aebnId; String locale = options.getLanguage().name(); if (!StringUtils.isBlank(locale)) { downloadUrl = downloadUrl + "&locale=" + locale; LOGGER.debug("AEBN: used locale({})", locale); } // begin download and scrape try { LOGGER.debug("AEBN: download movie detail page"); Url url = new Url(downloadUrl); InputStream in = url.getInputStream(); Document document = Jsoup.parse(in, "UTF-8", ""); in.close(); // Title // <h1 itemprop="name" class="md-movieTitle" >Titelname</h1> LOGGER.debug("AEBN: parse title"); elements = document.getElementsByAttributeValue("class", "md-movieTitle"); if (elements.size() > 0) { LOGGER.debug("AEBN: {} elements found (should be one!)", elements.size()); element = elements.first(); String movieTitle = cleanString(element.text()); LOGGER.debug("AEBN: title({})", movieTitle); md.storeMetadata(MediaMetadata.TITLE, movieTitle); } // Poster // front cover: // http://pic.aebn.net/Stream/Movie/Boxcovers/a66568_xlf.jpg String posterUrl = BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_xlf.jpg"; md.storeMetadata(MediaMetadata.POSTER_URL, posterUrl); // Fanart/Background // http://pic.aebn.net/Stream/Movie/Scenes/a113324_s534541.jpg // <img class="sceneThumbnail" alt="Scene Thumbnail" title="Scene Thumbnail" onError="..." // src="http://pic.aebn.net/Stream/Movie/Scenes/a113324_s534544.jpg" onclick="..." /> LOGGER.debug("AEBN: parse fanart / scene thumbs"); elements = document.getElementsByAttributeValue("class", "SceneThumbnail"); LOGGER.debug("AEBN: {} elements found", elements.size()); int i = 1; for (Element anchor : elements) { String backgroundUrl = anchor.attr("src"); LOGGER.debug("AEBN: backgroundUrl{}({})", i, backgroundUrl); md.storeMetadata("backgroundUrl" + Integer.valueOf(i).toString(), backgroundUrl); i++; } // Runtime LOGGER.debug("AEBN: parse runtime"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=duration]"); if (elements.size() > 0) { LOGGER.debug("AEBN: " + elements.size() + " elements found (should be one!)"); element = elements.first(); String movieRuntime = cleanString(element.attr("content")); movieRuntime = StrgUtils.substr(movieRuntime, "PT(\\d+)M"); LOGGER.debug("AEBN: runtime({})", movieRuntime); md.storeMetadata(MediaMetadata.RUNTIME, movieRuntime); } // Year LOGGER.debug("AEBN: parse year"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=datePublished]"); if (elements.size() > 0) { LOGGER.debug("AEBN: " + elements.size() + " elements found (should be one!)"); element = elements.first(); String movieYear = cleanString(element.attr("content")); movieYear = StrgUtils.substr(movieYear, "(\\d+)-"); LOGGER.debug("AEBN: year({})", movieYear); md.storeMetadata(MediaMetadata.YEAR, movieYear); } // Series (Collection) LOGGER.debug("AEBN: parse collection"); elements = document.getElementsByAttributeValue("id", "md-details").select("[class=series]"); if (elements.size() > 0) { LOGGER.debug("AEBN: {} elements found (should be one!)", elements.size()); element = elements.first(); String movieCollection = cleanString(element.text()); // Fake a TMDB_SET based on the hash value of the collection name int movieCollectionHash = movieCollection.hashCode(); md.storeMetadata(MediaMetadata.COLLECTION_NAME, movieCollection); md.storeMetadata(MediaMetadata.TMDB_SET, movieCollectionHash); LOGGER.debug("AEBN: collection({}), hashcode({})", movieCollection, movieCollectionHash); } // Studio LOGGER.debug("AEBN: parse studio"); elements = document.getElementsByAttributeValue("id", "md-details") .select("[itemprop=productionCompany]"); if (elements.size() > 0) { LOGGER.debug("AEBN: {} elements found (should be one!)", elements.size()); String movieStudio = cleanString(elements.first().text()); LOGGER.debug("AEBN: studio({})", movieStudio); md.storeMetadata(MediaMetadata.PRODUCTION_COMPANY, movieStudio); } // Genre LOGGER.debug("AEBN: parse genre"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=genre]"); for (Element g : elements) { md.addGenre(getTmmGenre(g.text())); } // add basic genre, since all genres at AEBN could be summarised // into this one md.addGenre(MediaGenres.EROTIC); // Certification // no data scrapeable---but obviously it's adult only, so simply // generate it String movieCertification = null; Certification certification = null; String country = options.getCountry().getAlpha2(); LOGGER.debug("AEBN: generate certification for {}", country); // @formatter:off if (country.equals("DE")) { movieCertification = "FSK 18"; } if (country.equals("US")) { movieCertification = "NC-17"; } if (country.equals("GB")) { movieCertification = "R18"; } if (country.equals("FR")) { movieCertification = "18"; } if (country.equals("ES")) { movieCertification = "PX"; } if (country.equals("JP")) { movieCertification = "R18+"; } if (country.equals("IT")) { movieCertification = "V.M.18"; } if (country.equals("NL")) { movieCertification = "16"; } // @formatter:on certification = Certification.getCertification(options.getCountry(), movieCertification); if (certification != null) { LOGGER.debug("AEBN: certification({})", certification); md.addCertification(certification); } // Plot and Tagline LOGGER.debug("AEBN: parse plot"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=about]"); if (elements.size() > 0) { LOGGER.debug("AEBN: {} elements found (should be one!)", elements.size()); String moviePlot = cleanString(elements.first().text()); md.storeMetadata(MediaMetadata.PLOT, moviePlot); // no separate tagline available, so extract the first sentence // from the movie plot String movieTagline = StrgUtils.substr(moviePlot, "^(.*?[.!?:])"); LOGGER.debug("AEBN: tagline(" + movieTagline + ")"); md.storeMetadata(MediaMetadata.TAGLINE, movieTagline); } // Actors LOGGER.debug("AEBN: parse actors"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=actor]"); LOGGER.debug("AEBN: {} actors found", elements.size()); for (Element anchor : elements) { String actorid = StrgUtils.substr(anchor.toString(), "starId=(\\d+)"); String actorname = cleanString(anchor.select("[itemprop=name]").first().text()); String actordetailsurl = BASE_DATAURL + anchor.attr("href"); if (!actorname.isEmpty()) { LOGGER.debug("AEBN: add actor id({}), name({}), details({})", actorid, actorname, actordetailsurl); MediaCastMember cm = new MediaCastMember(); cm.setType(MediaCastMember.CastType.ACTOR); cm.setName(actorname); if (!actorid.isEmpty()) { cm.setId(actorid); } // Actor detail page try { Url starurl = new Url(actordetailsurl); InputStream starurlstream = starurl.getInputStream(); Document stardocument = Jsoup.parse(starurlstream, "UTF-8", ""); starurlstream.close(); Elements elements2 = stardocument.getElementsByAttributeValue("class", "StarInfo"); if (elements2.size() == 0) { LOGGER.debug("AEBN: no additional actor details found"); } else { // Actor image String actorimage = elements2.select("[itemprop=image]").first().attr("src"); LOGGER.debug("AEBN: actor image({})", actorimage); if (!actorimage.isEmpty()) { cm.setImageUrl(actorimage); } // Actor 'fanart' images // unsure if this is ever shown in tmm elements2 = stardocument.getElementsByAttributeValue("class", "StarDetailGallery") .select("a"); LOGGER.debug("AEBN: {} gallery images found", elements2.size()); for (Element thumbnail : elements2) { LOGGER.debug("AEBN: add fanart image({})", thumbnail.attr("href")); cm.addFanart(thumbnail.attr("href")); } } } catch (Exception e) { LOGGER.error("AEBN: Error downloading {}: {}", actordetailsurl, e); } md.addCastMember(cm); } } // Director LOGGER.debug("AEBN: parse director"); elements = document.getElementsByAttributeValue("id", "md-details").select("[itemprop=director]"); if (elements.size() > 0) { LOGGER.debug("AEBN: {} elements found (should be one!)", elements.size()); String directorid = StrgUtils.substr(elements.toString(), "directorID=(\\d+)"); String directorname = cleanString(elements.select("[itemprop=name]").first().text()); if (!directorname.isEmpty()) { MediaCastMember cm = new MediaCastMember(CastType.DIRECTOR); cm.setName(directorname); if (!directorid.isEmpty()) { cm.setId(directorid); } cm.setImageUrl(""); md.addCastMember(cm); LOGGER.debug("AEBN: add director id({}), name({})", directorid, directorname); } } // Original Title // if we have no original title, just copy the title if (StringUtils.isBlank(md.getStringValue(MediaMetadata.ORIGINAL_TITLE))) { md.storeMetadata(MediaMetadata.ORIGINAL_TITLE, md.getStringValue(MediaMetadata.TITLE)); } } catch (Exception e) { LOGGER.error("AEBN: Error parsing {}: {}", options.getResult().getUrl(), e); } return md; } /** * Get movie artwork from aebn.net. * <p> * <b>NOTICE:</b> Automatic image scraping does not work (aebnId is not transferred)! Must be set to manual image * scraping at the tmm movie scraper settings. * */ @Override public List<MediaArtwork> getArtwork(MediaScrapeOptions options) throws Exception { LOGGER.debug("AEBN: getArtwork() {}", options); List<MediaArtwork> artwork = new ArrayList<MediaArtwork>(); MediaMetadata md; Integer aebnId = 0; // get aebnId from options if (options.getId(AEBNID) != null) { aebnId = Integer.parseInt(options.getId(AEBNID)); LOGGER.debug("AEBN: got aebnId({}) from options", aebnId); } if (!isValidAebnId(aebnId)) { LOGGER.info("AEBN: could not scrape artwork, no or incorrect aebnId"); return artwork; } // Poster if ((options.getArtworkType() == MediaArtworkType.ALL) || (options.getArtworkType() == MediaArtworkType.POSTER)) { // http://pic.aebn.net/Stream/Movie/Boxcovers/a136807_xlf.jpg // http://pic.aebn.net/Stream/Movie/Boxcovers/a136807_bf.jpg // http://pic.aebn.net/Stream/Movie/Boxcovers/a136807_160w.jpg MediaArtwork ma = new MediaArtwork(); ma.setProviderId(providerInfo.getId()); String posterpreviewUrl = BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_xlf.jpg"; String posterUrl = posterpreviewUrl; ma.setDefaultUrl(posterUrl); ma.setPreviewUrl(posterpreviewUrl); ma.addImageSize(380, 540, BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_xlf.jpg"); ma.addImageSize(220, 313, BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_bf.jpg"); ma.addImageSize(160, 227, BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_160w.jpg"); ma.setSizeOrder(FanartSizes.MEDIUM.getOrder()); ma.setLanguage(options.getLanguage().name()); ma.setType(MediaArtworkType.POSTER); artwork.add(ma); LOGGER.debug("AEBN: add poster({})", posterpreviewUrl); } // Poster Back (stored as Disc) if ((options.getArtworkType() == MediaArtworkType.ALL) || (options.getArtworkType() == MediaArtworkType.DISC)) { // http://pic.aebn.net/Stream/Movie/Boxcovers/a136807_xlb.jpg // http://pic.aebn.net/Stream/Movie/Boxcovers/a136807_bb.jpg MediaArtwork ma = new MediaArtwork(); ma.setProviderId(providerInfo.getId()); String posterpreviewUrl = BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_xlb.jpg"; String posterUrl = posterpreviewUrl; ma.setDefaultUrl(posterUrl); ma.setPreviewUrl(posterpreviewUrl); ma.addImageSize(380, 540, BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_xlb.jpg"); ma.addImageSize(220, 313, BASE_IMGURL + "/Stream/Movie/Boxcovers/a" + aebnId.toString() + "_bb.jpg"); ma.setSizeOrder(FanartSizes.MEDIUM.getOrder()); ma.setLanguage(options.getLanguage().name()); ma.setType(MediaArtworkType.DISC); artwork.add(ma); LOGGER.debug("AEBN: add poster({})", posterpreviewUrl); } if ((options.getArtworkType() == MediaArtworkType.ALL) || (options.getArtworkType() == MediaArtworkType.BACKGROUND)) { // Need to scrape movie metadata first (see getMetaData() -> Fanart/Background) md = getMetadata(options); LOGGER.debug("AEBN: return from media metadata scraping"); aebnId = Integer.parseInt(options.getId(AEBNID)); int i = 1; while (!md.getStringValue("backgroundUrl" + Integer.valueOf(i).toString()).isEmpty()) { MediaArtwork ma = new MediaArtwork(); ma.setProviderId(providerInfo.getId()); String backgroundUrl = md.getStringValue("backgroundUrl" + Integer.valueOf(i).toString()); ma.setDefaultUrl(backgroundUrl); ma.setPreviewUrl(backgroundUrl.replace("_179_101", "")); ma.addImageSize(179, 101, backgroundUrl); ma.addImageSize(120, 68, backgroundUrl.replace("_179_101", "")); ma.setSizeOrder(FanartSizes.SMALL.getOrder()); ma.setLanguage(options.getLanguage().name()); ma.setType(MediaArtworkType.BACKGROUND); artwork.add(ma); LOGGER.debug("AEBN: add background({})", backgroundUrl); i++; } } return artwork; } /** * Maps scraper genres to internal TMM genres. * * @param genre * genre name to map * @return MediaGenres genre */ private MediaGenres getTmmGenre(String genre) { LOGGER.debug("AEBN: getTmmGenre() {}", genre); MediaGenres g = null; if (genre.isEmpty()) { return g; } if (g == null) { g = MediaGenres.getGenre(genre); } return g; } /** * Sanitizes a string (remove non breaking spaces and trim). * * @param oldString * string to clean * @return the cleaned string */ private String cleanString(String oldString) { if (StringUtils.isEmpty(oldString)) { return ""; } // remove non breaking spaces String newString = oldString.replace(String.valueOf((char) 160), " "); // and trim return StringUtils.trim(newString); } /** * Sanitizes the search query by removing * <ul> * <li>stop words (a, the, der, die, das, la, le, il), * <li>digit values (e.g. year), * <li>punctuation marks, * <li>multiple spaces. * </ul> * * @param query * search query string to clean * @return the cleaned search query string */ private String cleanSearchQuery(String query) { if (StringUtils.isEmpty(query)) { return ""; } // use default function first // String newString = MetadataUtil.removeNonSearchCharacters(oldString); // prepare for easier regex ... String newString = " " + query + " "; // ... and sanitize, TODO: multiple stopwords newString = newString.replaceAll("(?i)( a | the | der | die | das | la | le | il |\\(\\d+\\))", " "); newString = newString.replaceAll("[\\.#&:!?,]", " "); newString = newString.replaceAll("\\s{2,}", " "); return StringUtils.trim(newString); } /** * Validates an AEBN id. * * @param aebnId * the AEBN id to be validated * @return true if is a valid AEBN id, false otherwise */ private static boolean isValidAebnId(Integer aebnId) { return ((aebnId != null) && (aebnId.intValue() > 0) && (aebnId.intValue() < 1000000)); } }