PostToNewsService.java - Web Service Client
ListenToNewsService.java - Web Service Client

/*
 * @author : Elangovan
 * @version 1.0

 *
 * Development Environment : Oracle9i JDeveloper 
 *
 * Name of the File        : NewsQueueEJB.java
 *
 * Creation / Modification History
 *

 *    Elangovan          16-May-2003        Created
 *
 */
package oracle.otnsamples.jmswebservice.ejb;

import java.io.Serializable;

import java.rmi.RemoteException;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import java.util.Date;

import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;


import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;

import javax.jms.TopicPublisher;
import javax.jms.TopicSession;

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

import javax.sql.DataSource;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.w3c.dom.NodeList;


/**
 * This Message Driven Bean is assosiated with the NewsQueue. This bean is invoked
 * whenever a Web Service client invokes the 'send()' operation in the service.
 *
 * This bean receives messages, gets the News from the message object,
 * persists to the datasource and publishes the News to a Topic. The Topic is 
 * also exposed as a JMS Web Service and any Web Service client can subscribe
 * to this Topic by calling the 'receive()' method of the Web Service.
 * The Topic to which the News has to be published is set as parameters in 

 * the inbound message.
 *
 */
public class NewsQueueEJB implements MessageDrivenBean, MessageListener  {

  private MessageDrivenContext    context;

  private TopicConnectionFactory  topicConnectionFactory = null;

  private DataSource              ds = null;
  

  /**

   *  EJB container calls this method while creating a bean instance.
   *
   * @exception RemoteException if remote call fails
   */
  public void ejbCreate() throws RemoteException {
    try {
      // Initialize JNDI context and lookup using the given JNDI name
      Context context = new InitialContext( );
      ds = (DataSource) context.lookup("jdbc/NewsDS");               
      
    } catch(NamingException nameEx) {
      throw new RemoteException(" Error accessing DataSource : " +
                                  nameEx.toString()); 
    }

    
  }

  /**
   * This method is invoked by the container when a message is enqueued in the
   * NewsQueue.
   *
   * The message contains the payload (News) as an XML Element conforming to
   * org.w3c.dom.Element standards.
   *
   * @param msg Message enqueued on the queue.
   *
   */
  public void onMessage(Message inMsg) {



    ObjectMessage objMsg                   = null;
    String        destTopicConnFactoryName = null;
    Destination   destTopic                = null;
    Element       newsElement              = null;
    try {
      // Message should be of type objectMessage
      if (inMsg instanceof ObjectMessage) {

        objMsg = (ObjectMessage) inMsg;

        // Retrieve the News element
        newsElement = (Element)objMsg.getObject();

        System.out.println( "News Service MDB : Received news " );


        // The destination factory name is specified using
        // <reply-to-connection-factory-resource-ref> in the deployment descriptor
        // Get the destination Topic factory name
        destTopicConnFactoryName = inMsg.getStringProperty("OC4J_REPLY_TO_FACTORY_NAME");

        // JMS reply is specified by setting
        // <reply-to-topic-resource-ref> in the deployment descriptor
        destTopic = inMsg.getJMSReplyTo();

        // Persist News to datasource
        this.storeNews(getNodeValueByName(newsElement,"NewsType"),
                       getNodeValueByName(newsElement,"Title"),
                       getNodeValueByName(newsElement,"Snippet"),
                       getNodeValueByName(newsElement,"DetailedNews"));


        // Publish the News to Topic

        this.publishToTopic(destTopicConnFactoryName,destTopic,newsElement);
       }

    }   catch (SQLException sqlEx)    {
      System.out.println("Error storing news : " +  sqlEx.toString());

    }  catch (Exception ex)     {        // Handle Generic exception
      System.out.println(" Error processing news message : "+ex.toString());
    }
  }

  /**
   * Initializes Topic connection factory.
   *
   * @param topicConnFactoryName JNDI name of topic connection factory
   *
   * @exception NamingException if lookup fails
   */

  public void initTopicConnectionFactory(String topicConnFactoryName)
      throws NamingException {

    if(topicConnectionFactory == null) {

      // Initialize JNDI context and lookup using the given JNDI name
      Context context = new InitialContext( );
      topicConnectionFactory =  (TopicConnectionFactory)
                   context.lookup("java:comp/env/"+topicConnFactoryName);

    }
  }
  

  /**
   * Publishes the News to the given Topic.
   *
   * @param destTopicConnFactoryName Destination Topic connection factory name
   * @param destTopic                Destination topic

   * @param newsElement              XML Element containing News info
   *
   * @exception JMSException if publish fails
   */
  private void publishToTopic(String destTopicConnFactoryName,Destination destTopic,
                                                            Element newsElement)
      throws JMSException {


    TopicConnection  topicConnection = null;
    TopicSession     topicSession    = null;
    Topic            topic           = null;
    TopicPublisher   topicPublisher  = null;
    ObjectMessage    outMsg          = null;

    try   {

      initTopicConnectionFactory(destTopicConnFactoryName);

      // Get the Topic

      topic = (Topic)destTopic;

      // Create a Topic Connection and Session
      topicConnection =  topicConnectionFactory.createTopicConnection();
      topicSession    =  topicConnection.createTopicSession(false,
                                         Session.AUTO_ACKNOWLEDGE);

      // Create a Topic Sender
      topicPublisher = topicSession.createPublisher(topic);

      // Start the connection
      topicConnection.start();

      // Create an Object Message
      outMsg = topicSession.createObjectMessage();

      // Set the payload to the given News
      outMsg.setObject ((Serializable)newsElement);

      // Publish the News Message to Topic
      topicPublisher.publish(outMsg);


      System.out.println("News Service: News dispatched successfully");

    }  catch (NamingException nameEx)     {
      System.out.println("Error accessing topic : " + nameEx.toString());
    }   catch (JMSException jmsEx)    {
      System.out.println("Error publishing to topic : " +  jmsEx.toString());
    }   finally     {

      // Close the Topic Connection
      if (topicConnection != null)     topicConnection.close();

    }

  }

  /**
   *  Persists the News to DataSource.
   * 
   * @param type News type
   * @param title News title
   * @param snippet News a short description

   * @param detailedNews Detailed News
   *
   * @exception SQLException if datasource operation fails
   */
  private void storeNews(String type, String title, String snippet, String detailedNews ) 
    throws SQLException {
    
    Connection        conn  = null;
    PreparedStatement pstmt = null;
    String insertsql =  " insert into News "+
                        " values( seqNewsId.nextval, sysdate,?,?,?,? ) ";
    try {
      // Get a connection from DataSource
      conn = ds.getConnection();   

      pstmt = conn.prepareStatement( insertsql );
      
      // Bind parameter values
      pstmt.setString(1, type);
      pstmt.setString(2, title);
      pstmt.setString(3, snippet);
      pstmt.setString(4, detailedNews);


      // Execute the insert
      pstmt.executeUpdate();
      
    } finally {  
      // Free resources
      if(pstmt != null) pstmt.close();
      if(conn!=null)    conn.close();
      
    }  
  }

  /**
   * Searches the given XML node for a matching node with the given node name,
   * return the node value of the matching node.
   *
   * @param node Node to be searched
   * @param name Name of the node to be searched
   *
   * @return node value having the given node name
   */
  private String getNodeValueByName(Node node, String name) {

    String value = null;
    try {

      if (node != null) {
        // Get the list of child nodes
        NodeList  children = node.getChildNodes();
        int childLen = children.getLength();
        // Search all child nodes with given node name
        for (int  ctr=0; ctr < childLen; ctr++) {
          Node child = children.item(ctr);
          if ((child != null) && (child.getNodeName() != null) &&
                                        child.getNodeName().equals(name) ) {
            Node grandChild = child.getFirstChild();
            if (grandChild.getNodeValue() != null)
              return  grandChild.getNodeValue();
          }
        }
      }
    } catch(NullPointerException ne) {
      value = null;
    }
    return value;
  }

  // Standard call-back methods

  public void ejbRemove() {    }


  public void setMessageDrivenContext(MessageDrivenContext ctx) {
    this.context = ctx;
  }


}
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