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

Java tutorial

Introduction

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

Source

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
 * (c) 2001 - 2013 OpenPlans
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.importer.web;

import static org.geoserver.ows.util.ResponseUtils.urlEncode;

import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.DefaultItemReuseStrategy;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.IChainingModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.web.GeoServerApplication;
import org.geoserver.web.demo.PreviewLayer;
import org.geoserver.web.wicket.CRSPanel;
import org.geoserver.web.wicket.GeoServerDataProvider;
import org.geoserver.web.wicket.GeoServerDataProvider.Property;
import org.geoserver.web.wicket.GeoServerDialog;
import org.geoserver.web.wicket.GeoServerDialog.DialogDelegate;
import org.geoserver.web.wicket.GeoServerTablePanel;
import org.geoserver.web.wicket.Icon;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geoserver.web.wicket.SRSToCRSModel;
import org.geoserver.web.wicket.SimpleAjaxLink;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.util.logging.Logging;

import org.geoserver.importer.ImportTask;
import org.geoserver.importer.Importer;
import org.geoserver.importer.web.ImportPage.DataIconModel;

import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.FactoryException;

public class ImportTaskTable extends GeoServerTablePanel<ImportTask> {

    static Logger LOGGER = Logging.getLogger(Importer.class);

    static CoordinateReferenceSystem EPSG_3857() throws FactoryException {
        return CRS.decode("EPSG:3857");
    }

    ModalWindow popupWindow;
    GeoServerDialog dialog;
    FeedbackPanel feedbackPanel;

    public ImportTaskTable(String id, GeoServerDataProvider<ImportTask> dataProvider, boolean selectable) {
        super(id, dataProvider, selectable);
        add(dialog = new GeoServerDialog("dialog"));
        add(popupWindow = new ModalWindow("popup"));
        ((DataView) get("listContainer:items")).setItemReuseStrategy(DefaultItemReuseStrategy.getInstance());
    }

    public ImportTaskTable setFeedbackPanel(FeedbackPanel feedbackPanel) {
        this.feedbackPanel = feedbackPanel;
        return this;
    }

    @Override
    protected Component getComponentForProperty(String id, final IModel itemModel, Property property) {
        if (property == ImportTaskProvider.NAME) {
            return new LayerLinkPanel(id, itemModel);
        }

        if (property == ImportTaskProvider.STATUS) {
            ImportTask.State state = (ImportTask.State) property.getModel(itemModel).getObject();
            Component c = null;
            if (state == ImportTask.State.ERROR) {
                c = new SimpleAjaxLink<ImportTask>(id, itemModel,
                        new StatusDescriptionModel(property.getModel(itemModel))) {
                    @Override
                    protected void onClick(AjaxRequestTarget target) {
                        popupWindow.setContent(
                                new ExceptionPanel(popupWindow.getContentId(), getModelObject().getError()));
                        popupWindow.show(target);
                    }
                };
            } else {

                c = new Label(id, new StatusDescriptionModel(property.getModel(itemModel)));
            }

            String cssClass = new StatusIconModel(property.getModel(itemModel)).getCssClass();
            return c.add(new SimpleAttributeModifier("class", cssClass));
        }
        if (property == ImportTaskProvider.ACTION) {

            ImportTask.State state = (ImportTask.State) property.getModel(itemModel).getObject();
            switch (state) {
            case COMPLETE:
                //link to map preview
                return new LayerPreviewPanel(id, itemModel);
            case NO_CRS:
                //provide link to choose crs
                return new NoCRSPanel(id, itemModel);
            //return createFixCRSLink(id, itemModel);
            case READY:
                //return advanced option link
                //for now disable if this is not a vector layer
                ImportTask task = (ImportTask) itemModel.getObject();
                if (task.getLayer() != null && task.getLayer().getResource() instanceof FeatureTypeInfo) {
                    return new AdvancedOptionPanel(id, itemModel);
                }
                return new WebMarkupContainer(id);
            default:
                return new WebMarkupContainer(id);
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    SimpleAjaxLink createFixCRSLink(String id, final IModel<ImportTask> itemModel) {
        return new SimpleAjaxLink(id, new Model("Fix...")) {
            @Override
            protected void onClick(AjaxRequestTarget target) {
                dialog.showOkCancel(target, new DialogDelegate() {

                    @Override
                    protected boolean onSubmit(AjaxRequestTarget target, Component contents) {
                        ImporterWebUtils.importer().changed(itemModel.getObject());
                        target.addComponent(ImportTaskTable.this);
                        return true;
                    }

                    @Override
                    protected Component getContents(String id) {
                        return new NoCRSPanel(id,
                                new SRSToCRSModel(new PropertyModel(itemModel, "layer.resource.sRS")));
                    }
                });
            }
        };
    }

    protected void onItemFixed(ImportTask task, AjaxRequestTarget target) {
        selectObject(task);
        target.addComponent(this);
        onSelectionUpdate(target);
    }

    static abstract class StatusModel<T> implements IChainingModel<T> {

        IModel chained;

        protected StatusModel(IModel model) {
            this.chained = model;
        }

        public void setObject(T object) {
        }

        public void detach() {
            chained.detach();
        }

        public void setChainedModel(IModel<?> model) {
            this.chained = model;
        }

        public IModel<?> getChainedModel() {
            return chained;
        }
    }

    static class StatusIconModel extends StatusModel<ResourceReference> {

        StatusIconModel(IModel model) {
            super(model);
        }

        public ResourceReference getObject() {
            ImportTask.State state = (ImportTask.State) chained.getObject();
            switch (state) {
            case READY:
                return new ResourceReference(GeoServerApplication.class, "img/icons/silk/bullet_go.png");
            case RUNNING:
                return new ResourceReference(ImportTaskTable.class, "indicator.gif");
            case COMPLETE:
                return new ResourceReference(GeoServerApplication.class, "img/icons/silk/accept.png");
            case NO_BOUNDS:
            case NO_CRS:
            case NO_FORMAT:
            case BAD_FORMAT:
                return new ResourceReference(GeoServerApplication.class, "img/icons/silk/error.png");
            case ERROR:
                return new ResourceReference(GeoServerApplication.class, "img/icons/silk/delete.png");
            }
            return null;
        }

        public String getCssClass() {
            ImportTask.State state = (ImportTask.State) chained.getObject();
            switch (state) {
            case READY:
                return "apply-link";
            case RUNNING:
                return "working-link";
            case COMPLETE:
                return "accept-link";
            case NO_BOUNDS:
            case NO_CRS:
            case ERROR:
            case NO_FORMAT:
            case BAD_FORMAT:
                return "warning-link";
            //case ERROR:
            //    return "error-link";
            case CANCELED:
                return "cancel-link";
            }
            return "";
        }
    }

    class StatusDescriptionModel extends StatusModel<String> {

        StatusDescriptionModel(IModel model) {
            super(model);
        }

        public String getObject() {
            ImportTask.State state = (ImportTask.State) chained.getObject();
            return new StringResourceModel(state.name().toLowerCase(), ImportTaskTable.this, null).getString();
        }
    }

    //    class FormatDelegate extends DialogDelegate {
    //
    //        LayerSummary layer;
    //        
    //        public FormatDelegate(LayerSummary layer) {
    //            this.layer = layer;
    //        }
    //        
    //        @Override
    //        protected Component getContents(String id) {
    //            // TODO Auto-generated method stub
    //            return null;
    //        }
    //
    //        @Override
    //        protected boolean onSubmit(AjaxRequestTarget target, Component contents) {
    //
    //        }
    //    }

    //    static class FormatPanel extends Panel {
    //
    //        public FormatPanel(String id, IModel model) {
    //            super(id);
    //            add(new FormatDropDownChoice("format", model).add(
    //                new AjaxFormComponentUpdatingBehavior("onchange") {
    //                    @Override
    //                    protected void onUpdate(AjaxRequestTarget target) {}
    //                }));
    //            add(new AjaxLink("apply") {
    //                @Override
    //                public void onClick(AjaxRequestTarget target) {
    //                    onApply(target);
    //                }
    //            });
    //        }
    //        
    //        protected void onApply(AjaxRequestTarget target) {
    //        }
    //    }
    //    
    //    static class FormatDropDownChoice extends DropDownChoice<LayerFormat> {
    //
    //        public FormatDropDownChoice(String id, IModel model) {
    //            super(id, model, new FormatsModel());
    //            setChoiceRenderer(new IChoiceRenderer<LayerFormat>() {
    //                public Object getDisplayValue(LayerFormat object) {
    //                    return getIdValue(object, -1);
    //                }
    //
    //                public String getIdValue(LayerFormat object, int index) {
    //                    return object.getName();
    //                }
    //            });
    //        }
    //    }
    //    
    //    static class FormatsModel extends LoadableDetachableModel<List<LayerFormat>> {
    //
    //        @Override
    //        protected List<LayerFormat> load() {
    //            return LayerFormat.all();
    //        }
    //        
    //    }
    //
    class NoCRSPanel extends Panel {

        public NoCRSPanel(String id, final IModel<ImportTask> model) {
            super(id, model);

            Form form = new Form("form");
            add(form);

            form.add(new CRSPanel("crs", new SRSToCRSModel(new PropertyModel(model, "layer.resource.sRS"))) {
                @Override
                protected CoordinateReferenceSystem fromSRS(String srs) {
                    try {
                        return CRS.decode(srs);
                    } catch (Exception e) {
                        error(e);
                        return null;
                    }
                }
            });

            form.add(new AjaxSubmitLink("apply") {
                @Override
                protected void onError(AjaxRequestTarget target, Form<?> form) {
                    target.addComponent(feedbackPanel);
                }

                @Override
                protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                    target.addComponent(feedbackPanel);
                    ImportTask item = model.getObject();
                    ImporterWebUtils.importer().changed(item);

                    //ImportItemTable.this.modelChanged();
                    target.addComponent(ImportTaskTable.this);
                    onItemFixed(item, target);
                }
            });
        }
    }

    static class LayerLinkPanel extends Panel {
        public LayerLinkPanel(String id, final IModel<ImportTask> model) {
            super(id);

            add(new Link<ImportTask>("link", model) {
                @Override
                public void onClick() {
                    ImportTask task = getModelObject();

                    PageParameters pp = new PageParameters();
                    pp.put("id", task.getContext().getId());

                    setResponsePage(new LayerPage(task.getLayer(), pp) {
                        protected void onSuccessfulSave() {
                            super.onSuccessfulSave();

                            //update the item
                            ImporterWebUtils.importer().changed(model.getObject());
                        };
                    });
                }
            }.add(new Label("name", new PropertyModel(model, "layer.name")))
                    .add(new Icon("icon", new DataIconModel(model.getObject().getData()))));
        }
    }

    class LayerPreviewPanel extends Panel {
        public LayerPreviewPanel(String id, IModel<ImportTask> model) {
            super(id);

            LayerInfo layer = model.getObject().getLayer();
            PreviewLayer preview = new PreviewLayer(layer);

            List<PreviewLink> links = new ArrayList<PreviewLink>();
            links.add(new PreviewLink("layerPreview", preview.getWmsLink() + "&format=application/openlayers"));

            links.add(new PreviewLink("googleearth", "../wms/kml?layers=" + layer.getName()));

            add(new DropDownChoice<PreviewLink>("links", new Model(links.get(0)), links,
                    new ChoiceRenderer<PreviewLink>() {
                        @Override
                        public Object getDisplayValue(PreviewLink object) {
                            return new ParamResourceModel(object.id, ImportTaskTable.this, object.id).getString();
                        }

                        @Override
                        public String getIdValue(PreviewLink object, int index) {
                            return object.href;
                        }
                    }).setNullValid(false).setOutputMarkupId(true));

            add(new ExternalLink("go", "#").add(new AttributeModifier("onclick",
                    new Model("go(document.getElementById('" + get("links").getMarkupId() + "'));"))));
        }

        class PreviewLink implements Serializable {
            String id;
            String href;

            PreviewLink(String id, String href) {
                this.id = id;
                this.href = href;
            }
        }
    }

    static class AdvancedOptionPanel extends Panel {
        public AdvancedOptionPanel(String id, IModel<ImportTask> model) {
            super(id);

            add(new Link<ImportTask>("link", model) {
                @Override
                public void onClick() {
                    setResponsePage(new ImportTaskAdvancedPage(getModel()));
                }
            });
        }
    }

    static class ErrorPanel extends Panel {
        ModalWindow popupWindow;

        public ErrorPanel(String id, IModel<ImportTask> model) {
            super(id);

            add(popupWindow = new ModalWindow("popup"));
            add(new AjaxLink<ImportTask>("link", model) {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    popupWindow.setContent(
                            new ExceptionPanel(popupWindow.getContentId(), getModelObject().getError()));
                    popupWindow.show(target);
                }
            });
        }
    }

    static class ExceptionPanel extends Panel {

        public ExceptionPanel(String id, final Exception ex) {
            super(id);
            add(new Label("message", ex.getLocalizedMessage()));
            add(new TextArea("stackTrace", new Model(handleStackTrace(ex))));
            add(new AjaxLink("copy") {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    String text = handleStackTrace(ex);
                    StringSelection selection = new StringSelection(text);
                    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
                }
            });
        }

        String handleStackTrace(Exception ex) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            PrintWriter writer = new PrintWriter(out);
            ex.printStackTrace(writer);
            writer.flush();

            return new String(out.toByteArray());
        }
    }
}