org.geoserver.web.importer.AbstractDBMSPage.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.web.importer.AbstractDBMSPage.java

Source

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.web.importer;

import java.io.Serializable;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;

import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.web.GeoServerSecuredPage;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geotools.data.DataAccess;
import org.geotools.data.DataAccessFinder;
import org.geotools.data.DataStoreFactorySpi;

/**
 * Base class for DBMS configuration pages
 * 
 * @author Andrea Aime - OpenGeo
 * 
 */
@SuppressWarnings("serial")
public abstract class AbstractDBMSPage extends GeoServerSecuredPage {
    protected static final String CONNECTION_DEFAULT = "Default";

    protected static final String CONNECTION_JNDI = "JNDI";

    protected String connectionType;

    protected GeneralStoreParamPanel generalParams;

    private WebMarkupContainer connParamContainer;

    protected Component otherParamsPanel;

    private RepeatingView paramPanels;

    protected LinkedHashMap<String, Component> paramPanelMap;

    public AbstractDBMSPage() {
        Form form = new Form("form");
        add(form);

        // general parameters panel
        form.add(generalParams = new GeneralStoreParamPanel("generalParams"));

        // connection type chooser
        paramPanelMap = buildParamPanels();
        connectionType = paramPanelMap.keySet().iterator().next();
        updatePanelVisibility(null);
        form.add(connectionTypeSelector(paramPanelMap));

        // default param panels
        connParamContainer = new WebMarkupContainer("connectionParamsContainer");
        form.add(connParamContainer);
        connParamContainer.setOutputMarkupId(true);
        paramPanels = new RepeatingView("paramPanelRepeater");
        for (Component panel : paramPanelMap.values()) {
            paramPanels.add(panel);
        }
        connParamContainer.add(paramPanels);

        // other params
        otherParamsPanel = buildOtherParamsPanel("otherParams");
        form.add(otherParamsPanel);

        // next button (where the action really is)
        SubmitLink submitLink = submitLink();
        form.add(submitLink);
        form.setDefaultButton(submitLink);
    }

    /**
     * Builds, configures and returns the other params panel
     * 
     * @return
     */
    protected Component buildOtherParamsPanel(String id) {
        return new OtherDbmsParamPanel(id, "public", false, true);
    }

    /**
     * Wheter the geometryless data is going to be imported, or not
     * @return
     */
    protected boolean isGeometrylessExcluded() {
        return ((OtherDbmsParamPanel) otherParamsPanel).excludeGeometryless;
    }

    /**
     * Switches between the types of param panels
     * 
     * @return
     */
    protected Component connectionTypeSelector(final Map<String, Component> paramPanelMap) {
        ArrayList<String> connectionTypeList = new ArrayList<String>(paramPanelMap.keySet());
        DropDownChoice choice = new DropDownChoice("connType", new PropertyModel(this, "connectionType"),
                new Model(connectionTypeList), new IChoiceRenderer() {

                    public String getIdValue(Object object, int index) {
                        return String.valueOf(object);
                    }

                    public Object getDisplayValue(Object object) {
                        return new ParamResourceModel("ConnectionType." + object, null).getString();
                    }
                });

        choice.add(new AjaxFormComponentUpdatingBehavior("onchange") {

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                updatePanelVisibility(target);
                target.addComponent(connParamContainer);
            }

        });

        return choice;
    }

    /**
     * Updates the panel visibility to show only the currently selected one.
     * Can also be used to perform actions when the panel visibility is updated
     * @param paramPanelMap
     * @param target Used when doing ajax updates, might be null
     */
    protected void updatePanelVisibility(AjaxRequestTarget target) {
        for (String type : paramPanelMap.keySet()) {
            Component panel = paramPanelMap.get(type);
            panel.setVisible(connectionType.equals(type));
        }
    }

    /**
     * Setups the datastore and moves to the next page
     * 
     * @return
     */
    SubmitLink submitLink() {
        // TODO: fill this up with the required parameters
        return new SubmitLink("next") {

            @Override
            public void onSubmit() {
                try {
                    // check there is not another store with the same name
                    WorkspaceInfo workspace = generalParams.getWorkpace();
                    NamespaceInfo namespace = getCatalog().getNamespaceByPrefix(workspace.getName());
                    StoreInfo oldStore = getCatalog().getStoreByName(workspace, generalParams.name,
                            StoreInfo.class);
                    if (oldStore != null) {
                        error(new ParamResourceModel("ImporterError.duplicateStore", AbstractDBMSPage.this,
                                generalParams.name, workspace.getName()).getString());
                        return;
                    }

                    // build up the store connection param map
                    Map<String, Serializable> params = new HashMap<String, Serializable>();
                    DataStoreFactorySpi factory = fillStoreParams(namespace, params);

                    // ok, check we can connect
                    DataAccess store = null;
                    try {
                        store = DataAccessFinder.getDataStore(params);
                        // force the store to open a connection
                        store.getNames();
                        store.dispose();
                    } catch (Throwable e) {
                        LOGGER.log(Level.INFO, "Could not connect to the datastore", e);
                        error(new ParamResourceModel("ImporterError.databaseConnectionError", AbstractDBMSPage.this,
                                e.getMessage()).getString());
                        return;
                    } finally {
                        if (store != null)
                            store.dispose();
                    }

                    // build the store
                    CatalogBuilder builder = new CatalogBuilder(getCatalog());
                    builder.setWorkspace(workspace);
                    StoreInfo si = builder.buildDataStore(generalParams.name);
                    si.setDescription(generalParams.description);
                    si.getConnectionParameters().putAll(params);
                    si.setEnabled(true);
                    si.setType(factory.getDisplayName());
                    getCatalog().add(si);

                    // redirect to the layer chooser
                    PageParameters pp = new PageParameters();
                    pp.put("store", si.getName());
                    pp.put("workspace", workspace.getName());
                    pp.put("storeNew", true);
                    pp.put("workspaceNew", false);
                    pp.put("skipGeometryless", isGeometrylessExcluded());
                    setResponsePage(VectorLayerChooserPage.class, pp);
                } catch (Exception e) {
                    LOGGER.log(Level.SEVERE, "Error while setting up mass import", e);
                }

            }
        };
    }

    /**
     * Builds and returns a map with params panels. The keys are used to fill in the drop down
     * choice and to look for the i18n key using the "ConnectionType.${key}" convention. The panels
     * built should have ids made of digits only, otherwise Wicket will complain about non safe ids
     * in repeater
     * 
     * @return
     */
    protected abstract LinkedHashMap<String, Component> buildParamPanels();

    /**
     * Fills the specified params map and returns the factory spi that we're expected to use to 
     * create the store
     * @param namespace
     * @param params
     * @return
     * @throws URISyntaxException
     */
    protected abstract DataStoreFactorySpi fillStoreParams(NamespaceInfo namespace,
            Map<String, Serializable> params) throws URISyntaxException;
}