Sponsors

News

Jobping Laurent Kempé MVP JetBrains Academy Member Certified ScrumMaster

Contact

My status

View Laurent Kempé's profile on LinkedIn
XING
twitter
facebook


Xbox 360



Map

Locations of visitors to this page

.NET Dudes

Family

French .NET Dudes

Friends

Jobping

Links

Tech Head Brothers

March 2005 - Posts

Microsoft Announces CodeZone!

Microsoft announces CodeZone!  Codezone will be a 'community of communities', a place for you and your groups to post links to your own articles, Web sites, blogs, discussions and events.

CodeZone Site

Tech Head Brothers is a member of CodeZone.

Report from Redmond - By Rick Ross of Javalobby

"Rick Ross, founder of Javalobby, talks about our recent trip to the Microsoft campus in Redmond Washington for the Technology Summit 2005. This gathering of developers from a variety of platforms yielded some interesting insights from all parties. Listen on for Rick's overview and thoughts on the summit.

Listen to the report now!
Read the offline PDF "

From Rick: "I am encouraging mutual respect and a dialogue to keep the possibility for progress alive. Frozen hatred is not in the best interests of the Java developer community."

"I want it to be explicitly clear that I am NOT advocating any Java developer to abandon Java. I am only saying that we should consider, as a community, treating our peer developers in the Microsoft world and elsewhere with more respect and open-mindedness."

Nothing to add. You said everything Rick !!!

8-( 8-( 8-( 8-( 8-( 8-( FURIOUS !!!!! :-( :-( :-( :-( :-( :-( :-(

I just started google to find out my NFOP article on Tech Head Brothers, and guess what I found that again someone copied content from my site without asking me and without any reference to the original author, in that case me.

I really hate that, I mean you spend time to create a website, to devlop it, to produce content, ok because you like that, but at least there should be a minimum respect about that.

So here is my original article:
Utilitaire basé sur NFop
Génération de fichier PDF avec .NET.

And here is the copy:
Comment générer un pdf à partir d'un fichier Word Doc en ASP.net?

If you haven't seen on the bottom of all Tech Head Brothers pages there is a copyright !!! On the site all articles are copyrighted by there author, and the whole site is also copyrighted.

Surfing on the site that is copying my article, I could find a name: Patrice Harmegnies and emails:
patrice.harmegnies@skynet.be
harmegniesp@tiscalinet.be
hpph.net@tiscali.be
even a picture:

If you find that way of copying not normal, please email that person to tell him to stop doing so. Thanks for your support.

Thanks to Didier for his support.

NFOP new way of creating the Pdf

I was asked about the new way to work with NFOP to generate the pdf without the old Engine class. So here is what I am doing:

  1 #region Using
  2 
  3 using System.Net;
  4 using System.Reflection;
  5 using System.Xml;
  6 using System.Xml.Xsl;
  7 using java.io;
  8 using log4net;
  9 using org.apache.fop.apps;
 10 using org.xml.sax;
 11 using TechHeadBrothers.Portal.UI;
 12 using StringWriter = System.IO.StringWriter;
 13 
 14 #endregion
 15 
 16 namespace TechHeadBrothers.TechHeadBrothers.Portal.UI
 17 {
 18 	/// <summary>
 19 	/// Strategy to print PDF using FOP
 20 	/// </summary>
 21 	public class FOPPrintStrategy : PrintStrategy
 22 	{
 23 		#region Logging Definition
 24 
 25 		private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 26 
 27 		#endregion	
 28 
 29 		protected override void Print(PrintArticle page, string xmlpath, string xslpah, XsltArgumentList xsltargs)
 30 		{
 31 			string fullFoDoc = XmlContentToFoContent(page, xmlpath, xslpah);
 32 
 33 			InputSource source = new InputSource(fullFoDoc);
 34 			ByteArrayOutputStream output = new ByteArrayOutputStream();
 35 
 36 			try
 37 			{
 38 				Driver driver = new Driver(source, output);
 39 				driver.setRenderer(Driver.RENDER_PDF);
 40 				driver.run();
 41 				output.close();
 42 
 43 				int sz = output.buf.Length;
 44 				byte[] pdf = new byte[sz];
 45 				for (int i = 0; i < sz; i++)
 46 					pdf[i] = (byte) output.buf[i];
 47 
 48 				page.Response.ClearHeaders();
 49 				page.Response.Clear();
 50 
 51 				page.Response.AddHeader("Content-Disposition", "attachment; filename=TechHeadBrothers.pdf");
 52 				page.Response.ContentType = "application/octet-stream";
 53 
 54 				page.Response.Flush();
 55 				page.Response.BinaryWrite(pdf);
 56 				page.Response.End();
 57 			}
 58 			catch (FOPException fope)
 59 			{
 60 				if (log.IsDebugEnabled)
 61 					log.Debug(fope.getMessage());
 62 			}
 63 		}
 64 }
Creating PDF with .NET

As I am using a lot XML, XML Schema and XSLT, e.g. for the content published on Tech Head Brothers, it is natural to use FOP and it's .NET port NFOP by Jason Pettys. Jason published a new version of NFOP based on the FOP version 0.20.5 that is working better than the first port. I encourage you to download this version to give it a try.

I wrote an article, in French,  about NFOP that you can read on Tech Head Brothers:
Utilitaire basé sur NFop
Génération de fichier PDF avec .NET.

Updater Application Block–Version 2.0

The latest release of Updater Application Block, version 2.0, can be downloaded from Microsoft Download Center.

Updater Application Block, version 2.0, uses other application blocks included in patterns & practices Enterprise Library. The Updater Application Block uses the Configuration Application Block and the Cryptography Application Block. You can choose to use these in your application or just take them as part of the implementation of the updater. Enterprise Library was released in January 2005. To learn about and download Enterprise Library, use the following links:

[ Currently Playing : beautiful - Moby - hotel (03:12) ]

Posted: Mar 15 2005, 10:50 PM by lkempe | with no comments
Filed under:
Introducing Custom Entity Classes

If you read my two last posts:

  1. DataAccessLayer.FindAll(PublishedBy(Author))
  2. Refactoring the set of Predicate with an Interpreter

Then I encourage you to read the article by Karl Seguin From Microsoft Corporation: "On the Way to Mastering ASP.NET: Introducing Custom Entity Classes" published on MSDN. It is a clear explanation of what I started on that two posts full of source code.

[ Currently Playing : hotel intro - Moby - hotel (01:55) ]

Refactoring the set of Predicate with an Interpreter

This evening I continued my journey with the C# Generics. I refactored what I described in my post "DataAccessLayer.FindAll(PublishedBy(Author)) " to be able to use the Design Pattern Interpreter.

The result in the ASPX code behind file is the following:

  1 AndSpec spec = new AndSpec(
  2                         new AndSpec(
  3                             new PublishedSpec(),
  4                             new BeforeDateSpec(DateTime.Parse("01/01/2005"))
  5                         ),
  6                         new OrSpec(
  7                             new AuthorSpec("Mathieu Kempé"),
  8                             new AuthorSpec("Laurent Kempé")
  9                         )
 10                     );
 11 
 12 DataAccessor<Article> articles = new DataAccessor<Article>("GetArticles");
 13 GridView3.DataSource = articles.FindAll(Matching(spec));
 14 GridView3.DataBind();
With the unique Matching Predicate, replacing all the other Predicate:
  1 protected Predicate<Article> Matching(Spec spec)
  2 {
  3 	return delegate(Article a)
  4 	{
  5 		return spec.isSatisfiedBy(a);
  6 	};
  7 }

To achieve this I first added two more properties to my Entity, Article. I did not added new constructors because those two properties are not mandatory:

  1 private DateTime datePublished;
  2 
  3 public DateTime DatePublished
  4 {
  5 	get { return datePublished; }
  6 	set { datePublished = value; }
  7 }
  8 
  9 private DateTime dateModified;
 10 
 11 public DateTime DateModified
 12 {
 13 	get { return dateModified; }
 14 	set { dateModified = value; }
 15 }
Then I modified my Data Access Layer to have it a bit more generic, starting with the interface :
  1 interface IDataAccess<T>
  2 {
  3 	List<T> GetAll();
  4 
  5 	List<T> FindAll(Predicate<T> match);
  6 }
  7 
I removed the method "T Get(Guid uuid)" and "T Get(string uuid)" because that can be easily expressed with a Predicate.
I made a Generic implementation of my Data Access through a DataAccessor class:
  1 namespace TechHeadBrothers.Portal.DAL
  2 {
  3 	public class DataAccessor<T> : IDataAccess<T> where T : new()
  4 	{
  5 		List<T> list = null;
  6 
  7 		public DataAccessor(string sp)
  8 		{
  9 			readFromDatabase(sp);
 10 		}
 11 
 12 		#region Protected Methods
 13 
 14 		protected void readFromDatabase(string sp)
 15 		{
 16 			// Create Instance of Connection and Command Object
 17 			SqlConnection myConnection =
 18 				new SqlConnection(ConfigurationManager.ConnectionStrings["TechHeadBrothers"].ConnectionString);
 19 
 20 			SqlDataAdapter myCommand = new SqlDataAdapter(sp, myConnection);
 21 
 22 			// Mark the Command as a SPROC
 23 			myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
 24 
 25 			// Create and Fill the DataSet
 26 			DataSet ds = new DataSet();
 27 			myCommand.Fill(ds);
 28 
 29 			myConnection.Close();
 30 
 31 			this.list = DataAdapterFactory.createAdapter<T>().Adapt(ds.Tables[0]);
 32 		}
 33 
 34 		#endregion
 35 
 36 		#region IDataAccess<T> Members
 37 
 38 		public List<T> GetAll()
 39 		{
 40 			return list;
 41 		}
 42 
 43 		public List<T> FindAll(Predicate<T> match)
 44 		{
 45 			return list.FindAll(match);
 46 		}
 47 
 48 		#endregion
 49 	}
 50 }
 
I had to implement an Adapter to convert the data from the Database representation to the Entity :
 
  1 abstract class DataAdapter<T> 
  2 {
  3 	public List<T> Adapt(DataTable table)
  4 	{
  5 		List<T> list = new List<T>(table.Rows.Count);
  6 
  7 		foreach (DataRow row in table.Rows)
  8 		{
  9 			list.Add(this.Adapt(row));
 10 		}
 11 
 12 		return list;
 13 	}
 14 
 15 	public abstract T Adapt(DataRow row);
 16 }
 
And a Factory :
 
  1 class DataAdapterFactory
  2 {
  3     public static DataAdapter<T> createAdapter<T>() where T : new()
  4     {
  5         string name = new T().GetType().Name.ToLower();
  6 
  7         if ( name == "article")
  8             return new ArticleAdapter() as DataAdapter<T>;
  9         else if ( name == "author")
 10             return new AuthorAdapter() as DataAdapter<T>;
 11 
 12         return null;
 13     }
 14 }
 
Here is the concrete implementation for the Article Entity Adapter:
 
  1 class ArticleAdapter : DataAdapter<Article>
  2 {
  3     public override Article Adapt(DataRow row)
  4     {
  5         Article article = new Article((string)row["Title"],
  6                                       (string)row["Description"],
  7                                       (string)row["Author"],
  8                                         (bool)row["isPublished"],
  9                                         (Guid)row["uuid"]);
 10 
 11         if (row["DatePublished"] != DBNull.Value)
 12         {
 13             article.DatePublished = (DateTime)row["DatePublished"];
 14         }
 15 
 16         if (row["DateModified"] != DBNull.Value)
 17         {
 18             article.DateModified = (DateTime)row["DateModified"];
 19         }
 20 
 21         return article;
 22     }
 23 }
 
I made also a Business Layer generic class, but has it is just for the moment a wrapper around the DataAccessor, I will not show it.
 
And finally the Interpreter Design Pattern:
 
  1 public abstract class Spec
  2 {
  3 	public abstract bool isSatisfiedBy(Article article);
  4 }
With the different concrete Specifications:
  1 public class PublishedSpec : Spec
  2 {
  3 	public PublishedSpec()
  4 	{
  5 	}
  6 
  7 	public override bool isSatisfiedBy(Article article)
  8 	{
  9  		return (article.isPublished == true);
 10 	}
 11 }
 12 
 13 public class BeforeDateSpec : Spec
 14 {
 15 	private DateTime date;
 16 
 17 	public DateTime Date
 18 	{
 19 		get { return date; }
 20 		set { date = value; }
 21 	}
 22 
 23 	public BeforeDateSpec(DateTime date)
 24 	{
 25 		this.Date = date;
 26 	}
 27 
 28 	public override bool isSatisfiedBy(Article article)
 29 	{
 30 		return (article.DatePublished < this.Date);
 31 	}
 32 }
 33 
 34 public class AuthorSpec : Spec
 35 {
 36 	private string author;
 37 
 38 	public string Author
 39 	{
 40 	  get { return author;}
 41 	  set { author = value; }
 42 	}
 43 
 44 	public AuthorSpec (string author)
 45 	{
 46 		this.Author = author;
 47 	}
 48 
 49 	public override bool isSatisfiedBy(Article article)
 50 	{
 51  		return (article.Author == this.Author);
 52 	}
 53 }
 54 
 55 public class NotSpec : Spec
 56 {
 57 	private Spec specToNegate;
 58 
 59 	public NotSpec(Spec specToNegate)
 60 	{
 61 		this.specToNegate = specToNegate;
 62 	}
 63 
 64 	public override bool isSatisfiedBy(Article article)
 65 	{
 66 		return !specToNegate.isSatisfiedBy(article);
 67 	}
 68 }
 69 
 70 public class AndSpec : Spec
 71 {
 72 	private Spec augend;
 73 	public Spec Augend
 74 	{
 75 	  get { return augend;}
 76 	}
 77 
 78 	private Spec addend;
 79 	public Spec Addend
 80 	{
 81 	  get { return addend;}
 82 	}
 83 	
 84 	public AndSpec (Spec augend, Spec addend)
 85 	{
 86 		this.augend = augend;
 87 		this.addend = addend;
 88 	}
 89 
 90 	public override bool  isSatisfiedBy(Article article)
 91 	{
 92  		return Augend.isSatisfiedBy(article) && Addend.isSatisfiedBy(article);
 93 	}
 94 }
 95 
 96 public class OrSpec : Spec
 97 {
 98 	private Spec augend;
 99 	public Spec Augend
100 	{
101 		get { return augend; }
102 	}
103 
104 	private Spec addend;
105 	public Spec Addend
106 	{
107 		get { return addend; }
108 	}
109 
110 	public OrSpec(Spec augend, Spec addend)
111 	{
112 		this.augend = augend;
113 		this.addend = addend;
114 	}
115 
116 	public override bool isSatisfiedBy(Article article)
117 	{
118 		return Augend.isSatisfiedBy(article) || Addend.isSatisfiedBy(article);
119 	}
120 }
Microsoft to aquire Groove Network - Groovy Baby

Groove Virtual Office added to lineup of Microsoft Office System products, servers and services
Microsoft Corp. (Nasdaq: MSFT) today announced it will acquire Groove Networks, a leading provider of collaboration software for the 'virtual office'. The deal unites two top technology innovators that help geographically distributed work groups be as productive as those that work in a single physical location. Financial terms of the acquisition were not disclosed.

Read the press release
Customer FAQ

Microsoft PressPass interview
with Jeff Raikes and Ray Ozzie

That's something I was saying at the minute I saw the first time Virtual Office.

Ok, first step is to have Virtual Office in the Office System. The next step is to have it at the OS level. Imagine scenarios using distributed workspace in which you are able to add user easily, to share content on a peer to peer basis with all workspace's users, to communicate with voice over ip, presence, messaging... Now add to this the power of WinFS or Msn Deskbar, and integrate it in the OS with look and feel of longhorn. My opinion is that it will absolutely change the way people are working together. A revolution is starting.
Posted: Mar 10 2005, 09:24 PM by lkempe | with 3 comment(s)
Filed under:
DataAccessLayer.FindAll(PublishedBy(Author))

One of the first development rule is to write human readable code. Why ? To avoid to have to write comments ;-) Because it will be read as a spoken language and it separate important code from distracting one.

What do you think about that line of code:

return DAL.FindAll(PublishedBy(Author));

Someone that has no clue about development might even read that code. Ok except the DAL word ;-)

With C# 2.0 you are able to write readable code like this using Generics, and the power of closures. In C# 2.0 closure are supported through the form of anonymous delegates.

Check out the different methods returning collection accordign to predefined rules: getAllUnpublished(), getAllPublished(), getAllPublishedBy()... There are all using Predicate, so to say anonymous delegate, that gives you human readable code.

Client code:

  1 protected void Page_Load(object sender, EventArgs e)
  2 {
  3 	GridView2.DataSource = TechHeadBrothers.Portal.BLL.ArticleBLL.getAllPublishedBy("Laurent Kempé");
  4 	GridView2.DataBind();
  5 
  6 	GridView3.DataSource = TechHeadBrothers.Portal.BLL.ArticleBLL.getAllWaitPublishingBy("Laurent Kempé");
  7 	GridView3.DataBind();
  8 }

The Business Layer:

  1 #region Using
  2 
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Text;
  6 using TechHeadBrothers.Portal.Entities;
  7 using TechHeadBrothers.Portal.DAL; 
  8 
  9 #endregion
 10 
 11 namespace TechHeadBrothers.Portal.BLL
 12 {
 13 	public static class ArticleBLL
 14 	{
 15 		static ArticleDAL DAL = new ArticleDAL();
 16 
 17 		public static List<Article> getAll()
 18 		{
 19 			return DAL.GetAll();
 20 		}
 21 
 22 		public static List<Article> getAllUnpublished()
 23 		{
 24 			return DAL.FindAll(NotPublished());
 25 		}
 26 
 27 		public static List<Article> getAllPublished()
 28 		{
 29 			return DAL.FindAll(Published());
 30 		}
 31 
 32 		public static List<Article> getAllPublishedBy(string Author)
 33 		{
 34 			return DAL.FindAll(PublishedBy(Author));
 35 		}
 36 
 37 		public static List<Article> getAllWaitPublishingBy(string Author)
 38 		{
 39 			return DAL.FindAll(WaitPublishingBy(Author));
 40 		}
 41 
 42 		protected static Predicate<Article> WaitPublishingBy(string author)
 43 		{
 44 			return delegate(Article a)
 45 			{
 46 				return !a.isPublished && (a.Author.ToLower() == author.ToLower());
 47 			};
 48 		}
 49 
 50 		protected static Predicate<Article> PublishedBy(string author)
 51 		{
 52 			return delegate(Article a)
 53 			{
 54 				return a.isPublished && (a.Author.ToLower() == author.ToLower());
 55 			};
 56 		}
 57 
 58 		protected static Predicate<Article> Published()
 59 		{
 60 			return delegate(Article a)
 61 			{
 62 				return a.isPublished;
 63 			};
 64 		}
 65 
 66 		protected static Predicate<Article> NotPublished()
 67 		{
 68 			return delegate(Article a)
 69 			{
 70 				return (!a.isPublished);
 71 			};
 72 		}
 73 	}
 74 }
 75 

The Entity class is represented as:

  1 #region Using
  2 
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Text; 
  6 
  7 #endregion
  8 
  9 namespace TechHeadBrothers.Portal.Entities
 10 {
 11 	public class Article
 12 	{
 13 		private Guid uuid;
 14 
 15 		public Guid Uuid
 16 		{
 17 			get { return uuid; }
 18 			set { uuid = value; }
 19 		}
 20 
 21 		private string title;
 22 
 23 		public string Title
 24 		{
 25 			get { return title; }
 26 			set { title = value; }
 27 		}
 28 
 29 		private string description;
 30 
 31 		public string Description
 32 		{
 33 			get { return description; }
 34 			set { description = value; }
 35 		}
 36 
 37 		private bool ispublished;
 38 
 39 		public bool isPublished
 40 		{
 41 			get { return ispublished; }
 42 			set { ispublished = value; }
 43 		}
 44 
 45 		private string author;
 46 
 47 		public string Author
 48 		{
 49 			get { return author; }
 50 			set { author = value; }
 51 		}
 52 
 53 		public Article(Guid uuid, string title, string description, string author)
 54 		{
 55 			this.Uuid = uuid;
 56 			this.Title = title;
 57 			this.Description = description;
 58 			this.isPublished = false;
 59 			this.Author = author;
 60 		}
 61 
 62 		public Article(string uuid, string title, string description, string author)
 63 			: this(new Guid (uuid), title, description, author)
 64 		{
 65 
 66 		}
 67 
 68 		public Article(string title, string description, string author)
 69 			: this(Guid.NewGuid(), title, description, author)
 70 		{
 71 
 72 		}
 73 	}
 74 } 

And the Data Access Layer Article class:

  1 #region Using
  2 
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Text;
  6 
  7 #endregion
  8 
  9 namespace TechHeadBrothers.Portal.DAL
 10 {
 11 	interface IDataAccess<T>
 12 	{
 13 		T Get(Guid uuid);
 14 
 15 		T Get(string uuid);
 16 
 17 		List<T> GetAll();
 18 
 19 		List<T> FindAll(Predicate<T> match);
 20 	}
 21 
 22 	public class ArticleDAL : IDataAccess<TechHeadBrothers.Portal.Entities.Article>
 23 	{
 24 		List<TechHeadBrothers.Portal.Entities.Article> articles;
 25 
 26 		public ArticleDAL(List<TechHeadBrothers.Portal.Entities.Article> articles)
 27 		{
 28 			this.articles = articles;
 29 		}
 30 
 31 		public ArticleDAL()
 32 		{
 33 			this.articles = new List<TechHeadBrothers.Portal.Entities.Article>();
 34 
 35 			//TODO: Remove this is just for test
 36 			this.articles.Add(
 37 				new TechHeadBrothers.Portal.Entities.Article("Les generics dans C#",
 38 				"Démonstration de l'utilisation des générics dans C# 2.0",
 39 				"Laurent Kempé"));
 40 
 41 			TechHeadBrothers.Portal.Entities.Article article =
 42 				new TechHeadBrothers.Portal.Entities.Article("8BF7FEBE-9FEB-4db6-86B7-70A6C44B1CAA",
 43 				"Les iterators dans C#",
 44 				"Démonstration de l'utilisation des iterators dans C# 2.0",
 45 				"Laurent Kempé");
 46 			article.isPublished = true;
 47 			this.articles.Add(article);
 48 		}
 49 
 50 		#region IDataAccess<Article> Members
 51 
 52 		public TechHeadBrothers.Portal.Entities.Article Get(Guid uuid)
 53 		{
 54 			for (int i = 0; i < articles.Count; i++)
 55 			{
 56 				if (articles[i].Uuid == uuid)
 57 				{
 58 					return articles[i];
 59 				}
 60 			}
 61 
 62 			return null;
 63 		}
 64 
 65 		public TechHeadBrothers.Portal.Entities.Article Get(string uuid)
 66 		{
 67 			return this.Get(new Guid(uuid));
 68 		}
 69 
 70 		public List<TechHeadBrothers.Portal.Entities.Article> GetAll()
 71 		{
 72 			return articles;
 73 		}
 74 
 75 		public List<TechHeadBrothers.Portal.Entities.Article> FindAll(Predicate<TechHeadBrothers.Portal.Entities.Article> match)
 76 		{
 77 			return articles.FindAll(match);
 78 		}
 79 
 80 		#endregion
 81 	}
 82 }
 83 

[ Currently Playing : Sound Enforcer / Impact - Carl Cox (04:10) ]

More Posts Next page »