1 18 package org.apache.activemq.command; 19 20 import org.apache.activemq.jndi.JNDIBaseStorable; 21 import org.apache.activemq.util.IntrospectionSupport; 22 import org.apache.activemq.util.URISupport; 23 24 import javax.jms.Destination ; 25 import javax.jms.JMSException ; 26 import javax.jms.Queue ; 27 import javax.jms.TemporaryQueue ; 28 import javax.jms.TemporaryTopic ; 29 import javax.jms.Topic ; 30 import java.io.Externalizable ; 31 import java.io.IOException ; 32 import java.io.ObjectInput ; 33 import java.io.ObjectOutput ; 34 import java.net.URISyntaxException ; 35 import java.util.ArrayList ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.Properties ; 39 import java.util.StringTokenizer ; 40 41 45 abstract public class ActiveMQDestination extends JNDIBaseStorable implements DataStructure, Destination , Externalizable , Comparable { 46 47 private static final long serialVersionUID = -3885260014960795889L; 48 49 public static final String PATH_SEPERATOR = "."; 50 public static final char COMPOSITE_SEPERATOR = ','; 51 52 public static final byte QUEUE_TYPE = 0x01; 53 public static final byte TOPIC_TYPE = 0x02; 54 public static final byte TEMP_MASK = 0x04; 55 public static final byte TEMP_TOPIC_TYPE = TOPIC_TYPE | TEMP_MASK; 56 public static final byte TEMP_QUEUE_TYPE = QUEUE_TYPE | TEMP_MASK; 57 58 public static final String QUEUE_QUALIFIED_PREFIX = "queue://"; 59 public static final String TOPIC_QUALIFIED_PREFIX = "topic://"; 60 public static final String TEMP_QUEUE_QUALIFED_PREFIX= "temp-queue://"; 61 public static final String TEMP_TOPIC_QUALIFED_PREFIX = "temp-topic://"; 62 63 protected String physicalName; 64 65 transient protected ActiveMQDestination[] compositeDestinations; 66 transient protected String [] destinationPaths; 67 transient protected boolean isPattern; 68 transient protected int hashValue; 69 protected Map options; 70 71 72 static public ActiveMQDestination createDestination(String name, byte defaultType) { 75 76 if( name.startsWith(QUEUE_QUALIFIED_PREFIX) ) { 77 return new ActiveMQQueue(name.substring(QUEUE_QUALIFIED_PREFIX.length())); 78 } else if( name.startsWith(TOPIC_QUALIFIED_PREFIX) ) { 79 return new ActiveMQTopic(name.substring(TOPIC_QUALIFIED_PREFIX.length())); 80 } else if( name.startsWith(TEMP_QUEUE_QUALIFED_PREFIX) ) { 81 return new ActiveMQTempQueue(name.substring(TEMP_QUEUE_QUALIFED_PREFIX.length())); 82 } else if( name.startsWith(TEMP_TOPIC_QUALIFED_PREFIX) ) { 83 return new ActiveMQTempTopic(name.substring(TEMP_TOPIC_QUALIFED_PREFIX.length())); 84 } 85 86 switch(defaultType) { 87 case QUEUE_TYPE: 88 return new ActiveMQQueue(name); 89 case TOPIC_TYPE: 90 return new ActiveMQTopic(name); 91 case TEMP_QUEUE_TYPE: 92 return new ActiveMQTempQueue(name); 93 case TEMP_TOPIC_TYPE: 94 return new ActiveMQTempTopic(name); 95 default: 96 throw new IllegalArgumentException ("Invalid default destination type: "+defaultType); 97 } 98 } 99 100 public static ActiveMQDestination transform(Destination dest) throws JMSException { 101 if( dest == null ) 102 return null; 103 if( dest instanceof ActiveMQDestination ) 104 return (ActiveMQDestination) dest; 105 if( dest instanceof TemporaryQueue ) 106 return new ActiveMQTempQueue(((TemporaryQueue )dest).getQueueName()); 107 if( dest instanceof TemporaryTopic ) 108 return new ActiveMQTempTopic(((TemporaryTopic )dest).getTopicName()); 109 if( dest instanceof Queue ) 110 return new ActiveMQQueue(((Queue )dest).getQueueName()); 111 if( dest instanceof Topic ) 112 return new ActiveMQTopic(((Topic )dest).getTopicName()); 113 throw new JMSException ("Could not transform the destination into a ActiveMQ destination: "+dest); 114 } 115 116 public static int compare(ActiveMQDestination destination, ActiveMQDestination destination2) { 117 if (destination == destination2) { 118 return 0; 119 } 120 if (destination == null) { 121 return -1; 122 } 123 else if (destination2 == null) { 124 return 1; 125 } 126 else { 127 if (destination.isQueue() == destination2.isQueue()) { 128 return destination.getPhysicalName().compareTo(destination2.getPhysicalName()); 129 } 130 else { 131 return destination.isQueue() ? -1 : 1; 132 } 133 } 134 } 135 136 137 public ActiveMQDestination() { 138 } 139 140 protected ActiveMQDestination(String name) { 141 setPhysicalName(name); 142 } 143 144 public ActiveMQDestination(ActiveMQDestination composites[]) { 145 setCompositeDestinations(composites); 146 } 147 148 public int compareTo(Object that) { 149 if (that instanceof ActiveMQDestination) { 150 return compare(this, (ActiveMQDestination) that); 151 } 152 if (that == null) { 153 return 1; 154 } 155 else { 156 return getClass().getName().compareTo(that.getClass().getName()); 157 } 158 } 159 160 public boolean isComposite() { 161 return compositeDestinations!=null; 162 } 163 public ActiveMQDestination[] getCompositeDestinations() { 164 return compositeDestinations; 165 } 166 167 public void setCompositeDestinations(ActiveMQDestination[] destinations) { 168 this.compositeDestinations=destinations; 169 this.destinationPaths=null; 170 this.hashValue=0; 171 this.isPattern=false; 172 173 StringBuffer sb = new StringBuffer (); 174 for (int i = 0; i < destinations.length; i++) { 175 if( i!=0 ) 176 sb.append(COMPOSITE_SEPERATOR); 177 if( getDestinationType()==destinations[i].getDestinationType()) { 178 sb.append(destinations[i].getPhysicalName()); 179 } else { 180 sb.append(destinations[i].getQualifiedName()); 181 } 182 } 183 physicalName = sb.toString(); 184 } 185 186 public String getQualifiedName() { 187 if( isComposite() ) 188 return physicalName; 189 return getQualifiedPrefix()+physicalName; 190 } 191 192 abstract protected String getQualifiedPrefix(); 193 194 197 public String getPhysicalName() { 198 return physicalName; 199 } 200 201 public void setPhysicalName(String physicalName){ 202 final int len=physicalName.length(); 203 int p=-1; boolean composite=false; 205 for(int i=0;i<len;i++){ 206 char c=physicalName.charAt(i); 207 if(c=='?'){ 208 p=i; 209 break; 210 } 211 if(c==COMPOSITE_SEPERATOR){ 212 isPattern=false; 214 composite=true; 215 }else if(!composite&&(c=='*'||c=='>')){ 216 isPattern=true; 217 } 218 } 219 if(p>=0){ 221 String optstring=physicalName.substring(p+1); 222 physicalName=physicalName.substring(0,p); 223 try{ 224 options=URISupport.parseQuery(optstring); 225 }catch(URISyntaxException e){ 226 throw new IllegalArgumentException ("Invalid destination name: "+physicalName 227 +", it's options are not encoded properly: "+e); 228 } 229 } 230 this.physicalName=physicalName; 231 this.destinationPaths=null; 232 this.hashValue=0; 233 if(composite){ 234 ArrayList <String > l=new ArrayList <String >(); 236 StringTokenizer iter=new StringTokenizer (physicalName,""+COMPOSITE_SEPERATOR); 237 while(iter.hasMoreTokens()){ 238 String name=iter.nextToken().trim(); 239 if(name.length()==0) 240 continue; 241 l.add(name); 242 } 243 if(l.size()>1){ 244 compositeDestinations=new ActiveMQDestination[l.size()]; 245 int counter=0; 246 for (String dest:l) { 247 compositeDestinations[counter++]=createDestination(dest); 248 } 249 } 250 } 251 } 252 253 public ActiveMQDestination createDestination(String name) { 254 return createDestination(name, getDestinationType()); 255 } 256 public String [] getDestinationPaths() { 257 258 if( destinationPaths!=null ) 259 return destinationPaths; 260 261 ArrayList l = new ArrayList (); 262 StringTokenizer iter = new StringTokenizer (physicalName, PATH_SEPERATOR); 263 while (iter.hasMoreTokens()) { 264 String name = iter.nextToken().trim(); 265 if( name.length() == 0 ) 266 continue; 267 l.add(name); 268 } 269 270 destinationPaths = new String [l.size()]; 271 l.toArray(destinationPaths); 272 return destinationPaths; 273 } 274 275 abstract public byte getDestinationType(); 276 277 public boolean isQueue() { 278 return false; 279 } 280 281 public boolean isTopic() { 282 return false; 283 } 284 285 public boolean isTemporary() { 286 return false; 287 } 288 289 public boolean equals(Object o) { 290 if( this == o ) 291 return true; 292 if( o==null || getClass()!=o.getClass() ) 293 return false; 294 295 ActiveMQDestination d = (ActiveMQDestination) o; 296 return physicalName.equals(d.physicalName); 297 } 298 299 public int hashCode() { 300 if( hashValue==0 ) { 301 hashValue = physicalName.hashCode(); 302 } 303 return hashValue; 304 } 305 306 public String toString() { 307 return getQualifiedName(); 308 } 309 310 public void writeExternal(ObjectOutput out) throws IOException { 311 out.writeUTF(this.getPhysicalName()); 312 out.writeObject(options); 313 } 314 315 public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException { 316 this.setPhysicalName(in.readUTF()); 317 this.options = (Map ) in.readObject(); 318 } 319 320 public String getDestinationTypeAsString() { 321 switch(getDestinationType()) { 322 case QUEUE_TYPE: 323 return "Queue"; 324 case TOPIC_TYPE: 325 return "Topic"; 326 case TEMP_QUEUE_TYPE: 327 return "TempQueue"; 328 case TEMP_TOPIC_TYPE: 329 return "TempTopic"; 330 default: 331 throw new IllegalArgumentException ("Invalid destination type: "+getDestinationType()); 332 } 333 } 334 335 public Map getOptions() { 336 return options; 337 } 338 339 public boolean isMarshallAware() { 340 return false; 341 } 342 343 public void buildFromProperties(Properties properties) { 344 if (properties == null) { 345 properties = new Properties (); 346 } 347 348 IntrospectionSupport.setProperties(this, properties); 349 } 350 351 public void populateProperties(Properties props) { 352 props.setProperty("physicalName", getPhysicalName()); 353 } 354 355 public boolean isPattern() { 356 return isPattern; 357 } 358 } 359 | Popular Tags |