【十一】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 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> forwardBreifMap = new HashMap>();

    Map, String> backwardBreifMap = new HashMap, 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.
     *
     * 

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 load(InputStream in, Class 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); }

 

你可能感兴趣的:(JAVA,geoserver)