Tuesday, 19 August 2008

Change Your Windows Live ID Primary Email Address

Over the lifetime of my Microsoft Passport/Windows Live ID I've had to do this once or twice and it can be a real bugger if you don't know how. I'll start by mentioning that you can't do this unless you've registered your Live ID with a third-party email address (i.e not hotmail.com or live.com). Thankfully I registered mine with a Mail2Web address I used to use so this wasn't a problem. Another annoying limitation is that you can only perform this function in Internet Explorer, the change email address button simply does not render in any other browser.

First thing you need to do is visit http://home.live.com and sign in with your current username and password. Once signed in you need to click the drop-down arrow next to your sign in name in the top right-hand corner of the screen. Select the "View Your Account" from the drop down menu. 

As I mentioned before, your only going to be able to do this if your in Internet Explorer, I know this sucks, I'm a Mac user at home and run FireFox and Safari, it doesn't work in either. When you load this page in IE you will see a "Change" button next to your primary email address. The form is pritty self explanatory for here so I won't insult your intelligence any further ;-)

Hope this saves you some time!

Wednesday, 6 August 2008

Drag and Drop Upload Applet Utilising WCF

I’ve recently been working on a Java applet upload control which will allow the user to drag and drop a file into the control and upload it to the server. My plan was to convert the dropped file into a byte array and pass it as a parameter to a Microsoft WCF (Windows Communication Foundation) service. I’m a little out of my comfort zone with Java so though I would blog about the challenges I faced, creating a simple applet, getting hold of the file using the drag events and calling the WCF service.

I didn’t have the Java SDK you need before developing and Java applications. The download and installation instructions are available from Sun. I started by creating a simple applet that would display an area where the user could drag and drop the file to be uploaded. For a Java application to become an Applet, I had to extend the Applet class and write some code to produce the layout.

   1:  public class UploadControl extends Applet

   2:  {

   3:      /* Controls */

   4:      private Container _container;

   5:      private GridBagLayout _gridBagLayout;

   6:      private GridBagConstraints _gridBagContainer;

   7:      private JLabel _dropZone;


   9:      public void init()

  10:      {    

  11:          /* Setup the Container */

  12:          setLayout(new BorderLayout());

  13:          _container = new Container();

  14:          add(_container, BorderLayout.CENTER);


  16:          /* Setup the GridBagLayout */

  17:          _gridBagLayout = new GridBagLayout();

  18:          _container.setLayout(_gridBagLayout);


  20:          /* Setup the GridBagConstraints */

  21:          GridBagConstraints _gridBagContainer = new GridBagConstraints();

  22:          _gridBagContainer.anchor = GridBagConstraints.NORTHWEST;

  23:          _gridBagContainer.fill = GridBagConstraints.BOTH;

  24:          _gridBagContainer.weighty = 0.6;

  25:          _gridBagContainer.weightx = 0.00001;

  26:          _gridBagContainer.gridy = 0;

  27:          _gridBagContainer.gridx = 0;

  28:          _gridBagContainer.gridheight = 1;

  29:          _gridBagContainer.gridwidth = 1;

  30:          _gridBagContainer.insets = new Insets(1, 0, 1, 1);            


  32:          /* Set the title of our drag n drop area */

  33:          _dropZone = new JLabel("Drag and Drop Files Here");

  34:          new DropTarget(_dropZone, this);

  35:          _dropZone.setVerticalAlignment(SwingConstants.CENTER);

  36:          _dropZone.setHorizontalAlignment(SwingConstants.CENTER);

  37:          _dropZone.setBorder(new LineBorder(Color.black));

  38:          _container.add(_dropZone);    

  39:          _gridBagLayout.setConstraints(_dropZone, _gridBagContainer);    

  40:      }

  41:  }

Compiling this using the javac command produced a .class file called UploadControl.class. I then can embedded this into an HTML page for testing by creating new html file using the mark-up below and moving the .class file into the same directory.

   1:  <html>

   2:  <head>

   3:     <title>Drag and Drop Upload Applet Utilising WCF</title>

   4:  </head>

   5:  <body>

   6:      <applet code="UploadControl.class" ></applet>

   7:  </body>

   8:  </html>

When I open up the new web page and responded to the security prompts from my browser, I could see small box with the words “Drag and Drop Files Here” in the middle, this meant that my applet was running. I now had my drop zone, and need to make the applet respond to the drag and drop events which fire as the user drags a file. I Added “implements DropTargetListener” to the end of the UploadControl class declaration and implement the interfaces methods using the code below.

   1:  @Override

   2:  public void dragEnter(DropTargetDragEvent arg0) 

   3:  {    

   4:  }


   6:  @Override

   7:  public void dragExit(DropTargetEvent arg0) 

   8:  {

   9:  }


  11:  @Override

  12:  public void dragOver(DropTargetDragEvent arg0) 

  13:  {

  14:      /* Set the title so the user knows something is happening */

  15:      _dropZone.setText("Drop File Here");        

  16:  }



  19:  @Override

  20:  public void drop(DropTargetDropEvent arg0) 

  21:  {

  22:  }


  24:  @Override

  25:  public void dropActionChanged(DropTargetDragEvent arg0) 

  26:  {

  27:  }

As you can see, the purpose of each method is fairly self explanatory. Using these methods you are able to make your applet respond as the user drags a file across, I’ve simply changed the text the applet displays to make it obvious to the user that this is the drop zone. The next step was to add some code to the drop method to register the drop action and get access to the file or files that have been dragged onto the control. The files are passed to the method wrapped in a Transferable object.

The control needs to check that this transferable object contains the data that we are interested in, remember, anything could have been dragged onto the control but we’re only interested in files. I used the javaFileListFlavor data flavour to retrieve a collection of files from the transferable object. Another thing to consider is that the user could have dragged multiple files onto the control at the same time. All files will be contained in the collection returned from the transferable object.

   1:  @Override

   2:  public void drop(DropTargetDropEvent arg0) 

   3:  {

   4:      /* Register the drop action */

   5:      int action = arg0.getDropAction();

   6:      arg0.acceptDrop(action);


   8:      /* Get the transferable object */

   9:      Transferable transferable = arg0.getTransferable();


  11:      /* If files have been dragged onto the drop zone */    

  12:      if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor))

  13:      {

  14:          /* Get a list of transferred files*/

  15:          Collection fileList = null;

  16:          try

  17:          {

  18:              fileList = (Collection) transferable.getTransferData(DataFlavor.javaFileListFlavor);

  19:          }

  20:          catch(IOException ex)

  21:          {

  22:          }

  23:          catch(UnsupportedFlavorException ex)

  24:          {

  25:          }


  27:          /* Convert the files collection to an array and get the first one*/

  28:          ArrayList fileArray = new ArrayList();

  29:          fileArray.addAll(fileList);


  31:          if(fileArray.size() > 0)

  32:          {

  33:              byte[] fileBytes = convertFileToByteArray(fileArray.get(0));


  35:              /* TODO: Call WCF Service*/

  36:          }

  37:      }


  39:      /* Complete the drop action*/

  40:      arg0.dropComplete(true);    

  41:  }

In the code above I’ve accessed the first file in the collection. This is only to make this a little simpler for this post, it wouldn’t take much code to call a WCF service for each file that has been dragged and dropped onto the upload control. I now pass my single file to a utility method which converts it to a byte array which I’m going to pass to my WCF service.

I then need to generate the stubs in order to allow the applet to call my WCF service. I’m not going to go into the creation of the WCF service all it currently does is return the number of bytes in the byte array. The UploadFile method on the service takes in a filename string and a file content byte array. I then exposed my service using a basicHttpBinding endpoint setup similar to the following:

   1:  <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfig" contract="DaveCromar.Wcf.Service">


To generate the method stubs I used the WSImport command which generates java files from the WCF WSDL (web service description language). The example below will generate .java source files to c:\java\src and class files to c:\java. Your WSDL should be hosted at the address specified in the command parameters.

Wsimport –s c:\java\src –extension –d c:\java http://localhost/davecromar/wcfservice.svc?wsdl

I could now use the files to make the call to the WCF service from within my applet. I added the following lines of code to the drop method (replacing the TODO: Call WCF Service comment). The UploadFile method on the WCF service will return a string containing the name of the file and the length of the byte array which was passed in which I will then display to the user within the applet. You probably wouldn’t want to do this in a finished product but it was good for testing everything was working.

   1:  /* Create the Url to the WSDL*/

   2:  URL url = null;


   4:  try

   5:  {

   6:      url = new URL("http://localhost/davecromar/wcfservice.svc?wsdl");

   7:  }

   8:  catch(MalformedURLException ex)

   9:  {

  10:  }


  12:  /* Make the call to the WCF service with the byte array */

  13:  org.tempuri.WcfService_Service service = new org.tempuri. WcfService _Service(url, new QName("http://tempuri.org/", "WcfService"));


  15:  /* Set the text on the applet to the string returned from the service*/

  16:  org.tempuri. WcfService port = service.getBasicHttpBindingCmsService();

  17:  _dropZone.setText(port.UploadFile(file.getName(), fileBytes));

The applet is now code complete and the only remaining thing to do before it will run is to sign it. A good tutorial on how to sign java applets can be found on the Sun Forms. After signing I had to modify my applet tag in the HTML test file to the following:

   1:  <html>

   2:  <head>

   3:     <title>Drag and Drop Upload Applet Utilising WCF</title>

   4:  </head>

   5:  <body>

   6:      <applet code="UploadControl.class" archive=”UploadControl.jar></applet>

   7:  </body>

   8:  </html>