head	1.2;
access;
symbols;
locks; strict;
comment	@# @;


1.2
date	2001.08.10.20.02.36;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2001.08.10.19.40.21;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.2
log
@More HTML correction.
@
text
@<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>

<head>
 <title>The Helm Search Plugin Architecture</title>
</head>

<body>

<h1>The Helm Search Plugin Architecture</h1>
Leonard Richardson &lt;leonardr at collab dot net&gt;<br>
<small>$Id: search.html,v 1.1 2001/08/10 19:40:21 leonardr Exp $</small>

<h2>Introduction</h2>

 <p>Since your component contains mission-critical project data, it's
 important that it be accessible by a Web-based infrastructure that
 allows secure access to dynamic data in near-real-time. So why not
 leverage the Helm search plugin architecture? It allows your
 component to provide search results to cross-component and full-site
 searches. All you have to do is implement the
 <code>SearchPlugin</code> interface and register your implementation
 with Helm.

<h2><code>SearchResult</code></h2>

 <p>This class is the unit of exchange between Helm's search
 capabilities and your component. A <code>SearchResult</code> object
 encapsulates a project artifact of some kind, providing an interface
 to all the information which interests the Helm search result
 page. That information is basically a priority (used for sorting
 search results, discussed further down), a URL for linking to the
 artifact, a title for using as the text of the link, and a text
 fragment showing how the artifact matched the search or otherwise
 justifying a user's clicking on the link.

 <p>A <code>SearchResult</code> artifact also contains an
 <code>isViewableBy(AccessControlList)</code> method which is used to
 ensure that only artifacts are shown which a user has permission to
 view.

<h2><code>SearchPlugin</code></h2>

 <p>Each component which manages searchable artifacts can expose its
 search mechanisms to Helm's unified search interface by implementing
 Helm's <code>SearchPlugin</code> interface, either directly or by
 subclassing
 <code>SimpleSearchPlugin</code>. <code>SearchPlugin</code> contains
 information about the names and relative priorities of the fields
 which can be searched. It also implements a <code>search</code>
 method which returns a <code>List</code> of <code>SearchResult</code>
 objects, and an <code>index</code> method which indexes the fields
 you plan to search.

 <p>There is a default Helm indexing implementation into which you can
 hook if your application does not have its own indexing mechanism,
 and a default <code>search</code> implementation which uses the
 default indexing mechanism and makes use of
 <code>SearchResult.isViewableBy</code>. The idea is to make it as
 easy as possible to add a searching mechanism to your component.

 <p>The fully-qualified classpath of a component's
 <code>SearchPlugin</code> should be registered as
 "[component].searchPlugin" in the
 conf/[0-9][0-9][component].components file for the component's
 adapter. <i>[NOTE: A component might need to have more than one
 <code>SearchPlugin</code>; for instance, the CVS adapter needs one
 <code>SearchPlugin</code> for CVS data and one for Web content (a
 subset of CVS data.]</i>

<h2><code>IndexingService</code></h2>

 <p><code>IndexingService</code> is a Fulcrum service which lives in
 Helm. Every so often (the delay is configured by a host attribute,
 and defaults to five minutes), it will loop over its registered
 <code>SearchPlugin</code>s and call each one's <code>index</code>
 method.

 <p><code>index</code> takes a <code>Date</code> object, which Helm
 will set to the time of the previous <code>index</code> call.  If
 your component is capable of finding only the artifacts which were
 changed after a certain time, you can reindex only those and save
 time.

<h2>The Search Servlet</h2>

 <p>Helm has a servlet called Search which allows a user to do
 searches at three granularities (in addition to being able to search
 the entire domain, one project and its descendants, or just one
 project):

 <ol>

   <li>Search all plugins.

   <li>Search a specific plugin. Eg. search for projects, CVS data, or
   project web pages.

   <li>Search a specific field of a specific plugin. Eg. search for
   projects by name or description; mailing list messages by subject,
   author, or body; or news items by headline or body.

 </ol>

 <p>The form displayed by Search may include a list of plugins (for
 search type 2), or a list of plugins with selection boxes by field
 (for search type 3). For search type 3, a component may provide its
 own search controls by providing a Search.vm template.

 <p>Search obtains the user's search input, then iterates over
 <code>SearchPlugins</code> (if doing a search of type 1) and calls
 <code>search</code> on each plugin, which can do the search any way
 it wants so long as it returns a <code>List</code> of
 <code>SearchResult</code>s. Search then displays the resulting
 <code>SearchResult</code>s, and everyone is happy.

<h2>Prioritization</h2>

 <p>Every searchable field of an artifact has a priority. Priorities
 are measured on an absolute scale, with Helm reserving the name of a
 project and other project fields as having the highest priority.
 Other components can define priorities for fields of their artifacts.
 For instance, the subject of a mailing list message is defined by the
 Eyebrowse adapter to have higher priority than the body of the same
 message. 

 <p>Every <code>SearchResult</code> has a priority, which can be
 determined from the priorities of all the fields which matched the
 search. The Search servlet displays its results ordered by priority.

 <p>The exact prioritization algorithm has yet to be worked out, but
 here are some rules of thumb that are being considered:

 <ul>
  
  <li>The "foo" artifact should show up before the "foobar" artifact,
   ie.  matching the entire string is better than matching part of the
   string.

  <li>All else being equal, an artifact with a "foo" in a priority x
   attribute has priority over an artifact with a "foo" in a priority
   x+1 attribute. Example: a mailing list message with "foo" both in
   the subject and in the body has priority over one with "foo" only in
   the body.

  <li>All else being equal, if two artifacts have "foo" in a priority
  x attribute, and if one of them has more occurances of "foo" in that
  attribute than does the other, it comes first. Example: a mailing
  list message with "foo bar foo" in the body has priority over one
  with a mere "foo" in the body. 

  <li>Tiebreaker: if two artifacts have the exact same priority, the
  more recent or more recently modified artifact comes first in the
  list.

 </ul>

<h2>Unresolved Issues</h2>

 <p>Should the search functionality go into Helm or into a separate
 search component? Its status as a plugin driver seems to place it
 into Helm, but it's the sort of functionality that would be useful
 apart from Helm.

<h2>Conclusion</h2>

 <p>To make your component searchable from Helm, it should suffice to
 define a subclass of <code>SimpleSearchPlugin</code> with a
 <code>SearchResult</code> factory and simple <code>search</code> and
 <code>index</code> methods which drive the superclass
 functionality. If your component already does searching and indexing,
 you can implement <code>SearchPlugin</code> directly, and your
 <code>search</code> and <code>index</code> methods will just be thin
 wrappers around different functionality.

 <p>Happy Searching!

</body>

</html>@


1.1
log
@Another piece of the puzzle: definition of the search plugin architecture.
@
text
@d12 1
a12 1
<small>$Id: event.html,v 1.1 2001/08/10 14:30:26 leonardr Exp $</small>
d71 1
a71 1
<h2><code>IndexingService<code></h2>
@

