001: package net.refractions.udig.catalog.internal.wms.ui;
002:
003: import java.io.Serializable;
004: import java.net.ConnectException;
005: import java.net.MalformedURLException;
006: import java.net.URL;
007: import java.util.ArrayList;
008: import java.util.Arrays;
009: import java.util.Collections;
010: import java.util.Iterator;
011: import java.util.List;
012: import java.util.Map;
013:
014: import net.refractions.udig.catalog.IService;
015: import net.refractions.udig.catalog.internal.wms.WMSServiceExtension;
016: import net.refractions.udig.catalog.internal.wms.WMSServiceImpl;
017: import net.refractions.udig.catalog.internal.wms.WmsPlugin;
018: import net.refractions.udig.catalog.ui.UDIGConnectionPage;
019: import net.refractions.udig.catalog.ui.workflow.ConnectionState;
020: import net.refractions.udig.catalog.ui.workflow.WorkflowWizard;
021: import net.refractions.udig.catalog.wms.internal.Messages;
022:
023: import org.eclipse.core.runtime.IProgressMonitor;
024: import org.eclipse.jface.dialogs.IDialogSettings;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.wizard.WizardPage;
027: import org.eclipse.swt.SWT;
028: import org.eclipse.swt.events.ModifyEvent;
029: import org.eclipse.swt.events.ModifyListener;
030: import org.eclipse.swt.events.SelectionEvent;
031: import org.eclipse.swt.layout.GridData;
032: import org.eclipse.swt.layout.GridLayout;
033: import org.eclipse.swt.widgets.Combo;
034: import org.eclipse.swt.widgets.Composite;
035: import org.eclipse.swt.widgets.Display;
036: import org.eclipse.swt.widgets.Label;
037: import org.eclipse.ui.PlatformUI;
038:
039: /**
040: * Data page responsible for aquiring WMS services.
041: * <p>
042: * Responsibilities:
043: * <ul>
044: * <li>defaults based on selection - for URL, WMSService, and generic IService (from search)
045: * <li>remember history in dialog settings
046: * <li>complete list here: <a
047: * href="http://udig.refractions.net/confluence/display/DEV/UDIGImportPage+Checklist">Import Page
048: * Checklist</a>
049: * </ul>
050: * </p>
051: * <p>
052: * This page is used in the Import and Add Layer wizards.
053: * </p>
054: *
055: * @author jgarnett
056: * @since 1.0.0
057: */
058: public class WMSWizardPage extends WizardPage implements
059: ModifyListener, UDIGConnectionPage {
060:
061: final static String[] types = { "WMS", "Directory" }; //$NON-NLS-1$ //$NON-NLS-2$
062:
063: private String url = ""; //$NON-NLS-1$
064:
065: private static final String WMS_WIZARD = "WMS_WIZARD"; //$NON-NLS-1$
066: private static final String WMS_RECENT = "WMS_RECENT"; //$NON-NLS-1$
067: private IDialogSettings settings;
068: private static final int COMBO_HISTORY_LENGTH = 15;
069:
070: private Combo urlCombo;
071:
072: /**
073: * Construct <code>WMSWizardPage</code>.
074: *
075: * @param pageName
076: */
077: public WMSWizardPage() {
078: super (Messages.WMSWizardPage_title);
079:
080: settings = WmsPlugin.getDefault().getDialogSettings()
081: .getSection(WMS_WIZARD);
082: if (settings == null) {
083: settings = WmsPlugin.getDefault().getDialogSettings()
084: .addNewSection(WMS_WIZARD);
085: }
086: }
087:
088: public String getId() {
089: return "net.refractions.udig.catalog.ui.WMS"; //$NON-NLS-1$
090: }
091:
092: /** Can be called during createControl */
093: protected Map<String, Serializable> defaultParams() {
094: IStructuredSelection selection = (IStructuredSelection) PlatformUI
095: .getWorkbench().getActiveWorkbenchWindow()
096: .getSelectionService().getSelection();
097: Map<String, Serializable> toParams = toParams(selection);
098: if (!toParams.isEmpty()) {
099: return toParams;
100: }
101:
102: WMSConnectionFactory connectionFactory = new WMSConnectionFactory();
103: Map<String, Serializable> params = connectionFactory
104: .createConnectionParameters(getState().getWorkflow()
105: .getContext());
106: if (params != null)
107: return params;
108:
109: return Collections.emptyMap();
110: }
111:
112: /** Retrieve "best" WMS guess of parameters based on provided context */
113: protected Map<String, Serializable> toParams(
114: IStructuredSelection context) {
115: if (context != null) {
116: WMSConnectionFactory connectionFactory = new WMSConnectionFactory();
117: for (Iterator itr = context.iterator(); itr.hasNext();) {
118: Map<String, Serializable> params = connectionFactory
119: .createConnectionParameters(itr.next());
120: if (!params.isEmpty())
121: return params;
122: }
123: }
124: return Collections.EMPTY_MAP;
125: }
126:
127: public void createControl(Composite parent) {
128: String[] recentWMSs = settings.getArray(WMS_RECENT);
129: if (recentWMSs == null) {
130: recentWMSs = new String[0];
131: }
132:
133: GridData gridData;
134: Composite composite = new Composite(parent, SWT.NULL);
135:
136: GridLayout gridLayout = new GridLayout();
137: int columns = 1;
138: gridLayout.numColumns = columns;
139: composite.setLayout(gridLayout);
140:
141: gridData = new GridData();
142:
143: Label urlLabel = new Label(composite, SWT.NONE);
144: urlLabel.setText(Messages.WMSWizardPage_label_url_text);
145: urlLabel.setLayoutData(gridData);
146:
147: gridData = new GridData(GridData.FILL_HORIZONTAL);
148: gridData.widthHint = 400;
149:
150: // For Drag 'n Drop as well as for general selections
151: // look for a url as part of the selction
152: Map<String, Serializable> params = defaultParams(); // based on selection
153:
154: urlCombo = new Combo(composite, SWT.BORDER);
155: urlCombo.setItems(recentWMSs);
156: urlCombo.setVisibleItemCount(15);
157: urlCombo.setLayoutData(gridData);
158:
159: URL selectedURL = getURL(params);
160: if (selectedURL != null) {
161: urlCombo.setText(selectedURL.toExternalForm());
162: url = selectedURL.toExternalForm();
163: setPageComplete(true);
164: } else if (url != null && url.length() != 0) {
165: urlCombo.setText(url);
166: setPageComplete(true);
167: } else {
168: url = null;
169: urlCombo.setText("http://"); //$NON-NLS-1$
170: setPageComplete(false);
171: }
172: urlCombo.addModifyListener(this );
173:
174: setControl(composite);
175:
176: Display.getCurrent().asyncExec(new Runnable() {
177: public void run() {
178:
179: ConnectionState currentState = getState();
180: Map<IService, Throwable> errors = currentState
181: .getErrors();
182: if (errors != null && !errors.isEmpty()) {
183: for (Map.Entry<IService, Throwable> entry : errors
184: .entrySet()) {
185: if (entry.getKey() instanceof WMSServiceImpl) {
186: Throwable value = entry.getValue();
187: if (value instanceof ConnectException) {
188: setErrorMessage(Messages.WMSWizardPage_serverConnectionError);
189: } else {
190: String message = Messages.WMSWizardPage_connectionProblem
191: + value.getLocalizedMessage();
192: setErrorMessage(message);
193: }
194: }
195: }
196: }
197:
198: }
199: });
200: }
201:
202: @Override
203: public void setErrorMessage(String newMessage) {
204: WizardPage page = (WizardPage) getContainer().getCurrentPage();
205: page.setErrorMessage(newMessage);
206: }
207:
208: @Override
209: public void setMessage(String newMessage) {
210: WizardPage page = (WizardPage) getContainer().getCurrentPage();
211: page.setMessage(newMessage);
212: }
213:
214: @Override
215: public void setMessage(String newMessage, int messageType) {
216: WizardPage page = (WizardPage) getContainer().getCurrentPage();
217: page.setMessage(newMessage, messageType);
218: }
219:
220: private ConnectionState getState() {
221: WorkflowWizard wizard = (WorkflowWizard) getWizard();
222: ConnectionState currentState = (ConnectionState) (wizard)
223: .getWorkflow().getCurrentState();
224: return currentState;
225: }
226:
227: public URL getURL(Map<String, Serializable> params) {
228: Object value = params.get(WMSServiceImpl.WMS_URL_KEY);
229: if (value == null)
230: return null;
231: if (value instanceof URL)
232: return (URL) value;
233: if (value instanceof String) {
234: try {
235: URL url = new URL((String) value);
236: return url;
237: } catch (MalformedURLException erp) {
238: }
239: }
240: return null;
241: }
242:
243: /**
244: * Double click in list, or return from url control.
245: *
246: * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
247: * @param e
248: */
249: public void widgetDefaultSelected(SelectionEvent e) {
250: e.getClass();// kill warning
251: if (getWizard().canFinish()) {
252: getWizard().performFinish();
253: }
254: }
255:
256: /**
257: * This should be called using the Wizard .. job when next/finish is pressed.
258: */
259: public List<IService> getResources(IProgressMonitor monitor)
260: throws Exception {
261: URL location = new URL(url);
262:
263: WMSServiceExtension creator = new WMSServiceExtension();
264:
265: Map<String, Serializable> params = creator
266: .createParams(location);
267: IService service = creator.createService(location, params);
268: service.getInfo(monitor); // load it
269:
270: List<IService> servers = new ArrayList<IService>();
271: servers.add(service);
272:
273: /*
274: * Success! Store the URL in history.
275: */
276: saveWidgetValues();
277:
278: return servers;
279: }
280:
281: public void modifyText(ModifyEvent e) {
282: try {
283: getState().getErrors().clear();
284: url = ((Combo) e.getSource()).getText();
285: new URL(url);
286: setErrorMessage(null);
287: setPageComplete(true);
288: } catch (MalformedURLException exception) {
289: setErrorMessage(Messages.WMSWizardPage_error_invalidURL);
290: setPageComplete(false);
291: }
292:
293: getWizard().getContainer().updateButtons();
294: }
295:
296: /**
297: * Saves the widget values
298: */
299: private void saveWidgetValues() {
300: // Update history
301: if (settings != null) {
302: String[] recentWMSs = settings.getArray(WMS_RECENT);
303: if (recentWMSs == null) {
304: recentWMSs = new String[0];
305: }
306: recentWMSs = addToHistory(recentWMSs, url);
307: settings.put(WMS_RECENT, recentWMSs);
308: }
309: }
310:
311: /**
312: * Adds an entry to a history, while taking care of duplicate history items and excessively long
313: * histories. The assumption is made that all histories should be of length
314: * <code>COMBO_HISTORY_LENGTH</code>.
315: *
316: * @param history the current history
317: * @param newEntry the entry to add to the history
318: * @return the history with the new entry appended Stolen from
319: * org.eclipse.team.internal.ccvs.ui.wizards.ConfigurationWizardMainPage
320: */
321: private String[] addToHistory(String[] history, String newEntry) {
322: ArrayList<String> l = new ArrayList<String>(Arrays
323: .asList(history));
324: addToHistory(l, newEntry);
325: String[] r = new String[l.size()];
326: l.toArray(r);
327: return r;
328: }
329:
330: /**
331: * Adds an entry to a history, while taking care of duplicate history items and excessively long
332: * histories. The assumption is made that all histories should be of length
333: * <code>COMBO_HISTORY_LENGTH</code>.
334: *
335: * @param history the current history
336: * @param newEntry the entry to add to the history Stolen from
337: * org.eclipse.team.internal.ccvs.ui.wizards.ConfigurationWizardMainPage
338: */
339: private void addToHistory(List<String> history, String newEntry) {
340: history.remove(newEntry);
341: history.add(0, newEntry);
342:
343: // since only one new item was added, we can be over the limit
344: // by at most one item
345: if (history.size() > COMBO_HISTORY_LENGTH)
346: history.remove(COMBO_HISTORY_LENGTH);
347: }
348:
349: public Map<String, Serializable> getParams() {
350: try {
351: URL location = new URL(url);
352:
353: WMSServiceExtension creator = new WMSServiceExtension();
354: String errorMessage = creator.reasonForFailure(location);
355: if (errorMessage != null) {
356: setErrorMessage(errorMessage);
357: return Collections.emptyMap();
358: } else
359: return creator.createParams(location);
360: } catch (MalformedURLException e) {
361: return null;
362: }
363: }
364:
365: public List<URL> getURLs() {
366: try {
367: ArrayList<URL> l = new ArrayList<URL>();
368: l.add(new URL(url));
369:
370: return l;
371: } catch (MalformedURLException e) {
372: return null;
373: }
374: }
375:
376: }
|