March 2005 - Posts
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.

Tech Head
Brothers is a member of CodeZone.
"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 !!!
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.
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 }
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.
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)
]
If you read my two last posts:
- DataAccessLayer.FindAll(PublishedBy(Author))
- 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)
]
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 }
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.
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.
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 »