/* (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.web.data.store.arcsde;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME;
import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
import org.geoserver.web.util.MapModel;
import org.geotools.arcsde.session.ArcSDEConnectionConfig;
import org.geotools.arcsde.session.ISession;
import org.geotools.arcsde.session.ISessionPool;
import org.geotools.arcsde.session.ISessionPoolFactory;
import org.geotools.arcsde.session.SessionPoolFactory;
import org.geotools.arcsde.session.UnavailableConnectionException;
/**
* A panel for {@link ArcSDECoverageStoreEditPanel} that shows a drop down list where to choose the
* raster table to create the coverage store for, and a refresh button to populate the list of
* available raster tables based on the form's connection input fields.
*
* @author Gabriel Roldan
*/
public class RasterTableSelectionPanel extends Panel {
private static final long serialVersionUID = 343924350476584166L;
private transient ISessionPoolFactory sessionPoolFactory;
/**
* temporary parameter name used to hold the raster table selected by the drop down into the
* store's connectionParameters
*/
public static final String TABLE_NAME = "tableName";
private static final String RESOURCE_KEY_PREFIX = RasterTableSelectionPanel.class
.getSimpleName();
private final DropDownChoice choice;
private FormComponent serverComponent;
private FormComponent portComponent;
private FormComponent instanceComponent;
private FormComponent userComponent;
private FormComponent passwordComponent;
public RasterTableSelectionPanel(final String id, final IModel paramsModel,
final Form storeEditForm, FormComponent server, FormComponent port,
FormComponent instance, FormComponent user, FormComponent password) {
super(id);
this.serverComponent = server;
this.portComponent = port;
this.instanceComponent = instance;
this.userComponent = user;
this.passwordComponent = password;
final MapModel tableNameModel = new MapModel(paramsModel, TABLE_NAME);
List<String> choices = new ArrayList<String>();
if (tableNameModel.getObject() != null) {
Object currentTableName = tableNameModel.getObject();
choices.add(String.valueOf(currentTableName));
}
choice = new DropDownChoice("rasterTable", tableNameModel, choices);
/*
* Make table name match the option id
*/
choice.setChoiceRenderer(new IChoiceRenderer() {
private static final long serialVersionUID = 1L;
public String getIdValue(Object tableName, int index) {
return tableName.toString();
}
public Object getDisplayValue(Object tableName) {
return tableName;
}
});
choice.setOutputMarkupId(true);
choice.setNullValid(false);
choice.setRequired(true);
final FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
feedback.add(choice);
add(feedback);
{
final String titleKey = RESOURCE_KEY_PREFIX + ".tableNameChoice.title";
ResourceModel titleModel = new ResourceModel(titleKey);
String title = String.valueOf(titleModel.getObject());
choice.add(new SimpleAttributeModifier("title", title));
}
final AjaxSubmitLink refreshTablesLink = new AjaxSubmitLink("refresh", storeEditForm) {
private static final long serialVersionUID = 1L;
/**
* We're not doing any validation here, just want to perform the same attempt to get to
* the list of connection parameters than at {@link #onSumbit}
*/
@Override
protected void onError(AjaxRequestTarget target, Form form) {
onSubmit(target, form);
}
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form form) {
final String server = serverComponent.getValue();
final String port = portComponent.getValue();
final String instance = instanceComponent.getValue();
final String user = userComponent.getValue();
final String password = passwordComponent.getValue();
final ISessionPoolFactory sessionFac = getSessionFactory();
List<String> rasterColumns;
try {
rasterColumns = getRasterColumns(server, port, instance, user, password,
sessionFac);
} catch (IllegalArgumentException e) {
rasterColumns = Collections.emptyList();
String message = "Refreshing raster tables list: " + e.getMessage();
storeEditForm.error(message);
target.addComponent(storeEditForm);// refresh
}
choice.setChoices(rasterColumns);
target.addComponent(choice);
// do nothing else, so we return to the same page...
}
};
add(refreshTablesLink);
{
final String titleKey = RESOURCE_KEY_PREFIX + ".refresh.title";
ResourceModel titleModel = new ResourceModel(titleKey);
String title = String.valueOf(titleModel.getObject());
refreshTablesLink.add(new SimpleAttributeModifier("title", title));
}
}
public DropDownChoice getFormComponent() {
return choice;
}
private ISessionPoolFactory getSessionFactory() {
if (this.sessionPoolFactory == null) {
final ISessionPoolFactory sessionFac = SessionPoolFactory.getInstance();
this.sessionPoolFactory = sessionFac;
}
return this.sessionPoolFactory;
}
void setSessionFactory(final ISessionPoolFactory factory) {
this.sessionPoolFactory = factory;
}
/**
*
* @param server
* @param port
* @param instance
* @param user
* @param password
* @param sessionFac
* @return
* @throws IllegalArgumentException
*/
List<String> getRasterColumns(final String server, final String port, final String instance,
final String user, final String password, final ISessionPoolFactory sessionFac)
throws IllegalArgumentException {
final ISessionPool pool;
{
final ArcSDEConnectionConfig connectionConfig;
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(SERVER_NAME_PARAM_NAME, server);
params.put(PORT_NUMBER_PARAM_NAME, port);
params.put(INSTANCE_NAME_PARAM_NAME, instance);
params.put(USER_NAME_PARAM_NAME, user);
params.put(PASSWORD_PARAM_NAME, password);
params.put(MIN_CONNECTIONS_PARAM_NAME, "1");
params.put(MAX_CONNECTIONS_PARAM_NAME, "1");
params.put(CONNECTION_TIMEOUT_PARAM_NAME, "1000");
connectionConfig = ArcSDEConnectionConfig.fromMap(params);
try {
pool = sessionFac.createPool(connectionConfig);
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
ISession session;
try {
session = pool.getSession();
} catch (IOException e) {
throw new IllegalAccessError(e.getMessage());
} catch (UnavailableConnectionException e) {
throw new IllegalAccessError(e.getMessage());
}
final List<String> rasterTables;
try {
rasterTables = session.getRasterColumns();
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
} finally {
session.dispose();
pool.close();
}
return rasterTables;
}
}