Author: aco Date: Mon Jan 16 01:58:02 2006 New Revision: 369411 URL: http://svn.apache.org/viewcvs?rev=369411&view=rev Log: - Made ActiveMQConnectionFactory and ActiveMQDestination referenceable. - Ported to 4.x the jndi implementation from 3.x (JNDIStorableInterface, JNDIBaseStorable, JNDIReferenceFactory) - Added a simple test case to test the object factory. Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIBaseStorable.java incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIReferenceFactory.java incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIStorableInterface.java incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ObjectFactoryTest.java Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/command/ActiveMQDestination.java incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ActiveMQInitialContextFactoryTest.java Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java?rev=369411&r1=369410&r2=369411&view=diff ============================================================================== --- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java (original) +++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java Mon Jan 16 01:58:02 2006 @@ -43,6 +43,7 @@ import org.apache.activemq.util.JMSExceptionSupport; import org.apache.activemq.util.URISupport; import org.apache.activemq.util.URISupport.CompositeData; +import org.apache.activemq.jndi.JNDIBaseStorable; import edu.emory.mathcs.backport.java.util.concurrent.Executor; import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor; @@ -57,7 +58,7 @@ * @version $Revision: 1.9 $ * @see javax.jms.ConnectionFactory */ -public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Referenceable { +public class ActiveMQConnectionFactory extends JNDIBaseStorable implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable { public static final String DEFAULT_BROKER_URL = "tcp://localhost:61616"; public static final String DEFAULT_USER = null; @@ -359,12 +360,7 @@ this.redeliveryPolicy = redeliveryPolicy; } - /** - * set the properties for this instance as retrieved from JNDI - * - * @param properties - */ - public void setProperties(Properties properties) throws URISyntaxException { + public void buildFromProperties(Properties properties) { if (properties == null) { properties = new Properties(); @@ -381,11 +377,12 @@ } } - public Properties getProperties() { - Properties props = new Properties(); + public void populateProperties(Properties props) { props.setProperty("asyncDispatch", Boolean.toString(isAsyncDispatch())); + props.setProperty(Context.PROVIDER_URL, getBrokerURL()); props.setProperty("brokerURL", getBrokerURL()); - props.setProperty("clientID", getClientID()); + if (getClientID() != null) + props.setProperty("clientID", getClientID()); props.setProperty("copyMessageOnSend", Boolean.toString(isCopyMessageOnSend())); props.setProperty("disableTimeStampsByDefault", Boolean.toString(isDisableTimeStampsByDefault())); props.setProperty("objectMessageSerializationDefered", Boolean.toString(isObjectMessageSerializationDefered())); @@ -395,9 +392,7 @@ props.setProperty("useAsyncSend", Boolean.toString(isUseAsyncSend())); props.setProperty("useCompression", Boolean.toString(isUseCompression())); props.setProperty("useRetroactiveConsumer", Boolean.toString(isUseRetroactiveConsumer())); - props.setProperty("username", getUserName()); - - return props; + props.setProperty("userName", getUserName()); } public boolean isOnSendPrepareMessageBody() { @@ -431,28 +426,4 @@ public void setAsyncDispatch(boolean asyncDispatch) { this.asyncDispatch = asyncDispatch; } - - /** - * Retrieve a Reference for this instance to store in JNDI - * - * @return the built Reference - * @throws NamingException if error on building Reference - */ - public Reference getReference() throws NamingException { - Reference ref = new Reference(this.getClass().getName()); - - try { - Properties props = getProperties(); - for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) { - String key = (String) iter.nextElement(); - String value = props.getProperty(key); - javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value); - ref.add(addr); - } - } catch (Exception e) { - throw new NamingException(e.getMessage()); - } - return ref; - } - } Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/command/ActiveMQDestination.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/command/ActiveMQDestination.java?rev=369411&r1=369410&r2=369411&view=diff ============================================================================== --- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/command/ActiveMQDestination.java (original) +++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/command/ActiveMQDestination.java Mon Jan 16 01:58:02 2006 @@ -26,7 +26,6 @@ import java.util.Map; import java.util.StringTokenizer; import java.util.Properties; -import java.util.Enumeration; import javax.jms.Destination; import javax.jms.JMSException; @@ -34,17 +33,16 @@ import javax.jms.TemporaryQueue; import javax.jms.TemporaryTopic; import javax.jms.Topic; -import javax.naming.Reference; -import javax.naming.NamingException; -import javax.naming.Referenceable; import org.apache.activemq.util.URISupport; +import org.apache.activemq.util.IntrospectionSupport; +import org.apache.activemq.jndi.JNDIBaseStorable; /** * @openwire:marshaller * @version $Revision: 1.10 $ */ -abstract public class ActiveMQDestination implements DataStructure, Destination, Externalizable, Comparable, Referenceable { +abstract public class ActiveMQDestination extends JNDIBaseStorable implements DataStructure, Destination, Externalizable, Comparable { private static final long serialVersionUID = -3885260014960795889L; @@ -335,43 +333,15 @@ return false; } - public Properties getProperties() { - Properties props = new Properties(); - - props.setProperty("composite", Boolean.toString(isComposite())); - props.setProperty("destinationType", Byte.toString(getDestinationType())); - props.setProperty("destinationTypeAsString", getDestinationTypeAsString()); - props.setProperty("marshallAware", Boolean.toString(isMarshallAware())); - props.setProperty("physicalName", getPhysicalName()); - props.setProperty("qualifiedName", getQualifiedName()); - props.setProperty("qualifiedPrefix", getQualifiedPrefix()); - props.setProperty("queue", Boolean.toString(isQueue())); - props.setProperty("temporary", Boolean.toString(isTemporary())); - props.setProperty("topic", Boolean.toString(isTopic())); + public void buildFromProperties(Properties properties) { + if (properties == null) { + properties = new Properties(); + } - return props; + IntrospectionSupport.setProperties(this, properties); } - /** - * Retrieve a Reference for this instance to store in JNDI - * - * @return the built Reference - * @throws javax.naming.NamingException if error on building Reference - */ - public Reference getReference() throws NamingException { - Reference ref = new Reference(this.getClass().getName()); - - try { - Properties props = getProperties(); - for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) { - String key = (String) iter.nextElement(); - String value = props.getProperty(key); - javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value); - ref.add(addr); - } - } catch (Exception e) { - throw new NamingException(e.getMessage()); - } - return ref; + public void populateProperties(Properties props) { + props.setProperty("physicalName", getPhysicalName()); } } Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIBaseStorable.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIBaseStorable.java?rev=369411&view=auto ============================================================================== --- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIBaseStorable.java (added) +++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIBaseStorable.java Mon Jan 16 01:58:02 2006 @@ -0,0 +1,83 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.jndi; + +import javax.naming.NamingException; +import javax.naming.Reference; +import java.util.Properties; + +/** + * Faciliates objects to be stored in JNDI as properties + */ + +public abstract class JNDIBaseStorable implements JNDIStorableInterface { + private Properties properties = null; + + + /** + * Set the properties that will represent the instance in JNDI + * + * @param props + */ + protected abstract void buildFromProperties(Properties props); + + /** + * Initialize the instance from properties stored in JNDI + * + * @param props + */ + + protected abstract void populateProperties(Properties props); + + /** + * set the properties for this instance as retrieved from JNDI + * + * @param props + */ + + public synchronized void setProperties(Properties props) { + this.properties = props; + buildFromProperties(props); + } + + /** + * Get the properties from this instance for storing in JNDI + * + * @return the properties + */ + + public synchronized Properties getProperties() { + if (this.properties == null) { + this.properties = new Properties(); + } + populateProperties(this.properties); + return this.properties; + } + + + /** + * Retrive a Reference for this instance to store in JNDI + * + * @return the built Reference + * @throws NamingException if error on building Reference + */ + public Reference getReference() throws NamingException { + return JNDIReferenceFactory.createReference(this.getClass().getName(), this); + } + +} + Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIReferenceFactory.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIReferenceFactory.java?rev=369411&view=auto ============================================================================== --- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIReferenceFactory.java (added) +++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIReferenceFactory.java Mon Jan 16 01:58:02 2006 @@ -0,0 +1,137 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.jndi; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.naming.spi.ObjectFactory; +import javax.naming.Name; +import javax.naming.Context; +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import javax.naming.NamingException; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Enumeration; + +/** + * Converts objects implementing JNDIStorable into a property fields so they can + * be stored and regenerated from JNDI + */ +public class JNDIReferenceFactory implements ObjectFactory { + + static Log log = LogFactory.getLog(JNDIReferenceFactory.class); + + /** + * This will be called by a JNDIprovider when a Reference is retrieved from + * a JNDI store - and generates the orignal instance + * + * @param object the Reference object + * @param name the JNDI name + * @param nameCtx the context + * @param environment the environment settings used by JNDI + * @return the instance built from the Reference object + * @throws Exception if building the instance from Reference fails (usually class + * not found) + */ + public Object getObjectInstance(Object object, Name name, Context nameCtx, Hashtable environment) throws Exception { + Object result = null; + if (object instanceof Reference) { + Reference reference = (Reference) object; + + if (log.isTraceEnabled()) { + log.trace("Getting instance of " + reference.getClassName()); + } + + Class theClass = loadClass(this, reference.getClassName()); + if (JNDIStorableInterface.class.isAssignableFrom(theClass)) { + + JNDIStorableInterface store = (JNDIStorableInterface) theClass.newInstance(); + Properties properties = new Properties(); + for (Enumeration iter = reference.getAll(); iter.hasMoreElements();) { + + StringRefAddr addr = (StringRefAddr) iter.nextElement(); + properties.put(addr.getType(), (addr.getContent() == null) ? "" : addr.getContent()); + + } + store.setProperties(properties); + result = store; + } + } + else { + log.error("Object " + object + " is not a reference - cannot load"); + throw new RuntimeException("Object " + object + " is not a reference"); + } + return result; + } + + /** + * Create a Reference instance from a JNDIStorable object + * + * @param instanceClassName + * @param po + * @return @throws + * NamingException + */ + + public static Reference createReference(String instanceClassName, JNDIStorableInterface po) throws NamingException { + if (log.isTraceEnabled()) { + log.trace("Creating reference: " + instanceClassName + "," + po); + } + Reference result = new Reference(instanceClassName, JNDIReferenceFactory.class.getName(), null); + try { + Properties props = po.getProperties(); + for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) { + String key = (String) iter.nextElement(); + String value = props.getProperty(key); + javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value); + result.add(addr); + } + } + catch (Exception e) { + log.error(e.getMessage(), e); + throw new NamingException(e.getMessage()); + } + return result; + } + + /** + * Retrieve the class loader for a named class + * + * @param thisObj + * @param className + * @return @throws + * ClassNotFoundException + */ + + public static Class loadClass(Object thisObj, String className) throws ClassNotFoundException { + // tryu local ClassLoader first. + ClassLoader loader = thisObj.getClass().getClassLoader(); + Class theClass; + if (loader != null) { + theClass = loader.loadClass(className); + } + else { + // Will be null in jdk1.1.8 + // use default classLoader + theClass = Class.forName(className); + } + return theClass; + } + +} Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIStorableInterface.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIStorableInterface.java?rev=369411&view=auto ============================================================================== --- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIStorableInterface.java (added) +++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/jndi/JNDIStorableInterface.java Mon Jan 16 01:58:02 2006 @@ -0,0 +1,44 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.jndi; + +import javax.naming.Referenceable; +import java.util.Properties; + +/** + * Faciliates objects to be stored in JNDI as properties + */ + +public interface JNDIStorableInterface extends Referenceable { + + /** + * set the properties for this instance as retrieved from JNDI + * + * @param properties + */ + + public void setProperties(Properties properties); + + /** + * Get the properties from this instance for storing in JNDI + * + * @return + */ + + public Properties getProperties(); + +} Modified: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ActiveMQInitialContextFactoryTest.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ActiveMQInitialContextFactoryTest.java?rev=369411&r1=369410&r2=369411&view=diff ============================================================================== --- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ActiveMQInitialContextFactoryTest.java (original) +++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ActiveMQInitialContextFactoryTest.java Mon Jan 16 01:58:02 2006 @@ -38,7 +38,7 @@ InitialContext context = new InitialContext(); - //make sure contest is not null + //make sure context is not null assertTrue("Created context", context != null); Object topicDestination = context.lookup("MyTopic"); Added: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ObjectFactoryTest.java URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ObjectFactoryTest.java?rev=369411&view=auto ============================================================================== --- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ObjectFactoryTest.java (added) +++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/ObjectFactoryTest.java Mon Jan 16 01:58:02 2006 @@ -0,0 +1,84 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.jndi; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.CombinationTestSupport; +import org.apache.activemq.command.ActiveMQDestination; +import org.apache.activemq.command.ActiveMQQueue; + +import javax.naming.Reference; + +public class ObjectFactoryTest extends CombinationTestSupport { + public void testConnectionFactory() throws Exception { + // Create sample connection factory + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(); + factory.setAsyncDispatch(false); + factory.setBrokerURL("vm://test"); + factory.setClientID("test"); + factory.setCopyMessageOnSend(false); + factory.setDisableTimeStampsByDefault(true); + factory.setObjectMessageSerializationDefered(true); + factory.setOnSendPrepareMessageBody(false); + factory.setOptimizedMessageDispatch(false); + factory.setPassword("pass"); + factory.setUseAsyncSend(true); + factory.setUseCompression(true); + factory.setUseRetroactiveConsumer(true); + factory.setUserName("user"); + + // Create reference + Reference ref = JNDIReferenceFactory.createReference(factory.getClass().getName(), factory); + + // Get object created based on reference + ActiveMQConnectionFactory temp; + JNDIReferenceFactory refFactory = new JNDIReferenceFactory(); + temp = (ActiveMQConnectionFactory)refFactory.getObjectInstance(ref, null, null, null); + + // Check settings + assertEquals(factory.isAsyncDispatch(), temp.isAsyncDispatch()); + assertEquals(factory.getBrokerURL(), temp.getBrokerURL()); + assertEquals(factory.getClientID(), temp.getClientID()); + assertEquals(factory.isCopyMessageOnSend(), temp.isCopyMessageOnSend()); + assertEquals(factory.isDisableTimeStampsByDefault(), temp.isDisableTimeStampsByDefault()); + assertEquals(factory.isObjectMessageSerializationDefered(), temp.isObjectMessageSerializationDefered()); + assertEquals(factory.isOnSendPrepareMessageBody(), temp.isOnSendPrepareMessageBody()); + assertEquals(factory.isOptimizedMessageDispatch(), temp.isOptimizedMessageDispatch()); + assertEquals(factory.getPassword(), temp.getPassword()); + assertEquals(factory.isUseAsyncSend(), temp.isUseAsyncSend()); + assertEquals(factory.isUseCompression(), temp.isUseCompression()); + assertEquals(factory.isUseRetroactiveConsumer(), temp.isUseRetroactiveConsumer()); + assertEquals(factory.getUserName(), temp.getUserName()); + } + + public void testDestination() throws Exception { + // Create sample destination + ActiveMQDestination dest = new ActiveMQQueue(); + dest.setPhysicalName("TEST.FOO"); + + // Create reference + Reference ref = JNDIReferenceFactory.createReference(dest.getClass().getName(), dest); + + // Get object created based on reference + ActiveMQDestination temp; + JNDIReferenceFactory refFactory = new JNDIReferenceFactory(); + temp = (ActiveMQDestination)refFactory.getObjectInstance(ref, null, null, null); + + // Check settings + assertEquals(dest.getPhysicalName(), temp.getPhysicalName()); + } +}