001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.catalog.internal.wfs.ui;
018:
019: import java.io.IOException;
020: import java.io.Serializable;
021: import java.net.ConnectException;
022: import java.net.URL;
023: import java.util.ArrayList;
024: import java.util.Arrays;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030:
031: import net.refractions.udig.catalog.CatalogPlugin;
032: import net.refractions.udig.catalog.IService;
033: import net.refractions.udig.catalog.internal.wfs.WFSServiceImpl;
034: import net.refractions.udig.catalog.internal.wfs.WfsPlugin;
035: import net.refractions.udig.catalog.ui.UDIGConnectionPage;
036: import net.refractions.udig.catalog.ui.wizard.DataStoreWizardPage;
037: import net.refractions.udig.catalog.ui.workflow.ConnectionState;
038: import net.refractions.udig.catalog.ui.workflow.WorkflowWizard;
039: import net.refractions.udig.catalog.wfs.internal.Messages;
040:
041: import org.eclipse.core.runtime.IProgressMonitor;
042: import org.eclipse.jface.dialogs.IDialogSettings;
043: import org.eclipse.jface.viewers.IStructuredSelection;
044: import org.eclipse.jface.wizard.WizardPage;
045: import org.eclipse.swt.SWT;
046: import org.eclipse.swt.events.ModifyEvent;
047: import org.eclipse.swt.events.ModifyListener;
048: import org.eclipse.swt.events.SelectionEvent;
049: import org.eclipse.swt.events.SelectionListener;
050: import org.eclipse.swt.graphics.Color;
051: import org.eclipse.swt.layout.GridData;
052: import org.eclipse.swt.layout.GridLayout;
053: import org.eclipse.swt.widgets.Button;
054: import org.eclipse.swt.widgets.Combo;
055: import org.eclipse.swt.widgets.Composite;
056: import org.eclipse.swt.widgets.Display;
057: import org.eclipse.swt.widgets.Group;
058: import org.eclipse.swt.widgets.Label;
059: import org.eclipse.swt.widgets.Text;
060: import org.eclipse.ui.PlatformUI;
061: import org.geotools.data.DataStoreFactorySpi;
062: import org.geotools.data.wfs.WFSDataStoreFactory;
063:
064: /**
065: * Data page responsible for aquiring WFS services.
066: * <p>
067: * Responsibilities:
068: * <ul>
069: * <li>defaults based on selection - for URL, WFSService, and generic IService (from search)
070: * <li>remember history in dialog settings
071: * <li>complete list here: <a
072: * href="http://udig.refractions.net/confluence/display/DEV/UDIGImportPage+Checklist">Import Page
073: * Checklist</a>
074: * </ul>
075: * </p>
076: * <p>
077: * This page is used in the Import and Add Layer wizards.
078: * </p>
079: *
080: * @since 1.0.0
081: */
082: public class WFSRegistryWizardPage extends DataStoreWizardPage
083: implements ModifyListener, SelectionListener,
084: UDIGConnectionPage {
085:
086: protected Combo urlCombo = null;
087: // protected Text user = null;
088: // protected Text pass = null;
089:
090: private Button advancedTag = null;
091: private Composite advanced = null;
092:
093: protected Button getDefault;
094: protected Button postDefault;
095:
096: protected Text bufferText;
097: protected Text timeoutText;
098: protected static final String timeoutDefault = "3"; //$NON-NLS-1$
099: protected static final String bufferDefault = "100"; //$NON-NLS-1$
100:
101: private IDialogSettings settings;
102: private static final String WFS_WIZARD_ID = "WFSWizard"; //$NON-NLS-1$
103: private static final String WFS_RECENTLY_USED_ID = "RecentlyUsed"; //$NON-NLS-1$
104: private String url = ""; //$NON-NLS-1$
105:
106: WFSConnectionFactory wfsConnFactory = new WFSConnectionFactory();
107:
108: public WFSRegistryWizardPage(String name) {
109: super (name);
110: settings = WfsPlugin.getDefault().getDialogSettings()
111: .getSection(WFS_WIZARD_ID);
112: if (settings == null) {
113: settings = WfsPlugin.getDefault().getDialogSettings()
114: .addNewSection(WFS_WIZARD_ID);
115: }
116: }
117:
118: public WFSRegistryWizardPage() {
119: this (""); //$NON-NLS-1$
120: }
121:
122: public String getId() {
123: return "net.refractions.udig.catalog.ui.wfs"; //$NON-NLS-1$
124: }
125:
126: // /**
127: // * True if this is a *real* wfs, or plays one on tv.
128: // * <p>
129: // * If this is real WFS, toWFS( Object data ) can be used to check for
130: // * explict parameter settings.
131: // * </p>
132: // *
133: // * @param data
134: // * @return boolean
135: // */
136: // protected boolean isWFS( Object data ){
137: // if( data instanceof WFSServiceImpl ){
138: // return true;
139: // }
140: // URL url = wfsConnFactory.toCapabilitiesURL( data );
141: // if( url == null ) return false;
142: // List<IResolve> list = CatalogPlugin.getDefault().getLocalCatalog().find( url, blm );
143: // for( IResolve resolve : list ){
144: // if( resolve instanceof WFSServiceImpl) return true;
145: // }
146: // return false;
147: // }
148:
149: /** Can be called during createControl */
150: protected Map<String, Serializable> defaultParams() {
151: IStructuredSelection selection = (IStructuredSelection) PlatformUI
152: .getWorkbench().getActiveWorkbenchWindow()
153: .getSelectionService().getSelection();
154: Map<String, Serializable> toParams = toParams(selection);
155: if (!toParams.isEmpty()) {
156: return toParams;
157: }
158:
159: WFSConnectionFactory connectionFactory = new WFSConnectionFactory();
160: Map<String, Serializable> params = connectionFactory
161: .createConnectionParameters(getState().getWorkflow()
162: .getContext());
163: if (params != null)
164: return params;
165:
166: return Collections.emptyMap();
167: }
168:
169: /** Retrieve "best" WFS guess of parameters based on provided context */
170: protected Map<String, Serializable> toParams(
171: IStructuredSelection context) {
172: if (context == null) {
173: // lets go with the defaults then
174: return Collections.emptyMap();
175: }
176: for (Iterator itr = context.iterator(); itr.hasNext();) {
177: Map<String, Serializable> params = wfsConnFactory
178: .createConnectionParameters(itr.next());
179: if (!params.isEmpty())
180: return params;
181: }
182: return Collections.emptyMap();
183: }
184:
185: /**
186: * TODO summary sentence for createControl ...
187: *
188: * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
189: * @param parent
190: */
191: public void createControl(Composite arg0) {
192: Composite composite = new Group(arg0, SWT.NULL);
193: composite.setLayout(new GridLayout(2, false));
194:
195: // add url
196: Label label = new Label(composite, SWT.NONE);
197: label.setText(Messages.WFSRegistryWizardPage_label_url_text);
198: label
199: .setToolTipText(Messages.WFSRegistryWizardPage_label_url_tooltip);
200: label.setLayoutData(new GridData(SWT.END, SWT.DEFAULT, false,
201: false));
202:
203: /*
204: url = new Text( composite, SWT.BORDER | SWT.SINGLE );
205: url.setLayoutData( new GridData(GridData.FILL_HORIZONTAL) );
206: url.setText( "http://" );
207: url.addModifyListener(this);
208: */
209: String[] temp = settings.getArray(WFS_RECENTLY_USED_ID);
210: if (temp == null) {
211: temp = new String[0];
212: }
213: List<String> recent = Arrays.asList(temp);
214: GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
215: gridData.widthHint = 400;
216:
217: //For Drag 'n Drop as well as for general selections
218: // look for a url as part of the selction
219: Map<String, Serializable> params = defaultParams(); // based on selection
220: URL selectedURL;
221: try {
222: selectedURL = (URL) WFSDataStoreFactory.URL.lookUp(params);
223: } catch (IOException e) {
224: selectedURL = null;
225: }
226: //URL selectedURL = (URL) params.get( WFSDataStoreFactory.URL.key );
227:
228: urlCombo = new Combo(composite, SWT.BORDER);
229: urlCombo.setItems(recent.toArray(new String[recent.size()]));
230: urlCombo.setVisibleItemCount(15);
231: urlCombo.setLayoutData(gridData);
232: if (selectedURL != null) {
233: urlCombo.setText(selectedURL.toExternalForm());
234: } else if (url != null && url.length() != 0) {
235: urlCombo.setText(url);
236: } else {
237: urlCombo.setText("http://"); //$NON-NLS-1$
238: }
239: urlCombo.addModifyListener(this );
240:
241: // add spacer
242: label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
243: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
244: false, 3, 3));
245:
246: // // usr
247: // label = new Label( composite, SWT.NONE );
248: // label.setText(Messages.WFSRegistryWizardPage_label_username_text );
249: // label.setToolTipText( Messages.WFSRegistryWizardPage_label_username_tooltip );
250: // label.setLayoutData( new GridData(SWT.END, SWT.DEFAULT, false, false ) );
251: //
252: // user = new Text( composite, SWT.BORDER );
253: // user.setLayoutData( new GridData(GridData.FILL_HORIZONTAL) );
254: // user.addModifyListener(this);
255: //
256: // pass
257: // label = new Label( composite, SWT.NONE );
258: // label.setText(Messages.WFSRegistryWizardPage_label_password_text );
259: // label.setToolTipText( Messages.WFSRegistryWizardPage_label_password_tooltip );
260: // label.setLayoutData( new GridData(SWT.END, SWT.DEFAULT, false, false ) );
261: //
262: // pass = new Text( composite, SWT.BORDER | SWT.PASSWORD );
263: // pass.setLayoutData( new GridData(GridData.FILL_HORIZONTAL) );
264: // pass.addModifyListener(this);
265: //
266: // add advanced stuff
267:
268: advancedTag = new Button(composite, SWT.CHECK);
269: advancedTag.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
270: false, false));
271: advancedTag.setSelection(false);
272: advancedTag.addSelectionListener(this );
273: advancedTag
274: .setText(Messages.WFSRegistryWizardPage_advanced_text);
275: advancedTag
276: .setToolTipText(Messages.WFSRegistryWizardPage_advanced_tooltip);
277:
278: label = new Label(composite, SWT.NONE);
279: label.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT,
280: false, false));
281:
282: advanced = createAdvancedControl(composite);
283: advanced.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
284: true, true, 2, 1));
285:
286: setControl(composite);
287: setPageComplete(true);
288:
289: urlCombo.addModifyListener(this );
290:
291: Display.getCurrent().asyncExec(new Runnable() {
292: public void run() {
293:
294: ConnectionState currentState = getState();
295: Map<IService, Throwable> errors = currentState
296: .getErrors();
297: if (errors != null && !errors.isEmpty()) {
298: for (Map.Entry<IService, Throwable> entry : errors
299: .entrySet()) {
300: if (entry.getKey() instanceof WFSServiceImpl) {
301: Throwable value = entry.getValue();
302: if (value instanceof ConnectException) {
303: setErrorMessage(Messages.WFSRegistryWizardPage_serverConnectionProblem);
304: } else {
305: String message = Messages.WFSRegistryWizardPage_problemConnecting
306: + value.getLocalizedMessage();
307: setErrorMessage(message);
308: }
309: }
310: }
311: }
312:
313: }
314: });
315:
316: }
317:
318: private Composite createAdvancedControl(Composite arg0) {
319: advanced = new Group(arg0, SWT.BORDER);
320: advanced.setLayout(new GridLayout(2, false));
321:
322: // get
323: Label label = new Label(advanced, SWT.NONE);
324: label.setText("GET"); //$NON-NLS-1$
325: label
326: .setToolTipText(Messages.WFSRegistryWizardPage_label_get_tooltip);
327: label.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
328: false, false));
329:
330: getDefault = new Button(advanced, SWT.CHECK);
331: getDefault.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
332: false, false));
333: getDefault.setSelection(false);
334: getDefault.addSelectionListener(this );
335:
336: // post
337: label = new Label(advanced, SWT.NONE);
338: label.setText("POST"); //$NON-NLS-1$
339: label
340: .setToolTipText(Messages.WFSRegistryWizardPage_label_post_tooltip);
341: label.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
342: false, false));
343:
344: postDefault = new Button(advanced, SWT.CHECK);
345: postDefault.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
346: false, false));
347: postDefault.setSelection(false);
348: postDefault.addSelectionListener(this );
349:
350: // add spacer
351: label = new Label(advanced, SWT.SEPARATOR | SWT.HORIZONTAL);
352: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
353: false, 2, 3));
354:
355: // buffer
356: label = new Label(advanced, SWT.NONE);
357: label.setText(Messages.WFSRegistryWizardPage_label_buffer_text);
358: label
359: .setToolTipText(Messages.WFSRegistryWizardPage_label_buffer_tooltip);
360: label.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
361: false, false));
362:
363: bufferText = new Text(advanced, SWT.BORDER | SWT.RIGHT);
364: bufferText.setLayoutData(new GridData(GridData.FILL,
365: SWT.DEFAULT, true, false));
366: bufferText.setText(bufferDefault);
367: bufferText.setTextLimit(5);
368: bufferText.addModifyListener(this );
369:
370: // timeout
371: label = new Label(advanced, SWT.NONE);
372: label
373: .setText(Messages.WFSRegistryWizardPage_label_timeout_text);
374: label
375: .setToolTipText(Messages.WFSRegistryWizardPage_label_timeout_tooltip);
376: label.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT,
377: false, false));
378:
379: timeoutText = new Text(advanced, SWT.BORDER | SWT.RIGHT);
380: timeoutText.setLayoutData(new GridData(GridData.FILL,
381: SWT.DEFAULT, true, false, 1, 1));
382: timeoutText.setText(timeoutDefault);
383: timeoutText.setTextLimit(5);
384: timeoutText.addModifyListener(this );
385:
386: advanced.setVisible(false);
387:
388: return advanced;
389: }
390:
391: @Override
392: public void setErrorMessage(String newMessage) {
393: WizardPage page = (WizardPage) getContainer().getCurrentPage();
394: page.setErrorMessage(newMessage);
395: }
396:
397: @Override
398: public void setMessage(String newMessage) {
399: WizardPage page = (WizardPage) getContainer().getCurrentPage();
400: page.setMessage(newMessage);
401: }
402:
403: @Override
404: public void setMessage(String newMessage, int messageType) {
405: WizardPage page = (WizardPage) getContainer().getCurrentPage();
406: page.setMessage(newMessage, messageType);
407: }
408:
409: private ConnectionState getState() {
410: WorkflowWizard wizard = (WorkflowWizard) getWizard();
411: ConnectionState currentState = (ConnectionState) (wizard)
412: .getWorkflow().getCurrentState();
413: return currentState;
414: }
415:
416: @Override
417: public void dispose() {
418: super .dispose();
419: if (red != null)
420: red.dispose();
421: }
422:
423: public void modifyText(ModifyEvent e) {
424: if (e.widget != null && e.widget instanceof Text)
425: ((Text) e.widget).setForeground(null);
426: if (e.widget == urlCombo) {
427: ((Combo) e.widget).setForeground(null);
428: setErrorMessage(null);
429: url = urlCombo.getText();
430: }
431: getContainer().updateButtons();
432: }
433:
434: /**
435: * TODO summary sentence for widgetSelected ...
436: *
437: * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
438: * @param e
439: */
440: public void widgetSelected(SelectionEvent e) {
441: Button b = (Button) e.widget;
442: if (b.equals(getDefault)) {
443: // allow get was clicked
444: if (getDefault.getSelection() && postDefault.getSelection()) {
445: postDefault.setSelection(false);
446: }
447: } else {
448: if (b.equals(postDefault)) {
449: if (postDefault.getSelection()
450: && getDefault.getSelection()) {
451: getDefault.setSelection(false);
452: }
453: } else {
454: if (b.equals(advancedTag)) {
455: advanced.setVisible(advancedTag.getSelection());
456: }
457: }
458: }
459:
460: getWizard().getContainer().updateButtons();
461: }
462:
463: /**
464: * Double click in list, or return from url control.
465: *
466: * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
467: * @param e
468: */
469: public void widgetDefaultSelected(SelectionEvent e) {
470: if (getWizard().canFinish()) {
471: getWizard().performFinish();
472: }
473: }
474:
475: private Color red;
476:
477: @Override
478: public boolean isPageComplete() {
479: Map<String, Serializable> params = getParams();
480: if (params == null)
481: return false;
482: URL url = (URL) params.get(WFSDataStoreFactory.URL.key);
483: String trim = url.getHost().trim();
484: if (trim.length() == 0)
485: return false;
486: return factory.canProcess(params);
487: }
488:
489: private WFSDataStoreFactory factory = new WFSDataStoreFactory();
490: private static final int COMBO_HISTORY_LENGTH = 15;
491:
492: public List<URL> getURLs() {
493: return null;
494: }
495:
496: public Map<String, Serializable> getParams() {
497: Map<String, Serializable> r = new HashMap<String, Serializable>();
498: boolean error = false;
499: try {
500: URL u = new URL(urlCombo.getText());
501: r.put(WFSDataStoreFactory.URL.key, u);
502: } catch (Exception e) {
503: if (red == null)
504: red = new Color(null, 255, 0, 0);
505: urlCombo.setForeground(red);
506: error = true;
507: }
508: // if(user.getText()!=null && !user.getText().equals("")){ //$NON-NLS-1$
509: // String username = user.getText();
510: // String password = pass.getText();
511: // if(password == null || "".equals(password)){ //$NON-NLS-1$
512: // if(red == null)
513: // red = new Color(null,255,0,0);
514: // user.setForeground(red);
515: // pass.setForeground(red);
516: // error = true;
517: // }
518: // r.put(WFSDataStoreFactory.USERNAME.key,username);
519: // r.put(WFSDataStoreFactory.PASSWORD.key,password);
520: // }
521:
522: if (postDefault.getSelection()) {
523: r.put(WFSDataStoreFactory.PROTOCOL.key, Boolean.TRUE);
524: } else {
525: if (getDefault.getSelection()) {
526: r.put(WFSDataStoreFactory.PROTOCOL.key, Boolean.FALSE);
527: } else {
528: r.put(WFSDataStoreFactory.PROTOCOL.key, null);
529: }
530: }
531:
532: String timeout = timeoutText.getText();
533: if (!WFSRegistryWizardPage.timeoutDefault.equals(timeout)) {
534: // parse the string
535: Integer sec = null;
536: try {
537: sec = new Integer(timeout);
538: } catch (NumberFormatException e) {
539: if (red == null)
540: red = new Color(null, 255, 0, 0);
541: timeoutText.setForeground(red);
542: error = true;
543: }
544: r.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(sec
545: .intValue() * 1000));
546: }
547:
548: String buffer = bufferText.getText();
549: if (!WFSRegistryWizardPage.bufferDefault.equals(buffer)) {
550: // parse the string
551: Integer sec = null;
552: try {
553: sec = new Integer(buffer);
554: } catch (NumberFormatException e) {
555: if (red == null)
556: red = new Color(null, 255, 0, 0);
557: bufferText.setForeground(red);
558: error = true;
559: }
560: r.put(WFSDataStoreFactory.BUFFER_SIZE.key, sec);
561: }
562:
563: return error ? null : r;
564: }
565:
566: /*
567: * @see net.refractions.udig.catalog.ui.UDIGImportPage#getResources(org.eclipse.core.runtime.IProgressMonitor)
568: */
569: public List<IService> getResources(IProgressMonitor monitor)
570: throws Exception {
571: if (!isPageComplete())
572: return null;
573:
574: List<IService> list = CatalogPlugin.getDefault()
575: .getServiceFactory().acquire(getParams());
576: saveWidgetValues();
577: return (List<IService>) list;
578: }
579:
580: /**
581: * TODO summary sentence for getDataStoreFactorySpi ...
582: *
583: * @see net.refractions.udig.catalog.internal.ui.datastore.DataStoreWizard#getDataStoreFactorySpi()
584: * @return
585: */
586: protected DataStoreFactorySpi getDataStoreFactorySpi() {
587: return factory;
588: }
589:
590: /**
591: * Saves the widget values
592: */
593: private void saveWidgetValues() {
594: // Update history
595: if (settings != null) {
596: String[] recentWFSs = settings
597: .getArray(WFS_RECENTLY_USED_ID);
598: if (recentWFSs == null)
599: recentWFSs = new String[0];
600: recentWFSs = addToHistory(recentWFSs, urlCombo.getText());
601: settings.put(WFS_RECENTLY_USED_ID, recentWFSs);
602: }
603: }
604:
605: /**
606: * Adds an entry to a history, while taking care of duplicate history items
607: * and excessively long histories. The assumption is made that all histories
608: * should be of length <code>ConfigurationWizardMainPage.COMBO_HISTORY_LENGTH</code>.
609: *
610: * @param history the current history
611: * @param newEntry the entry to add to the history
612: * @return the history with the new entry appended
613: * Stolen from org.eclipse.team.internal.ccvs.ui.wizards.ConfigurationWizardMainPage
614: */
615: private String[] addToHistory(String[] history, String newEntry) {
616: ArrayList<String> l = new ArrayList<String>(Arrays
617: .asList(history));
618: addToHistory(l, newEntry);
619: String[] r = new String[l.size()];
620: l.toArray(r);
621: return r;
622: }
623:
624: /**
625: * Adds an entry to a history, while taking care of duplicate history items
626: * and excessively long histories. The assumption is made that all histories
627: * should be of length <code>ConfigurationWizardMainPage.COMBO_HISTORY_LENGTH</code>.
628: *
629: * @param history the current history
630: * @param newEntry the entry to add to the history
631: * Stolen from org.eclipse.team.internal.ccvs.ui.wizards.ConfigurationWizardMainPage
632: */
633: private void addToHistory(List<String> history, String newEntry) {
634: history.remove(newEntry);
635: history.add(0, newEntry);
636:
637: // since only one new item was added, we can be over the limit
638: // by at most one item
639: if (history.size() > COMBO_HISTORY_LENGTH)
640: history.remove(COMBO_HISTORY_LENGTH);
641: }
642: }
|