[jboss-svn-commits] JBL Code SVN: r20821 - in labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools: src/org/guvnor/tools and 5 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jun 26 16:05:04 EDT 2008


Author: john.graham at jboss.org
Date: 2008-06-26 16:05:04 -0400 (Thu, 26 Jun 2008)
New Revision: 20821

Added:
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/AuthenticationPromptDialog.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/IWebDavClient.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClientFactory.java
Modified:
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/META-INF/MANIFEST.MF
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/GuvnorLocationManager.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/PlatformUtils.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClient.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavException.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavServerCache.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/RepositoryView.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/model/TreeParent.java
   labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/wizards/GuvnorMainConfigPage.java
Log:
Add prompt for user name and password

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/META-INF/MANIFEST.MF
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/META-INF/MANIFEST.MF	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/META-INF/MANIFEST.MF	2008-06-26 20:05:04 UTC (rev 20821)
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin.name
 Bundle-SymbolicName: org.guvnor.tools;singleton:=true
-Bundle-Version: 0.5.0.200806251126
+Bundle-Version: 0.5.0.200806261455
 Bundle-Activator: org.guvnor.tools.Activator
 Bundle-Vendor: %plugin.provider
 Bundle-Localization: plugin

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/GuvnorLocationManager.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/GuvnorLocationManager.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/GuvnorLocationManager.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -60,6 +60,7 @@
 			}
 			res = repList.remove(theRep);
 			Platform.flushAuthorizationInfo(new URL(rep), "", "basic");
+			Activator.getLocationManager().removeRepository(theRep.getLocation());
 			notifyListeners(IRepositorySetListener.REP_ADDED);
 			commit();
 		} catch (Exception e) {

Added: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/AuthenticationPromptDialog.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/AuthenticationPromptDialog.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/AuthenticationPromptDialog.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -0,0 +1,124 @@
+package org.guvnor.tools.utils;
+
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.guvnor.tools.Activator;
+
+/**
+ * A dialog for collecting user authentication information
+ * @author jgraham
+ *
+ */
+public class AuthenticationPromptDialog extends TitleAreaDialog {
+	
+	private static final int INITIAL_WIDTH = 780;
+	private static final int INITIAL_HEIGHT = 350;
+	
+	private Text unField;
+	private Text pwField;
+	
+	private Button cbSavePassword;
+	
+	private String serverName;
+	
+	private String username;
+	private String password;
+	private boolean saveInfo;
+	
+	public AuthenticationPromptDialog(Shell parentShell, String serverName) {
+		super(parentShell);
+		super.setShellStyle(getShellStyle() | SWT.RESIZE);
+		this.serverName = serverName;
+	}
+	
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		super.setTitle("Guvnor Repository Log in");
+		super.setMessage("Authentication required for repository: " + serverName);
+		super.setTitleImage(Activator.getImageDescriptor(Activator.IMG_GUVREPWIZBAN).createImage());
+		
+		Composite composite = createComposite(parent, 2);
+		new Label(composite, SWT.NONE).setText("User Name: ");
+		unField = new Text(composite, SWT.SINGLE | SWT.BORDER);
+		unField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		unField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				username = unField.getText();	
+			}
+		});
+		
+		new Label(composite, SWT.NONE).setText("Password: ");
+		pwField = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
+		pwField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		pwField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				password = pwField.getText();	
+			}
+		});
+		
+		new Label(composite, SWT.NONE).setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		Composite pwgroup = createComposite(composite, 2);
+		cbSavePassword = new Button(pwgroup, SWT.CHECK);
+		cbSavePassword.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) { }
+
+			public void widgetSelected(SelectionEvent e) {
+				saveInfo = cbSavePassword.getSelection();
+			}
+			
+		});
+		// WTF? setSelection(true) is not picked up by the control, so we have to set 
+		// this initial value explicitly. After that toggle seems to work...
+		saveInfo = true;
+		cbSavePassword.setSelection(true);
+		
+		new Label(pwgroup, SWT.NONE).setText("Save user name and password");
+		
+		new Label(composite, SWT.NONE).setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		new Label(composite, SWT.WRAP).setText("NOTE: Saved passwords are stored on your computer in a file that is difficult, but not impossible, for an intruder to read.");
+		
+		return super.createDialogArea(parent);
+	}
+	
+	@Override
+	protected Point getInitialSize() {
+		// Try to set a reasonable default size.
+		return new Point(INITIAL_WIDTH, INITIAL_HEIGHT);
+	}
+	
+	private Composite createComposite(Composite parent, int numColumns) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		
+		GridLayout layout = new GridLayout();
+		layout.numColumns = numColumns;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		return composite;
+	}
+	
+	public String getUserName() {
+		return username;
+	}
+	
+	public String getPassword() {
+		return password;
+	}
+	
+	public boolean saveAuthenInfo() {
+		return saveInfo;
+	}
+}

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/PlatformUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/PlatformUtils.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/PlatformUtils.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -1,15 +1,52 @@
 package org.guvnor.tools.utils;
 
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.eclipse.core.resources.IStorage;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorDescriptor;
 import org.eclipse.ui.IStorageEditorInput;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
 import org.guvnor.tools.Activator;
+import org.guvnor.tools.utils.webdav.IWebDavClient;
+import org.guvnor.tools.utils.webdav.WebDavSessionAuthenticator;
 
+/**
+ * A set of utilities for interacting with the Eclipse platform.
+ * 
+ * @author jgraham
+ */
 public class PlatformUtils {
+	
+	private static PlatformUtils instance;
+	
+	/**
+	 * For convenience, we keep one instance of PlatformUtils around
+	 * @return the PlatformUtils instance
+	 */
+	public static PlatformUtils getInstance() {
+		if (instance == null) {
+			instance = new PlatformUtils();
+		}
+		return instance;
+	}
+	
+	/**
+	 * Opens a read-only, in-memory editor.
+	 * @param contents The contents for the editor
+	 * @param name The name of the file. Will be used to determine
+	 *        eclipse editor association, defaulting to text editor
+	 *        if no association is found
+	 */
 	public static void openEditor(String contents, String name) {
 		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
 		IStorage storage = new StringStorage(contents, name);
@@ -17,6 +54,8 @@
 		IWorkbenchPage page = window.getActivePage();
 		IEditorDescriptor desc = PlatformUI.getWorkbench().
         							getEditorRegistry().getDefaultEditor(name);
+		// If there is no editor associated with the given file name, we'll just
+		// use the eclipse text editor as a default
 		String editorId = desc != null?desc.getId():"org.eclipse.ui.DefaultTextEditor";
 		try {
 		if (page != null) {
@@ -26,4 +65,106 @@
 			Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
 		}
 	}
-}
+	
+	public boolean authenticateForServer(String server, IWebDavClient client) throws Exception {
+		AuthPromptResults res = promptForAuthentication(server);
+		if (res != null) {
+			if (res.wasSaved()) {
+				Platform.addAuthorizationInfo(new URL(server), "", "basic", res.getAuthInfo());
+			} else {
+				WebDavSessionAuthenticator authen = new WebDavSessionAuthenticator();
+				authen.addAuthenticationInfo(new URL(server), "", "basic", res.getAuthInfo());
+				client.setSessionAuthenticator(authen);
+				client.setSessionAuthentication(true);
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	/**
+	 * Convenience method for reporting log in failure
+	 */
+	public static void reportAuthenticationFailure() {
+		Display display = PlatformUI.getWorkbench().getDisplay();
+		display.asyncExec(new Runnable() {
+			public void run() {
+				Display display = Display.getCurrent();
+				Shell shell = display.getActiveShell();
+				MessageDialog.openError(shell, "Guvnor Repository Log in", 
+						               "Authentication failure");
+			}
+		});
+	}
+	
+	/**
+	 * Prompts for user name and password for a given Guvnor repository.
+	 * @param server The repository for log in
+	 * @return The dialog results. Includes whether the user decided to save
+	 *         the user name and password in the platform's key ring.
+	 *         Null if the user cancels the dialog.
+	 */
+	public AuthPromptResults promptForAuthentication(final String server) {
+		
+		Display display = PlatformUI.getWorkbench().getDisplay();
+		AuthPromptRunnable op = new AuthPromptRunnable(server);
+	    display.syncExec(op);
+	    return op.getResults();
+	}
+	
+	/**
+	 * An operation for running a log in dialog in the next
+	 * available UI thread.
+	 * @author jgraham
+	 */
+	class AuthPromptRunnable implements Runnable {
+		AuthPromptResults res = null;
+		private String server;
+		
+		public AuthPromptRunnable(String server) {
+			this.server = server;
+		}
+		
+		public void run() {
+            Display display = Display.getCurrent();
+            Shell shell = display.getActiveShell();
+            AuthenticationPromptDialog diag = new AuthenticationPromptDialog(shell, server);
+            if (diag.open() == Dialog.OK) {
+            	Map<String, String> info = new HashMap<String, String>();
+            	info.put("username", diag.getUserName());
+            	info.put("password", diag.getPassword());
+            	res = new AuthPromptResults(info, diag.saveAuthenInfo());
+            }
+        }
+		
+		public AuthPromptResults getResults() {
+			return res;
+		}
+	}
+	
+	/**
+	 * The results from a log in dialog prompt.
+	 * @author jgraham
+	 */
+	public class AuthPromptResults {
+		// username and password
+		private Map<String, String> info;
+		// whether the user wants to save the authentication information
+		// in the platform's key ring file
+		private boolean saved;
+		
+		public AuthPromptResults(Map<String, String> info, boolean saved) {
+			this.info = info;
+			this.saved = saved;
+		}
+		
+		public Map<String, String> getAuthInfo() {
+			return info;
+		}
+		
+		public boolean wasSaved() {
+			return saved;
+		}
+	}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/IWebDavClient.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/IWebDavClient.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/IWebDavClient.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -0,0 +1,64 @@
+package org.guvnor.tools.utils.webdav;
+
+import java.io.InputStream;
+import java.util.Map;
+
+import org.eclipse.webdav.IContext;
+import org.eclipse.webdav.client.RemoteDAVClient;
+import org.eclipse.webdav.http.client.IAuthenticator;
+
+/**
+ * Client methods for interacting with WebDav.
+ * @author jgraham
+ */
+public interface IWebDavClient {
+	/**
+	 * Tell the client to use the supplied authenticator, instead
+	 * of one tied to the platform key ring.
+	 * @param sessionAuthen The authenticator
+	 */
+	public void setSessionAuthenticator(IAuthenticator sessionAuthen);
+	
+	/**
+	 * Answers whether a session-oriented authenticator is in use or not.
+	 */
+	public boolean isUsingSessionAuthenication();
+	
+	/**
+	 * Tell the client to use a session authenticator or not.
+	 * @param useSession true to use session authentication, false for default authentication
+	 * @return false if a session authenticator is not registered but the request is
+	 *         to use session authentication.
+	 */
+	public boolean setSessionAuthentication(boolean useSession);
+	
+	/**
+	 * Provides access to the underlying RemoteDAVClient.
+	 * @return The client associated with the current repository connection.
+	 */
+	public RemoteDAVClient getClient();
+	
+	/**
+	 * Convenience method for creating a request IContext.
+	 * @return An instance of IContext
+	 */
+	public IContext createContext();
+	
+	/**
+	 * Lists a directory (collection) in WebDav.
+	 * @param path The directory (collection) to list
+	 * @return An association of directory content names and their properties
+	 * @throws Exception Exception Various WebDav errors can occur (See IResponse for details)
+	 */
+	public Map<String, ResourceProperties> listDirectory(String path) throws Exception;
+	
+	/**
+	 * Get the contents of a resource from a WebDav repository.
+	 * @param resource The address of the resource
+	 * @return The contents of the resource
+	 * @throws Exception Various WebDav errors can occur (See IResponse for details)
+	 */
+	public String getResourceContents(String resource) throws Exception;
+	
+	public void putResource(String location, String name, InputStream is) throws Exception;
+}

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClient.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClient.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClient.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -10,80 +10,133 @@
 import org.eclipse.webdav.client.RemoteDAVClient;
 import org.eclipse.webdav.client.WebDAVFactory;
 import org.eclipse.webdav.http.client.HttpClient;
+import org.eclipse.webdav.http.client.IAuthenticator;
 
 /**
  * WebDav wrapper client.
  * @author jgraham
  *
  */
-public class WebDavClient {
+public class WebDavClient implements IWebDavClient {
 	private RemoteDAVClient client;
 	
+	private WebDavAuthenticator authen;
+	private IAuthenticator sessionAuthen;
+	private HttpClient hClient;
+	private boolean usingSessionAuthen;
+	
 	/**
 	 * Ctor for this wrapper WebDav client.
 	 * @param serverUrl The WebDav repository location (server)
 	 */
-	public WebDavClient(URL serverUrl) {
-		WebDavAuthenticator authen =  new WebDavAuthenticator(serverUrl);
-		HttpClient hClient = new HttpClient();
+	/** package */ WebDavClient(URL serverUrl) {
+		authen =  new WebDavAuthenticator(serverUrl);
+		hClient = new HttpClient();
 		hClient.setAuthenticator(authen);
 		client = new RemoteDAVClient(new WebDAVFactory(), hClient);
 	}
 	
-	/**
-	 * Provides access to the underlying RemoteDAVClient.
-	 * @return The client associated with the current repository connection.
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#setSessionAuthenticator(org.eclipse.webdav.http.client.IAuthenticator)
 	 */
+	public void setSessionAuthenticator(IAuthenticator sessionAuthen) {
+		this.sessionAuthen = sessionAuthen;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#isUsingSessionAuthenication()
+	 */
+	public boolean isUsingSessionAuthenication() {
+		return usingSessionAuthen;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#setSessionAuthentication(boolean)
+	 */
+	public boolean setSessionAuthentication(boolean useSession) {
+		// We can't use session authenticator, if a session authenticator isn't present
+		if (useSession && sessionAuthen == null) {
+			usingSessionAuthen = false;
+			return false;
+		} else {
+			usingSessionAuthen = useSession;
+			return true;
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#getClient()
+	 */
 	public RemoteDAVClient getClient() {
 		return client;
 	}
 	
-	/**
-	 * Convenience method for creating a request IContext.
-	 * @return An instance of IContext
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#createContext()
 	 */
 	public IContext createContext() {
 		return WebDAVFactory.contextFactory.newContext();
 	}
 	
-	/**
-	 * Lists a directory (collection) in WebDav.
-	 * @param path The directory (collection) to list
-	 * @return An association of directory content names and their properties
-	 * @throws Exception Exception Various WebDav errors can occur (See IResponse for details)
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#listDirectory(java.lang.String)
 	 */
 	public Map<String, ResourceProperties> listDirectory(String path) throws Exception {
-		IContext context = createContext();
-		context.put("Depth", "1");
-		ILocator locator = WebDAVFactory.locatorFactory.newLocator(path);
-		IResponse response = client.propfind(locator, context, null);
-		if (response.getStatusCode() != IResponse.SC_MULTI_STATUS 
-		   && response.getStatusCode() != IResponse.SC_MULTI_STATUS) {
-			throw new Exception("WebDav error: " + response.getStatusCode());
+		if (isUsingSessionAuthenication()) {
+			if (sessionAuthen != null) {
+				hClient.setAuthenticator(sessionAuthen);
+			} else {
+				setSessionAuthentication(false);
+			}
 		}
-		return StreamProcessingUtils.parseListing(path, response.getInputStream());
+		try {
+			IContext context = createContext();
+			context.put("Depth", "1");
+			ILocator locator = WebDAVFactory.locatorFactory.newLocator(path);
+			IResponse response = client.propfind(locator, context, null);
+			if (response.getStatusCode() != IResponse.SC_MULTI_STATUS 
+			   && response.getStatusCode() != IResponse.SC_MULTI_STATUS) {
+				throw new WebDavException("WebDav error: " + response.getStatusCode(), 
+									     response.getStatusCode());
+			}
+			return StreamProcessingUtils.parseListing(path, response.getInputStream());
+		} finally {
+			if (isUsingSessionAuthenication()) {
+				hClient.setAuthenticator(authen);
+			}
+		}
 	}
 	
-	/**
-	 * Get the contents of a resource from a WebDav repository.
-	 * @param resource The address of the resource
-	 * @return The contents of the resource
-	 * @throws Exception Various WebDav errors can occur (See IResponse for details)
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#getResourceContents(java.lang.String)
 	 */
 	public String getResourceContents(String resource) throws Exception {
 		ILocator locator = WebDAVFactory.locatorFactory.newLocator(resource);
 		IResponse response = client.get(locator, createContext());
 		if (response.getStatusCode() != IResponse.SC_OK) {
-			throw new Exception("WebDav error: " + response.getStatusCode());
+			throw new WebDavException("WebDav error: " + response.getStatusCode(), 
+									 response.getStatusCode());
 		}
 		return StreamProcessingUtils.getStreamContents(response.getInputStream());
 	}
 	
+	/*
+	 * (non-Javadoc)
+	 * @see org.guvnor.tools.utils.webdav.IWebDavClient#putResource(java.lang.String, java.lang.String, java.io.InputStream)
+	 */
 	public void putResource(String location, String name, InputStream is) throws Exception {
 		ILocator locator = WebDAVFactory.locatorFactory.newLocator(location + "/" + name);
 		IResponse response = client.post(locator, createContext(), is);
 		if (response.getStatusCode() != IResponse.SC_OK) {
-			throw new Exception("WebDav error: " + response.getStatusCode());
+			throw new WebDavException("WebDav error: " + response.getStatusCode(), 
+									 response.getStatusCode());
 		}
 	}
-}
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClientFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClientFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavClientFactory.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -0,0 +1,14 @@
+package org.guvnor.tools.utils.webdav;
+
+import java.net.URL;
+
+/**
+ * Encapsulating the creation of IWebDavClient so it can be swapped out for other
+ * WebDav libraries if necessary.
+ * @author jgraham
+ */
+public class WebDavClientFactory {
+	public static IWebDavClient createClient(URL serverUrl) {
+		return new WebDavClient(serverUrl);
+	}
+}

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavException.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavException.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavException.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -2,13 +2,12 @@
 
 public class WebDavException extends Exception {
 	
-	//TODO: put a real serialization value here
-	private static final long serialVersionUID = 1L;
+	private static final long serialVersionUID = -2421203349714311291L;
 	
 	private int errCode;
 	
-	public WebDavException(int errCode) {
-		super();
+	public WebDavException(String msg, int errCode) {
+		super(msg);
 		this.errCode = errCode;
 	}
 	

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavServerCache.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavServerCache.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/utils/webdav/WebDavServerCache.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -9,18 +9,18 @@
  */
 public class WebDavServerCache {
 	
-	private static HashMap<String, WebDavClient> cache;
+	private static HashMap<String, IWebDavClient> cache;
 	
-	public static WebDavClient getWebDavClient(String serverUrl) {
+	public static IWebDavClient getWebDavClient(String serverUrl) {
 		if (cache == null) {
 			return null;
 		}
 		return cache.get(serverUrl);
 	}
 	
-	public static void cacheWebDavClient(String serverUrl, WebDavClient client) {
+	public static void cacheWebDavClient(String serverUrl, IWebDavClient client) {
 		if (cache == null) {
-			cache = new HashMap<String, WebDavClient>();
+			cache = new HashMap<String, IWebDavClient>();
 		}
 		cache.put(serverUrl, client);
 	}

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/RepositoryView.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/RepositoryView.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/RepositoryView.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -44,7 +44,8 @@
 import org.guvnor.tools.GuvnorRepository;
 import org.guvnor.tools.GuvnorLocationManager.IRepositorySetListener;
 import org.guvnor.tools.utils.PlatformUtils;
-import org.guvnor.tools.utils.webdav.WebDavClient;
+import org.guvnor.tools.utils.webdav.IWebDavClient;
+import org.guvnor.tools.utils.webdav.WebDavClientFactory;
 import org.guvnor.tools.utils.webdav.WebDavServerCache;
 import org.guvnor.tools.views.model.TreeObject;
 import org.guvnor.tools.views.model.TreeParent;
@@ -54,8 +55,8 @@
 	
 	private TreeViewer viewer;
 	private DrillDownAdapter drillDownAdapter;
-	private Action action1;
-	private Action action2;
+	private Action deleteRepositoryLoc;
+	private Action addRepositoryLoc;
 	private Action doubleClickAction;
 	
 	class NameSorter extends ViewerSorter {
@@ -114,6 +115,12 @@
 					files.toArray(res);
 					event.data = res;
 				} catch (Exception e) {
+					// Note: we could catch a 401 (not authorized) WebDav error and retry,
+					// like we do when listing directories. But since we have to first list
+					// directories to get to files, and the act of listing directories authenticates
+					// for the server, currently we do not have a situation requiring authentication
+					// for specific files. This might be different in the future if the Guvnor security
+					// model changes, or users can directly connect to specific files.
 					Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
 				}
 			}
@@ -191,14 +198,14 @@
 	}
 
 	private void fillLocalPullDown(IMenuManager manager) {
-		manager.add(action1);
+		manager.add(deleteRepositoryLoc);
 		manager.add(new Separator());
-		manager.add(action2);
+		manager.add(addRepositoryLoc);
 	}
 
 	private void fillContextMenu(IMenuManager manager) {
-		manager.add(action1);
-		manager.add(action2);
+		manager.add(deleteRepositoryLoc);
+		manager.add(addRepositoryLoc);
 		manager.add(new Separator());
 		drillDownAdapter.addNavigationActions(manager);
 		// Other plug-ins can contribute there actions here
@@ -206,14 +213,14 @@
 	}
 	
 	private void fillLocalToolBar(IToolBarManager manager) {
-		manager.add(action1);
-		manager.add(action2);
+		manager.add(deleteRepositoryLoc);
+		manager.add(addRepositoryLoc);
 		manager.add(new Separator());
 		drillDownAdapter.addNavigationActions(manager);
 	}
 
 	private void makeActions() {
-		action1 = new Action() {
+		deleteRepositoryLoc = new Action() {
 			public void run() {
 				ISelection selection = viewer.getSelection();
 				Object obj = ((IStructuredSelection)selection).getFirstElement();
@@ -227,12 +234,12 @@
 				}
 			}
 		};
-		action1.setText("Delete");
-		action1.setToolTipText("Delete Guvnor repository location");
-		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
+		deleteRepositoryLoc.setText("Delete");
+		deleteRepositoryLoc.setToolTipText("Delete Guvnor repository location");
+		deleteRepositoryLoc.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
 			getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
 		
-		action2 = new Action() {
+		addRepositoryLoc = new Action() {
 			public void run() {
 				NewRepLocationWizard wiz = new NewRepLocationWizard();
 				wiz.init(Activator.getDefault().getWorkbench(), null);
@@ -242,9 +249,9 @@
 			    dialog.open();
 			}
 		};
-		action2.setText("Add");
-		action2.setToolTipText("Add a Guvnor respository location");
-		action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
+		addRepositoryLoc.setText("Add");
+		addRepositoryLoc.setToolTipText("Add a Guvnor respository location");
+		addRepositoryLoc.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
 				getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD));
 		doubleClickAction = new Action() {
 			public void run() {
@@ -280,6 +287,12 @@
 				String contents = getResourceContents(node);
 				PlatformUtils.openEditor(contents, node.getName());
 			} catch (Exception e) {
+				// Note: we could catch a 401 (not authorized) WebDav error and retry,
+				// like we do when listing directories. But since we have to first list
+				// directories to get to files, and the act of listing directories authenticates
+				// for the server, currently we do not have a situation requiring authentication
+				// for specific files. This might be different in the future if the Guvnor security
+				// model changes, or users can directly connect to specific files.
 				Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
 			}
 		}
@@ -287,9 +300,9 @@
 	
 	private String getResourceContents(TreeObject node) throws Exception {
 		GuvnorRepository rep = node.getGuvnorRepository();
-		WebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
+		IWebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
 		if (webdav == null) {
-			webdav = new WebDavClient(new URL(rep.getLocation()));
+			webdav = WebDavClientFactory.createClient(new URL(rep.getLocation()));
 			WebDavServerCache.cacheWebDavClient(rep.getLocation(), webdav);
 		}
 		return webdav.getResourceContents(node.getFullPath());	

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/model/TreeParent.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/model/TreeParent.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/views/model/TreeParent.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -11,10 +11,14 @@
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
 import org.eclipse.ui.progress.IElementCollector;
+import org.eclipse.webdav.IResponse;
 import org.guvnor.tools.Activator;
 import org.guvnor.tools.GuvnorRepository;
+import org.guvnor.tools.utils.PlatformUtils;
+import org.guvnor.tools.utils.webdav.IWebDavClient;
 import org.guvnor.tools.utils.webdav.ResourceProperties;
-import org.guvnor.tools.utils.webdav.WebDavClient;
+import org.guvnor.tools.utils.webdav.WebDavClientFactory;
+import org.guvnor.tools.utils.webdav.WebDavException;
 import org.guvnor.tools.utils.webdav.WebDavServerCache;
 
 public class TreeParent extends TreeObject implements IDeferredWorkbenchAdapter {
@@ -62,7 +66,6 @@
 					p.setResourceProps(props);
 					collector.add(p, monitor);
 					monitor.worked(1);
-					if (i < reps.size() - 1) pause(500);
 				}
 				monitor.done();
 			}
@@ -72,6 +75,12 @@
 			}
 		}
 		
+		/**
+		 * Creates a directory listing.
+		 * @param node The directory to list.
+		 * @param collector The collector for the elements listed.
+		 * @param monitor Progress monitor for the operation.
+		 */
 		public void listDirectory(TreeParent node,
 				 		         IElementCollector collector, 
 				                 IProgressMonitor monitor) {
@@ -80,38 +89,51 @@
 			monitor.worked(1);
 			GuvnorRepository rep = node.getGuvnorRepository();
 			try {
-				WebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
+				IWebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
 				if (webdav == null) {
-					webdav = new WebDavClient(new URL(rep.getLocation()));
+					webdav = WebDavClientFactory.createClient(new URL(rep.getLocation()));
 					WebDavServerCache.cacheWebDavClient(rep.getLocation(), webdav);
 				}
-				Map<String, ResourceProperties> listing = webdav.listDirectory(node.getFullPath());
-				for (String s: listing.keySet()) {
-					ResourceProperties resProps = listing.get(s);
-					TreeObject o = null;
-					if (resProps.isDirectory()) {
-						o = new TreeParent(s, Type.PACKAGE);	
-					} else {
-						o = new TreeObject(s, Type.RESOURCE);
+				Map<String, ResourceProperties> listing = null;
+				try {
+					listing = webdav.listDirectory(node.getFullPath());
+				} catch (WebDavException wde) {
+					if (wde.getErrorCode() != IResponse.SC_UNAUTHORIZED) {
+						// If not an authentication failure, we don't know what to do with it
+						throw wde;
 					}
-					o.setGuvnorRepository(rep);
-					o.setResourceProps(resProps);
-					collector.add(o, monitor);
+					boolean retry = PlatformUtils.getInstance().authenticateForServer(
+												node.getGuvnorRepository().getLocation(), webdav); 
+					if (retry) {
+						listing = webdav.listDirectory(node.getFullPath());
+					}
 				}
+				if (listing != null) {
+					for (String s: listing.keySet()) {
+						ResourceProperties resProps = listing.get(s);
+						TreeObject o = null;
+						if (resProps.isDirectory()) {
+							o = new TreeParent(s, Type.PACKAGE);	
+						} else {
+							o = new TreeObject(s, Type.RESOURCE);
+						}
+						o.setGuvnorRepository(rep);
+						o.setResourceProps(resProps);
+						collector.add(o, monitor);
+					}
+				} 
 				monitor.worked(1);
+			} catch (WebDavException e) {
+				if (e.getErrorCode() == IResponse.SC_UNAUTHORIZED) {
+					PlatformUtils.reportAuthenticationFailure();
+				} else {
+					Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
+				}
 			} catch (Exception e) {
 				Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
 			}
 		}
 		
-		private void pause(long msec){
-		  try {
-		    Thread.sleep(msec);
-		  } catch (InterruptedException e) {
-		    e.printStackTrace();
-		  }
-		}
-		
 		/*
 		 * (non-Javadoc)
 		 * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object)

Modified: labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/wizards/GuvnorMainConfigPage.java
===================================================================
--- labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/wizards/GuvnorMainConfigPage.java	2008-06-26 18:35:09 UTC (rev 20820)
+++ labs/jbossrules/trunk/drools-eclipse/org.guvnor.tools/src/org/guvnor/tools/wizards/GuvnorMainConfigPage.java	2008-06-26 20:05:04 UTC (rev 20821)
@@ -62,8 +62,8 @@
 			}
 		});
 
-		new Label(composite, SWT.NONE).setText("NOTE: ") ;
-		new Label(composite, SWT.WRAP).setText("Saved passwords are stored on your computer in a file that is difficult, but not impossible, for an intruder to read.");
+		new Label(composite, SWT.NONE).setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		new Label(composite, SWT.WRAP).setText("NOTE: Saved passwords are stored on your computer in a file that is difficult, but not impossible, for an intruder to read.");
 		
 		super.setControl(composite);
 	}




More information about the jboss-svn-commits mailing list