Andrew Rea - A Developer On A Few Platforms

C#, JAVA, ASP.NET, C++, ACTION SCRIPT

Andrew Rea - For May 2010

  1. IDEA for a Drop Box like application to work with the Google Docs List Data API

    I have spoken a couple of times to someone at work about Google Docs and they were mentioning how good it would be if there was support similar to what you have with Drop Box and of course I agreed.  So it got me thinking and I have done a little, *tiny*, research just out of sheer interest. 

    The language I would choose

    In a perfect world I would like to say I could build this cross platform application using C++ but unfortunately my skills are not at the level where I can just jump in and code.  I am thinking about using either:

    • Java
    • .NET (With Mono in mind for X Platform)

    I am not to sure of the exact deployment requirements for both Java and .NET Mono so I shall leave this point currently at the stage of I would use either.

    The service

    To work in a similar fashion to Drop Box we would need functionality where by we can have a simple set up to select a folder which will be sync'd, and a service running which will detect :

    • File Creation
    • File Update
    • File Delete

    I have read somewhere about meta data on the API so it would not be a bad to reflect file meta data when they change also.  This is where the deployment would differ each platform has a different way of setting up and handling services of course.

    The API

    http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html

    As you will read the API provides the necessary methods to develop core functionality we would require to reflect that of Drop Box.  Once of the main things which you will need before you can get anything of the ground is Authentication.  There is a section for Client Login which is what we will need for the installed Application.

    Progressing Synchronization

    At any stage it needs to be possible to see the current progress of any synchronization that is ongoing, complete or has failed.  My thoughts for this, and I am not a GUI GURU, was having a context menu over a system icon in the task bar which might say - Synchronization Status.  I would then envisage may be a three tab interface with the tab headings of:

    • In Progress
    • Complete
    • Failed

    Each tab would contain a data grid to display the file paths and I would give the following context menus. 

    In Progress Tab

    Cancel Menu Item

    Failed Tab

    Retry Menu Item

    I am thinking that the complete tab would simply show the last 100 completed actions or something simply for immediate reference. So because of that would not require a context menu.

    Is there anything like this currently out there.  I hope so, if not?  Damn cool project to open source and get collaboration on, and ultimately use!!

    Cheers for now,

    Andrew

    Posted by Andrew Rea on May 12 at 2:46 PM

  2. AutoMapper MappingFunction from Source Type of NameValueCollection

    I have had a situation arise today where I need to construct a complex type from a source of a NameValueCollection.  A little while back I submitted a patch for the Agatha Project to include REST (JSON and XML) support for the service contract.  I realized today that as useful as it is, it did not actually support true REST conformance, as REST should support GET so that you can use JSONP from JavaScript directly meaning you can query cross domain services.  My original implementation for POX and JSON used the POST method and this immediately rules out JSONP as from reading, JSONP only works with GET Requests.

    This then raised another issue.  The current operation contract of Agatha and one of its main benefits is that you can supply an array of Request objects in a single request, limiting the about of server requests you need to make.  Now, at the present time I am thinking that this will not be the case for the REST imlementation but will yield the benefits of the fact that :

    • The same Request objects can be used for SOAP and RST (POX, JSON)
    • The construct of the JavaScript functions will be simpler and more readable
    • It will enable the use of JSONP for cross domain REST Services

    The current contract for the Agatha WcfRequestProcessor is at time of writing the following:

    
        [ServiceContract]
        public interface IWcfRequestProcessor
        {
            [OperationContract(Name = "ProcessRequests")]
            [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
            [TransactionFlow(TransactionFlowOption.Allowed)]
            Response[] Process(params Request[] requests);
    
            [OperationContract(Name = "ProcessOneWayRequests", IsOneWay = true)]
            [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
            void ProcessOneWayRequests(params OneWayRequest[] requests);
        }
    

     

    My current proposed solution, and at the very early stages of my concept is as follows:

    
        [ServiceContract]
        public interface IWcfRestJsonRequestProcessor
        {
            [OperationContract(Name="process")]
            [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
            [TransactionFlow(TransactionFlowOption.Allowed)]
            [WebGet(UriTemplate = "process/{name}/{*parameters}", BodyStyle = WebMessageBodyStyle.WrappedResponse, ResponseFormat = WebMessageFormat.Json)]
            Response[] Process(string name, NameValueCollection parameters);
    
            [OperationContract(Name="processoneway",IsOneWay = true)]
            [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
            [WebGet(UriTemplate = "process-one-way/{name}/{*parameters}", BodyStyle = WebMessageBodyStyle.WrappedResponse, ResponseFormat = WebMessageFormat.Json)]
            void ProcessOneWayRequests(string name, NameValueCollection parameters);
        }
    

     

    Now this part I have not yet implemented, it is the preliminart step which I have developed which will allow me to take the name of the Request Type and the NameValueCollection and construct the complex type which is that of the Request which I can then supply to a nested instance of the original IWcfRequestProcessor  and work as it should normally.  To give an example of some of the urls which you I envisage with this method are:

    Another reason why my direction has gone to a single request for the REST implementation is because of restrictions which are imposed by browsers on the length of the url.  From what I have read this is on average 2000 characters.  I think that this is a very acceptable usage limit in the context of using 1 request, but I do not think this is acceptable for accommodating multiple requests chained together.  I would love to be corrected on that one, I really would but unfortunately from what I have read I have come to the conclusion that this is not the case.

    The mapping function

    So, as I say this is just the first pass I have made at this, and I am not overly happy with the try catch for detecting types without default constructors.  I know there is a better way but for the minute, it escapes me.  I would also like to know the correct way for adding mapping functions and not using the anonymous way that I have used.  To achieve this I have used recursion which I am sure is what other mapping function use. As you do have to go as deep as the complex type is.

    
            public static object RecurseType(NameValueCollection collection, Type type, string prefix)
            {
                try
                {
                    var returnObject = Activator.CreateInstance(type);
    
                    foreach (var property in type.GetProperties())
                    {
                        foreach (var key in collection.AllKeys)
                        {
                            if (String.IsNullOrEmpty(prefix) || key.Length > prefix.Length)
                            {
                                var propertyNameToMatch = String.IsNullOrEmpty(prefix) ? key : key.Substring(property.Name.IndexOf(prefix) + prefix.Length + 1);
    
                                if (property.Name == propertyNameToMatch)
                                {
                                    property.SetValue(returnObject, Convert.ChangeType(collection.Get(key), property.PropertyType), null);
                                }
                                else if(property.GetValue(returnObject,null) == null)
                                {
                                    property.SetValue(returnObject, RecurseType(collection, property.PropertyType, String.Concat(prefix, property.PropertyType.Name)), null);
                                }
                            }
                        }
                    }
    
                    return returnObject;
                }
                catch (MissingMethodException)
                {
                    //Quite a blunt way of dealing with Types without default constructor
                    return null;
                }
            }
    

     

    Another thing is performance, I have not measured this in anyway, it is as I say the first pass, so I hope this can be the start of a more perfected implementation.  I tested this out with a complex type of three levels, there is no intended logical meaning to the properties, they are simply for the purposes of example.  You could call this a spiking session, as from here on in, now I know what I am building I would take a more TDD approach.  OK, purists, why did I not do this from the start, well I didn't, this was a brain dump and now I know what I am building I can.

    The console test and how I used with AutoMapper is as follows:

    
            static void Main(string[] args)
            {
                var collection = new NameValueCollection();
                collection.Add("Name", "Andrew Rea");
                collection.Add("Number", "1");
                collection.Add("AddressLine1", "123 Street");
                collection.Add("AddressNumber", "2");
                collection.Add("AddressPostCodeCountry", "United Kingdom");
                collection.Add("AddressPostCodeNumber", "3");
    
                AutoMapper.Mapper.CreateMap<NameValueCollection, Person>()
                    .ConvertUsing(x =>
                    {
                        return(Person) RecurseType(x, typeof(Person), null);
                    });
    
                var person = AutoMapper.Mapper.Map<NameValueCollection, Person>(collection);
    
                Console.WriteLine(person.Name);
                Console.WriteLine(person.Number);
                Console.WriteLine(person.Address.Line1);
                Console.WriteLine(person.Address.Number);
                Console.WriteLine(person.Address.PostCode.Country);
                Console.WriteLine(person.Address.PostCode.Number);
                Console.ReadLine();
            }
    

     

    Notice the convention that I am using and that this method requires you do use.  Each property is prefixed with the constructed name of its parents combined.  This is the convention used by AutoMapper and it makes sense.

    image

    I can also think of other uses for this including using with ASP.NET MVC ModelBinders for creating a complex type from the QueryString which is itself is a NameValueCollection.

    Hope this is of some help to people and I would welcome any code reviews you could give me.

    References:

    Agatha : http://code.google.com/p/agatha-rrsl/

    AutoMapper : http://automapper.codeplex.com/

     

    Cheers for now,

    Andrew

     

    P.S. I will have the proposed solution for a more complete REST implementation for AGATHA very soon. 

    Posted by Andrew Rea on May 09 at 2:48 PM

© Copyright 2010 Powered by AtomSite 1.4.0.0