/* 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.services;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
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.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.validation.validator.UrlValidator;
import org.geoserver.config.GeoServer;
import org.geoserver.config.ServiceInfo;
import org.geoserver.web.GeoServerHomePage;
import org.geoserver.web.GeoServerSecuredPage;
import org.geoserver.web.wicket.KeywordsEditor;
import org.geoserver.web.wicket.LiveCollectionModel;
/**
* Base page for service administration pages.
* <p>
* Subclasses of this page should contribute form components in the {@link #build(ServiceInfo, Form)}
* method. Each component that is added to the form should have a corresponding
* markup entry of the following form:
* <pre>
* <wicket:extend>
* <li>
* <span>
* <label><wicket:message key="maxFeatures.title">Maximum Features</wicket:message></label>
* <input wicket:id="maxFeatures" class="field text" type="text"></input>
* </span>
* <p class="instruct">
* </p>
* </li>
*
* </wicket:extend>
* </pre>
* </p>
*
*@author Justin Deoliveira, The Open Planning Project
*
*/
public abstract class BaseServiceAdminPage<T extends ServiceInfo> extends GeoServerSecuredPage {
public BaseServiceAdminPage() {
final IModel infoModel = new LoadableDetachableModel() {
public Object load() {
return getGeoServer().getService(getServiceClass());
}
};
Form form = new Form( "form", new CompoundPropertyModel(infoModel));
add(form);
form.add(new Label("service.enabled", new StringResourceModel("service.enabled", this, null, new Object[]{
getServiceName()
})));
form.add(new TextField("maintainer"));
TextField onlineResource = new TextField("onlineResource");
onlineResource.add(new UrlValidator());
form.add(onlineResource);
form.add(new CheckBox("enabled"));
form.add(new CheckBox("citeCompliant"));
form.add(new TextField("title"));
form.add(new TextArea("abstract"));
form.add(new KeywordsEditor("keywords", LiveCollectionModel.list(new PropertyModel(infoModel, "keywords"))));
form.add(new TextField("fees"));
form.add(new TextField("accessConstraints"));
build(infoModel, form);
//add the extension panels
ListView extensionPanels = createExtensionPanelList("extensions", infoModel);
form.add(extensionPanels);
SubmitLink submit = new SubmitLink("submit",new StringResourceModel( "save", (Component)null, null) ) {
@Override
public void onSubmit() {
try {
handleSubmit((T)infoModel.getObject());
setResponsePage(GeoServerHomePage.class);
}
catch(Exception e) {
error(e);
}
}
};
form.add(submit);
Button cancel = new Button( "cancel", new StringResourceModel( "cancel", (Component)null, null) ) {
public void onSubmit() {
setResponsePage(GeoServerHomePage.class);
}
};
form.add( cancel );
//cancel.setDefaultFormProcessing( false );
}
protected ListView createExtensionPanelList(String id, final IModel infoModel) {
List<AdminPagePanelInfo> panels =
getGeoServerApplication().getBeansOfType(AdminPagePanelInfo.class);
for (Iterator<AdminPagePanelInfo> it = panels.iterator(); it.hasNext();) {
AdminPagePanelInfo panel = it.next();
if (!getServiceClass().equals(panel.getServiceClass())) {
it.remove();
}
}
return new ListView<AdminPagePanelInfo>(id, panels) {
@Override
protected void populateItem(ListItem<AdminPagePanelInfo> item) {
AdminPagePanelInfo info = item.getModelObject();
try {
AdminPagePanel panel = info.getComponentClass().getConstructor(
String.class, IModel.class).newInstance("content", infoModel);
item.add(panel);
}
catch (Exception e) {
throw new WicketRuntimeException("Failed to create admin extension panel of " +
"type " + info.getComponentClass().getSimpleName(), e);
}
}
};
}
/**
* The class of the service.
* <p>
* This value is used to obtain a reference to the service info
* object via {@link GeoServer#getService(Class)}.
* </p>
*/
protected abstract Class<T> getServiceClass();
/**
* Builds the form for the page.
* <p>
* The form uses a {@link CompoundPropertyModel} so in the normal
* case components do not need a model as its inherited from the parent.
* This means that component id's should match the info bean property
* they correspond to.
* </p>
* @param info The service info object.
* @param form The page form.
*/
protected abstract void build(IModel info, Form form ); // {
// }
/**
* Callback for submit.
* <p>
* This implementation simply saves the service. Subclasses may
* extend / override if need be.
* </p>
* @param info
*/
protected void handleSubmit( T info ) {
getGeoServer().save( info );
}
/**
* The string to use when representing this service to users.
* Subclasses must override.
*/
protected abstract String getServiceName();
}