Sunday, April 22, 2007
Cobertura vs EMMA
We've been using Cobertura at work till now and its done its job nicely - the reports look great and the maven 1.x integration, while not neat, is functional. While we knew that someday we were going to have to merge coverage data and have a single report across multiple test methods (junit, selenium tests and manual), cobertura documentation stated that this was possible and so we weren't really bothered.
Thought I'd give it a whirl and set it up - and that's when the trouble started. Atleast, with the maven integration.
First of all - there's no way to just instrument code. You can generate the report (which will instrument classes and run the tests) but if you just want to instrument classes so that the final deployable contains instrumented classes, its a no go with the maven plugin tools.
Obviously, no point giving it up there - so thought I'd just include the ant tasks and go the ant way in my maven goal. Turns out that there's no 'plugin init' kind of goal that can be called post build:start that will set up dependencies and import the cobertura ant tasks. You have to do it all yourself. Fine - went that way too - so now my maven.xml uses the cobertura ant tasks and finally I'm able to generate an instrumented build. YIPPPPPPPEEEEEE.... or wait...lets' just make sure that this thing works...
Does it?
Turns out - no - it doesnt - so I dropped the WAR into tomcat and accessed the login page of the application and then shut down tomcat nicely. There's even a cobertura.ser created in the tomcat bin folder and I'm thinking that probably this will all work together finally...
So I go ahead, tweak my Maven.xml further with a coverage task that will merge the data from the junit runs and servlet container runs. Turn the switch on... and lo and behold...Exception reading the merged data file. Back to google and after hunting around for sometime found this Bug while merging reports
So finally I'm ready to give up cobertura and give Emma a try...and it couldnt have been better...
1. Goals are nicely setup
2. You can init the emma system with the emma:init goal and then use ant tasks if you want flexibility for doing things like merging reports.
3. The merging works :))
One sticky issue that I did come up with was that the for the same source and test cases the coverage reported by cobertura and emma differ widely. With Cobertura, we were at 40% coverage while with EMMA, the number's up to 60% coverage - and while EMMA has some literature on how it does things - I'd be glad if someone did explain why or how the reported numbers could be so different for the same base code and unit test suite?
Tuesday, April 17, 2007
Tulip festival at Skagit county
Anyway, had a lovely weekend driving up to Mount Vernon with friends and had a memorable weekend.
![]() |
| TulipFestival |
Saturday, March 17, 2007
Ninotech Path Copy 4
Novell Cool Solutions: Cool Tool
Was looking for a shell extension to copy filenames from explorer. Thought there'd be a dime a dozen - and it turns out that
a) they have 20 other things that I dont want.
b) Its trial ware.
Finally after searching high and low, came across this and it's GREAT!
powered by performancing firefox
Thursday, March 15, 2007
Production Eclipse Configuration
At a minimum, it helps to have a central Eclipse installation that has all the tools configured and setup - so each person doesn't have to do it. Alternatively, there should be a reference set of plugins and their configuration files available in the source control repository. Here's my eclipse configuration
Wednesday, March 14, 2007
Tips for using Eclipse
Great Article - full of very very useful tips!
Firefox - not so obvious search
In Firefox, you can use / (forward slash) to search for text OR links - and if its a link, then you can follow the link just by clicking Enter! That is way cool - especially when you're on a laptop and cant/dont have your mouse around. I've always find it a pain to do a "link find" - ' (single quote) and a text find - ctrl-f separately...Never knew that there was a shortcut that did both and what more - its way natural if you're used to 'less'!!
To complete the keys for Firefox mouseless browsing,
- space - page down
- shift - space - page up
Sunday, February 25, 2007
Performancing and Wordpress - initial imression - very nice!
Performancing | Firefox Add-ons | Mozilla Corporation
Performancing for Firefox is a full featured blog editor that sits right in your Firefox browser and lets you post to your blog easily. You can drag and drop formatted text from the page you happen to be browsing, and take notes as well as post to your blog.
powered by performancing firefox
Saturday, February 24, 2007
Diigo - a hidden gem
I've been using it for quite some time now (after trying out del.icio.us and google notepad) and I'm not budging! Recently I was doing a bunch of research online and diigo excelled!
- Online bookmarking - will also simultaneously post to your del.icio.account
- Firefox toolbar
- tagging
- Web clipping
- Web annotation
Now to "hidden" - I've been on Diigo more than 8 months or so now - and yet I'm still to meet someone who knew about Diigo!!
Diigo rocks!
Imaging the tenth dimension
Great flash movie explaining dimensions 4 (time), 5, 6 all the way uptil 10. And why they stop after 10!
I've never come across a clearer explanation ever and the great visualization does the trick.
Instant messenger client utopia
I hate running 3 different chat clients (yahoo, msn, gtalk) on my machine - and that's just 3x memory, startup programs and useless adversting too many.
And I hate msn and yahoo's advertising that's built into their clients...esp on MSN which insists on opening a mini page on login...
Use GAIM - and do yourself a favour. Of course that's if you don't need the very specialized features :)).
Installation is a breeze and use plugins you like and avoid the bloat....The best plugins I like are guifications and text replace. Lastly, if you keep moving between machines as much as I do, then its a breeze to retain your settings between all your machines.
Friday, April 29, 2005
XSLT Analog to sysouts
Tried a couple of IDEs - Stylus Studio (free edition) and Marrowsoft XSelerator. Stylus studio did a graceful exit, Xselerator went purple in the face and died a gruesome death :-(
Hmm... so after sometime I was wondering if I could annotate the XSL output with information on the templates matched it would atleast help partway. I was thinking of perl/C#/regular expressions and then suddenly the penny dropped "for each xsl:template node, include a comment with the template match/mode" - Hang on!!! looks like that sounds like a job for XSLT....
Anyway, there are a couple of quirks - the first one you hit will be when you try to output a template like this
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="xsl:stylesheet" >
<!-- generate an output xsl:stylesheet node -->
<xsl:stylesheet></xsl:stylesheet>
</xsl:template>
</xsl:stylesheet>
Oops! The XSLT processor cribs (and with good reason too)! It doesn't know which xsl:template is for the current stylesheet vs which is intended to be output to the result document.There are a couple of approaches around this. One is to use xsl:element like this
<xml:namespace prefix = xsl />
<xsl:element name="xsl:template">
</xsl:element>
But this results in enormously wordy documents. Thankfully there's a neater way out. You use something called
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gen="http://www.w3.org/1999/XSL/Transform/2">
<xsl:namespace-alias stylesheet-prefix="gen" result-prefix="xsl"/>
<xsl:template match="xsl:stylesheet">
<gen:stylesheet>
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates></xsl:apply-templates>
<xsl:if test="not(xsl:template[@name='pseudo-xpath-to-current-node'])" >
<xsl:text>
&#10;&#10;
</xsl:text> <xsl:copy-of select="document('')/xsl:stylesheet/xsl:template[ @name='pseudo-xpath-to-current-node']"/>
<xsl:text>
&#10;&#10;
</xsl:text>
</xsl:if>
</gen:stylesheet>
</xsl:template>
</xsl:stylesheet>
Note the usage of xsl:namespace-alias and the code for generating an xsl:stylesheet element in the result document.
I've included my efforts here - along with a simple books.xml, a books.xsl which generates a table and finally an instrument.xsl that instruments books.xsl to generate an instrumented version. Transforming books.xml with the instrumented xslt generates output that annotated with custom nodes that highlight which template got called when.
After I was mostly done with the code, I came across an article in IBM developerWorks which discusses the same topic. Rather than cover the same material again, you can find the article here. Stuff that's different is that I generate custom nodes (which I thought would be useful to view in XML IDE which allow a hierarchical display). I've also shamelessly borrowed the code to generate the Xpath of the node (part of what you see in the snippet).
I'm on a high. I've been stuck with this problem o...
Tried a couple of IDEs - Stylus Studio (free edition) and Marrowsoft XSelerator. Stylus studio did a graceful exit, Xselerator went purple in the face and died a gruesome death :-(
Hmm... so after sometime I was wondering if I could annotate the XSL output with information on the templates matched it would atleast help partway. I was thinking of perl/C#/regular expressions and then suddenly the penny dropped "for each xsl:template node, include a comment with the template match/mode" - Hang on!!! looks like that sounds like a job for XSLT....
Anyway, there are a couple of quirks - the first one you hit will be when you try to output a template like this
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="xsl:stylesheet" >
<!-- generate an output xsl:stylesheet node -->
<xsl:stylesheet>
</xsl:stylesheet>
</xsl:template>
</xsl:stylesheet>
Oops! The XSLT processor cribs (and with good reason too)! It doesn't know which xsl:template is for the current stylesheet vs which is intended to be output to the result document.There are a couple of approaches around this. One is to use xsl:element like this
<xml:namespace prefix = xsl />
<xsl:element name="xsl:template"></xsl:element>
But this results in enormously wordy documents. Thankfully there's a neater way out. You use something called . Basically, what it does is that it allows you to use a dummy namespace in your xslt. You set up the dummy namespace (let's say genxsl) to map to a real namespace in the result document (xsl). Then you basically use the dummy namespace in your XSLT. However, when generating output, the processor will replace all references to the dummy namespace in the result document with references to the real namespace. For ex.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gen="http://www.w3.org/1999/XSL/Transform/2">
<xsl:namespace-alias stylesheet-prefix="gen" result-prefix="xsl"/>
<xsl:template match="xsl:stylesheet">
<gen:stylesheet>
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}"><xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates></xsl:apply-templates>
<xsl:if test="not(xsl:template[@name='pseudo-xpath-to-current-node'])" >
<xsl:text></xsl:text>
<xsl:copy-of select="document('')/xsl:stylesheet/xsl:template[ @name='pseudo-xpath-to-current-node']"/><xsl:text></xsl:text>
</xsl:if>
</gen:stylesheet>
</xsl:template>
Note the usage of xsl:namespace-alias and the code for generating an xsl:stylesheet element in the result document.
I've included my efforts here - along with a simple books.xml, a books.xsl which generates a table and finally an instrument.xsl that instruments books.xsl to generate an instrumented version. Transforming books.xml with the instrumented xslt generates output that annotated with custom nodes that highlight which template got called when.
After I was mostly done with the code, I came across an article in IBM developerWorks which discusses the same topic. Rather than cover the same material again, you can find the article here. Stuff that's different is that I generate custom nodes (which I thought would be useful to view in XML IDE which allow a hierarchical display). I've also shamelessly borrowed the code to generate the Xpath of the node (part of what you see in the snippet).
Thursday, April 14, 2005
I love the premise of Test Driven Development - I've even used it a few times in the line of duty ;-) (I do have to admit, I've been naughty and left out the step of  seeing the test case fail a few times )...Anyway, I end up working on web applications more often than not and while you can use TDD for your class libraries, a web app is a totally different animal. The fact that you can use TDD for class libraries makes the whole thing even more frustrating - you have a bit that works for sure (the class libraries with their tests) and then you hit this piece (aspx) on which you dont have the same level of confidence.
I've been working around it making sure that pages generate nice logs, so that during development, whenever I find a sticky piece, I put in an additional log statement. This thing works but at best is a poor cousin to automated testing ala nunit.
Enter NunitAsp - it promises to do for web applications what nunit does to class libraries - pretty stiff goal indeed! I've looked at this piece about an year ago for a similar project but had to decide against its use after going through the feature list. As a result, though I understand the aims, I havent got my hands into it. These days' I'm planning to do a dive-deep into it - just to make a more diligent evaluation if it'll actually work.
I love the premise of Test Driven Development -...
I love the premise of Test Driven Development - I've even used it a few times in the line of duty ;-) (I do have to admit, I've been naughty and left out the step of  seeing the test case fail a few times )...Anyway, I end up working on web applications more often than not and while you can use TDD for your class libraries, a web app is a totally different animal. The fact that you can use TDD for class libraries makes the whole thing even more frustrating - you have a bit that works for sure (the class libraries with their tests) and then you hit this piece (aspx) on which you dont have the same level of confidence.
I've been working around it making sure that pages generate nice logs, so that during development, whenever I find a sticky piece, I put in an additional log statement. This thing works but at best is a poor cousin to automated testing ala nunit.
Enter NunitAsp - it promises to do for web applications what nunit does to class libraries - pretty stiff goal indeed! I've looked at this piece about an year ago for a similar project but had to decide against its use after going through the feature list. As a result, though I understand the aims, I havent got my hands into it. These days' I'm planning to do a dive-deep into it - just to make a more diligent evaluation if it'll actually work.
Monday, April 11, 2005
For the most part, I find ASP.NET far more easier to use than Java. But the ONE BIG THING where I've found ASP.NET sorely lacking is in the support for page templates.
Page templates, if you need to brush up, allow you to define common layout and contents for a web site. Furthermore, once defined, its easy to change the layout and or move your default items around the place.
Basically, what you need is to be able to define a template page with the different areas (header, left pane, main content, footer etc). So the template page controls what is shown where. In addition, you also define the default content for all these areas.
Now each page in the application just overrides the content for the main area (assuming that the defaults are fine for the rest of it). WOW!!!
Java's had this quite some time - Jakarta Struts has something called Tiles which does exactly this.
For .NET, as I mentioned, the need's going to be fulfilled with v2.0 of ASP.NET. Meanwhile, if you feel the idea's great and there's no point in waiting for v2.0, release, do take a look at MasterPage as www.asp.net control gallery. Do note that since the asp.net team has released this control, there's a good chance that most of the features will end up in asp.net 2.0.
There are a few shortcomings of the control though - you'll get a hang of them if you read the posts. Paul Wilson has a version which overcomes these - and best of all, he releases the control with source :). You can find it here.
For the most part, I find ASP.NET far more easi...
For the most part, I find ASP.NET far more easier to use than Java. But the ONE BIG THING where I've found ASP.NET sorely lacking is in the support for page templates.
Page templates, if you need to brush up, allow you to define common layout and contents for a web site. Furthermore, once defined, its easy to change the layout and or move your default items around the place.
Basically, what you need is to be able to define a template page with the different areas (header, left pane, main content, footer etc). So the template page controls what is shown where. In addition, you also define the default content for all these areas.
Now each page in the application just overrides the content for the main area (assuming that the defaults are fine for the rest of it). WOW!!!
Java's had this quite some time - Jakarta Struts has something called Tiles which does exactly this.
For .NET, as I mentioned, the need's going to be fulfilled with v2.0 of ASP.NET. Meanwhile, if you feel the idea's great and there's no point in waiting for v2.0, release, do take a look at MasterPage as www.asp.net control gallery. Do note that since the asp.net team has released this control, there's a good chance that most of the features will end up in asp.net 2.0.
There are a few shortcomings of the control though - you'll get a hang of them if you read the posts. Paul Wilson has a version which overcomes these - and best of all, he releases the control with source :). You can find it here.
Friday, April 08, 2005
The ASP.NET validation summary is great for displaying all the errors in the page. It would be nice though to be able to use a validation summary to display errors that occur on the server side.
A typical scenario is when you have a page that does a search and then displays the results of the search. For the case where no results are found, it would be nice to be able to display the results in our custom validation summary control. It takes away the need to handle the display of the error message in a validation summary control.
This is what you can do about it - implement the IValidator class
public
class CustomErrorMessage:IValidator
    {
        privatestring message;
        public CustomErrorMessage()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        #region IValidator Members
        publicvoid Validate()
        {
            // TODO: Add CustomErrorMessage.Validate implementation
        }
        publicbool IsValid
        {
            get
            {
                returnfalse;
            }
            set
            {
               Â
            }
        }
        publicstring ErrorMessage
        {
            get
            {
               Â
                return message;
            }
            set
            {
                this.message = value;
            }
        }
        #endregion
    }
And here's code to use the validator at runtime in response to a server side error.
CustomErrorMessage msg = new CustomErrorMessage();
msg.ErrorMessage = "No rows found";
ServerErrors.Visible =true;
ValidationSummary1.Visible = false;
Page.Validators.Add(msg);
Page.Validate();
The ASP.NET validation summary is great for displaying all the errors in the page. It would be nice though to be able to use a validation summary to display errors that occur on the server side.
A typical scenario is when you have a page that does a search and then displays the results of the search. For the case where no results are found, it would be nice to be able to display the results in our custom validation summary control. It takes away the need to handle the display of the error message in a validation summary control.
This is what you can do about it - implement the IValidator class
public
class CustomErrorMessage:IValidator
    {
        privatestring message;
        public CustomErrorMessage()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        #region IValidator Members
        publicvoid Validate()
        {
            // TODO: Add CustomErrorMessage.Validate implementation
        }
        publicbool IsValid
        {
            get
            {
                returnfalse;
            }
            set
            {
               Â
            }
        }
        publicstring ErrorMessage
        {
            get
            {
               Â
                return message;
            }
            set
            {
                this.message = value;
            }
        }
        #endregion
    }
Been tinkering with getting a nice paging algorithm out. To get a basic hang of the problem, do take a look at
Do take a look at the second query given. I've modified it a little bit so that you can sort by a given field and removed a bit of the cruft (the au_lname like '%A%' bit). Here the table used is called Pager - with a column called Name.
Some of my bare bones requirements for a paging system are:
1. Should allow sorting
2. Should not impose any requirements on the table schema/ resultset.
3. Should be done on SQL Server as much as possible. Definitely not default paging that results in all rows being sent to the middle layer.
4. Ideally, should not require dynamic queries. (Though note that this conflicts with 1 & 3 as these two requirements almost make dynamic queries mandatory).
5. Should not use temp tables.
declare @pagenum int
declare @pageSize int
set rowcount @pagesize
select *Â
   from Pager P
where
    (select count(*)
    from Pager P2
    where P2.Name <= P.name) > @pagesize * @pagenum
order by
       p.name
Â
The ASP.NET validation summary is great for dis...
The ASP.NET validation summary is great for displaying all the errors in the page. It would be nice though to be able to use a validation summary to display errors that occur on the server side.
A typical scenario is when you have a page that does a search and then displays the results of the search. For the case where no results are found, it would be nice to be able to display the results in our custom validation summary control. It takes away the need to handle the display of the error message in a validation summary control.
This is what you can do about it - implement the IValidator class
public
class CustomErrorMessage:IValidator
    {
        privatestring message;
        public CustomErrorMessage()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        #region IValidator Members
        publicvoid Validate()
        {
            // TODO: Add CustomErrorMessage.Validate implementation
        }
        publicbool IsValid
        {
            get
            {
                returnfalse;
            }
            set
            {
               Â
            }
        }
        publicstring ErrorMessage
        {
            get
            {
               Â
                return message;
            }
            set
            {
                this.message = value;
            }
        }
        #endregion
    }
And here's code to use the validator at runtime in response to a server side error.
CustomErrorMessage msg = new CustomErrorMessage();
msg.ErrorMessage = "No rows found";
ServerErrors.Visible =true;
ValidationSummary1.Visible = false;
Page.Validators.Add(msg);
Page.Validate();
The ASP.NET validation summary is great for dis...
The ASP.NET validation summary is great for displaying all the errors in the page. It would be nice though to be able to use a validation summary to display errors that occur on the server side.
A typical scenario is when you have a page that does a search and then displays the results of the search. For the case where no results are found, it would be nice to be able to display the results in our custom validation summary control. It takes away the need to handle the display of the error message in a validation summary control.
This is what you can do about it - implement the IValidator class
public
class CustomErrorMessage:IValidator
    {
        privatestring message;
        public CustomErrorMessage()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        #region IValidator Members
        publicvoid Validate()
        {
            // TODO: Add CustomErrorMessage.Validate implementation
        }
        publicbool IsValid
        {
            get
            {
                returnfalse;
            }
            set
            {
               Â
            }
        }
        publicstring ErrorMessage
        {
            get
            {
               Â
                return message;
            }
            set
            {
                this.message = value;
            }
        }
        #endregion
    }
Been tinkering with getting a nice paging algor...
Been tinkering with getting a nice paging algorithm out. To get a basic hang of the problem, do take a look at
Do take a look at the second query given. I've modified it a little bit so that you can sort by a given field and removed a bit of the cruft (the au_lname like '%A%' bit). Here the table used is called Pager - with a column called Name.
Some of my bare bones requirements for a paging system are:
1. Should allow sorting
2. Should not impose any requirements on the table schema/ resultset.
3. Should be done on SQL Server as much as possible. Definitely not default paging that results in all rows being sent to the middle layer.
4. Ideally, should not require dynamic queries. (Though note that this conflicts with 1 & 3 as these two requirements almost make dynamic queries mandatory).
5. Should not use temp tables.
declare @pagenum int
declare @pageSize int
set rowcount @pagesize
select *Â
   from Pager P
where
    (select count(*)
    from Pager P2
    where P2.Name <= P.name) > @pagesize * @pagenum
order by
       p.name
Â
Monday, March 28, 2005
Have been pulling my hair out trying to make commandbar buttons go in VB Addins for Office 2000. There are a couple of gotchas here
1. Any references to buttons that you've added are not valid by the time you get to the disconnection method. There's a MSDN KB article on this and the workaround is to use FindControl to get a new reference to the button.
2. The above technique works for Powerpoint and Excel. With ms word, the button is more stubborn. Turns out that it updates the normal template. So in a word addin, in addition to calling delete on the button, you should also save the normal template - see below..
btn.Delete
m_Application.NormalTemplate.Save
Have been pulling my hair out trying to make co...
Have been pulling my hair out trying to make commandbar buttons go in VB Addins for Office 2000. There are a couple of gotchas here
1. Any references to buttons that you've added are not valid by the time you get to the disconnection method. There's a MSDN KB article on this and the workaround is to use FindControl to get a new reference to the button.
2. The above technique works for Powerpoint and Excel. With ms word, the button is more stubborn. Turns out that it updates the normal template. So in a word addin, in addition to calling delete on the button, you should also save the normal template - see below..
btn.Delete
m_Application.NormalTemplate.Save
Thursday, March 24, 2005
BSNL Broadband..
And then it all had to come down eventually!!! For the past two days, the downloads are going at 3 Kbytes/sec... So today I called their help desk and as expected, got no real help other than getting a complaint registered. I was told that the problem will be fixed 'soon' - with no details being provided on how soon is 'soon' :-)
Anyway, thankfully the connections a bit better now - though still slow...getting 100 Kbps - which is way behind the advertised speed.
So its wait and watch down here.
BSNL Broadband..
And then it all had to come down eventually!!! For the past two days, the downloads are going at 3 Kbytes/sec... So today I called their help desk and as expected, got no real help other than getting a complaint registered. I was told that the problem will be fixed 'soon' - with no details being provided on how soon is 'soon' :-)
Anyway, thankfully the connections a bit better now - though still slow...getting 100 Kbps - which is way behind the advertised speed.
So its wait and watch down here.
Thursday, March 10, 2005
Am learning how to call web services asynchronously....here are some good resources to start off with.
Accessing an XML Web Service Asynchronously in Managed Code
Communicating with XML Web Services Asynchronously
I would actually like to make asynch calls from vb (sic!)...well that's quite some way off..
Â
1. Integrating Web Services and COM Components using the SOAP Toolkit - Article
2. Migrating from the Microsoft SOAP Toolkit to the .NET Framework - Article
3. Calling .NET Assemblies and Web Services from VB6 - Article
From:
Thanks, Simon
Wednesday, March 09, 2005
Editing documents in sharepoint library in Office 2000
"Edit
In" functionality is only available for Office XP and Office 2003 on
the client, however I saw this workaround from a now unknown poster and
Joel Faigin
was kind enough to confirm that it works.
But here is a work around to get the same exact function from Office 2000 as you do in Office 2003.
8. Your changes should now be shown, as well as version history if enabled."
from:
http://wss.collutions.com/Lists/FAQ/DispForm.aspx?ID=308
Coaxing IE to open office documents in Application windows
- Launch Windows Explorer.
- Select âFolder Options...â from the Tools menu.
- Select the âFile Typesâ tab.
- Scroll down the list of âRegistered file typesâ until you find âDOC - Microsoft Word Documentâ and select it.
- Click on the âAdvanced...â button at the bottom of the dialog.
- Uncheck the âBrowse in same windowâ checkbox.
from:
http://blogs.msdn.com/gusperez/archive/2004/04/28/122768.aspx
Editing documents in sharepoint library in Office 2000
"Edit
In" functionality is only available for Office XP and Office 2003 on
the client, however I saw this workaround from a now unknown poster and
Joel Faigin
was kind enough to confirm that it works.
But here is a work around to get the same exact function from Office 2000 as you do in Office 2003.
8. Your changes should now be shown, as well as version history if enabled."
from:
http://wss.collutions.com/Lists/FAQ/DispForm.aspx?ID=308
Obituary - My VS.NET 2003 debugger
error with a suggestion to add myself to Debugger Users group or be an
Administrator.
I'm already the administrator and also part of Debugger users group.
Googling a bit, found a collection of entries on M K Park's blog
Feature Request: Environment variable expansion in CMAB
against it is that it doesnt support environment variables for
specifying things like the path of the actual configuration file [One
of the projects that does is Log4Net]
I've looked at the code and supporting environment variable expansion shoudlnt be too difficult to do.
I'll post a suggestion in and see what happens.
Enterprise Library
"Summary
The patterns & practices Enterprise Library is a library
of application blocks designed to assist developers with common
enterprise development challenges. Application blocks are a type of
guidance, provided as source code that can be used "as is," extended,
or modified by developers to use on enterprise development projects.
Enterprise Library features new and updated versions of application
blocks that were previously available as stand-alone application
blocks. All Enterprise Library application blocks have been updated
with a particular focus on consistency, extensibility, ease of use, and
integration."
I've just got a copy of it. The cribs are
A. The download locations for the old Application Blocks is still in
place. They don't link to the Enterprise library page either. (Though
GDN does have a note pointing users to the Enterprise library workspace)
B. I've yet to look at the Blocks in detail, but the changes are big and not very helpful.
a. Namespaces have changed.
b. There's a new configuration tool
c. The documentation's been updated but there's precious little for people migrating from older versions.
d. [Configuration Application Block] <Crib>
Name value collections are not supported and so are XML Serializer. One
of the beauties of the original release was that you could integrate it
with the standard classes seamlessly. Probably, this one does too, but
I'll need to look it up.
Coaxing IE to open office documents in Application windows
- Launch Windows Explorer.
- Select âFolder Options...â from the Tools menu.
- Select the âFile Typesâ tab.
- Scroll down the list of âRegistered file typesâ until you find âDOC - Microsoft Word Documentâ and select it.
- Click on the âAdvanced...â button at the bottom of the dialog.
- Uncheck the âBrowse in same windowâ checkbox.
from:
http://blogs.msdn.com/gusperez/archive/2004/04/28/122768.aspx
Obituary - My VS.NET 2003 debugger
error with a suggestion to add myself to Debugger Users group or be an
Administrator.
I'm already the administrator and also part of Debugger users group.
Googling a bit, found a collection of entries on M K Park's blog
Feature Request: Environment variable expansion in CMAB
against it is that it doesnt support environment variables for
specifying things like the path of the actual configuration file [One
of the projects that does is Log4Net]
I've looked at the code and supporting environment variable expansion shoudlnt be too difficult to do.
I'll post a suggestion in and see what happens.
Enterprise Library
"Summary
The patterns & practices Enterprise Library is a library
of application blocks designed to assist developers with common
enterprise development challenges. Application blocks are a type of
guidance, provided as source code that can be used "as is," extended,
or modified by developers to use on enterprise development projects.
Enterprise Library features new and updated versions of application
blocks that were previously available as stand-alone application
blocks. All Enterprise Library application blocks have been updated
with a particular focus on consistency, extensibility, ease of use, and
integration."
I've just got a copy of it. The cribs are
A. The download locations for the old Application Blocks is still in
place. They don't link to the Enterprise library page either. (Though
GDN does have a note pointing users to the Enterprise library workspace)
B. I've yet to look at the Blocks in detail, but the changes are big and not very helpful.
a. Namespaces have changed.
b. There's a new configuration tool
c. The documentation's been updated but there's precious little for people migrating from older versions.
d. [Configuration Application Block] <Crib>
Name value collections are not supported and so are XML Serializer. One
of the beauties of the original release was that you could integrate it
with the standard classes seamlessly. Probably, this one does too, but
I'll need to look it up.
Monday, March 07, 2005
Sharepoint Web Services and NTLM Authentication
I noticed this strange behaviour and thought its worth a post - till I find a solution/explanation.
Scenario: I have a custom web service running under sharepoint. This means that the .asmx is in "c:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI" and the binaries in the bin folder under it. The url of the web service is
http://aditi277/XTeam/spaces/outlooksynch/_vti_bin/OfflineServices.asmx
The _vti_bin has NTLM authentication enabled.
When I paste the url in a browser, I go straight through to the page without any authentication! (I've set "Prompt for username and password" in IE).
In the web service, Context.Request.IsAuthenticated returns False and Context.User.Identity.Name returns an empty string. This is as expected.
I have a small program that connects to the web service. In the program I'm setting the credentials for the web service.
The fun starts when I create an SPSite object in the web service code. The SPWeb.CurrentUser.ToString() returns the username of the credentials set on the client!!! How the heck is the identity being passed on to Sharepoint? Or is it a bug in sharepoint that it doesnt set the Context properties? I'm stumped!!!
Â
Sharepoint Web Services and NTLM Authentication
I noticed this strange behaviour and thought its worth a post - till I find a solution/explanation.
Scenario: I have a custom web service running under sharepoint. This means that the .asmx is in "c:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI" and the binaries in the bin folder under it. The url of the web service is
http://aditi277/XTeam/spaces/outlooksynch/_vti_bin/OfflineServices.asmx
The _vti_bin has NTLM authentication enabled.
When I paste the url in a browser, I go straight through to the page without any authentication! (I've set "Prompt for username and password" in IE).
In the web service, Context.Request.IsAuthenticated returns False and Context.User.Identity.Name returns an empty string. This is as expected.
I have a small program that connects to the web service. In the program I'm setting the credentials for the web service.
The fun starts when I create an SPSite object in the web service code. The SPWeb.CurrentUser.ToString() returns the username of the credentials set on the client!!! How the heck is the identity being passed on to Sharepoint? Or is it a bug in sharepoint that it doesnt set the Context properties? I'm stumped!!!
Â
Friday, March 04, 2005
Logging in ASP.NET - Web Services (contd.)
I'm almost through with a decent logging implementation for a Web service running under Windows Sharepoint services. Here are some hard earned lessons:
1. I could not use Global.asax for a sharepoint hosted web service. The Sharepoint web services Global.asax derives from stssoap and when I included the code in a C# script block, the code never got invoked.
2. Also, the concept of an application is not useful in the case of web service - since a single web might be used to host multiple services. So, now, I've moved all the Log4Net initialization code to the ASMX code behind ctor. I've also got a SetContext() method that sets the user name, application (service) name. I'm also mulling about including the last few characters from the session key - for cases where the same user is logged on from multiple machines.
3. I need to do some more fine tuning - like enabling the connection pooling for the log4net connection string.
4. Another great lesson learned - and this is for all the times when you've got all the bits of log4net up and running and yet can't seem to get the logs...Use the log4net Debug release with the DbgView utility from sysinternals. Log4net fails silently on errors and just doesn't give you a clue as to what happened. For all those times when something utterly silly like a typo in your config brings all your logging to a standstill, keep DbgView running side by side. If Log4net hits a problem, it'll get logged in the dbgview console. :)
Logging in ASP.NET - Web Services (contd.)
I'm almost through with a decent logging implementation for a Web service running under Windows Sharepoint services. Here are some hard earned lessons:
1. I could not use Global.asax for a sharepoint hosted web service. The Sharepoint web services Global.asax derives from stssoap and when I included the code in a C# script block, the code never got invoked.
2. Also, the concept of an application is not useful in the case of web service - since a single web might be used to host multiple services. So, now, I've moved all the Log4Net initialization code to the ASMX code behind ctor. I've also got a SetContext() method that sets the user name, application (service) name. I'm also mulling about including the last few characters from the session key - for cases where the same user is logged on from multiple machines.
3. I need to do some more fine tuning - like enabling the connection pooling for the log4net connection string.
4. Another great lesson learned - and this is for all the times when you've got all the bits of log4net up and running and yet can't seem to get the logs...Use the log4net Debug release with the DbgView utility from sysinternals. Log4net fails silently on errors and just doesn't give you a clue as to what happened. For all those times when something utterly silly like a typo in your config brings all your logging to a standstill, keep DbgView running side by side. If Log4net hits a problem, it'll get logged in the dbgview console. :)
Thursday, March 03, 2005
Logging in ASP.NET
I've been trying to get decent logs on web application/web service. Its critical in cases where you dont have remote debugging access on the server.
I've been using Log4Net for over an year now and it's saved me more than once. It's the first time that I've tried to use it in a web scenario. There's just a couple of things to keep in mind:
Usually the worker process runs under the ASPNET account - this doesnt have rights to logon and doesnt have an associated console. Meaning console appender is out of the reckoning.
You could use FileAppender (the usual choice on single user applications), however, as multiple requests are served simultaneously, the logs will most probably quite unreadable.
The best choice is the ADONetAppender - you log everything in the DB and then use SQL to get a trace. Here we come across the next problem - how do you get the user information for each log entry?
The solution lies in using log4net's Mapped Diagnostic Context - MDC. Its basically a set of name value pairs that you can render using a pattern layout %X{name} in the log4net config file.
Here's the Log4Net.config file for reference
<Note the lines where the insert statement has an the username parameter and the additional param tag is added to the parameter list. You'll need to create a matching column definition in your table.
The next issue to be tackled is the log4net initialization and setting the username for the request.
The log4net system can be initialized the Application_onStart event and you can set the username in the PreRequestHandlerExecute event - this event is called just before the request is handed off for processing to the HttpModule and hence the best place to set the username. Relevant portions of Global.asax are shown below.
Â
protected
void Application_Start(Object sender, EventArgs e)
{
   ConfigureLog4Net();          Â
   Debug.WriteLine("In Application Start");
}
privatevoid ConfigureLog4Net()
{
   string filepath = Server.MapPath("log4net.config");
   Debug.WriteLine(filepath);
   FileInfo fs = new FileInfo(filepath);
   log4net.Config.DOMConfigurator.ConfigureAndWatch(fs);
   Debug.WriteLine("Finished Log4net configuration");
}
protectedvoid Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
       Debug.WriteLine("In PreRequestHandlerExecute");
   if (!LogManager.GetLoggerRepository().Configured)
   {
           Debug.WriteLine("Log4net not configured, calling configure");
           ConfigureLog4Net();
   }
   Debug.WriteLine(Context.User.Identity.Name);
   log4net.MDC.Set("user",Context.User.Identity.Name);
}
Logging in ASP.NET
I've been trying to get decent logs on web application/web service. Its critical in cases where you dont have remote debugging access on the server.
I've been using Log4Net for over an year now and it's saved me more than once. It's the first time that I've tried to use it in a web scenario. There's just a couple of things to keep in mind:
Usually the worker process runs under the ASPNET account - this doesnt have rights to logon and doesnt have an associated console. Meaning console appender is out of the reckoning.
You could use FileAppender (the usual choice on single user applications), however, as multiple requests are served simultaneously, the logs will most probably quite unreadable.
The best choice is the ADONetAppender - you log everything in the DB and then use SQL to get a trace. Here we come across the next problem - how do you get the user information for each log entry?
The solution lies in using log4net's Mapped Diagnostic Context - MDC. Its basically a set of name value pairs that you can render using a pattern layout %X{name} in the log4net config file.
Here's the Log4Net.config file for reference
>Note the lines where the insert statement has an the username parameter and the additional param tag is added to the parameter list. You'll need to create a matching column definition in your table.
The next issue to be tackled is the log4net initialization and setting the username for the request.
The log4net system can be initialized the Application_onStart event and you can set the username in the PreRequestHandlerExecute event - this event is called just before the request is handed off for processing to the HttpModule and hence the best place to set the username. Relevant portions of Global.asax are shown below.
Â
protected
void Application_Start(Object sender, EventArgs e)
{
   ConfigureLog4Net();          Â
   Debug.WriteLine("In Application Start");
}
privatevoid ConfigureLog4Net()
{
   string filepath = Server.MapPath("log4net.config");
   Debug.WriteLine(filepath);
   FileInfo fs = new FileInfo(filepath);
   log4net.Config.DOMConfigurator.ConfigureAndWatch(fs);
   Debug.WriteLine("Finished Log4net configuration");
}
protectedvoid Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
       Debug.WriteLine("In PreRequestHandlerExecute");
   if (!LogManager.GetLoggerRepository().Configured)
   {
           Debug.WriteLine("Log4net not configured, calling configure");
           ConfigureLog4Net();
   }
   Debug.WriteLine(Context.User.Identity.Name);
   log4net.MDC.Set("user",Context.User.Identity.Name);
}
Friday, February 25, 2005
Part 6: Efficiently Representing Sets - Continued...
Great article. Gives some very valuable information on implementing sets with a finite universe.
It doesn't suit my requirements - I need to represent sets where the universal set might be infinite - like, say the set of strings.
The trouble starts with trying to implement the set complement operation - you can't obviously list an infinite set, so the trick is to represent it as a cofinite set. I haven't really read up on cofinite sets, but the layman definition goes as
'A set whose complement is finite'
Well that's it. So keep a flag with the data structure to indicate a set complement.
The ElementOf operation is trivial to implement. Subset is trickier and so's union, intersection and difference.
I just completed a bare bones implementation using a hashmap. All the tests are working (got 20 of them). You can find it here if you're interested.
Part 6: Efficiently Representing Sets - Continued...
It doesn't suit my requirements - I need to represent sets where the universal set might be infinite - like, say the set of strings.
The trouble starts with trying to implement the set complement operation - you can't obviously list an infinite set, so the trick is to represent it as a cofinite set. I haven't really read up on cofinite sets, but the layman definition goes as
'A set whose complement is finite'
Well that's it. So keep a flag with the data structure to indicate a set complement.
The ElementOf operation is trivial to implement. Subset is trickier and so's union, intersection and difference.
I just completed a bare bones implementation using a hashmap. All the tests are working (got 20 of them). You can find it here if you're interested.
Thursday, February 24, 2005
Visual C# Developer Center: Part 6: Efficiently Representing Sets
I've been looking on the net for some guidelines to implement the same - implementing a data structure is never easy so its better to be cautious to get it right. Just found this article which seems to fit the bill.
Visual C# Developer Center: Part 6: Efficiently Representing Sets
Hope this helps. Will post more on the article later.
CAPICOM - Accessing CryptoAPI from VB6
I've this need to calculate a file fingerprint in VB6. So the need to access CrptoAPI in vb6. Didnt want to do win32 calls from VB and thankfully MS has a COM layer over cryptoAPI called CAPICOM. Useful stuff...as the MSDN site says
"Summary: CAPICOM is a new security technology from Microsoft that allows Microsoft Visual Basic, Visual Basic Script, ASP, and C++ programmers to easily incorporate digital signing and encryption into their application. (5 printed pages)"
Okay, now you can calculate SHA1, SHA-256 and SHA512 using VB. Trouble was that you cannot use the Filesystem object as it doesnt read binary files.
Here's a small sample that does a SHA1 for binary files in VB6.
Const BUFFER_SIZE AsString= 4096
Dim sha As CAPICOM.HashedData
Set sha =New CAPICOM.HashedData
f =FreeFile
Open "somebinaryfile.xyz"For Binary As f
Dim totalbytes AsLong
totalbytes =LOF(f)
Dim currentPos AsLong
currentPos = 0
While currentPos + BUFFER_SIZE <= totalbytes
Get f, , buffer
currentPos = currentPos + BUFFER_SIZE
sha.Hash buffer
Wend
Dim chunk() AsByte
Dim chunkSize AsLong
chunkSize = totalbytes - currentPos
If (chunkSize > 0) Then
ReDim chunk(1 To chunkSize)
Get f, , chunk
sha.Hash chunk
EndIf
Close f
txtHash.Text = sha.Value
ASPAlliance.com : ASP and ASP.NET Tutorials : The LogonUser API
Finally found a way to allow ASPNET user access to the LogonUser api. Guess what, WinXP and above, no specific permissions are required! Cool.
Visual C# Developer Center: Part 6: Efficiently Representing Sets
I've been looking on the net for some guidelines to implement the same - implementing a data structure is never easy so its better to be cautious to get it right. Just found this article which seems to fit the bill.
Visual C# Developer Center: Part 6: Efficiently Representing Sets
Hope this helps. Will post more on the article later.
CAPICOM - Accessing CryptoAPI from VB6
I've this need to calculate a file fingerprint in VB6. So the need to access CrptoAPI in vb6. Didnt want to do win32 calls from VB and thankfully MS has a COM layer over cryptoAPI called CAPICOM. Useful stuff...as the MSDN site says
"Summary: CAPICOM is a new security technology from Microsoft that allows Microsoft Visual Basic, Visual Basic Script, ASP, and C++ programmers to easily incorporate digital signing and encryption into their application. (5 printed pages)"
Okay, now you can calculate SHA1, SHA-256 and SHA512 using VB. Trouble was that you cannot use the Filesystem object as it doesnt read binary files.
Here's a small sample that does a SHA1 for binary files in VB6.
Const BUFFER_SIZE AsString= 4096
Dim sha As CAPICOM.HashedData
Set sha =New CAPICOM.HashedData
f =FreeFile
Open "somebinaryfile.xyz"For Binary As f
Dim totalbytes AsLong
totalbytes =LOF(f)
Dim currentPos AsLong
currentPos = 0
While currentPos + BUFFER_SIZE <= totalbytes
Get f, , buffer
currentPos = currentPos + BUFFER_SIZE
sha.Hash buffer
Wend
Dim chunk() AsByte
Dim chunkSize AsLong
chunkSize = totalbytes - currentPos
If (chunkSize > 0) Then
ReDim chunk(1 To chunkSize)
Get f, , chunk
sha.Hash chunk
EndIf
Close f
txtHash.Text = sha.Value
ASPAlliance.com : ASP and ASP.NET Tutorials : The LogonUser API
Finally found a way to allow ASPNET user access to the LogonUser api. Guess what, WinXP and above, no specific permissions are required! Cool.
Wednesday, February 23, 2005
WSE2SP2 - Installing test certificates and the Mystery of Missing 'Other People' Tab
I was trying out WSE2.0 SP2 Hands on lab on security and hit this really strange problem.
I needed to install the sample certificates supplied with WSE, typically located in C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates.
As given in the Hands on lab manual, I installed the Server Certificate.pfx (server's private key) to the LocalMachine\Personal store and the Client Certificate.pfx (client's private key) to the CurrentUser\Personal store. The trouble started when I wanted to install the Server's public key to the Current User's\Other People store as directed. There wasn't an Other people Tab available in the mmc snap in. There is a workaround given in the Hands on lab manual -
Note: if you don't have an Other People store under Current User, open Internet Explorer, select Tools, Internet Options, Content, and press the Certificates button. You should see an Other People tab in the certificates dialog. You can import the certificate here through this interface or you can return to mmc and refresh the Current User tree and Other People should now show up.
Trouble was, it didnt work for me. I never got the tab in MMC as the note says and nor was I able to import the certificate to the correct location.
After a bit of googling, turns out that you can use the certmgr.exe's command line. It accepts a '-s' argument used to specify the store - and the value required for 'Other People' store is "AddressBook"
So the command becomes
certmgr -add "Server Public.cer" -s AddressBook
and voila - works like a charm. You can then refresh MMC console and see that the certificate has indeed been imported successfully.
WSE2SP2 - Installing test certificates and the Mystery of Missing 'Other People' Tab
I was trying out WSE2.0 SP2 Hands on lab on security and hit this really strange problem.
I needed to install the sample certificates supplied with WSE, typically located in C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates.
As given in the Hands on lab manual, I installed the Server Certificate.pfx (server's private key) to the LocalMachine\Personal store and the Client Certificate.pfx (client's private key) to the CurrentUser\Personal store. The trouble started when I wanted to install the Server's public key to the Current User's\Other People store as directed. There wasn't an Other people Tab available in the mmc snap in. There is a workaround given in the Hands on lab manual -
Note: if you don't have an Other People store under Current User, open Internet Explorer, select Tools, Internet Options, Content, and press the Certificates button. You should see an Other People tab in the certificates dialog. You can import the certificate here through this interface or you can return to mmc and refresh the Current User tree and Other People should now show up.
Trouble was, it didnt work for me. I never got the tab in MMC as the note says and nor was I able to import the certificate to the correct location.
After a bit of googling, turns out that you can use the certmgr.exe's command line. It accepts a '-s' argument used to specify the store - and the value required for 'Other People' store is "AddressBook"
So the command becomes
certmgr -add "Server Public.cer" -s AddressBook
and voila - works like a charm. You can then refresh MMC console and see that the certificate has indeed been imported successfully.
Thursday, February 17, 2005
Back to work....
Am back today after a long time. Been down with viral fever and doing nothing more than warming the bed with my backside :(. Really depressing!
Anyway am back today - but feeling quite tired.
This thing's thrown a spanner in the works in more than one thing - was supposed to go to the finale of the Aero India show here and couldn't make it - thanks to the viral! Was hoping to snap some nice pics there - esp. of the Surya Kirans' acrobatic show and post them on the blog...
Â
Back to work....
Am back today after a long time. Been down with viral fever and doing nothing more than warming the bed with my backside :(. Really depressing!
Anyway am back today - but feeling quite tired.
This thing's thrown a spanner in the works in more than one thing - was supposed to go to the finale of the Aero India show here and couldn't make it - thanks to the viral! Was hoping to snap some nice pics there - esp. of the Surya Kirans' acrobatic show and post them on the blog...
Â
Saturday, January 29, 2005
in XSLT - MSXML3, MSXML4
<?xml version="1.0"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " "> <!-- white space in XSL -->
]>
Sadly, this doesn't work with MSXML3 or MSXML4. The generated HTML has a space ' ' character rather than
After some googling, found the answer and a workaround on the xsl list
Editing XSLT
1. Support intellisense
2. Have a decent XPATH visualizer
3. Debugging (optional)
4. FREE :))
5. Editor with regexp support for search/replace (We all write XHTML. But if you need to start of with an existing HTML page, 99 times out of hundered, its not going to be XHTML)
I've been using Marrowsoft's Xselerator for the past week. The XSL editor is great, other than for a couple of problems
1. Long lines - tends to get the editor confused.
2. Search/replace - Search/Replace dialogs are hard to handle.
3. 15 day trial version - so I'm soon going to be left without an editor.
Plus points are
1. Good XPath visualizer
2. Support for stylesheet params
Sadly, VS.NET lacks intellisense for XSLT files. However, there's a workaround found on Fesersoft's site
It works quite well. Plus you get VS.NET's regexp search and replace. I'm using XSLDebugger for Xpath visualization. It's a free download, though no longer supported. I guess my troubles will start when I have xsl stylesheet parameters where I'll have to live with default parameters values.
in XSLT - MSXML3, MSXML4
<?xml version="1.0"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " "> <!-- white space in XSL -->
]>
Sadly, this doesn't work with MSXML3 or MSXML4. The generated HTML has a space ' ' character rather than
After some googling, found the answer and a workaround on the xsl list
Editing XSLT
1. Support intellisense
2. Have a decent XPATH visualizer
3. Debugging (optional)
4. FREE :))
5. Editor with regexp support for search/replace (We all write XHTML. But if you need to start of with an existing HTML page, 99 times out of hundered, its not going to be XHTML)
I've been using Marrowsoft's Xselerator for the past week. The XSL editor is great, other than for a couple of problems
1. Long lines - tends to get the editor confused.
2. Search/replace - Search/Replace dialogs are hard to handle.
3. 15 day trial version - so I'm soon going to be left without an editor.
Plus points are
1. Good XPath visualizer
2. Support for stylesheet params
Sadly, VS.NET lacks intellisense for XSLT files. However, there's a workaround found on Fesersoft's site
It works quite well. Plus you get VS.NET's regexp search and replace. I'm using XSLDebugger for Xpath visualization. It's a free download, though no longer supported. I guess my troubles will start when I have xsl stylesheet parameters where I'll have to live with default parameters values.

Performancing for Firefox is a full featured blog editor that sits right in your Firefox browser and lets you post to your blog easily. You can drag and drop formatted text from the page you happen to be browsing, and take notes as well as post to your blog.