Switch Expression on Types in .Net

Do you want to create a switch statement in C# on types? And the compiler says:

“error CS0151: a switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type”

17-04-2014 09-36-19

Yes, this is a common situation that I faced already a couple of times. And that is why I want to share my solution here:

public class SwitchType
{
 readonly Dictionary<Type, Action> _matches = new Dictionary<Type, Action>();
 private Action _default = () => { };

 public TypeSwitch Case<T>(Action action)
 {
   _matches.Add(typeof(T), action);
   return this;
 }

 public TypeSwitch Default(Action action)
 {
   _default = action;
   return this;
 }

 public void Switch<T>()
 {
   if (_matches.ContainsKey(typeof(T)))
     _matches[typeof(T)]();
   else
     _default();
 }

}

And this tests shows how to use the class:

[Test]
public void AddingIntAndStringCase_SwitchPerformsCorrectCase()
{
 Type type = null;

 var typeSwitch = new SwitchType()
 .Case<int>(()=>type = typeof(int))
 .Case<string>(()=>type = typeof(string));

 typeSwitch.Switch<string>();

 Assert.AreEqual(typeof(string), type);
}
[Test]
public void AddingStringAndInt_butSwitchingForDouble_performsDefaultSwitch()
{
  Type type = null;
  var typeSwitch = new SwitchType()
   .Case<int>(() => type = typeof(int))
   .Case<string>(() => type = typeof(string))
   .Default(()=>type = typeof(double));

  typeSwitch.Switch<double>();

  Assert.AreEqual(typeof(double), type);
}

Hope this helps :)

Posted in Uncategorized | Leave a comment

vaultRuler – First Steps

You just moved from Vault Basic to Vault Workgroup or Vault Professional and all files are still in category without lifecycle or revision?

Then this is the right tool for you. I would like to give you a little introduction about the workflow:

1. First we create some categories and define some rules for them. We should also set default behaviors for the category if we want them to be applied by the vaultRuler, for example we set a default lifecycle (as shown in the picture below).

CategoryRules2 CategoryRules

2. Now it’s time to start the application. We log in with our Vault credentials and then choose our operations. In our case, we only want to apply the category rules, but in case you manually managed revision and state in a custom property, the vaultRuler provides the possibility to update state/revision from a custom property.

vaultRulerLogin vaultRulerOperations

3. Then we let the application process our files. It provides an overview on success and failures.

vaultRulerProcess

That’s it. Easy and quick!

I hope you liked the little introduction. Test it and give us feedback!

Posted in Uncategorized, Vault API | Tagged , , | 2 Comments

bcpCreator – Three steps for a successful migration into Vault

Yes, there are really just three steps to transfer your data into Vault via bcpCreator.

All you need is the DataExportUtility from Autodesk, an SQL database that contains your metadata and of course your CAD-files. That’s it!

And here we go with the explanation of all the three steps (I use the Padlock from Autodesk as an example.)

1. Scan your CAD-files

This step should be the simplest one, but is not obligatory! Download and install the Autodesk ProductStream DataExportUtility 2014 from Autodesk Website. Now run the application and select the project file (1), and then analyze your data (2):

28-03-2014 17-05-24As soon as the analysis is complete, the tool will show “Done” in the status bar. Now you can check if your files are ok (take a look at the categories that the ExportUtility shows).

The main reason, why you had to scan your data, is because this tool will create a database file, that contains all the relevant information for the export (e.g. information about associations of Inventor files). Without this database, you will not be able to open Inventor files correctly when you imported them into Vault.

The result should be a lucene database in this directory: C:\ProgramData\Autodesk\Productstream Data Export Utility\v2014\NOPSP

2. Bring your meta-data into a SQL-database

Mabe you have already a SQL-database, because you are migrating from an SQL-based Data Management System (e.g. SmartTeam or ProductStream Professional). Than you can go straight to step three. Because I want to bring the Padlock example into an SQL database, I have created a CSV file containing all the files from the Padlock directory, and the associations between the files.

Download the Padlock.csv. But our SQL-database is still empty. Let’s fill the database with our new Padlock.csv. Open SQL-Management Studio and run this query:

USE TestDb
GO
CREATE TABLE CSVTest
(ID INT,
FullName VARCHAR(300),
CreationTimeUtc VARCHAR(100),
LastWriteTimeUtc VARCHAR(100),
ChildIDs VARCHAR(50),
) GO
BULK
INSERT CSVTest
FROM 'c:\Temp\Padlock.csv'
WITH
(
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n'
)
GO

Yea, thats it! Now you can find the new table that contains the Padlock metadata:03-04-2014 10-50-56

3. Export with bcpCreator

The first thing we have to do now, is configuring the bcpCreator correctly. bcpCreator needs the lucene database from the Export Utility. It needs to know where the SQL-database with its files is, and it needs a valid export configuration.

Therefore the first thing we do, is adapting the bcpCreator.exe.config file in the installation directory:

03-04-2014 11-00-21

Now we run the bcpCreator for the first time. It will detect that this is the first run and create a stored procedure in your SQL-database (under Programmability / Sored Procedures / bcpCreator_GetDocuments)

And here is the customized procedure that we can use for the export:

USE [SOME_DATABASE]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Martin Weiss
-- =============================================
ALTER PROCEDURE [dbo].[bcpCreator_GetDocuments] 
AS
BEGIN
 SET NOCOUNT ON;
-- configure this select querry
 SELECT [ID] as 'Id'
 ,[FullName] as 'FileLocation'
 ,'$'+SUBSTRING(REPLACE([FullName],'\','/'),CHARINDEX('\Padlock\',[FullName])+8,300) as 'VaultLocation'
 ,'A' as 'Revision'
 ,'Work in Progress' as 'State'
 ,'Basic Release Process' as 'Lifecycle'
 ,'Standard Alphabetic Format' as 'Revision Definition'
 ,CASE UPPER(RIGHT([FullName],3))
 WHEN 'IAM' THEN 'Engineering'
 WHEN 'IPT' THEN 'Engineering'
 else 'Base'
 END as 'Category'
 ,'Administrator' as 'Created By'
 ,[CreationTimeUtc] as 'Create Date'
 ,'Test import' as 'Revision Description'
 ,[ChildIds] as 'Child Ids'
 ,'Martin' as 'UDP_Author'
 FROM [SOME_DATABASE].[dbo].[CSVTest]
END

Now we are ready for the final export! Run the bcpCreator again and relax…

If you have configured that, the Bcp-Utility will be launched automatically. There is nothing left to do anymore. Otherwise you can search and launch this batch file C:\Temp\bcpCreatorExportPackage_***\Package_Import.bat

03-04-2014 12-28-46When the export is done, open your Vault client, and check if the folders are created and are containing the padlock files. Check if the Revisions, States, Properties and the History is Ok.

Now we are done!

Posted in PowerShell, Uncategorized, Vault API | Tagged , , , | Leave a comment

folderPicker revisited!

One of the common requirements with Data Standard is to pick the right folder. In a previous post I’ve shown how this can be done with two or more cascading combo-boxes, where each combo points to a folder-level inside Vault. With this post I’d like to show you another way of picking a folder. A while ago, we posted on a tool that we call folderPicker.

folderPicker

It’s a dialog that lists a tree of objects, where the user can navigate through and pick one. The resulting path is returned and can be used. Based on customer feedback, the folderPicker holds a history of recently selected paths and a list of favorites, so that re-picking similar or frequently used objects becomes easy. I deliberately say objects and not folders, as the folderPicker in realty can display any type of objects-tree. For instance, you could display BOMs, pick an item and get the path of such selection, or any other hierarchically managed object.

Anyway, we talk about folders today. But, as you know, each customer project might have particular requirements. One customer has a complete free path, another one has a fixed initial path and then a free one, the next one would like to pick just from certain folder types, such as project or other categories, and so on. So, the folder picker must be flexible in terms of his root folder and filter criteria for the child elements.

The folderPicker is an assembly you can easily load into your Data Standard project and bind for instance a button with it. As the customer hits the button, the folderPicker dialog appears. The function behind the button calls the folderPicker and the resulting value is stored in a field that can be used for creating the path. The method Show requires as arguments the root folder, so that you can choose where the tree of the folderPicker shall start, and you can pass a title and  full path in case you like that the folderPicker should already expand that path in the tree.

In order to find and display the children for the given root element, an according logic must be implemented. In the package provided with this post, the logic for finding child folders is already implemented. However, in case you like to influence the finding logic, you have to adapt the function GetChildren. This way, you may display only folders of certain categories, names, or other properties.

All right, with the coolOrange folderPicker you have a now a very elegant and flexible instrument for picking a folder, either from your local disk, or Vault. We published on the source code on GitHub, so that if you like to better understand how it works, or you like to tweak the folderPicker, you are free to do it.

Have fun!

Posted in Uncategorized | Leave a comment

bcpDevkit – First Steps

Do you want a quick solution to create your customized BCP package to migrate your data to Vault? And your data-source or migration process is so special and complex that there is no tool that is configurable enough to manage this?

Ok, then why shouldn’t you write your own migration process that generates a BCP package that you can import later? If you have tried this, than you probably know the issues. But we have the answer to these problems: The bcpDevkit

The bcpDevkit is an independent part of our recently launched Data Migration Suite. It’s a simple to use .Net library is not just the core, that we use internally in our migration projects and products. This SDK is developed for people who try to create a BCP package containing their data in an easy and flexible way!

Now I want to show you the simplicity in using the API. And what could be better for this, than combining the power of Windows PowerShell and the bcpDevKit!

Here we go:

1. Download and extract the bcpDevKit binaries into C:\bcpDevKit

2. Open a powerShell IDE (e.g. powerGUI) and load the main binaries

Add-Type -Path "C:\bcpDevKit\bcpDevKit.dll"
Add-Type -Path "C:\bcpDevKit\bcpDevKit.Entities.dll"

3. Configure and create the BcpService using the BcpServiceBuilder:

$bcpServiceBuilder = New-Object bcpDevKit.BcpServiceBuilder
$bcpServiceBuilder.Version = 2014
$bcpServiceBuilder.SetPackageLocation("C:\Temp\myBcpPackage1")

$bcpService = $bcpServiceBuilder.Build()

4. Now you can use the service. You can export a local directory containing files and folders very quick:

$exportFiles = Get-ChildItem -recurse "C:\The_directory_to_be_exported"
foreach( $exportFile in $exportFiles )
{
   $vaultLocation = $exportFile.FullName.Replace($exportDirectory,"$")
   $file = $bcpService.FileService.AddFile( $vaultLocation, $exportFile.FullName )
}

5. When we are done, we flush our changes in the package to the filesystem.

$bcpService.Flush()

Thats it!

17-03-2014 15-29-12

Now you can import your package using the corresponding version of Autodesk Vault Transfer Utility to import your package into Vault.

I hope you like the bcpDevKit as much as I do. Use it, test it, and give us feedback!

Posted in Uncategorized | Leave a comment

Context menus with Data Standard

Data Standard builds on top of WPF (Windows Presentation Foundation), so more or less everything supported by WPF can be done with Data Standard. The options are endless, however today I’d like to introduce context menus.

2014-03-14_08-43-12

Context menus can be configured everywhere on the Data Standard user interface. The interesting thing is that you can have a generic context menu that is accessible in the whole form area, but you can also have very local context menus for certain areas or controls. Basically, you only have to decide to which control you like to add the context menu. In the general case, you probably attach the context menu to the most outside Gird, like this:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
 <ScrollViewer.ContextMenu>
  <ContextMenu>
   <MenuItem Header="Copy to clipboard" Command="{Binding PsCmd[CopyToClipboard]}">
    <MenuItem.Icon>
     <Image Source="C:\ProgramData\Autodesk\Vault 2014\Extensions\DataStandard\Vault\cO.ico"/>
    </MenuItem.Icon>
   </MenuItem>
  <MenuItem Header="Save to CSV" Command="{Binding PsCmd[SaveToCSV]}"/>
 </ContextMenu>
</ScrollViewer.ContextMenu>

In the case of the DataSheet tab, the most outer control is a ScrollViever, which is responsible for scrolling in case the visible area is too small. Anyway, it’s a control and it eposes the ContextMenu property. Well almost every control has such property, so the same would apply to a single TextBox, if you like. Inside the ContextMenu we will define the ContextMenu area and then several MenuItems. Each MenuItem exposes properties such as Header for the menu text, Icon for the picture to be displayed, and Command, which can be bound to a PowerShell function via the PsCmd. Here are the functions:

function CopyToClipboard
{
  $text = @($Prop["Title"].Value,$Prop["Description"].Value,$Prop["Category Name"].Value,$Prop["State"].Value)
  $text = $text -join ","
  [Windows.Forms.Clipboard]::SetText($text)
}

function SaveToCSV
{
  $text = @($Prop["Title"].Value,$Prop["Description"].Value,$Prop["Category Name"].Value,$Prop["State"].Value)
  $text | Export-Csv C:\temp\mycsv.csv
}

The first function copies some properties of the selected file into the clipboard. We use the standard .Net function SetText, which is in the assembly Windows.Forms.Clipboard. Just pass any text to the function and it will be in your clipboard ready to be pasted. As you can see, I collect the several file properties into an array ( @(“…”,”…”,”…”) ) and then transform it into a comma separated string via the –join parameter. You would say “why not create the string as comma separated in the first place?”. Good question, but I was willing to show you this little genial parameter –join which allows you to easily transform an array into a string with the separator you prefer. This are the little things that makes PowerShell so great. For a developer, transforming an array into a string is not a big deal, but for a non-developer, this could be a big headache. Such small arguments, parameters, etc. makes it by far easier to script rather then to develop.

Anyway, now we have 2 menu items that are available across the whole form. In case we like to ha a specific command for a specific control, then it look identical to what we did so far, but for our specific control. For instance, I’d like copying just the title to my clipboard. So, I define a context menu for the TextBox only, like this:

<TextBox Text="{Binding Prop[Title].Value}" Grid.Column="1" Grid.Row="3">
 <TextBox.ContextMenu>
</span><span style="line-height: 1.5;">  <ContextMenu>
   <MenuItem Header="Copy to clipboard" Command="{Binding PsCmd[CopyTitleToClipboard]}">
    <MenuItem.Icon>
     <Image Source="C:\ProgramData\Autodesk\Vault 2014\Extensions\DataStandard\Vault\cO.ico"/>
    </MenuItem.Icon>
   </MenuItem>
  </ContextMenu>
 </TextBox.ContextMenu>
</TextBox></span><span style="line-height: 1.5;">

and here is the according powerShell function:

function CopyTitleToClipboard
{
  [Windows.Forms.Clipboard]::SetText($Prop["Title"].Value)
}

Try it out! You will have 2 menu items for the whole form, and just a single menu item for the TextBox title. So, now It’s up to you. You are free to configure any context menu as you like. Of course you can have nested menu items and separators. Have fun!

And here is the complete code.

Posted in Data Standard, PowerShell | Leave a comment

Vault migrations? No problem!

It’s done! The Data Migration Suite is available as Beta version. What is it? It’s a collection of tools all around Vault migration challenges.

Data Migration Suite

Over the past years, we had the pleasure to help resellers around the globe in migration projects. There have been migrations from known, unknown and self-made systems, and also upgrades from Vanilla Vault to a higher version. Every migration had its peculiarity. During the course of this period, we developed several tools for ourselves and now we make them accessible to the greater Autodesk community. The migration process is always somewhat the same:

prepare > check > import > cleanup > complete

While the import is done with Autodesk Data Transfer Utility, also known as Vault BCP, it has been useful to prepare the BCP, check it before running the import, and once the data were in Vault, to clean them up and potentially complete it. So the tools are partially related to BCP packages pre-import and partially to Vault for cleaning up and completing the import. Here a short overview of the tools and each purpose:

  • bcpDevKit: for all those of you that tried creating a BCP package by yourself and run into issues, here a simple to use .Net assembly which you can use in your Visual Studio project for generating BCP packages.
  • bcpCreator: if you have a data source such as SQL, or any other that can be imported into a SQL database, here is a ready-to-use tool that transforms such data into a BCP package.
  • bcpChecker: after having created the BCP package, the bcpChecker prevents you from running the import for several hours and then figuring out that something was misconfigured. Instead, it displays the BCP package’s content before the import in a Vault like UI, where you can navigate, check the data and more.
  • postBCP: once the data are imported into Vault, you may want to sync back the Vault data to your Inventor files and also fresh up the file-BOM information, so that the customer can start working right away.
  • vaultRuler: this tool typically finds application when you move from Vanilla Vault to Vault Workgroup/Professional. It brings all your files into the configured category and more.
  • dataLoader: if you have an additional source of data that shall be applied to your file properties, dataLoader will automate this process.

For a more complete overview of the tools, check out the brochure here.

With the Data Migration Suite, we took a new approach for promoting our projects. You can purchase a single customer/project license for a specific use within the context of your project. You can also purchase a single tool as a so-called “flatrate”, which allows you to make unlimited use of that tool in any of your projects. Or, if you think that more than 3 tools might be interesting, then take advantage of the special offer until end of march 2014, and get the complete Data Migration Suite. It’s an unrepeatable opportunity!

In any case, take a look at the tools (www.coolorange.com) and give us feedback!! We hope you enjoy them and they will help you in your Vault projects!

Posted in Uncategorized | Leave a comment