portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From woon...@apache.org
Subject svn commit: r966940 - in /portals/jetspeed-2/portal/trunk: ./ components/jetspeed-search/ components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/ components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/ componen...
Date Fri, 23 Jul 2010 02:56:14 GMT
Author: woonsan
Date: Fri Jul 23 02:56:13 2010
New Revision: 966940

URL: http://svn.apache.org/viewvc?rev=966940&view=rev
Log:
JS2-1198: Upgrading Lucene to the latest one.
Also, 
- made the test case to not open http connection during testing; instead load html content from the local classpath urls.
- added 'synthetic' field (which is indexed but not stored) to simplify query without using MultiFieldQueryParser.
- improved not to add multiple documents on a portlet.
- improved resource usages to avoid possible leaks.
- added max top count in search API because Lucene has that limitation in API as well.
- added portlet registry search test case.

Added:
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java   (with props)
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt   (with props)
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt   (with props)
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt   (with props)
Modified:
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/pom.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/URLToDocHandler.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/SearchEngineImpl.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestSearch.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/ParsedObject.java
    portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/SearchEngine.java
    portals/jetspeed-2/portal/trunk/pom.xml

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-search/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/pom.xml?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/pom.xml Fri Jul 23 02:56:13 2010
@@ -19,66 +19,74 @@
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    
-    <modelVersion>4.0.0</modelVersion>
-    <prerequisites>
-        <maven>2.0.9</maven>
-    </prerequisites>
-    
-    <artifactId>jetspeed-search</artifactId>
-    <name>Jetspeed-2 Search Component</name>
-    <description>Jetspeed-2 Search Component</description>
-    <parent>
-        <groupId>org.apache.portals.jetspeed-2</groupId>
-        <artifactId>components</artifactId>
-        <version>2.2.2-SNAPSHOT</version>
-    </parent>
-    <packaging>jar</packaging>
+  
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>2.0.9</maven>
+  </prerequisites>
+  
+  <artifactId>jetspeed-search</artifactId>
+  <name>Jetspeed-2 Search Component</name>
+  <description>Jetspeed-2 Search Component</description>
+  <parent>
+    <groupId>org.apache.portals.jetspeed-2</groupId>
+    <artifactId>components</artifactId>
+    <version>2.2.2-SNAPSHOT</version>
+  </parent>
+  <packaging>jar</packaging>
 
-    <!-- Dependencies -->
+  <!-- Dependencies -->
 
-    <dependencies>
+  <dependencies>
 
-        <!-- Build Dependencies -->
-        <dependency>
-            <groupId>${pom.groupId}</groupId>
-            <artifactId>jetspeed-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>${pom.groupId}</groupId>
-            <artifactId>jetspeed-commons</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-httpclient</groupId>
-            <artifactId>commons-httpclient</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.lucene</groupId>
-            <artifactId>lucene-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        
-        <!-- Test Dependencies -->
-        <dependency>
-            <groupId>${pom.groupId}</groupId>
-            <artifactId>jetspeed-cm</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-          <groupId>org.slf4j</groupId>
-          <artifactId>slf4j-log4j12</artifactId>
-          <scope>test</scope>
-        </dependency>
-        
-    </dependencies>
+    <!-- Build Dependencies -->
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>jetspeed-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>jetspeed-commons</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-httpclient</groupId>
+      <artifactId>commons-httpclient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>jetspeed-cm</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+    
+  </dependencies>
 
 </project>

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/URLToDocHandler.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/URLToDocHandler.java?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/URLToDocHandler.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/handlers/URLToDocHandler.java Fri Jul 23 02:56:13 2010
@@ -18,11 +18,13 @@ package org.apache.jetspeed.search.handl
 
 // Java imports
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.io.IOUtils;
 import org.apache.jetspeed.search.AbstractObjectHandler;
 import org.apache.jetspeed.search.BaseParsedObject;
 
@@ -56,9 +58,45 @@ public class URLToDocHandler extends Abs
         }
 
         URL pageToAdd = (URL) o;
+        String content = getContentFromURL(pageToAdd);
+        
+        if (content != null)
+        {
+            try
+            {
+                result.setKey(java.net.URLEncoder.encode(pageToAdd.toString(),"UTF-8"));
+                result.setType(org.apache.jetspeed.search.ParsedObject.OBJECT_TYPE_URL);
+                // TODO: We should extract the <title> tag here.
+                result.setTitle(pageToAdd.toString());
+                result.setContent(content);
+                result.setDescription("");
+                result.setLanguage("");
+                result.setURL(pageToAdd);
+                result.setClassName(o.getClass().getName());
+                //logger.info("Parsed '" + pageToAdd.toString() + "'");
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+                //logger.error("Adding document to index", e);
+            }
+        }
+        
+        return result;
 
+    }
+    
+    private String getContentFromURL(final URL url)
+    {
+        if ("file".equals(url.getProtocol()))
+        {
+            return readContentFromURL(url);
+        }
+        
+        String content = null;
+        
         HttpClient client = new HttpClient();
-        GetMethod method = new GetMethod(pageToAdd.toString());
+        GetMethod method = new GetMethod(url.toString());
         method.setFollowRedirects(true);
         int statusCode = -1;
         int attempt = 0;
@@ -91,7 +129,6 @@ public class URLToDocHandler extends Abs
             // Check that we didn't run out of retries.
             if (statusCode != -1)
             {
-                String content = null;
                 try
                 {
                     content = method.getResponseBodyAsString();
@@ -100,28 +137,6 @@ public class URLToDocHandler extends Abs
                 {
                     //logger.error("Getting content for " + pageToAdd.toString(), ioe);
                 }
-
-                if (content != null)
-                {
-                    try
-                    {
-                        result.setKey(java.net.URLEncoder.encode(pageToAdd.toString(),"UTF-8"));
-                        result.setType(org.apache.jetspeed.search.ParsedObject.OBJECT_TYPE_URL);
-                        // TODO: We should extract the <title> tag here.
-                        result.setTitle(pageToAdd.toString());
-                        result.setContent(content);
-                        result.setDescription("");
-                        result.setLanguage("");
-                        result.setURL(pageToAdd);
-                        result.setClassName(o.getClass().getName());
-                        //logger.info("Parsed '" + pageToAdd.toString() + "'");
-                    }
-                    catch (Exception e)
-                    {
-                        e.printStackTrace();
-                        //logger.error("Adding document to index", e);
-                    }
-                }
             }
         }
         finally
@@ -129,8 +144,37 @@ public class URLToDocHandler extends Abs
             method.releaseConnection();
         }
 
-        return result;
-
+        return content;
+    }
+    
+    private String readContentFromURL(final URL url)
+    {
+        String content = null;
+        InputStream input = null;
+        
+        try
+        {
+            input = url.openStream();
+            content = IOUtils.toString(input);
+        }
+        catch (Exception e)
+        {
+        }
+        finally
+        {
+            if (input != null)
+            {
+                try
+                {
+                    input.close();
+                }
+                catch (Exception ce)
+                {
+                }
+            }
+        }
+        
+        return content;
     }
 }
 

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/SearchEngineImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/SearchEngineImpl.java?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/SearchEngineImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/main/java/org/apache/jetspeed/search/lucene/SearchEngineImpl.java Fri Jul 23 02:56:13 2010
@@ -29,6 +29,7 @@ import java.util.Set;
 
 import org.apache.commons.collections.MultiMap;
 import org.apache.commons.collections.map.MultiValueMap;
+import org.apache.commons.lang.StringUtils;
 import org.apache.jetspeed.search.BaseParsedObject;
 import org.apache.jetspeed.search.HandlerFactory;
 import org.apache.jetspeed.search.ObjectHandler;
@@ -39,15 +40,19 @@ import org.apache.lucene.analysis.Analyz
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Fieldable;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
-import org.apache.lucene.queryParser.ParseException;
-import org.apache.lucene.search.Hits;
+import org.apache.lucene.queryParser.QueryParser;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.util.Version;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -58,55 +63,87 @@ import org.slf4j.LoggerFactory;
 public class SearchEngineImpl implements SearchEngine
 {
     protected final static Logger log = LoggerFactory.getLogger(SearchEngineImpl.class);
-    private File rootIndexDir = null;
-    private String analyzerClassName = null;
+    private Directory directory;
+    private Analyzer analyzer;
     private boolean optimizeAfterUpdate = true;
     private HandlerFactory handlerFactory;
     
     private static final int KEYWORD = 0;
     private static final int TEXT = 1;
     
-    public SearchEngineImpl(String indexRoot, String analyzerClassName, boolean optimzeAfterUpdate, HandlerFactory handlerFactory)
+    private int defaultTopHitsCount = 1000;
+    
+    public SearchEngineImpl(Directory directory, Analyzer analyzer, boolean optimzeAfterUpdate, HandlerFactory handlerFactory)
     throws Exception
     {
-        //assume it's full path for now
-        rootIndexDir = new File(indexRoot);
-        this.analyzerClassName = analyzerClassName;
+        this(directory, analyzer, optimzeAfterUpdate, handlerFactory, 0);
+    }
+    
+    public SearchEngineImpl(Directory directory, Analyzer analyzer, boolean optimzeAfterUpdate, HandlerFactory handlerFactory, int defaultTopHitsCount)
+    throws Exception
+    {
+        this.directory = directory;
+        this.analyzer = analyzer;
         this.optimizeAfterUpdate = optimzeAfterUpdate;
         this.handlerFactory = handlerFactory;
         
-        try
+        if (defaultTopHitsCount > 0)
         {
-            Searcher searcher = null;
-            searcher = new IndexSearcher(rootIndexDir.getPath());
-            searcher.close();
+            this.defaultTopHitsCount = defaultTopHitsCount;
         }
-        catch (Exception e)
+        
+        validateIndexDirectory();
+    }
+    
+    public SearchEngineImpl(String indexRoot, String analyzerClassName, boolean optimzeAfterUpdate, HandlerFactory handlerFactory)
+    throws Exception
+    {
+        this(indexRoot, analyzerClassName, optimzeAfterUpdate, handlerFactory, 0);
+    }
+    
+    public SearchEngineImpl(String indexRoot, String analyzerClassName, boolean optimzeAfterUpdate, HandlerFactory handlerFactory, int defaultTopHitsCount)
+    throws Exception
+    {
+        if(analyzerClassName != null)
         {
-            if (rootIndexDir.exists())
-            {
-                log.warn("Failed to open Portal Registry indexes in {}. {}", 
-                          rootIndexDir.getPath(), e);
-            }
-            try
-            {
-                rootIndexDir.delete();
-                rootIndexDir.mkdirs();
-                
-                IndexWriter indexWriter = new IndexWriter(rootIndexDir, newAnalyzer(), true);
-                indexWriter.close();
-                indexWriter = null;
-                log.warn("Re-created Lucene Index in " + rootIndexDir.getPath());
-            }
-            catch (Exception e1)
-            {
-                String message = "Cannot RECREATE Portlet Registry indexes in "  + rootIndexDir.getPath();
-                log.error(message, e1);
-                throw new Exception(message);
+            try {
+                Class analyzerClass = Class.forName(analyzerClassName);
+                analyzer = (Analyzer) analyzerClass.newInstance();
+            } catch(InstantiationException ce) {
+                //logger.error("InstantiationException", e);
+            } catch(ClassNotFoundException ce) {
+                //logger.error("ClassNotFoundException", e);
+            } catch(IllegalAccessException ce) {
+                //logger.error("IllegalAccessException", e);
             }
         }
+        
+        if (analyzer == null) 
+        {
+            analyzer = new StandardAnalyzer(Version.LUCENE_30);
+        }
+        
+        this.optimizeAfterUpdate = optimzeAfterUpdate;
+        this.handlerFactory = handlerFactory;
+        
+        if (defaultTopHitsCount > 0)
+        {
+            this.defaultTopHitsCount = defaultTopHitsCount;
+        }
+        
+        //assume it's full path for now
+        File rootIndexDir = new File(indexRoot);
+        
+        if (!rootIndexDir.isDirectory())
+        {
+            rootIndexDir.mkdirs();
+        }
+        
+        directory = FSDirectory.open(rootIndexDir);
+        
+        validateIndexDirectory();
     }
-
+    
     /* (non-Javadoc)
      * @see org.apache.jetspeed.search.SearchEnging#add(java.lang.Object)
      */
@@ -123,129 +160,181 @@ public class SearchEngineImpl implements
      */
     public synchronized boolean add(Collection objects)
     {
-        boolean result = false;
+        IndexWriter indexWriter = null;
+        IndexReader indexReader = null;
+        Searcher searcher = null;
         
-        IndexWriter indexWriter;
         try
         {
-            indexWriter = new IndexWriter(rootIndexDir, newAnalyzer(), false);
-        }
-        catch (IOException e)
-        {
-            //logger.error("Error while creating index writer. Skipping add...", e);
-            return result;
-        }
-
-        Iterator it = objects.iterator();
-        while (it.hasNext()) 
-        {
-            Object o = it.next();
-            // Look up appropriate handler
-            ObjectHandler handler = null;
-            try
-            {
-                handler = handlerFactory.getHandler(o);
-            }
-            catch (Exception e)
-            {
-                //logger.error("Failed to create hanlder for object " + o.getClass().getName());
-                continue;
-            }
-
-            // Parse the object
-            ParsedObject parsedObject = handler.parseObject(o);
-
-            // Create document
-            Document doc = new Document();
-
-            // Populate document from the parsed object
-            if (parsedObject.getKey() != null)
-            {                
-                doc.add(new Field(ParsedObject.FIELDNAME_KEY, parsedObject.getKey(), Field.Store.YES, Field.Index.UN_TOKENIZED));
-            }
-            if (parsedObject.getType() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_TYPE, parsedObject.getType(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if (parsedObject.getTitle() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_TITLE, parsedObject.getTitle(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if (parsedObject.getDescription() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_DESCRIPTION, parsedObject.getDescription(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if (parsedObject.getContent() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_CONTENT, parsedObject.getContent(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if (parsedObject.getLanguage() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_LANGUAGE, parsedObject.getLanguage(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if (parsedObject.getURL() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_URL, parsedObject.getURL().toString(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            if(parsedObject.getClassName() != null)
-            {
-                doc.add(new Field(ParsedObject.FIELDNAME_CLASSNAME, parsedObject.getClassName(), Field.Store.YES, Field.Index.TOKENIZED));
-            }
-            
-            String[] keywordArray = parsedObject.getKeywords();
-            if(keywordArray != null)
+            Iterator it = objects.iterator();
+            while (it.hasNext()) 
             {
-            	for(int i=0; i<keywordArray.length; ++i)
-            	{
-            		String keyword = keywordArray[i];
-            		doc.add(new Field(ParsedObject.FIELDNAME_KEYWORDS, keyword, Field.Store.YES, Field.Index.UN_TOKENIZED));
-            	}
-            }
+                if (indexWriter == null)
+                {
+                    indexWriter = new IndexWriter(directory, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
+                    indexReader = indexWriter.getReader();
+                    searcher = new IndexSearcher(indexReader);
+                }
+                
+                Object o = it.next();
+                // Look up appropriate handler
+                ObjectHandler handler = null;
+                try
+                {
+                    handler = handlerFactory.getHandler(o);
+                }
+                catch (Exception e)
+                {
+                    log.error("Failed to create hanlder for object " + o.getClass().getName());
+                    continue;
+                }
+    
+                // Parse the object
+                ParsedObject parsedObject = handler.parseObject(o);
+                
+                String key = parsedObject.getKey();
+                // if there's an existing one with the same key, then remove it first.
+                if (parsedObject.getKey() != null)
+                {
+                    Term keyTerm = new Term(ParsedObject.FIELDNAME_KEY, key);
+                    TopDocs topDocs = searcher.search(new TermQuery(keyTerm), 1);
+                    if (topDocs.totalHits > 0)
+                    {
+                        indexWriter.deleteDocuments(keyTerm);
+                    }
+                }
+                
+                String type = parsedObject.getType();
+                String title = parsedObject.getTitle();
+                String description = parsedObject.getDescription();
+                String content = parsedObject.getContent();
+                String language = parsedObject.getLanguage();
+                URL url = parsedObject.getURL();
+                String className = parsedObject.getClassName();
+                
+                // Create document
+                Document doc = new Document();
+                
+                // Populate document from the parsed object
+                if (key != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_KEY, key, Field.Store.YES, Field.Index.NOT_ANALYZED));
+                }
+                if (type != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_TYPE, type, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                if (title != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_TITLE, title, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                if (description != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_DESCRIPTION, description, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                if (content != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_CONTENT, content, Field.Store.NO, Field.Index.ANALYZED));
+                }
+                if (language != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_LANGUAGE, language, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                if (url != null)
+                {
+                    String urlString = url.toString();
+                    doc.add(new Field(ParsedObject.FIELDNAME_URL, urlString, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                if (className != null)
+                {
+                    doc.add(new Field(ParsedObject.FIELDNAME_CLASSNAME, className, Field.Store.YES, Field.Index.ANALYZED));
+                }
+                
+                String[] keywordArray = parsedObject.getKeywords();
+                if(keywordArray != null)
+                {
+                	for(int i=0; i<keywordArray.length; ++i)
+                	{
+                		String keyword = keywordArray[i];
+                		doc.add(new Field(ParsedObject.FIELDNAME_KEYWORDS, keyword, Field.Store.YES, Field.Index.NOT_ANALYZED));
+                	}
+                }
+    
+                Map keywords = parsedObject.getKeywordsMap();
+                addFieldsToDocument(doc, keywords, KEYWORD);
+                
+                Map fields = parsedObject.getFields();
+                addFieldsToDocument(doc, fields, TEXT);
+                
+                List<String> syntheticField = new ArrayList<String>();
+                for (Fieldable fieldable : doc.getFields())
+                {
+                    String value = fieldable.stringValue();
+                    if (value != null)
+                    {
+                        syntheticField.add(value);
+                    }
+                }
+                doc.add(new Field(ParsedObject.FIELDNAME_SYNTHETIC, StringUtils.join(syntheticField, ' '), Field.Store.NO, Field.Index.ANALYZED));
 
-            Map keywords = parsedObject.getKeywordsMap();
-            addFieldsToDocument(doc, keywords, KEYWORD);
-            
-            Map fields = parsedObject.getFields();
-            addFieldsToDocument(doc, fields, TEXT);
- 
-            // Add the document to search index
-            try
-            {
+                // Add the document to search index
                 indexWriter.addDocument(doc);
+                //logger.debug("Index Document Count = " + indexWriter.docCount());
+                //logger.info("Added '" + parsedObject.getTitle() + "' to index");
             }
-            catch (IOException e)
-            {
-               //logger.error("Error adding document to index.", e);
-            }
-            //logger.debug("Index Document Count = " + indexWriter.docCount());
-            //logger.info("Added '" + parsedObject.getTitle() + "' to index");
-            result = true;
-        }
 
-        try
-        {
-        	if(optimizeAfterUpdate)
+        	if (objects.size() > 0 && optimizeAfterUpdate && indexWriter != null)
             {
-                indexWriter.optimize();
+        	    try
+        	    {
+        	        indexWriter.optimize();
+        	    }
+                catch (IOException e)
+                {
+                    log.error("Error while trying to optimize index.", e);
+                }
             }
         }
         catch (IOException e)
         {
-            //logger.error("Error while trying to optimize index.");
+            log.error("Error while writing index.", e);
+            return false;
         }
         finally
         {
-            try
+            if (searcher != null)
             {
-                indexWriter.close();
+                try
+                {
+                    searcher.close();
+                }
+                catch (IOException ce)
+                {
+                }
             }
-            catch (IOException e)
+            if (indexReader != null)
             {
-               //logger.error("Error while closing index writer.", e);
+                try
+                {
+                    indexReader.close();
+                }
+                catch (IOException ce)
+                {
+                }
+            }
+            if (indexWriter != null)
+            {
+                try
+                {
+                    indexWriter.close();
+                }
+                catch (IOException ce)
+                {
+                }
             }
         }
         
-        return result;
+        return true;
     }
 
     /* (non-Javadoc)
@@ -264,15 +353,19 @@ public class SearchEngineImpl implements
      */
     public synchronized boolean remove(Collection objects)
     {
-        boolean result = false;
+        IndexReader indexReader = null;
+        int deleteCount = 0;
         
         try 
         {
-            IndexReader indexReader = IndexReader.open(this.rootIndexDir);
-
             Iterator it = objects.iterator();
             while (it.hasNext()) 
             {
+                if (indexReader == null)
+                {
+                    indexReader = IndexReader.open(directory, false);
+                }
+                
                 Object o = it.next();
                 // Look up appropriate handler
                 ObjectHandler handler = handlerFactory.getHandler(o);
@@ -287,28 +380,42 @@ public class SearchEngineImpl implements
                 {
                     term = new Term(ParsedObject.FIELDNAME_KEY, parsedObject.getKey());
                     // Remove the document from search index
-                    int rc = indexReader.deleteDocuments(term);
+                    deleteCount += indexReader.deleteDocuments(term);
                     //logger.info("Attempted to delete '" + term.toString() + "' from index, documents deleted = " + rc);
                     //System.out.println("Attempted to delete '" + term.toString() + "' from index, documents deleted = " + rc);
-                    result = rc > 0;
                 }
             }
-
-            indexReader.close();
-
-            if(optimizeAfterUpdate)
+            
+            if (indexReader != null)
             {
-                optimize();
+                indexReader.close();
+                indexReader = null;
+            }
+            
+            if (deleteCount > 0 && optimizeAfterUpdate)
+            {
+                optimizeIndex();
             }
-
         }
         catch (Exception e)
         {
-            //logger.error("Exception", e);
-            result = false;
+            log.error("Exception during removing documents in the search index.", e);
+        }
+        finally
+        {
+            if (indexReader != null)
+            {
+                try
+                {
+                    indexReader.close();
+                }
+                catch (IOException ce)
+                {
+                }
+            }
         }
 
-        return result;
+        return deleteCount > 0;
     }
 
     /* (non-Javadoc)
@@ -362,11 +469,16 @@ public class SearchEngineImpl implements
      */
     public synchronized boolean optimize()
     {
+        return optimizeIndex();
+    }
+    
+    private boolean optimizeIndex()
+    {
         boolean result = false;
 
-    	try
-		{
-    		IndexWriter indexWriter = new IndexWriter(rootIndexDir, newAnalyzer(), false);
+        try
+        {
+            IndexWriter indexWriter = new IndexWriter(directory, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
             indexWriter.optimize();
             indexWriter.close();
             result = true;
@@ -377,71 +489,46 @@ public class SearchEngineImpl implements
         }
         return result;
     }
-
+    
     /* (non-Javadoc)
      * @see org.apache.jetspeed.search.SearchEngine#search(java.lang.String)
      */
     public SearchResults search(String queryString)
-    {        
-        Searcher searcher = null;
-        Hits hits = null;
-        
-        try
-        {
-            searcher = new IndexSearcher(rootIndexDir.getPath());
-        }
-        catch (IOException e)
-        {
-            //logger.error("Failed to create index search using path " + rootDir.getPath());
-            return null;
-        }
-        
-        Analyzer analyzer = newAnalyzer();
+    {
+        return search(queryString, defaultTopHitsCount);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.search.SearchEngine#search(java.lang.String)
+     */
+    public SearchResults search(String queryString, int topHitsCount)
+    {
+        SearchResults results = null;
         
-        String[] searchFields = {ParsedObject.FIELDNAME_CONTENT, ParsedObject.FIELDNAME_DESCRIPTION, ParsedObject.FIELDNAME_FIELDS,
-                           ParsedObject.FIELDNAME_KEY, ParsedObject.FIELDNAME_KEYWORDS, ParsedObject.FIELDNAME_LANGUAGE,
-                           ParsedObject.FIELDNAME_SCORE, ParsedObject.FIELDNAME_TITLE, ParsedObject.FIELDNAME_TYPE,
-                           ParsedObject.FIELDNAME_URL, ParsedObject.FIELDNAME_CLASSNAME};
-                            
-        Query query= null;
-        try
-        {
-        	String s[] = new String[searchFields.length];
-        	for(int i=0;i<s.length;i++)
-        		s[i] = queryString;
-            query = MultiFieldQueryParser.parse(s, searchFields, analyzer);
-//          Query query = QueryParser.parse(searchString, ParsedObject.FIELDNAME_CONTENT, analyzer);
-        }
-        catch (ParseException e)
-        {
-            List<ParsedObject> resultList = new ArrayList<ParsedObject>();
-            SearchResults results = new SearchResultsImpl(resultList);
-            return results;            
-        }
+        IndexReader indexReader = null;
+        Searcher searcher = null;
         
         try
         {
-            hits = searcher.search(query);
-        }
-        catch (IOException e)
-        {
-            List<ParsedObject> resultList = new ArrayList<ParsedObject>();
-            SearchResults results = new SearchResultsImpl(resultList);
-            return results;            
-        }
-
-        int hitNum = hits.length();
-        List<ParsedObject> resultList = new ArrayList<ParsedObject>(hitNum);
-        for(int i=0; i<hitNum; i++)
-        {
-            ParsedObject result = new BaseParsedObject();
-            try
+            indexReader = IndexReader.open(directory);
+            searcher = new IndexSearcher(indexReader);
+            
+            QueryParser queryParser = new QueryParser(Version.LUCENE_30, ParsedObject.FIELDNAME_SYNTHETIC, analyzer);
+            Query query = queryParser.parse(queryString);
+            TopDocs topDocs = searcher.search(query, topHitsCount);
+            
+            int count = Math.min(topHitsCount, topDocs.totalHits);
+            List<ParsedObject> resultList = new ArrayList<ParsedObject>(count);
+            
+            for (int i = 0; i < count; i++)
             {
-	            Document doc = hits.doc(i);
+                ParsedObject result = new BaseParsedObject();
+                
+	            Document doc = searcher.doc(topDocs.scoreDocs[i].doc);
 	        
 		        addFieldsToParsedObject(doc, result);
 		        
-		        result.setScore(hits.score(i));
+		        result.setScore(topDocs.scoreDocs[i].score);
 		        Field type = doc.getField(ParsedObject.FIELDNAME_TYPE);
 		        if(type != null)
 		        {
@@ -506,52 +593,43 @@ public class SearchEngineImpl implements
 		        
 		        resultList.add(i, result);
             }
-            catch(IOException e)
-            {
-                //logger
-            }
+            
+            results = new SearchResultsImpl(resultList);
         }
-
-        if (searcher != null)
+        catch (Exception e)
         {
-            try
+            log.error("Failed to search. ", e);
+        }
+        finally
+        {
+            if (searcher != null)
             {
-                searcher.close();
+                try
+                {
+                    searcher.close();
+                }
+                catch (IOException ioe)
+                {
+                    //logger.error("Closing Searcher", ioe);
+                }
             }
-            catch (IOException ioe)
+            
+            if (indexReader != null)
             {
-                //logger.error("Closing Searcher", ioe);
+                try
+                {
+                    indexReader.close();
+                }
+                catch (IOException ioe)
+                {
+                    //logger.error("Closing Index Reader", ioe);
+                }
             }
         }
         
-        SearchResults results = new SearchResultsImpl(resultList);
-        return results;
+        return (results != null ? results : new SearchResultsImpl(new ArrayList<ParsedObject>()));
     }
     
-    private Analyzer newAnalyzer() {
-        Analyzer rval = null;
-
-        if(analyzerClassName != null)
-        {
-	        try {
-	            Class analyzerClass = Class.forName(analyzerClassName);
-	            rval = (Analyzer) analyzerClass.newInstance();
-	        } catch(InstantiationException e) {
-	            //logger.error("InstantiationException", e);
-	        } catch(ClassNotFoundException e) {
-	            //logger.error("ClassNotFoundException", e);
-	        } catch(IllegalAccessException e) {
-	            //logger.error("IllegalAccessException", e);
-	        }
-        }
-
-        if(rval == null) {
-            rval = new StandardAnalyzer();
-        }
-
-        return rval;
-    }
-
     private void addFieldsToDocument(Document doc, Map fields, int type)
     {
         if(fields != null)
@@ -575,11 +653,11 @@ public class SearchEngineImpl implements
                                 {
                                     if(type == TEXT)
                                     {
-                                        doc.add(new Field(key.toString(), value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
+                                        doc.add(new Field(key.toString(), value.toString(), Field.Store.YES, Field.Index.ANALYZED));
                                     }
                                     else
                                     {
-                                        doc.add(new Field(key.toString(), value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
+                                        doc.add(new Field(key.toString(), value.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                                     }
                                 }
                             }
@@ -588,11 +666,11 @@ public class SearchEngineImpl implements
                         {
                             if(type == TEXT)
                             {
-                                doc.add(new Field(key.toString(), values.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
+                                doc.add(new Field(key.toString(), values.toString(), Field.Store.YES, Field.Index.ANALYZED));
                             }
                             else
                             {
-                                doc.add(new Field(key.toString(), values.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
+                                doc.add(new Field(key.toString(), values.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                             }
                         }
                     }
@@ -655,4 +733,80 @@ public class SearchEngineImpl implements
             }
         }
     }
+    
+    private void validateIndexDirectory() throws Exception
+    {
+        boolean recreateIndex = false;
+        
+        IndexReader indexReader = null;
+        Searcher searcher = null;
+        
+        try
+        {
+            indexReader = IndexReader.open(directory);
+            searcher = new IndexSearcher(indexReader);
+            searcher.close();
+            searcher = null;
+            indexReader.close();
+            indexReader = null;
+        }
+        catch (Exception e)
+        {
+            recreateIndex = true;
+        }
+        finally
+        {
+            if (searcher != null)
+            {
+                try 
+                {
+                    searcher.close();
+                }
+                catch (Exception ce)
+                {
+                }
+            }
+            if (indexReader != null)
+            {
+                try 
+                {
+                    indexReader.close();
+                }
+                catch (Exception ce)
+                {
+                }
+            }
+        }
+        
+        if (recreateIndex)
+        {
+            IndexWriter indexWriter = null;
+            
+            try
+            {
+                indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
+                indexWriter.close();
+                indexWriter = null;
+            }
+            catch (Exception e1)
+            {
+                String message = "Cannot RECREATE Portlet Registry indexes in "  + directory;
+                log.error(message, e1);
+                throw new Exception(message);
+            }
+            finally
+            {
+                if (indexWriter != null)
+                {
+                    try 
+                    {
+                        indexWriter.close();
+                    }
+                    catch (Exception ce)
+                    {
+                    }
+                }
+            }
+        }
+    }
 }

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java?rev=966940&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java Fri Jul 23 02:56:13 2010
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jetspeed.search;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.commons.collections.MultiHashMap;
+import org.apache.jetspeed.search.handlers.HandlerFactoryImpl;
+import org.apache.jetspeed.search.lucene.SearchEngineImpl;
+import org.apache.jetspeed.test.JetspeedTestCase;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.Version;
+
+/**
+ * TestPortletRegistrySearch
+ * @version $Id$
+ */
+public class TestPortletRegistrySearch extends JetspeedTestCase
+{
+    private Directory directory;
+    private Analyzer analyzer;
+    
+    SearchEngine searchEngine;
+    
+    public TestPortletRegistrySearch(String name)
+    {
+        super(name);
+    }
+    
+    /**
+     * Start the tests.
+     *
+     * @param args the arguments. Not used
+     */
+    public static void main(String args[]) 
+    {
+        junit.awtui.TestRunner.main( new String[] { TestPortletRegistrySearch.class.getName() } );
+    }
+ 
+    /**
+     * Creates the test suite.
+     *
+     * @return a test suite (<code>TestSuite</code>) that includes all methods
+     *         starting with "test"
+     */
+    public static Test suite() 
+    {
+        // All methods starting with "test" will be executed in the test suite.
+        return new TestSuite( TestPortletRegistrySearch.class );
+    }
+    
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        HashMap mapping = new HashMap();
+        mapping.put("java.util.HashMap", MapObjectHandler.class.getName());
+        HandlerFactoryImpl hfi = new HandlerFactoryImpl(mapping);
+        directory = new RAMDirectory();
+        analyzer = new StandardAnalyzer(Version.LUCENE_30);
+        searchEngine = new SearchEngineImpl(directory, analyzer, true, hfi);
+    }
+    
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        directory.close();
+    }
+    
+    public void testSimpleSearch()
+    {
+        Map<String, String> paDemo = new HashMap<String, String>();
+        paDemo.put("keyPrefix", "PortletApplication::");
+        paDemo.put("description", "demo portlet application");
+        paDemo.put("title", "Demo");
+        paDemo.put("name", "demo");
+        paDemo.put("type", ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION);
+
+        Map<String, String> paRss = new HashMap<String, String>();
+        paRss.put("keyPrefix", "PortletApplication::");
+        paRss.put("description", "rss portlet application");
+        paRss.put("title", "RSS");
+        paRss.put("name", "rss");
+        paRss.put("type", ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION);
+
+        searchEngine.add(paDemo);
+        searchEngine.add(paRss);
+        
+        SearchResults searchResults = searchEngine.search("demo");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("rss");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("application");
+        assertEquals(2, searchResults.size());
+        
+        // adding one more; the search engine is expected to have duplicate index.
+        searchEngine.add(paDemo);
+        
+        searchResults = searchEngine.search("demo");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("application");
+        assertEquals(2, searchResults.size());
+    }
+    
+    public void testPortletSearch()
+    {
+        Map<String, String> paDemo = new HashMap<String, String>();
+        paDemo.put("keyPrefix", "PortletApplication::");
+        paDemo.put("description", "demo portlet application");
+        paDemo.put("title", "Demo");
+        paDemo.put("name", "demo");
+        paDemo.put("type", ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION);
+
+        Map<String, String> helloPortlet = new HashMap<String, String>();
+        helloPortlet.put("keyPrefix", "PortletDefinition::");
+        helloPortlet.put("description", "hello portlet definition");
+        helloPortlet.put("title", "Hello World");
+        helloPortlet.put("name", "hello");
+        helloPortlet.put("type", ParsedObject.OBJECT_TYPE_PORTLET);
+
+        Map<String, String> guessPortlet = new HashMap<String, String>();
+        guessPortlet.put("keyPrefix", "PortletDefinition::");
+        guessPortlet.put("description", "guess portlet definition");
+        guessPortlet.put("title", "Guess - Pick A Number");
+        guessPortlet.put("name", "guess");
+        guessPortlet.put("type", ParsedObject.OBJECT_TYPE_PORTLET);
+
+        searchEngine.add(paDemo);
+        searchEngine.add(Arrays.asList(helloPortlet, guessPortlet));
+        
+        SearchResults searchResults = searchEngine.search("demo");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("hello");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("guess");
+        assertEquals(1, searchResults.size());
+        
+        searchResults = searchEngine.search("definition");
+        assertEquals(2, searchResults.size());
+    }
+    
+    public void testPortletSearchByRichQuery()
+    {
+        Map<String, String> paDemo = new HashMap<String, String>();
+        paDemo.put("keyPrefix", "PortletApplication::");
+        paDemo.put("description", "demo portlet application");
+        paDemo.put("title", "Demo");
+        paDemo.put("name", "demo");
+        paDemo.put("type", ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION);
+
+        Map<String, String> helloPortlet = new HashMap<String, String>();
+        helloPortlet.put("keyPrefix", "PortletDefinition::");
+        helloPortlet.put("description", "demo hello portlet definition");
+        helloPortlet.put("title", "Hello World");
+        helloPortlet.put("name", "hello");
+        helloPortlet.put("type", ParsedObject.OBJECT_TYPE_PORTLET);
+
+        Map<String, String> guessPortlet = new HashMap<String, String>();
+        guessPortlet.put("keyPrefix", "PortletDefinition::");
+        guessPortlet.put("description", "demo guess portlet definition");
+        guessPortlet.put("title", "Guess - Pick A Number");
+        guessPortlet.put("name", "guess");
+        guessPortlet.put("type", ParsedObject.OBJECT_TYPE_PORTLET);
+
+        searchEngine.add(paDemo);
+        searchEngine.add(Arrays.asList(helloPortlet, guessPortlet));
+        
+        SearchResults searchResults = searchEngine.search("demo");
+        assertEquals(3, searchResults.size());
+
+        String query = ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION + "\" AND ( demo )";
+        
+        searchResults = searchEngine.search(query);
+        assertEquals(1, searchResults.size());
+        
+        query = ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET + "\" " +
+            "AND NOT " + ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION + "\" " + 
+            "AND ( demo )";
+        
+        searchResults = searchEngine.search(query);
+        assertEquals(2, searchResults.size());
+
+        query = ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET + "\" " +
+        "AND NOT " + ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION + "\" " + 
+        "AND ( hello )";
+    
+        searchResults = searchEngine.search(query);
+        assertEquals(1, searchResults.size());
+        
+        query = ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET + "\" " +
+        "AND NOT " + ParsedObject.FIELDNAME_TYPE + ":\"" + ParsedObject.OBJECT_TYPE_PORTLET_APPLICATION + "\" " + 
+        "AND ( guess )";
+    
+        searchResults = searchEngine.search(query);
+        assertEquals(1, searchResults.size());
+    }
+    
+    public static class MapObjectHandler extends AbstractObjectHandler
+    {
+        private String keyPrefix;
+        
+        public ParsedObject parseObject(Object o)
+        {
+            BaseParsedObject result = null;
+            
+            if(o instanceof Map)
+            {
+                result = new BaseParsedObject();
+                Map<String, String> map = (Map<String, String>) o;
+                
+                keyPrefix = map.get("keyPrefix");
+                
+                result.setDescription(map.get("description"));
+                
+                result.setTitle(map.get("title"));
+                result.setKey(keyPrefix + map.get("name"));
+                result.setType(map.get("type"));
+                result.setClassName(map.get("class"));
+                
+                MultiHashMap fieldMap = new MultiHashMap();
+                fieldMap.put(ParsedObject.ID, map.get("name"));
+            }
+            
+            return result;
+        }
+    }
+}

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestPortletRegistrySearch.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestSearch.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestSearch.java?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestSearch.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/java/org/apache/jetspeed/search/TestSearch.java Fri Jul 23 02:56:13 2010
@@ -17,24 +17,25 @@
 package org.apache.jetspeed.search;
 
 import java.io.File;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Iterator;
 
-import org.apache.jetspeed.search.ParsedObject;
-import org.apache.jetspeed.search.SearchEngine;
-import org.apache.jetspeed.search.SearchResults;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
 import org.apache.jetspeed.search.handlers.HandlerFactoryImpl;
 import org.apache.jetspeed.search.lucene.SearchEngineImpl;
 import org.apache.jetspeed.test.JetspeedTestCase;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.Version;
 
 /**
  * @author jford
- *
+ * @version $Id$
  */
 public class TestSearch extends JetspeedTestCase
 {
@@ -42,6 +43,10 @@ public class TestSearch extends Jetspeed
     private final static String INDEX_DIRECTORY = "target/search_index";
 
     private File indexRoot;
+    
+    private Directory directory;
+    private Analyzer analyzer;
+    
     SearchEngine searchEngine;
     
     private URL jetspeedHomePage = null;
@@ -51,12 +56,15 @@ public class TestSearch extends Jetspeed
         super(name);
         
         try {
-            jetspeedHomePage = new URL("http://portals.apache.org/jetspeed-1/");
-        } catch (MalformedURLException e) {
+            jetspeedHomePage = getClass().getResource("jetspeed-1.txt");
+        } catch (Exception e) {
             e.printStackTrace();
         }
         
         indexRoot = new File(getBaseDir()+INDEX_DIRECTORY);
+        
+        directory = new RAMDirectory();
+        analyzer = new StandardAnalyzer(Version.LUCENE_30);
     }
     
     /**
@@ -89,29 +97,17 @@ public class TestSearch extends Jetspeed
         
         HandlerFactoryImpl hfi = new HandlerFactoryImpl(mapping);
         
-        searchEngine = new SearchEngineImpl(indexRoot.getPath(), null, true, hfi);
+        //searchEngine = new SearchEngineImpl(indexRoot.getPath(), null, true, hfi);
+        searchEngine = new SearchEngineImpl(directory, analyzer, true, hfi);
     }
     
     protected void tearDown() throws Exception
     {
-        File[] indexFiles = indexRoot.listFiles();
-        if(indexFiles != null)
-        {
-	        for(int i=0; i<indexFiles.length; i++)
-	        {
-	            File file = indexFiles[i];
-	            file.delete();
-	        }
-        }
-        
-        indexRoot.delete();
         super.tearDown();
     }
     
     public void testRemoveWebPage() throws Exception
     {
-        //System.out.println("search home = " + JetspeedResources.getString("services.SearchService.directory"));
-        
         assertNotNull("Created URL to Jetspeed Home Page",  jetspeedHomePage);
         assertTrue("Removing non-existent index entry", searchEngine.remove(jetspeedHomePage) == false);
         assertTrue("Adding to index", searchEngine.add(jetspeedHomePage));
@@ -120,12 +116,10 @@ public class TestSearch extends Jetspeed
     
     public void testPutWebPage() throws Exception
     {
-        //System.out.println("search home = " + JetspeedResources.getString("services.SearchService.directory"));
-        
         assertNotNull("Created URL to Jetspeed Home Page",  jetspeedHomePage);
         assertTrue("Adding to index", searchEngine.add(jetspeedHomePage));
-        assertTrue("Adding to index", searchEngine.add(new URL("http://www.java.net")));
-        assertTrue("Adding to index", searchEngine.add(new URL("http://portals.apache.org")));
+        assertTrue("Adding to index", searchEngine.add(getClass().getResource("supporting.txt")));
+        assertTrue("Adding to index", searchEngine.add(getClass().getResource("portals.txt")));
     }
     
     /**
@@ -154,10 +148,11 @@ public class TestSearch extends Jetspeed
     
     public void testVerifyJetspeedSearch1() throws Exception
     {
-//      because tear down deletes files, need to do add again
+        //because tear down deletes files, need to do add again
         testPutWebPage();
         
         SearchResults results  = searchEngine.search("Jetspeed");
+        System.out.println("Hit count: " + results.size());
         assertTrue(" Hit count == 0", results.size() > 0);
         
         Iterator resultIter = results.iterator();
@@ -173,10 +168,11 @@ public class TestSearch extends Jetspeed
     
     public void testVerifyJetspeedSearch2() throws Exception
     {
-//      because tear down deletes files, need to do add again
+        //because tear down deletes files, need to do add again
         testPutWebPage();
         
-        SearchResults results  = searchEngine.search("community");
+        SearchResults results  = searchEngine.search("collaborative");
+        System.out.println("Hit count: " + results.size());
         assertTrue(" Hit count == 0", results.size() > 0);
         
         Iterator resultIter = results.iterator();

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt?rev=966940&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt Fri Jul 23 02:56:13 2010
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+Project Status Update
+Jetspeed-1 is Retired
+
+    As of 2008-12-04, the Jetspeed-1 project is retired.
+
+    All new development for Jetspeed is now found under the current, active project, Apache Project Jetspeed-2.
+
+    This site is kept online to provide documentation for legacy projects.
+
+What is Jetspeed?
+
+Jetspeed is an Open Source implementation of an Enterprise Information Portal, using Java and XML. A portal makes network resources (applications, databases and so forth) available to end-users. The user can access the portal via a web browser, WAP-phone, pager or any other device. Jetspeed acts as the central hub where information from multiple sources are made available in an easy to use manner.
+
+The data presented via Jetspeed is independent of content type, This means that content from for example XML,RSS or SMTP can be integrated with Jetspeed. The actual presentation of the data is handled via ates XSL and delivered to the user for example via the combination of Java Server Pages (JSPs) and HTML. Jetspeed provides support for templating and content publication frameworks such as Cocoon, WebMacro and Velocity. Note that outside of regualar browser Jetspeed also supports WAP devices.
+
+Jetspeed helps you build portal applications quickly. The goal is to make Jetspeed a tool for both portal developers as well as user interface designers. Currently the focus is on providing developers with a set of tools that facilitates building the base for the portal. With Jetspeed you can quickly build an XML portal and also syndicate your own content.
+Overview
+
+Around 1995 the Internet really started to catch on. Real value started to be created when companies put their information online. Soon after this, many companies were started that had the goal of organizing all this information. The term "Portal" was created that described a Web Application that was designed to present a ton of information in a concise and centered way, thereby making the Internet easier to use. Popular examples would be Yahoo.com or Netscape.com, etc.
+
+Around 1999 Open Source really started to catch on. Apache and Java were really taking off. Enterprise Information Portals were created that would provide a drop down Intranet/Internet for companies. Jetspeed was created to deliver an Open Source Portal that individuals or companies could use and contribute to in an Open (Source) manner.
+
+Soon after creation, it became apparent that Jetspeed was going to become an "engine" for web applications. The only problem is that this was beyond the scope of this project. Around that time there were many discussions on the mailing list that spawned the Turbine project based on technology donated by Jon Stevens/Clear Ink. Turbine is now the Web Application framework that Jetspeed shares with many other web applications including Jyve.
+
+Please see the Resources page for more information.
+
+Copyright © 2010 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
+Apache and the Apache feather logo are trademarks of The Apache Software Foundation.
\ No newline at end of file

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/jetspeed-1.txt
------------------------------------------------------------------------------
    svn:keywords = Id

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt?rev=966940&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt Fri Jul 23 02:56:13 2010
@@ -0,0 +1,49 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+Welcome to the Apache Portals Project
+
+Apache Portals is a collaborative software development project dedicated to providing robust, full-featured, commercial-quality, and freely available Portal related software on a wide variety of platforms and programming languages. This project is managed in cooperation with various individuals worldwide (both independent and company-affiliated experts), who use the Internet to communicate, plan, and develop Portal software and related documentation.
+
+For more information on getting started with Apache Portals, see the Getting Started guide.
+About Portals
+
+Modern software is complex and expensive, which has motivated many companies to invest in enterprise portals as a mechanism by which they can manage information in a cohesive and structured fashion.
+
+Portals offer many advantages over other software applications. First, they provide a single point of entry for employees, partners, and customers. Second, portals can access Web services transparently from any device in virtually any location. Third, portals are highly flexible; they can exist in the form of B2E intra-nets, B2B extra-nets, or B2C inter-nets. Fourth, portals can be combined to form a portal network that can span a companys entire enterprise system, allowing for access both inside and outside the firewall.
+
+Portals have many advantages, which is why they have become the de facto standard for Web application delivery. In fact, analysts have predicted that portals will become the next generation for the desktop environment.
+
+Portals distinguish themselves from other software systems because they provide the ability to integrate disparate systems and leverage the functionality provided by those systems. As such, they are not mutually exclusive, and do not force you into an either-or decision vis-a-vis existing software systems. This point is of paramount importance, particularly when you consider the fact that Web services are destined to fuel the explosion of Web applications. Since portals can access any Web services, the conclusion is inescapable: portals provide a unique opportunity to leverage the functionality of nascent technologies as well as mature, well-established software systems.
+Jetspeed-2
+
+Jetspeed-2 is an Open Portal Platform and Enterprise Information Portal, written entirely in open source under the Apache license in Java and XML and based on open standards. All access to the portal is managed through a robust portal security policy. Within a Jetspeed portal, individual portlets can be aggregated to create a page. Each portlet is an independent application with Jetspeed acting as the central hub making information from multiple sources available in an easy to use manner.
+
+The latest version of Jetspeed, Version 2.2.1, most significantly introduces the Jetui client-side customization engine. Version 2.2.0 was our first release conformant to the Java Portlet 2.0 Standard. All releases prior, such as the 2.1.x releases, are conformant to the first Java Portlet Specification, the Java Portlet 1.0 Standard.
+Pluto
+
+Pluto is the Reference Implementation of the Java Portlet Specification. The current version of this Portlet specification is JSR 168 1.0 Portlets are designed to run in the context of a portal. They are written to the Portlet API. Pluto implements the contract, the Portlet API, between portlets and portals. Pluto is a portlet container.
+Applications
+
+ApplicationsApache Portals Applications (APA) is a collaborative software development project existing under the Apache Portals project. APA is dedicated to providing robust, full-featured, commercial-quality, and freely available Portlet Applications under the Apache license developed at the Apache Software Foundation.
+Portals-bridges
+
+The Bridges subproject includes common code and demos for the use of common web frameworks via portlets. Currently there is support for writing portlets using JSF, Struts, perl CGI scripts, php code and Velocity templates. Jetspeed-2 includes demos for those technologies.
+Jetspeed-1
+
+Jetspeed-1 is an Open Source implementation of an Enterprise Information Portal, using Java and XML. Jetspeed-1 is a user-customizable portal system, supporting a rich feature set and mature user base. 
+
+Copyright © 2010 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
+Apache and the Apache feather logo are trademarks of The Apache Software Foundation.
\ No newline at end of file

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/portals.txt
------------------------------------------------------------------------------
    svn:keywords = Id

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt?rev=966940&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt Fri Jul 23 02:56:13 2010
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+Supporting Apache
+
+The Apache Software Foundation provides the infrastructure for the many Apache projects - the mailing lists, code repositories, bug tracking systems and other services that are so valuable for code development. All of this requires a financial assistance to maintain a paid staff to handle essential administration, to purchase bandwidth and to keep our servers running.
+
+All financial assistance to Apache is contributed by its user community, be they individuals or corporate entities. If you would like to contribute, the following pages explain more:
+
+    * Sponsoring Apache - the direct approach, you or your company could become one of our named sponsors.
+    * Donating to Apache - for smaller donations, you can donate via Paypal, Check, or even your car.
+    * Buy Apache Merchandise - get cool Apache merchandised swag, portions of the income are sent to Apache
+
+If you would like more information about supporting the ASF, please contact fundraising at apache dot org for more information.
+
+Lastly, thanks to all of those who have supported the ASF with sponsorship and donation over the years, we couldn't have done it without you. See our 'Thanks!' page to see this year's sponsors.
+
+Copyright © 2010 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
+Apache and the Apache feather logo are trademarks of The Apache Software Foundation.
\ No newline at end of file

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-search/src/test/resources/org/apache/jetspeed/search/supporting.txt
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/ParsedObject.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/ParsedObject.java?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/ParsedObject.java (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/ParsedObject.java Fri Jul 23 02:56:13 2010
@@ -50,7 +50,8 @@ public interface ParsedObject
     public static final String FIELDNAME_SCORE_DEFAULT = "Score";
     public static final String FIELDNAME_CLASSNAME = "fieldname.className";
     public static final String FIELDNAME_CLASSNAME_DEFAULT = "ClassName";
-
+    public static final String FIELDNAME_SYNTHETIC = "fieldname.synthetic";
+    
     // Known object types
     public static final String OBJECT_TYPE_URL = "url";
     public static final String OBJECT_TYPE_PORTLET = "portlet";

Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/SearchEngine.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/SearchEngine.java?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/SearchEngine.java (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/search/SearchEngine.java Fri Jul 23 02:56:13 2010
@@ -20,6 +20,7 @@ import java.util.Collection;
 
 /**
  * @author <a href="mailto: jford@apache.org">Jeremy Ford</a>
+ * @version $Id$
  */
 public interface SearchEngine
 {
@@ -38,4 +39,6 @@ public interface SearchEngine
     boolean optimize();
     
     SearchResults search(String query);
+    
+    SearchResults search(String query, int topHitsCount);
 }

Modified: portals/jetspeed-2/portal/trunk/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/pom.xml?rev=966940&r1=966939&r2=966940&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/pom.xml Fri Jul 23 02:56:13 2010
@@ -279,7 +279,7 @@
     
     <jdom.version>1.1</jdom.version>
     <log4j.version>1.2.14</log4j.version>
-    <lucene.version>2.3.2</lucene.version>
+    <lucene.version>3.0.2</lucene.version>
     <myfaces.version>1.1.5</myfaces.version>
     <ojb.version>1.0.3</ojb.version>
     <org.apache.derby.version>10.3.2.1</org.apache.derby.version>



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message