You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nutch.apache.org by si...@apache.org on 2006/04/16 21:48:15 UTC

svn commit: r394550 [1/5] - in /lucene/nutch/trunk/contrib: ./ web2/ web2/lib/ web2/res/ web2/src/ web2/src/main/ web2/src/main/java/ web2/src/main/java/org/ web2/src/main/java/org/apache/ web2/src/main/java/org/apache/nutch/ web2/src/main/java/org/apa...

Author: siren
Date: Sun Apr 16 12:48:09 2006
New Revision: 394550

URL: http://svn.apache.org/viewcvs?rev=394550&view=rev
Log:
new nutch ui

Added:
    lucene/nutch/trunk/contrib/
    lucene/nutch/trunk/contrib/web2/
    lucene/nutch/trunk/contrib/web2/README.txt
    lucene/nutch/trunk/contrib/web2/build.xml
    lucene/nutch/trunk/contrib/web2/lib/
    lucene/nutch/trunk/contrib/web2/lib/commons-beanutils.jar   (with props)
    lucene/nutch/trunk/contrib/web2/lib/commons-collections-3.0.jar   (with props)
    lucene/nutch/trunk/contrib/web2/lib/commons-digester.jar   (with props)
    lucene/nutch/trunk/contrib/web2/lib/struts.jar   (with props)
    lucene/nutch/trunk/contrib/web2/res/
    lucene/nutch/trunk/contrib/web2/res/nutch-header.xsl
    lucene/nutch/trunk/contrib/web2/res/nutch-page.xsl
    lucene/nutch/trunk/contrib/web2/src/
    lucene/nutch/trunk/contrib/web2/src/main/
    lucene/nutch/trunk/contrib/web2/src/main/java/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/BaseSearch.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/NavigationHelper.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/PluginResourceLoader.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Preferences.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Search.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContext.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContextImpl.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchForm.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchResultBean.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServiceLocator.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServletContextServiceLocator.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/WebappInstanceServiceLocator.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/web2_services.png   (with props)
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/AnchorsController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/CachedController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/ExplainController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/I18NPageController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/NutchController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/controller/SearchController.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/extension/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/extension/PostSearchExtensionPoint.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/extension/PreSearchExtensionPoint.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/extension/SearchExtensionPoint.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/extension/UIExtensionPoint.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/servlet/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/servlet/CachedServlet.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/servlet/OpenSearchServlet.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/tiles/
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/tiles/ExtendableDefinitionsFactory.java
    lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/tiles/NutchRequestProcessor.java
    lucene/nutch/trunk/contrib/web2/src/main/resources/
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_ca.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_de.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_es.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_fi.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_fr.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_hu.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_ms.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_nl.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_pl.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_pt.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_sh.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_sr.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_sv.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_th.properties
    lucene/nutch/trunk/contrib/web2/src/main/resources/org/nutch/jsp/resources_zh.properties
    lucene/nutch/trunk/contrib/web2/src/main/webapp/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/dtd/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/dtd/struts-config_1_2.dtd
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/dtd/tiles-config_1_1.dtd
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/dtd/web-app_2_2.dtd
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/dtd/web-app_2_3.dtd
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/anchors.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/cached.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/common.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/explain.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/footer.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/header.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/i18ncontent.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/more.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/navigate.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/noResults.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/results.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/search.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/jsp/template.jsp
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/res/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/res/style.css
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/struts-config.xml
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/tiles-defs.xml
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/tld/
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/tld/struts-bean.tld
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/tld/struts-logic.tld
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/tld/struts-tiles.tld
    lucene/nutch/trunk/contrib/web2/src/main/webapp/WEB-INF/web.xml   (with props)
    lucene/nutch/trunk/contrib/web2/src/main/webapp/index.jsp

Added: lucene/nutch/trunk/contrib/web2/README.txt
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/README.txt?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/README.txt (added)
+++ lucene/nutch/trunk/contrib/web2/README.txt Sun Apr 16 12:48:09 2006
@@ -0,0 +1,66 @@
+This folder contains an alternative search frontend implementation
+with a goal to be modular and extendable. Currently it
+is still in very early stage of development and might miss
+some functionality from the original ui.
+
+To achieve the primary goal it uses tiles 
+http://struts.apache.org/struts-tiles/index.html
+to represent blocks of functinality and layout on a search
+(and related) pages. Layout is constructed by using following
+tag libraries:
+
+struts-logic
+struts-tiles
+struts-bean
+
+These tiles blocks can be extended or overridden by plugins
+implementing org.apache.nutch.webapp.UIExtensionPoint. A
+plugin implementation typically contains own tiles-defs.xml
+file that contains definitions (extensions or overriders)
+it provides, tiles Controller, supporting classes and libraries.
+
+WebApp extension can contain ui logic (in forms of tiles
+controllers and pojos, jar libraries), ui markup
+(in form of html, jsp), ui resources css, javascript. there's
+no support for binary items at the time of writing this.
+
+To compile you need to fist build your nutch (core and plugins)
+after that run ant war to generate war.
+
+The nutch plugins are no included in the generated war and you
+need to properly configure where your plugins are. This is achieved
+by editing the nutch configuration file <NUTCH_HOME>/conf/nutch-site.xml
+the configuration parameter you need to edit is named
+'plugin.folders'
+
+
+Todo:
+
+-Provide some samples of ui plugins
+
+
+Directory contents
+
+/lib
+	contains required additional libraties, all Licenced and maintained by ASF.
+	struts.jar (version 1.2.9) and libraries required by struts.
+	
+/res
+  contains stylesheets to transform static html pages or page snippets
+
+/src/main/java
+	java sources
+	
+/src/main/resources
+	resources to be packaged in .jar, currently the localized resource files
+	
+/src/main/webapp
+  standard webapp folder
+	
+build.xml
+  contains minimal build instructions to create a .war
+  
+README.txt
+	this file
+	
+	

Added: lucene/nutch/trunk/contrib/web2/build.xml
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/build.xml?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/build.xml (added)
+++ lucene/nutch/trunk/contrib/web2/build.xml Sun Apr 16 12:48:09 2006
@@ -0,0 +1,291 @@
+<?xml version="1.0"?>
+<!-- This is a minimal build.xml file to build the
+webapp
+-->
+<project name="nutch-web2">
+
+	<property name="name" value="${ant.project.name}" />
+	<property name="root" value="${basedir}" />
+	<property name="nutch.root" location="${root}/../../" />
+
+
+	<property name="build.dir" location="target" />
+	<property name="build.classes" location="${build.dir}/classes" />
+	<property name="build.test" location="${build.dir}/test" />
+
+	<property name="src.dir" location="${root}/src/main/java" />
+	<property name="src.test" location="${root}/src/test" />
+	<property name="conf.dir" location="${nutch.root}/conf" />
+
+	<property name="deploy.dir" location="target" />
+
+	<property name="docs.src" value="${nutch.root}/src/web"/>
+	<property name="web.src.dir" value="${basedir}/src/main/webapp"/>
+	<property name="docs.dir" value="${build.dir}/${name}/"/>
+  <property name="build.plugins" value="${nutch.root}/build/plugins"/>
+
+	<property file="${nutch.root}/default.properties"/>
+
+	<property name="web.final.name" value="${name}-${version}" />
+
+	<fileset id="lib.jars" dir="." includes="lib/*.jar" />
+
+	<!--
+	Normal classpath
+	-->
+	<path id="classpath">
+		<pathelement location="${build.classes}" />
+		<fileset refid="lib.jars" />
+		<pathelement location="${nutch.root}/build/classes" />
+		<fileset dir="${nutch.root}/lib">
+			<include name="servlet-api.jar" />
+			<include name="hadoop-0.1.1.jar" />
+		</fileset>
+	</path>
+
+	<!--
+	Init
+	-->
+	<target name="init">
+		<mkdir dir="${build.dir}" />
+		<mkdir dir="${build.classes}" />
+		<mkdir dir="${build.test}" />
+	</target>
+
+	<!--
+	Compile Java files
+	-->
+	<target name="compile" depends="init">
+		<echo message="Compiling ${name}" />
+		<javac encoding="${build.encoding}" srcdir="${src.dir}" includes="**/*.java" destdir="${build.classes}" debug="${javac.debug}" optimize="${javac.optimize}" target="${javac.version}" source="${javac.version}" deprecation="${javac.deprecation}">
+			<classpath refid="classpath" />
+		</javac>
+	</target>
+
+	<target name="compile-core">
+		<ant target="compile-core" inheritall="false" dir="${nutch.root}" />
+		<ant target="compile" />
+	</target>
+
+	<!-- 
+	Make webapp .jar
+	-->
+	<target name="jar" depends="compile">
+		<jar jarfile="${build.dir}/${web.final.name}.jar">
+		<zipfileset dir="${build.classes}"/>
+		<!-- localized resources -->
+		<zipfileset dir="src/main/resources"/>
+		</jar>
+	</target>
+
+	<!--
+		generate the nutch.xml (servlet context) file 
+	-->
+	<target name="generate-context">
+	  <!-- xmlcatalog definition for xslt task -->
+	  <xmlcatalog id="docDTDs">
+	     <dtd publicId="-//W3C//DTD XHTML 1.0 Transitional//EN"            
+	          location="${nutch-root}/xmlcatalog/xhtml1-transitional.dtd"/> 
+	  </xmlcatalog> 
+		<xslt in="${nutch.root}/conf/nutch-default.xml" out="${build.dir}/nutch.xml" style="${nutch.root}/conf/context.xsl">
+			<xmlcatalog refid="docDTDs" />
+			<outputproperty name="indent" value="yes" />
+		</xslt>
+	</target>
+
+	<target name="war" depends="jar, generate-context, generate-pages">
+		<war destfile="${build.dir}/${web.final.name}.war" webxml="src/main/webapp/WEB-INF/web.xml">
+			<fileset dir="${web.src.dir}" excludes="WEB-INF/web.xml"/>
+			<zipfileset dir="${docs.src}" includes="include/*.html" />
+			<zipfileset dir="${build.docs}" includes="*/include/*.html" />
+			<fileset dir="${docs.dir}" />
+			<lib dir="${nutch.root}/lib">
+				<include name="lucene-*.jar" />
+				<include name="hadoop-*.jar" />
+				<include name="commons-lang-*.jar" />
+			</lib>
+
+			<fileset dir="${nutch.root}/docs" includes="img/**"/>
+
+			<!-- webapp .jar -->
+			<lib dir="${build.dir}">
+				<include name="${web.final.name}.jar"/>
+			</lib>
+			<lib dir="lib" includes="*.jar"/>
+
+			<!-- nutch .jar -->
+			<lib dir="${nutch.root}/build">
+				<include name="*.jar" />
+			</lib>
+			<classes dir="${conf.dir}" excludes="**/*.template" />
+<!-- no plugins
+			<zipfileset prefix="WEB-INF/classes/plugins" dir="${build.plugins}" >
+				<exclude name="parse-*/**"/>
+				<exclude name="protocol-*/**"/>
+			</zipfileset>
+			-->
+		</war>
+	</target>
+
+	<!--
+	Deploy to ${deploy.dir}
+	-->
+	<target name="deploy" depends="war">
+		<mkdir dir="${deploy.dir}" />
+		<copy file="${build.dir}/${web.final.name}.war" todir="${deploy.dir}" failonerror="false" />
+	</target>
+	
+	<!--
+	Compile test code
+	-->
+	<target name="compile-test" depends="compile" if="test.available">
+		<javac encoding="${build.encoding}" srcdir="${src.test}" includes="**/*.java" destdir="${build.test}" debug="${javac.debug}" optimize="${javac.optimize}" target="${javac.version}" source="${javac.version}" deprecation="${javac.deprecation}">
+			<classpath refid="test.classpath" />
+		</javac>
+	</target>
+
+	<!--
+	Run unit tests
+	-->
+	<target name="test" depends="compile-test, deploy" if="test.available">
+		<junit printsummary="yes" haltonfailure="no" fork="yes" errorProperty="tests.failed" failureProperty="tests.failed">
+			<sysproperty key="test.data" value="${build.test}/data" />
+			<sysproperty key="test.input" value="${root}/data" />
+			<classpath refid="test.classpath" />
+			<formatter type="plain" />
+			<batchtest todir="${build.test}" unless="testcase">
+				<fileset dir="${src.test}" includes="**/Test*.java" excludes="**/${test.exclude}.java" />
+			</batchtest>
+			<batchtest todir="${build.test}" if="testcase">
+				<fileset dir="${src.test}" includes="**/${testcase}.java" />
+			</batchtest>
+		</junit>
+
+		<fail if="tests.failed">Tests failed!</fail>
+
+	</target>
+
+	<!--
+	Clean.  Delete the build files, and their directories
+	-->
+	<target name="clean">
+		<delete dir="${build.dir}" />
+		<delete dir="${deploy.dir}" />
+	</target>
+
+  <target name="generate-locale" if="doc.locale">
+    <echo message="Generating docs for locale=${doc.locale}"/>
+
+    <mkdir dir="${build.docs}/${doc.locale}/include"/>
+    <xslt in="${docs.src}/include/${doc.locale}/header.xml"
+          out="${build.docs}/${doc.locale}/include/header.html"
+          style="res/nutch-header.xsl">
+        <xmlcatalog refid="docDTDs"/>
+    </xslt>
+
+    <dependset>
+       <srcfileset dir="${docs.src}/include/${doc.locale}" includes="*.xml"/>
+       <srcfileset dir="${docs.src}/style" includes="*.xsl"/>
+       <targetfileset dir="${docs.dir}/${doc.locale}" includes="*.html"/>
+    </dependset>  
+
+<!--    <copy file="${docs.src}/style/nutch-page.xsl"
+          todir="${build.docs}/${doc.locale}"
+          preservelastmodified="true"/>
+-->
+    <xslt basedir="${docs.src}/pages/${doc.locale}"
+          destdir="${docs.dir}/${doc.locale}"
+          includes="*.xml"
+          style="res/nutch-page.xsl">
+         <xmlcatalog refid="docDTDs"/>
+    </xslt>
+  </target>
+
+
+  <target name="generate-pages" depends="init">
+    <mkdir dir="${build.docs}/include"/>
+    <copy todir="${build.docs}/include">
+      <fileset dir="${docs.src}/include"/>
+    </copy>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="ca"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="de"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="en"/>
+    </antcall>
+    
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="es"/>
+    </antcall>
+    
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="fi"/>
+    </antcall>
+    
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="fr"/>
+    </antcall>
+    
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="hu"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="it"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="jp"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="ms"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="nl"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="pl"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="pt"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="sh"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="sr"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="sv"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="th"/>
+    </antcall>
+
+    <antcall target="generate-locale">
+      <param name="doc.locale" value="zh"/>
+    </antcall>
+
+    <fixcrlf srcdir="${docs.dir}" eol="lf" encoding="utf-8"
+             includes="**/*.html"/>
+
+  	<replace dir="${docs.dir}" token="search.jsp" value="search.do" includes="**/*.html"/>
+  	<replace dir="${docs.dir}" token="../" value="" includes="**/*.html"/>
+  	
+  </target>
+	
+</project>

Added: lucene/nutch/trunk/contrib/web2/lib/commons-beanutils.jar
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/lib/commons-beanutils.jar?rev=394550&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lucene/nutch/trunk/contrib/web2/lib/commons-beanutils.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lucene/nutch/trunk/contrib/web2/lib/commons-collections-3.0.jar
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/lib/commons-collections-3.0.jar?rev=394550&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lucene/nutch/trunk/contrib/web2/lib/commons-collections-3.0.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lucene/nutch/trunk/contrib/web2/lib/commons-digester.jar
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/lib/commons-digester.jar?rev=394550&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lucene/nutch/trunk/contrib/web2/lib/commons-digester.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lucene/nutch/trunk/contrib/web2/lib/struts.jar
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/lib/struts.jar?rev=394550&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lucene/nutch/trunk/contrib/web2/lib/struts.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lucene/nutch/trunk/contrib/web2/res/nutch-header.xsl
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/res/nutch-header.xsl?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/res/nutch-header.xsl (added)
+++ lucene/nutch/trunk/contrib/web2/res/nutch-header.xsl Sun Apr 16 12:48:09 2006
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- XSLT stylesheet that generates localized versions of the page header. -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:template match="header-menu">
+    <xsl:comment>This file is automatically generated.  Do not edit!</xsl:comment>
+    <table width="635" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+        <td valign="bottom" width="140" rowspan="2">
+	  <a href="./"><img src="img/reiter/logo_nutch.gif" border="0"/></a>
+          <img src="img/reiter/spacer_666666.gif" width="140" height="1"/>
+        </td>
+      </tr>
+      <tr>
+        <td width="495" valign="bottom" align="right">
+          <table border="0" cellpadding="0" cellspacing="0" width="495">
+            <tr>
+              <td background="img/reiter/_bg_reiter.gif" width="400">
+                <xsl:text disable-output-escaping="yes">&amp;#160;</xsl:text>
+              </td>
+<!-- menu -->
+              <xsl:for-each select="item">
+                <td height="28" valign="bottom" width="10">
+                  <xsl:choose>
+                    <xsl:when test="position()=1">
+                      <img src="img/reiter/reiter_inactive_le1.gif" border="0"/>
+                    </xsl:when>
+                    <xsl:otherwise>
+                      <img src="img/reiter/reiter_inactive_le.gif" border="0"/>
+                    </xsl:otherwise>
+                  </xsl:choose>
+                </td>
+                <td background="img/reiter/_bg_reiter_inactive.gif" valign="bottom" nowrap="nowrap">
+                  <xsl:variable name="url" select="a/@href"/>
+                  <a class="bodytext" href="{$url}">
+                    <xsl:value-of select="." disable-output-escaping="yes"/>
+                  </a>
+                </td>
+                <td height="28" valign="bottom" width="10">
+                  <img src="img/reiter/reiter_inactive_ri.gif" border="0"/>
+                </td>
+              </xsl:for-each>
+<!-- menue -->
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+  </xsl:template>
+</xsl:stylesheet>

Added: lucene/nutch/trunk/contrib/web2/res/nutch-page.xsl
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/res/nutch-page.xsl?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/res/nutch-page.xsl (added)
+++ lucene/nutch/trunk/contrib/web2/res/nutch-page.xsl Sun Apr 16 12:48:09 2006
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!-- XSLT stylesheet that adds Nutch style, header, and footer
+  elements.  This is used by Ant to generate static html pages. -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
+  <xsl:template match="page">
+      <xsl:comment>This page is automatically generated.  Do not edit!</xsl:comment>
+        <table width="635" border="0" cellpadding="0" cellspacing="0">
+          <tr valign="top">
+            <td width="140">
+              <xsl:call-template name="subnavi"/>
+            </td>
+            <td width="20" background="img/reiter/_spacer_cccccc.gif">
+              <xsl:text disable-output-escaping="yes">&amp;#160;</xsl:text>
+            </td>
+            <td width="475" class="body">
+              <xsl:call-template name="body"/>
+            </td>
+          </tr>
+        </table>
+  </xsl:template>
+<!-- included menu -->
+  <xsl:template name="subnavi">
+    <table width="100%" cellpadding="0" cellspacing="0">
+      <xsl:for-each select="menu/item">
+        <xsl:if test="not(.='')">
+          <tr class="menuTd" height="25">
+            <td class="menuTd" onmouseover="this.className='menuTdhover';" onmouseout="this.className='menuTd'" width="100%">
+              <xsl:text disable-output-escaping="yes">&amp;#160;:: </xsl:text>
+              <xsl:variable name="url" select="a/@href"/>
+              <a href="{$url}" class="menuEntry">
+                <xsl:value-of select="."/>
+              </a>
+            </td>
+          </tr>
+          <tr height="1px">
+            <td>
+              <img src="img/reiter/spacer_666666.gif" height="1" width="100%"/>
+            </td>
+          </tr>
+        </xsl:if>
+      </xsl:for-each>
+      <tr>
+        <td>
+          <xsl:text disable-output-escaping="yes">&amp;#160;</xsl:text>
+        </td>
+      </tr>
+    </table>
+  </xsl:template>
+<!-- /included menu -->
+<!-- included body -->
+  <xsl:template name="body">
+    <table width="475" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+        <td class="title" height="125" width="275" valign="bottom">
+          <xsl:value-of select="title" disable-output-escaping="yes"/>
+        </td>
+        <td height="125" width="200" valign="bottom">
+          <img src="img/reiter/robots.gif"/>
+        </td>
+      </tr>
+    </table>
+    <br class="br"/>
+    <xsl:for-each select="body/node()">
+      <xsl:choose>
+<!-- orange intro -->
+        <xsl:when test="name()='p' and position() &lt; 3">
+          <span class="intro">
+            <xsl:copy-of select="."/>
+          </span>
+        </xsl:when>
+<!-- all other text -->
+        <xsl:otherwise>
+          <span class="bodytext">
+            <xsl:copy-of select="."/>
+          </span>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+    <br class="br"/>
+    <br class="br"/>
+  </xsl:template>
+<!-- /included body -->
+</xsl:stylesheet>

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/BaseSearch.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/BaseSearch.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/BaseSearch.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/BaseSearch.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.LogFormatter;
+import org.apache.nutch.plugin.Extension;
+import org.apache.nutch.plugin.ExtensionPoint;
+import org.apache.nutch.plugin.PluginRuntimeException;
+import org.apache.nutch.webapp.extension.PostSearchExtensionPoint;
+import org.apache.nutch.webapp.extension.PreSearchExtensionPoint;
+import org.apache.nutch.webapp.extension.SearchExtensionPoint;
+
+public class BaseSearch {
+
+  public static Logger LOG = LogFormatter.getLogger(BaseSearch.class.getName());
+
+  protected PreSearchExtensionPoint[] presearch;
+
+  protected SearchExtensionPoint[] search;
+
+  protected PostSearchExtensionPoint[] postsearch;
+
+  protected Object[] setup(String xPoint, Configuration conf) {
+    HashMap filters = new HashMap();
+    try {
+      ExtensionPoint point = serviceLocator.getPluginRepository()
+          .getExtensionPoint(xPoint);
+      if (point == null)
+        throw new RuntimeException(xPoint + " not found.");
+      Extension[] extensions = point.getExtensions();
+      for (int i = 0; i < extensions.length; i++) {
+        Extension extension = extensions[i];
+        Object extensionInstance = extension.getExtensionInstance();
+        if (!filters.containsKey(extensionInstance.getClass().getName())) {
+          filters
+              .put(extensionInstance.getClass().getName(), extensionInstance);
+        }
+      }
+      return (Object[]) filters.values().toArray(new Object[filters.size()]);
+    } catch (PluginRuntimeException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  // private HttpServletRequest request;
+  private SearchContextImpl context;
+
+  private ServiceLocator serviceLocator;
+
+  /**
+   * Construct new BaseSearch object
+   */
+  public BaseSearch(ServiceLocator locator) {
+    this.serviceLocator = locator;
+    presearch = getPreSearchExtensions(serviceLocator.getConfiguration());
+    search = getSearchExtensions(serviceLocator.getConfiguration());
+    postsearch = getPostSearchExtensions(serviceLocator.getConfiguration());
+  }
+
+  public PreSearchExtensionPoint[] getPreSearchExtensions(Configuration conf) {
+    if (conf.getObject(PreSearchExtensionPoint.X_POINT_ID) == null) {
+      conf.set(PreSearchExtensionPoint.X_POINT_ID, setup(
+          PreSearchExtensionPoint.X_POINT_ID, conf));
+    }
+    return (PreSearchExtensionPoint[]) conf
+        .getObject(PreSearchExtensionPoint.X_POINT_ID);
+  }
+
+  public SearchExtensionPoint[] getSearchExtensions(Configuration conf) {
+    if (conf.getObject(SearchExtensionPoint.X_POINT_ID) == null) {
+      conf.set(SearchExtensionPoint.X_POINT_ID, setup(
+          SearchExtensionPoint.X_POINT_ID, conf));
+    }
+    return (SearchExtensionPoint[]) conf
+        .getObject(SearchExtensionPoint.X_POINT_ID);
+  }
+
+  public PostSearchExtensionPoint[] getPostSearchExtensions(Configuration conf) {
+    if (conf.getObject(PostSearchExtensionPoint.X_POINT_ID) == null) {
+      conf.set(PostSearchExtensionPoint.X_POINT_ID, setup(
+          PostSearchExtensionPoint.X_POINT_ID, conf));
+    }
+    return (PostSearchExtensionPoint[]) conf
+        .getObject(PostSearchExtensionPoint.X_POINT_ID);
+  }
+
+  /**
+   * Call plugins participating PreSearch activities
+   */
+  void callPreSearch() {
+    for (int i = 0; i < presearch.length; i++) {
+      presearch[i].doPreSearch(context);
+    }
+  }
+
+  /**
+   * Call plugins participating Search activities
+   */
+  void callSearch() {
+    for (int i = 0; i < search.length; i++) {
+      search[i].doSearch(context);
+    }
+  }
+
+  /**
+   * Call plugins participating postSearch activities
+   */
+  void callPostSearch() {
+    for (int i = 0; i < postsearch.length; i++) {
+      postsearch[i].doPostSearch(context);
+    }
+  }
+
+  /**
+   * Entry point to execute the search
+   */
+  public void doSearch() {
+    // initiate Search Object
+    LOG.fine("create search");
+    Search search = new Search(serviceLocator);
+    // create context
+    LOG.fine("create context");
+    context = new SearchContextImpl(search, serviceLocator);
+    LOG.fine("presearch");
+    callPreSearch();
+    LOG.fine("search");
+    callSearch();
+    LOG.fine("post");
+    callPostSearch();
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/NavigationHelper.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/NavigationHelper.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/NavigationHelper.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/NavigationHelper.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+/**
+ * Helper class to aid when forming search result navigation
+ * 
+ * 
+ */
+public class NavigationHelper {
+
+  private int pageStart;
+
+  private int hitsPerPage;
+
+  private long totalHits;
+
+  private boolean totalIsExact;
+
+  public NavigationHelper(int pageStart, int hitsPerPage, long totalHits,
+      boolean totalIsExact) {
+    this.pageStart = pageStart;
+    this.hitsPerPage = hitsPerPage;
+    this.totalHits = totalHits;
+    this.totalIsExact = totalIsExact;
+  }
+
+  protected Boolean hasPrev() {
+    return new Boolean(pageStart > 0);
+  }
+
+  protected Boolean hasNext() {
+    return new Boolean((totalIsExact && pageStart + hitsPerPage < totalHits)
+        || (!totalIsExact && totalHits > pageStart + hitsPerPage));
+
+  }
+
+  protected void next() {
+    pageStart += hitsPerPage;
+  }
+
+  /**
+   * Returns offset to next page
+   * 
+   * @return
+   */
+  public long getNextStart() {
+    return pageStart + hitsPerPage;
+  }
+
+  public void prev() {
+    pageStart -= hitsPerPage;
+  }
+
+  public int getPageNumber() {
+    return pageStart / hitsPerPage;
+  }
+
+  protected Boolean getShowAllHits() {
+    return new Boolean(!totalIsExact && (totalHits <= pageStart + hitsPerPage));
+  }
+
+  public long getEnd() {
+    return Math.min(totalHits, getNextStart());
+  }
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/PluginResourceLoader.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/PluginResourceLoader.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/PluginResourceLoader.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/PluginResourceLoader.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.util.LogFormatter;
+import org.apache.nutch.plugin.Extension;
+import org.apache.nutch.plugin.ExtensionPoint;
+import org.apache.nutch.plugin.PluginClassLoader;
+import org.apache.nutch.webapp.extension.UIExtensionPoint;
+
+/**
+ * PluginResourceLoader is capable of loading plugged in resources.
+ */
+public class PluginResourceLoader extends ClassLoader {
+
+  public class ThrowAwayClassLoader extends ClassLoader {
+
+    private ClassLoader one;
+
+    private ClassLoader two;
+
+    public ThrowAwayClassLoader(ClassLoader two, ClassLoader one) {
+      this.one = one;
+      this.two = two;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.ClassLoader#getResource(java.lang.String)
+     */
+    public URL getResource(String name) {
+      URL retVal = one.getResource(name);
+      if (retVal == null)
+        retVal = two.getResource(name);
+      return retVal;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
+     */
+    public InputStream getResourceAsStream(String name) {
+      InputStream retVal = one.getResourceAsStream(name);
+      if (retVal == null)
+        retVal = two.getResourceAsStream(name);
+      return retVal;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.ClassLoader#getResources(java.lang.String)
+     */
+    public Enumeration getResources(String name) throws IOException {
+      Enumeration retVal = one.getResources(name);
+      if (retVal == null)
+        retVal = two.getResources(name);
+      return retVal;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.ClassLoader#loadClass(java.lang.String)
+     */
+    public Class loadClass(String name) throws ClassNotFoundException {
+      LOG.info("loading class " + name + " from " + one);
+      try {
+        return one.loadClass(name);
+      } catch (ClassNotFoundException e) {
+      }
+      LOG.info("loading class " + name + " from " + two);
+      try {
+        return two.loadClass(name);
+      } catch (ClassNotFoundException e) {
+      }
+      LOG.info("could not find class, must throw Exception");
+      throw new ClassNotFoundException(name);
+    }
+  }
+
+  ClassLoader wrapped;
+
+  ArrayList classloaders = new ArrayList();
+
+  public static Logger LOG = LogFormatter.getLogger(PluginResourceLoader.class
+      .getName());
+
+  public static PluginResourceLoader getInstance(ServiceLocator locator,
+      ClassLoader parent) {
+    PluginResourceLoader loader = (PluginResourceLoader) locator
+        .getConfiguration().getObject(PluginResourceLoader.class.getName());
+
+    if (loader == null) {
+      LOG.info("created new nutch loader with parent loader:" + parent);
+      loader = new PluginResourceLoader(locator, parent);
+      locator.getConfiguration().setObject(
+          PluginResourceLoader.class.getName(), loader);
+    }
+    return loader;
+  }
+
+  private PluginResourceLoader(ServiceLocator locator, ClassLoader parent) {
+    init(locator, parent);
+  }
+
+  protected void init(ServiceLocator locator, ClassLoader parent) {
+
+    ArrayList seen = new ArrayList();
+
+    ArrayList paths = new ArrayList();
+
+    LOG
+        .info("PluginResourceLoader : dynamically setting jars based on plugins implementing UIExtensionPoint.");
+
+    ExtensionPoint point = locator.getPluginRepository().getExtensionPoint(
+        UIExtensionPoint.X_POINT_ID);
+
+    if (point == null) {
+      LOG.info("Can't find extension point '" + UIExtensionPoint.X_POINT_ID
+          + "'");
+      classloaders.add(parent);
+      return;
+    }
+
+    Extension[] extensions = point.getExtensions();
+
+    for (int i = 0; i < extensions.length; i++) {
+      Extension extension = extensions[i];
+
+      PluginClassLoader loader = extension.getDescriptor().getClassLoader();
+
+      // classloaders.add(loader);
+
+      URL urls[] = loader.getURLs();
+
+      for (int k = 0; k < urls.length; k++) {
+        URL url = urls[k];
+        if (!seen.contains(url)) {
+          paths.add(url);
+          LOG.info("Adding to classpath:" + url);
+        }
+        seen.add(url);
+      }
+    }
+
+    URL[] urls = (URL[]) paths.toArray(new URL[paths.size()]);
+    classloaders.add(new URLClassLoader(urls, parent));
+
+  }
+
+  /*
+   * s (non-Javadoc)
+   * 
+   * @see java.lang.ClassLoader#getResource(java.lang.String)
+   */
+  public URL getResource(String name) {
+    Iterator i = classloaders.iterator();
+
+    while (i.hasNext()) {
+      ClassLoader loader = (ClassLoader) i.next();
+      URL retVal = loader.getResource(name);
+      if (retVal != null) {
+        return retVal;
+      }
+    }
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
+   */
+  public InputStream getResourceAsStream(String name) {
+    Iterator i = classloaders.iterator();
+
+    while (i.hasNext()) {
+      ClassLoader loader = (ClassLoader) i.next();
+      InputStream retVal = loader.getResourceAsStream(name);
+      if (retVal != null) {
+        return retVal;
+      }
+    }
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see java.lang.ClassLoader#getResources(java.lang.String)
+   */
+  public Enumeration getResources(String name) throws IOException {
+    Iterator i = classloaders.iterator();
+
+    while (i.hasNext()) {
+      ClassLoader loader = (ClassLoader) i.next();
+      Enumeration retVal = loader.getResources(name);
+      if (retVal != null) {
+        return retVal;
+      }
+    }
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see java.lang.ClassLoader#loadClass(java.lang.String)
+   */
+  public Class loadClass(String name) throws ClassNotFoundException {
+
+    try {
+      // LOG.info("CUSTOM_LOADER->load");
+      Iterator i = classloaders.iterator();
+      Class retVal = null;
+      while (i.hasNext()) {
+
+        ClassLoader loader = (ClassLoader) i.next();
+        // LOG.info("trying to load " + name + " from:" + loader);
+        try {
+          retVal = loader.loadClass(name);
+        } catch (Exception e) {
+          LOG.info("Exception in loader " + e);
+        }
+        if (retVal != null) {
+          // LOG.info("CUSTOM_LOADER->found");
+          return retVal;
+        }
+      }
+      // LOG.info("CUSTOM_LOADER_not found");
+    } catch (Exception e) {
+      LOG.info("Exception in loader " + e);
+      e.printStackTrace(System.out);
+    }
+    throw new ClassNotFoundException(name);
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Preferences.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Preferences.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Preferences.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Preferences.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Preferences represents (extendable) configuration object that is persistable
+ * into user browser (as cookie)
+ * 
+ * cookie is in format key-1=value-1,key-2=value-2,key-n=value-n
+ */
+public class Preferences extends HashMap {
+
+  private static final long serialVersionUID = 1;
+
+  public static final String KEY_LOCALE = "L";
+
+  public static final String KEY_RESULTS_PER_PAGE = "R";
+
+  public static final String KEY_RESULTS_PER_DUP = "S";
+
+  public static final String KEY_DUP_FIELD = "D";
+
+  // Name of web ui cookie that stores users cutomized user preferences
+  public static String COOKIE_NAME = "NUTCH";
+
+  // default preferences, used for all who have not customized
+  static Preferences defaults = new Preferences();
+
+  static {
+    // results per page
+    defaults.put(KEY_RESULTS_PER_PAGE, "10");
+
+    // dup field
+    defaults.put(KEY_DUP_FIELD, "site");
+  }
+
+  /**
+   * 
+   * @return locale of user (from preferences if set, or from request)
+   */
+  public Locale getLocale(HttpServletRequest request) {
+    if (containsKey(KEY_LOCALE))
+      return new Locale((String) defaults.get(KEY_LOCALE));
+    else
+      return request.getLocale();
+  }
+
+  public static void setPreferencesCookie(HttpServletRequest request,
+      HttpServletResponse response, Preferences prefs) {
+    if (defaults.equals(prefs)) {
+      removeCookie(response);
+    } else {
+      setPreferencesCookie(response, prefs);
+    }
+  }
+
+  private static void setPreferencesCookie(HttpServletResponse response,
+      Preferences prefs) {
+    Cookie prefscookie = new Cookie(COOKIE_NAME, prefs.toString());
+    prefscookie.setMaxAge(Integer.MAX_VALUE);
+    response.addCookie(prefscookie);
+  }
+
+  public static void removeCookie(HttpServletResponse response) {
+    Cookie prefscookie = new Cookie(COOKIE_NAME, "");
+    prefscookie.setMaxAge(-1);
+    response.addCookie(prefscookie);
+  }
+
+  /**
+   * Parse Preferences from cookie
+   * 
+   * @param request
+   */
+  public static Preferences parseCookie(HttpServletRequest request) {
+    // find right cookie
+    Cookie c[] = request.getCookies();
+
+    if (c != null) {
+      for (int i = 0; i < c.length; i++) {
+        if (COOKIE_NAME.equals(c[i].getName())) {
+          return Preferences.parse(c[i].getValue());
+        }
+      }
+    }
+    return defaults;
+  }
+
+  public static Preferences parse(String data) {
+    Preferences p = new Preferences();
+    p.putAll(defaults);
+    String[] dataitems = data.split(",");
+    for (int i = 0; i < dataitems.length; i++) {
+      String keyvalue[] = dataitems[0].split("=");
+      if (keyvalue.length == 2) {
+        p.put(keyvalue[0], keyvalue[1]);
+        break;
+      }
+    }
+    return p;
+  }
+
+  public int getInt(String name, int defaultVal) {
+    try {
+      return get(name) == null ? defaultVal : Integer
+          .parseInt((String) get(name));
+    } catch (Exception e) {
+      return defaultVal;
+    }
+  }
+
+  /**
+   * return value or default if non existing
+   * 
+   */
+  public String getString(String name, String defaultVal) {
+    return get(name) == null ? defaultVal : (String) get(name);
+  }
+
+  public String toString() {
+    StringBuffer txt = new StringBuffer();
+    Object[] keys = keySet().toArray();
+
+    for (int i = 0; i < keys.length; i++) {
+      txt.append(keys[i].toString()).append("=").append(get(keys[i]));
+      if (i < keys.length - 1)
+        txt.append(",");
+    }
+
+    return txt.toString();
+  }
+
+  public static Preferences getPreferences(HttpServletRequest request) {
+    Preferences prefs = (Preferences) request.getAttribute(Preferences.class
+        .getName());
+    // processing locale
+    if (prefs == null) {
+      prefs = Preferences.parseCookie(request);
+      request.setAttribute(Preferences.class.getName(), prefs);
+    }
+    return prefs;
+  }
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Search.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Search.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Search.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/Search.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.util.LogFormatter;
+import org.apache.nutch.html.Entities;
+import org.apache.nutch.searcher.Hit;
+import org.apache.nutch.searcher.HitDetails;
+import org.apache.nutch.searcher.Hits;
+import org.apache.nutch.searcher.NutchBean;
+import org.apache.nutch.searcher.Query;
+
+/**
+ * Search is a bean that represents an ongoing search.
+ * 
+ * After search searchBean that represents the search user doing (also the
+ * results) might be a good candidate for caching ?
+ * 
+ */
+public class Search {
+
+  public static Logger LOG = LogFormatter.getLogger(Search.class.getName());
+
+  String queryString;
+
+  String htmlQueryString;
+
+  Query query;
+
+  int maxHits;
+
+  int startOffset;
+
+  int hitsPerSite;
+
+  int hitsPerPage;
+
+  String sortColumn;
+
+  boolean sortDesc;
+
+  Hits hits;
+
+  Hit[] show;
+
+  HitDetails[] details;
+
+  String[] summaries;
+
+  ArrayList results = null;
+
+  NavigationHelper navigationHelper;
+
+  ServiceLocator locator;
+
+  SearchForm form;
+
+  String dupField;
+
+  /**
+   * Perform search described by this bean
+   * 
+   * @param bean
+   */
+  public void performSearch(NutchBean bean) {
+
+    try {
+      hits = bean.search(getQuery(), getStartOffset() + getMaxHits(),
+          getHitsPerSite(), getDupField(), getSortColumn(), isSortDesc());
+    } catch (IOException e) {
+      hits = new Hits(0, new Hit[0]);
+    }
+
+    navigationHelper = new NavigationHelper(startOffset, hitsPerPage, hits
+        .getTotal(), hits.totalIsExact());
+
+    // set offset to next page to form so it get's to ui
+    if (navigationHelper.hasNext().booleanValue()) {
+      form.setValue(SearchForm.NAME_START, Long.toString(navigationHelper
+          .getNextStart()));
+    }
+
+    LOG.info("form:");
+    LOG.info(locator.getSearchForm().toString());
+    LOG.info("performing search");
+
+    // found some unused code ?
+    int realEnd = (int) Math.min(hits.getLength(), getStartOffset()
+        + getMaxHits());
+
+    show = hits.getHits(getStartOffset(), realEnd - getStartOffset());
+
+    try {
+      details = bean.getDetails(show);
+      summaries = bean.getSummary(details, getQuery());
+    } catch (IOException e) {
+      LOG.info("Error getting hit information:" + e);
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * gets the results of search to display
+   * 
+   * @return
+   */
+  public List getResults() {
+    if (results == null) {
+      results = new ArrayList(details.length);
+      for (int i = 0; i < details.length; i++) {
+        results.add(new SearchResultBean(this, show[i], details[i],
+            summaries[i]));
+      }
+    }
+    return results;
+  }
+
+  protected int parseInt(String value, int defaultValue) {
+    int ret = defaultValue;
+    if (value != null) {
+      try {
+        ret = Integer.parseInt(value);
+      } catch (Exception e) {
+        // ignore
+      }
+    }
+    return ret;
+  }
+
+  public Search(ServiceLocator locator) {
+    this.locator = locator;
+    Preferences prefs = locator.getPreferences();
+    form = locator.getSearchForm();
+
+    queryString = form.getValueString(SearchForm.NAME_QUERYSTRING);
+    if (queryString == null)
+      queryString = "";
+    htmlQueryString = Entities.encode(queryString);
+
+    startOffset = parseInt(form.getValueString(SearchForm.NAME_START), 0);
+    hitsPerPage = parseInt(form.getValueString(SearchForm.NAME_HITSPERPAGE),
+        prefs.getInt(Preferences.KEY_RESULTS_PER_PAGE, 10));
+    hitsPerSite = parseInt(form.getValueString("hitsPerSite"), prefs.getInt(
+        Preferences.KEY_RESULTS_PER_DUP, 2));
+
+    maxHits = hitsPerPage;
+
+    sortColumn = form.getValueString(SearchForm.NAME_SORTCOLUMN);
+
+    sortDesc = (sortColumn != null && "true".equals(form
+        .getValueString(SearchForm.NAME_SORTREVERSE)));
+
+    dupField = form.getValueString(SearchForm.NAME_DUPCOLUMN);
+    if (dupField == null)
+      dupField = "site";
+
+    try {
+      query = Query.parse(queryString, locator.getConfiguration());
+    } catch (IOException e) {
+      LOG.info("Error parsing query:" + e);
+      e.printStackTrace();
+    }
+
+  }
+
+  /**
+   * @return Returns the hitsPerPage.
+   */
+  public int getHitsPerPage() {
+    return hitsPerPage;
+  }
+
+  /**
+   * @param hitsPerPage
+   *          The hitsPerPage to set.
+   */
+  protected void setHitsPerPage(int hitsPerPage) {
+    this.hitsPerPage = hitsPerPage;
+  }
+
+  /**
+   * @return Returns the hitsPerSite.
+   */
+  public int getHitsPerSite() {
+    return hitsPerSite;
+  }
+
+  /**
+   * @param hitsPerSite
+   *          The hitsPerSite to set.
+   */
+  protected void setHitsPerSite(int hitsPerSite) {
+    this.hitsPerSite = hitsPerSite;
+  }
+
+  /**
+   * @return Returns the maxHits.
+   */
+  public int getMaxHits() {
+    return maxHits;
+  }
+
+  /**
+   * @param maxHits
+   *          The maxHits to set.
+   */
+  protected void setMaxHits(int maxHits) {
+    this.maxHits = maxHits;
+  }
+
+  /**
+   * @return Returns the query.
+   */
+  public Query getQuery() {
+    return query;
+  }
+
+  /**
+   * @param query
+   *          The query to set.
+   */
+  protected void setQuery(Query query) {
+    this.query = query;
+  }
+
+  /**
+   * @return Returns the queryString.
+   */
+  public String getQueryString() {
+    return queryString;
+  }
+
+  /**
+   * @param queryString
+   *          The queryString to set.
+   */
+  protected void setQueryString(String queryString) {
+    this.queryString = queryString;
+  }
+
+  /**
+   * Returns true if sort is descending
+   * 
+   * @return Returns sort order
+   */
+  public boolean isSortDesc() {
+    return sortDesc;
+  }
+
+  /**
+   * Set sort order
+   * 
+   * @param sortAsc
+   *          The sortAsc to set.
+   */
+  protected void setSortDesc(boolean sortAsc) {
+    this.sortDesc = sortAsc;
+  }
+
+  /**
+   * @return Returns the sortColumn.
+   */
+  public String getSortColumn() {
+    return sortColumn;
+  }
+
+  /**
+   * @param sortColumn
+   *          The sortColumn to set.
+   */
+  protected void setSortColumn(String sortColumn) {
+    this.sortColumn = sortColumn;
+  }
+
+  /**
+   * @return Returns the startOffset.
+   */
+  public int getStartOffset() {
+    return startOffset;
+  }
+
+  /**
+   * @param startOffset
+   *          The startOffset to set.
+   */
+  protected void setStartOffset(int startOffset) {
+    this.startOffset = startOffset;
+  }
+
+  /**
+   * @return Returns the htmlQueryString.
+   */
+  public String getHtmlQueryString() {
+    return htmlQueryString;
+  }
+
+  /**
+   * @param htmlQueryString
+   *          The htmlQueryString to set.
+   */
+  protected void setHtmlQueryString(String htmlQueryString) {
+    this.htmlQueryString = htmlQueryString;
+  }
+
+  /**
+   * @return Returns the details.
+   */
+  public HitDetails[] getDetails() {
+    return details;
+  }
+
+  /**
+   * @param details
+   *          The details to set.
+   */
+  protected void setDetails(HitDetails[] details) {
+    this.details = details;
+  }
+
+  /**
+   * @return Returns the hits.
+   */
+  public Hits getHits() {
+    return hits;
+  }
+
+  /**
+   * @param hits
+   *          The hits to set.
+   */
+  protected void setHits(Hits hits) {
+    this.hits = hits;
+  }
+
+  /**
+   * @return Returns the show.
+   */
+  public Hit[] getShow() {
+    return show;
+  }
+
+  /**
+   * @param show
+   *          The show to set.
+   */
+  protected void setShow(Hit[] show) {
+    this.show = show;
+  }
+
+  /**
+   * @return Returns the summaries.
+   */
+  public String[] getSummaries() {
+    return summaries;
+  }
+
+  /**
+   * @param summaries
+   *          The summaries to set.
+   */
+  protected void setSummaries(String[] summaries) {
+    this.summaries = summaries;
+  }
+
+  /**
+   * returns start, end, total, used for printing message on search page, this
+   * is why offset is +1'd
+   */
+  public String[] getResultInfo() {
+    return new String[] { Long.toString(startOffset + 1),
+        Long.toString(navigationHelper.getEnd()),
+        Long.toString(hits.getTotal()), getHtmlQueryString() };
+  }
+
+  /**
+   * @return true if more results available
+   */
+  public Boolean getHasNextPage() {
+    return navigationHelper.hasNext();
+  }
+
+  /**
+   * @return true if previous page if available
+   */
+  public Boolean getHasPrevPage() {
+    return navigationHelper.hasPrev();
+  }
+
+  public String getDupField() {
+    return dupField;
+  }
+
+  protected SearchForm getForm() {
+    return form;
+  }
+
+  /**
+   * 
+   * @return
+   */
+  public List getFormProperties() {
+    return form.getActive();
+  }
+
+  public Boolean getShowAllHits() {
+    return navigationHelper.getShowAllHits();
+  }
+
+  /**
+   * return boolean if there are results
+   * 
+   * @return
+   */
+  public Boolean getHasResults() {
+    return new Boolean(hits.getTotal() > 0);
+  }
+
+  public Boolean getIsSearch() {
+    return new Boolean(queryString == null || queryString.trim().equals(""));
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContext.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContext.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContext.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContext.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * SearchContext
+ */
+public interface SearchContext {
+
+  /**
+   * Get active search
+   * 
+   * @return
+   */
+  Search getSearch();
+
+  /**
+   * Test is named parameter exits
+   * 
+   * @param key
+   * @return
+   */
+  boolean containsKey(Object key);
+
+  /**
+   * Return named parameter
+   * 
+   * @param key
+   * @return
+   */
+  String getParameter(Object key);
+
+  /**
+   * Return named object
+   * 
+   * @param key
+   * @return
+   */
+  Object get(Object key);
+
+  /**
+   * Return active Preferences
+   * 
+   * @return
+   */
+  Preferences getPreferences();
+
+  /**
+   * Return active SearchForm
+   * 
+   * @return
+   */
+  SearchForm getSearchForm();
+
+  /**
+   * Return active Configuration
+   * 
+   * @return
+   */
+  Configuration getConfigiration();
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContextImpl.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContextImpl.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContextImpl.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchContextImpl.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.util.HashMap;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * Default Implementation of
+ * 
+ * @see SearchContext
+ */
+public class SearchContextImpl extends HashMap implements SearchContext {
+
+  private static final long serialVersionUID = 1L;
+
+  Search search;
+
+  ServiceLocator serviceLocator;
+
+  /**
+   * Constructs a SearchContextImpl object and initializes it with provided data
+   * 
+   * @param search
+   *          the Search object this context belongs to
+   * @param locator
+   *          Used ServiceLocator
+   */
+  SearchContextImpl(Search search, ServiceLocator locator) {
+    super();
+    this.search = search;
+    this.serviceLocator = locator;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.SearchContext#getSearch()
+   */
+  public Search getSearch() {
+    return search;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.SearchContext#getParameter(java.lang.Object)
+   */
+  public String getParameter(Object key) {
+    return (String) get(key);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.SearchContext#getPreferences()
+   */
+  public Preferences getPreferences() {
+    return serviceLocator.getPreferences();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.SearchContext#getSearchForm()
+   */
+  public SearchForm getSearchForm() {
+    return serviceLocator.getSearchForm();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.SearchContext#getConfigiration()
+   */
+  public Configuration getConfigiration() {
+    return serviceLocator.getConfiguration();
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchForm.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchForm.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchForm.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchForm.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SearchForm is a representation of query parameters submitted as part of
+ * search form. It provides functionality to preserve all required parameters
+ * for example when creating link to "next page"
+ * 
+ * Plugins participating in search
+ * 
+ * @see org.apache.nutch.webapp.extension.PreSearch,
+ * @see org.apache.nutch.webapp.extension.Search,
+ * @see org.apache.nutch.webapp.extension.PostSearch
+ * 
+ * can by reading (existing) or setting values to/from this map make sure that
+ * those parameters are persisted to forms/links requiring them without any
+ * special tricks.
+ * 
+ */
+public class SearchForm {
+
+  /**
+   * General HTTP parameter name wich contains hits per page value
+   */
+  public static final String NAME_HITSPERPAGE = "hitsPerPage";
+
+  public static final String NAME_HITSPERSITE = "hitsPerSite";
+
+  public static final String NAME_START = "start";
+
+  public static final String NAME_QUERYSTRING = "query";
+
+  public static final String NAME_SORTCOLUMN = "sort";
+
+  public static final String NAME_SORTREVERSE = "reverse";
+
+  public static final String NAME_DUPCOLUMN = "dup";
+
+  private static final long serialVersionUID = 1L;
+
+  Map o_values;
+
+  Map n_values = new HashMap();
+
+  ArrayList active;
+
+  /**
+   * KeyValue presents a class that holds key value pair
+   * 
+   */
+  public static class KeyValue {
+
+    String key;
+
+    String value;
+
+    /**
+     * Construct new KeyValue with provided values
+     * 
+     * @param key
+     *          the key
+     * @param value
+     *          the value
+     */
+    public KeyValue(String key, String value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    /**
+     * Gets the key
+     * 
+     * @return contained key
+     */
+    public String getKey() {
+      return key;
+    }
+
+    /**
+     * Gets the value
+     * 
+     * @return contained value
+     */
+    public String getValue() {
+      return value;
+    }
+
+    /**
+     * Sets the value
+     * 
+     * @param value
+     *          The value to set.
+     */
+    public void setValue(String value) {
+      this.value = value;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+      return value.toString();
+    }
+  }
+
+  /**
+   * Construct new SearchForm based on provided map map values are String arrays
+   * 
+   * @param parameters
+   *          original map from request
+   */
+  public SearchForm(Map parameters) {
+    o_values = parameters;
+    active = new ArrayList();
+  }
+
+  /**
+   * Sets value for provided key
+   * 
+   * @param key
+   *          the key to set the value on
+   * @param value
+   *          the value to set
+   */
+  public void setValue(String key, String value) {
+    if (n_values.containsKey(key)) {
+      ((KeyValue) n_values.get(key)).setValue(value);
+    } else {
+      n_values.put(key, new KeyValue(key, value));
+    }
+    active.add(n_values.get(key));
+  }
+
+  /**
+   * Gets the real value contained in keyed KeyValue
+   * 
+   * @param key
+   * @return
+   */
+  public String getValue(String key) {
+    if (n_values.containsKey(key)) {
+      active.add(n_values.get(key));
+      return (String) ((KeyValue) n_values.get(key)).getValue();
+    } else
+      return null;
+  }
+
+  /**
+   * Gets the String value contained in keyed KeyValue
+   * 
+   * @param key
+   * @return Object.toString()
+   */
+  public String getValueString(String key) {
+    if (n_values.containsKey(key)) {
+      active.add(n_values.get(key));
+    } else if (o_values.containsKey(key)) {
+      // get only the 1st parameter
+      n_values.put(key, new KeyValue(key, ((String[]) o_values.get(key))[0]));
+      active.add(n_values.get(key));
+    } else
+      return null;
+
+    try {
+      return (String) ((KeyValue) n_values.get(key)).getValue();
+    } catch (ClassCastException e) {
+      return ((KeyValue) n_values.get(key)).getValue().toString();
+    }
+  }
+
+  /**
+   * Remove named key (and the KeyValue)
+   * 
+   * @param key
+   * @return
+   */
+  public KeyValue remove(String key) {
+    if (n_values.containsKey(key)) {
+      active.remove(n_values.get(key));
+      return (KeyValue) n_values.remove(key);
+    } else
+      return null;
+  }
+
+  /**
+   * Get named KeyValue object
+   * 
+   * @param key
+   * @return named object or null if not existing
+   */
+  public KeyValue getKeyValue(String key) {
+    if (n_values.containsKey(key)) {
+      active.add(key);
+    }
+    return (KeyValue) n_values.get(key);
+  }
+
+  /**
+   * returns list of KeyValue objects that have been read or set
+   * 
+   * @return List containing KeyValue objects
+   */
+  public List getActive() {
+    return active;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see java.lang.Object#toString()
+   */
+  public String toString() {
+
+    StringBuffer sb = new StringBuffer();
+
+    sb.append("Original map {");
+
+    Iterator i = o_values.keySet().iterator();
+
+    while (i.hasNext()) {
+      Object o = i.next();
+      sb.append("[" + o.toString()).append(", ");
+      sb.append(((String[]) o_values.get(o))[0]).append("] ");
+    }
+    sb.append("}\n");
+
+    sb.append("Used map {");
+
+    i = n_values.keySet().iterator();
+
+    while (i.hasNext()) {
+      Object o = i.next();
+      sb.append("[" + o.toString()).append(", ");
+      sb.append(n_values.get(o)).append("] ");
+    }
+    sb.append("}\n");
+
+    return sb.toString();
+  }
+
+  /**
+   * Returns a string usable in urls that contains all active parameters and
+   * their values, if submitted encoding does not work values are encoded with
+   * default encoding.
+   * 
+   * @param encoding
+   * @return
+   */
+  public String getParameterString(String encoding)
+      throws UnsupportedEncodingException {
+
+    boolean useEncoding = true;
+    StringBuffer sb = new StringBuffer();
+
+    try {
+      URLEncoder.encode("", encoding);
+    } catch (UnsupportedEncodingException e) {
+      useEncoding = false;
+    }
+
+    List l = getActive();
+
+    Iterator i = l.iterator();
+    while (i.hasNext()) {
+      KeyValue kv = (KeyValue) i.next();
+      if (useEncoding) {
+        sb.append(URLEncoder.encode(kv.getKey(), encoding)).append("=").append(
+            URLEncoder.encode(kv.getValue(), encoding));
+      } else {
+        sb.append(URLEncoder.encode(kv.getKey())).append("=").append(
+            URLEncoder.encode(kv.getValue()));
+      }
+      if (i.hasNext()) {
+        sb.append("&");
+      }
+    }
+    return sb.toString();
+  }
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchResultBean.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchResultBean.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchResultBean.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/SearchResultBean.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.apache.nutch.html.Entities;
+import org.apache.nutch.searcher.Hit;
+import org.apache.nutch.searcher.HitDetails;
+
+/**
+ * SearchResultBean contains information about one search result in easily
+ * accessible form.
+ */
+public class SearchResultBean {
+
+  Hit hit;
+
+  String summary;
+
+  HitDetails details;
+
+  Search search;
+
+  public SearchResultBean(Search search, Hit hit, HitDetails details,
+      String summary) {
+    this.search = search;
+    this.hit = hit;
+    this.details = details;
+    this.summary = summary;
+  }
+
+  /**
+   * Url of search result
+   * 
+   * @return
+   */
+  public String getUrl() {
+    return details.getValue("url");
+  }
+
+  /**
+   * Title of search result
+   * 
+   * @return
+   */
+  public String getTitle() {
+    String title = details.getValue("title");
+    return title == null || title.equals("") ? getUrl() : title;
+  }
+
+  /**
+   * Id of search result
+   * 
+   * @return
+   */
+  public String getId() {
+    return "idx=" + hit.getIndexNo() + "&id=" + hit.getIndexDocNo();
+  }
+
+  /**
+   * Summary of search result
+   * 
+   * @return
+   */
+  public String getSummary() {
+    return summary;
+  }
+
+  /**
+   * Url of search result in encoded form
+   * 
+   * @return
+   */
+  public String getEncodedUrl() {
+    return Entities.encode(getUrl());
+  }
+
+  /**
+   * Title of search result in encoded form
+   * 
+   * @return
+   */
+  public String getEncodedTitle() {
+    return Entities.encode(getTitle());
+  }
+
+  /**
+   * "more" url this should be replaced with help of SearchForm
+   * 
+   * @return
+   * 
+   */
+  public String getMoreUrl() throws UnsupportedEncodingException {
+    String more = "";
+
+    more = "query="
+        + URLEncoder.encode(search.getDupField() + ":" + hit.getDedupValue()
+            + " " + search.getQueryString(), "UTF8")
+        + search.getForm().getParameterString("UTF8");// "&hitsPerSite=" + 0;
+
+    return more;
+  }
+
+  /**
+   * Dedup field name
+   * 
+   * @return
+   */
+  public String getDedupValue() {
+    return hit.getDedupValue();
+  }
+
+  /**
+   * QueryString in encoded form
+   * 
+   * @return
+   */
+  public String getUrlEncodedQuery() {
+    try {
+      if (search.getQueryString() != null)
+        return URLEncoder.encode(search.getQueryString(), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    return search.queryString != null ? search.queryString : "";
+  }
+
+  /**
+   * HitDetails of search result
+   * 
+   * @return
+   */
+  public HitDetails getDetails() {
+    return details;
+  }
+
+  /**
+   * Hit of search result
+   * 
+   * @return
+   */
+  public Hit getHit() {
+    return hit;
+  }
+
+  /**
+   * Boolean indicating that there are other, lower-scoring hits with the same
+   * dedup value
+   * 
+   * @see Hit#moreFromDupExcluded()
+   * 
+   * @return true if more dups available
+   */
+  public Boolean getHasMore() {
+    return new Boolean(hit.moreFromDupExcluded());
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServiceLocator.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServiceLocator.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServiceLocator.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServiceLocator.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.util.Locale;
+
+import org.apache.hadoop.conf.Configuration;
+
+import org.apache.nutch.plugin.PluginRepository;
+import org.apache.nutch.searcher.NutchBean;
+
+/**
+ * ServiceLocator interface. ServiceLocator is used to get handle to some of the
+ * core services of nutch.
+ */
+public interface ServiceLocator {
+
+  /**
+   * Return active Configuration instance (application context)
+   * 
+   * @return
+   */
+  public Configuration getConfiguration();
+
+  /**
+   * Return active PluginRepsository instance (application instance)
+   * 
+   * @return
+   */
+  public PluginRepository getPluginRepository();
+
+  /**
+   * Return active SearchForm (request instance)
+   * 
+   * @return
+   */
+  public SearchForm getSearchForm();
+
+  /**
+   * Return active Preferences (request context)
+   * 
+   * @return
+   */
+  public Preferences getPreferences();
+
+  /**
+   * Return active NutchBean (application context)
+   * 
+   * @return
+   */
+  public NutchBean getNutchBean();
+
+  /**
+   * Return active PluginResourceLoader (application context)
+   * 
+   * @return
+   */
+  public PluginResourceLoader getPluginResourceLoader(ClassLoader loader);
+
+  /**
+   * Return active Search (request context)
+   * 
+   * @return
+   */
+  public Search getSearch();
+
+  public Locale getLocale();
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServletContextServiceLocator.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServletContextServiceLocator.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServletContextServiceLocator.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/ServletContextServiceLocator.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,133 @@
+package org.apache.nutch.webapp.common;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletContext;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.LogFormatter;
+import org.apache.nutch.plugin.PluginRepository;
+import org.apache.nutch.searcher.NutchBean;
+import org.apache.nutch.util.NutchConfiguration;
+
+public abstract class ServletContextServiceLocator implements ServiceLocator {
+
+  /**
+   * ServiceLocator will be saved in ServletContext under this key
+   */
+  private static final String KEY = ServletContextServiceLocator.class
+      .getName();
+
+  /**
+   * Logger
+   */
+  public static Logger LOG = LogFormatter
+      .getLogger(ServletContextServiceLocator.class.getName());
+
+  /**
+   * ServletContext this ServiceLocator is bound to
+   */
+  protected ServletContext servletContext;
+
+  /**
+   * Active configuration
+   */
+  protected Configuration config;
+
+  /**
+   * Active PluginRepository
+   */
+  private PluginRepository repository;
+
+  /**
+   * Active NutchBean
+   */
+  private NutchBean bean;
+
+  /**
+   * Private Constructor used to create new ServiceLocator when needed
+   * 
+   * @param servletContext
+   */
+  private ServletContextServiceLocator(ServletContext servletContext) {
+    this.servletContext = servletContext;
+    config = NutchConfiguration.get(servletContext);
+    repository = PluginRepository.get(config);
+    try {
+      bean = new NutchBean(config);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Factory method to get handle to ServiceLocator, or if none exists in
+   * ServletContext then one is created.
+   * 
+   * @param context
+   * @return ServiceLocator instance bound to ServletContext
+   */
+  public static ServiceLocator getInstance(ServletContext context) {
+    ServiceLocator locator = (ServiceLocator) context.getAttribute(KEY);
+    if (locator == null) {
+      LOG.info("creating new serviceLocator for context:" + context);
+      locator = new ServletContextServiceLocator(context) {
+        public SearchForm getSearchForm() {
+          return null;
+        }
+
+        public Preferences getPreferences() {
+          return null;
+        }
+
+        public Search getSearch() {
+          return null;
+        }
+
+        public Locale getLocale() {
+          return null;
+        }
+      };
+      context.setAttribute(KEY, locator);
+    }
+    return locator;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getConfiguration()
+   */
+  public Configuration getConfiguration() {
+    return config;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getPluginRepository()
+   */public PluginRepository getPluginRepository() {
+    return repository;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getNutchBean()
+   */
+  public NutchBean getNutchBean() {
+    return bean;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getPluginResourceLoader(java.lang.ClassLoader)
+   */
+  public PluginResourceLoader getPluginResourceLoader(ClassLoader loader) {
+    return PluginResourceLoader.getInstance(this, loader);
+  }
+
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/WebappInstanceServiceLocator.java
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/WebappInstanceServiceLocator.java?rev=394550&view=auto
==============================================================================
--- lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/WebappInstanceServiceLocator.java (added)
+++ lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/WebappInstanceServiceLocator.java Sun Apr 16 12:48:09 2006
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.nutch.webapp.common;
+
+import java.util.Locale;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.LogFormatter;
+import org.apache.nutch.plugin.PluginRepository;
+import org.apache.nutch.searcher.NutchBean;
+
+public class WebappInstanceServiceLocator implements ServiceLocator {
+
+  public static Logger LOG = LogFormatter
+      .getLogger(WebappInstanceServiceLocator.class.getName());
+
+  HttpServletRequest request;
+
+  ServiceLocator contextLocator;
+
+  /**
+   * Creates new WebappInstanceServiceLocator instance and binds it to request
+   * 
+   * @param request
+   * @param servletContext
+   */
+  public WebappInstanceServiceLocator(HttpServletRequest request,
+      ServletContext servletContext) {
+    this.request = request;
+    contextLocator = ServletContextServiceLocator.getInstance(servletContext);
+    WebappInstanceServiceLocator.register(request, this);
+  }
+
+  public Preferences getPreferences() {
+    return Preferences.getPreferences(request);
+  }
+
+  public SearchForm getSearchForm() {
+    if (request.getAttribute(SearchForm.class.getName()) == null) {
+      request.setAttribute(SearchForm.class.getName(), new SearchForm(request
+          .getParameterMap()));
+    }
+    return (SearchForm) request.getAttribute(SearchForm.class.getName());
+  }
+
+  public Search getSearch() {
+    String key = Search.class.getName();
+    Search search = (Search) request.getAttribute(key);
+    if (search == null) {
+      search = new Search(this);
+      request.setAttribute(key, search);
+    }
+
+    return search;
+  }
+
+  /**
+   * 
+   * @param request
+   * @return
+   */
+  public static ServiceLocator getFrom(HttpServletRequest request) {
+    return (ServiceLocator) request
+        .getAttribute(WebappInstanceServiceLocator.class.getName());
+  }
+
+  /**
+   * 
+   * @param request
+   * @param locator
+   */
+  public static void register(HttpServletRequest request,
+      WebappInstanceServiceLocator locator) {
+    WebappInstanceServiceLocator l = (WebappInstanceServiceLocator) request
+        .getAttribute(WebappInstanceServiceLocator.class.getName());
+    if (locator != null && locator != l) {
+      request.setAttribute(WebappInstanceServiceLocator.class.getName(),
+          locator);
+    }
+  }
+
+  /*
+   *  (non-Javadoc)
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getConfiguration()
+   */
+  public Configuration getConfiguration() {
+    return contextLocator.getConfiguration();
+  }
+
+  /*
+   *  (non-Javadoc)
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getPluginRepository()
+   */
+  public PluginRepository getPluginRepository() {
+    return contextLocator.getPluginRepository();
+  }
+
+  /*
+   *  (non-Javadoc)
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getNutchBean()
+   */
+  public NutchBean getNutchBean() {
+    return contextLocator.getNutchBean();
+  }
+
+  /*
+   *  (non-Javadoc)
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getPluginResourceLoader(java.lang.ClassLoader)
+   */
+  public PluginResourceLoader getPluginResourceLoader(ClassLoader loader) {
+    return contextLocator.getPluginResourceLoader(loader);
+  }
+
+  /*
+   *  (non-Javadoc)
+   * @see org.apache.nutch.webapp.common.ServiceLocator#getLocale()
+   */
+  public Locale getLocale() {
+    return getPreferences().getLocale(request);
+  }
+}

Added: lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/web2_services.png
URL: http://svn.apache.org/viewcvs/lucene/nutch/trunk/contrib/web2/src/main/java/org/apache/nutch/webapp/common/web2_services.png?rev=394550&view=auto
==============================================================================
Binary file - no diff available.