/* 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.data.layer; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.logging.Level; import org.apache.wicket.Component; import org.apache.wicket.ResourceReference; 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.basic.Label; 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.image.Image; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.Model; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogBuilder; import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.CoverageStoreInfo; import org.geoserver.catalog.DataStoreInfo; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.StoreInfo; import org.geoserver.web.CatalogIconFactory; import org.geoserver.web.GeoServerSecuredPage; import org.geoserver.web.data.resource.ResourceConfigurationPage; import org.geoserver.web.wicket.GeoServerTablePanel; import org.geoserver.web.wicket.ParamResourceModel; import org.geoserver.web.wicket.SimpleAjaxLink; import org.geoserver.web.wicket.GeoServerDataProvider.Property; /** * A page listing the resources contained in a store, and whose links will bring * the user to a new resource configuration page * * @author Andrea Aime - OpenGeo */ @SuppressWarnings("serial") public class NewLayerPage extends GeoServerSecuredPage { String storeId; private NewLayerPageProvider provider; private GeoServerTablePanel<Resource> layers; private WebMarkupContainer layersContainer; private WebMarkupContainer selectLayersContainer; private WebMarkupContainer selectLayers; private Label storeName; public NewLayerPage() { this(null); } public NewLayerPage(String storeId) { this.storeId = storeId; // the store selector, used when no store is initially known Form selector = new Form("selector"); selector.add(storesDropDown()); selector.setVisible(storeId == null); add(selector); // the layer choosing block // visible when in any way a store has been chosen selectLayersContainer = new WebMarkupContainer("selectLayersContainer"); selectLayersContainer.setOutputMarkupId(true); add(selectLayersContainer); selectLayers = new WebMarkupContainer("selectLayers"); selectLayers.setVisible(storeId != null); selectLayersContainer.add(selectLayers); selectLayers.add(storeName = new Label("storeName", new Model())); if(storeId != null) { StoreInfo store = getCatalog().getStore(storeId, StoreInfo.class); storeName.setModelObject(store.getName()); } provider = new NewLayerPageProvider(); provider.setStoreId(storeId); provider.setShowPublished(true); layers = new GeoServerTablePanel<Resource>("layers", provider) { @Override protected Component getComponentForProperty(String id, IModel itemModel, Property<Resource> property) { if (property == NewLayerPageProvider.NAME) { return new Label(id, property.getModel(itemModel)); } else if (property == NewLayerPageProvider.PUBLISHED) { final Resource resource = (Resource) itemModel.getObject(); final CatalogIconFactory icons = CatalogIconFactory.get(); if(resource.isPublished()) { ResourceReference icon = icons.getEnabledIcon(); Fragment f = new Fragment(id, "iconFragment", NewLayerPage.this); f.add(new Image("layerIcon", icon)); return f; } else { return new Label(id); } } else if(property == NewLayerPageProvider.ACTION) { final Resource resource = (Resource) itemModel.getObject(); if(resource.isPublished()) { return resourceChooserLink(id, itemModel, new ParamResourceModel("publishAgain", this)); } else { return resourceChooserLink(id, itemModel, new ParamResourceModel("publish", this)); } } else { throw new IllegalArgumentException( "Don't know of property " + property.getName()); } } }; layers.setFilterVisible(true); selectLayers.add(layers); } private DropDownChoice storesDropDown() { final DropDownChoice stores = new DropDownChoice("storesDropDown", new Model(), new StoreListModel(), new StoreListChoiceRenderer()); stores.setOutputMarkupId(true); stores.add(new AjaxFormComponentUpdatingBehavior("onchange") { @Override protected void onUpdate(AjaxRequestTarget target) { if (stores.getModelObject() != null) { StoreInfo store = (StoreInfo) stores.getModelObject(); provider.setStoreId(store.getId()); storeName.setModelObject(store.getName()); selectLayers.setVisible(true); // make sure we can actually list the contents, it may happen // the store is actually unreachable, in that case we // want to display an error message try { provider.getItems(); } catch(Exception e) { LOGGER.log(Level.SEVERE, "Error retrieving layers for the specified store", e); error(e.getMessage()); selectLayers.setVisible(false); } } else { selectLayers.setVisible(false); } target.addComponent(selectLayersContainer); target.addComponent(feedbackPanel); } }); return stores; } SimpleAjaxLink resourceChooserLink(String id, IModel itemModel, IModel label) { return new SimpleAjaxLink(id, itemModel, label) { @Override protected void onClick(AjaxRequestTarget target) { Resource resource = (Resource) getModelObject(); setResponsePage(new ResourceConfigurationPage( buildLayerInfo(resource), true)); } }; } /** * Turns a resource name into a full {@link ResourceInfo} * * @param resource * @return */ LayerInfo buildLayerInfo(Resource resource) { Catalog catalog = getCatalog(); StoreInfo store = catalog.getStore(getSelectedStoreId(), StoreInfo.class); // try to build from coverage store or data store try { CatalogBuilder builder = new CatalogBuilder(catalog); builder.setStore(store); if (store instanceof CoverageStoreInfo) { CoverageInfo ci = builder.buildCoverage(); return builder.buildLayer(ci); } else if (store instanceof DataStoreInfo) { FeatureTypeInfo fti = builder.buildFeatureType(resource.getName()); return builder.buildLayer(fti); } } catch (Exception e) { throw new RuntimeException( "Error occurred while building the resources for the configuration page", e); } // handle the case in which the store was not found anymore, or was not // of the expected type if (store == null) throw new IllegalArgumentException( "Store is missing from configuration!"); else throw new IllegalArgumentException( "Don't know how to deal with this store " + store); } /** * Returns the storeId provided during construction, or the one pointed * by the drop down if none was provided during construction * @return */ String getSelectedStoreId() { // the provider is always up to date return provider.getStoreId(); } final class StoreListModel extends LoadableDetachableModel { @Override protected Object load() { List<StoreInfo> stores = getCatalog().getStores(StoreInfo.class); stores = new ArrayList<StoreInfo>(stores); Collections.sort(stores, new Comparator<StoreInfo>() { public int compare(StoreInfo o1, StoreInfo o2) { if (o1.getWorkspace().equals(o2.getWorkspace())) { return o1.getName().compareTo(o2.getName()); } return o1.getWorkspace().getName().compareTo(o2.getWorkspace().getName()); } }); return stores; } } static final class StoreListChoiceRenderer implements IChoiceRenderer { public Object getDisplayValue(Object store) { StoreInfo info = (StoreInfo) store; return new StringBuilder(info.getWorkspace().getName()).append(':').append( info.getName()); } public String getIdValue(Object store, int arg1) { return ((StoreInfo) store).getId(); } } }