Link to home
Start Free TrialLog in
Avatar of jrwalker2
jrwalker2

asked on

Enumeration Interface - Iterate backwards, Getting the size, Start iterating at a certain point

I have had this issue for a while now, and I'm hoping that someone can help me with this. I have a java class that connects to a queue using the jmx QueueBrowser api. I used its getEnumeration() method in order to iterate through the messages on a Weblogic queue as this is the only way that is provided. The messages are returned in the way a queue works (FIFO).

Questions:
--------------------
1. Is there a way to iterate through this Enumeration starting from the last message on published to the queue, essentially working with it as if it were a stack and not a queue?

2. Is there a way to get the total size of the Enumeration without first converting it to a Collection? Note: I tried the code below and it killed the performance of my application to the point where it was not usable (takes an extremely long time to do this conversion).

List<BrowserVO> messagesList = Collections.list(queueBrowser.getEnumeration());
int total = messagesList.size();

3. Is there a way to start iterating through an Enumeration at a certain spot (not at the first element)? I tried to convert it to a collection first, but performance is a major issue (see #2 above). I'd like to be able to return messages 1-50 to the caller, and then 51-100, and so on based on the caller's request. Right now, I can only return the first n items and that's it.

Thanks again.

private static final String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
	private static final String JDBC_DRIVER_CLASS_NAME = "oracle.jdbc.driver.OracleDriver";
	private int numMsgs;
	private int totalMsgs;
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public ArrayList browseJmsQueue(String server, String queueName,String connectionFactoryName,String user,String pass) throws Exception
	{
		
		ArrayList list = new ArrayList();
		numMsgs = 0;
		
	 	
	 	try
	 	{
	 		Hashtable env = new Hashtable();
	        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
	        env.put(Context.PROVIDER_URL, server);
	        InitialContext ctx1 = new InitialContext(env);
		 	Queue queue = (Queue) ctx1.lookup(queueName);
		 	QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx1.lookup(connectionFactoryName);
		 	QueueConnection queueConn = connFactory.createQueueConnection(user,pass);
		 	QueueSession queueSession = queueConn.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
		 	QueueBrowser queueBrowser = queueSession.createBrowser(queue);
		 	queueConn.start();
		 	
			Enumeration<BrowserVO> e = queueBrowser.getEnumeration();
			
			//List<BrowserVO> messages = Collections.list(queueBrowser.getEnumeration());
			//ArrayList <BrowserVO>aList = Collections.list(e);
			//Iterator iterator = IteratorUtils.asIterator(e);
			//ListIterator listIterator = IteratorUtils.singletonListIterator(iterator);
			
			
			
			BrowserVO valueObj = null;
			while (e.hasMoreElements() && numMsgs<50) 
			{
				Message message = (Message) e.nextElement();
				numMsgs++;
				
				String messageStr = ((TextMessage)message).getText();
				
				try
				{
					valueObj = new BrowserVO();
					valueObj.setMessage(messageStr);
					
					list.add(valueObj);
				}
				catch(Exception e1)
				{
					//Ignore the messages that don't fit the type I am looking for
				}
			}
			
			System.out.println("Total Messages: "+numMsgs);
			
			queueConn.close();
        }
       
	 	catch(Exception e)
	 	{
	 		throw new QueueBrowserException(e.toString());
	 	}
	 	
		return list;
	}

Open in new window

Avatar of for_yan
for_yan
Flag of United States of America image



That's waht I read here:
http://www.theserverside.com/discussions/thread.tss?thread_id=1618

Enumerations don't have a size as they don't contain anything. You can get the size of the container, but an enumeration is essentially a const(in terms of the refrence not the object) iterator. Its responsibiliy is to know where the next item is. If you have a handle to the container being iterated I would suggest checking to see if it has a size method (most do).
But I guess you should be getting the collection in the first place
this looks like some backwards operation of creating collection from enumeartion again:
List<BrowserVO> messagesList = Collections.list(queueBrowser.getEnumeration());

There should be some collection before enumeration
maybe you can just try

queueBrowser.size()


maybe it inherits form Collection interface
Yes, I understand you tries all that with ListIterator
Looks like this is indeed a problem; they were probably not designed to be traversed in different way;
maybe there is still some solution

Maybe you want to consume messages not to browse through them ?
Avatar of jrwalker2
jrwalker2

ASKER

Hi for_yan,

Thanks for your responses but you are right, this is still an issue. My requirement will not allow me to consume the messages (only browse them). Since I am using a WebLogic Server, I'm thinking that I might be able to access the JMS MBean to get this information. I'm still looking for some code.

Thanks
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of CEHJ
>>(takes an extremely long time to do this conversion).

How much faster (if at all) is it to simply enumerate with the Enumeration?
Thanks for_yan for your comments. I ended up solving the count issue with an MBean implementation. Please see the code below. I will award you the full points for your persistent attempts.

CEHJ - I'm not sure what you mean by "enumerate with the Enumeration". I was not asking how to enumerate over the Enumeration. If you take a look at the code I originally posted, you will see that I am doing exactly that (iterating through the first fifty messages and incrementing a counter along the way). The issue with this is that it requires me to iterate through all the messages...takes too long.



int totalCurrentMessageCount; 
		
		try
		{
			Hashtable env = new Hashtable();
			env.put(Context.PROVIDER_URL, server);
			env.put(Context.SECURITY_PRINCIPAL, user);
			env.put(Context.SECURITY_CREDENTIALS, pass);
			env.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
			InitialContext ctx = new InitialContext(env);

			Destination queue = (Destination) ctx.lookup(queueName);

			JMSDestinationRuntimeMBean destMBean = JMSRuntimeHelper.getJMSDestinationRuntimeMBean(ctx, queue);
			
			totalCurrentMessageCount = (int)destMBean.getMessagesCurrentCount();
			
			
		}
		catch(Exception e)
		{
			throw new QueueBrowserException(e.toString());
		}

Open in new window

I've requested that this question be closed as follows:

Accepted answer: 500 points for for_yan's comment http:/Q_27316085.html#36563659
Assisted answer: 0 points for jrwalker2's comment http:/Q_27316085.html#36564788

for the following reason:

Accepting my comment because I ended up solving my own issue. The solution was different than anything suggested.
Accepting my comment because I ended up solving my own issue. The solution was different than anything suggested.
intend to assign points to for_yan