001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    
019    package org.activemq.io;
020    import java.io.DataInputStream;
021    import java.io.IOException;
022    
023    import javax.jms.JMSException;
024    
025    import org.activemq.io.impl.DefaultWireFormat;
026    import org.activemq.util.FactoryFinder;
027    
028    /**
029     * Represents a strategy of encoding packets on the wire or on disk using some kind of serialization or wire format.
030     * <p/>We use a default efficient format for Java to Java communication but other formats to other systems can be used,
031     * such as using simple text strings when talking to JavaScript or coming up with other formats for talking to C / C#
032     * languages or proprietary messaging systems we wish to interface with at the wire level etc.
033     * 
034     * @version $Revision: 1.1.1.1 $
035     */
036    public class WireFormatLoader {
037        private static FactoryFinder finder = new FactoryFinder("META-INF/services/org/activemq/io/");
038        private WireFormat preferedWireFormat;
039    
040        /**
041         * Default Constructor
042         */
043        public WireFormatLoader() {
044            this(new DefaultWireFormat());
045        }
046    
047        /**
048         * Construct WireFormatLoader with the prefered WireFormat
049         * 
050         * @param prefered
051         */
052        public WireFormatLoader(WireFormat prefered) {
053            this.preferedWireFormat = prefered;
054        }
055    
056        /**
057         * Create a wire format
058         * 
059         * @param dataIn
060         * @return the WireFormat
061         * @throws JMSException
062         * @throws IOException
063         */
064        public WireFormat getWireFormat(DataInputStream dataIn) throws JMSException, IOException {
065            WireFormat result = preferedWireFormat;
066            dataIn.mark(10);
067            int protocol = dataIn.read();
068            if (protocol == 128) {
069                //tis amqfast
070                result = WireFormatLoader.getWireFormat("amqpfast");
071            }
072            dataIn.reset();
073            return result;
074        }
075    
076        /**
077         * @return Returns the preferedWireFormat.
078         */
079        public WireFormat getPreferedWireFormat() {
080            return preferedWireFormat;
081        }
082    
083        /**
084         * @param preferedWireFormat The preferedWireFormat to set.
085         */
086        public void setPreferedWireFormat(WireFormat preferedWireFormat) {
087            this.preferedWireFormat = preferedWireFormat;
088        }
089    
090        /**
091         * load a WireFormat by name - e.g. 'default','amqpfast' etc.
092         * 
093         * @param format
094         * @return the wire format
095         * @throws JMSException
096         */
097        public static WireFormat getWireFormat(String format) throws JMSException {
098            try {
099                Object value = finder.newInstance(format);
100                if (value instanceof WireFormat) {
101                    return (WireFormat) value;
102                }
103                else {
104                    throw new JMSException(format + " is not a WireFormat: " + value);
105                }
106            }
107            catch (IllegalAccessException e) {
108                throw createJMSexception(format, e);
109            }
110            catch (InstantiationException e) {
111                throw createJMSexception(format, e);
112            }
113            catch (IOException e) {
114                throw createJMSexception(format, e);
115            }
116            catch (ClassNotFoundException e) {
117                throw createJMSexception(format, e);
118            }
119        }
120    
121        protected static JMSException createJMSexception(String protocol, Exception e) {
122            JMSException answer = new JMSException("Could not load protocol: " + protocol + ". Reason: " + e);
123            answer.setLinkedException(e);
124            return answer;
125        }
126    }