head	1.20;
access;
symbols
	TIGRIS_1_1_0RC2:1.9
	TIGRIS_1_1_0RC1:1.9
	TIGRIS_1_1:1.9.0.4
	TIGRIS_1_0_8:1.9
	TIGRIS_1_0_8RC3:1.9
	TIGRIS_1_0_8RC2:1.9
	TIGRIS_1_0_8RC1:1.9
	TIGRIS_1_0_7:1.9
	TIGRIS_1_0_7RC3:1.9
	TIGRIS_1_0_7RC2:1.9
	TIGRIS_1_0_7RC1:1.9
	TIGRIS_1_0_6:1.9
	TIGRIS_1_0_6RC5:1.9
	TIGRIS_1_0_6RC4:1.9
	TIGRIS_1_0_6RC3:1.9
	TIGRIS_1_0_6RC2:1.9
	TIGRIS_1_0_6RC1:1.9
	TIGRIS_1_0_5:1.9
	TIGRIS_1_0_5RC6:1.9
	TIGRIS_1_0_5RC5:1.9
	TIGRIS_1_0_5RC4:1.9
	TIGRIS_1_0_5RC3:1.9
	TIGRIS_1_0_5RC2:1.9
	TIGRIS_1_0_5RC1:1.9
	TIGRIS_1_0_4:1.9
	TIGRIS_1_0_3:1.9
	TIGRIS_1_0_2:1.9
	TIGRIS_1_0_1:1.9
	TIGRIS_1_0:1.9.0.6
	TIGRIS_1_0_0:1.9
	TIGRIS_1_0_0_RC1:1.9.0.2
	TIGRIS_0_9_2_4:1.2
	TIGRIS_0_9_2_3:1.2
	HELM_PEER_PORT_BRANCH:1.4.0.2
	TURBINE_PEER:1.4
	TIGRIS_0_9_2_1:1.4
	TIGRIS_0_9_2:1.2.0.6
	TIGRIS_0_9_0:1.2.0.4
	TIGRIS_0_8_4:1.2.0.2
	NEWHELM:1.1.1.1
	TIGRIS_NOV_12_2000:1.1.1;
locks; strict;
comment	@# @;


1.20
date	2001.08.28.17.45.18;	author leonardr;	state Exp;
branches;
next	1.19;

1.19
date	2001.08.28.01.36.37;	author leonardr;	state Exp;
branches;
next	1.18;

1.18
date	2001.08.11.09.08.08;	author dlr;	state Exp;
branches;
next	1.17;

1.17
date	2001.07.24.00.02.28;	author leonardr;	state Exp;
branches;
next	1.16;

1.16
date	2001.07.23.20.30.04;	author dlr;	state Exp;
branches;
next	1.15;

1.15
date	2001.07.19.20.22.44;	author dlr;	state Exp;
branches;
next	1.14;

1.14
date	2001.07.18.10.05.15;	author dlr;	state Exp;
branches;
next	1.13;

1.13
date	2001.07.17.20.22.46;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.07.16.21.37.32;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2001.06.25.18.22.19;	author leonardr;	state Exp;
branches;
next	1.10;

1.10
date	2001.05.23.01.50.20;	author dlr;	state Exp;
branches;
next	1.9;

1.9
date	2001.03.07.01.53.27;	author lucas;	state Exp;
branches;
next	1.8;

1.8
date	2001.02.23.19.08.04;	author stack;	state Exp;
branches;
next	1.7;

1.7
date	2001.02.21.05.36.24;	author edk;	state Exp;
branches;
next	1.6;

1.6
date	2001.02.21.05.06.13;	author edk;	state Exp;
branches;
next	1.5;

1.5
date	2001.02.21.04.06.32;	author edk;	state Exp;
branches;
next	1.4;

1.4
date	2001.01.26.18.29.08;	author edk;	state Exp;
branches
	1.4.2.1;
next	1.3;

1.3
date	2001.01.26.05.24.07;	author edk;	state dead;
branches;
next	1.2;

1.2
date	2000.11.27.23.36.10;	author stack;	state Exp;
branches;
next	1.1;

1.1
date	2000.11.12.21.16.30;	author dlr;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	2000.11.12.21.16.30;	author dlr;	state Exp;
branches;
next	;

1.4.2.1
date	2001.01.28.01.02.19;	author dlr;	state dead;
branches;
next	;


desc
@@


1.20
log
@More methods migrated to ContextAPI.
@
text
@/* ================================================================
 * Copyright (c) 2000 Collab.Net.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by Collab.Net (http://www.Collab.Net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of Collab.Net.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of Collab.Net.
 */
package org.tigris.helm.search;

import java.sql.*;
import java.util.*;

import org.apache.turbine.util.Log;
import org.apache.commons.util.exception.NestableException;
import org.apache.velocity.context.Context;

import org.tigris.helm.search.Query;
import org.tigris.helm.search.SearchSwishe;
import org.tigris.helm.search.SearchResult;
import org.tigris.helm.search.SearchResultItem;

import org.tigris.helm.om.Project;
import org.tigris.helm.om.Domain;
import org.tigris.helm.om.ProjectPeer;
import org.tigris.helm.tool.SessionManager;
import org.tigris.helm.DoesNotExist;
import org.tigris.helm.security.AccessControlList;
import org.tigris.helm.security.RedirectException;
import org.tigris.helm.tool.ContextAPI;

 
/** Search servlet that runs the result set through a permissions filter weeding
 * out results for which user does not have view permissions.
 * 
 * This servlet is based on <code>org.tigris.helm.search.SearchServlet</code>.
 *
 * <p>
 * Issues:
 * <ol>
 *    <li>None</li>
 * </ol>
 * </p>
 * <p>
 * Test Cases:
 * <ol>
 * <li>Permissions: What if user can view none of the result set, some of the 
 * result-set or all of the result-set?</li>
 * <li>What happens when form is empty and it's submitted?
 *     <ol>
 *         <li>Missing Fields message shows up saying Query is empty.</li>
 *     </ol>
 * </li>
 * <li>What happens when form is partially completed?  Does the missing fields
 *  messages display?
 *     <ol>
 *        <li>Doesn't apply.
 *        </li>
 *     </ol>
 * </li>
 * <li>On successful submission, does the content show up in the database?  
 *         <ol>
 *            <li>Doesn't apply.</li>
 *        </ol>
 * </li>
 * <li>On successful submission, are we taken to the next page, the project 
 * home page?
 *     <ol>
 *        <li>Yes -- only its same page but w/ search results filled out.</li>
 *    </ol>
 * </li>
 * <li>Check the javadoc.  How does it come out?
 *         <ol>
 *            <li>Looks good.  I built the javadoc using: 
 *                 <pre>/home/stack/software/jdk1.3/bin/javadoc -d javadoc -classpath /home/stack/cvsroot/sandbox/site/lib/helm.jar:${CLASSPATH}  -sourcepath . org.tigris.helm.search
 *                </pre>
 *            </li>
 *        </ol>
 * </li>
 * </ol>
 *
 * @@author <a href="mailto:stack@@collab.net">St.Ack</a>
 * @@version $Id: Search.java,v 1.19 2001/08/28 01:36:37 leonardr Exp $
 * @@see org.tigris.helm.search.SearchServlet
 */
public class Search
    extends org.tigris.helm.security.HelmServlet
    implements org.tigris.helm.search.SearchServletConstants
{
    /** Are we in debug state?
     */
    private static final boolean DEBUG = true;   
        
    
    /** Permission to check.  
     * Read from property file.
     */
    private String actionString = null;
    
    
    /** Key to pull permission from property file with.
     */
    private static final String PERMISSION = "permission";    
        

    /** Key to pull whether we should do permission check from.
     * property file.
     */
    private static final String PERMISSION_CHECK_KEY = "run_permissions";
    
    /** Process search.
     *
     * My form data is inaccessible if i go across a TLogin redirect.
     * Had to add special handling -- first to notice we're not logged
     * in, and secondly to save off form data in the not-logged in case.
     * 
     * @@param    connection  A connection to a JDBC database
     * @@param    context  The Context partially populated by WMServlet
     * @@return    The template name
     * @@exception    HandlerException
     * @@exception    RedirectException
     */
    protected String processRequest(Context context)
        throws NestableException, RedirectException
    {
        // Check we're logged in.  If not, take evasive 
        // action to save our form fields across the 
        // TLogin redirect
        //
        SessionManager sMgr = getSessionManager( context );
        if( !( sMgr.isLoggedIn( ) ).booleanValue( ) )
        {
            String strPtr = null; // String pointer . Reused.
            
            strPtr = ContextAPI.getParameter(context,  QUERY_KEY );
            if( haveValue( strPtr ) )
            {
                contextPut( context, QUERY_KEY, strPtr );
                if( DEBUG )
                    Log.debug( "NOT LOGGED IN: contextPut " 
                        + QUERY_KEY
                        + ": "
                        + strPtr );
            }
            
            strPtr = ContextAPI.getParameter(context,  RESULTS_PER_PAGE_KEY );
            if( haveValue( strPtr ) )
            {
                contextPut( context, RESULTS_PER_PAGE_KEY, strPtr );
                if( DEBUG )
                    Log.debug( "NOT LOGGED IN: contextPut " 
                        + RESULTS_PER_PAGE_KEY
                        + ": "
                        + strPtr );
            }
        }
        
        String templateName = super.processRequest(context );
            
        try
        {
            String query = ContextAPI.processRequiredField
                (context, QUERY_KEY, "Query string");
                    
            // Log the query so later we can analyze the kind of things users
            // are searching for.  We can use this data to optimize search.
            if (DEBUG) Log.debug( "Search Query: " + query );

            String resultsPerPage = ContextAPI.processRequiredField
                (context, RESULTS_PER_PAGE_KEY, 
                 "Results per Page (Hidden Field)"); 
        
            String action = getAction(context);

            // Work on the search action but also
            // if the action is login.  The latter
            // happens if we're coming back from 
            // a TLogin redirect.
            //
            label_action_test: if( haveValue( action ) 
                                    && action.equals( SEARCH_ACTION ) )
            {
                if(ContextAPI.isValidUserInput(context))
                {
                    String index = myProperties.getProperty( INDEX_PATH );
                        
                    Query objQuery 
                        = new Query( query, 
                            index,
                            Integer.parseInt( resultsPerPage ) );
                
                    SearchSwishe swishe
                        = new SearchSwishe( 
                            myProperties.getProperty( BINARY_PATH ),
                            myProperties.getProperty( DOC_ROOT ),
                            myProperties.getProperty( DOMAIN_KEY ),
                            myProperties.getProperty( HTTP_PORT_KEY ),
                            ContextAPI.getRequest(context).getScheme() );
                        
                    SearchResult searchresult = swishe.search( objQuery );

                    // Read property to see if we should do permission
                    // checking.  For debugging purposes.  
                    //
                    String runPermissionCheck 
                        = myProperties.getProperty( PERMISSION_CHECK_KEY );
                    if (runPermissionCheck.equals(Boolean.FALSE.toString()))
                    {
                        if( DEBUG )
                            Log.debug( "run_permissions property <FALSE>" );
                    }
                    else
                    {
                        AccessControlList acl = getLoginUser(context).getACL();
                        searchresult 
                            = filterOnPermission( searchresult, acl, context );
                    }
                                    
                    if( DEBUG )
                    {
                        Log.debug( "Number Of Hits: " 
                            + Integer.toString( 
                                searchresult.getNumberOfHits( ) ) );
                    }
                                    
                    context.put( SEARCH_RESULT_KEY, searchresult );
                }
            }
        } // label_action_test
        
        catch( Exception e ) 
        {
            Log.error(e);
            throw new NestableException(e);
        }
        
        finally
        {                 
            if( DEBUG )
                Log.debug( "done" );
        }
        
        return templateName;
    }


    /** Servlet info method.
     * @@return String name of this servlet.
     */
    public String getServletInfo( )
    {
        return "Helm Search: $Id: Search.java,v 1.19 2001/08/28 01:36:37 leonardr Exp $";
    }           
    
    /** Filter the search results through permissions.
     *
     * Cycle on the items in inSearchResult.resultItems
     * removing each for which the user does not have permissions.
     * Update the inSearchResults.numberOfHits.
     * Return a new SearchResult object because SearchResult is
     * immutable.
     * <p>
     * Talking w/ Jason Robbins on IRC, he pointed me at the
     * permission i need to check.  Its the permission property
     * on SecureView as specified in 
     * <code>org.tigris.helm.publish.SecureView.properties</code>.
     * This property is duplicated in the property file for this
     * servlet.
     * 
     * @@see <a href="http://projects.collab.net/issues/show_bug.cgi?id=72">IRC Conversation w/ Jason Robbins</a>
     *
     * @@param inSearchResult Search Result set
     * @@param inContext WebMacro Context.
     *
     * @@result SearchResult cut-down according what the user has 
     * permissions to view.
     *
     * @@exception NullPointerException if i can't get key values.
     * @@exception com.workingdogs.village.DataSetException Thrown 
     * by hasPermission
     * @@exception java.sql.SQLException Thrown by hasPermission
     */
    private SearchResult filterOnPermission( SearchResult inSearchResult,
                                             AccessControlList acl, 
                                             Context inContext )
        throws Exception
    {
        if( DEBUG )
            Log.debug( "Before Filter NumOfItems: "
                + Integer.toString( inSearchResult.getNumberOfHits( ) ) );
                
        SearchResultItem resultItem = null;
        List list = inSearchResult.getSearchResultItems( );

        if( list != null )
        {
            for( Iterator iterator = list.iterator( ); iterator.hasNext( ); )
            {
                resultItem = ( SearchResultItem )iterator.next( );
                if( !hasPermission( resultItem, acl, inContext ) )
                    iterator.remove( );
            }
        }
   
        int count = ( list == null )? 0 : list.size( );
        if( DEBUG )
            Log.debug( "After Filter NumOfItems: "
                + Integer.toString( count ) );
                
        return new SearchResult( inSearchResult.getQuery( ),
            list,
            inSearchResult.getIndexName( ),
            count,
            inSearchResult.getIndexModDate( ),
            inSearchResult.getIndexStats( ),
            inSearchResult.getIndexPointer( ),
            inSearchResult.getDescription( ),
            inSearchResult.getSearchengineSearchWords( ) );
    }
    
    
    /** Does the user have permission to view passed in search result item?
     *
     * For each item found, i need to find the project the page is
     * associated with. ASSUMPTION is that name of the project is the 
     * directory immediately following the htdoc root.
     * <p>
     * Talking w/ Jason Robbins on IRC, the 'resource' is:
     * <pre>
     * &ltstack_> What is path_from_project_dir_to_page more explicitly
     * &ltstack_> So all content will be under a project dir?
     * &ltjr> if you find a hit in 
     * /usr/local/tigris/data/helm/htdoc/chess/www/design/head-to-head.html
     * &ltjr> then the projectID is the ID for project chess
     * &ltjr> and the path is www/design/head-to-head.html
     * </pre>
     * <p>
     * Talking more w/ Jason, 11/01/2000, i think this stuff will
     * change.  Keep what will change local to this method.
     *
     * @@param inSearchResultItem The search result item
     * @@param inContext WebMacro Context.
     *
     * @@return True if user has permission to view this item.  Otherwise false
     *
     * @@exception Exception 
     *
     * @@see <a href="http://projects.collab.net/issues/show_bug.cgi?id=72">IRC Conversation w/ Jason Robbins</a>
     */
    private boolean hasPermission( SearchResultItem inSearchResultItem, 
                                   AccessControlList acl,
                                   Context inContext )
        throws NullPointerException, 
                IndexOutOfBoundsException, 
                Exception
    {   
        boolean booleanToReturn = false; // Don't have permission is default

        if( actionString == null ) // Data member
            actionString = myProperties.getProperty( PERMISSION );
        if( actionString == null )
            throw new NullPointerException( "getProperties("
                + PERMISSION
                + ") returned null" );   
        if (DEBUG)
            Log.debug( "ACTIONSTRING: " + actionString );
                
        // relativeURL looks like /PROJECT_NAME/www/some_file, etc.
        // Cut it up into projectName and resource according to 
        // Jason Robbins receipe from IRC quoted at head of this
        // method.
        // 
        String relativeURL = inSearchResultItem.getFileRelativeToHtDoc( );
        if( relativeURL == null )
            throw new NullPointerException( "getFileRelativeToHtDoc( ) returns null" );
        if( relativeURL.startsWith( java.io.File.separator ) )
            relativeURL = relativeURL.substring( 1 ); // Strip leading '/'
        int index = relativeURL.indexOf( java.io.File.separator ); // Find next '/'
        if( index < 0 )
        {
            throw new IndexOutOfBoundsException( "getFileRelativeToHtDoc( )"
                + " does not have expected 'project'/'resource' pattern: "
                + relativeURL );
        }
        String resource 
            = relativeURL.substring( index + 1 /* Pass-out '/' */ );
        String projectName = relativeURL.substring( 0, index );
        Project project = getProject( projectName, inContext );

        if( project != null && resource != null && actionString != null )
        {
            booleanToReturn 
                = acl.hasPermission( actionString, resource, project );
        }

        if( DEBUG )
        {
            Log.debug( "hasPermission '"
                + actionString
                + "' <"
                + ( new Boolean( booleanToReturn ) ).toString( )
                + ">, Resource: " 
                + resource
                + ", projectName: "
                + projectName
                + ", project: " 
                + project );
        }

        return booleanToReturn;
    }
    
    
    /**
     * Return Project given the project name.
     */
    private Project getProject( String inProjectName, 
                                    Context inContext )
        throws Exception
    {
        Domain domain = getCurrentDomain( inContext );
            
        return ProjectPeer.getInstanceByName(domain, inProjectName);
    }       
}
@


1.19
log
@A bit more cleanup.
@
text
@d120 1
a120 1
 * @@version $Id: Search.java,v 1.18 2001/08/11 09:08:08 dlr Exp $
d172 1
a172 1
            strPtr = getParameter(context,  QUERY_KEY );
d183 1
a183 1
            strPtr = getParameter(context,  RESULTS_PER_PAGE_KEY );
d289 1
a289 1
        return "Helm Search: $Id: Search.java,v 1.18 2001/08/11 09:08:08 dlr Exp $";
@


1.18
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@d120 1
a120 1
 * @@version $Id: Search.java,v 1.17 2001/07/24 00:02:28 leonardr Exp $
d235 1
a235 1
                            getRequest(context).getScheme() );
d289 1
a289 1
        return "Helm Search: $Id: Search.java,v 1.17 2001/07/24 00:02:28 leonardr Exp $";
@


1.17
log
@The final pieces of the error handling revolution.
@
text
@d52 1
a52 1
import org.apache.turbine.util.TurbineException;
d120 1
a120 1
 * @@version $Id: Search.java,v 1.16 2001/07/23 20:30:04 dlr Exp $
d161 1
a161 1
        throws TurbineException, RedirectException
d271 1
a271 1
            throw new TurbineException(e);
d289 1
a289 1
        return "Helm Search: $Id: Search.java,v 1.16 2001/07/23 20:30:04 dlr Exp $";
@


1.16
log
@Removed Joist reference.
@
text
@d120 1
a120 1
 * @@version $Id: Search.java,v 1.15 2001/07/19 20:22:44 dlr Exp $
d270 2
a271 5
            Log.error( e );
            String message = e.getMessage( );
            if( DEBUG ) 
                Log.debug( message );
            appendToMessage( context, message );
d289 1
a289 1
        return "Helm Search: $Id: Search.java,v 1.15 2001/07/19 20:22:44 dlr Exp $";
@


1.15
log
@Ported Joist searching classes into Helm.
@
text
@d112 1
a112 1
 *                 <pre>/home/stack/software/jdk1.3/bin/javadoc -d javadoc -classpath /home/stack/cvsroot/sandbox/site/lib/joist.jar:${CLASSPATH}  -sourcepath . org.tigris.helm.search
d120 1
a120 1
 * @@version $Id: Search.java,v 1.14 2001/07/18 10:05:15 dlr Exp $
d292 1
a292 1
        return "Helm Search: $Id: Search.java,v 1.14 2001/07/18 10:05:15 dlr Exp $";
@


1.14
log
@Ported Joist Redirect*Exception to Helm.
@
text
@d55 4
a58 4
import org.joist.search.Query;
import org.joist.search.SearchSwishe;
import org.joist.search.SearchResult;
import org.joist.search.SearchResultItem;
d73 1
a73 1
 * This servlet is based on <code>org.joist.search.SearchServlet</code>.
d112 1
a112 1
 *                 <pre>/home/stack/software/jdk1.3/bin/javadoc -d javadoc -classpath /home/stack/cvsroot/sandbox/site/lib/joist.jar:${CLASSPATH}  -sourcepath . org.joist.search
d120 2
a121 2
 * @@version $Id: Search.java,v 1.13 2001/07/17 20:22:46 leonardr Exp $
 * @@see org.joist.search.SearchServlet
d125 1
a125 1
    implements org.joist.search.SearchServletConstants
d292 1
a292 1
        return "Helm Search: $Id: Search.java,v 1.13 2001/07/17 20:22:46 leonardr Exp $";
@


1.13
log
@Ported servlet to new error-handling mechanism.
@
text
@a52 1
import org.apache.turbine.util.TurbineException;
d55 4
a58 1
import com.workingdogs.village.*;
a62 2
import org.joist.database.*; 
import org.joist.security.*;
a63 4
import org.joist.search.Query;
import org.joist.search.SearchSwishe;
import org.joist.search.SearchResult;
import org.joist.search.SearchResultItem;
d66 1
d120 1
a120 1
 * @@version $Id: Search.java,v 1.12 2001/07/16 21:37:32 dlr Exp $
d292 1
a292 1
        return "Helm Search: $Id: Search.java,v 1.12 2001/07/16 21:37:32 dlr Exp $";
@


1.12
log
@Removed worthless variable which does little but produce extraneous deltas on commit.
@
text
@d70 1
d123 1
a123 1
 * @@version $Id: Search.java,v 1.11 2001/06/25 18:22:19 leonardr Exp $
a198 2
         
        ArrayList missingFields = new ArrayList( );
d202 2
a203 12
            // This class overrides processField
            // looking in 'contextGet' first giving
            // this preference.  See the code above
            // that does a contextPut if we're not
            // logged in. 
            //
            String query
                = processField( context,
                    QUERY_KEY,
                    "",
                    "Query string",
                    missingFields );
d207 1
a207 3
            //
            if (DEBUG)
                Log.debug( "Search Query: " + query );
d209 3
a211 6
            String resultsPerPage 
                = processField( context, 
                    RESULTS_PER_PAGE_KEY,
                    "",
                    "Results per Page (Hidden Field)",
                    missingFields ); 
d213 1
a213 4
            String action = ( String )context.get( ACTION_KEY );
            if( DEBUG ) 
                Log.debug( "Action: " + action );
            
d223 1
a223 8
                if( !missingFields.isEmpty( ) ) 
                {
                    if( DEBUG )
                        Log.debug( "INVALID INPUT: " 
                            + missingFields.toString( ) );
                    reportInvalidUserInput( context, missingFields, null );
                }
                else
d295 2
a296 57
        return "Helm Search: $Id: Search.java,v 1.11 2001/06/25 18:22:19 leonardr Exp $";
    }

    
    
    /**
     * Retrieves HTML form and/or CGI query string data, both adding the data 
     * to the context and returning it.  If the form field contains no data, 
     * the provided <code>description</code> is noted in the 
     * <code>missingFields</code> list (if provided).
     * <p>
     * The name of this method is, unfortunately, ambiguous (because it does 
     * so many things).  It may not be a cohesive, but it sure is useful!
     * <p>
     * This override adds checking of the contextGet and using this 
     * value in preference to what's in the current context.  contextGet, 
     * if non-null, has what was put into context w/ contextPut just 
     * before we crossed a TLogin redirect.
     * 
     * @@param context       The Context to add the param to.
     * @@param key           The name of the form field and context key.
     * @@param defaultValue  The default value to use if there is nothing in 
     *                      the form.
     * @@param description   The description to put into the 
     *                      <code>missingFields</code> list if the the form 
     *                      field has no value (or <code>null</code>).
     * @@param missingFields The list of missing fields (or <code>null</code> 
     *                      if you do not care if the field is missing).
     * @@return The form value retrieved.
     */
    protected String processField (Context context, String key, 
        String defaultValue, String description, 
        List missingFields )
    {
        String strPtr = ( String )contextGet( context, key );
            
        if( haveValue( strPtr ) )
        {
            context.put( key, strPtr );
            if( DEBUG )
                Log.info( "Processing field (contextGet): "
                    + key 
                    + "="
                    + strPtr );
        }
        else
        {
            strPtr = super.processField( context, 
                                            key, 
                                            defaultValue, 
                                            description, 
                                            missingFields );
        }
        
        return strPtr;
    }
    
@


1.11
log
@No longer need to keep a cache, since ProjectPeer keeps a system-wide cache.
@
text
@d122 1
a122 1
 * @@version $Id: Search.java,v 1.10 2001/05/23 01:50:20 dlr Exp $
a128 5
    /** Class version string
     */
    public static final String versionID 
        = "$Id: Search.java,v 1.10 2001/05/23 01:50:20 dlr Exp $";
    
d321 1
a321 1
        return "Helm Search: $Id: Search.java,v 1.10 2001/05/23 01:50:20 dlr Exp $";
@


1.10
log
@Ported Helm from WebMacro to Velocity.
@
text
@d122 1
a122 1
 * @@version $Id: Search.java,v 1.9 2001/03/07 01:53:27 lucas Exp $
d132 1
a132 1
        = "$Id: Search.java,v 1.9 2001/03/07 01:53:27 lucas Exp $";
d153 1
a153 11
    private static final String PERMISSION_CHECK_KEY = "run_permissions"; 
        

    /** List of projects.
     * Keep a cache of projects.  Refresh it every request.
     * Otherwise, everytime we want to do a project name to 
     * project ID conversion, it'll mean a database hit.
     * @@see #getProject
     */
    private List projects = null;
        
a275 3
                    // See head of this method for comment on what the 
                    // refreshCacheOfProjects is about
                    //
a285 1
                        refreshCacheOfProjects( context, acl );
d326 1
a326 1
        return "Helm Search: $Id: Search.java,v 1.9 2001/03/07 01:53:27 lucas Exp $";
d553 1
a553 24
    }
    
    
    /** Refresh projects cache.
     *
     * This method refreshes our projects list cache.  It
     * goes and refetches the list.  The cached list is used
     * by getProject.  W/o this cache, getProject would
     * be going to the database everytime it wanted to do 
     * a converstion of project name to project id.
     *
     * @@param inContext WebMacro Context.
     * @@exception DataSetException
     * @@exception SQLException
     * @@exception JoistDatabaseException
     * @@see #getProject
     */
    private void refreshCacheOfProjects( Context inContext,
                                         AccessControlList acl)
        throws Exception
    {   
        projects 
            = getCurrentDomain( inContext ).getProjectsForContentViewing(acl);
    }
@


1.9
log
@Corrected regex madness for Torque upgrade.  -dlr
@
text
@d52 3
a54 1
import org.webmacro.servlet.*;
d63 1
a63 1
import org.joist.session.*;
d122 1
a122 1
 * @@version $Id: Search.java,v 1.8 2001/02/23 19:08:04 stack Exp $
d132 1
a132 1
        = "$Id: Search.java,v 1.8 2001/02/23 19:08:04 stack Exp $";
d172 1
a172 1
     * @@param    context  The WebContext partially populated by WMServlet
d177 2
a178 2
    protected String processRequest( Connection connection, WebContext context )
        throws HandlerException, RedirectException
d189 1
a189 1
            strPtr = context.getForm( QUERY_KEY );
d200 1
a200 1
            strPtr = context.getForm( RESULTS_PER_PAGE_KEY );
d212 1
a212 1
        String templateName = super.processRequest( connection, context );
d279 1
a279 1
                            context.getRequest( ).getScheme( ) );
d291 1
a291 1
                    if( runPermissionCheck.equals( Boolean.FALSE.toString( ) ) )
d340 1
a340 1
        return "Helm Search: $Id: Search.java,v 1.8 2001/02/23 19:08:04 stack Exp $";
d359 1
a359 1
     * @@param context       The WebContext to add the param to.
d370 1
a370 1
    protected String processField (WebContext context, String key, 
d428 1
a428 1
                                             WebContext inContext )
d495 1
a495 1
                                   WebContext inContext )
d561 1
a561 1
                                    WebContext inContext )
d584 1
a584 1
    private void refreshCacheOfProjects( WebContext inContext,
@


1.8
log
@Remove a javadoc 'see' that points to nonexistent method
@
text
@d58 1
a58 2
import org.tigris.helm.om.peer.ProjectPeer;

d120 1
a120 1
 * @@version $Id: Search.java,v 1.7 2001/02/21 05:36:24 edk Exp $
d130 1
a130 1
        = "$Id: Search.java,v 1.7 2001/02/21 05:36:24 edk Exp $";
d338 1
a338 1
        return "Helm Search: $Id: Search.java,v 1.7 2001/02/21 05:36:24 edk Exp $";
@


1.7
log
@fix imports, exceptions, and use turbine logging
@
text
@d121 1
a121 1
 * @@version $Id: Search.java,v 1.6 2001/02/21 05:06:13 edk Exp $
d131 1
a131 1
        = "$Id: Search.java,v 1.6 2001/02/21 05:06:13 edk Exp $";
a158 1
     * @@see #refreshProjectsCache
d339 1
a339 1
        return "Helm Search: $Id: Search.java,v 1.6 2001/02/21 05:06:13 edk Exp $";
@


1.6
log
@fix import and throws
@
text
@d121 1
a121 1
 * @@version $Id: Search.java,v 1.5 2001/02/21 04:06:32 edk Exp $
d131 1
a131 1
        = "$Id: Search.java,v 1.5 2001/02/21 04:06:32 edk Exp $";
d340 1
a340 1
        return "Helm Search: $Id: Search.java,v 1.5 2001/02/21 04:06:32 edk Exp $";
d429 1
a429 3
        throws NullPointerException,
                com.workingdogs.village.DataSetException,
                java.sql.SQLException
a434 2
        if( inSearchResult == null )
            throw new NullPointerException( "inSearchResult null" );
d489 1
a489 4
     * @@exception NullPointerException if i can't get key values.
     * @@exception IndexOutOfBoundsException If we cannot make sense of the path 
     * @@exception com.workingdogs.village.DataSetException Call to getACL( )
     * @@exception java.sql.SQLException Call to getACL( )
d498 1
a498 2
                com.workingdogs.village.DataSetException,
                java.sql.SQLException
d557 2
a558 14
    /** Return Project given the project name.
     *
     * @@param inProjectName Name of project we want the project ID for.
     * @@param inContext WebMacro Context.
     *
     * @@return Project which may be null
     *
     * @@exception NullPointerException If we do not find a project
     * w/ the passed in project name.
     * @@exception com.workingdogs.village.DataSetException. 
     * Thrown by projects.getName( )
     * @@exception java.sql.SQLException Thrown by projects.getName( )
     *
     * @@see #refreshCacheOfProjects
d562 1
a562 3
        throws NullPointerException, 
                com.workingdogs.village.DataSetException,
                java.sql.SQLException
@


1.5
log
@nuke tabs; use turbine logging; use the peer port of the business objects;
change getProjectID to getProject 'cause we never want the ProjectID
@
text
@d51 1
a51 1
import org.webmacro.util.Log;
d57 1
d121 1
a121 1
 * @@version $Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $
d131 1
a131 1
        = "$Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $";
d298 1
a298 1
                        AccessControlList acl = getACL(context, connection);
d340 1
a340 1
        return "Helm Search: $Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $";
d580 1
a580 1
    private String getProject( String inProjectName, 
d608 1
a608 4
        throws DataSetException, 
               SQLException, 
               JoistDatabaseException, 
               DoesNotExist
@


1.4
log
@readding all the files as part of the process of returning to the way
things were as of tuesday
@
text
@d56 3
d120 1
a120 1
 * @@version $Id: Search.java,v 1.2 2000/11/27 23:36:10 stack Exp $
d130 1
a130 2
        = "$Id: Search.java,v 1.2 2000/11/27 23:36:10 stack Exp $";
    
a131 5
    /** Logging object.
     */
    private Log log = new Log( "search", "ACL Search" );
        
        
d134 1
a134 1
    private static final boolean debug = true;   
d152 1
a152 1
		
d159 1
a159 1
     * @@see #getProjectID
d165 10
a174 10
	 *
	 * My form data is inaccessible if i go across a TLogin redirect.
	 * Had to add special handling -- first to notice we're not logged
	 * in, and secondly to save off form data in the not-logged in case.
	 * 
     * @@param	connection  A connection to a JDBC database
     * @@param	context  The WebContext partially populated by WMServlet
     * @@return	The template name
     * @@exception	HandlerException
     * @@exception	RedirectException
d176 2
a177 2
	protected String processRequest( Connection connection, WebContext context )
	    throws HandlerException, RedirectException
d179 4
a182 6
        log.setLevel( log.DEBUG );

		// Check we're logged in.  If not, take evasive 
		// action to save our form fields across the 
		// TLogin redirect
		//
d186 23
a208 23
			String strPtr = null; // String pointer . Reused.
			
			strPtr = context.getForm( QUERY_KEY );
			if( haveValue( strPtr ) )
			{
            	contextPut( context, QUERY_KEY, strPtr );
            	if( debug )
                	log.debug( "NOT LOGGED IN: contextPut " 
						+ QUERY_KEY
						+ ": "
						+ strPtr );
			}
			
			strPtr = context.getForm( RESULTS_PER_PAGE_KEY );
			if( haveValue( strPtr ) )
			{
            	contextPut( context, RESULTS_PER_PAGE_KEY, strPtr );
            	if( debug )
                	log.debug( "NOT LOGGED IN: contextPut " 
						+ RESULTS_PER_PAGE_KEY
						+ ": "
						+ strPtr );
			}
d210 1
a210 1
		
d217 12
a228 12
			// This class overrides processField
			// looking in 'contextGet' first giving
			// this preference.  See the code above
			// that does a contextPut if we're not
			// logged in. 
			//
			String query
				= processField( context,
					QUERY_KEY,
					"",
					"Query string",
					missingFields );
d233 2
a234 1
            log.info( "Search Query: " + query );
d237 1
a237 1
				= processField( context, 
d244 2
a245 2
            if( debug ) 
                log.debug( "Action: " + action );
d248 5
a252 5
			// Work on the search action but also
			// if the action is login.  The latter
			// happens if we're coming back from 
			// a TLogin redirect.
			//
d258 2
a259 2
                    if( debug )
                        log.debug( "INVALID INPUT: " 
d292 2
a293 2
                        if( debug )
                            log.debug( "run_permissions property <FALSE>" );
d303 1
a303 1
                    if( debug )
d305 1
a305 1
                        log.debug( "Number Of Hits: " 
d317 1
a317 1
            log.exception( e );
d319 2
a320 2
            if( debug ) 
                log.debug( message );
d326 2
a327 2
            if( debug )
                log.debug( "done" );
d339 1
a339 1
        return "Helm Search: $Id: Search.java,v 1.2 2000/11/27 23:36:10 stack Exp $";
d342 2
a343 2
	
	
d353 5
a357 5
	 * This override adds checking of the contextGet and using this 
	 * value in preference to what's in the current context.  contextGet, 
	 * if non-null, has what was put into context w/ contextPut just 
	 * before we crossed a TLogin redirect.
	 * 
d372 5
a376 5
	{
		String strPtr = ( String )contextGet( context, key );
			
		if( haveValue( strPtr ) )
		{
d378 2
a379 2
            if( debug )
                log.info( "Processing field (contextGet): "
d383 12
a394 12
		}
		else
		{
			strPtr = super.processField( context, 
											key, 
											defaultValue, 
											description, 
											missingFields );
		}
		
		return strPtr;
	}
d398 27
a424 27
    *
    * Cycle on the items in inSearchResult.resultItems
    * removing each for which the user does not have permissions.
    * Update the inSearchResults.numberOfHits.
    * Return a new SearchResult object because SearchResult is
    * immutable.
    * <p>
    * Talking w/ Jason Robbins on IRC, he pointed me at the
    * permission i need to check.  Its the permission property
    * on SecureView as specified in 
    * <code>org.tigris.helm.publish.SecureView.properties</code>.
    * This property is duplicated in the property file for this
    * servlet.
    * 
    * @@see <a href="http://projects.collab.net/issues/show_bug.cgi?id=72">IRC Conversation w/ Jason Robbins</a>
    *
    * @@param inSearchResult Search Result set
    * @@param inContext WebMacro Context.
    *
    * @@result SearchResult cut-down according what the user has 
    * permissions to view.
    *
    * @@exception NullPointerException if i can't get key values.
    * @@exception com.workingdogs.village.DataSetException Thrown 
    * by hasPermission
    * @@exception java.sql.SQLException Thrown by hasPermission
    */
d432 2
a433 2
        if( debug )
            log.debug( "Before Filter NumOfItems: "
d452 2
a453 2
        if( debug )
            log.debug( "After Filter NumOfItems: "
d469 30
a498 30
    *
    * For each item found, i need to find the project the page is
    * associated with. ASSUMPTION is that name of the project is the 
    * directory immediately following the htdoc root.
    * <p>
    * Talking w/ Jason Robbins on IRC, the 'resource' is:
    * <pre>
    * &ltstack_> What is path_from_project_dir_to_page more explicitly
    * &ltstack_> So all content will be under a project dir?
    * &ltjr> if you find a hit in 
    * /usr/local/tigris/data/helm/htdoc/chess/www/design/head-to-head.html
    * &ltjr> then the projectID is the ID for project chess
    * &ltjr> and the path is www/design/head-to-head.html
    * </pre>
    * <p>
    * Talking more w/ Jason, 11/01/2000, i think this stuff will
    * change.  Keep what will change local to this method.
    *
    * @@param inSearchResultItem The search result item
    * @@param inContext WebMacro Context.
    *
    * @@return True if user has permission to view this item.  Otherwise false
    *
    * @@exception NullPointerException if i can't get key values.
    * @@exception IndexOutOfBoundsException If we cannot make sense of the path 
    * @@exception com.workingdogs.village.DataSetException Call to getACL( )
    * @@exception java.sql.SQLException Call to getACL( )
    *
    * @@see <a href="http://projects.collab.net/issues/show_bug.cgi?id=72">IRC Conversation w/ Jason Robbins</a>
    */
d515 2
a516 1
        log.info( "ACTIONSTRING: " + actionString );
d538 1
a538 1
        String projectID = getProjectID( projectName, inContext );
d540 1
a540 1
        if( projectID != null && resource != null && actionString != null )
d543 1
a543 3
                = acl.hasPermissionForProject( actionString, 
                    resource,
                    projectID );
d546 1
a546 1
        if( debug )
d548 1
a548 1
            log.debug( "hasPermission '"
d556 2
a557 2
                + ", projectID: " 
                + projectID );
d564 16
a579 19
    /** Return projectID given the project name.
    *
    * @@param inProjectName Name of project we want the project ID for.
    * @@param inContext WebMacro Context.
    *
    * @@return Project ID as a string. The projectID we return 
    * may be null.  An example of this would be a project that
    * is under htdocs but not in the database.  Projects such
    * as 'look', and 'www' would fit this category.
    *
    * @@exception NullPointerException If we do not find a project
    * w/ the passed in project name.
    * @@exception com.workingdogs.village.DataSetException. 
    * Thrown by projects.getName( )
    * @@exception java.sql.SQLException Thrown by projects.getName( )
    *
    * @@see #refreshCacheOfProjects
    */
    private String getProjectID( String inProjectName, 
d585 1
a585 2
        String projectID = null;
        String domainName = getCurrentDomain( inContext ).getName( );
d587 1
a587 16
        log.info( "DOMAINNAME: " + domainName );
        log.info( "IN_PROJECTNAME: " + inProjectName );
        org.tigris.helm.project.Project project = null;
            
        for( Iterator iterator = projects.iterator( ); iterator.hasNext( ); )
        {
            project = ( org.tigris.helm.project.Project )iterator.next( );
            log.info( "PROJECTNAME: " + project.getName( ) );
            if( project.getName( ).equals( inProjectName ) )
            {
                projectID = project.getID( );
                break;
            }
        }
        
        return projectID;
d592 13
a604 13
    *
    * This method refreshes our projects list cache.  It
    * goes and refetches the list.  The cached list is used
    * by getProjectID.  W/o this cache, getProjectID would
    * be going to the database everytime it wanted to do 
    * a converstion of project name to project id.
    *
    * @@param inContext WebMacro Context.
    * @@exception DataSetException
    * @@exception SQLException
    * @@exception JoistDatabaseException
    * @@see #getProjectID
    */
@


1.4.2.1
log
@Porting to the Turbine Peer system.  -dlr and leonardr
@
text
@d117 1
a117 1
 * @@version $Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $
d127 1
a127 1
        = "$Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $";
d343 1
a343 1
        return "Helm Search: $Id: Search.java,v 1.4 2001/01/26 18:29:08 edk Exp $";
@


1.3
log
@revert this stuff to its state as of 2001/01/24 12:42:00 GMT -- with
the following exceptions, which have some different modifications so
they'll work with changes which have happened in joist:

ProjectNewsEdit.java
SkinManager.java
SkinStyleElementValueManager.java
StyleElementManager.java
StyleManager.java

it compiles.  i dunno if it works, though.
@
text
@@


1.2
log
@Changed my projects list caching method to use new method added by leonardr to org.tigris.helm.domain.Domain.  New method does Project Content - View permission
@
text
@d117 1
a117 1
 * @@version $Id: Search.java,v 1.1.1.1 2000/11/12 21:16:30 dlr Exp $
d127 1
a127 1
        = "$Id: Search.java,v 1.1.1.1 2000/11/12 21:16:30 dlr Exp $";
d343 1
a343 1
        return "Helm Search: $Id: Search.java,v 1.1.1.1 2000/11/12 21:16:30 dlr Exp $";
@


1.1
log
@Initial revision
@
text
@d117 1
a117 1
 * @@version $Id: Search.java,v 1.8 2000/11/11 03:33:33 dlr Exp $
d127 1
a127 1
        = "$Id: Search.java,v 1.8 2000/11/11 03:33:33 dlr Exp $";
d343 1
a343 1
        return "Helm Search: $Id: Search.java,v 1.8 2000/11/11 03:33:33 dlr Exp $";
d519 1
d596 2
d603 1
d636 2
a637 1
        projects = getCurrentDomain( inContext ).getProjects(acl);
@


1.1.1.1
log
@Merging newhelm tree into helm, as per IZ issue #557.  Previous major version of helm is tagged TIGRIS_NOV_11_2000.
@
text
@@
