 package org.bodington.servlet.facilities;

 import java.awt.Color;
 import org.bodington.servlet.*;
 import org.bodington.database.PrimaryKey;
 import org.bodington.server.events.UserFileEvent;
 import org.bodington.server.realm.Permission;
 import org.bodington.server.resources.*;
 import org.bodington.server.*;
 import org.bodington.xml.XMLRepository;
 import org.bodington.xml.XMLQuery;
 import org.bodington.xml.XMLObjectRecord;
 import org.bodington.servlet.template.Template;
 import org.bodington.util.ColourPreferenceMapper;

 import java.util.logging.*;
 import java.util.Vector;
 import java.util.StringTokenizer;
 import java.util.Enumeration;
 import java.io.*;
 import java.sql.*;
// import java.rmi.*;
 import java.math.BigInteger;
 import javax.servlet.*;



 public class EasyBuilderFacility extends SuiteFacility
 {

   public void insert( Request req, PrintWriter out, String command, String insertname )
       throws ServletException, IOException
   {
     Logger.getLogger( "org.bodington" ).fine( " EasyBuilderFacility insert()" );

     if ( command.equalsIgnoreCase( "javascript_lib" ) )
     {
       // Creates path to a Javascript library file.
       // Uses 'insertname' param to find bodington.property.
       // Appends value of bodington.property (i.e. lib name) to end of path.

       String path, property;

       path = req.getContextPath();
       if ( !path.endsWith( "/" ) )
         path +=	"/";

       BuildingContext context = BuildingContext.getContext();
       property = context.getProperty( insertname );
       if ( property == null || property.equals("") )
       {
         out.println( "<!-- javascript library name not found in bodington.properties file. -->" );
         return;
       }

       path += property;

       out.println( path );
       return;
     }

     /** @todo Move JavaScript to templates... */
     // httpsess variable is used by the methods following:
     HttpSession httpsess = (org.bodington.servlet.HttpSession)req.getSession( false );

     if ( command.equalsIgnoreCase( "createcontainer" ) )
     {
       /** @todo make more robust? :
        * url != null is only check that container hasn't already been created */
       if ( req.getParameter("url") != null && out!=null) {
         Resource new_resource;
         String container_name, creator;
         new_resource = createconfirm( req, out, insertname );
         if ( new_resource == null )
         {
           out.println("Creation of containing resource failed");
           return;
         }

         // createconfirm() might have altered new resource's name, so get/set it here:
         container_name = new_resource.getName();
         httpsess.setAttribute( "org.bodington.servlet.container_name", container_name );

         try {
           BuildingSessionImpl session = (BuildingSessionImpl)req.getServerNavigationSession().getSession();
           PrimaryKey key = new_resource.getResourceId();

           if (req.getParameter( "creator" ) != null)
           {
             creator = req.getParameter( "creator" );
             session.addMetadataField( key, "author", creator );
           }
           if (req.getParameter( "keywords" ) != null)
           {/** @todo create separate fields for each keyword */
             String keywords = req.getParameter( "keywords" );
             session.addMetadataField( key, "keyword", keywords );
           }
         }
         catch (BuildingServerException ex) {
           out.println("Error adding metadata for resource:" + ex.friendlyMessage());
         }

         out.println("<SCRIPT LANGUAGE=JavaScript>");
         out.println("top.buildmain.graphic.location.href=\""+container_name+"/bs_template_minimenu.html\";");
         out.println("</SCRIPT>");
       }

       return;
     }

     if ( command.equalsIgnoreCase( "containername" ) )
     {
       /**
        * Used to add container name to urls, in order to enable creating resources
        *  in a different location to the current location.
        */

       String container_name;
       Resource current = req.getResource();

       if ( httpsess.getAttribute( "org.bodington.servlet.container_name" ) != null )
       {
         container_name = (String)httpsess.getAttribute( "org.bodington.servlet.container_name" );

         if ( !container_name.equals( current.getName() ))
         {
           out.print( container_name );
           return;
         }
       }

       out.print( "." );
       return;
     }

     if ( command.equalsIgnoreCase( "createincontainer" ) )
     {
       if ( out!=null )
       {
         String container_name;
         Resource new_resource;

         if ( httpsess.getAttribute( "org.bodington.servlet.container_name" ) != null )
           container_name = (String)httpsess.getAttribute( "org.bodington.servlet.container_name" );
         else
           container_name = req.getResource().getName();

         new_resource = createconfirm( req, out, insertname );

         if ( new_resource == null )
         {
           out.println("Creation of resource within container has failed");
           return;
         }

         out.println("<SCRIPT LANGUAGE=JavaScript>");
         out.println("top.buildmain.graphic.location.href=\""+container_name+"/bs_template_minimenu.html\";");
         out.println("</SCRIPT>");
       }
       return;
     }

     if (  command.equalsIgnoreCase( "uploadwithlink" ) )
     {/** @todo if method returns after error occurs, need to output JavaScript to update minimenu */
       if ( out!=null )
       {
         String file_name, link;
         Resource new_resource, current;
         boolean completed;

         file_name = req.getParameterFileName("file");
         /** @todo Seems to be a bug in Bod code to check that the file exists?
          * (possible to upload a non-existent file... */
         if ( file_name == null || file_name.equals( "" ))
         {
           out.println( "No file name supplied" );
           return;
         }

         new_resource = createconfirm( req, out, insertname );
         if ( new_resource == null )
         {
           out.println("Creation of the link to the uploaded file has failed.<br />");
           out.println("File has not been uploaded.");
           return;
         }

         completed = upload( req, new_resource, out );

         if ( !completed )
         {
           /** @todo rollback resource creation if upload fails... */
//           out.println( "File upload failed, please use the 'Manage' interface to correct this." );
//           return;
           file_name = "bs_template_manage.html";
         }

         link = "./" + new_resource.getName() + "/" + file_name;

         if ( new_resource instanceof QuickLink)
         {
           try {
             ((QuickLink) new_resource).setNewWindow(true);
             ((QuickLink) new_resource).setLink(link);
             ((QuickLink) new_resource).save();
           }
           catch (BuildingServerException ex) {
             out.println("The URL for the link could not be set, please do this using the 'Manage' interface.");
           }
         }
         else
           out.println("The URL for the link could not be set, please do this using the 'Manage' interface.");

         current = req.getResource();

         out.println("<SCRIPT LANGUAGE=JavaScript>");
         out.println("top.buildmain.graphic.location.href=\""+current.getName()+"/bs_template_minimenu.html\";");
         out.println("</SCRIPT>");
       }

       return;
     }


     if ( command.equalsIgnoreCase( "contentlist" ) )
     {
       if ( out!=null )
         contentlist( req, out, insertname );

       return;
     }

     if ( command.equalsIgnoreCase( "metadatasearch" ) )
     {
       if ( out!=null )
         metadatasearch( req, out );
       return;
     }

     super.insert( req, out, command, insertname );
   }


/**
 * Cut down version of navigation() method in Facility.
 * comment from Facilty class:
 * "this method is only called from legacy templates and we
 * have to assume that the html page class has been given
 * us in an attribuate to the BUILDING tag but we expect
 * the default to be a navigation page."
 */

   public void contentlist( Request breq, PrintWriter out, String name )
       throws IOException
   {
     String smliconurl, parentsmliconurl;
     boolean tree;
     int n;
     BuildingContext context;
     FacilityList fl;
     Facility facility;
     Template template;
     String colour_mapper_code="";
     Resource resource, current, next;
     String html_body_class, tree_attribute;

     context = BuildingContext.getContext();
     fl = FacilityList.getFacilities();

     org.bodington.servlet.HttpSession http_session = (org.bodington.servlet.HttpSession)breq.getSession( false );
     NavigationSession nav_session = breq.getServerNavigationSession();

     html_body_class = breq.getInsertAttribute( "html_body_class", "bodington_navigation_page" );

     try {
       StyleSheetSessionData sssd = getStyleSheetSessionData( http_session );
       ColourPreferenceMapper colour_mapper = sssd.getUserColourPreferenceMapper( http_session );

       BuildingSession session = nav_session.getSession();
       Color f;
       Color b;
       if ("bodington_navigation_page".equals(html_body_class)) {
         f = session.getPropertyColor(
            "style_navigation_graphic_foreground_colour", new Color(0xeeeeee));
         b = session.getPropertyColor(
            "style_navigation_graphic_background_colour", new Color(0x111111));
       }
       else {
         f = session.getPropertyColor("style_graphic_foreground_colour",
                                      new Color(0xeeeeee));
         b = session.getPropertyColor("style_graphic_background_colour",
                                      new Color(0x111111));
       }
       colour_mapper.setReferenceColours(b, f);
       colour_mapper_code = "?code=" + colour_mapper.toString();
     }
     catch (BuildingServerException bsex) {
       logException(out, "Facility", "navigation",
                    "A technical problem occurred.",
                    bsex);

       colour_mapper_code = "";
     }

     tree_attribute = (String)breq.getInsertAttribute( "tree", null );
     tree =  tree_attribute == null ||
         tree_attribute.equalsIgnoreCase( "yes" ) ||
         tree_attribute.equalsIgnoreCase( "true" );

     try
     {
       resource = context.getResource();

       if ( name.equalsIgnoreCase( "links" ) )
       {
         parentsmliconurl = "bs_template_iconsmall.gif";
         template = Template.get( this.facilityname, resource.getImplicitHttpUIStyle(), null, "iconsmall.gif" );
         if ( template != null )
                    parentsmliconurl = breq.getContextPath() + "/processedgif/templates" + template.getUrl() + colour_mapper_code;

         Enumeration enum=resource.findChildren();
         n=0;
         current=null;
         while ( enum.hasMoreElements() )
         {
           current = (Resource)enum.nextElement();
           if ( current.checkPermission( Permission.SEE ) )
             break;
           current=null;
         }

         while( current!=null )
         {
           next=null;
           while ( enum.hasMoreElements() )
           {
             next = (Resource)enum.nextElement();
             if ( next.checkPermission( Permission.SEE ) )
               break;
             next=null;
           }

           // find url of small icon for current resource
           smliconurl = current.getName() + "/bs_template_navigation_iconsmall.gif";
           facility = fl.get( new Integer( current.getHttpFacilityNo() ) );
           if ( facility!=null )
           {
             template = Template.get( facility.facilityname, current.getImplicitHttpUIStyle(), null, "iconsmall.gif" );
             if ( template != null )
                            smliconurl = breq.getContextPath() + "/processedgif/templates" + template.getUrl() + colour_mapper_code;
           }

           if ( n==0 )
           {
             // if we have found a resource to list start off the table
             out.print( "<TABLE border=0 cellpadding=0 cellspacing=0>" );
             if ( tree )
             {
               // first display
               // icon for containing resource
               out.print( "<TR><TD VALIGN=TOP COLSPAN=2>" );
               out.print( "<IMG alt=\"" + resource.getResourceTypeName() + ".\" BORDER=0 SRC=\"" );
               out.print( parentsmliconurl );
               out.print( "\">" );
               //out.print( "</TD><TD>" );
               out.println( "</TD></TR>" );
               out.println( "<TR><TD VALIGN=TOP BACKGROUND=" + breq.getContextPath() + "/icons/thread-line.gif>" );
               out.print( "<IMG BORDER=0 SRC=\"" + breq.getContextPath() + "/icons/thread-filler.gif\">" );
               out.println( "</TD><TD></TD></TR>" );
             }
           }
           n++;

           out.println( "<TR>" );

           if ( tree )
           {
             if ( next==null )
               out.println( "<TD VALIGN=TOP>" );
             else
               out.println( "<TD VALIGN=TOP BACKGROUND=" + breq.getContextPath() + "/icons/thread-line.gif>" );
             out.println("<IMG SRC=" + breq.getContextPath() + "/icons/resource-arrow.gif>");
             out.println( "</TD>" );
           }

           out.print( "<TD VALIGN=TOP>" );
           out.print( "<IMG alt=\"Icon for a " + current.getResourceType() + ".\" CLASS=bs-links-icon BORDER=0 SRC=\"" );
           out.print( smliconurl );
           out.print( "\">" );
           out.println( "</TD>" );

           out.print( "<TD VALIGN=TOP>" );
           out.print( "<SPAN CLASS=bs-links-title>" );
           out.print( current.getTitle() );
             //out.println( "</NOBR>" );
           out.println( "</SPAN>" );
           out.println( "</TD>" );

           out.println( "</TR>" );

           current = next;
         }
         if ( n>0 )
           out.println( "</TABLE>" );
         return;
       }
     }

     catch ( BuildingServerException bsex )
     {
       return;
     }

     out.print( "<! navigation HTML inserted here>" );
   }


   /** @todo method copied from Facility, with modifications, and returns a Resource... */
   private Resource createconfirm(Request breq, PrintWriter out, String name)
       throws IOException
   {
     FacilityList fl;
     Facility f;
     Connection con = null;
     ResourceTree tree = null;
     Resource new_resource = null;
     boolean completed = false;
     BuildingContext context = BuildingContext.getContext();

     if (!BuildingContext.getContext().checkPermission("create")) {
       out.println( "<PRE>You don't have permission to create resources here.</PRE>\n");
       return null;
     }

     if (!breq.isAuthenticated()) {
       out.println("<HR>Problem finding user.<HR>");
       return null;
     }

     fl = FacilityList.getFacilities();
     if (fl == null) {
       out.println("<HR>Problem finding facilities.<HR>");
       return null;
     }
     f = fl.get(name);

     if (f == null) {
       out.println("<HR>Unable to create this type of resource.<HR>");
       return null;
     }

     try {
       String url, str;
       String title = "", description = "", introduction = "";
       boolean parentacl;

       url = breq.getParameter("url");
       if (url.length() < 1) {
         out.println( "<HR>Unable to create new location - you must supply a name.<HR>");
         out.println( "Please use the backtrack facility of your browser to return to the form.");
         return null;
       }
       if (url.length() > 12) {
         out.println( "<HR>Unable to create new location - name is more than 12 characters.<HR>");
         out.println( "Please use the backtrack facility of your browser to return to the form.");
         return null;
       }
       for (int i = 0; i < url.length(); i++) {
         char c = url.charAt(i);
         if (c >= '0' && c <= '9')
           continue;
         if (c >= 'a' && c <= 'z')
           continue;
         if (c != '_') {
           out.println( "<HR>Unable to create new location - the name contains invalid characters.<HR>");
           out.println( "Please use the backtrack facility of your browser to return to the form.");
           return null;
         }
       }

       if ( breq.getParameter("title") != null ) {
         title = breq.getParameter("title").trim();
         if ( title.length() == 0 && breq.getParameter("defaulttitle") != null )
           title = breq.getParameter("defaulttitle").trim(); // use default value if available.
       }
       if ( breq.getParameter("description") != null ) {
         description = breq.getParameter("description").trim();
         if ( description.length() == 0 && breq.getParameter("defaultdescription") != null )
           description = breq.getParameter("defaultdescription").trim(); // use default value if available.
       }
       if ( breq.getParameter("introduction") != null ) {
         introduction = breq.getParameter("introduction").trim();
         if ( introduction.length() == 0 && breq.getParameter("defaultintroduction") != null )
           introduction = breq.getParameter("defaultintroduction").trim(); // use default value if available.
       }


       if (title.length() == 0 || description.length() == 0 || introduction.length() == 0) {
         out.println("<HR>Unable to create new location - one or more of the boxes was left blank.<HR>");
         out.println( "Please use the backtrack facility of your browser to return to the form.");
         return null;
       }

       str = breq.getParameter("parentacl");
       parentacl = str != null && str.equalsIgnoreCase("yes");

       if (!f.createCheck(breq, out)) {
         out.println(
             "<BR>Please use the backtrack facility of your browser to return to the form.");
         return null;
       }

       Enumeration enum = breq.getResource().findChildren();
       Resource child;

       Vector names = new Vector();
       String append = "";
       int start = 2;

       while (enum.hasMoreElements())
         names.add( ( (Resource) enum.nextElement()).getName());

         /** @todo limit max number for 'start'? */
       while (names.contains(url + append)) {
         append = Integer.toString(start++);
         if ( (url + append).length() > 12)
           url = url.substring(0, 12 - append.length());
       }

       url = url + append;

       //do general location creation stuff

       tree = ResourceTree.getInstance();

       synchronized (tree) {
         new_resource = f.newResource();
         new_resource.setName(url);
         new_resource.setTitle(title);
         new_resource.setDescription(description);
         new_resource.setIntroduction(introduction);
         new_resource.setHttpFacilityNo(f.id.intValue());
         new_resource.setUseParentAcl(parentacl);

         if (!f.initResource(breq, new_resource)) {
           out.println("<HR>Unable to initialise new resource.<HR>");
           out.println("<BR>Please use the backtrack facility of your browser to return to the form and try again.");
           return null;
         }

         con = context.getConnection();
         //may need to rollback after several
         //operations
         con.setAutoCommit(false);
         tree.addResource(breq.getResource(), new_resource);
         //tree.updateIndices();
         //tree.saveAll();

         //specific creation stuff
         if (!f.create(breq, con, new_resource)) {
           out.println(
               "<HR>Unable to create supporting data for new resource.<HR>");
           throw new BuildingServerException(
               "Problem creating resource specific data in database.");
         }

         con.commit();
         completed = true;
         out.println("<CENTER><B>New resource created O.K.</B></CENTER><HR>");
         con.setAutoCommit(true);
       }

       // mustn't attempt to get a session inside the synchronized section because
       // this could cause deadlock.

       // create metadata record
       try {
         BuildingSession session = BuildingSessionManagerImpl.getSession(
             new_resource);
         session.updateBasicMetadata(title, description);
       }
       catch (BuildingServerException bsex) {
         logException(out, "Facility", "createConfirm",
             "Unable to save the associated metadata for the newly created item.",
             bsex);
       }
     }
     catch (Exception ex) {
       out.println("<HR>Unable to create resource.<HR>" + ex);
       logException(out, "Facility", "createConfirm",
                    "Unable to create resource.", ex);
       //just drop through;
     }

     if (!completed) {
       try {
         if (tree != null && new_resource != null) {
           tree.removeResource(new_resource);
           //tree.updateIndices();
           //tree.saveAll();
         }
       }
       catch (Exception ex) {
         out.println(
             "<HR>A problem occurred cleaning up after the failure to create the resource.  " +
             "A 'phantom' resource may appear in the list of resources.<HR>" +
             ex);
         //just drop through;
       }

       try {
         if (con != null)
           con.rollback();
       }
       catch (SQLException sqlex) {
         out.println("<HR>Unable to roll back database operations.<HR>" + sqlex);
         //just drop through;
       }
       return null;
     }
     return new_resource;
   }

   private boolean upload( Request req, Resource parent, PrintWriter out )
       throws ServletException, IOException
   {
     StringBuffer dest_filename=new StringBuffer();
     String file_name, file, mime_type;
     BuildingSession session;
     UploadedFileSummary summary;

     file_name = req.getParameterFileName("file");
     file = req.getParameter( "file" );

     if ( file_name == null || file_name.length() == 0 )
     {
       out.println( "Upload failed because no file name was supplied in the form." );
       return false;
     }

     dest_filename.append( fileParameter( req ) );
     if ( dest_filename.length()>0 )
       dest_filename.append( "/" );

     try
     {
       session = BuildingSessionManagerImpl.getSession( parent );

       if ( session==null )
//         throw new BuildingServerException( "Unable to access the destination resource." );
         return false;

//       if ( file!=null && file_name!=null ) this is checked in calling method

       if ( file_name.indexOf( '/' )>=0 || file_name.indexOf( '\\' )>=0 )
       {
         out.println( "File names may not contain any slash or backslash characters." );
         return false;
       }

       dest_filename.append( file_name );

       mime_type=req.getServletConfig().getServletContext().getMimeType( file_name.toLowerCase() );

       if ( mime_type==null )
         mime_type="application/octet-stream";

       summary = session.transferFile( file, dest_filename.toString(), mime_type );

       out.println( "<CENTER><B>File upload succeeded.</B></CENTER><HR>" );
     }
     catch ( Exception ex )
     {
       logException( out, this.getClass().getName(), "upload",
                     "A technical problem occurred.", ex );
       return false;
     }

     try
     {
       UserFileEvent event = new UserFileEvent(
          UserFileEvent.EVENT_UPLOAD,
          req.getResource().getResourceId(),
          summary.getCreateUserId(),
          null,
          new Integer( summary.getUploadedFileId().intValue() ),
          new BigInteger( Long.toString( summary.getSize() ) ),
          file_name );

       event.save();

     /** @todo Leaving this here means that if the UserFileEvent code fails, this won't be executed.
      * If invalidateResourceMenu() fails, it's not serious enough to return false in the catch statement above... */

       session.invalidateResourceMenu();
     }
     catch ( Exception ex )
     {
       logException( out, this.getClass().getName(), "upload",
                     "A technical problem occurred.", ex );
     }

     return true;
   }

   public String fileParameter(Request req) {
     String url;
     StringBuffer dest_filename = new StringBuffer();

     for (int i = 0; i < req.getTemplateParameterCount(); i++) {
       dest_filename.append("/");
       url = (String) req.getTemplateParameter(i);
       dest_filename.append(url);
     }

     return dest_filename.toString();
   }

   /** @todo method copied from Facility, modified to also search 'keyword' */
   /** @todo separate method into multiple methods, each searching the different fields? */
   private void metadatasearch(  Request req, PrintWriter out )
       throws IOException
   {
     BuildingSession session;

     try
     {
       session = BuildingSessionManagerImpl.getSession( org.bodington.server.resources.NavigationSessionImpl.class );
       session.setResource(req.getResource().getResourceId());

       String general_elements = req.getParameter("general_elements");
       String general_title = req.getParameter("general_title");
       String general_title_opt = req.getParameter("general_title_opt");

       if (general_title_opt == null)
         general_title_opt = "a";
       if (general_elements == null)
         general_elements = "a";

       XMLRepository rep = BuildingContext.getContext().getXMLRepository();
       XMLQuery q_top = rep.getQueryInstance();
       XMLQuery q_general = rep.getQueryInstance();
       XMLQuery q_generald = rep.getQueryInstance();
       XMLQuery q_generalk = rep.getQueryInstance();
       XMLQuery q_title = rep.getQueryInstance();
       XMLQuery q_langstring = rep.getQueryInstance();
       XMLQuery q_string = rep.getQueryInstance();
       XMLQuery q_description = rep.getQueryInstance();
       XMLQuery q_keyword = rep.getQueryInstance();
       XMLQuery q_langstringd = rep.getQueryInstance();
       XMLQuery q_langstringk = rep.getQueryInstance();
       XMLQuery q_stringd = rep.getQueryInstance();
       XMLQuery q_stringk = rep.getQueryInstance();

       q_top.combination = XMLQuery.COMBINE_UNION;

       if (general_title_opt.equals("a")) {
         q_string.combination = XMLQuery.COMBINE_UNION;
         q_stringd.combination = XMLQuery.COMBINE_UNION;
       }
       else {
         q_string.combination = XMLQuery.COMBINE_INTERCEPT;
         q_stringd.combination = XMLQuery.COMBINE_INTERCEPT;
         q_stringk.combination = XMLQuery.COMBINE_INTERCEPT;
       }

       StringTokenizer tok = new StringTokenizer(general_title);
       String token;
       while (tok.hasMoreTokens()) {
         token = tok.nextToken();
         q_string.words.addElement(token);
         q_stringd.words.addElement(token);
         q_stringk.words.addElement(token);
       }

       q_string.title_criterion = "? = 'resource_id'"; //search only for metadata attached to resources
       q_string.relationship = XMLQuery.RELATE_CHILD;
       q_stringd.title_criterion = "? = 'resource_id'"; //search only for metadata attached to resources
       q_stringd.relationship = XMLQuery.RELATE_CHILD;
       q_stringk.title_criterion = "? = 'resource_id'"; //search only for metadata attached to resources
       q_stringk.relationship = XMLQuery.RELATE_CHILD;

       // ..in a langstring
       q_langstring.element_name = "langstring";
       q_langstring.relationship = XMLQuery.RELATE_CHILD;
       q_langstringd.element_name = "langstring";
       q_langstringd.relationship = XMLQuery.RELATE_CHILD;

       // ...in a title
       q_title.element_name = "title";
       q_title.relationship = XMLQuery.RELATE_CHILD;

       q_description.element_name = "description";
       q_description.relationship = XMLQuery.RELATE_CHILD;
       ///////////////////////////
       q_keyword.element_name = "keyword";
       q_keyword.relationship = XMLQuery.RELATE_CHILD;
       /////////////////////

       //...in general section
       q_general.element_name = "general";
       q_generald.element_name = "general";
       q_generalk.element_name = "general";

       q_string.addElement(q_langstring);
       q_langstring.addElement(q_title);
       q_title.addElement(q_general);

       q_stringd.addElement(q_langstringd);
       q_langstringd.addElement(q_description);
       q_description.addElement(q_generald);

       //////////////////////////////////////
       q_stringk.addElement(q_langstringk);
       q_langstringk.addElement(q_keyword);
       q_keyword.addElement(q_generalk);

       ///////////////////////////////////////

       Vector list;

       if (general_elements.equals("a"))
         list = session.searchMetadata(q_string);
       else if (general_elements.equals("b"))
         list = session.searchMetadata(q_stringd);
       else if (general_elements.equals("d"))
         list = session.searchMetadata(q_stringk);

       else {
         q_top.addElement(q_string);
         q_top.addElement(q_stringd);
         list = session.searchMetadata(q_top);
       }

       if (list == null || list.size() < 1) {
         out.println("<P>No records were found.</P>");
         return;
       }

       if (list.size() > 100)
         out.println("<P>More than one hundred resources were found, the first one hundred are listed here but you should refine your search.</P>");
       else
         out.println("<P>Number of resources found: " + list.size() + "</P>");

       XMLObjectRecord record;
       Resource found_resource;
       boolean viewable;
       for (int i = 0; i < list.size(); i++) {
         record = (XMLObjectRecord) list.elementAt(i);
         found_resource = Resource.findResource(new PrimaryKey(record.
             getReference().intValue()));
         if (found_resource != null) {
           viewable = found_resource.checkPermission(Permission.VIEW);

           out.print("<HR>");
           out.print("<H4>");
           if (viewable) {
             out.print("<A TARGET=_top HREF=\"");
             out.print(req.getContextPath());
             out.print(req.getServletPath());
             out.print(found_resource.getFullName());
             out.print("\">");
           }
           out.print(found_resource.getTitle());
           if (viewable)
             out.println("</A>");

           out.print("</H4>");

           if (!viewable)
             out.println(
                 "<P><I>You are not on the access list for this item.</I></P>");
           out.print("<P>");
           out.print(found_resource.getDescription());
           out.println("</P>");
         }
       }

     }
     catch (BuildingServerException bsex) {
       out.println("<PRE>");
       out.println(bsex.getMessage());
       out.println("</PRE>");
     }

     return;
   }

}