All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.xml.xstream.XStreamBuilder Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.3.0
Show newest version
/*
 * Copyright (C) 2008 feilong
 *
 * 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 com.feilong.xml.xstream;

import static com.feilong.core.CharsetType.UTF8;
import static com.feilong.core.Validator.isNotNullOrEmpty;
import static com.feilong.core.Validator.isNullOrEmpty;

import java.io.Writer;
import java.util.List;
import java.util.Map;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

/**
 * 基于 {@link XStreamConfig} 构造 {@link XStream}.
 *
 * @author feilong
 * @since 1.10.7
 */
public final class XStreamBuilder{

    /** xstream 默认用的是 xppDriver 需要依赖 xmlpull:xmlpull jar. */
    private static final HierarchicalStreamDriver DEFAULT_NONAMECODER               = new DomDriver(UTF8, new NoNameCoder());

    /** xstream 默认用的是 xppDriver 需要依赖 xmlpull:xmlpull jar. */
    private static final HierarchicalStreamDriver DEFAULT_NONAMECODER_COMPACTWRITER = new DomDriver(UTF8, new NoNameCoder()){

                                                                                        @Override
                                                                                        public HierarchicalStreamWriter createWriter(
                                                                                                        Writer out){
                                                                                            return new CompactWriter(out, getNameCoder());
                                                                                        }
                                                                                    };
    //---------------------------------------------------------------

    /** Don't let anyone instantiate this class. */
    private XStreamBuilder(){
        //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
        //see 《Effective Java》 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    //---------------------------------------------------------------

    /**
     * 基于 {@link XStreamConfig} 构造 {@link XStream}.
     *
     * @param xStreamConfig
     *            the xstream config
     * @return the x stream
     */
    public static XStream build(XStreamConfig xStreamConfig){
        XStream xstream = buildDefault(xStreamConfig);
        if (isNullOrEmpty(xStreamConfig)){
            return xstream;
        }

        //---------------------------------------------------------------
        doAlias(xStreamConfig, xstream);

        doAddImplicitCollection(xStreamConfig, xstream);

        doWithConverter(xStreamConfig, xstream);

        doProcessAnnotationsTypes(xStreamConfig, xstream);

        doDefaultImplementationMap(xStreamConfig, xstream);

        // 属性重命名
        // xstream.aliasField(alias, definedIn, fieldName)
        // 包重命名
        // xstream.aliasPackage(name, pkgName)
        return xstream;
    }

    //---------------------------------------------------------------

    /**
     * Do default implementation map.
     *
     * @param xStreamConfig
     *            the x stream config
     * @param xstream
     *            the xstream
     * @since 1.10.7
     */
    private static void doDefaultImplementationMap(XStreamConfig xStreamConfig,XStream xstream){
        Map, Class> defaultImplementationMap = xStreamConfig.getDefaultImplementationMap();
        if (isNotNullOrEmpty(defaultImplementationMap)){

            for (Map.Entry, Class> entry : defaultImplementationMap.entrySet()){
                Class defaultImplementation = entry.getKey();
                Class ofType = entry.getValue();
                //Associate a default implementation of a class with an object.
                //Whenever XStream encounters an instance of this type, it will use the default implementation instead.
                //For example, java.util.ArrayList is the default implementation of java.util.List.
                xstream.addDefaultImplementation(defaultImplementation, ofType);
            }
        }
    }

    //---------------------------------------------------------------

    /**
     * Do with converter.
     *
     * @param xStreamConfig
     *            the x stream config
     * @param xstream
     *            the xstream
     */
    private static void doWithConverter(XStreamConfig xStreamConfig,XStream xstream){
        List converterList = xStreamConfig.getConverterList();
        if (isNotNullOrEmpty(converterList)){
            for (Converter converter : converterList){
                xstream.registerConverter(converter);
            }
        }
    }

    //---------------------------------------------------------------

    /**
     * Builds the default.
     *
     * @param xStreamConfig
     *            the x stream config
     * @return the x stream
     */
    private static XStream buildDefault(XStreamConfig xStreamConfig){
        XStream xstream = new XStream(buildHierarchicalStreamDriver(xStreamConfig));
        //since 1.4.7
        xstream.addPermission(AnyTypePermission.ANY);

        //自动探测注解
        xstream.autodetectAnnotations(true);

        //忽略未知元素 Ignore all unknown elements.
        xstream.ignoreUnknownElements();

        //避免出现以下警告:Security framework of XStream not initialized, XStream is probably vulnerable
        //since 1.14.3
        //XStream.setupDefaultSecurity(xstream)
        return xstream;
    }

    /**
     * Do process annotations types.
     *
     * @param xStreamConfig
     *            the x stream config
     * @param xstream
     *            the xstream
     */
    private static void doProcessAnnotationsTypes(XStreamConfig xStreamConfig,XStream xstream){
        Class[] processAnnotationsTypes = xStreamConfig.getProcessAnnotationsTypes();

        if (isNotNullOrEmpty(processAnnotationsTypes)){
            xstream.processAnnotations(processAnnotationsTypes);
        }
    }

    //---------------------------------------------------------------

    /**
     * Builds the hierarchical stream driver.
     *
     * @param xStreamConfig
     *            the x stream config
     * @return the hierarchical stream driver
     */
    private static HierarchicalStreamDriver buildHierarchicalStreamDriver(XStreamConfig xStreamConfig){
        return defaultDriver(xStreamConfig);
    }

    /**
     * Default driver.
     *
     * @param xStreamConfig
     *            the x stream config
     * @return the xpp driver
     */
    private static HierarchicalStreamDriver defaultDriver(XStreamConfig xStreamConfig){
        if (null == xStreamConfig){
            return DEFAULT_NONAMECODER;
        }
        return xStreamConfig.getIsPrettyPrint() ? DEFAULT_NONAMECODER : DEFAULT_NONAMECODER_COMPACTWRITER;
    }

    //---------------------------------------------------------------

    /**
     * 设置 add implicit collection.
     *
     * @param xStreamConfig
     *            the x stream config
     * @param xstream
     *            the xstream
     */
    private static void doAddImplicitCollection(XStreamConfig xStreamConfig,XStream xstream){
        Map> implicitCollectionMap = xStreamConfig.getImplicitCollectionMap();
        if (isNullOrEmpty(implicitCollectionMap)){
            return;
        }

        //---------------------------------------------------------------
        for (Map.Entry> entry : implicitCollectionMap.entrySet()){
            String key = entry.getKey();
            Class value = entry.getValue();
            xstream.addImplicitCollection(value, key);
        }
    }

    //---------------------------------------------------------------

    /**
     * 设置 alias.
     *
     * @param xStreamConfig
     *            the x stream config
     * @param xstream
     *            the xstream
     */
    private static void doAlias(XStreamConfig xStreamConfig,XStream xstream){
        Map> aliasMap = xStreamConfig.getAliasMap();
        if (isNullOrEmpty(aliasMap)){
            return;
        }

        //---------------------------------------------------------------
        for (Map.Entry> entry : aliasMap.entrySet()){
            String key = entry.getKey();
            Class value = entry.getValue();
            // 类重命名
            xstream.alias(key, value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy