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 */
017package org.apache.activemq.util;
018
019import java.util.Iterator;
020import java.util.Map;
021
022import org.springframework.beans.factory.FactoryBean;
023import org.springframework.beans.propertyeditors.ClassEditor;
024import org.springframework.util.Assert;
025
026import com.thoughtworks.xstream.XStream;
027import com.thoughtworks.xstream.converters.Converter;
028import com.thoughtworks.xstream.converters.ConverterMatcher;
029import com.thoughtworks.xstream.converters.SingleValueConverter;
030
031public 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}