[tomboy] Switch to using Hyena.Json for deserialization (serialization not implemented yet).



commit 2d23f978e7817b06df445daaf0c0d0e5bd1dc146
Author: Sandy Armstrong <sanfordarmstrong gmail com>
Date:   Fri May 15 18:49:14 2009 -0700

    Switch to using Hyena.Json for deserialization (serialization not implemented yet).
    
    Also, add NoteInfo.NoteContentVersion and implement conversion between Note<->NoteInfo.
---
 Tomboy.mdp                                         |   10 ++-
 Tomboy/Addins/WebSyncService/Api/NoteInfo.cs       |  122 ++++++++++++++++++++
 .../Addins/WebSyncService/Api/ResourceReference.cs |   25 ++++
 Tomboy/Addins/WebSyncService/Api/UserInfo.cs       |   98 ++++++++++++++--
 Tomboy/Addins/WebSyncService/Makefile.am           |   13 +-
 Tomboy/Addins/WebSyncService/WebSyncServer.cs      |   36 ++++++-
 6 files changed, 284 insertions(+), 20 deletions(-)

diff --git a/Tomboy.mdp b/Tomboy.mdp
index 690bb6a..c043990 100644
--- a/Tomboy.mdp
+++ b/Tomboy.mdp
@@ -153,6 +153,15 @@
     <File name="Tomboy/Addins/WebSyncService/Api/UserInfo.cs" subtype="Code" buildaction="Compile" />
     <File name="Tomboy/Addins/WebSyncService/Api/ResourceReference.cs" subtype="Code" buildaction="Compile" />
     <File name="Tomboy/Addins/WebSyncService/Api/WebHelper.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/Deserializer.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/IJsonCollection.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/JsonArray.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/JsonObject.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/Token.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/Tokenizer.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/TokenType.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/Tests/DeserializerTests.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/WebSyncService/Hyena.Json/Tests/TokenizerTests.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
@@ -164,7 +173,6 @@
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
     <ProjectReference type="Gac" localcopy="True" refto="pango-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Cairo, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
-    <ProjectReference type="Gac" localcopy="True" refto="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </References>
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="./Makefile.am" ExecuteTargetName="run">
     <BuildFilesVar />
diff --git a/Tomboy/Addins/WebSyncService/Api/NoteInfo.cs b/Tomboy/Addins/WebSyncService/Api/NoteInfo.cs
index ca87b0a..2641a11 100644
--- a/Tomboy/Addins/WebSyncService/Api/NoteInfo.cs
+++ b/Tomboy/Addins/WebSyncService/Api/NoteInfo.cs
@@ -30,6 +30,107 @@ namespace Tomboy.WebSync.Api
 {
 	public class NoteInfo
 	{
+		#region Public Static Methods
+
+		public static NoteInfo ParseJson (string jsonString)
+		{
+			Hyena.Json.Deserializer deserializer =
+				new Hyena.Json.Deserializer (jsonString);
+			object obj = deserializer.Deserialize ();
+
+			Hyena.Json.JsonObject jsonObj =
+				obj as Hyena.Json.JsonObject;
+			return ParseJson (jsonObj);
+		}
+
+		public static NoteInfo ParseJson (Hyena.Json.JsonObject jsonObj)
+		{
+			if (jsonObj == null)
+				throw new ArgumentException ("jsonObj does not contain a valid NoteInfo representation");
+
+			// TODO: Checks
+			NoteInfo note = new NoteInfo ();
+			note.Guid = (string) jsonObj ["guid"];
+
+			// TODO: Decide how much is required
+			object val;
+
+			if (jsonObj.TryGetValue (TitleElementName, out val))
+				note.Title = (string) val;
+			if (jsonObj.TryGetValue (NoteContentElementName, out val))
+				note.NoteContent = (string) val;
+			if (jsonObj.TryGetValue (NoteContentVersionElementName, out val))
+				note.NoteContentVersion = (double) val;
+			
+			if (jsonObj.TryGetValue (LastChangeDateElementName, out val))
+				note.LastChangeDate = DateTime.Parse ((string) val);
+			if (jsonObj.TryGetValue (LastMetadataChangeDateElementName, out val))
+				note.LastMetadataChangeDate = DateTime.Parse ((string) val);
+			if (jsonObj.TryGetValue (CreateDateElementName, out val))
+				note.CreateDate = DateTime.Parse ((string) val);
+			
+			if (jsonObj.TryGetValue (LastSyncRevisionElementName, out val))
+				note.LastSyncRevision = (int) val;
+			if (jsonObj.TryGetValue (OpenOnStartupElementName, out val))
+				note.OpenOnStartup = (bool) val;
+			
+			if (jsonObj.TryGetValue (TagsElementName, out val)) {
+				Hyena.Json.JsonArray tagsJsonArray =
+					(Hyena.Json.JsonArray) val;
+				note.Tags = new List<string> (tagsJsonArray.Count);
+				foreach (string tag in tagsJsonArray)
+					note.Tags.Add (tag);
+			}
+
+			if (jsonObj.TryGetValue (ResourceReferenceElementName, out val))
+				note.ResourceReference =
+					ResourceReference.ParseJson ((Hyena.Json.JsonObject) val);
+
+			return note;
+		}
+		
+		#endregion
+
+		#region Public Methods
+
+		public Hyena.Json.JsonObject ToUpdateObject ()
+		{
+			Hyena.Json.JsonObject noteUpdateObj =
+				new Hyena.Json.JsonObject ();
+			noteUpdateObj [GuidElementName] = Guid;
+			
+			if (!string.IsNullOrEmpty (Command)) {
+				noteUpdateObj [CommandElementName] = Command;
+				return noteUpdateObj;
+			}
+
+			noteUpdateObj [TitleElementName] = Title;
+			noteUpdateObj [NoteContentElementName] = NoteContent;
+			noteUpdateObj [NoteContentVersionElementName] = NoteContentVersion;
+			
+			noteUpdateObj [LastChangeDateElementName] =
+				LastChangeDate.ToString (NoteArchiver.DATE_TIME_FORMAT);
+			noteUpdateObj [LastMetadataChangeDateElementName] =
+				LastMetadataChangeDate.ToString (NoteArchiver.DATE_TIME_FORMAT);
+			noteUpdateObj [CreateDateElementName] =
+				CreateDate.ToString (NoteArchiver.DATE_TIME_FORMAT);
+			
+			noteUpdateObj [LastSyncRevisionElementName] = LastSyncRevision;
+			noteUpdateObj [OpenOnStartupElementName] = OpenOnStartup;
+
+			Hyena.Json.JsonArray tagArray =
+				new Hyena.Json.JsonArray ();
+			foreach (string tag in Tags)
+				tagArray.Add (tag);
+			noteUpdateObj [TagsElementName] = tagArray;
+
+			return noteUpdateObj;
+		}
+
+		#endregion
+		
+		#region API Members
+		
 		public string Guid { get; set; }
 		
 		public ResourceReference ResourceReference { get; set; }
@@ -37,6 +138,8 @@ namespace Tomboy.WebSync.Api
 		public string Title { get; set; }
 		
 		public string NoteContent { get; set; }
+
+		public double NoteContentVersion { get; set; }
 		
 		public DateTime LastChangeDate { get; set; }
 		
@@ -51,5 +154,24 @@ namespace Tomboy.WebSync.Api
 		public List<string> Tags { get; set; }
 
 		public string Command { get; set; }
+
+		#endregion
+
+		#region Public Constants
+
+		public const string GuidElementName = "guid";
+		public const string ResourceReferenceElementName = "ref";
+		public const string TitleElementName = "title";
+		public const string NoteContentElementName = "note-content";
+		public const string NoteContentVersionElementName = "note-content-version";
+		public const string LastChangeDateElementName = "last-change-date";
+		public const string LastMetadataChangeDateElementName = "last-metadata-change-date";
+		public const string CreateDateElementName = "create-date";
+		public const string LastSyncRevisionElementName = "last-sync-revision";
+		public const string OpenOnStartupElementName = "open-on-startup";
+		public const string TagsElementName = "tags";
+		public const string CommandElementName = "command";
+
+		#endregion
 	}
 }
diff --git a/Tomboy/Addins/WebSyncService/Api/ResourceReference.cs b/Tomboy/Addins/WebSyncService/Api/ResourceReference.cs
index cdbcf4d..14f6ead 100644
--- a/Tomboy/Addins/WebSyncService/Api/ResourceReference.cs
+++ b/Tomboy/Addins/WebSyncService/Api/ResourceReference.cs
@@ -29,7 +29,32 @@ namespace Tomboy.WebSync.Api
 {
 	public class ResourceReference
 	{
+		#region API Members
+		
 		public string Href { get; private set; }
+		
 		public string ApiRef { get; private set; }
+
+		#endregion
+
+		#region Public Static Members
+
+		public static ResourceReference ParseJson (Hyena.Json.JsonObject jsonObj)
+		{
+			if (jsonObj == null)
+				throw new ArgumentNullException ("jsonObj");
+
+			// TODO: Casting checks?
+			ResourceReference resourceRef = new ResourceReference ();
+			object uri;
+			if (jsonObj.TryGetValue ("api-ref", out uri))
+				resourceRef.ApiRef = (string) uri;
+			if (jsonObj.TryGetValue ("href", out uri))
+				resourceRef.Href = (string) uri;
+			
+			return resourceRef;
+		}
+
+		#endregion
 	}
 }
diff --git a/Tomboy/Addins/WebSyncService/Api/UserInfo.cs b/Tomboy/Addins/WebSyncService/Api/UserInfo.cs
index 1fe4861..3ae5aac 100644
--- a/Tomboy/Addins/WebSyncService/Api/UserInfo.cs
+++ b/Tomboy/Addins/WebSyncService/Api/UserInfo.cs
@@ -25,32 +25,66 @@
 
 using System;
 using System.Collections.Generic;
-using System.Web.Script.Serialization;
 
 namespace Tomboy.WebSync.Api
 {
 	public class UserInfo
 	{
+		#region Public Static Methods
+		
 		public static UserInfo GetUser (string uri)
 		{
 			// TODO: Error-handling in GET and Deserialize
 			WebHelper helper = new WebHelper ();
 			string jsonString = helper.Get (uri, null);
+			return ParseJson (jsonString);
+		}
+
+		public static UserInfo ParseJson (string jsonString)
+		{
+			Hyena.Json.Deserializer deserializer =
+				new Hyena.Json.Deserializer (jsonString);
+			object obj = deserializer.Deserialize ();
+
+			Hyena.Json.JsonObject jsonObj =
+				obj as Hyena.Json.JsonObject;
+			if (jsonObj == null)
+				throw new ArgumentException ("jsonString does not contain a valid UserInfo representation");
+
+			// TODO: Checks
+			UserInfo user = new UserInfo ();
+			user.FirstName = (string) jsonObj ["first-name"];
+			user.LastName = (string) jsonObj ["last-name"];
+			user.LatestSyncRevision = (int) jsonObj ["latest-sync-revision"];
+
+			Hyena.Json.JsonObject notesRefJsonObj =
+				(Hyena.Json.JsonObject) jsonObj ["notes-ref"];
+			user.Notes =
+				ResourceReference.ParseJson (notesRefJsonObj);
 
-			JavaScriptSerializer ser = new JavaScriptSerializer ();
-			return ser.Deserialize <UserInfo> (jsonString);
+			object friendsRefObj;
+			if (jsonObj.TryGetValue ("friends-ref", out friendsRefObj)) {
+				user.Notes =
+					ResourceReference.ParseJson ((Hyena.Json.JsonObject) friendsRefObj);
+			}
+
+			return user;
 		}
+
+		#endregion
+
+		#region API Members
 		
 		public string FirstName { get; private set; }
 
 		public string LastName { get; private set; }
 
+		public int LatestSyncRevision { get; private set; }
+
 		public ResourceReference Notes { get; private set; }
 
 		public ResourceReference Friends { get; private set; }
 
-		public int LatestSyncRevision { get; private set; }
-
 		public IList<NoteInfo> GetNotes (bool includeContent)
 		{
 			return GetNotes (includeContent, -1);
@@ -71,20 +105,62 @@ namespace Tomboy.WebSync.Api
 			
 			jsonString = helper.Get (Notes.ApiRef, parameters);
 
-			JavaScriptSerializer ser = new JavaScriptSerializer ();
-			return ser.Deserialize <List<NoteInfo>> (jsonString);
+			return ParseJsonNotes (jsonString);
 		}
 
 		public void UpdateNotes (IList<NoteInfo> noteUpdates)
 		{
 			// TODO: Error-handling in PUT, Serialize, and Deserialize
 			WebHelper helper = new WebHelper ();
-			JavaScriptSerializer ser = new JavaScriptSerializer ();
 
-			string jsonString =
-				helper.PutJson (Notes.ApiRef, null, ser.Serialize (noteUpdates));
+			string jsonResponseString =
+				helper.PutJson (Notes.ApiRef, null, CreateNoteChangesJsonString (noteUpdates));
 			
-			ser.Deserialize <List<NoteInfo>> (jsonString);
+			ParseJsonNotes (jsonResponseString);	// TODO: What?
 		}
+
+		#endregion
+
+		#region Private Methods
+
+		private IList<NoteInfo> ParseJsonNotes (string jsonString)
+		{
+			Hyena.Json.Deserializer deserializer =
+				new Hyena.Json.Deserializer (jsonString);
+			object obj = deserializer.Deserialize ();
+			Hyena.Json.JsonObject jsonObj =
+				obj as Hyena.Json.JsonObject;
+			Hyena.Json.JsonArray noteArray =
+				(Hyena.Json.JsonArray) jsonObj ["notes"];
+			return ParseJsonNoteArray (noteArray);
+		}
+
+		public IList<NoteInfo> ParseJsonNoteArray (Hyena.Json.JsonArray jsonArray)
+		{
+			if (jsonArray == null)
+				throw new ArgumentNullException ("jsonArray does not contain a valid NoteInfo array representation");
+
+			// TODO: Checks
+			List<NoteInfo> noteList = new List<NoteInfo> ();
+			foreach (Hyena.Json.JsonObject jsonObj in jsonArray)
+				noteList.Add (NoteInfo.ParseJson (jsonObj));
+			return noteList;
+		}
+
+		private string CreateNoteChangesJsonString (IList<NoteInfo> noteUpdates)
+		{
+			Hyena.Json.JsonObject noteChangesObj =
+				new Hyena.Json.JsonObject ();
+			Hyena.Json.JsonArray noteChangesArray =
+				new Hyena.Json.JsonArray ();
+			foreach (NoteInfo note in noteUpdates)
+				noteChangesArray.Add (note.ToUpdateObject ());
+			noteChangesObj ["note-changes"] = noteChangesArray;
+
+			// TODO: Convert noteChangsObj to string
+			return string.Empty;
+		}
+		
+		#endregion
 	}
 }
diff --git a/Tomboy/Addins/WebSyncService/Makefile.am b/Tomboy/Addins/WebSyncService/Makefile.am
index a67fb35..e14ddec 100644
--- a/Tomboy/Addins/WebSyncService/Makefile.am
+++ b/Tomboy/Addins/WebSyncService/Makefile.am
@@ -9,8 +9,7 @@ ASSEMBLIES = 					\
 	$(LINK_TOMBOY_EXE)			\
 	$(GTKSHARP_LIBS) 				\
 	$(LINK_MONO_ADDINS)			\
-	-r:Mono.Posix               \
-	-r:System.Web.Extensions
+	-r:Mono.Posix
 
 #
 # Web Sync Service Addin
@@ -18,12 +17,14 @@ ASSEMBLIES = 					\
 
 TARGET = WebSyncServiceAddin.dll
 CSFILES = \
-	$(srcdir)/WebSyncServer.cs		\
+	$(srcdir)/WebSyncServer.cs          \
 	$(srcdir)/WebSyncServiceAddin.cs	\
-	$(srcdir)/Api/NoteInfo.cs	\
+	$(srcdir)/Api/NoteInfo.cs       	\
 	$(srcdir)/Api/ResourceReference.cs	\
-	$(srcdir)/Api/UserInfo.cs	\
-	$(srcdir)/Api/WebHelper.cs
+	$(srcdir)/Api/UserInfo.cs       	\
+	$(srcdir)/Api/WebHelper.cs          \
+	$(srcdir)/Hyena.Json/*.cs           \
+	$(srcdir)/Hyena.Json/Tests/*.cs
 RESOURCES = \
 	-resource:$(srcdir)/WebSyncService.addin.xml
 
diff --git a/Tomboy/Addins/WebSyncService/WebSyncServer.cs b/Tomboy/Addins/WebSyncService/WebSyncServer.cs
index e00c8c2..77492c4 100644
--- a/Tomboy/Addins/WebSyncService/WebSyncServer.cs
+++ b/Tomboy/Addins/WebSyncService/WebSyncServer.cs
@@ -25,6 +25,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Text.RegularExpressions;
 
 using Tomboy.Sync;
 using Tomboy.WebSync.Api;
@@ -151,14 +152,45 @@ namespace Tomboy.WebSync
 				noteInfo.Tags.Add (tag.Name);
 
 			// TODO: content
+			const string noteContentRegex =
+				@"\A<note-content(\s+version=""(?<contentVersion>[^""]+)"")?>(?<innerContent>.*)</note-content>\Z";
+			Match m = Regex.Match (note.XmlContent, noteContentRegex);
+			Group versionGroup = m.Groups ["contentVersion"];
+			Group contentGroup = m.Groups ["innerContent"];
+
+			double contentVersion;
+			if (versionGroup.Success &&
+			    double.TryParse (versionGroup.Value, out contentVersion)) {
+				noteInfo.NoteContentVersion = contentVersion;
+			} else
+				noteInfo.NoteContentVersion = 0.1;
+
+			if (contentGroup.Success)
+				noteInfo.NoteContent = contentGroup.Value;
+			else
+				noteInfo.NoteContent = string.Empty;
 
 			return noteInfo;
 		}
 
 		private string CreateNoteXml (NoteInfo noteInfo)
 		{
-			// TODO: Everything
-			return string.Empty;
+			NoteData noteData = new NoteData (noteInfo.Guid);
+			noteData.Title = noteInfo.Title;
+			noteData.Text =
+				"<note-content version=\"" + noteInfo.NoteContentVersion.ToString () + "\">" +
+				noteInfo.NoteContent + "</note-content>";
+			noteData.ChangeDate = noteInfo.LastChangeDate;
+			noteData.MetadataChangeDate = noteInfo.LastMetadataChangeDate;
+			noteData.CreateDate = noteInfo.CreateDate;
+			noteData.IsOpenOnStartup = noteInfo.OpenOnStartup;
+
+			foreach (string tagName in noteInfo.Tags) {
+				Tag tag = TagManager.GetOrCreateTag (tagName);
+				noteData.Tags [tag.NormalizedName] = tag;
+			}
+			
+			return NoteArchiver.WriteString (noteData);
 		}
 
 		#endregion



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]