001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.activemq.util;
018    
019    import java.util.Iterator;
020    import java.util.Map;
021    
022    import org.springframework.beans.factory.FactoryBean;
023    import org.springframework.beans.propertyeditors.ClassEditor;
024    import org.springframework.util.Assert;
025    
026    import com.thoughtworks.xstream.XStream;
027    import com.thoughtworks.xstream.converters.Converter;
028    import com.thoughtworks.xstream.converters.ConverterMatcher;
029    import com.thoughtworks.xstream.converters.SingleValueConverter;
030    
031    public class XStreamFactoryBean implements FactoryBean {
032    
033            XStream xstream = new XStream();
034            
035        /**
036         * Sets the <code>Converters</code> or <code>SingleValueConverters</code> to be registered with the
037         * <code>XStream</code> instance.
038         *
039         * @see Converter
040         * @see SingleValueConverter
041         */
042        public void setConverters(ConverterMatcher[] converters) {
043            for (int i = 0; i < converters.length; i++) {
044                if (converters[i] instanceof Converter) {
045                    xstream.registerConverter((Converter) converters[i], i);
046                }
047                else if (converters[i] instanceof SingleValueConverter) {
048                    xstream.registerConverter((SingleValueConverter) converters[i], i);
049                }
050                else {
051                    throw new IllegalArgumentException("Invalid ConverterMatcher [" + converters[i] + "]");
052                }
053            }
054        }
055    
056        /**
057         * Set a alias/type map, consisting of string aliases mapped to <code>Class</code> instances (or Strings to be
058         * converted to <code>Class</code> instances).
059         *
060         * @see org.springframework.beans.propertyeditors.ClassEditor
061         */
062        public void setAliases(Map aliases) {
063            for (Iterator iterator = aliases.entrySet().iterator(); iterator.hasNext();) {
064                Map.Entry entry = (Map.Entry) iterator.next();
065                // Check whether we need to convert from String to Class.
066                Class type;
067                if (entry.getValue() instanceof Class) {
068                    type = (Class) entry.getValue();
069                }
070                else {
071                    ClassEditor editor = new ClassEditor();
072                    editor.setAsText(String.valueOf(entry.getValue()));
073                    type = (Class) editor.getValue();
074                }
075                xstream.alias((String) entry.getKey(), type);
076            }
077        }   
078        
079        /**
080         * Sets the XStream mode.
081         *
082         * @see XStream#XPATH_REFERENCES
083         * @see XStream#ID_REFERENCES
084         * @see XStream#NO_REFERENCES
085         */
086        public void setMode(int mode) {
087            xstream.setMode(mode);
088        }    
089        
090        /**
091         * Sets the classes, for which mappings will be read from class-level JDK 1.5+ annotation metadata.
092         *
093         * @see Annotations#configureAliases(XStream, Class[])
094         */
095        public void setAnnotatedClass(Class<?> annotatedClass) {
096            Assert.notNull(annotatedClass, "'annotatedClass' must not be null");
097            xstream.processAnnotations(annotatedClass);
098        }
099    
100        /**
101         * Sets annotated classes, for which aliases will be read from class-level JDK 1.5+ annotation metadata.
102         *
103         * @see Annotations#configureAliases(XStream, Class[])
104         */
105        public void setAnnotatedClasses(Class<?>[] annotatedClasses) {
106            Assert.notEmpty(annotatedClasses, "'annotatedClasses' must not be empty");
107            xstream.processAnnotations(annotatedClasses);
108        }    
109            
110            public Object getObject() throws Exception {
111                    return xstream;
112            }
113    
114            public Class getObjectType() {
115                    return XStream.class;
116            }
117    
118            public boolean isSingleton() {
119                    return true;
120            }
121    
122    }