【十一】geoserver源码&XStreamPersister

XStreamPersister类用于加载目录和配置类对象,首先该类定义了一个接口。如下所示,那么这里需要注意的是HierarchicalStreamWriter是一个结构输出流,MarshallingContext是序列化上下文信息。具体的将还会在该类的其他函数与类中有使用。
    private boolean unwrapNulls = true;

    /** Callback interface or xstream persister. */
    public static class Callback {
        /** Return the CatalogInfo object being modified by the current request */
        protected CatalogInfo getCatalogObject() {
            return null;
        }
        /** Return the ServiceInfo object being modified by the current request */
        protected ServiceInfo getServiceObject() {
            return null;
        }
        /** Return the class of the object being acted upon by the current request */
        protected Class<? extends Info> getObjectClass() {
            return null;
        }

        protected void postEncodeWorkspace(
                WorkspaceInfo ws, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeNamespace(
                NamespaceInfo ns, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeDataStore(
                DataStoreInfo ds, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeCoverageStore(
                CoverageStoreInfo ds,
                HierarchicalStreamWriter writer,
                MarshallingContext context) {}

        protected void postEncodeFeatureType(
                FeatureTypeInfo ds, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeWMSLayer(
                WMSLayerInfo ds, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeWMTSLayer(
                WMTSLayerInfo ds, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeCoverage(
                CoverageInfo ds, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeLayer(
                LayerInfo ls, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeLayerGroup(
                LayerGroupInfo ls, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeReference(
                Object obj,
                String ref,
                String prefix,
                HierarchicalStreamWriter writer,
                MarshallingContext context) {}

        protected void postEncodeWMSStore(
                WMSStoreInfo store, HierarchicalStreamWriter writer, MarshallingContext context) {}

        protected void postEncodeWMTSStore(
                WMTSStoreInfo store, HierarchicalStreamWriter writer, MarshallingContext context) {}
    }

我们先来看一下该类的一些属性。

    /** logging instance */
    static Logger LOGGER = Logging.getLogger("org.geoserver");

    /** internal xstream instance */
    XStream xs;

    /** GeoServer reference used to resolve references to gloal from services */
    GeoServer geoserver;

    /** Catalog reference, used to resolve references to stores, workspaces + namespaces */
    Catalog catalog;

    /** Callback instance. */
    Callback callback;

    /** Flag controlling how references to objects are encoded. */
    boolean referenceByName = false;

    /** The type map used in {@link BreifMapConverter} to handle complex objects */
    Map<String, Class<?>> forwardBreifMap = new HashMap<String, Class<?>>();

    Map<Class<?>, String> backwardBreifMap = new HashMap<Class<?>, String>();

    private Level forceLevel = LOGGER.getLevel() == null ? Level.INFO : LOGGER.getLevel();

    /** Flag controlling whether the persister should perform encryption on password fields */
    boolean encryptPasswordFields = true;

接着是在构造函数中的Init方法。

   /**
     * Sets null handling in proxy objects. Defaults to unwrap. If set to false, proxy object are
     * not transformed to nulls.
     */
    public void setUnwrapNulls(boolean unwrapNulls) {
        this.unwrapNulls = unwrapNulls;
    }

    protected void init(XStream xs) {
        // Default implementations
        initImplementationDefaults(xs);

        // ignore unkonwn fields, this should help using data dirs that has new config elements
        // with older versions of GeoServer
        xs.ignoreUnknownElements();

        // Aliases
        xs.alias("global", GeoServerInfo.class);
        xs.alias("settings", SettingsInfo.class);
        xs.alias("logging", LoggingInfo.class);
        xs.alias("jai", JAIInfo.class);
        xs.alias("coverageAccess", CoverageAccessInfo.class);
        xs.alias("catalog", Catalog.class);
        xs.alias("namespace", NamespaceInfo.class);
        xs.alias("workspace", WorkspaceInfo.class);
        xs.alias("dataStore", DataStoreInfo.class);
        xs.alias("wmsStore", WMSStoreInfo.class);
        xs.alias("wmtsStore", WMTSStoreInfo.class);
        xs.alias("coverageStore", CoverageStoreInfo.class);
        xs.alias("style", StyleInfo.class);
        xs.alias("legend", LegendInfo.class);
        xs.alias("featureType", FeatureTypeInfo.class);
        xs.alias("coverage", CoverageInfo.class);
        xs.alias("wmsLayer", WMSLayerInfo.class);
        xs.alias("wmtsLayer", WMTSLayerInfo.class);
        xs.alias("coverageDimension", CoverageDimensionInfo.class);
        xs.alias("coverageBand", CoverageBand.class);
        xs.alias("inputCoverageBand", InputCoverageBand.class);
        xs.alias("metadataLink", MetadataLinkInfo.class);
        xs.alias("dataLink", DataLinkInfo.class);
        xs.alias("attribute", AttributeTypeInfo.class);
        xs.alias("layer", LayerInfo.class);
        xs.alias("layerGroup", LayerGroupInfo.class);
        xs.alias("published", PublishedInfo.class);
        xs.alias("gridGeometry", GridGeometry2D.class);
        xs.alias("projected", DefaultProjectedCRS.class);
        xs.alias("attribution", AttributionInfo.class);
        xs.aliasField("abstract", ResourceInfoImpl.class, "_abstract");
        xs.alias("AuthorityURL", AuthorityURLInfo.class);
        xs.alias("Identifier", LayerIdentifierInfo.class);

        // GeoServerInfo
        xs.omitField(impl(GeoServerInfo.class), "clientProperties");
        xs.omitField(impl(GeoServerInfo.class), "geoServer");
        xs.registerLocalConverter(
                impl(GeoServerInfo.class), "metadata", new MetadataMapConverter());

        // ServiceInfo
        xs.omitField(impl(ServiceInfo.class), "clientProperties");
        xs.omitField(impl(ServiceInfo.class), "geoServer");
        xs.registerLocalConverter(
                impl(ServiceInfo.class), "workspace", new ReferenceConverter(WorkspaceInfo.class));
        xs.registerLocalConverter(impl(ServiceInfo.class), "metadata", new MetadataMapConverter());
        xs.registerLocalConverter(impl(ServiceInfo.class), "keywords", new KeywordListConverter());

        // Catalog
        xs.omitField(impl(Catalog.class), "resourcePool");
        xs.omitField(impl(Catalog.class), "resourceLoader");
        xs.omitField(impl(Catalog.class), "listeners");
        xs.omitField(impl(Catalog.class), "LOGGER");

        xs.omitField(impl(DefaultCatalogFacade.class), "catalog");
        xs.omitField(impl(DefaultCatalogFacade.class), "resources");
        xs.omitField(impl(DefaultCatalogFacade.class), "layers");
        xs.omitField(impl(DefaultCatalogFacade.class), "maps");
        xs.omitField(impl(DefaultCatalogFacade.class), "layerGroups");

        xs.registerLocalConverter(
                DefaultCatalogFacade.class, "stores", new StoreMultiValueMapConverter());
        xs.registerLocalConverter(
                DefaultCatalogFacade.class, "namespaces", new SpaceMapConverter("namespace"));
        xs.registerLocalConverter(
                DefaultCatalogFacade.class, "workspaces", new SpaceMapConverter("workspace"));

        // WorkspaceInfo
        xs.omitField(impl(WorkspaceInfo.class), "_default");
        xs.registerLocalConverter(
                impl(WorkspaceInfo.class), "metadata", new MetadataMapConverter());

        // NamespaceInfo
        xs.omitField(impl(NamespaceInfo.class), "catalog");
        xs.omitField(impl(NamespaceInfo.class), "_default");
        xs.registerLocalConverter(
                impl(NamespaceInfo.class), "metadata", new MetadataMapConverter());

        // StoreInfo
        xs.omitField(impl(StoreInfo.class), "catalog");
        xs.omitField(impl(StoreInfo.class), "error");
        // xs.omitField(StoreInfo.class), "workspace"); //handled by StoreInfoConverter
        xs.registerLocalConverter(
                impl(StoreInfo.class), "workspace", new ReferenceConverter(WorkspaceInfo.class));
        xs.registerLocalConverter(
                impl(StoreInfo.class), "connectionParameters", new BreifMapConverter());
        xs.registerLocalConverter(impl(StoreInfo.class), "metadata", new MetadataMapConverter());
        xs.registerLocalConverter(
                impl(WMSStoreInfo.class), "password", new EncryptedFieldConverter());
        xs.registerLocalConverter(
                impl(WMTSStoreInfo.class), "password", new EncryptedFieldConverter());

        // StyleInfo
        xs.omitField(impl(StyleInfo.class), "catalog");
        xs.registerLocalConverter(
                impl(StyleInfo.class), "workspace", new ReferenceConverter(WorkspaceInfo.class));
        xs.registerLocalConverter(impl(StyleInfo.class), "metadata", new MetadataMapConverter());

        // ResourceInfo
        xs.omitField(impl(ResourceInfo.class), "catalog");
        xs.omitField(impl(ResourceInfo.class), "crs");
        xs.registerLocalConverter(impl(ResourceInfo.class), "nativeCRS", new CRSConverter());
        xs.registerLocalConverter(
                impl(ResourceInfo.class), "store", new ReferenceConverter(StoreInfo.class));
        xs.registerLocalConverter(
                impl(ResourceInfo.class), "namespace", new ReferenceConverter(NamespaceInfo.class));
        xs.registerLocalConverter(impl(ResourceInfo.class), "metadata", new MetadataMapConverter());
        xs.registerLocalConverter(impl(ResourceInfo.class), "keywords", new KeywordListConverter());

        // FeatureTypeInfo
        PackageAliasingMapper bindingAliasingMapper =
                new OneWayPackageAliasingMapper(
                        new DefaultMapper(new ClassLoaderReference(xs.getClassLoader())));
        // For compatibility with JTS 1.15 and older bindings
        bindingAliasingMapper.addPackageAlias(
                "com.vividsolutions.jts.geom", "org.locationtech.jts.geom");

        xs.registerLocalConverter(
                impl(AttributeTypeInfo.class),
                "binding",
                (SingleValueConverter)
                        new SingleValueConverterWrapper(
                                new JavaClassConverter(bindingAliasingMapper) {}));

        // CoverageInfo
        xs.registerLocalConverter(
                impl(CoverageInfo.class),
                "supportedFormats",
                new LaxCollectionConverter(xs.getMapper()));
        xs.registerLocalConverter(
                impl(CoverageInfo.class), "requestSRS", new LaxCollectionConverter(xs.getMapper()));
        xs.registerLocalConverter(
                impl(CoverageInfo.class),
                "responseSRS",
                new LaxCollectionConverter(xs.getMapper()));
        xs.registerLocalConverter(
                impl(CoverageInfo.class),
                "interpolationMethods",
                new LaxCollectionConverter(xs.getMapper()));
        xs.registerLocalConverter(
                impl(CoverageInfo.class), "dimensions", new LaxCollectionConverter(xs.getMapper()));

        // CoverageDimensionInfo
        xs.registerLocalConverter(
                impl(CoverageDimensionInfo.class), "range", new NumberRangeConverter());

        // AttributeTypeInfo
        xs.omitField(impl(AttributeTypeInfo.class), "featureType");
        xs.omitField(impl(AttributeTypeInfo.class), "attribute");

        // LayerInfo
        // xs.omitField( LayerInfo.class), "resource");
        xs.registerLocalConverter(
                impl(LayerInfo.class), "resource", new ReferenceConverter(ResourceInfo.class));
        xs.registerLocalConverter(
                impl(LayerInfo.class), "defaultStyle", new ReferenceConverter(StyleInfo.class));
        xs.registerLocalConverter(
                impl(LayerInfo.class), "styles", new ReferenceCollectionConverter(StyleInfo.class));
        xs.registerLocalConverter(impl(LayerInfo.class), "metadata", new MetadataMapConverter());

        // LayerGroupInfo
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class),
                "workspace",
                new ReferenceConverter(WorkspaceInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class), "rootLayer", new ReferenceConverter(LayerInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class),
                "rootLayerStyle",
                new ReferenceConverter(StyleInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class),
                "layers",
                new ReferenceCollectionConverter(LayerInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class),
                "publishables",
                new ReferenceCollectionConverter(
                        PublishedInfo.class, LayerInfo.class, LayerGroupInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class),
                "styles",
                new ReferenceCollectionConverter(StyleInfo.class));
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class), "metadata", new MetadataMapConverter());
        xs.registerLocalConverter(
                impl(LayerGroupInfo.class), "keywords", new KeywordListConverter());

        // ReferencedEnvelope
        xs.registerLocalConverter(ReferencedEnvelope.class, "crs", new SRSConverter());
        xs.registerLocalConverter(GeneralEnvelope.class, "crs", new SRSConverter());

        // ServiceInfo
        xs.registerConverter(new ServiceInfoConverter());
        xs.omitField(impl(ServiceInfo.class), "geoServer");

        // Converters
        xs.registerConverter(new SpaceInfoConverter());
        xs.registerConverter(new StoreInfoConverter());
        xs.registerConverter(new ResourceInfoConverter());
        xs.registerConverter(new FeatureTypeInfoConverter());
        xs.registerConverter(new CoverageInfoConverter());
        xs.registerConverter(new LayerInfoConverter());
        xs.registerConverter(new LayerGroupInfoConverter());
        xs.registerConverter(new GridGeometry2DConverter());
        xs.registerConverter(new ProxyCollectionConverter(xs.getMapper()));
        xs.registerConverter(new VirtualTableConverter());
        xs.registerConverter(new KeywordInfoConverter());
        xs.registerConverter(new SettingsInfoConverter());
        xs.registerConverter(new WMSLayerInfoConverter());
        // this should have been a metadata map too, but was not registered as such and got a plain
        // map converter. Switched to SettingsTolerantMapConverter to make it work when plugins get
        // removed and leave configuration that cannot be parsed anymore in there
        xs.registerLocalConverter(
                impl(SettingsInfo.class),
                "metadata",
                new SettingsTolerantMapConverter(xs.getMapper(), MetadataMap.class));
        xs.registerConverter(new MeasureConverter());
        xs.registerConverter(new MultimapConverter(xs.getMapper()));

        // register Virtual structure handling
        registerBreifMapComplexType("virtualTable", VirtualTable.class);
        registerBreifMapComplexType("coverageView", CoverageView.class);
        registerBreifMapComplexType("dimensionInfo", DimensionInfoImpl.class);

        callback = new Callback();

        // setup white list of accepted classes
        xs.allowTypeHierarchy(Info.class);
        xs.allowTypeHierarchy(Multimap.class);
        xs.allowTypeHierarchy(JAIInfo.class);
        xs.allowTypes(new Class[] {DynamicProxyMapper.DynamicProxy.class});
        xs.allowTypes(new String[] {"java.util.Collections$SingletonList"});
        xs.allowTypesByWildcard(new String[] {"org.geoserver.catalog.**"});
        xs.allowTypesByWildcard(new String[] {"org.geoserver.security.**"});
    }

那么这里需要注意的是xs.alias("global", GeoServerInfo.class),xs.omitField(impl(ServiceInfo.class), "clientProperties"),xs.registerLocalConverter(impl(ServiceInfo.class), "keywords", new KeywordListConverter());分别为别名设置,属性忽略,设置转换器。那么这里还需要注意几个函数,一个是加载,另外一个是保存函数,这些函数后面都将会使用得到。

    /**
     * Saves an object to persistence.
     *
     * @param obj The object to save.
     * @param out The stream to save the object to.
     */
    public void save(Object obj, OutputStream out) throws IOException {
        // unwrap dynamic proxies
        Object unwrapped = unwrapProxies(obj);
        xs.toXML(unwrapped, new OutputStreamWriter(out, "UTF-8"));
    }

    /**
     * Unwraps any proxies around the object.
     *
     * <p>If the object is not being proxied it is passed back.
     */
    public static Object unwrapProxies(Object obj) {
        obj = SecureCatalogImpl.unwrap(obj);
        obj = GeoServerImpl.unwrap(obj);
        obj = CatalogImpl.unwrap(obj);
        return obj;
    }

    /**
     * Loads an object from peristence.
     *
     * @param in The input stream to read the object from.
     * @param clazz The class of the expected object.
     */
    public <T> T load(InputStream in, Class<T> clazz) throws IOException {
        T obj = clazz.cast(xs.fromXML(in));

        // call resolve() to ensure that any references created during loading
        // get resolved to actual objects, for instance for links from datastores
        // to workspaces
        if (obj instanceof CatalogImpl) {
            ((CatalogImpl) obj).resolve();
        }

        return obj;
    }

    /**
     * Builds a converter that will marshal/unmarshal the target class by reference, that is, by
     * storing the object id as opposed to fully serializing it
     */
    public ReferenceConverter buildReferenceConverter(Class clazz) {
        return new ReferenceConverter(clazz);
    }

    /**
     * Same as {@link #buildReferenceConverter(Class)}, but works against a collection of objects
     */
    public ReferenceCollectionConverter buildReferenceCollectionConverter(Class clazz) {
        return new ReferenceCollectionConverter(clazz);
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值