oracle.otnsamples.cmsxdb.admin.CMSAdminBean (Java2HTML)
/*
 * @author  : Elangovan
 * @version : 1.0
 *
 * Development Environment : Oracle9i JDeveloper

 * Name of the File        : CMSAdminBean.java
 *
 * Creation / Modification History
 *    Elangovan           12-Dec-2002        Created
 *
 */


package oracle.otnsamples.cmsxdb.admin;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.CallableStatement;

import java.util.ArrayList;
import java.util.LinkedList;

import java.util.Collection;
import java.util.StringTokenizer;

import javax.sql.DataSource;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.http.HttpServletRequest;


import oracle.xdb.XMLType;

import oracle.jdbc.OracleTypes;

import oracle.AQ.AQQueue;
import oracle.AQ.AQMessage;
import oracle.AQ.AQSession;
import oracle.AQ.AQException;
import oracle.AQ.AQOracleQueue;

import oracle.AQ.AQObjectPayload;
import oracle.AQ.AQDriverManager;
import oracle.AQ.AQEnqueueOption;
import oracle.AQ.AQDequeueOption;

import oracle.otnsamples.cmsxdb.ConnParams;
import oracle.otnsamples.cmsxdb.exception.CMSAdminException;


/**
 * This class handles the admin operations of the XML Content Management  

 * application.  This class handles the following admin tasks,
 * 
 *   -- Allows users to raise requests for privilege ( Content Managers )
 *   -- Grant/Reject privilege requests
 *   -- Externalize resources
 *   
 * From Oracle9i R2 onwards XMLType can be used as AQ payload type. Extern and 
 * Privilege requests are enqueued into Extern_Queue and Privilege_Queue 
 * respectively (as XMLType messages). The admin browses through these queues 
 * and either accepts or rejects these requests. When a request is accepted, 
 * the messages is dequeued and the payload is processed, else the message 
 * is dequeued and discarded.

 * 
 *     Enqueue    ----->    Extern_Queue    ----->    Dequeue 
 *  ( Java API )           ( Oracle AQ )            ( Java API )
 *  
 *     Enqueue    ----->    Privilege_Queue    ----->    Dequeue 
 *  ( Java API )             ( Oracle AQ )            ( PL/SQL API )
 *  
 */
public class CMSAdminBean  {

  private DataSource datasource            = null;  

  // Generates files on the application server hostmachine

  private Externalizer externalizer        = null;

  // Upper limit on number requests to be displayed to Admin
  private static final int MAXLIST = 10;

  // Byte array to store message id, array index is used for generating GUI
  private byte[][] privMsgId   = new byte[MAXLIST][16];
  private byte[][] externMsgId = new byte[MAXLIST][16];
  
  /**
   * Empty constructor. Loads the AQDriver.
   * 
   * @exception CMSAdminException if loading AQDriver fails
   */

  public CMSAdminBean() 
    throws CMSAdminException {
    try {
      // Load AQ Driver
      Class.forName( "oracle.AQ.AQOracleDriver" );

      // Initialize externalizer with the location where files have to be generated
      // The generated file path is relative to this location
      externalizer = new Externalizer( ConnParams.siteRootPath );
      
    } catch ( ClassNotFoundException clsNtFdEx ) {
    
      throw new CMSAdminException( "Error Loading AQDriver :" + clsNtFdEx.toString( ) );
      
    } 

  
  }

  /**
   * Parses the servlet request to generate an XML representation of privilege
   * request which is enqueued into Privilege_Queue.
   * 
   * Privilege request payload:
   * 
   *  <Request>
   *    <ResourceLoc>/xxx/xxx/xxx.xxx</ResourceLoc>
   *    <Ace> 
   *      <grant>true/false</grant>
   *      <principal>XXXX</principal>
   *      <privilege><dav:xxx/></privilege>
   *    </Ace>

   *  </Request>
   * 
   * @param     req         HttpServlet request 
   * 
   * @return                PrivilegeRequest object that was enqueued
   * 
   * @exception CMSAdminException if enqueuing fails
   */
  public PrivilegeRequest enqueuePrivRequest( HttpServletRequest req ) 
    throws CMSAdminException {

    // Resource path for which privilege is required
    String   resPath = req.getParameter("ResourcePath");
    // List of privileges required
    String[] privReq = req.getParameterValues("Privilege");
    // User requesting privilege
    String   user    = req.getParameter("User");


    Connection       conn    = null;
    PrivilegeRequest privreq = null;

    try { 

      // Get connection
      conn = this.getConnection( );

      // Construct a PrivilegeRequest object ( assume the request is a grant request )
      privreq = new PrivilegeRequest(user, resPath, true,privReq, null, null );

      // Enqueue XMLType message to privilege request queue
      this.enqueue("privilege_queue", privreq.toXMLType(conn), conn );

    } finally {
      try {
        // close connection

        if( conn != null ) conn.close();
      } catch(SQLException sqlEx) {
        throw new CMSAdminException(" Error closing connection : "+sqlEx.getMessage() );
      }      
    }
    
    return privreq;
    
  }

  /**
   * Parses the request and grant/reject privileges based on admin input.
   * Calls a PL/SQL procedure to dequeue the message and process the request.
   * If the request has been rejected, then the message is just dequeued and 
   * ignored.
   * 
   * @param     req         HttpServlet request that holds the message details
   * 
   * @return                Collection of PrivilegeRequests and the status of 

   *                        processing  ( SUCCESS/Error message )
   * 
   * @exception CMSAdminException if connecting to datasource fails
   * @exception SQLException      if dequeuing or processing  message fails
   */
  public Collection processPrivilegeRequest( HttpServletRequest req )
    throws CMSAdminException, SQLException {

    Collection processedRequest = new ArrayList( );
    
    Connection        conn  = null;
    CallableStatement cstmt = null;    
    
    String[] messageId  = req.getParameterValues( "MessageId" );
    String[] principal  = req.getParameterValues( "Principal" );
    String[] resPath    = req.getParameterValues( "ResourcePath" );
    String[] grant      = req.getParameterValues( "Grant" );
    String[] privileges = req.getParameterValues( "Privileges" );

    boolean  accept     = false;

    boolean  isGrant    = false;

    String   status     = null;
    String[] priv       = null; 

    if( messageId != null ) {

      try {

        // Initialize connection
        conn = this.getConnection( );

        // Call 'Process_Message' with message id and flag [ Y-accept / N-reject ]
        cstmt = conn.prepareCall( " begin ? := OTNCMS_ADMIN.Process_Message( ?, ? ); end; " );

        for( int ctr = 0; ctr < messageId.length; ctr++ ) {

          // Get the accept/reject flag for the current message id
          String grantRequest = req.getParameter( messageId[ctr] );

          isGrant = grant[ctr].equals( "Y" )?true:false;

          
          // Get message index
          int msgidx = Integer.parseInt(messageId[ctr]);

          if( grantRequest != null )  {

            // Set the message id and flag          
            cstmt.registerOutParameter( 1, OracleTypes.INTEGER );
            cstmt.setBytes( 2, privMsgId[msgidx] );
            cstmt.setString(3, grantRequest );

            try {            
            
              cstmt.execute( );
              // Returns a positive integer if change was success
              int result = cstmt.getInt(1);               
              if( result > 0 ) {
                if( isGrant ) {
                  status = "Granted";
                } else {
                  status = "Denied";
                }

              }  else {
                status = " Could not change privilege, user might already have the requested privilege "; 
              }  
            
            } catch ( SQLException sqlEx )  {
              status = "ERROR";
              System.out.println(" Error executing processing privilege : " + sqlEx.toString( ));
            }

            // Construct a String[] of requested privileges
            StringTokenizer tokens = new StringTokenizer( privileges[ctr] );
            priv = new String[ tokens.countTokens( ) ]; 
            for(int i = 0; i < priv.length; i++ ) {
              priv[i] = tokens.nextToken();
            }  
          
            processedRequest.add( new PrivilegeRequest( principal[ctr], resPath[ctr],
                                                        true, priv, null, status ) );          
          }        
        }  

      } catch( SQLException sqlEx ) {
    

        System.out.println(" SQL Error while processing privileges : "+
                           sqlEx.toString( ));

      } catch( Exception ex ) {
    
        System.out.println(" Error while processing privileges : "+
                           ex.toString( ));
                         
      } finally {

        // Close callable statement and connection
        try { 
          if( cstmt != null ) cstmt.close();
          if( conn != null ) conn.close();
        
        } catch(Exception ex) {
          System.out.println(" Error closing Statement/Connection : "+ex.toString());
        }
      }
      
    }  

    return processedRequest; 
  }


  /**
   * Gathers parameters from servlet request and generates files if extern request
   * has been accepted by Admin.
   * 
   * @param     req         Request containing message id to be processed
   * 
   * @return                Collection of ExternRequest and status of extern
   * 
   * @exception CMSAdminException if dequeue of messages fail
   * @exception SQLException      if connecting to database fails
   */
  public Collection processExternRequest( HttpServletRequest req )
    throws CMSAdminException, SQLException {

    Collection processedRequest = new ArrayList( );

    String[] messageId  = req.getParameterValues( "MessageId" );
    String[] grant      = req.getParameterValues( "Grant" );
    boolean  accept     = false;
    int      msgidx     = 0;
    String   status     = null;

    AQQueue              queue     = null;
    AQSession            aqSession = null;    

    AQMessage            message   = null;
    AQObjectPayload      payload   = null;
    AQDequeueOption      dqOption  = null;
    Connection           conn      = null;

    try {

      // Initialize database connection and AQ session      
      conn      = this.getConnection( );
      aqSession = this.getAQSession( conn );

      // Get queue
      queue = aqSession.getQueue(ConnParams.dbUsername, "extern_queue");
 
      dqOption = new AQDequeueOption();
      dqOption.setWaitTime(AQDequeueOption.WAIT_NONE);

      if( messageId != null ) {
          
        for( int ctr = 0; ctr < messageId.length; ctr++ ) {

          // Get accept/reject flag for current message id
          String grantRequest = req.getParameter( messageId[ctr] );
          msgidx = Integer.parseInt( messageId[ctr] );
    
          if( grantRequest != null )  {


            // Set the message id of message to be dequeued        
            dqOption.setMessageId( externMsgId[ msgidx ] );

            // Dequeue the message
            message = ((AQOracleQueue)queue).dequeue(dqOption, XMLType.getORADataFactory() );
            payload = message.getObjectPayload();

            ExternRequest ereq = new ExternRequest( null, (XMLType) payload.getPayloadData( ) );

            if( grantRequest.equalsIgnoreCase("Y") ) {

              // Generate file  
              externalizer.generateFile( ereq.getResourceUrl(), ereq.getXSLLocation() ,
                                           ereq.getContentType() );

              status = "Generated";
                
            }  else { 
              status = "Rejected";
            }  
            conn.commit();              
            ereq.setStatus( status );  
            processedRequest.add( ereq );             
          }        
        }        
      }                    

    } catch ( AQException aqEx ) {
      System.out.println("Error Dequeuing extern requests : " + aqEx.toString( ));
      throw new CMSAdminException( "Error Dequeuing extern requests :" + aqEx.getMessage() );

    } catch ( Exception ex )  {
      System.out.println(" Error during externalization : " + ex.toString());
      ex.printStackTrace();
      throw new CMSAdminException( "Error during externalization : " + ex.getMessage() );
              
    } finally {
    
      if( aqSession != null ) aqSession.close();
      if( conn != null )      conn.close();
      
    }

    return processedRequest; 
  }

  /**
   * Enqueue the XMLType message into the queue with the given queue name.
   * 
   * @param     queueName   name of the queue where the message has to be enqueued
   * @param     xmlmsg      XMLType message to be enqueued
   * @param     conn        datasource connection 
   * 
   * @return                message id of the enqueued message
   * 

   * @exception CMSAdminExcpetion if enqueuing fails
   */
  public byte[] enqueue( String queueName, XMLType xmlmsg,Connection conn ) 
      throws CMSAdminException {

    AQQueue              queue     = null;
    AQMessage            message   = null;
    AQSession            aqSession = null;    
    AQObjectPayload      payload   = null;
    AQEnqueueOption      eqOption  = null;
    
    byte[]               msgid     = null;

    try {

      // Get connection
      conn = this.getConnection( );

      // Get AQ session to access messages
      aqSession = this.getAQSession( conn );    

      // Get the queue to enqueue
      queue = aqSession.getQueue(ConnParams.dbUsername , queueName );

      // Enqueue a message 
      message = queue.createMessage();
      payload = message.getObjectPayload();

      // Set the payload data as XMLType 

      payload.setPayloadData(xmlmsg);
      
      eqOption = new AQEnqueueOption();

      // Enqueue the message into queue
      queue.enqueue(eqOption, message); 

      // Get the message id of the enqueued message
      msgid = message.getMessageId();

      // Explicitly commit
      conn.commit( );
      
    } catch( AQException aqEx ) {
    
      System.out.println(" AQ Error enqueuing into queue "+queueName+
                         " : "+aqEx.toString( ));                         
                         
    } catch( SQLException sqlEx ) {
    
      System.out.println(" SQL Error enqueuing into queue "+queueName+
                         " : "+sqlEx.toString( ));
                         
    } finally {

      // Close AQ session 
      try { 
        if( aqSession != null ) aqSession.close();
        
      } catch(Exception ex) {

        System.out.println(" Error closing AQ Session : "+ex.toString());
      }
    }

    if( msgid == null ) 
      throw new CMSAdminException ( " Error enqueuing message into " + queueName );
      
    return msgid;        
    
  }


  /**
   * Returns the list of pending extern/privilege requests based on the queue 
   * name parameter. Constructs a collection of pending requests by browsing 
   * the queue (without dequeuing) .
   * 
   * @param     queueName   Name of queue to browse and gather messages
   * 
   * @return                Collection of pending requests 
   * 
   * @exception CMSAdminException if browsing queue fails
   * 
   */
  public Collection getPendingRequests( String queueName ) 
    throws CMSAdminException  {

    AQSession        aqSession        = null;    
    AQQueue          reqQueue         = null;
    AQMessage        msg              = null;
    AQObjectPayload  payload          = null;

    AQDequeueOption  dqOption         = null;
    
    XMLType          requestXML       = null;
    LinkedList       pendingRequests  = null;
    Connection       conn             = null;

   
    pendingRequests = new LinkedList( );

    try {

      // Initialize database connection and AQ session
      conn      = this.getConnection( );
      aqSession = this.getAQSession( conn );

      // Get queue
      reqQueue = aqSession.getQueue( ConnParams.dbUsername, queueName );
    
      // Set dequeue options for browsing messages
      // Note that messages will not be dequeued during browsing
      dqOption = new AQDequeueOption( );
      dqOption.setWaitTime( AQDequeueOption.WAIT_NONE );
      dqOption.setDequeueMode( AQDequeueOption.DEQUEUE_BROWSE );
      
      // Start browsing from the first message
      dqOption.setNavigationMode( AQDequeueOption.NAVIGATION_FIRST_MESSAGE );

      // Loop until there are no messages in queue or 10 messages have been reached
      for( int msgcnt = 0; msgcnt < MAXLIST ; msgcnt++) {

        try {
        

          // Dequeue the message
          msg = ( (AQOracleQueue) reqQueue).dequeue( dqOption, XMLType.getORADataFactory( ) );
          
        } catch (AQException aqEx) { 

          // Ignore error and break from loop, since queue might be empty or 
          // there are no messages to browse further
          break;          
          
        }
        // Get the message payload, payload contains the XML request
        payload = msg.getObjectPayload( );

        // Get the XMLType request from payload
        requestXML = ( XMLType ) payload.getPayloadData( );

        // Based on queue name, construct value object and add to return collection
        if( queueName.equals("privilege_queue")) {
        
          pendingRequests.addLast( new PrivilegeRequest (new String( msg.getMessageId( ) ),requestXML));
          // Store privilege request message id array, this array will be used 
          // to get the message id based on message index.
          privMsgId[msgcnt] = msg.getMessageId( );
          
        } else if( queueName.equals("extern_queue")) {
        
          pendingRequests.addLast( new ExternRequest(new String( msg.getMessageId( )),requestXML));          
          // Store extern request message id array, this array will be used 
          // to get the message id based on message index.
          externMsgId[msgcnt] = msg.getMessageId( );          
        }
        
        dqOption.setMessageId(null);

        
        // Move to next message
        dqOption.setNavigationMode(AQDequeueOption.NAVIGATION_NEXT_MESSAGE); 
      }  

    } catch( AQException aqEx ) {
    
      System.out.println(" AQ Error browsing queue "+queueName+
                         " : "+aqEx.toString( ));                         
                         
    } catch( SQLException sqlEx ) {
    
      System.out.println(" SQL Error browsing queue "+queueName+
                         " : "+sqlEx.toString( ));
                         
    } finally {

      // Close session and connection
      try { 
        if( aqSession != null ) aqSession.close();
        if( conn != null ) conn.close();
        
      } catch(Exception ex) { 
        System.out.println("Error closing session/connection : "+ex.toString());
      }
    }

    return pendingRequests;    
  }

  
  /**
   * Creates a AQSession to perform queuing operations.
   * 

   * @param conn Datasource connection
   * 
   * @return AQSession from the passed connection
   * 
   * @exception CMSAdminException if creating AQSession fails
   * @exception SQLException      if disabling auto-commit fails
   */
  private AQSession getAQSession( Connection conn ) 
     throws CMSAdminException, SQLException  {
  
    AQSession aqSession = null;
    
    try  {

      conn.setAutoCommit( false );
      // Initialize AQ session 
      aqSession = AQDriverManager.createAQSession( conn );

    }  catch ( AQException aqEx ) {
    
      throw new CMSAdminException( "Error creating AQSession: " + aqEx.toString( ) );
    }

    return aqSession;
        
  }

  /**
   * Returns a connection to datasource.
   * 
   * @return Connection to datasource
   * 
   * @exception CMSAdminException if lookup or connecting to datasource fails
   */
  private Connection getConnection( ) throws CMSAdminException {


    Connection conn = null;    
    try {      

      if ( datasource == null ) {
        // Initialize datasource
        datasource = ( DataSource ) new InitialContext( ).lookup( ConnParams.datasourceName );
       } 

      // Retrieve a connection from datasource     
      conn = datasource.getConnection( );

    } catch ( NamingException  nameEx )  {
    
      throw new CMSAdminException( "Error during DataSource lookup :" + nameEx.toString( ) );
     
    } catch ( SQLException sqlEx )  {
    
      throw new CMSAdminException( "Error Connecting to Datasource :" + sqlEx.toString( ) );
      
    }      

    return conn;
  }

}
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy