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

Java tutorial

Introduction

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

Source

/* Copyright (c) 2001 - 2008 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.File;
import java.io.Serializable;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
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.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.validator.AbstractValidator;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.DataStoreInfo;
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.GeoServerDialog;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geoserver.web.wicket.browser.ExtensionFileFilter;
import org.geoserver.web.wicket.browser.GeoServerFileChooser;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;

/**
 * Sets up the import process and starts it up delegating the progress to {@link ImportProgressPage}
 */
@SuppressWarnings("serial")
public class DirectoryPage extends GeoServerSecuredPage {
    String directory = "";

    GeoServerDialog dialog;

    private TextField dirField;

    private Form form;

    GeneralStoreParamPanel generalParams;

    public DirectoryPage() {
        add(dialog = new GeoServerDialog("dialog"));

        form = new Form("form", new CompoundPropertyModel(this));
        add(form);

        form.add(generalParams = new GeneralStoreParamPanel("generalParams"));

        dirField = new TextField("directory");
        dirField.add(new DirectoryValidator());
        dirField.setRequired(true);
        dirField.setOutputMarkupId(true);
        form.add(dirField);
        form.add(chooserButton(form));

        SubmitLink submitLink = submitLink();
        form.add(submitLink);

        form.setDefaultButton(submitLink);
    }

    private Component chooserButton(Form form) {
        AjaxSubmitLink link = new AjaxSubmitLink("chooser") {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form form) {
                dialog.setTitle(new ParamResourceModel("chooseDirectory", this));
                dialog.showOkCancel(target, new GeoServerDialog.DialogDelegate() {

                    @Override
                    protected Component getContents(String id) {
                        // use what the user currently typed
                        File file = null;
                        if (!dirField.getInput().trim().equals("")) {
                            file = new File(dirField.getInput());
                            if (!file.exists())
                                file = null;
                        }

                        GeoServerFileChooser chooser = new GeoServerFileChooser(id, new Model(file));
                        chooser.setFilter(new Model(new ExtensionFileFilter(".shp")));
                        return chooser;
                    }

                    @Override
                    protected boolean onSubmit(AjaxRequestTarget target, Component contents) {
                        GeoServerFileChooser chooser = (GeoServerFileChooser) contents;
                        directory = ((File) chooser.getDefaultModelObject()).getAbsolutePath();
                        // clear the raw input of the field won't show the new model value
                        dirField.clearInput();

                        target.addComponent(dirField);
                        return true;
                    }

                    @Override
                    public void onClose(AjaxRequestTarget target) {
                        // update the field with the user chosen value
                        target.addComponent(dirField);
                    }

                });

            }

        };
        // otherwise the link won't trigger when the form contents are not valid
        link.setDefaultFormProcessing(false);
        return link;
    }

    SubmitLink submitLink() {
        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", DirectoryPage.this,
                                generalParams.name, workspace.getName()).getString());
                        return;
                    }

                    // build/reuse the store
                    String storeType = new ShapefileDataStoreFactory().getDisplayName();
                    Map<String, Serializable> params = new HashMap<String, Serializable>();
                    params.put(ShapefileDataStoreFactory.URLP.key, new File(directory).toURI().toURL().toString());
                    params.put(ShapefileDataStoreFactory.NAMESPACEP.key, new URI(namespace.getURI()).toString());

                    DataStoreInfo si;
                    StoreInfo preExisting = getCatalog().getStoreByName(workspace, generalParams.name,
                            StoreInfo.class);
                    boolean storeNew = false;
                    if (preExisting != null) {
                        if (!(preExisting instanceof DataStoreInfo)) {
                            error(new ParamResourceModel("storeExistsNotVector", this, generalParams.name));
                            return;
                        }
                        si = (DataStoreInfo) preExisting;
                        if (!si.getType().equals(storeType) || !si.getConnectionParameters().equals(params)) {
                            error(new ParamResourceModel("storeExistsNotSame", this, generalParams.name));
                            return;
                        }
                        // make sure it's enabled, we just verified the directory exists
                        si.setEnabled(true);
                    } else {
                        storeNew = true;
                        CatalogBuilder builder = new CatalogBuilder(getCatalog());
                        builder.setWorkspace(workspace);
                        si = builder.buildDataStore(generalParams.name);
                        si.setDescription(generalParams.description);
                        si.getConnectionParameters().putAll(params);
                        si.setEnabled(true);
                        si.setType(storeType);

                        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", storeNew);
                    pp.put("workspaceNew", false);
                    setResponsePage(VectorLayerChooserPage.class, pp);
                } catch (Exception e) {
                    LOGGER.log(Level.SEVERE, "Error while setting up mass import", e);
                }

            }
        };
    }

    /**
     * Tries to figure out a free project name from a prefix (was meant to work for a random
     * directory name but could not hook it up properly to both dialog navigation and manual
     * directory field filling so I just gave up).
     * 
     * @param prefix
     * @return
     */
    String getProjectNameFromPrefix(String prefix) {
        String name = new File(prefix).getName();
        if (name.length() > 6) {
            name = name.substring(0, 6);
        }

        Catalog catalog = getCatalog();
        String candidate = name;
        for (int i = 1; i < 100; i++) {
            if (catalog.getWorkspaceByName(candidate) == null)
                return candidate;

            if (catalog.getDataStoreByName(candidate, candidate) == null)
                return candidate;

            // build a 6 chars version with a number at the end
            if (i < 10) {
                if (prefix.length() == 6)
                    candidate = prefix.substring(0, 5) + i;
                else
                    candidate = prefix + i;
            } else {
                if (prefix.length() > 4)
                    candidate = prefix.substring(0, 4) + i;
                else
                    candidate = prefix + i;
            }
        }

        return null;
    }

    static class DirectoryValidator extends AbstractValidator {

        @Override
        protected void onValidate(IValidatable validatable) {
            String directory = (String) validatable.getValue();

            DataStore store = null;
            Map<String, Serializable> params = new HashMap<String, Serializable>();
            try {
                // check the store can be built (we need to provide the namespace as well
                params.put(ShapefileDataStoreFactory.URLP.key, new File(directory).toURI().toURL());
                params.put(ShapefileDataStoreFactory.NAMESPACEP.key, new URI("http://www.geoserver.org"));
                store = DataStoreFinder.getDataStore(params);
                if (store == null) {
                    error(validatable, "ImportPage.invalidPath");
                } else if (store.getTypeNames().length == 0) {
                    error(validatable, "ImportPage.noData");
                }
            } catch (Exception e) {
                error(validatable, "ImportPage.noData");
            }
        }
    }

    class ProjectValidator extends AbstractValidator {

        @Override
        protected void onValidate(IValidatable validatable) {
            String project = (String) validatable.getValue();

            // new workspace? if so, good
            WorkspaceInfo ws = getCatalog().getWorkspaceByName(project);
            if (ws == null)
                return;

            // new store too?
            StoreInfo store = getCatalog().getStoreByName(ws, project, StoreInfo.class);
            if (store != null)
                error(validatable, "ImportPage.duplicateStore", Collections.singletonMap("project", project));
        }

    }

}