com.boundlessgeo.geoserver.bundle.BundleImporter.java Source code

Java tutorial

Introduction

Here is the source code for com.boundlessgeo.geoserver.bundle.BundleImporter.java

Source

/* (c) 2014 Boundless, http://boundlessgeo.com
 * This code is licensed under the GPL 2.0 license.
 */
package com.boundlessgeo.geoserver.bundle;

import org.apache.commons.io.FileUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.config.GeoServerDataDirectory;
import org.geoserver.config.util.XStreamPersister;
import org.geoserver.config.util.XStreamPersisterFactory;
import org.geoserver.data.util.IOUtils;
import org.geoserver.platform.GeoServerResourceLoader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Imports GeoServer config/data bundle.
 */
public class BundleImporter {

    static FileFilter DIRECTORY = new FileFilter() {
        @Override
        public boolean accept(File file) {
            return file.isDirectory();
        }
    };

    static FilenameFilter CONFIG_FILE = new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".xml") && !name.endsWith(".xml.xml");
        }
    };

    Catalog catalog;
    ImportOpts options;

    WorkspaceInfo workspace;
    NamespaceInfo namespace;

    Path root;
    GeoServerDataDirectory importDataDir;
    GeoServerDataDirectory targetDataDir;

    XStreamPersister xsp;

    public BundleImporter(Catalog catalog, ImportOpts options) throws IOException {
        this.catalog = catalog;
        this.options = options;
        workspace = options.workspace();
        namespace = catalog.getNamespaceByPrefix(workspace.getName());

        // temp directory to unpack
        root = Files.createTempDirectory(null);
        importDataDir = new GeoServerDataDirectory(new GeoServerResourceLoader(root.toFile()));
        targetDataDir = new GeoServerDataDirectory(catalog.getResourceLoader());

        // config deserializer
        xsp = new XStreamPersisterFactory().createXMLPersister();
        xsp.setExcludeIds();
        xsp.setReferenceByName(true);
        xsp.setCatalog(catalog);
    }

    public Path unzip(Path zip) throws IOException {
        try (InputStream in = new BufferedInputStream(new FileInputStream(zip.toFile()));) {
            IOUtils.decompress(in, root.toFile());
        }
        return root;
    }

    public void run() throws IOException {
        loadWorkspace(root.toFile());
        //        // workspaces
        //        File wsRoot = root.resolve("workspaces").toFile();
        //        for (File dir : wsRoot.listFiles(DIRECTORY)) {
        //            loadWorkspace(dir);
        //        }
    }

    void loadStyles(File styleDir) throws IOException {
        for (File f : styleDir.listFiles(CONFIG_FILE)) {
            StyleInfo s = depersist(f, StyleInfo.class);
            s.setWorkspace(workspace);

            //TODO: copy over sld file?
            catalog.add(s);
        }
    }

    void loadWorkspace(File wsDir) throws IOException {
        //        WorkspaceInfo ws = depersist(new File(wsDir, "workspace.xml"), WorkspaceInfo.class);
        //        catalog.add(ws);
        //
        //        NamespaceInfo ns = depersist(new File(wsDir, "namespace.xml"), NamespaceInfo.class);
        //        catalog.add(ns);

        // data directory
        File dataDir = new File(wsDir, "data");
        if (dataDir.exists()) {
            FileUtils.copyDirectory(dataDir, targetDataDir.get(workspace, "data").dir());
        }

        // styles
        File styleDir = new File(wsDir, "styles");
        if (styleDir.exists()) {
            loadStyles(styleDir);
        }

        //TODO: layer groups

        // stores
        for (File dir : wsDir.listFiles(DIRECTORY)) {
            loadStore(dir, wsDir);
        }
    }

    void loadStore(File storeDir, File wsDir) throws IOException {
        //TODO: wms store
        File file = new File(storeDir, "datastore.xml");
        if (!file.exists()) {
            file = new File(storeDir, "coveragestore.xml");
        }
        if (!file.exists()) {
            file = new File(storeDir, "store.xml");
        }
        if (!file.exists()) {
            return;
        }

        StoreInfo s = depersist(file, StoreInfo.class);
        s.setWorkspace(workspace);
        updateConnectionParams(s);
        catalog.add(s);

        for (File dir : storeDir.listFiles(DIRECTORY)) {
            loadResource(dir, s);
        }

    }

    void updateConnectionParams(StoreInfo s) {
        // update workspace relative paths
        // update namespace uri
        LinkedHashMap<String, Serializable> map = new LinkedHashMap<>();
        for (Map.Entry<String, Serializable> e : s.getConnectionParameters().entrySet()) {
            Serializable value = e.getValue();
            if (value instanceof String && value.toString().contains("%WORKSPACE%")) {
                value = value.toString().replace("%WORKSPACE%", "workspaces/" + workspace.getName());
            }
            if ("namespace".equalsIgnoreCase(e.getKey())) {
                value = namespace.getURI();
            }
            map.put(e.getKey(), value);
        }

        s.getConnectionParameters().clear();
        s.getConnectionParameters().putAll(map);
    }

    void loadResource(File resourceDir, StoreInfo s) throws IOException {
        // TODO: wms layer
        File file = new File(resourceDir, "featuretype.xml");
        if (!file.exists()) {
            file = new File(resourceDir, "coverage.xml");
        }
        if (!file.exists()) {
            file = new File(resourceDir, "resource.xml");
        }
        if (!file.exists()) {
            return;
        }

        ResourceInfo r = depersist(file, ResourceInfo.class);
        r.setStore(s);
        r.setNamespace(namespace);
        catalog.add(r);

        File layerFile = new File(resourceDir, "layer.xml");
        LayerInfo l = depersist(layerFile, LayerInfo.class);
        l.setResource(r);

        // have to do a bit more hacking to get the style to resolve properly since it's reference is
        // encoded by name, basically parse the layer.xml and pull out the name and resolve it
        // manually
        resolveStyles(l, layerFile);

        catalog.add(l);
    }

    void resolveStyles(LayerInfo l, File layerFile) throws IOException {
        Document doc = null;
        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(layerFile);
        } catch (Exception e) {
            throw new IOException(e);
        }

        if (l.getDefaultStyle() == null) {
            NodeList defaultStyles = doc.getDocumentElement().getElementsByTagName("defaultStyle");
            if (defaultStyles.getLength() > 0) {
                String styleName = pullStyleName((Element) defaultStyles.item(0));
                if (styleName != null) {
                    l.setDefaultStyle(catalog.getStyleByName(workspace, styleName));
                }
            }
        }

        NodeList styles = doc.getDocumentElement().getElementsByTagName("styles");
        if (styles.getLength() > 0) {
            l.getStyles().clear();
            for (int i = 0; i < styles.getLength(); i++) {
                Element e = (Element) styles.item(i);
                String styleName = pullStyleName(e);
                if (styleName != null) {
                    StyleInfo style = catalog.getStyleByName(workspace, styleName);
                    if (style != null) {
                        l.getStyles().add(style);
                    }
                }
            }
        }
    }

    String pullStyleName(Element e) {
        NodeList names = e.getElementsByTagName("name");
        if (names.getLength() > 0) {
            String styleName = names.item(0).getTextContent();
            //Strip off workspace
            int seperator = styleName.indexOf(':');
            if (seperator >= 0) {
                styleName = styleName.substring(seperator + 1, styleName.length());
            }
            return styleName;
        }
        return null;
    }

    <T> T depersist(File file, Class<T> type) throws IOException {
        try (InputStream in = new BufferedInputStream(new FileInputStream(file));) {
            return xsp.load(in, type);
        }
    }
}