View Javadoc

1   package org.astrogrid.portal.resources;
2   
3   import org.apache.avalon.framework.parameters.Parameters;
4   import org.apache.cocoon.acting.AbstractAction;
5   import org.apache.cocoon.environment.Request;
6   import org.apache.cocoon.environment.Session;
7   import org.apache.cocoon.environment.Redirector;
8   import org.apache.cocoon.environment.SourceResolver;
9   import org.apache.cocoon.environment.ObjectModelHelper;
10  import java.util.ArrayList;
11  import java.util.HashMap;
12  import java.util.Map;
13  
14  import org.apache.commons.logging.Log;
15  import org.apache.axis.components.logger.LogFactory;
16  import org.apache.axis.utils.XMLUtils;
17  import org.astrogrid.util.DomHelper;
18  
19  import org.astrogrid.registry.client.admin.RegistryAdminDocumentHelper;
20  import org.astrogrid.registry.client.RegistryDelegateFactory;
21  import org.astrogrid.registry.client.query.RegistryService;
22  import org.astrogrid.registry.RegistryException;
23  
24  import org.astrogrid.config.Config;
25  
26  import org.w3c.dom.Document;
27  import org.w3c.dom.Element;
28  import org.w3c.dom.Node;
29  import org.w3c.dom.NodeList;
30  import org.xml.sax.SAXParseException;
31  
32  import org.astrogrid.util.DomHelper;
33  import org.astrogrid.registry.common.WSDLBasicInformation;
34  import org.astrogrid.store.Ivorn;
35  
36  
37  /***
38   * @author Phil Nicolson (pjn3@star.le.ac.uk) Jan 05
39   * @version $Name:  $Revision: 1.2 $Date:
40   */
41  public class ResourceAction extends AbstractAction {
42  
43    /*** Compile-time switch used to turn tracing on/off. 
44     * Set this to false to eliminate all trace statements within the byte code.*/
45    private static final boolean TRACE_ENABLED = true;
46  
47    /*** Compile-time switch used to turn certain debugging statements on/off. 
48     * Set this to false to eliminate these debugging statements within the byte code.*/
49    private static final boolean DEBUG_ENABLED = true;
50  
51    private static Log log = LogFactory.getLog("ResourceAction");     
52  
53    public static final String 
54        ACTION_PARAM_TAG = "action" ,
55        ACTION_CATALOG_QUERY = "search for catalogs" ,
56        ACTION_TASK_QUERY = "search for tasks" ,
57        ACTION_FILESTORE_QUERY = "filestore_query" ,
58  	  ERROR_MESSAGE_PARAMETER = "resource_error_message" ,
59  	  ERROR_INFO_PARAMETER = "resource_info_message" ,
60  	  PARAM_RESULT_COUNT = "resource_result_count" ;
61  
62    // General constraints
63    public static final String
64        PARAM_RESOURCE_NAME = "resourceNameField",
65        PARAM_DESCRIPTION = "descriptionField",
66        PARAM_PUBLISHER = "publisherField",
67        PARAM_TITLE = "titleField",
68        PARAM_CONSTRAINT_JOIN = "ConstraintAndOr",
69        PARAM_CONSTRAINT_ALL = "finalAndOr",
70    // Wavelength
71        PARAM_WAVELENGTH = "wavelength" ,
72        PARAM_WAVELENGTH_JOIN = "WavelengthAndOr",
73    // Mission
74        PARAM_MISSION = "mission" ,
75        PARAM_MISSION_JOIN = "MissionAndOr",
76    // Keyword
77        PARAM_KEYWORD = "keyword",
78        PARAM_KEYWORD_JOIN = "KeywordAndOr",
79        
80    // Task
81        PARAM_AUTHORITY_FIELD = "taskNameField",
82        PARAM_TASK_JOIN = "TaskAndOr";  
83  
84    public static Config conf = null;   
85       
86    static {
87      if(conf == null) {
88        conf = org.astrogrid.config.SimpleConfig.getSingleton();
89      }      
90    }
91   
92  
93    /***
94    * Our action method.
95    *
96    */
97    public Map act ( Redirector redirector,
98                     SourceResolver resolver,
99                     Map objectModel,
100                    String source,
101                    Parameters params ) {                  
102      if( TRACE_ENABLED ) trace( "ResourceAction.act() entry" );  
103 
104      ResourceActionImpl myAction = null;
105      Map retMap = null;
106 
107      try {     
108         myAction = new ResourceActionImpl( redirector,
109                                            resolver,
110                                            objectModel,
111                                            source,
112                                            params );
113 
114         retMap = myAction.act();                                            
115      }
116      catch ( Exception ex ) {
117         ex.printStackTrace();
118      }
119      finally {
120         if( TRACE_ENABLED ) trace( "ResourceAction.act() exit" );  
121      }
122 
123      return retMap; 
124  
125   } // end of act()
126   
127   private class ResourceActionImpl {
128         
129     private Redirector redirector;
130     private SourceResolver resolver;
131     private Map objectModel, results;
132     private String source;
133     private Parameters params;
134     private Request request;
135     private Session session;    
136     private String action;     
137         
138     public ResourceActionImpl( Redirector redirector,
139                                SourceResolver resolver,
140                                Map objectModel,
141                                String source,
142                                Parameters params ) {                                   
143       if( TRACE_ENABLED ) trace( "ResourceActionImpl() entry" ); 
144             
145       try {          
146         this.redirector = redirector;
147         this.resolver = resolver;
148         this.objectModel = objectModel;
149         this.source = source;
150         this.params = params;         
151         this.results = new HashMap();
152             
153         // Get current request and session.
154         this.request = ObjectModelHelper.getRequest( objectModel );
155         this.session = request.getSession();
156             
157         this.action = request.getParameter( ACTION_PARAM_TAG );              
158                     
159       }
160       catch (Exception ex) {
161         ex.printStackTrace();
162       }
163           
164       finally {
165         if( TRACE_ENABLED ) trace( "ResourceActionImpl() exit" ); 
166       }
167               
168     } // end of ResourceActionImpl()
169         
170         
171     public Map act() {
172       if( TRACE_ENABLED ) trace( "ResourceActionImpl.act() entry" );      
173         
174       try {
175 
176         debug( "action is: " + action );
177                     
178         if( action == null )
179         {
180           // first time into resource browser - need to set attributes to empty string to prevent front end displaying them as null
181 		  session.setAttribute( ERROR_MESSAGE_PARAMETER, "" ) ;
182 		  session.setAttribute( ERROR_INFO_PARAMETER, "" ) ;
183 		  session.setAttribute( PARAM_RESULT_COUNT, "" );           
184         }      
185               
186         else if ( ACTION_CATALOG_QUERY.equals(action) )  {
187           this.catalogQuery();
188         }
189         else if ( ACTION_TASK_QUERY.equals(action) )  { 
190           this.taskQuery();                   
191         }
192         else if ( ACTION_FILESTORE_QUERY.equals(action) )  {
193           this.filestoreQuery(); 
194         }
195         else {
196           results = null;
197           debug( "unsupported action"); 
198           throw new UnsupportedOperationException(
199                  action + " no longer supported" );
200         }
201             }
202       catch( ConsistencyException cex ) {
203         results = null;
204         debug( "ConsistencyException occurred");
205       }
206       //PJN Note: these should only be here during testing...
207       catch( Exception ex) {
208         results = null;
209         debug( "Exception: ex" );
210         ex.printStackTrace();
211       }
212       //PJN Note: these should only be here during testing...
213       catch( Throwable th ) {
214         results = null;
215         debug( "Throwable th" );
216         th.printStackTrace();
217       }
218       finally {
219         if( TRACE_ENABLED ) trace( "ResourceActionImpl.act() exit" );  
220       }
221     
222       return results;
223             
224     } // end of ResourceActionImpl.act()
225 
226 
227    /***
228      * Generate xml string to pass to Registry 
229      */
230     private void catalogQuery() throws ConsistencyException {
231       if( TRACE_ENABLED ) trace( "ResourceActionImpl.catalogQuery() entry" );
232               
233               
234       String resource = "";
235       String description = "";
236       String publisher = "";
237       String title = "";
238       String constraintjoin = "";
239       String wavelength[] = {""};
240       String wavelengthjoin = "";
241       String mission[] = {""};
242       String missionjoin = "";
243       String keyword[] = {""};
244       String keywordjoin = "";
245       String categoryjoin = "";
246       String query = "";
247       String andor = "";
248       boolean andreqd = false; // used to add 'and' between e.g. (constraints) and (wavelength)
249                     
250       try { 
251         // General constraints
252         resource = request.getParameter( PARAM_RESOURCE_NAME ).trim();
253         description = request.getParameter( PARAM_DESCRIPTION ).trim();
254         publisher = request.getParameter( PARAM_PUBLISHER ).trim();
255         title = request.getParameter( PARAM_TITLE ).trim();
256         constraintjoin = request.getParameter( PARAM_CONSTRAINT_JOIN ).trim();         
257 
258         // Wavelength
259         wavelength = request.getParameterValues( PARAM_WAVELENGTH );
260         wavelengthjoin = request.getParameter( PARAM_WAVELENGTH_JOIN ).trim();
261 
262         // Mission
263         mission = request.getParameterValues( PARAM_MISSION );       
264         missionjoin = request.getParameter( PARAM_MISSION_JOIN ).trim();                
265         
266         // Keyword         
267         keyword = request.getParameterValues( PARAM_KEYWORD );
268         keywordjoin = request.getParameter( PARAM_KEYWORD_JOIN ).trim(); 
269         
270         categoryjoin = request.getParameter( PARAM_CONSTRAINT_ALL ).trim();
271                              
272         // Lets build up the XML for a query.
273         query = "<query>\n"
274          + "<selectionSequence>\n" // start of main sequence
275          + "<selection item='searchElements' itemOp='EQ' value='Resource'/>\n"
276          + "<selectionOp op='$and$'/>\n"
277          + "<selection item='vr:Type' itemOp='EQ' value='Catalog'/>\n" ;
278 		 
279 
280          // is this an empty search?
281 		 if ( resource.length() > 0 || description.length() > 0 || 
282 		      publisher.length() >0 || title.length() > 0 ||
283 		      ( wavelength != null && wavelength.length > 0 ) || 
284 		      ( mission != null && mission.length > 0 )  ||
285 		      ( keyword != null && keyword.length > 0 ) ) 
286 		  {
287             query += "\n<selectionOp op='AND'/>";
288 			query +=  "\n<selectionSequence>\n"; // start of inner sequence
289         
290             // GENERAL CONSTRAINTS
291             if ( resource.length() > 0 || description.length() > 0 ||
292                  publisher.length() >0 || title.length() > 0 ) {        
293                  
294 			  query +=  "\n<selectionSequence>\n"; // start of constraints sequence
295 			         
296               if ( resource.length() > 0 ) 
297               {
298                 query +=  "\n<selectionSequence>\n";          	
299                 query += "<selection item='vr:Identifier/vr:AuthorityID' itemOp='CONTAINS' value='" + resource + "'/>";
300   			    query += "<selectionOp op='OR'/>";
301 			    query += "<selection item='vr:Identifier/vr:ResourceKey' itemOp='CONTAINS' value='" + resource + "'/>";
302                 query +=  "\n</selectionSequence>\n";
303                 andreqd = true;
304               }
305               if ( description.length() > 0 ) 
306               {
307                 if (andreqd) 
308                   query += "\n<selectionOp op='"+constraintjoin+"'/>";
309                 query += "<selection item='vr:Summary/vr:Description' itemOp='CONTAINS' value='" + description + "'/>";
310                 andreqd = true;
311               }
312               if ( publisher.length() > 0 ) 
313               {
314                 if (andreqd)
315                   query += "\n<selectionOp op='"+constraintjoin+"'/>";
316                 query += "<selection item='vr:Curation/vr:Publisher/vr:Title' itemOp='CONTAINS' value='" + publisher + "'/>";
317                 andreqd = true;
318               }
319               if ( title.length() > 0 ) 
320               {
321                 if (andreqd)
322                   query += "\n<selectionOp op='"+constraintjoin+"'/>";
323                 query += "<selection item='vr:Title' itemOp='CONTAINS' value='" + title + "'/>";
324                 andreqd = true;
325               }
326               query +=  "\n</selectionSequence>\n"; // end of constraints sequence
327             } // end of GENERAL CONSTRAINTS
328 
329             // WAVELENGTH
330             if ( wavelength != null && wavelength.length > 0 ) 
331             {
332 			  if (andreqd)
333                 query +=  "\n<selectionOp op='" + categoryjoin + "'/>" ;
334 			  query += "<selectionSequence>"; // start of wavelength sequence
335               for ( int i=0; i< wavelength.length; i++ ) {
336                 if ( i > 0 ) 
337                 {
338                   query += "\n<selectionOp op='" + wavelengthjoin + "'/>";
339                 }
340                 query += "<selection item='vs:Coverage/vs:Spectral/vs:Waveband'"
341                       + " itemOp='EQ' value='" + wavelength[i].trim() + "'/>";          
342               }
343 			  andreqd = true;
344               query +=  "\n</selectionSequence>"; // end of wavelength sequence
345             } // end of WAVELENGTH
346 
347             // MISSION
348             if ( mission != null && mission.length > 0 ) 
349             {
350 			  if (andreqd)
351                 query +=  "\n<selectionOp op='" + categoryjoin + "'/>";
352               query += "\n<selectionSequence>"; // start of mission sequence
353               for ( int i=0; i< mission.length; i++ ) {
354                 if ( i > 0 ) 
355                 {
356                   query += "\n<selectionOp op='" + missionjoin + "'/>";
357                 }
358                 query += "<selection item='vr:Facility'"
359                       + " itemOp='EQ' value='" + mission[i].trim() + "'/>";          
360               }
361 			  andreqd = true;
362               query +=  "\n</selectionSequence>"; // end of main mission
363             } // end of MISSION
364 
365             // KEYWORD
366             if ( keyword != null && keyword.length > 0 ) 
367             {
368 			  if (andreqd)
369                 query +=  "\n<selectionOp op='" + categoryjoin + "'/>" ;
370               query += "\n<selectionSequence>"; // start of keyword sequence
371               for ( int i=0; i< keyword.length; i++ ) 
372               {
373                 if ( i > 0 ) 
374                 {
375                   query += "\n<selectionOp op='" + keywordjoin + "'/>";
376                 }
377               query += "<selection item='vr:Subject'"
378                     + " itemOp='EQ' value='" + keyword[i].trim() + "'/>";          
379               }
380               query +=  "\n</selectionSequence>";  // end of keyword sequence
381             } // end of KEYWORD
382             
383 		  query +=  "\n</selectionSequence>"; // end of inner sequence
384             
385 		  }
386 		  
387 	    query += "\n</selectionSequence>\n";  // end of main sequence  
388         //  End of Query.
389         query += "\n</query>";  
390       }
391       catch(Exception ex) {
392 		session.setAttribute( ERROR_MESSAGE_PARAMETER, ex.getMessage() ) ;      	
393 		debug("Error thrown whilst creating task query xml: "); 
394 		debug( ex.getMessage() ) ;
395         query = "";
396       }        
397 
398       try {      
399         debug( query ); 
400         if ( query.length() > 0 ) 
401           submitQuery( query );
402       }
403       catch(Exception ex) {
404         ex.printStackTrace();
405       }
406       finally {
407         if( TRACE_ENABLED ) trace( "ResourceActionImpl.catalogQuery() exit" );
408       }                    
409     } // end of catalogQuery()
410 
411       
412     /***
413       * Generate xml string to pass to Registry 
414       */
415     private void taskQuery() throws ConsistencyException {
416       if( TRACE_ENABLED ) trace( "ResourceActionImpl.taskQuery() entry" );
417 
418       String authorityId = "";
419       String taskTitle = "";
420       String description = ""; 
421       String taskJoin = "";          
422       String query = "";
423 	  boolean andreqd = false; // used to add 'and' between e.g. (constraints) and (wavelength)
424   
425       try {        
426         authorityId = request.getParameter( PARAM_AUTHORITY_FIELD ).trim();				
427         taskTitle = request.getParameter( PARAM_TITLE ).trim();
428         description = request.getParameter( PARAM_DESCRIPTION ).trim();
429 		taskJoin = request.getParameter( PARAM_TASK_JOIN ).trim();        
430 
431         // Lets build up the XML for a query.
432         query = "<query>\n"
433                 + "<selectionSequence>\n"
434 				+ "<selectionSequence>\n"
435                 + "<selection item='searchElements' itemOp='EQ'"
436                 + " value='Resource'/>\n"
437                 + "<selectionOp op='$and$'/>"
438                 + "<selection item='@xsi:Type' itemOp='EQ'"
439                 + " value='CeaHttpApplicationType'/>"
440                 + "<selectionOp op='OR'/>"                
441                 + "\n<selection item='@xsi:type' itemOp='EQ'"
442                 + " value='CeaApplicationType'/>"
443                 + "<selectionOp op='OR'/>"                
444                 + "<selection item='@xsi:Type' itemOp='EQ'"
445                 + " value='cea:CeaHttpApplicationType'/>"
446                 + "<selectionOp op='OR'/>"                
447                 + "\n<selection item='@xsi:type' itemOp='EQ'"
448                 + " value='cea:CeaApplicationType'/>"
449 				+  "\n</selectionSequence>\n";
450 
451 		// is this an empty search?
452 		if ( authorityId.length() > 0 || taskTitle.length() > 0 || description.length() > 0 )
453 		{					 
454 		  query += "\n<selectionOp op='AND'/>"
455 		        +  "\n<selectionSequence>\n"; // start of inner sequence
456 
457           if ( authorityId.length() > 0 ) 
458           {
459 			query +=  "\n<selectionSequence>\n";          	
460 			query += "<selection item='vr:Identifier/vr:AuthorityID' itemOp='CONTAINS' value='" + authorityId + "'/>";
461 		    query += "<selectionOp op='OR'/>";
462 			query += "<selection item='vr:Identifier/vr:ResourceKey' itemOp='CONTAINS' value='" + authorityId + "'/>";
463 			query +=  "\n</selectionSequence>\n";
464 			andreqd = true;
465           }
466           if ( taskTitle.length() > 0 ) 
467           {
468 			if (andreqd) 
469 			  query += "\n<selectionOp op='"+taskJoin+"'/>";          	
470 			query += "<selection item='vr:Title' itemOp='CONTAINS' value='" + taskTitle + "'/>";
471 			andreqd = true;
472           }
473           if ( description.length() > 0 ) 
474           {
475 		    if (andreqd) 
476 			  query += "\n<selectionOp op='"+taskJoin+"'/>";          	          	
477 			  query += "<selection item='vr:Summary/vr:Description' itemOp='CONTAINS' value='" + description + "'/>";
478           }
479 		
480 		  query +=  "\n</selectionSequence>"; // end of inner sequence
481 		}
482 		  
483 		query += "\n</selectionSequence>\n";  // end of main sequence                  
484         //  End of Query.
485         query += "\n</query>";               
486       }
487       catch(Exception ex){
488 		session.setAttribute( ERROR_MESSAGE_PARAMETER, ex.getMessage() ) ;      	
489 		debug("Error thrown whilst creating task query xml: "); 
490 		debug( ex.getMessage() ) ;
491         query = "";
492       }
493       
494       try {      
495         debug( query ); 
496         if ( query.length() > 0 )         
497           submitQuery( query );                
498       }
499       catch(Exception ex) 
500       {     	
501 		ex.printStackTrace() ;
502       }
503       finally {
504         if( TRACE_ENABLED ) trace( "ResourceActionImpl.taskQuery() exit" );
505       }                    
506     } // end of taskQuery()
507 
508 
509     /***
510       * This method does nothing at present! To follow...
511       */
512     private void filestoreQuery() throws ConsistencyException {
513       if( TRACE_ENABLED ) trace( "ResourceActionImpl.filestoreQuery() entry" );
514               
515       try {          
516       }
517       catch(Exception ex){
518       }
519       finally {
520         if( TRACE_ENABLED ) trace( "ResourceActionImpl.filestoreQuery() exit" );
521       }                    
522     } // end of filestoreQuery()
523 
524 
525     /***
526      * This method submits query to Registry
527      * 
528      * @param String query 	xml query string.     
529      * @return void
530      */
531     private void submitQuery( String query ) throws ConsistencyException {
532       if( TRACE_ENABLED ) trace( "ResourceActionImpl.submitQuery() entry" );
533               
534       try {
535         ArrayList resultlist = null;
536         String count = "";         
537           // Now lets submit the query.
538         RegistryService rs = RegistryDelegateFactory.createQuery( );
539         debug( "Service = " + rs );
540         if (query.length() > 0 )
541         // if error thrown in building query string,
542         // string will be empty so do not submit.
543         {
544            Document doc = rs.submitQuery( query );        
545 
546           //create the results and put it in the request.
547            resultlist = createList( doc );
548            count = "" + resultlist.size();
549            
550 		   debug( "Number of Result = " + count );
551 		   session.setAttribute( PARAM_RESULT_COUNT, count );           
552 
553           // Not sure if this is req'd, but do we really want to retrieve everything from registry?
554           if (resultlist.size() <= 100 ) {
555             session.setAttribute("resultDoc", doc);			
556           }
557           else 
558           {
559 			session.setAttribute( ERROR_INFO_PARAMETER, "Your search will return more than 100 entries, please narrow it" ) ;
560           }
561         }                                                
562       }
563 
564       catch( Exception ex ) 
565       {     	
566 		session.setAttribute( ERROR_MESSAGE_PARAMETER, ex.getMessage() ) ;      	
567         debug("Error thrown whilst submitting query: "); 
568         debug( ex.getMessage() ) ;        
569       }
570         
571       finally {
572         if( TRACE_ENABLED ) trace( "ResourceActionImpl.submitQuery() exit" );
573       }                    
574     } // end of submitQuery()
575 
576     /***
577      * This method gets a list of key elements from the result document.
578      * @param doc Query results in a DOM tree format.
579      * @return ArrayList of relevant the String XML results.
580      */
581     private ArrayList createList( Document doc ) {
582        NodeList nodes = doc.getDocumentElement().getChildNodes();
583        return listNodes( nodes );
584     }
585     private ArrayList listNodes( NodeList nl ) {
586       ArrayList al = new ArrayList();
587       for(int i = 0; i < nl.getLength(); i++) {
588         String element = null;
589         Node node = nl.item(i);
590         if( node instanceof org.w3c.dom.Element ) {
591            element = XMLUtils.ElementToString( (Element) node );
592            al.add( element );
593         }                  
594       }
595       return al;
596     }    
597     
598   } // end of inner class ResourceActionImpl
599 
600 
601   private class ConsistencyException extends Exception {
602   }
603 
604     private void trace( String traceString ) {
605       // logger.debug( traceString );
606       System.out.println( traceString );
607   }
608     
609   private void debug( String logString ){
610     // logger.debug( logString );
611     System.out.println( logString );
612   }     
613 
614 } // end of class ResourceAction