/* 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.workspace; import java.util.List; import java.util.logging.Logger; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.form.CheckBox; 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.markup.html.link.BookmarkablePageLink; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.PropertyModel; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.DataStoreInfo; import org.geoserver.catalog.NamespaceInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.catalog.event.CatalogAddEvent; import org.geoserver.catalog.event.CatalogListener; import org.geoserver.catalog.event.CatalogModifyEvent; import org.geoserver.catalog.event.CatalogPostModifyEvent; import org.geoserver.catalog.event.CatalogRemoveEvent; import org.geoserver.web.GeoServerSecuredPage; import org.geoserver.web.data.namespace.NamespaceDetachableModel; import org.geoserver.web.wicket.ParamResourceModel; import org.geoserver.web.wicket.URIValidator; import org.geoserver.web.wicket.XMLNameValidator; import org.geotools.util.logging.Logging; /** * Allows editing a specific workspace */ @SuppressWarnings("serial") public class WorkspaceEditPage extends GeoServerSecuredPage { private static final Logger LOGGER = Logging.getLogger("org.geoserver.web.data.workspace"); IModel wsModel; IModel nsModel; boolean defaultWs; /** * Uses a "name" parameter to locate the workspace * @param parameters */ public WorkspaceEditPage(PageParameters parameters) { String wsName = parameters.getString("name"); WorkspaceInfo wsi = getCatalog().getWorkspaceByName(wsName); if(wsi == null) { error(new ParamResourceModel("WorkspaceEditPage.notFound", this, wsName).getString()); setResponsePage(WorkspacePage.class); return; } init(wsi); } public WorkspaceEditPage(WorkspaceInfo ws) { init(ws); } private void init(WorkspaceInfo ws) { defaultWs = ws.getId().equals(getCatalog().getDefaultWorkspace().getId()); wsModel = new WorkspaceDetachableModel( ws ); NamespaceInfo ns = getCatalog().getNamespaceByPrefix( ws.getName() ); nsModel = new NamespaceDetachableModel(ns); Form form = new Form( "form", new CompoundPropertyModel( nsModel ) ) { protected void onSubmit() { try { saveWorkspace(); } catch (RuntimeException e) { error(e.getMessage()); } } }; add(form); TextField name = new TextField("name", new PropertyModel(wsModel, "name")); name.setRequired(true); name.add(new XMLNameValidator()); form.add(name); TextField uri = new TextField("uri", new PropertyModel(nsModel, "uRI"), String.class); uri.setRequired(true); uri.add(new URIValidator()); form.add(uri); CheckBox defaultChk = new CheckBox("default", new PropertyModel(this, "defaultWs")); form.add(defaultChk); //stores // StorePanel storePanel = new StorePanel("storeTable", new StoreProvider(ws), false); // form.add(storePanel); SubmitLink submit = new SubmitLink("save"); form.add(submit); form.setDefaultButton(submit); form.add(new BookmarkablePageLink("cancel", WorkspacePage.class)); } private void saveWorkspace() { final Catalog catalog = getCatalog(); NamespaceInfo namespaceInfo = (NamespaceInfo) nsModel.getObject(); WorkspaceInfo workspaceInfo = (WorkspaceInfo) wsModel.getObject(); //sync up workspace name with namespace prefix, temp measure namespaceInfo.setPrefix(workspaceInfo.getName()); // this will ensure all datastore namespaces are updated when the workspace is modified DataStoreNamespaceUpdatingListener listener = new DataStoreNamespaceUpdatingListener( workspaceInfo, catalog); catalog.addListener(listener); try { catalog.save(workspaceInfo); catalog.save(namespaceInfo); if(defaultWs) catalog.setDefaultWorkspace(workspaceInfo); } finally { catalog.removeListener(listener); } setResponsePage(WorkspacePage.class); } /** * Listens to Catalog's namespace URI modifications and updates the "namespace" * {@link DataStoreInfo#getConnectionParameters() connection parameter} for all the datastores * configured for the workspace */ private static final class DataStoreNamespaceUpdatingListener implements CatalogListener { private final WorkspaceInfo workspaceInfo; private final Catalog catalog; public DataStoreNamespaceUpdatingListener(final WorkspaceInfo workspaceInfo, final Catalog catalog) { this.workspaceInfo = workspaceInfo; this.catalog = catalog; } /** * @see CatalogListener#handlePostModifyEvent(CatalogPostModifyEvent) */ public void handlePostModifyEvent(CatalogPostModifyEvent event) { if (event.getSource() instanceof NamespaceInfo) { LOGGER.info("Updating namespace parameter for all DataStoreInfo" + " objects in workspace " + workspaceInfo.getName()); final NamespaceInfo nsInfo = (NamespaceInfo) event.getSource(); String namespaceURI = nsInfo.getURI(); List<DataStoreInfo> stores = catalog.getDataStoresByWorkspace(workspaceInfo); if (stores.size() > 0) { for (DataStoreInfo store : stores) { if (store.getConnectionParameters().containsKey("namespace")) { store.getConnectionParameters().put("namespace", namespaceURI); LOGGER.info("Setting namespace for store " + store.getName() + " to be " + namespaceURI); catalog.save(store); } } LOGGER.info("namespace parameter for " + stores.size() + " stores in workspace " + workspaceInfo.getName() + " successfully updated"); } else { LOGGER.info("No stores in workspace " + workspaceInfo.getName()); } } } /** * Ignored event * * @see CatalogListener#handleModifyEvent(CatalogModifyEvent) */ public void handleModifyEvent(CatalogModifyEvent event) { // ignore } /** * Ignored event * * @see CatalogListener#handleRemoveEvent(CatalogRemoveEvent) */ public void reloaded() { // ignore } /** * Ignored event * * @see CatalogListener#handleRemoveEvent(CatalogRemoveEvent) */ public void handleRemoveEvent(CatalogRemoveEvent event) { // ignore } /** * Ignored event * * @see CatalogListener#handleAddEvent(CatalogAddEvent) */ public void handleAddEvent(CatalogAddEvent event) { // ignore } } }