November 2007 - Posts - David Airapetyan
in

InfoPath Dev

David Airapetyan

November 2007 - Posts

  • How to automatically build and deploy DBXL solutions

    A DBXL solution typically is a complex system consisting of a database schema as well as several InfoPath templates along with their corresponding DBXL settings and database mappings. Maintaining and deploying those can be a challenging task. The DBXL Migration Tool (also known as Document Deployer) allows automating the process of building and deploying a DBXL solution.
     
    Step one: creating an installer
    The first step is to create a Document Deployer installer. Let us assume that a DBXL solution consists of several InfoPath templates saved as source files (typical setup when creating InfoPath templates with business logic). Furthermore, let us assume that the templates have already been deployed to DBXL and mappings have been created. To create the installer, follow these steps:

    1. Create a Mappings\Samples folder next to the solutions
    2. For each InfoPath Template, use the Migration Tool to export the configuration and save the mapping.xml into individual folders under the Mappings\Samples folder.
    3. (Optional) Manually edit each mapping.xml file and remove the contents of the template node. This is done to keep the mappings files small; the build process will replace the template node with the fresh bits anyway.
    4. Add an install.sql to one of the folders, it does not matter which one but make sure that the mapping with the SQL installer gets executed first. It is a best practice to have the install.sql create the database schema only if one does not exist already, this enables the upgrade scenario.
    5. Add whatever documents needing to be deployed alongside the mappings in the corresponding SampleDocs folder.
    6. Within the Mappings folder, create a Document Deployer install script (see example in the appendix).
    7. (Optional) Create batch files to facilitate the deployment

    Step 2: creating a build for the template DLLs
    If you have an InfoPath solution with business logic, it has to be compiled before the XSN can be generated. Create an empty Visual Studio solution that will be used to build all of your InfoPath templates. Then create one C# project for each template and add the source files (typically FormCode.cs) as link to those solutions. You will need to add the missing references manually such as Microsoft.Office.Interop.InfoPath.SemiTrust. Make sure to edit the project properties to make sure that the names of the DLLs generated match the ones build by InfoPath.
     
    Step 3: creating a Document Deployer build
    Now that you can build the InfoPath business logic and that you have an installer structure in place, creating a Document Deployer build is simply a matter of creating a Document Deployer script that will combine the expanded template files with the DLLs and put the result into the mapping.xml files. See the appendix for the example of such a script.
     
    Appendix: Example
    Suppose that your DBXL system has two solutions, Users and Expense Reports (first one allows to edit the users in the system while the second one allows the users to edit their expense reports). Initially, you will have the following directory structure:

    ExpenseSystem
     Users
      InfoPath Form Template
     ExpenseReport
      InfoPathFormTemplate

    Add the Mappings\Samples folder and save the mappings for the two solutions. Assuming there is an install.sql file for each of the solutions that creates the database tables, the new folder structure will look like this:

    ExpenseSystem
     Users
      InfoPath Form Template
     ExpenseReport
      InfoPathFormTemplate
     Mappings
      Samples
       Users
        install.sql
        mapping.xml
       ExpenseReport
        install.sql
        mapping.xml 

    Now create a DocumentDeployer scenario called InstallSamples.xml in the Mappings folder:

    <?xml version="1.0" encoding="utf-8" ?>
    <ScenarioDefinition>
     <Imports useXpath="true">
      <ImportActionDefinitions>concat($ScenariosPath, '\MigrateCore.xml')</ImportActionDefinitions>
     </Imports>
     <GlobalVariables>
      <GlobalVariable name="installSql" value="True"/>
     </GlobalVariables>
     <Runs>
      <Run name="InstallExpenseSystem">
       <Action name="InstallDocType">
        <param name="path">Samples\Users</param>
        <param name="database">ExpenseDatabase</param>
        <param name="installDatabase" useXpath="true">$installSql</param>
       </Action>
       <Action name="InstallDocType">
        <param name="path">Samples\ExpenseReport</param>
        <param name="database">ExpenseDatabase</param>
        <param name="installDatabase" useXpath="true">$installSql</param>
       </Action>
      </Run>
     </Runs>
    </ScenarioDefinition>

    It defines a global variable called installSql which specifies whether or not to execute the install.sql scripts. This variable when specified of DocumentDeployer's command-line allows to tweak the process to enable update scenarios. To invoke the installation, run the following command: "C:\Program Files\Qdabra Software\DBXLMigrationTool\DocumentDeployer.exe" InstallSamples.xml InstallExpenseSystem --databaseServer=yourDbServer --DBXLUrl=yourDbxlUrl --installSql=True|False

    The Build scenario will look like this:

    <?xml version="1.0" encoding="utf-8"?>
    <ScenarioDefinition>
     <GlobalVariables>
      <GlobalVariable name="mappingRoot" value="C:\ExpenseSystem \Mappings\Samples\"/>
      <GlobalVariable name="binariesRoot" value="path to the compiled dlls"/>
      <GlobalVariable name="solutionsRoot" value=" C:\ExpenseSystem \"/>
     </GlobalVariables>
     <Classes xmlns:dd="
    http://www.qdabra.com/DocumentDeployer">
      <dd:Class Assembly="Qdabra.DocumentDeployer.InfoPathTools" Name="Qdabra.DocumentDeployer.InfoPathTools.SolutionTools" Alias="Tools">
      </dd:Class>
     </Classes>
     <ActionDefinitions>
      <ActionDefinition name="AssembleAndUpdateMapping">
       <Variables>
        <Variable name="solutionSourcePath" output="false"/>
        <Variable name="solutionDllPath" output="false"/>
        <Variable name="templateXsnName" output="false"/>
        <Variable name="mappingToUpdatePath" output="false"/>
       </Variables>
       <Methods>
        <Method class="Tools" name="UpdateMapping">
         <XPathParameter>$solutionSourcePath</XPathParameter>
         <XPathParameter>$solutionDllPath</XPathParameter>
         <XPathParameter>$templateXsnName</XPathParameter>
         <XPathParameter>$mappingToUpdatePath</XPathParameter>
        </Method>
       </Methods>
      </ActionDefinition>
     </ActionDefinitions>
     <Runs>
      <Run name="AssembleExpenseSystem">
       <Action name="AssembleAndUpdateMapping">
        <param name="solutionSourcePath" useXpath="true">concat($solutionsRoot, "Users\InfoPath Form Template\manifest.xsf")</param>
        <param name="solutionDllPath" useXpath="true">$binariesRoot</param>
        <param name="templateXsnName">Users</param>
        <param name="mappingToUpdatePath" useXpath="true">concat($mappingRoot, "Users\mapping.xml")</param>
       </Action>
       <Action name="AssembleAndUpdateMapping">
        <param name="solutionSourcePath" useXpath="true">concat($solutionsRoot, "ExpenseReport\ InfoPath Form Template\manifest.xsf")</param>
        <param name="solutionDllPath" useXpath="true">$binariesRoot</param>
        <param name="templateXsnName">ExpenseReport</param>
        <param name="mappingToUpdatePath" useXpath="true">concat($mappingRoot, "ExpenseReport\mapping.xml")</param>
       </Action>
      </Run>
     </Runs>
    </ScenarioDefinition>

    Once you specify the location of the binaries, Document Deployer will assemble the solutions under the mappings folder which will create the final installer.

  • Announcement: Migration Tool v2 released

    The second version of the Qdabra DBXL Migration Tool (aka Document Deployer) has been released as a public Beta and can be downloaded here: http://www.infopathdev.com/files/folders/dbxldownload/entry24682.aspx

    Here are new features in v2:

    1.       Authentication: in v1, Document Deployer would fail if the currently logged in user failed to authenticate with DBXL. As of v2, Document Deployer will detect this situation and will prompt the user to enter the credentials (caching the username only).

    This unblocks scenarios where a user connects via RAS/VPN when the machine is not joined to the domain.

    2.       Built-in variables support. Now several system values are available anywhere in the system:

    a)      DocumentDeployerPath – specifies the root of the Document Deployer installation

    b)      ScenariosPath – specifies the folder that contains the out-of-the-box scenarios

    c)       DBXLUrl – Defaults to the configuration setting, can be changed dynamically

    d)      DocServiceTimeout – Defaults to .NET setting, can be changed dynamically

    e)      EnumDBTimeout - Defaults to .NET setting, can be changed dynamically

    Built-ins enable scenarios where you can switch DBXL location mid-flight and tweak the parameters such as timeout.

    3.       Global variables and command-line variables: you can finally provide arbitrary arguments via command-line and you can use global variables to provide defaults. With command-line arguments, you can specify the DBXL location, the database name etc... this allows much greater reuse of existing scenarios – no more need to modify the scenario file to change 5 to 10!

    4.       New Core methods:

    a.       Trace (for debugging purposes)

    b.      SetVariable – allows to set xpath variables dynamically in a declarative way

     

    5.       Importing previous runs: Document Deployer v2 allows importing XML files from previous runs enabling abort-and-resume scenarios. Importing XML files also enables very generic input mechanisms.

    6.       Minor tweaks:

    a.       Actions can now fail without failing the entire run

    b.      A few additional checks to prevent faulty scenarios from crashing later

    c.       File version changed to 2.0

    New Migration Tool Features

     

    In addition to Document Deployer changes, the Migration Tool has been updated to use the new features. The Migration Tool features include:

    1.       Ability to specify timeouts via command-line (including sql timeout)

    2.       Ability to specify different source/target DBXL paths via command-line. This allows performing migration in one run. It is no longer needed to modify the configuration of the tool.

    3.       Ability to resume the download of the documents.

    4.       Ability to resume the upload of the documents.

    5.       Most methods got another, richer, version (see the documentation for details)

     

    User interface

     

    The  Migration Tool has been augmented with a graphical user interface which makes running scenarios much easier.

     

     

  • Implementing reusable OM that can be exposed to a task pane

    When developing InfoPath solutions with a task pane, it is possible to call into form's code (business logic) via the window.external.Window.XDocument.Extension mechanism. For example, if you have a public method GetUserName() in your form code, you can call it as window.external.Window.XDocument.Extension.GetUserName().

    What if you want to build a reusable library that can be exposed to the taskpane? It turns out that it's pretty easy to do:

    1.       Create a regular C# library project, implement the OM as you see fit (make sure the assembly has a strong name)

    2.       In project Assembly properties, mark the assembly as COM-visible

    3.       Reference the library in your InfoPath project the usual way

    4.       Create an OM member and expose it as a public property

    5.       You can now call methods via the new OM property

    The key here is step #2, marking the assembly as COM-visible. This allows Javascript to access its members and properties.

    For example, if your library is called MyObjectModel and it has a method GetData(), you can expose and call it as follows:

    In your FormCode.cs:

    // Initialize it when appropriate, probably in OnLoad()
    private
    MyObjectModel _objectModel;

    public MyObjectModel ObjectModel
    {
      get {return _objectModel;}
    } 

    In your task pane code:

    window.external.Window.XDocument.Extension.ObjectModel.GetData(); 

     

    If you form needs to run in the Forms Server this becomes a little trickier because Forms Server business logic does not support member variables. Instead you have to store all state in the FormState object. Because of that you have to make your OM class serializable by adding [System.SerializableAttribute()] to the class definition.

    Your public property then becomes this:

    public ObjectModel ObjectModel
    {
     
    get { return (ObjectModel)FormState["ObjectModel"]; }
    } 

    This assumes you have initialized FormState["ObjectModel"] to an instance of your OM class, for example, during OnLoad().

     

    Important: if you are using InfoPath 2007 OM, you need to mark both your business logic and the OM assemblies with the [assembly: AllowPartiallyTrustedCallers()]attribute.

     

Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.