How to get rid of empty attributes in XSLT output?

Some time ago, I faced an issue related to XSLT stylesheets. It was while we were developing quite complex XSLT template whose purpose was to convert one  XML  into completely different another one. During the implementation, it turned out that the output XML contains a lot unnecessary empty attributes, e.g.:

<field attr="" />

It was actually possible to get rid of them with <xsl:if> or <xsl:choose> instructions. However, it would require one conditional instruction per one <xsl:attribute…/> instruction. This would make the XSLT file too complex. So I needed other approach, that would act after the basic transform. And this is achievable by usage of

multi-pass XSLT transforms.

Let’s say that we have the following input XML:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<database>
<record firstName=\"john\" lastName=\"smith\">writer</record>
</database>

We would like to have the above XML converted by this XSLT transform:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes" exclude-result-prefixes="xs xsl"/>

    <xsl:template match="/database/record">
        <output>
            <xsl:attribute name="firstName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="lastName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="middleName">
                <xsl:value-of select="@middleName"/>
            </xsl:attribute>
            <xsl:attribute name="dob">
                <xsl:value-of select="@dob"/>
            </xsl:attribute>
            <xsl:text>recordFound</xsl:text>
        </output>
    </xsl:template>
</xsl:stylesheet>

The output looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<output firstName="john" lastName="john" middleName="" dob="">recordFound</output>

As you can see there are two empty attributes: middlename and dob. And this is where we can think about multi-pass transforms. We would like to have another transform applied on the results of the this XSLT.

Now, let’s consider what should be done to remove empty attributes. This is very to accomplish using identity transforms. This is simple variant of identity transform that removes empty attributes:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="node()|@*" >
        <xsl:copy>
             <xsl:apply-templates select="@*[.!='']" />
             <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

What is left is merging our both  XSLTs. The following code is the final XSLT transformation. We are using modes that are available XSLT 2.0. We store the result of our business operation in the variable $firstPassResult and we perform the removal of empty attributes on it.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">    
    <xsl:output indent="yes" exclude-result-prefixes="xs xsl"/>
    <xsl:variable name="firstPassResult">
        <xsl:apply-templates select="/" mode="firstPass" />
    </xsl:variable>

    <xsl:template match="/database/record" mode="firstPass">
        <output>
            <xsl:attribute name="firstName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="lastName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="middleName">
                <xsl:value-of select="@middleName"/>
            </xsl:attribute>
            <xsl:attribute name="dob">
                <xsl:value-of select="@dob"/>
            </xsl:attribute>
            <xsl:text>recordFound</xsl:text>
        </output>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates select="$firstPassResult"
            mode="secondPass" />
    </xsl:template>

    <xsl:template match="node()|@*" mode="secondPass">
        <xsl:copy>
             <xsl:apply-templates select="@*[.!='']" mode="secondPass"/>
             <xsl:apply-templates select="node()" mode="secondPass"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

A piece of very old assembly code

A couple of weeks ago I’ve been looking through some old backup CDs. To my surprise I have found some old source codes written more than 10 years ago. Of course, most of them were unfinished and ugly. Some of them turned out to be totally useless rubbish which made me feel embarrassed. But I have also found a couple of interesting things. For a moment I was amazed… I still cannot believe that I used to have so much patience to write code in pure assembler.
Here is a sample source code. It was supposed to be a 4KB intro.
The intro was written in 1999 (a twilight of MS-DOS era) in pure 80×86 assembly language. It should run on 32-bit Windows. The executable itself is 3529 bytes long and it is .COM executable file. Its name was supposed to be “Loser”, but I really do not remember why such a title was chosen. There were some nasty tricks used to make the code as short as possible… but who would care about them today? It doesn’t generate any sound effects or music, but trust me it was also possible in assembler! The visual effects were of course supposed to make an impression of a damaged TV-set (so please do not adjust your monitor:).
I have recorded and uploaded this animation on YouTube:

If you would like to compile source code of this “demo” you should use Borland’s Turbo Assembler and Turbo Linker.

Problem: MS Office Communicator 2005 fails to install

In my current company, I’m forced to use IM which is MS Office Communicator 2005. Accidentally (or perhaps my tortured subconsciousness told me do so;), I uninstalled this thing. Unfortunately, re-installation of this application wasn’t so easy as it seemed to be. When I ran installer it exited saying that Communicator could not be installed. That was really strange. After a couple of hours, I’ve finally realized that configuration of my workstation doesn’t really differ from the configuration of a typical WinXP machine, so the problem may be in some service pack or some security update. And that was it. A little creature named “Security Update KB974571” was the reason causing the failure (it was enough to uninstall it and reboot the computer). I wasted about 4 hours of my life which could be spent on coding.

Back

Apart from Java/C# coding, sometimes I do some small side projects such as webpages. I have never considered myself as a real webmaster. However, I have always admired well-designed websites.
Here is a project I did a couple weeks ago. It is a web page for a radiology laboratory. All the work (design & PHP code) is mine – I did not use any templates.

Radiologica-Rzeszow Website

NHibernate SchemaValidator reimplemented.

Some time ago a new utility class was introduced to NHibernate. It’s called SchemaValidator and it allows you to detect inconsistencies between mappings and database schema. Here you can find a short sample code showing how it works.

The class has got only one useful method called Validate(). It analyzes and compares database metadata with mappings. It can detect missing tables, missing columns, improper types in mappings, etc. It throws HibernateException immediately after it encounters such a problem. However, this is a serious disadvantage (at least for me), because I would like to know all issues related to my mappings and I don’t want to be surprised by a sudden NH exception telling me that I have forgotten one column in my .HBM file. That is why I have decided to reimplement this class so that it would not throw HibernateException, but rather return a list of possible issues.

The following code is based on original NHibernate.Tool.hbm2ddl.SchemaValidator class. Instead of throwing HibernateException it returns a list of strings. The code was tested with Sql Server 2005.

using System;
using System.Collections.Generic;
using System.Data.Common;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Dialect.Schema;
using NHibernate.Engine;
using NHibernate.Id;
using NHibernate.Mapping;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Util;

namespace MyApplication.Server.DAO.SchemaValidation 
{ 
    class SchemaValidator
    {
        private readonly Configuration configuration;
        private readonly IConnectionHelper connectionHelper;
        private readonly Dialect dialect;

        public SchemaValidator(Configuration cfg) : this(cfg, cfg.Properties) { }

        public SchemaValidator(Configuration cfg, IDictionary<string, string> connectionProperties)
        {
            configuration = cfg;
            dialect = Dialect.GetDialect(connectionProperties);
            IDictionary<string, string> props = new Dictionary<string, string>(dialect.DefaultProperties);
            foreach (var prop in connectionProperties)
            {
                props[prop.Key] = prop.Value;
            }
            connectionHelper = new ManagedProviderConnectionHelper(props);
        }

        public SchemaValidator(Configuration cfg, Settings settings)
        {
            configuration = cfg;
            dialect = settings.Dialect;
            connectionHelper = new SuppliedConnectionProviderConnectionHelper(settings.ConnectionProvider);
        }

        public IList<string> Validate()
        {
            try
            {
                DatabaseMetadata meta;
                try
                {
                    connectionHelper.Prepare();
                    DbConnection connection = connectionHelper.Connection;
                    meta = new DatabaseMetadata(connection, dialect, false);
                }
                catch (Exception sqle)
                {
                    throw;
                }

                return ValidateSchema(dialect, meta);
            }
            catch (Exception e)
            {
                throw;
            }
            finally
            {
                try
                {
                    connectionHelper.Release();
                }
                catch (Exception e)
                {
                	throw;
                }
            }
        }
        
        private IList<string> ValidateSchema(
            Dialect dialect, DatabaseMetadata databaseMetadata)
        {
            IList<string> problems = new List<string>();

            string defaultCatalog = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultCatalog, 
                configuration.Properties, null);
            string defaultSchema = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultSchema, 
                configuration.Properties, null);

            IMapping mapping = configuration.BuildMapping();
            ICollection<PersistentClass> list = configuration.ClassMappings;
            foreach (PersistentClass pc in list)
            {
                try
                {
                    var table = pc.Table;
                    if (table.IsPhysicalTable)
                    {
                        ITableMetadata tableInfo = databaseMetadata.GetTableMetadata(
                            table.Name,
                            table.Schema ?? defaultSchema,
                            table.Catalog ?? defaultCatalog,
                            table.IsQuoted);
                        if (tableInfo == null)
                            problems.Add(string.Format("Missing table: {0}", table.Name));
                        else
                            ValidateColumns(problems, table, dialect, mapping, tableInfo);
                    }
                }
                catch (HibernateException ex)
                {
                    problems.Add(ex.Message);
                }
            }

            var persistenceIdentifierGenerators = IterateGenerators(dialect);
            foreach (var generator in persistenceIdentifierGenerators)
            {
                string key = generator.GeneratorKey();
                if (!databaseMetadata.IsSequence(key) && !databaseMetadata.IsTable(key))
                {
                    problems.Add(string.Format("Missing sequence or table: {0}", key));
                }
            }
            return problems;
        }

        private IEnumerable<IPersistentIdentifierGenerator> IterateGenerators(Dialect dialect)
        {
            var generators = new Dictionary<string, IPersistentIdentifierGenerator>();
            string defaultCatalog = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultCatalog,
                configuration.Properties, null);
            string defaultSchema = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultSchema,
                configuration.Properties, null);

            foreach (var pc in configuration.ClassMappings)
            {
                if (!pc.IsInherited)
                {
                    var ig =
                        pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass)pc) as
                        IPersistentIdentifierGenerator;

                    if (ig != null)
                    {
                        generators[ig.GeneratorKey()] = ig;
                    }
                }
            }

            foreach (var collection in configuration.CollectionMappings)
            {
                if (collection.IsIdentified)
                {
                    var ig =
                        ((IdentifierCollection)collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema,
                                                                                                 null) as IPersistentIdentifierGenerator;

                    if (ig != null)
                    {
                        generators[ig.GeneratorKey()] = ig;
                    }
                }
            }

            return generators.Values;
        }


        private void ValidateColumns(
            IList<string> problems, 
            Table table,
            Dialect dialect,
            IMapping mapping,
            ITableMetadata tableInfo)
        {
            IEnumerable<Column> iter = table.ColumnIterator;
            foreach (Column column in iter)
            {
                IColumnMetadata columnInfo = tableInfo.GetColumnMetadata(column.Name);

                if (columnInfo == null)
                {
                    problems.Add(string.Format("Missing column: {0} in {1}", column.Name,
                        NHibernate.Mapping.Table.Qualify(tableInfo.Catalog, tableInfo.Schema, tableInfo.Name)));
                }
                else
                {
                    bool typesMatch = column.GetSqlType(dialect, mapping).ToLower().StartsWith(columnInfo.TypeName.ToLower());
                    if (!typesMatch)
                    {
                        problems.Add(string.Format("Wrong column type in {0} for column {1}. Found: {2}, Expected {3}",
                                                                   NHibernate.Mapping.Table.Qualify(tableInfo.Catalog, tableInfo.Schema, tableInfo.Name),
                                                                   column.Name, columnInfo.TypeName.ToLower(),
                                                                   column.GetSqlType(dialect, mapping)));
                    }
                }
            }
        }

    }
}

Visual Studio Design Mode – another approach.

Some time ago I published here a piece of code that detects the design mode in Visual Studio Designer. The code worked great (as long as you use only MS Visual Studio). However, after some time, with our project getting more and more complex, the solution turned out to be problematic, as its usage is limited only to classes that extend the BaseDesignModeUserControl. If, for instance, you need to extend System.ComponentModel.Component, then you have to duplicate the code (and the rhetorical question is who likes to duplicate the code?)
So, it turns out that we should forget about “the-base-class” approach and use an extension method instead:

    public static class ExtensionMethods
    {
        private static bool? isDesignMode = null;

        [DebuggerStepThrough]
        public static bool IsDesignMode(this object obj)
        {
            if (!isDesignMode.HasValue)
                isDesignMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName.IndexOf("devenv") != -1);
            return isDesignMode.Value;
        }
    }

It seems that this piece of code may be called anywhere and I hope that this is the final solution of the problem.

NHibernate IUserType for fake database booleans

In the db schema I’m currently working on, boolean values are represented by columns whose type is tinyint nullable (it’s SQL Server 2005). If such a value equals 1, then it is supposed to be True, 0 means False and if it is null then it is False, too.
This time I would like to show how to use NHibernate IUserType interface to enable automatic conversion from a database field to System.Boolean value
NHibernate.UserTypes.IUserType is a very useful interface when you are to handle some strange db schemas in your data access layer. As you can guess, the thing that we need is a class that implements this interface. You can see it below. The most important methods are NullSafeGet(…) and NullSafeSet(…) as they are responsible for conversion ‘logic’.

namespace MyNamespace
{
  public class ByteAsBool : IUserType
  {
      #region IUserType Members

      public object Assemble(object cached, object owner)
      {
          return cached;
      }

      public object DeepCopy(object value)
      {
          return value;
      }

      public object Disassemble(object value)
      {
          return value;
      }

      public int GetHashCode(object x)
      {
          if (x == null)
              return 0;
          return x.GetHashCode();
      }
      public bool IsMutable
      {
         get { return false; }
      }

      // represents conversion on load-from-db operations:
      public object NullSafeGet(System.Data.IDataReader rs, 
             string[] names, object owner)
      {
          var obj = NHibernateUtil.String.
                 NullSafeGet(rs, names[0]);
          if (obj == null)
              return false;
           byte b = 0;
          try
          {
              if (obj is string)
                  b = byte.Parse(obj as string);
              else
                  b = (byte)obj;
          }
          catch (Exception)
          {
              return false;
          }
          return b == 1;
      }

      // represents conversion on save-to-db operations:
      public void NullSafeSet(System.Data.IDbCommand cmd, 
             object value, int index)
      {
          if (value == null)
          {
              ((IDataParameter)cmd.Parameters[index]).Value = 
                    DBNull.Value;
          }
          else
          {
              var boolValue = (bool)value;
              ((IDataParameter)cmd.Parameters[index]).Value = 
                    boolValue ? (byte)1 : (byte)0;
          }
      }
      public object Replace(object original, object target, 
             object owner)
      {
          return original;
      }

      public Type ReturnedType
      {
          get { return typeof(bool); }
      }

      public NHibernate.SqlTypes.SqlType[] SqlTypes
      {
          get { return new[] { SqlTypeFactory.Byte }; }
      }
      #endregion

      bool IUserType.Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
  }
}

The class ByteAsBool can be now used in NHibernate mappings in the following way:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="SomeAssembly" namespace="MyNamespace.Types">
  <class name="SomeClass" table="Some_Table" >
  <!-- ... -->
    <property name="active" 
        column="ACTIVE" 
        type="MyNamespace.ByteAsBool, SomeAssembly" access="field" />
  <!-- ... -->
  </class>
</hibernate-mapping>

The mapped class is very simple and looks very nice, as there are no ugly bool? types, just simple System.Boolean:

  public class SomeClass : BaseEntity
  {
     protected bool active;
     // ...
  }

“SqlDateTime overflow…” exception horror.

Currently, I am involved in developing a client-server multi-layered application that uses NHibernate library as its data access layer. It is designed to support some old legacy database schema. Database is SQL Server 2005. All tables in schema have got two fields which are called CREATE_TIME and UPDATE_TIME. They are both of type datetime nullable in DB schema (btw. our schema contains about 200 tables, which is, in my opinion, A LOT). Their purpose was to describe the time when a certain record was created and when it was updated.

To cope with these fields I created a base class for all mapped entities in our project – a class called BaseEntity:

    public abstract class BaseEntity
    {
        protected int id; // always mapped to primary key
        protected DateTime created;
        protected DateTime updated;

        public BaseEntity() { }

        public virtual int Id
        {
            get { return id; }
            set { this.id = value; }
        }
        public virtual DateTime Created
        {
            set { created = value; }
            get { return created; }
        }
        public virtual DateTime Updated
        {
            set { updated = value; }
            get { return updated; }
        }
    }

The three members of this class were mapped in every NHibernate mapping file (the code below shows a mapping for a Foo class whose base class is, of course, BaseEntity):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Some.Assembly" namespace="ProjectNamespace.Types">
  <class name="Foo" table="Foo_table">
    
  <id name="Id" type="System.Int32" column="ID_FOO_TABLE" unsaved-value="0">
    <generator class="native" />
  </id>

   <!-- BaseEntity -->
  <property name="created" column="CREATE_TIME" access="field" not-null="false" type="System.DateTime"  insert="true" update="true"/>
  <property name="updated" column="UPDATE_TIME" access="field" not-null="false" type="System.DateTime"  insert="true" update="true"/>
  
  <!-- other properties here... -->
  </class>
</hibernate-mapping>

Everything seemed to work just fine until we populated our database with some real data taken from a production environment. I need to mention here that the tables were very very big (a lot of columns and records – besides the schema is an excellent example of a bad design).
Suddenly, it turned out during tests that a strange exception was caught when users tried to save certain entities. The exception looked like this:
SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM….
However, this exception didn’t appear too often, which made it difficult to debug. It happened only sometimes on NHibernate operations such us session.Merge() or session.Update().
We spent a lot of time trying to figure out what was going on. NHibernate traces were giving a clue that something is wrong with created/updated fields – Nhibernate was trying to persist ‘0001-01-01 00:00:00’ values, which are incorrect values for SQL Server datetime column type.

The explanation is really simple. The database we were given contained a few records whose CREATE_TIME and UPDATE_TIME fields were null. We actually did not care about them – there were more important things to do than storing last modification time in every entity. During merge or update operation NHibernate converted these fields into DateTime.MinValue (which is actually ‘0001-01-01 00:00:00’) and such a value causes SqlDateTime overflow exception when entity is being saved. So the solution is also very simple. It is enough to change created/updated members type to Nullable<DateTime>:

    public abstract class BaseEntity
    {
        // ...
        protected DateTime? created;
        protected DateTime? updated;
        // ...
     }

DataSourceUpdateMode property.

Almost every beginning programmer in MS .NET seems to avoid going deeper into data bindings stuff. Although they are very, very helpful and can reduce the amount of time spent on development, most of the beginners prefer manual initialization of their controls, e.g. by setting EditValue or Text properties. Then, when they need to validate their controls’ data, they write thousands of EditValueChanged handlers.
However, the simplest solution can be found in Binding definition which provides DataSourceUpdateMode property. When it is set to OnPropertyChanged value, it strictly binds the property with the value in the control. Also, DataSourceUpdateMode can be set in Binding constructor.

SQL Server 2005 issue.

A few days ago I was forced to install and use SQL Server database on my system. A few days later I had to install MS VS .NET 2008. After that, it turned out that the standard utility SQL Server Configuration Manager does not seem to work correctly. It shows a message box that contains the following error:
Cannot connect to WMI provider. You do not have permission or the server is unreachable. Note that you can only manage SQL Server 2005 servers with SQL Server Configuration Manager.
Nie można znaleźć określonego modułu. [0x8007007e]

Unfortunately, I could not find any working solution of this problem (perhaps it is so because my knowledge of Microsoft’s database is less than miserable ) Some pages suggested running Mof-compiler program with *.mof file from SQL Server installation directory but it does not work in my case.

EDIT: After some time I figured out what should done to solve this problem. It is simple. It just requires copying framedyn.dll file from folder: “C:\WINDOWS\system32\wbem” to folder: “C:\WINDOWS\system32”.