Saturday, May 23, 2009

We have huge amounts of memory and concurrent programming is an exception

It's quite amazing to hear Anders advocating bloat in a world where most of the world still has bad internet connections and hate large downloads, mobile phones prefer 1MB applications over 10MB apps, where RAM can be a bottleneck, where battery life is always too short and where many large organizations struggle with bad performance.

I recently had the chance to see the standard configuration for virtual servers in a large organization. In order to improve network traffic, the standard network adapter is limited to 10Mbit/sec.

Add-in Express 2009 for Office and VCL

Visual designers and components of Add-in Express in combination with a perfect Delphi compiler provide you with the best platform for Office development. Add-in Express makes it equally easy to build toolbars, menus and sub-menus for Microsoft Office 2000 – 2003, customize the Office 2007 Ribbon using the Office 2007 Ribbon designer as well as to create custom static and contextual ribbon tabs, task panes, navigation pane and reading pane, Office Menu and Quick Access Toolbar.

Add-in Express for Delphi implements all interfaces and techniques required by supported technologies, you write functional code only. Another key benefit of Add-in Express is version neutrality – you write the plug-in code once and get a secure Microsoft Office extension that works for all applications and versions.

Plug-in types: COM add-ins, smart tags, real-time data servers
Office versions: Office 2000, 2002, 2003, 2007
Applications: Outlook, Word, Excel, PowerPoint, Access, Publisher, Project, MapPoint, InfoPath, Visio
IDEs: Delphi 5, 6, 7, 2006, 2007, 2009
Windows Vista ready

Wednesday, May 20, 2009

DataSnap the fastest multi-tier development

The new approach was introduced with RAD Studio 2009 (including Delphi & C++Builder) and was based on a NON-COM/DCOM approach. The new approach used JSON (JavaScript Object Notation) http://www.json.org/ housed on a TCP/IP message layer wrapped in the DataSnap technology.

What makes this approach great is that it is simple to implement:


  1. Create a DataSnap Server

    1. Create a VCL Form application

    2. Add the 3 DataSnap Server components

    3. Connect the Server components

    4. Add a ServerModule (this is where the developer exposes business logic and data from the backend storage)

    5. Connect the ServerModule to the Server components for the wire protocol and transfer of information

  2. Create a client (generic client)

    1. Create a VCL form application, Web application, ASP.NET (Prism) application

    2. Drop a TSQLConnection component

    3. Set the connection properties (3 in all)

    4. Right-mouse click on the TSQLConnection and generate Client Proxy

    5. Use Proxy to connect to the remote server and call logic at will

    6. Expose information on client

  3. Done

This is a nine minute demo with explanations, 5 without… at best and IMO, it is the fastest multi-tier approach out there compared to JEE, CORBA, RMI, COM/DCOM, or plain old RPC.


This approach isolates the database layer to the middle tier; there is no reason for the client to know that you are even connecting to a backend database. The exposure of business logic is as simple as writing public functions and the building of the actual server is a form and three (3) components. There are no 7 helper files like with Java’s EJB, or 3 helper files with CORBA, or IDL/RIDL with COM/DCOM, and you surely don’t have to define each side of the communication like with RPC.


So there must be a downside to the technology… there always is… isn’t there? As far as I can see today, there are no advert downsides. There is no royalty to use it, it is simple to understand, it helps to reduce database connections, it very fast, it scales well, and it uses open protocols. What is not to like?


Now could there be more features added or could it even become simpler to use in future releases of the feature/functionality? Sure, but then again, if you are a diehard Delphi/C++Builder developer you already know that we don’t rest on the past implementation we are always trying to push the technology to the next level.


This leads to the next item; I’m going to be publishing the roadmap for RAD Studio very soon and also an audio recording of the presentation. There will be more details about where the technology of DataSnap is going in the future and should give every Delphi/C++Builder/Prism developer some great piece of mind to see the investment being put into our beloved product with Embarcadero!

HelpNDoc let's you generate help files in various formats from a single source

  • CHM: Compiled Microsoft Windows HTML Help;

  • HTML: Complete web help optimized for easy online browsing and search engines;

  • DOC: Complete help documentation as a Microsoft Word document or RTF file;

  • PDF: Standard Adobe portable document format documentation for easy sharing and printing;

  • HelpNDoc includes a complete WYSIWYG editor with advanced formatting and layout capabilities.



    • Advanced paragraph formatting: alignment, indentation, line spacing, tabs and text flow;

    • Advanced font customization: character spacing, offset, scaling, superscripts and subscripts;

    • Extensive image format support: JPG, PNG, GIF, BMP, ICO, EMF, WMF;

    • Advanced table support: cell padding and spacing, alignment, customizable borders and fills;

    • Complete live spell checker with custom dictionaries and automatic corrections;

  • Table of content editor with instant reorganization and customization;

  • Extremely fast topic creation, deletion and customization;

  • Advanced keywords editor: easily attach keywords with topics, categorize and manage them;

  • Automatic Topic ID and Context number generation;

  • Writing and integrating help files has never been easier thanks to HelpNDoc's advanced functionalities.



    • Live external document import: the document will be imported when the help file is generated;

    • Project or user defined variables: the variable will be replaced when the help file is generated;

    • Project-wide efficient find and replace tool: find a sentence and replace it by a variable;

    • Multiple language code generation: C/C++ headers, Delphi units, Visual Basic and Fortran modules to ease help file interaction;

    • Extensive command line support to pilot HelpNDoc from an external application, an automated processing or a batch script;

    Delphi Prism Web Services and SOAP Security

    In this article, I'll demonstrate how to use SOAP Headers as security technique for ASP.NET Web Service projects using Delphi Prism (extending the example from last month by adding a security layer to it).


    SOAP Headers

    In order to work with SOAP Headers in an ASP.NET Web Service, we have to add System.Web.Services.Protocols to the uses clause, and define a new class derived from the SoapHeader class found in the aforementioned namespace.
    The new class can be called anything, so I've decided to call it TCredentials (I know that in the .NET Framework you're not supposed to prefix everything with a "T", but since I'm a proud Delphi developer, I always use a T prefix for my types).


    It must be a public class, since we need to export it so any client importing our ASP.NET web service can also know about it.
    Adding a Username and Password field to the TCredentials class, this could lead to the following definition.



    type
    TCredentials = public class(System.Web.Services.Protocols.SoapHeader)
    public
    Username: String;
    Password: String;
    end;


    With this class definition in mind, we can add a public field (for example called token) to the public class Service, as well as a private method (for example called CheckCredentials) to check if the credentials have been received and contain the correct username/password information.
    This leads to the following modification of the Service class:



    Service = public class(System.Web.Services.WebService)
    public
    var

    token: TCredentials;

    private
    method
    CheckCredentials: Boolean;


    In order to specify that the token has to be used for certain web method (from the original set), we have to add the attribute SoapHeader to the web method, specifying the token as well as the direction in which the token is assigned (in our case only on input, so only the web service client will be writing information in the token, and the Service web service "engine" can check the token for valid credentials by looking at its value).


    Using the example from last month, we can modify some of the web methods as follows:



    public
    [WebMethod(EnableSession := true)]
    [SoapHeader('token', Direction := SoapHeaderDirection.&In)]
    method Remember(const Name,Value: String);

    [WebMethod(EnableSession := true)]
    [SoapHeader('token', Direction := SoapHeaderDirection.&In)]
    method Recall(const Name: String): String;

    [WebMethod(EnableSession := true)]
    method Forget(const Name: String);

    [WebMethod(EnableSession := true)]
    method Amnesia; // forget all
    end;


    Note that I only added the SoapHeader attribute to the Remember and Recall web methods, and not to the Forget or Amnesia methods.
    In other words: you are free to forget, but in order to remember or recall something, you need security clearance.


    Inside that Remember and Recall methods, we will have to call the CheckCredentials method before doing their actual work, in order to verify the value of the token.
    Which leads us to the implementation of CheckCredentials, which is shown below (using a hard-coded check for the values of the Username and Password properties of the token - you should obviously implement a stronger check here!).


    Note that apart from returning False is the Username and Password are incorrect, we can also raise an exception, for example if the token is not found in the SOAP header (which might happen if the web service is consumed and used by web service client applications who do not add the token to the SOAP header in the first place).



    method Service.CheckCredentials: Boolean;
    begin
    Result := False;
    if not Assigned(token) then
    raise
    ApplicationException.Create('No token in SOAP Header!');

    if (token.Username.ToLower = 'bob') and
    (token.Password.ToLower = 'swart') then Result := True
    end;


    The implementation of Remember and Recall can simple be extended by calling the CheckCredentials method before doing anything:



    method Service.Remember(const Name,Value: String);
    begin
    if
    CheckCredentials then
    Session[Name] := Value
    end;

    method Service.Recall(const Name: String): String;
    begin
    if
    CheckCredentials then
    if
    Assigned(Session[Name]) then
    Result := Session[Name].ToString
    else Result := ''
    end;


    Note that Forget and Amnesia remain unchanged, since you are always allowed to forget:



    method Service.Forget(const Name: String);
    begin
    Session.Remove(Name) // always allowed
    end;

    method Service.Amnesia;
    begin
    Session.Abandon // always allowed
    end;


    Before deploying and consuming this new secure web service, there's one thing to keep in mind about using SOAP Headers: the contents are sent in plain text over the network.
    So passing a username and password inside a SOAP Header is adding authorization capabilities, but still lacks a little security.
    For that reason, I always recommend to use SOAP Headers in combination with HTTPS and SSL.
    That way, the traffic between the web service and client is encrypted, and nobody else should be able to decypher the information sent by the client to the server (since it's encrypted with the public key from the server, and can only be decrypted by the private key of the server, so anyone sniffing the network only gets an encrypted package).


    Implementing HTTPS and SSL requires two things: first, you should purchase a certificate and install it on your web server (or ask your provider if a certificate is already available for use by your web service), and second, all URLs that are used to communicate with the web service should use https:// and not http://.


    For this example, I give you the option of exploring the difference, so I've deployed the secure web service on two different web servers: one with HTTPS and one without.
    On one server, you can access the web service via http://www.bobswart.net/MyWebService/Service.asmx and on the other (secure) web server you have to use HTTPS and the URL https://www.bobswart.nl/MyWebService/Service.asmx instead.


    Both will work the same (the MyWebService.dll code behind assembly is exactly the same on both machines), but one connection is more secure than the other, which is important when using SOAP Headers.