Java tutorial
/* 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 static org.geoserver.ows.util.ResponseUtils.*; import static org.geoserver.web.importer.ImportSummaryProvider.*; import java.util.logging.Level; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.Page; import org.apache.wicket.PageParameters; import org.apache.wicket.ResourceReference; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogBuilder; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.StoreInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.importer.ImportStatus; import org.geoserver.importer.ImportSummary; import org.geoserver.importer.LayerSummary; import org.geoserver.web.CatalogIconFactory; import org.geoserver.web.GeoServerSecuredPage; import org.geoserver.web.data.resource.ResourceConfigurationPage; import org.geoserver.web.demo.PreviewLayer; import org.geoserver.web.wicket.CRSPanel; import org.geoserver.web.wicket.ConfirmationAjaxLink; import org.geoserver.web.wicket.GeoServerTablePanel; import org.geoserver.web.wicket.ParamResourceModel; import org.geoserver.web.wicket.SRSListPanel; import org.geoserver.web.wicket.SimpleAjaxLink; import org.geoserver.web.wicket.GeoServerDataProvider.Property; import org.opengis.feature.type.FeatureType; import org.opengis.feature.type.GeometryDescriptor; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * Reports the import results in a table and allows the user to edit the and to preview the layers * * @author Andrea Aime - OpenGeo * */ @SuppressWarnings("serial") public class ImportSummaryPage extends GeoServerSecuredPage { private ModalWindow popupWindow; private GeoServerTablePanel<LayerSummary> summaryTable; private SimpleAjaxLink declareSRSLink; public ImportSummaryPage(final ImportSummary summary) { // the synthetic results IModel summaryMessage; Exception error = summary.getError(); if (error != null) { String errorSummary = error.getClass().getSimpleName() + ", " + error.getMessage(); summaryMessage = new ParamResourceModel("summaryError", this, errorSummary); } else if (summary.getProcessedLayers() == 0) { summaryMessage = new ParamResourceModel("summaryCancelled", this); // no undo link in this case add(new Label("undo", "")); } else { if (summary.getFailures() > 0) { if (summary.isCompleted()) { summaryMessage = new ParamResourceModel("summaryFailures", this, summary.getProcessedLayers(), summary.getProject(), summary.getFailures()); } else { summaryMessage = new ParamResourceModel("summaryPartialFailures", this, summary.getProcessedLayers(), summary.getProject(), summary.getFailures()); } } else { if (summary.isCompleted()) { summaryMessage = new ParamResourceModel("summarySuccess", this, summary.getProcessedLayers(), summary.getProject()); } else { summaryMessage = new ParamResourceModel("summaryPartialSuccess", this, summary.getProcessedLayers(), summary.getProject(), summary.getFailures()); } } // show undo link add(undoLink(summary)); } add(new Label("summary", summaryMessage)); // the popup window popupWindow = new ModalWindow("popup"); add(popupWindow); // the declare SRS link declareSRSLink = popupLink("declareSRS", new ParamResourceModel("declareSRS", this), srsListSelectionPanel()); declareSRSLink.getLink().setEnabled(false); declareSRSLink.setOutputMarkupId(true); add(declareSRSLink); // the list of imported layers ImportSummaryProvider provider = new ImportSummaryProvider(summary.getLayers()); summaryTable = new GeoServerTablePanel<LayerSummary>("importSummary", provider, true) { @Override protected Component getComponentForProperty(String id, IModel itemModel, Property<LayerSummary> property) { final LayerSummary layerSummary = (LayerSummary) itemModel.getObject(); final CatalogIconFactory icons = CatalogIconFactory.get(); LayerInfo layer = layerSummary.getLayer(); if (property == LAYER) { Fragment f = new Fragment(id, "edit", ImportSummaryPage.this); // keep the last modified name if possible IModel label; if (layerSummary.getLayer() != null) label = new Model(layerSummary.getLayer().getName()); else label = new Model(layerSummary.getLayerName()); // build the edit link Link editLink = editLink(layerSummary, label); editLink.setEnabled(layer != null); // also set a tooltip explaining what this action does editLink.add(new AttributeModifier("title", true, new ParamResourceModel("edit", this, label.getObject()))); f.add(editLink); return f; } else if (property == TYPE) { if (layer != null) { // show icon type or an error icon if anything went wrong ResourceReference icon; IModel title = new Model(getTypeTooltip(layer)); if (layerSummary.getStatus().successful()) { icon = icons.getSpecificLayerIcon(layer); title = new Model(getTypeTooltip(layer)); } else { icon = icons.getDisabledIcon(); title = ISSUES.getModel(itemModel); } Fragment f = new Fragment(id, "iconFragment", ImportSummaryPage.this); Image image = new Image("icon", icon); image.add(new AttributeModifier("title", true, title)); image.add(new AttributeModifier("alt", true, title)); f.add(image); return f; } else { // no icon, no description return new Label(id, ""); } } else if (property == ISSUES) { if (layerSummary.getStatus() != ImportStatus.NO_SRS_MATCH) { return new Label(id, property.getModel(itemModel)); } else { Fragment f = new Fragment(id, "noSRSMatch", ImportSummaryPage.this); f.add(new Label("issue", property.getModel(itemModel))); f.add(getLayerWKTLink(itemModel)); return f; } } else if (property == SRS) { if (layerSummary.getStatus().successful()) { return new Label(id, property.getModel(itemModel)); } else if (layerSummary.getStatus() == ImportStatus.MISSING_NATIVE_CRS || layerSummary.getStatus() == ImportStatus.NO_SRS_MATCH) { return popupLink(id, new ParamResourceModel("declareSRS", this), srsListLayerPanel(itemModel)); } else { Fragment f = new Fragment(id, "edit", ImportSummaryPage.this); // build the edit link Link editLink = editLink(layerSummary, new ParamResourceModel("directFix", this)); editLink.setEnabled(layer != null); f.add(editLink); } } else if (property == COMMANDS) { boolean geometryless = false; ResourceInfo resource = layerSummary.getLayer().getResource(); if (resource instanceof FeatureTypeInfo) { try { FeatureType featureType = ((FeatureTypeInfo) resource).getFeatureType(); geometryless = featureType.getGeometryDescriptor() == null; } catch (Exception e) { geometryless = true; } } if (layerSummary.getStatus().successful() && !geometryless) { Fragment f = new Fragment(id, "preview", ImportSummaryPage.this); PreviewLayer preview = new PreviewLayer(layer); f.add(new ExternalLink("ol", preview.getWmsLink() + "&format=application/openlayers")); f.add(new ExternalLink("ge", "../wms/kml?layers=" + layer.getName())); f.add(new ExternalLink("styler", "/styler/index.html?layer=" + urlEncode( layer.getResource().getStore().getWorkspace().getName() + ":" + layer.getName()))); return f; } else { return new Label(id, ""); } } return null; } @Override protected void onSelectionUpdate(AjaxRequestTarget target) { declareSRSLink.getLink().setEnabled(getSelection().size() > 0); target.addComponent(declareSRSLink); } }; summaryTable.setOutputMarkupId(true); summaryTable.setFilterable(false); add(summaryTable); } /** * Rolls back the import and redirects to the initial page * * @param summary * @return */ private ConfirmationAjaxLink undoLink(final ImportSummary summary) { return new ConfirmationAjaxLink("undo", null, new ParamResourceModel("rollback", this), new ParamResourceModel("confirmRollback", this)) { @Override protected void onClick(AjaxRequestTarget target) { Catalog catalog = getCatalog(); ImporterCascadeDeleteVisitor deleteVisitor = new ImporterCascadeDeleteVisitor(catalog); String project = summary.getProject(); if (summary.isWorkspaceNew()) { WorkspaceInfo ws = catalog.getWorkspaceByName(project); if (ws != null) ws.accept(deleteVisitor); } else if (summary.isStoreNew()) { StoreInfo si = catalog.getStoreByName(project, project, StoreInfo.class); if (si != null) si.accept(deleteVisitor); } else { // just remove the layers we created for (LayerSummary layer : summary.getLayers()) { catalog.remove(layer.getLayer()); catalog.remove(layer.getLayer().getResource()); } } setResponsePage(StoreChooserPage.class, new PageParameters("afterCleanup=true")); } }; } Link editLink(final LayerSummary layerSummary, IModel labelModel) { Link link = new Link("edit") { @Override public void onClick() { Page p = new ResourceConfigurationPage(layerSummary.getLayer(), true) { @Override protected void onSuccessfulSave() { setResponsePage(ImportSummaryPage.this); layerSummary.setStatus(ImportStatus.SUCCESS); layerSummary.updateLayer(getCatalog()); } @Override protected void onCancel() { setResponsePage(ImportSummaryPage.this); } }; setResponsePage(p); } }; link.add(new Label("name", labelModel)); return link; } String getTypeTooltip(LayerInfo layer) { try { String type = null; FeatureTypeInfo fti = (FeatureTypeInfo) layer.getResource(); GeometryDescriptor gd = fti.getFeatureType().getGeometryDescriptor(); if (gd != null) { type = gd.getType().getBinding().getSimpleName(); } if (type != null) return new ParamResourceModel("geomtype." + type, ImportSummaryPage.this).getString(); else return "geomtype.null"; } catch (Exception e) { LOGGER.log(Level.WARNING, "Could not compute the geom type tooltip", e); return "geomtype.error"; } } Component getLayerWKTLink(IModel layerSummaryModel) { return new SimpleAjaxLink("seeWKT", layerSummaryModel, new ParamResourceModel("seeWKT", this)) { @Override protected void onClick(AjaxRequestTarget target) { popupWindow.setInitialHeight(375); popupWindow.setInitialWidth(525); LayerSummary summary = (LayerSummary) getDefaultModel().getObject(); CoordinateReferenceSystem crs = summary.getLayer().getResource().getNativeCRS(); popupWindow.setContent(new CRSPanel.WKTPanel(popupWindow.getContentId(), crs)); if (crs != null) popupWindow.setTitle(crs.getName().toString()); popupWindow.show(target); } }; } SimpleAjaxLink popupLink(String id, final IModel label, final Component windowContent) { return new SimpleAjaxLink(id, label) { @Override protected void onClick(AjaxRequestTarget target) { popupWindow.setContent(windowContent); popupWindow.setTitle(new ParamResourceModel("selectSRS", ImportSummaryPage.this)); popupWindow.show(target); } }; } /** * Builds the srs list panel component for a single layer */ SRSListPanel srsListLayerPanel(final IModel layerSummaryModel) { SRSListPanel srsList = new SRSListPanel(popupWindow.getContentId()) { @Override protected void onCodeClicked(AjaxRequestTarget target, String epsgCode) { popupWindow.close(target); LayerSummary summary = (LayerSummary) layerSummaryModel.getObject(); forceEpsgCode(epsgCode, summary); target.addComponent(summaryTable); } }; srsList.setCompactMode(true); return srsList; } /** * Builds the srs list panel component for a single layer */ SRSListPanel srsListSelectionPanel() { SRSListPanel srsList = new SRSListPanel(popupWindow.getContentId()) { @Override protected void onCodeClicked(AjaxRequestTarget target, String epsgCode) { popupWindow.close(target); for (LayerSummary summary : summaryTable.getSelection()) { forceEpsgCode(epsgCode, summary); } summaryTable.clearSelection(); target.addComponent(summaryTable); } }; srsList.setCompactMode(true); return srsList; } /** * Sets the EPSG code on a layer and saves it * * @param epsgCode * @param catalog * @param summary */ void forceEpsgCode(String epsgCode, LayerSummary summary) { Catalog catalog = getCatalog(); LayerInfo layer = summary.getLayer(); ResourceInfo resource = layer.getResource(); resource.setSRS("EPSG:" + epsgCode); try { new CatalogBuilder(getCatalog()).setupBounds(resource); } catch (Exception e) { LOGGER.log(Level.FINE, "Issue occurred while computing the bounding boxes", e); } if (resource.getLatLonBoundingBox() == null) { summary.setStatus(ImportStatus.MISSING_BBOX); } else { summary.setStatus(ImportStatus.SUCCESS); } if (layer.getId() == null || catalog.getLayer(layer.getId()) == null) { catalog.add(resource); catalog.add(layer); } else { catalog.save(resource); catalog.save(layer); } summary.updateLayer(catalog); } }