| Main | Javadoc | Example |
|
|
This demo will show how several page import renderers and other framework elements can be combined using the DynamicPageImportRenderer to make automated (configured) navigation decisions.
The subject of the demo is a stock quote search against Quotes.com. On entering this page, the user can either type a ticker symbol into the search box or navigate to the lookup symbol page if they know the name of the company but not its stock ticker symbol.We will enhance the functionality of this site by allowing the user to use a single search form into which they can enter either a company name or a ticker symbol. Our strategy will be to use a DynamicPageImportRenderer which will allow us to check the returned page before sending it to the browser. If the initial search fails assuming a ticker symbol, we will run it as a name search and scrape the resulting URL an return that. If the name search returns more than one possible ticker symbol, we will return the results page.
<!-- ==================================================================== -->
<!-- DynamicPageImportRenderer: Stock Quote Resolver -->
<!-- ==================================================================== -->
<SystemObject type="PageImportRenderer" name="StockQuoteResolver"
configurableClass="com.raritantechnologies.searchApp.taglibrary.DynamicPageImportRenderer" >
<!-- ===================================================================== -->
<!-- Make sure we have a valid query first: -->
<!-- ===================================================================== -->
<ProxyRenderer>
<RequestParams>
<Param name="company" >
<Comparator class="com.raritantechnologies.utils.comparators.AnythingComparator" />
</Param>
</RequestParams>
<!-- ====================================================================== -->
<!-- The DynamicPageImportRenderer first tries to get the page assuming -->
<!-- that the user entered a valid ticker symbol. If this fails, Quotes.com -->
<!-- will return a results page that has the phrase 'is not a valid symbol' -->
<!-- in it. If we don't see this, we can assume that the search succeeded -->
<!-- and we will display the page. If we do see the failure message, we -->
<!-- will try again assuming that the user entered a company name. -->
<!-- ====================================================================== -->
<PageContextRenderer class="com.raritantechnologies.searchApp.taglibrary.DynamicPageImportRenderer" >
<ProxyRenderer>
<!-- ================================================================ -->
<!-- Use URLPageImportRenderer to do a Quotes.com ticker search -->
<!-- set dynamic params to do ticker symbol search on Quotes.com e.g. -->
<!-- http://www.quote.com/qc/stocks/quotes.aspx?symbols=[TICKER] -->
<!-- ================================================================ -->
<PageContextRenderer class="com.raritantechnologies.searchApp.taglibrary.URLPageImportRenderer"
pageFrom="dynamicURL"
urlBase="http://www.quote.com/qc/stocks/quotes.aspx" >
<Param inputParam="company" outputParam="symbols" />
</PageContextRenderer>
<!-- ========================================================================= -->
<!-- detect a valid data page (Valid if we DON'T see "is not a valid symbol" ) -->
<!-- Use a NotComparator to invert the logic of a StringContainsComparator: -->
<!-- ========================================================================= -->
<OutputComparator class="com.raritantechnologies.utils.comparators.NotComparator" >
<Comparator class="com.raritantechnologies.utils.comparators.StringContainsComparator"
contains="is not a valid symbol" />
</OutputComparator>
<!-- Need an OutputFilter here: fix relative URLs -->
<OutputFilter class="com.raritantechnologies.utils.filter.ReplaceSubstringFilter"
inPattern="href="/" outPattern="href="http://www.quote.com/"
replace="ALL" />
</ProxyRenderer>
<!-- ========================================================================== -->
<!-- If the above fails because the user entered a company name or a non-valid -->
<!-- ticker symbol, assume that a company name was tried and resolve that using -->
<!-- some string filtering magic. -->
<!-- ========================================================================== -->
<ProxyRenderer>
<PageContextRenderer class="com.raritantechnologies.searchApp.taglibrary.URLPageImportRenderer"
pageFrom="dynamicURL"
urlBase="http://www.quote.com/qc/lookup/search_results.aspx" >
<Param inputParam="company" outputParam="lookup" />
<FixedParam outputParam="context" outputValue="www_stocks" />
<PageFilter class="com.raritantechnologies.utils.filter.SequentialStringFilter" >
<!-- =========================================================== -->
<!-- Use a SelectingStringFilter to check if we need to go -->
<!-- after the single result of let the results page stand. -->
<!-- =========================================================== -->
<StringFilter class="com.raritantechnologies.utils.filter.SelectingStringFilter" >
<!-- Detect a single result "Showing results 1 through 1 of 1" -->
<Comparator class="com.raritantechnologies.utils.comparators.StringContainsComparator"
contains="1 of 1." />
<!-- ========================================================= -->
<!-- If we have only one result: lets just go GET it (even -->
<!-- computers are smart enough to make this decision )!!! -->
<!-- ========================================================= -->
<StringFilter class="com.raritantechnologies.utils.filter.SequentialStringFilter" >
<!-- HTMLScraperFilter to get link to Quote page URL (set for httpMethod = none ) -->
<StringFilter class="com.raritantechnologies.HTML.HTMLScraperFilter"
xmlScraperConfig="BASE_PATH/WEB-INF/conf/StockQuotes/QuotesDotComScraper.xml"
httpMethod="none" />
<!-- SAXCallbackStringFilter to extract quote URL from XML -->
<StringFilter class="com.raritantechnologies.xml.filter.SAXCallbackStringFilter"
callbackClass="com.raritantechnologies.xml.sax.filter.callbacks.CDataCallbackOperation"
multiple="false" >
<Comparator class="com.raritantechnologies.xml.sax.filter.comparators.TagComparator" >
<!-- This matches the Tag created by the HTMLScraperFilter -->
<TagName>QuoteURL</TagName>
</Comparator>
</StringFilter>
<!-- Now that we have a URL to the final quotes page: get it -->
<StringFilter class="com.raritantechnologies.utils.filter.ConcatenateFilter"
prependString="http://www.quote.com" />
<!-- URLContentFilter to get page from href -->
<StringFilter class="com.raritantechnologies.utils.filter.URLContentFilter"
useURLSocket="false"
requestMethod="get" />
</StringFilter>
</StringFilter> <!-- SelectingStringFilter -->
<!-- =============================================================== -->
<!-- Got here either after a deep scrape to get Quote page OR a -->
<!-- search results page if no, or too many initial results. In -->
<!-- either case, we need to do some cleanup on the hrefs since we -->
<!-- are framing the result page. This filter adds base urls for -->
<!-- relative paths so all images display with the full absolute url. -->
<!-- =============================================================== -->
<StringFilter class="com.raritantechnologies.utils.filter.ReplaceSubstringFilter"
inPattern="href="/" outPattern="href="http://www.quote.com/"
replace="ALL" />
</PageFilter>
</PageContextRenderer>
<!-- No comparator -->
</ProxyRenderer>
</PageContextRenderer> <!-- Check for valid search -->
</ProxyRenderer>
</SystemObject>