Coding conventions and non-standard standards

Coding conventions and non-standard standards

Coding conventions and style is probably programmers’ most fiercely-contested topic, and also the least-important. At the end of the day, as long as the compiler can read your code, and you can read your code, you’re fine. But consistency is good, so many organisations have rules on what their code should look like. These rules answer questions like, do braces start on their own line? Do we prefix private class members? Do we use CamelCase or underscores to separate words? And other such matters of great importance.

Deciding on these rules can be quite a nightmare, as everyone has their own personal preferences which they believe are superior. A lot of arguing can ensue. When deciding on what coding conventions to use, good standards can be found with:

  • The language’s authors
  • Application frameworks and libraries that you use a lot
  • Respectable groups like the GNU project or Mozilla

Bad conventions come from:

  • Other languages
  • Long-standing tradition and sacred cows
  • Other vendors’ implementations
  • Non-programmers

My best recommendation is simply to go with the flow and use whatever style is recommended by your language’s authors and tools. If you’re writing a program in C, use K&R. If you’re using Java, use Sun’s Java conventions. If you’re writing C++ with Qt or some other framework use their standards, otherwise use the STL’s. For Microsoft T-SQL use the style generated by their SQL Server client tools. If you’re writing .NET code it should look the same as the Base Class Library. There is nothing wrong with these standards, and any deviations will simply require extra work to implement, like changing defaults or modifying generated code to match your company’s non-standard standards.

Implementing access control in a tiered application

Implementing access control in a tiered application

Recently I have been working on a reasonably-large ERP system that supports around 2,000 users. The system has approximately forty access control groups to which individual users can belong. Each of these groups grants or restricts access to parts of the system. For example, a user may be allowed to edit the price of a product if they are in the SalesManagers group. If they are in the InventoryManagers group, they can edit the number of items in stock. If they are in the Admins group they can do everything.

public class User{        // A list of groups the user belongs to.        public List<string> MembershipGroups { get; };         // ... etc}

To handle all these access groups and their associated rules, a form page’s load method contained several screenfulls of business logic to determine which elements should be editable by the user and which should not.

Here’s a simple example of what it might look like on an EditProduct page:

public class EditProductPage : Page{        // Form elements.        private TextBox ProductName;        private TextBox Price;        private TextBox NumberInStock;         public void InitializeForm()        {                if (CurrentUser.MembershipGroups.Contains("Admins"))                {                        // Admins can change anything.                        ProductName.Enabled = true;                        Price.Enabled = true;                        NumberInStock.Enabled = true;                }                else if (CurrentUser.MembershipGroups.Contains("SalesManagers"))                {                        // SalesManagers can change the product's price.                        ProductName.Enabled = false;                        Price.Enabled = true;                        NumberInStock.Enabled = false;                }                else if (CurrentUser.MembershipGroups.Contains("InventoryManagers"))                {                        // InventoryManagers can change the inventory levels.                        ProductName.Enabled = false;                        Price.Enabled = false;                        NumberInStock.Enabled = true;                }                else                {                        // Regular users can't do anything.                        ProductName.Enabled = false;                        Price.Enabled = false;                        NumberInStock.Enabled = false;                }                 // ... other complex business logic        }}

Now this is all good and well, but what happens if someone is a member of SalesManagers and InventoryManagers? Or if we add rules related to editing certain types of products? What happens if we need to make another form? This code will grow exponentially and start to spaghetti out of control.

I believe there are two fundamental problems with this design. Firstly, it is not clear what the different access groups mean in the context of the form. For example, if you’re a member of the InventoryManagers group, which fields should be editable and which should be locked? These rules are probably defined clearly in a requirements document somewhere, but are difficult to understand from reading the source code.

The second problem is that these rules are implemented at each point they are consumed, i.e. in the presentation layer. Each form is free to access and interpret what each group means. This logic clearly don’t belong here: a form page should only know how to hide and show elements! On the other hand, it seems this responsibility doesn’t lies exclusively with the business layer either, as it relates to form-specific elements. So where should it go?

In a well-designed application, the relationship between group membership and access privileges would not be exposed to the UI. Instead, we should define a list of easily-understood permission flags that have direct meaning to consumers of our model. Each of these flags will explicitly define what a user can and cannot do. They must be as simple to understand as possible.

public class AccessPermissions{        // Correct: these flags can be applied directly to a form.        public bool CanEditName { get; };        public bool CanEditPrice { get; };        public bool CanEditNumberInStock { get; };         // Incorrect: this flag is too vague.        bool IsAdmin { get; };}

We can then add these permissions to our User class:

public class User{        // A list of groups the user belongs to.        public List<string> MembershipGroups { get; };         // The user's access permissions.        public AccessPermissions Permissions { get; };         // ... etc}

Setting these flags may involve complex and conditional business logic, which is now removed from the presentation layer. These simplified flags can then be directly used by the form’s Supervising Controller:

public class ProductEditFormController : ISupervisingController         // The passive view for the current form.        private IEditFormView Form;         // Set up form state.        public void InitializeForm()        {                AccessPermissions permissions = CurrentUser.Permissions;                 if (permissions.CanEditName)                        Form.ProductName.Editable = true;                 if (permissions.CanEditPrice)                        Form.Price.Editable = true;                 if (permissions.CanEditNumberInStock)                        Form.NumberInStock.Editable = true;                 // ... etc        }}

Privileges should be separated amongst multiple classes, specific to different areas of functionality. For example, you might provide a UserPermissions class for a user management form:

// Permissions related to user management.public class UserPermissions{        bool CanEditName;        bool CanEditMembershipGroups;        bool CanDeleteUser;}

By removing access level-related logic from the point of consumption and declaring them as explicit, immediately-usable flags, we can make it much easier for developers to consistently apply access control. Removing potentially complex business logic from the presentation layer cuts down on code duplication (and bugs). The overall quality of the system improves.

A new website on a new domain

A new website on a new domain

I have just finished migrating this website from Blogspot to my own domain and web server. I am now able to post code, host files and basically do whatever I like!

I am using WordPress, a powerful open-source blogging engine, and I have modified the look and feel to be as clean and simple as possible. I hope you like it.

Adding GMail’s Archive button to Microsoft Outlook 2007

Recently, I have been using GMail as my primary e-mail client. It’s simple to use, lightweight, fast and powerful. One feature I particularly like is the Archive button, which lets me clear messages out of my inbox with a single click. Instead of letting e-mails clutter up my inbox just in case I need them again, I can archive them as soon as I’ve read them. Fewer items in my inbox makes it easier to focus and prioritize tasks, which in turn makes me more productive.

In the high-pressure environment at work, where I frequently receive up to a hundred or so e-mails a day, everything I can do to make my life easier helps. Here is how I added an Archive button to Microsoft Outlook:

  1. Make a new folder in Outlook called Archive.
  2. Open the macro editor under Tools > Macros > Visual Basic Editor.
  3. Open ThisOutlookSession under Project1 in the Project Explorer window at the left side of the screen.
  4. Paste the following code:
    Option Explicit
    Public Sub ArchiveSelectedItems()
        MoveSelectedItemsToFolder "Archive"
    End Sub
    Private Sub MoveSelectedItemsToFolder(FolderName As String)
        On Error GoTo ErrorHandler
        Dim Namespace As Outlook.Namespace
        Set Namespace = Application.GetNamespace("MAPI")
        Dim Inbox As Outlook.MAPIFolder
        Set Inbox = Namespace.GetDefaultFolder(olFolderInbox)
        Dim Folder As Outlook.MAPIFolder
        Set Folder = Inbox.Folders(FolderName)
        If Folder Is Nothing Then
            MsgBox "The '" & FolderName & "' folder doesn't exist!", _
                vbOKOnly + vbExclamation, "Invalid Folder"
        End If
        Dim Item As Object
        For Each Item In Application.ActiveExplorer.Selection
            If Item.UnRead Then Item.UnRead = False
            Item.Move Folder
        Next
        Exit Sub
    ErrorHandler:
        MsgBox Error(Err)
    End Sub
  5. Save and close the editor.

Now the archive macro has been created. Let’s add a button that will trigger it:

  1. Click on View > Toolbars > Customize, and select the Commands tab.
  2. Scroll down to the Macros category.
  3. Drag the Project1.ThisOutlookSession.ArchiveSelected command to a toolbar.
  4. Right-click on your new button, and rename it to Archive Selected. Set it to display Text Only.
  5. Click Close.

All done!

If it ain’t broke, don’t fix it

If it ain’t broke, don’t fix it

Resisting the urge to rewrite other peoples’ code is one of the hardest challenges an inexperienced developer may encounter when working in a team environment. It is perfectly understandable; after all it is much easier to write code than to understand it. Not to mention the desire to fix and improve on any genuine flaws that may exist.

Recently, I have been involved in a number of projects that require extending and changing existing applications, developed by other people. Many times I have been tempted to rewrite functions that look buggy or inefficient. Much of the code is simply downright awful. However, as bad as it may seem to me, it works and it is trusted. I cannot touch it. In the increasingly marshaled enterprise environment I work in, changes that have not been agreed with the customer simply cannot be made. System requirements have formed a project contract which I cannot step outside of.

Existing code has been tested. Other people understand it. It is known to work. Making unnecessary changes risks introducing new bugs. Introducing a new bug would be a big step backwards.

Ultimately, because you’re not adding anything new, any unnecessary changes will be a complete waste of time, in the eyes of your customer. And if you’re being paid for your work, a waste of time equates to a waste of money.

No matter how bad the code, no matter how brain-damaged the design, do not change anything unless you absolutely have to. Log issues. Discuss them. But otherwise, if it ain’t broke, don’t fix it!

Generating documentation with Doxygen

Generating documentation with Doxygen

A few days ago, I had my first experience with Doxygen, an open-source documentation generator similar to Javadoc.

After a few hours of documenting my code to a satisfactory level, I had a very professional-looking set of HTML documentation. At work the next day, I used Doxygen to generate code for a Visual C# class library, which had been documented with XML comments.

Doxygen supports most C-derived programming languages including C, C++, Java and C#. It also allows you to define custom pages and sections; you are not limited to code documentation.

Documenting a method is very simple:

/// @brief Calculate the sum of two values.////// Adds the two values together and returns their sum.////// @param[in] aa The first value./// @param[in] bb The second value.////// @return The sum of both values.////// @note This method is deprecated!////// @see operator+()int add(int aa, int bb);

A full list of Doxygen commands is available.

Short-circuit evaluation in VB.NET

Short-circuit evaluation in VB.NET

When evaluating an and statement, there is no point testing the right hand side if the left is false.

If (False And SomeOtherCondition) Then        ' ...End If

In this example, there is no point evaluating SomeOtherCondition, because its value has no effect on the overall result of the and statement (false).

If (True Or SomeOtherCondition) Then        ' ...End If

Similiarly, in this example, there is no point evaluating SomeOtherCondition because it will have no effect on the overall result of the or statement. Breaking out of such a statement early is known as short-circuit evaluation, and is performed automatically in many programming languages.

Unfortunately, the And and Or operators VB and VB.NET perform no such optimization, and always evaluate both conditions, regardless of their values.

To alleviate this problem, VB.NET introduces a couple of handy new operators, AndAlso and OrElse:

If (True OrElse SomeOtherCondition) Then        ' SomeOtherCondition will never be evaluatedEnd IfIf (False AndAlso SomeOtherCondition) Then        ' SomeOtherCondition will never be evaluatedEnd If

These two simple additions provide VB.NET programmers with a convenience that has been taken for granted with other languages for years, and allows them to reduce the number of VB/VB.NET’s syntactically bulky flow control statements.

Windows Integrated Authentication in ScrewTurn Wiki

Windows Integrated Authentication in ScrewTurn Wiki

ScrewTurn Wiki is a simple, open source wiki engine that reproduces much of the functionality found in Mediawiki. ScrewTurn Wiki is powered by ASP.NET 2 and Microsoft SQL Server, which makes it ideal for Windows-centric corporate environments. Unfortunately, ScrewTurn Wiki has no out-of-the box support for Windows Integrated Authentication (and, according to the developer, never will).

Windows Integrated Authentication allows users’ credentials to be automatically passed to IIS. This allows the application (if it supports it) to use Windows login details – i.e., the same user name across an entire domain. The user is automatically and seamlessly logged in to the application – a huge benefit over having to remember multiple user names and passwords.

I have created a simple Windows Integrated Authentication implementation for ScrewTurn Wiki, similar to that used by Community Server (another ASP.NET/SQL Server-based collaboration tool). Note that ScrewTurn Wiki’s Plugin Framework does not cater for extra functionality at this level (yet). When a new session is spawned on the web server, the application searches for an account matching the user’s login name. If none is found, a new account is created automatically. Events are logged via the standard ScrewTurn Wiki event log.

Replace Session_Start in ScrewTurn Wiki’s Global.asax with the following:

void Session_Start(object sender, EventArgs e){    // Code that runs when a new session is started    ScrewTurn.Wiki.Users.OnlineUsers++;    ScrewTurn.Wiki.SessionFacade.Breadcrumbs = new ScrewTurn.Wiki.BreadcrumbsManager();    // Get identity name from web server.    string identityName = System.Web.HttpContext.Current.User.Identity.Name;    if (identityName == null || identityName.Length < 1)        throw new System.ApplicationException("Could not get current Windows user name." +            "Ensure Integrated Windows Authentication is enabled.");    string username;    // Strip domain prefix (e.g. "\COMPANY.NETDoeJ").    int domainDelimOffset = identityName.IndexOf("\");    if (domainDelimOffset > 0)        username = identityName.Substring(domainDelimOffset + 1);    else        username = identityName;    if (username.Length < 1)        throw new System.ApplicationException("Username " + identityName +            " is empty after domain stripped.");    // Locate user.    ScrewTurn.Wiki.PluginFramework.UserInfo user =            ScrewTurn.Wiki.Users.Instance.Find(username);    if (user == null)    {        // User not found, add a new one.        if (!ScrewTurn.Wiki.Users.Instance.AddUser(username, string.Empty,                string.Empty, true, false, null))            throw new System.ApplicationException("Could not add user ""                + username + "".");            // Get freshly-added user.            user = ScrewTurn.Wiki.Users.Instance.Find(username);            if (user == null)                throw new System.ApplicationException("Could not find user ""                    + username + "".");    }    // Set up session.    ScrewTurn.Wiki.SessionFacade.LoginKey =        ScrewTurn.Wiki.Tools.ComputeSecuredUsernameHash(user.Username);    ScrewTurn.Wiki.SessionFacade.Username = user.Username;    ScrewTurn.Wiki.SessionFacade.Admin = user.Admin;    // Log event.    ScrewTurn.Wiki.Log.LogEntry("User " +        ScrewTurn.Wiki.SessionFacade.Username +        " logged in through Windows Integrated Authentication",        ScrewTurn.Wiki.EntryType.General, "SYSTEM");}

For more information about Windows Integrated Authentication and ScrewTurn Wiki (including comments on this implementation), see this thread at the ScrewTurn Wiki forum.

Generating a Makefile from Xcode

Generating a Makefile from Xcode

Almost all open source software projects I have encountered rely on GNU Make as a build tool. Make is a tool available on many platforms (most notably Linux and UNIX) that manages the compilation and installation of software programs. A Makefile defines the location of source files and steps required to compile and link targets to create the executable program file.

Importing existing Make-based software projects into Apple’s Xcode IDE is relatively easy; source files can be dragged and dropped into a Project, and Xcode will link and compile them automatically.

Unfortunately, porting Xcode Projects to other platforms is not so simple. While Xcode can integrate a Makefile as an External Build Target, it cannot export or create one. This functionality is granted with the use of a third party tool called PBTOMAKE. Note that Xcode was originally called Project Builder.

PBTOMAKE is a command line utility which creates a simple Makefile from an Xcode Project file. Integrating PBTOMAKE into an Xcode Project allows us to create a Makefile on the fly as part of the build process. Here’s how:

  1. Download and install PBTOMAKE, so that the ‘pbtomake’ command is available to the current user.
  2. In Xcode, ensure all Project file reference paths are specified Relative to the Project.
  3. Right click on the relevant build Target, and add a New Run Script Build Phase. Enter the following command:

    pbtomake -i $PROJECT_NAME.xcodeproj -o path/to/Makefile

  4. Build your Project.

PBTOMAKE’s default compiler is GCC. Use the -cc option to change compiler, and -bin_dir to specify an alternate output directory.

An example cross-platform command-line application written in C++ which links against OpenSSL‘s libraries would use the following Run Script Build Phase to generate a Makefile from within Xcode:

pbtomake -i $PROJECT_NAME.xcodeproj -o path/to/Makefile -link_opt "-lssl -lcrypto" -no_framework -cc g++ -bin_dir path/to/bin

This method allows us to create and maintain C and C++ projects in Xcode, while providing excellent cross-platform portability via GNU Make.