diff --git a/ktwsapi/delphi/TODO.txt b/ktwsapi/delphi/TODO.txt
deleted file mode 100644
index e69de29..0000000
--- a/ktwsapi/delphi/TODO.txt
+++ /dev/null
diff --git a/ktwsapi/delphi/doc/KTWSAPI.chm b/ktwsapi/delphi/doc/KTWSAPI.chm
new file mode 100644
index 0000000..a64e7ea
--- /dev/null
+++ b/ktwsapi/delphi/doc/KTWSAPI.chm
diff --git a/ktwsapi/delphi/examples/KTWSAPIExamples.bdsproj b/ktwsapi/delphi/examples/KTWSAPIExamples.bdsproj
new file mode 100644
index 0000000..188af84
--- /dev/null
+++ b/ktwsapi/delphi/examples/KTWSAPIExamples.bdsproj
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+ KTWSAPIExamples.dpr
+
+
+ 7.0
+
+
+ 8
+ 0
+ 1
+ 1
+ 0
+ 0
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 0
+ 1
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 1
+ 1
+ 1
+ True
+ True
+ WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+
+ False
+
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ False
+ False
+ False
+ True
+ True
+ True
+ True
+ True
+ True
+
+
+
+ 0
+ 0
+ False
+ 1
+ False
+ False
+ False
+ 16384
+ 1048576
+ 4194304
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+
+ False
+
+
+ True
+ False
+
+
+
+ $00000000
+
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1044
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+ RemObjects Everwood for Delphi
+ RemObjects SDK - Core Library
+ RemObjects SDK - WebBroker Library
+ RemObjects SDK - RODXSock Library
+ RemObjects SDK - BPDX Library
+ RemObjects SDK - DataSnap Integration Pack
+ RemObjects Pascal Script - Core Package
+ RemObjects Pascal Script - RemObjects SDK 3.0 Integration
+ RemObjects SDK - Indy Library
+ RemObjects SDK - IDE Integration for Win32
+ RemObjects Data Abstract - Core Library
+ RemObjects Data Abstract - IDE Package
+ RemObjects Data Abstract - ADOExpress/dbGo Driver
+ RemObjects Data Abstract - InterBase Express Driver
+ RemObjects Data Abstract - dbExpress Driver
+ RemObjects Data Abstract - Scripting Integration Library
+
+
+
+
+
diff --git a/ktwsapi/delphi/examples/KTWSAPIExamples.dpr b/ktwsapi/delphi/examples/KTWSAPIExamples.dpr
new file mode 100644
index 0000000..abacfde
--- /dev/null
+++ b/ktwsapi/delphi/examples/KTWSAPIExamples.dpr
@@ -0,0 +1,55 @@
+{
+ Copyright (c) 2007, The Jam Warehouse Software (Pty) Ltd.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ i) Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ ii) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ iii) Neither the name of the The Jam Warehouse Software (Pty) Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+}
+
+{*
+ This is a Delphi port of the php api for KnowledgeTree WebService.
+
+ @Author Bjarte Kalstveit Vebjørnsen
+ @Version 1.0 BKV 24.09.2007 Initial revision
+*}
+
+
+program KTWSAPIExamples;
+
+uses
+ Forms,
+ uFolderContentExample in 'uFolderContentExample.pas' {FolderContentExample},
+ uwebservice in '..\uwebservice.pas',
+ uktwsapi in '..\uktwsapi.pas',
+ uPHPserialize in '..\uPHPserialize.pas';
+
+{$R *.res}
+
+begin
+ Application.Initialize;
+ Application.CreateForm(TFolderContentExample, FolderContentExample);
+ Application.Run;
+end.
+
diff --git a/ktwsapi/delphi/examples/KTWSAPIExamples.res b/ktwsapi/delphi/examples/KTWSAPIExamples.res
new file mode 100644
index 0000000..7eb23e4
--- /dev/null
+++ b/ktwsapi/delphi/examples/KTWSAPIExamples.res
diff --git a/ktwsapi/delphi/examples/uFolderContentExample.dfm b/ktwsapi/delphi/examples/uFolderContentExample.dfm
new file mode 100644
index 0000000..51a0ed1
--- /dev/null
+++ b/ktwsapi/delphi/examples/uFolderContentExample.dfm
@@ -0,0 +1,183 @@
+object FolderContentExample: TFolderContentExample
+ Left = 0
+ Top = 0
+ Caption = 'FolderContentExample'
+ ClientHeight = 538
+ ClientWidth = 219
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ OldCreateOrder = False
+ PixelsPerInch = 96
+ TextHeight = 13
+ object tvFolderList: TTreeView
+ AlignWithMargins = True
+ Left = 3
+ Top = 34
+ Width = 213
+ Height = 501
+ Align = alClient
+ Images = ImageList4
+ Indent = 19
+ TabOrder = 0
+ OnCollapsed = tvFolderListCollapsed
+ OnExpanded = tvFolderListExpanded
+ end
+ object Button1: TButton
+ AlignWithMargins = True
+ Left = 3
+ Top = 3
+ Width = 213
+ Height = 25
+ Align = alTop
+ Caption = 'Populate folders'
+ TabOrder = 1
+ OnClick = Button1Click
+ end
+ object ImageList4: TImageList
+ Left = 8
+ Top = 496
+ Bitmap = {
+ 494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+ 0000000000003600000028000000400000001000000001002000000000000010
+ 00000000000000000000000000000000000000000000078DBE00078DBE00078D
+ BE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE00078DBE00078DBE00000000000000000000000000078DBE00078DBE00078D
+ BE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE00078DBE000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE0063CBF800078DBE00A3E1
+ FB0066CDF90065CDF80065CDF90065CDF90065CDF80065CDF90065CDF80066CD
+ F8003AADD800ACE7F500078DBE0000000000078DBE0025A1D10071C6E80084D7
+ FA0066CDF90065CDF90065CDF90065CDF90065CDF80065CDF90065CDF80066CE
+ F9003AADD8001999C90000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE006AD1F900078DBE00A8E5
+ FC006FD4FA006FD4F9006ED4FA006FD4F9006FD4FA006FD4FA006FD4FA006ED4
+ F9003EB1D900B1EAF500078DBE0000000000078DBE004CBCE70039A8D100A0E2
+ FB006FD4FA006FD4F9006ED4FA006FD4F9006FD4FA006FD4FA006FD4FA006ED4
+ F9003EB1D900C9F0F300078DBE00000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE0072D6FA00078DBE00AEEA
+ FC0079DCFB0079DCFB0079DCFB0079DCFB0079DCFB007ADCFB0079DCFA0079DC
+ FA0044B5D900B6EEF600078DBE0000000000078DBE0072D6FA00078DBE00AEE9
+ FC0079DCFB0079DCFB0079DCFB0079DCFB0079DCFB007ADCFB0079DCFA0079DC
+ FA0044B5D900C9F0F300078DBE00000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE0079DDFB00078DBE00B5EE
+ FD0083E4FB0084E4FB0083E4FC0083E4FC0084E4FC0083E4FC0083E4FB0084E5
+ FC0048B9DA00BBF2F600078DBE0000000000078DBE0079DDFB001899C7009ADF
+ F30092E7FC0084E4FB0083E4FC0083E4FC0084E4FC0083E4FC0083E4FB0084E5
+ FC0048B9DA00C9F0F3001496C400000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE0082E3FC00078DBE00BAF3
+ FD008DEBFC008DEBFC008DEBFC008DEBFD008DEBFD008DEBFC008DEBFD008DEB
+ FC004CBBDA00BEF4F700078DBE0000000000078DBE0082E3FC0043B7DC0065C2
+ E000ABF0FC008DEBFC008DEBFC008DEBFD008DEBFD008DEBFC008DEBFD008DEB
+ FC004CBBDA00C9F0F300C9F0F300078DBE000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE008AEAFC00078DBE00FFFF
+ FF00C9F7FE00C8F7FE00C9F7FE00C9F7FE00C9F7FE00C8F7FE00C9F7FE00C8F7
+ FE009BD5E700DEF9FB00078DBE0000000000078DBE008AEAFC0077DCF300219C
+ C700FEFFFF00C8F7FD00C9F7FD00C9F7FD00C9F7FE00C8F7FE00C9F7FD00C8F7
+ FE009BD5E600EAFEFE00D2F3F800078DBE000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE0093F0FE00078DBE00078D
+ BE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE00078DBE00078DBE00078DBE0000000000078DBE0093F0FE0093F0FD001697
+ C500078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE00078DBE00078DBE00078DBE00078DBE000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE009BF5FE009AF6FE009AF6
+ FE009BF5FD009BF6FE009AF6FE009BF5FE009AF6FD009BF5FE009AF6FE009AF6
+ FE000989BA00000000000000000000000000078DBE009BF5FE009AF6FE009AF6
+ FE009BF5FD009BF6FE009AF6FE009BF5FE009AF6FD009BF5FE009AF6FE009AF6
+ FE000989BA000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000078DBE00FEFEFE00A0FBFF00A0FB
+ FE00A0FBFE00A1FAFE00A1FBFE00A0FAFE00A1FBFE00A1FBFF00A0FBFF00A1FB
+ FF000989BA00000000000000000000000000078DBE00FEFEFE00A0FBFF00A0FB
+ FE00A0FBFE00A1FAFE00A1FBFE00A0FAFE00A1FBFE00A1FBFF00A0FBFF00A1FB
+ FF000989BA000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000078DBE00FEFEFE00A5FE
+ FF00A5FEFF00A5FEFF00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE000000000000000000000000000000000000000000078DBE00FEFEFE00A5FE
+ FF00A5FEFF00A5FEFF00078DBE00078DBE00078DBE00078DBE00078DBE00078D
+ BE00000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000078DBE00078D
+ BE00078DBE00078DBE0000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000078DBE00078D
+ BE00078DBE00078DBE0000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000424D3E000000000000003E000000
+ 2800000040000000100000000100010000000000800000000000000000000000
+ 000000000000000000000000FFFFFF0080038007000000000001000300000000
+ 0001000100000000000100010000000000010001000000000001000000000000
+ 0001000000000000000100000000000000070007000000000007000700000000
+ 800F800F00000000C3FFC3FF00000000FFFFFFFF00000000FFFFFFFF00000000
+ FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000
+ 000000000000}
+ end
+end
diff --git a/ktwsapi/delphi/examples/uFolderContentExample.pas b/ktwsapi/delphi/examples/uFolderContentExample.pas
new file mode 100644
index 0000000..728495c
--- /dev/null
+++ b/ktwsapi/delphi/examples/uFolderContentExample.pas
@@ -0,0 +1,108 @@
+unit uFolderContentExample;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, uKtwsapi, uWebService, ImgList, ComCtrls, StdCtrls;
+
+type
+ TFolderContentExample = class(TForm)
+ tvFolderList: TTreeView;
+ ImageList4: TImageList;
+ Button1: TButton;
+ procedure Button1Click(Sender: TObject);
+ procedure tvFolderListCollapsed(Sender: TObject; Node: TTreeNode);
+ procedure tvFolderListExpanded(Sender: TObject; Node: TTreeNode);
+ private
+ { Private declarations }
+ FIsPopulating: Boolean;
+ procedure PopulateTreeView(items: kt_folder_items;
+ parent: TTreeNode; tv: TTreeView);
+ public
+ { Public declarations }
+ end;
+
+var
+ FolderContentExample: TFolderContentExample;
+ UserName, Password: String;
+
+implementation
+
+{$R *.dfm}
+
+procedure TFolderContentExample.Button1Click(Sender: TObject);
+var
+ ktapi: TKTWSAPI;
+ folder: TKTWSAPI_Folder;
+ contents: kt_folder_contents;
+begin
+ if FIsPopulating then Exit;
+
+ Screen.Cursor := crHourglass;
+
+ FIsPopulating := True;
+ ktapi := TKTWSAPI.Create;
+ try
+ ktapi.SetDownloadPath(ExtractFileDir(Application.ExeName));
+ ktapi.StartSession(UserName,Password);
+
+ folder:= ktapi.GetRootFolder;
+ try
+ contents := folder.GetListing(10);
+ try
+ PopulateTreeView(contents.items, nil, tvFolderList);
+ finally
+ contents.Free;
+ end;
+ finally
+ folder.Free;
+ end;
+
+ ktapi.Logout;
+ finally
+ ktapi.Free;
+ Screen.Cursor := crDefault;
+ FIsPopulating := False;
+ end;
+end;
+
+procedure TFolderContentExample.PopulateTreeView(items: kt_folder_items; parent: TTreeNode;
+ tv: TTreeView);
+var
+ I: Integer;
+ node: TTreeNode;
+ it: kt_folder_item;
+begin
+ for I := 0 to Length(items) - 1 do
+ begin
+ it := items[i];
+ if it.item_type <> 'F' then Continue;
+ node := tv.Items.AddChild(parent, it.title);
+ node.ImageIndex := 0;
+ node.Data := it;
+ if (Length(it.items) > 0) then
+ PopulateTreeView(it.items, node, tv);
+ end;
+end;
+
+procedure TFolderContentExample.tvFolderListCollapsed(Sender: TObject;
+ Node: TTreeNode);
+begin
+ Node.ImageIndex := 0;
+end;
+
+procedure TFolderContentExample.tvFolderListExpanded(Sender: TObject;
+ Node: TTreeNode);
+begin
+ Node.ImageIndex := 1;
+end;
+
+initialization
+ UserName := 'xxxx';
+ Password := 'xxxx';
+ uktwsapi.KTWebServerUrl := 'http://ktdms.trunk';
+ uktwsapi.KTWebServiceUrl := uktwsapi.KTWebServerUrl+'/ktwebservice/webservice.php?wsdl';
+ uktwsapi.KTUploadUrl := uktwsapi.KTWebServerUrl+'/ktwebservice/upload.php';
+
+end.
diff --git a/ktwsapi/delphi/uPHPserialize.pas b/ktwsapi/delphi/uPHPserialize.pas
new file mode 100644
index 0000000..38905c8
--- /dev/null
+++ b/ktwsapi/delphi/uPHPserialize.pas
@@ -0,0 +1,469 @@
+{
+ Copyright (c) 2007, The Jam Warehouse Software (Pty) Ltd.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ i) Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ ii) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ iii) Neither the name of the The Jam Warehouse Software (Pty) Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+}
+
+{*
+ A helper unit to unserialize a php serialized string
+
+ Inspired by the various implementaions presented here
+ http://www.phpguru.org/static/PHP_Unserialize.html
+
+ @Author Bjarte Kalstveit Vebjørnsen
+ @Version 1.0 BKV 24.09.2007 Initial revision
+ @Todo A complementary serializing function would be nice
+*}
+
+unit uPHPSerialize;
+
+interface
+
+uses
+ Classes, SysUtils, Variants, ComCtrls;
+
+type
+ TPHPValue = class;
+ TPHPArray = class;
+ TPHPSerialize = class;
+
+ /// a single hash element
+ TPHPHashElement = record
+ Key: TPHPValue; /// The Key part of the element
+ Value: TPHPValue; /// The Value part of the element
+ end;
+
+ /// an array of hash elements
+ TPHPHashedElementArray = array of TPHPHashElement;
+
+ /// Tries to replicate a php array by accessing values through strings
+ /// @Todo: Add support for numeric keys
+ TPHPArray = class
+ private
+ FElements: TPHPHashedElementArray; /// array of hash elements
+ function GetValue(Key: string): TPHPValue; overload;
+ function GetValue(Key: TPHPValue): TPHPValue; overload;
+ procedure SetValue(Key: TPHPValue; VValue: TPHPValue); overload;
+ function GetCount: Integer;
+ function Getempty: Boolean;
+ public
+ property Value[Key: string]: TPHPValue read GetValue; default;
+ property Value[Key: TPHPValue]: TPHPValue read GetValue write SetValue; default;
+ property Count: Integer read GetCount;
+ property Empty: Boolean read Getempty;
+ procedure Clear;
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+ /// Tries to represent a PHP value of any type
+ TPHPValue = class
+ private
+ FObj: TObject; /// Holds value if it's an object or array
+ FValue: String; /// Holds value if it's something else
+ procedure Clear;
+ public
+ constructor Create(Value: TObject); overload;
+ constructor Create(Value: String); overload;
+ destructor Destroy; override;
+ function AsString: String;
+ function AsDouble: Double;
+ function AsInteger: Integer;
+ function AsObject: TObject;
+ function AsArray: TPHPArray;
+ function AsBoolean: Boolean;
+ end;
+
+ /// Class for unserializing a php serialized string
+ TPHPSerialize = class
+ private
+ function GetLength(Data: String): Integer;
+ function GetIntLength(Value: Integer): Integer;
+ public
+ class function Unserialize(Data: String): TPHPValue;
+ function _Unserialize(var Data: String): TPHPValue;
+ end;
+
+implementation
+
+{ TPHPSerialize }
+
+{*
+ Finds the length of they to the type
+
+ @param string Data
+ @return integer
+*}
+function TPHPSerialize.GetLength(Data: String): Integer;
+begin
+ Data := Copy(Data, 3, Length(Data));
+
+ Result := StrToIntDef(Copy(Data, 0, Pos(':', Data)-1), 0);
+end;
+
+{*
+ Finds the lenght of the character-space the value occupies
+
+ @param integer Value
+ @return Integer
+*}
+function TPHPSerialize.GetIntLength(Value: Integer): Integer;
+begin
+ Result := Length(IntToStr(Value));
+end;
+
+{*
+ Helper function to use this class statically
+
+ @param integer Value
+ @return Integer
+*}
+class function TPHPSerialize.Unserialize(Data: String): TPHPValue;
+var
+ obj: TPHPSerialize;
+begin
+ obj := TPHPSerialize.Create;
+ try
+ Result := obj._Unserialize(Data);
+ finally
+ obj.Free;
+ end;
+end;
+
+{*
+ Recursing function for unserializing a string and creating a php value from it
+
+ @see TPHPValue
+ @param Data String
+ @return TPHPValue
+*}
+function TPHPSerialize._Unserialize(var Data: String): TPHPValue;
+var
+ I, Len: Integer;
+ Num: Double;
+ C: String;
+ Arr: TPHPArray;
+ Key, Value: TPHPValue;
+begin
+ C := Copy(Data,0,1);
+
+ if (C = 'a') then
+ begin
+ Len := GetLength(Data);
+ Data := Copy(Data, GetIntLength(Len) + 5, Length(Data) );
+
+ Arr := TPHPArray.Create;
+ for I := 0 to Len-1 do
+ begin
+ Key := _Unserialize(Data);
+ Value := _Unserialize(Data);
+
+ Arr[Key] := Value;
+ end;
+
+ Data := Copy(Data, Length(Data));
+ Result := TPHPValue.Create(Arr);
+
+ end else if (C = 's') then
+ begin
+ Len := GetLength(Data);
+ Result := TPHPValue.Create(Copy(Data, GetIntLength(Len) + 5, Len));
+ Data := Copy(Data, GetIntLength(Len) + 7 + Len, Length(Data));
+ end else if (C = 'i') or (C = 'd') then
+ begin
+ Num := StrToFloat(Copy(Data, 3, AnsiPos(';', Data)-3));
+ Result := TPHPValue.Create(FloatToStr(Num));
+ Data := Copy(Data, Length(FloatToStr(Num)) + 4, Length(Data));
+ end else if (C = 'b') then
+ begin
+ Result := TPHPValue.Create(BoolToStr(Copy(Data, 3, 1) = '1'));
+ Data := Copy(Data, 4, Length(Data));
+ end else if (C = 'O') or (C = 'r') or (C = 'C') or (C = 'R')
+ or (C = 'U') then
+ begin
+ raise Exception.Create('Unsupported PHP data type found!');
+ end else if (C = 'N') then
+ begin
+ Result := TPHPValue.Create(nil);
+ Data := Copy(Data, 2, Length(Data));
+ end else
+ begin
+ Result := TPHPValue.Create(nil);
+ Data := '';
+ end;
+end;
+
+
+{ TPHPValue }
+
+{*
+ Returns value as boolan
+
+ @return boolean value
+*}
+function TPHPValue.AsBoolean: Boolean;
+begin
+ Result := StrToBool(FValue);
+end;
+
+{*
+ Returns value as double
+
+ @return double value
+*}
+function TPHPValue.AsDouble: Double;
+begin
+ Result := StrToFloat(FValue);
+end;
+
+{*
+ Returns value as an associative-array
+
+ @return associative-array
+*}
+function TPHPValue.AsArray: TPHPArray;
+begin
+ Result := nil;
+ Assert(Assigned(FObj));
+
+ if (FObj.ClassType = TPHPArray) then
+ Result := TPHPArray(FObj);
+end;
+
+{*
+ Returns value as an integer
+
+ @return integer value
+*}
+function TPHPValue.AsInteger: Integer;
+begin
+ Result := StrToInt(FValue);
+end;
+
+{*
+ Returns value as an object
+
+ @return object value
+*}
+function TPHPValue.AsObject: TObject;
+begin
+ Assert(Assigned(FObj));
+ Result := FObj;
+end;
+
+{*
+ Returns value as a string
+
+ @return string value
+*}
+function TPHPValue.AsString: String;
+begin
+ Result := FValue;
+end;
+
+{*
+ Constructor
+
+ @param Value Value to store
+*}
+constructor TPHPValue.Create(Value: String);
+begin
+ Clear;
+ FValue := Value;
+end;
+
+{*
+ Constructor
+
+ @param Value Value to store
+*}
+constructor TPHPValue.Create(Value: TObject);
+begin
+ Clear;
+ FObj := Value;
+end;
+
+{*
+ Clears current value
+*}
+procedure TPHPValue.Clear;
+begin
+ FValue := '';
+ if Assigned(FObj) then FObj.Free;
+ FObj := nil;
+end;
+
+{*
+ Destructor
+*}
+destructor TPHPValue.Destroy;
+begin
+ Clear;
+ inherited;
+end;
+
+{ TPHPArray }
+
+
+{*
+ Clears whole array
+*}
+procedure TPHPArray.Clear;
+var
+ i: Integer;
+begin
+ for i := 0 to GetCount - 1 do
+ begin
+ FElements[i].Key.Free;
+ FElements[i].Key := nil;
+ FElements[i].Value.Free;
+ FElements[i].Value := nil;
+ end;
+ SetLength(FElements, 0);
+end;
+
+{*
+ Constructor
+*}
+constructor TPHPArray.Create;
+begin
+ inherited;
+ Clear;
+end;
+
+{*
+ Destructor
+*}
+destructor TPHPArray.Destroy;
+begin
+ Clear;
+ inherited;
+end;
+
+{*
+ Returns the number of items in the array
+
+ @return number of items
+*}
+function TPHPArray.GetCount: Integer;
+begin
+ Result := Length(FElements);
+end;
+
+{*
+ Checks if the array is empty
+
+ @return true
+*}
+function TPHPArray.Getempty: Boolean;
+begin
+ Result := Length(FElements) = 0;
+end;
+
+{*
+ Fetch a phpvalue from the array
+
+ @param Key Handle to phpvalue
+ @return handle to phpvalue
+*}
+function TPHPArray.GetValue(Key: TPHPValue): TPHPValue;
+begin
+ Result := GetValue(Key.FValue);
+end;
+
+{*
+ Fetch a phpvalue from the array
+
+ @param Key Index to element
+ @return handle to phpvalue
+*}
+function TPHPArray.GetValue(Key: string): TPHPValue;
+var
+ i: Integer;
+ r: Boolean;
+begin
+ Result := nil;
+ i := 0;
+ r := False;
+ while (i < Length(FElements)) and (not r) do
+ begin
+ if AnsiUpperCase(FElements[i].key.AsString) = AnsiUpperCase(Key) then
+ begin
+ Result := FElements[i].Value;
+ r := True;
+ end;
+ i := i + 1;
+ end;
+end;
+
+{*
+ Insert a phpvalue into the array
+
+ @param Key Index to element
+ @return handle to phpvalue
+*}
+procedure TPHPArray.SetValue(Key, VValue: TPHPValue);
+var
+ i, j: Integer;
+ r: Boolean;
+ E: TPHPHashedElementArray;
+begin
+ if VValue <> nil then
+ begin
+ i := 0;
+ r := False;
+ while (i < Length(FElements)) and not r do
+ begin
+ if AnsiUpperCase(FElements[i].key.AsString) = AnsiUpperCase(Key.AsString) then
+ begin
+ FElements[i].Value := VValue;
+ r := True;
+ end;
+ i := i + 1;
+ end;
+ if not r then
+ begin
+ SetLength(FElements, Length(FElements) + 1);
+ FElements[Length(FElements) - 1].Key := Key;
+ FElements[Length(FElements) - 1].Value := Vvalue;
+ end;
+ end;
+
+ SetLength(E, Length(FElements));
+ for i := 0 to Length(FElements) - 1 do E[i] := FElements[i];
+ SetLength(FElements, 0);
+ for i := 0 to Length(E) - 1 do if (E[i].Key.AsString <> '')
+ and (E[i].Value <> nil) then
+ begin
+ j := Length(FElements);
+ setlength(FElements, j + 1);
+ FElements[j] := E[i];
+ end;
+end;
+
+end.
+
diff --git a/ktwsapi/delphi/uktwsapi.pas b/ktwsapi/delphi/uktwsapi.pas
new file mode 100644
index 0000000..8e8e88d
--- /dev/null
+++ b/ktwsapi/delphi/uktwsapi.pas
@@ -0,0 +1,1630 @@
+{
+ Copyright (c) 2007, The Jam Warehouse Software (Pty) Ltd.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ i) Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ ii) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ iii) Neither the name of the The Jam Warehouse Software (Pty) Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+}
+
+{*
+ This is a Delphi port of the php api for KnowledgeTree WebService.
+
+ @Author Bjarte Kalstveit Vebjørnsen
+ @Version 1.0 BKV 24.09.2007 Initial revision
+*}
+
+unit uktwsapi;
+
+interface
+
+uses
+ Classes, SysUtils, SOAPHTTPClient, uwebservice;
+
+type
+
+ /// Base exception class
+ EKTWSAPI_Exception = class(Exception);
+
+ TKTWSAPI_FolderItem = class;
+ TKTWSAPI_Folder = class;
+ TKTWSAPI_Document = class;
+ TKTWSAPI = class;
+
+ /// Base class for documents and folders
+ TKTWSAPI_FolderItem = class(TObject)
+ private
+ FKTAPI: TKTWSAPI; /// Handle to KTAPI object
+ FParentId: Integer; /// Id of parent folder
+
+ function _GetFileSize(FileName: WideString): WideString;
+ function _UploadFile(FileName, Action: WideString; DocumentId: Integer = 0): WideString;
+ function _DownloadFile(Url, LocalPath, FileName: WideString): Boolean;
+ function _SaveBase64StringAsFile(Base64String, LocalPath, FileName: WideString): Boolean;
+ function _LoadFileAsBase64String(FileName: WideString): WideString;
+
+ public
+ function GetParentFolder:TKTWSAPI_Folder;
+ end;
+
+ /// Class representing a folder
+ TKTWSAPI_Folder = class(TKTWSAPI_FolderItem)
+ private
+ FFolderName, /// Name of folder
+ FFullPath: WideString; /// Full path to folder
+
+ FFolderId: Integer; /// Id to folder
+ public
+ constructor Create(KTAPI:TKTWSAPI; FolderDetail: kt_folder_detail); overload;
+ class function Get(KTAPI: TKTWSAPI; FolderId:Integer): TKTWSAPI_Folder;
+ function GetParentFolderId: Integer;
+ function GetFolderName: WideString;
+ function GetFolderId: Integer;
+ function GetFolderByName(FolderName: WideString): TKTWSAPI_Folder;
+ function GetFullPath: WideString;
+ function GetListing(Depth: Integer=1; What: WideString = 'DF'): kt_folder_contents;
+ function GetDocumentByName(Title: WideString): TKTWSAPI_Document;
+ function GetDocumentByFileName(FileName: WideString): TKTWSAPI_Document;
+ function AddFolder(FolderName: WideString): TKTWSAPI_Folder;
+ function Delete(Reason: WideString): Boolean;
+ function Rename(NewName: WideString): Boolean;
+ function Move(TargetFolder:TKTWSAPI_Folder; Reason: WideString): Boolean;
+ function Copy(TargetFolder:TKTWSAPI_Folder; Reason: WideString): Boolean;
+ function AddDocument(FileName: WideString; Title: WideString = '';
+ DocumentType: WideString = ''): TKTWSAPI_Document;
+ function AddDocumentBase64(FileName: WideString; Title: WideString = '';
+ DocumentType: WideString = ''): TKTWSAPI_Document;
+ published
+ property FolderName: WideString read FFolderName write FFolderName;
+ property FullPath: WideString read FFullPath write FFullPath;
+ property FolderId: Integer read FFolderId write FFolderId;
+ end;
+
+ /// Class representing a document
+ TKTWSAPI_Document = class(TKTWSAPI_FolderItem)
+ private
+
+ FDocumentId: Integer; /// Id of document
+ FTitle, /// Title of document
+ FDocumentType, /// Type of document
+ FVersion, /// Document version
+ FFileName, /// Original filename
+ FCreatedDate, /// Date created
+ FCreatedBy, /// Name of user who created
+ FUpdatedDate, /// Date updated
+ FUpdatedBy, /// Name of user who updated
+ FWorkflow, /// Workflow
+ FWorkflowState, /// Workflow state
+ FCheckoutBy, /// Name of user who checked out
+ FFullPath: WideString; /// Full path to document
+ public
+ constructor Create(KTAPI: TKTWSAPI; DocumentDetail: kt_document_detail);
+
+ class function Get(KTAPI: TKTWSAPI; DocumentId: Integer;
+ LoadInfo: Boolean = System.True): TKTWSAPI_Document;
+ function Checkin(FileName, Reason: WideString; MajorUpdate: Boolean): Boolean;
+ function Checkout(Reason: WideString; LocalPath: WideString = '';
+ DownloadFile: Boolean = True): Boolean;
+ function UndoCheckout(Reason: WideString): Boolean;
+ function Download(Version: WideString = ''; LocalPath: WideString = ''; FileName: WideString = ''): Boolean;
+ function Delete(Reason: WideString): Boolean;
+ function ChangeOwner(UserName, Reason: WideString): Boolean;
+ function Copy(Folder: TKTWSAPI_Folder; Reason: WideString;
+ NewTitle: WideString = ''; NewFileName: WideString = ''): Boolean;
+ function Move(Folder: TKTWSAPI_Folder; Reason: WideString;
+ NewTitle: WideString = ''; NewFileName: WideString = ''): Boolean;
+ function ChangeDocumentType(DocumentType: WideString): Boolean;
+ function RenameTitle(NewTitle: WideString): Boolean;
+ function RenameFilename(NewFilename: WideString): Boolean;
+ function StartWorkflow(WorkFlow: WideString): Boolean;
+ function DeleteWorkflow: Boolean;
+ function PeformWorkflowTransition(Transition, Reason: WideString): Boolean;
+ function GetMetadata:kt_metadata_response;
+ function UpdateMetadata(Metadata: kt_metadata_fieldsets): Boolean;
+ function GetTransactionHistory: kt_document_transaction_history_response;
+ function GetVersionHistory: kt_document_version_history_response;
+ function GetLinks: kt_linked_document_response;
+ function Link(DocumentId: Integer; const LinkType: WideString): Boolean;
+ function Unlink(DocumentId: Integer): Boolean;
+ function CheckinBase64(FileName, Reason: WideString; MajorUpdate: Boolean): Boolean;
+ function CheckoutBase64(Reason: WideString; LocalPath: WideString = '';
+ DownloadFile: Boolean = True): Boolean;
+ function DownloadBase64(Version: WideString = ''; LocalPath: WideString = ''): Boolean;
+ function GetTypes: kt_document_types_response;
+ function GetLinkTypes: kt_document_types_response;
+
+ property DocumentId: Integer read FDocumentId write FDocumentId;
+ property Title: WideString read FTitle write FTitle;
+ property DocumentType: WideString read FDocumentType write FDocumentType;
+ property Version: WideString read FVersion write FVersion;
+ property FileName: WideString read FFileName write FFileName;
+ property CreatedDate: WideString read FCreatedBy write FCreatedBy;
+ property CreatedBy: WideString read FCreatedBy write FCreatedBy;
+ property UpdatedDate: WideString read FUpdatedDate write FUpdatedDate;
+ property UpdatedBy: WideString read FUpdatedBy write FUpdatedBy;
+ property Workflow: WideString read FWorkflow write FWorkflow;
+ property WorkflowState: WideString read FWorkflowState write FWorkflowState;
+ property CheckoutBy: WideString read FCheckoutBy write FCheckoutBy;
+ property FullPath: WideString read FFullPath write FFullPath;
+ end;
+
+ /// Api entry point
+ TKTWSAPI = class
+ private
+
+ FSession, /// Current session id
+ FDownloadPath: WideString; /// Current download path
+
+ FSoapClient:KnowledgeTreePort; /// Object implementing the
+ /// KnowledgeTreePort interface
+ public
+ constructor Create();
+ function GetDownloadPath: WideString;
+ function SetDownloadPath(DownloadPath:WideString): Boolean;
+ function StartAnonymousSession(Ip: WideString = ''): WideString;
+ function StartSession(Username, Password: WideString; Ip: WideString = ''): WideString;
+ function ActiveSession(Session: WideString; Ip: WideString = ''): WideString;
+ function Logout: Boolean;
+ function GetRootFolder: TKTWSAPI_Folder;
+ function GetFolderById(FolderId: Integer): TKTWSAPI_Folder;
+ function GetDocumentById(DocumentId: Integer): TKTWSAPI_Document;
+ published
+ property SoapClient: KnowledgeTreePort read FSoapClient write FSoapClient;
+ property Session: WideString read FSession write FSession;
+ end;
+var
+ KTWebServerUrl: WideString; /// Your webserver url
+ KTUploadUrl: WideString; /// URL to the web-service upload.php
+ KTWebServiceUrl: WideString; /// URL to the web-service wsdl
+
+implementation
+
+uses
+ IdComponent, IdURI, IdHttp, IdMultipartFormData, IdGlobalProtocols,
+ uPHPSerialize, EncdDecd;
+const
+ KTWSAPI_ERR_SESSION_IN_USE =
+ 'There is a session already active.'; /// Exception message when session is in use
+ KTWSAPI_ERR_SESSION_NOT_STARTED =
+ 'An active session has not been started.'; /// Exception message when session is not started
+
+
+{ TKTWSAPI_FolderItem }
+
+{*
+ Finds the filesize of a file.
+
+ @param FileName Path to the file
+ @return The size of the file as a string
+*}
+function TKTWSAPI_FolderItem._GetFileSize(FileName: WideString): WideString;
+var
+ SearchRec: TSearchRec;
+ sgPath: string;
+ inRetval, I1: Integer;
+begin
+ sgPath := ExpandFileName(FileName);
+ try
+ inRetval := FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec);
+ if inRetval = 0 then
+ I1 := SearchRec.Size
+ else
+ I1 := -1;
+ finally
+ SysUtils.FindClose(SearchRec);
+ end;
+ Result := IntToStr(I1);
+end;
+
+{*
+ Reads a file into a string and base64 encodes it.
+
+ @param Base64String Base64 encoded string
+ @param LocalPath Path to load from
+ @param FileName FileName to read
+ @return base64 encoded string
+ @throws EKTWSAPI_Exception 'Could not access file to read.'
+*}
+function TKTWSAPI_FolderItem._LoadFileAsBase64String(FileName: WideString): WideString;
+var
+ Stream: TFileStream;
+ InString: AnsiString;
+begin
+ if not FileExists(FileName) then
+ raise EKTWSAPI_Exception.Create('Could not access file to read.');
+ Stream := TFileStream.Create(FileName, fmOpenRead);
+ try
+ SetLength(InString, Stream.Size);
+ Stream.ReadBuffer(InString[1], Length(InString));
+ Result := EncodeString(InString);
+ finally
+ Stream.Free;
+ end;
+end;
+
+{*
+ Save a Base64 encoded string as a file.
+
+ @param Base64String Base64 encoded string
+ @param LocalPath Path to save to
+ @param FileName FileName to save as
+ @return true if success
+*}
+function TKTWSAPI_FolderItem._SaveBase64StringAsFile(Base64String, LocalPath,
+ FileName: WideString): Boolean;
+var
+ OutString: AnsiString;
+ Stream: TFileStream;
+ LocalFileName: String;
+begin
+ LocalFileName := LocalPath + '/' + FileName;
+ OutString := DecodeString(Base64String);
+ Stream := TFileStream.Create(LocalFileName, fmCreate);
+ try
+ // For some reason it fails if I use WideString instead of AnsiString
+ Stream.WriteBuffer(Pointer(OutString)^, Length(OutString));
+ Result := true;
+ finally
+ Stream.Free;
+ end;
+end;
+
+{*
+ Upload a file to KT.
+
+ @param FileName Path to upload file
+ @param Action Which action to perform with the file (A = Add, C = Checkin)
+ @param DocumentId Id of the document
+ @return The temporary filename on the server
+ @throws EKTWSAPI_Exception Could not access file to upload.
+ @throws EKTWSAPI_Exception No response from server.
+ @throws EKTWSAPI_Exception Could not upload file.
+*}
+function TKTWSAPI_FolderItem._UploadFile(FileName, Action: WideString;
+ DocumentId: Integer): WideString;
+var
+ UploadName, UploadStatus, SessionId, StatusCode: WideString;
+ PostStream: TIdMultiPartFormDataStream;
+ ResponseStream: TStringStream;
+ Fields: TStringList;
+ HTTP: TIdHTTP;
+ UploadData: TPHPValue;
+ FilesArr: TPHPArray;
+begin
+ Result := '';
+ if not FileExists(FileName) then
+ raise EKTWSAPI_Exception.Create('Could not access file to upload.');
+ // TODO: Check if file is readable
+
+ if (DocumentId = 0) then
+ UploadName := 'upload_document'
+ else
+ UploadName := 'upload_'+IntToStr(DocumentId);
+ SessionId := FKTAPI.Session;
+
+ HTTP := TIdHttp.Create(nil);
+ try
+ PostStream := TIdMultiPartFormDataStream.Create;
+ ResponseStream := TStringStream.Create('');
+ Fields := TStringList.Create;
+ try
+ PostStream.AddFormField('session_id', SessionId);
+ PostStream.AddFormField('action', Action);
+ PostStream.AddFormField('document_id',IntToStr(DocumentId));
+ PostStream.AddFormField(UploadName,'@' + FileName);
+ PostStream.AddFile('file',FileName,GetMIMETypeFromFile(FileName));
+
+ HTTP.Request.ContentType := PostStream.RequestContentType;
+ HTTP.Post(KTUploadURL, PostStream, ResponseStream);
+ if (ResponseStream.DataString = '') then
+ raise EKTWSAPI_Exception.Create('No response from server.');
+ ExtractStrings(['&'], [' '], pAnsiChar(ResponseStream.DataString), Fields);
+
+ StatusCode := Copy(Fields[0], Pos('=',Fields[0])+1, 1);
+ if (StatusCode <> '0') then
+ raise EKTWSAPI_Exception.Create('Could not upload file.');
+
+
+ UploadStatus := Copy(Fields[1], Pos('=',Fields[1])+1, Length(Fields[1]));
+ UploadStatus := TIdURI.URLDecode(UploadStatus);
+ UploadData := TPHPSerialize.Unserialize(TIdURI.URLDecode(UploadStatus));
+ Assert(Assigned(UploadData));
+ Assert(Assigned(UploadData.AsArray['file']));
+ try
+ FilesArr := UploadData.AsArray['file'].AsArray;
+
+ if (FilesArr['size'].AsString <> _GetFileSize(FileName)) then
+ raise EKTWSAPI_Exception.Create('Could not upload file.');
+
+ Result := FilesArr['tmp_name'].AsString;
+ finally
+ UploadData.Free;
+ end;
+ finally
+ PostStream.Free;
+ ResponseStream.Free;
+ Fields.Free;
+ end;
+ finally
+ HTTP.Free;
+ end;
+end;
+
+{*
+ Downloads a file from KT.
+
+ @param Url Http-url to download
+ @param LocalPath Path to save to
+ @param FileName FileName to save as
+ @return true if success
+ @throws EKTWSAPI_Exception Could not create local file
+*}
+function TKTWSAPI_FolderItem._DownloadFile(Url, LocalPath,
+ FileName: WideString): Boolean;
+var
+ Stream: TMemoryStream;
+ LocalFileName: WideString;
+ FP: File;
+ HTTP: TIdHTTP;
+begin
+ LocalFileName := LocalPath + '/' + FileName;
+
+ AssignFile(FP, LocalFileName);
+ {$I-}
+ Rewrite(FP,1);
+ {$I+}
+ if (IOResult <> 0) then
+ raise EKTWSAPI_Exception.Create('Could not create local file');
+ CloseFile(FP);
+ HTTP := TIdHttp.Create(Nil);
+ try
+ Stream := TMemoryStream.Create;
+ try
+ HTTP.Get(Url, Stream);
+ Stream.SaveToFile(LocalFileName);
+ Result := true;
+ finally
+ Stream.Free;
+ end;
+ finally
+ HTTP.Free;
+ end;
+end;
+
+{*
+ Returns a reference to the parent folder.
+
+ @return Handle to parent folder
+*}
+function TKTWSAPI_FolderItem.GetParentFolder: TKTWSAPI_Folder;
+begin
+ Result := FKTAPI.GetFolderById(FParentId);
+end;
+
+
+ { TKTWSAPI_Folder }
+
+{*
+ Constructor
+
+ @param KTAPI Handle to KTAPI object
+ @param FolderDetail Handle to kt_folder_detail
+*}
+constructor TKTWSAPI_Folder.Create(KTAPI: TKTWSAPI;
+ FolderDetail: kt_folder_detail);
+begin
+ FKTAPI := KTAPI;
+ FFolderId := FolderDetail.id;
+ FFolderName := FolderDetail.folder_name;
+ FParentId := FolderDetail.parent_id;
+ FFullPath := FolderDetail.full_path;
+end;
+
+{*
+ Returns a reference to a TKTWSAPI_Folder
+
+ @param KTAPI Handle to KTAPI object
+ @param FolderId Id of folder to fetch
+ @return folder handle
+ @throws EKTWSAPI_Exception Response message
+*}
+class function TKTWSAPI_Folder.Get(KTAPI: TKTWSAPI;
+ FolderId: Integer): TKTWSAPI_Folder;
+var
+ FolderDetail: kt_folder_detail;
+begin
+ Assert(Assigned(KTAPI));
+ Assert(KTAPI.ClassNameIs('TKTWSAPI'));
+ Result := nil;
+
+ FolderDetail := KTAPI.SoapClient.get_folder_detail(KTAPI.Session, FolderId);
+ try
+ if (FolderDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(FolderDetail.message_);
+
+ Result := TKTWSAPI_Folder.Create(KTAPI, FolderDetail);
+
+ finally
+ FolderDetail.Free;
+ end;
+end;
+
+{*
+ Returns the parent folder id.
+
+ @return parent folder id
+*}
+function TKTWSAPI_Folder.GetParentFolderId: Integer;
+begin
+ Result := FParentId;
+end;
+
+{*
+ Returns the folder name.
+
+ @return folder name
+*}
+function TKTWSAPI_Folder.GetFolderName: WideString;
+begin
+ Result := FFolderName;
+end;
+
+{*
+ Returns the current folder id.
+
+ @return current folder id
+*}
+function TKTWSAPI_Folder.GetFolderId: Integer;
+begin
+ Result := FFolderId;
+end;
+
+{*
+ Returns the folder based on foldername.
+
+ @param FolderName Name of folder
+ @return folder handle
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.GetFolderByName(FolderName: WideString): TKTWSAPI_Folder;
+var
+ Path: WideString;
+ FolderDetail: kt_folder_detail;
+begin
+ Path := FFullPath + '/' + FolderName;
+ if (System.Copy(Path, 0, 13) = '/Root Folder/') then
+ Path := System.Copy(Path, 13, Length(Path)-1);
+ if (System.Copy(Path, 0, 12) = 'Root Folder/') then
+ Path := System.Copy(Path, 12, Length(Path)-1);
+
+ FolderDetail := FKTAPI.SoapClient.get_folder_detail_by_name(FKTAPI.Session,
+ Path);
+
+ if (FolderDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(FolderDetail.message_);
+
+ Result := TKTWSAPI_Folder.Create(FKTAPI, FolderDetail);
+end;
+
+{*
+ Returns the full folder path.
+
+ @return Full folder path
+*}
+function TKTWSAPI_Folder.GetFullPath: WideString;
+begin
+ Result := FFullPath;
+end;
+
+{*
+ Returns the contents of a folder.
+
+ @param Depth How many sub-folders to fetch
+ @param What to fetch (F=Folders, D=Documents, FD=Both)
+ @return folder contents handle
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.GetListing(Depth: Integer;
+ What: WideString): kt_folder_contents;
+begin
+ Result := FKTAPI.SoapClient.get_folder_contents(
+ FKTAPI.Session, FFolderId, Depth, What);
+
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Returns a document based on title.
+
+ @param Title Title of document
+ @return document handle
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.GetDocumentByName(Title: WideString): TKTWSAPI_Document;
+var
+ Path: WideString;
+ DocumentDetail: kt_document_detail;
+begin
+ Path := FFullPath + '/' + Title;
+ if (System.Copy(Path, 0, 13) = '/Root Folder/') then
+ Path := System.Copy(Path, 13, Length(Path)-1);
+ if (System.Copy(Path, 0, 12) = 'Root Folder/') then
+ Path := System.Copy(Path, 12, Length(Path)-1);
+
+ DocumentDetail := FKTAPI.SoapClient.get_document_detail_by_name(FKTAPI.Session,
+ Path, 'T');
+
+ if (DocumentDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(DocumentDetail.message_);
+
+ Result := TKTWSAPI_Document.Create(FKTAPI, DocumentDetail);
+end;
+
+{*
+ Returns a document based on filename.
+
+ @param FileName Name of file
+ @return document handle
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.GetDocumentByFileName(
+ FileName: WideString): TKTWSAPI_Document;
+var
+ Path: WideString;
+ DocumentDetail: kt_document_detail;
+begin
+ Result := nil;
+ Path := FFullPath + '/' + FileName;
+ if (System.Copy(Path, 0, 13) = '/Root Folder/') then
+ Path := System.Copy(Path, 13, Length(Path)-1);
+ if (System.Copy(Path, 0, 12) = 'Root Folder/') then
+ Path := System.Copy(Path, 12, Length(Path)-1);
+
+ DocumentDetail := FKTAPI.SoapClient.get_document_detail_by_name(FKTAPI.Session,
+ Path, 'F');
+ try
+ if (DocumentDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(DocumentDetail.message_);
+ Result := TKTWSAPI_Document.Create(FKTAPI, DocumentDetail);
+ finally
+ DocumentDetail.Free;
+ end;
+end;
+
+{*
+ Adds a sub folder.
+
+ @param FolderName Name of folder
+ @return new folder handle
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.AddFolder(FolderName: WideString): TKTWSAPI_Folder;
+var
+ FolderDetail: kt_folder_detail;
+begin
+ Result := nil;
+ FolderDetail := FKTAPI.SoapClient.create_folder(FKTAPI.Session, FFolderId, FolderName);
+ try
+ if (FolderDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(FolderDetail.message_);
+
+ Result := TKTWSAPI_Folder.Create(FKTAPI, FolderDetail);
+ finally
+ FolderDetail.Free;
+ end;
+end;
+
+{*
+ Deletes the current folder.
+
+ @param Reason Reason for deletetion
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.Delete(Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ // TODO: check why no transaction in folder_transactions
+ Result := System.False;
+ response := FKTAPI.SoapClient.delete_folder(FKTAPI.Session,
+ FFolderId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Renames the current folder.
+
+ @param NewName New folder name
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.Rename(NewName: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.rename_folder(FKTAPI.Session,
+ FFolderId, NewName);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Moves a folder to another location.
+
+ @param TargetFolder Handle to target folder
+ @param Reason Reason for move
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.Move(TargetFolder: TKTWSAPI_Folder;
+ Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ Assert(Assigned(TargetFolder));
+ Assert(TargetFolder.ClassNameIs('TKTWSAPI_Folder'));
+
+ response := FKTAPI.SoapClient.move_folder(FKTAPI.Session,
+ FFolderId, TargetFolder.GetFolderId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Copies a folder to another location
+
+ @param TargetFolder Handle to target folder
+ @param Reason Reason for copy
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.Copy(TargetFolder: TKTWSAPI_Folder;
+ Reason: WideString): Boolean;
+var
+ TargetId: Integer;
+ response: kt_response;
+begin
+ Result := System.False;
+ Assert(Assigned(TargetFolder));
+ Assert(TargetFolder.ClassNameIs('TKTWSAPI_Folder'));
+
+ TargetId := TargetFolder.GetFolderId;
+ response := FKTAPI.SoapClient.copy_folder(FKTAPI.Session,
+ FFolderId, TargetId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Adds a document to the current folder.
+
+ @param FileName FileName to upload
+ @param Title Title to give document
+ @param DocumentType Documenttype of document (Default is 'Default')
+ @return handle to new document
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.AddDocument(FileName, Title,
+ DocumentType: WideString): TKTWSAPI_Document;
+var
+ BaseName, TempFileName: WideString;
+ DocumentDetail: kt_document_detail;
+begin
+ Result := nil;
+ BaseName := ExtractFileName(FileName);
+ if (Title = '') then
+ Title := BaseName;
+ if (DocumentType = '') then
+ DocumentType := 'Default';
+
+ TempFileName := _UploadFile(FileName, 'A');
+ DocumentDetail := FKTAPI.FSoapClient.add_document(FKTAPI.Session, FFolderId,
+ Title, BaseName, DocumentType, TempFileName);
+ try
+ if (DocumentDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(DocumentDetail.message_);
+
+ Result := TKTWSAPI_Document.Create(FKTAPI, DocumentDetail);
+ finally
+ DocumentDetail.Free;
+ end;
+end;
+
+{*
+ Adds a document to the current folder through web service.
+
+ @param FileName FileName to upload
+ @param Title Title to give document
+ @param DocumentType Documenttype of document (Default is 'Default')
+ @return handle to new document
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Folder.AddDocumentBase64(FileName, Title,
+ DocumentType: WideString): TKTWSAPI_Document;
+begin
+ raise EKTWSAPI_Exception.Create('Not implemented yet!');
+end;
+
+{ TKTWSAPI_Document }
+
+{*
+ Constructor
+
+ @param KTAPI Handle to KTAPI object
+ @param DocumentDetail handle to kt_document_detail
+*}
+constructor TKTWSAPI_Document.Create(KTAPI: TKTWSAPI;
+ DocumentDetail: kt_document_detail);
+begin
+ FKTAPI := KTAPI;
+ FDocumentId := DocumentDetail.document_id;
+ FTitle := DocumentDetail.title;
+ FDocumentType := DocumentDetail.document_type;
+ FVersion := DocumentDetail.version;
+ FFilename := DocumentDetail.filename;
+ FCreatedDate := DocumentDetail.created_date;
+ FCreatedBy := DocumentDetail.created_by;
+ FUpdatedDate := DocumentDetail.updated_date;
+ FUpdatedBy := DocumentDetail.updated_by;
+ FParentId := DocumentDetail.folder_id;
+ FWorkflow := DocumentDetail.workflow;
+ FWorkflowState := DocumentDetail.workflow_state;
+ FCheckoutBy := DocumentDetail.checkout_by;
+ FFullPath := DocumentDetail.full_path;
+end;
+
+{*
+ Returns a reference to a document.
+
+ @param KTAPI Handle to KTAPI object
+ @param DocumentId Id of document
+ @param LoadInfo Call web service to load document details
+ @return handle to document
+ @throws EKTWSAPI_Exception Response message
+*}
+class function TKTWSAPI_Document.Get(KTAPI: TKTWSAPI; DocumentId: Integer;
+ LoadInfo: Boolean): TKTWSAPI_Document;
+var
+ DocumentDetail:kt_document_detail;
+begin
+ Assert(Assigned(KTAPI));
+ Assert(KTAPI.ClassNameIs('TKTWSAPI'));
+ if LoadInfo then
+ begin
+ DocumentDetail := KTAPI.SoapClient.get_document_detail(KTAPI.Session, DocumentId);
+
+ if (DocumentDetail.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(DocumentDetail.message_);
+
+ end else
+ begin
+ DocumentDetail := kt_document_detail.Create;
+ DocumentDetail.document_id := DocumentId;
+ end;
+ try
+ Result := TKTWSAPI_Document.Create(KTAPI, DocumentDetail);
+ finally
+ DocumentDetail.Free;
+ end;
+end;
+
+{*
+ Checks in a document.
+
+ @param FileName Name of file to checkin
+ @param Reason Reason for checkin
+ @param MajorUpdate Checkin as a major update (bumps major version number)
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Checkin(FileName, Reason: WideString;
+ MajorUpdate: Boolean): Boolean;
+var
+ BaseName, TempFileName: WideString;
+ response: kt_response;
+begin
+ Result := System.False;
+ BaseName := ExtractFileName(FileName);
+
+ TempFileName := _UploadFile(FileName, 'C', FDocumentId);
+ response := FKTAPI.SoapClient.checkin_document(FKTAPI.Session, FDocumentId, BaseName, Reason, TempFileName, MajorUpdate);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Checks out a document.
+
+ @param Reason Reason for checkout
+ @param LocalPath to save downloaded file to
+ @param DownloadFile if false then checkout will happen without download
+ @return true
+ @throws EKTWSAPI_Exception local path does not exist
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Checkout(Reason, LocalPath: WideString;
+ DownloadFile: Boolean): Boolean;
+var
+ response: kt_response;
+ Url: WideString;
+begin
+ Result := System.False;
+ if (LocalPath = '') then LocalPath := FKTAPI.GetDownloadPath;
+
+ if not DirectoryExists(LocalPath) then
+ raise EKTWSAPI_Exception.Create('local path does not exist');
+
+ // TODO check if Directory is writable
+
+ response := FKTAPI.SoapClient.checkout_document(FKTAPI.Session, FDocumentId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Url := response.message_;
+
+ if DownloadFile then
+ _DownloadFile(KTWebServerURL+Url, LocalPath, FFileName);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Undo a document checkout
+
+ @param Reason Reason for undoing the checkout
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.UndoCheckout(Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.undo_document_checkout(FKTAPI.Session, FDocumentId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Download a version of the document
+
+ @param Version Which version of document to download
+ @param LocalPath Optional path to save file to
+ @param FileName Optional filename to save file as
+ @return true
+ @throws EKTWSAPI_Exception local path does not exist
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Download(Version, LocalPath, FileName: WideString): Boolean;
+var
+ response: kt_response;
+ Url: WideString;
+begin
+ Result := System.False;
+ if (LocalPath = '') then LocalPath := FKTAPI.GetDownloadPath;
+ if (FileName = '') then FileName := FFileName;
+
+ if (not DirectoryExists(LocalPath)) then
+ raise EKTWSAPI_Exception.Create('local path does not exist');
+
+ // TODO: Check if local path is writable
+
+ response := FKTAPI.SoapClient.download_document(FKTAPI.Session, FDocumentId);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Url := response.message_;
+ Result := _DownloadFile(KTWebServerURL+Url, LocalPath, FileName);
+ finally
+ response.Free;
+ end;
+end;
+
+
+{*
+ Download a version of the document through webservice
+
+ @param Version Which version of document to download
+ @param LocalPath Path to save file to
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.DownloadBase64(Version,
+ LocalPath: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ if (LocalPath = '') then LocalPath := FKTAPI.GetDownloadPath;
+ if (FileName = '') then FileName := FFileName;
+
+ if (not DirectoryExists(LocalPath)) then
+ raise EKTWSAPI_Exception.Create('local path does not exist');
+
+ // TODO: Check if local path is writable
+
+ response := FKTAPI.SoapClient.download_base64_document(FKTAPI.Session, FDocumentId);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := _SaveBase64StringAsFile(response.message_, LocalPath, FileName);
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Deletes the current document.
+
+ @param Reason Reason for delete
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Delete(Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.delete_document(FKTAPI.Session, FDocumentId, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Changes the owner of the document.
+
+ @param UserName Username of new owner
+ @param Reason Reason for the owner change
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.ChangeOwner(UserName, Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.change_document_owner(FKTAPI.Session, FDocumentId, UserName, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Copies the current document to the specified folder.
+
+ @param Folder Handle to target folder
+ @param Reason Reason for copy
+ @param NewTitle New title of the file
+ @param NewFileName New filename of the file
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Copy(Folder: TKTWSAPI_Folder; Reason, NewTitle,
+ NewFileName: WideString): Boolean;
+var
+ response: kt_response;
+ FolderId: Integer;
+begin
+ Result := System.False;
+ Assert(Assigned(Folder));
+ Assert(Folder.ClassNameIs('TKTWSAPI_Folder'));
+ FolderId := Folder.GetFolderId;
+
+ response := FKTAPI.SoapClient.copy_document(FKTAPI.Session, FDocumentId, FolderId, Reason, NewTitle, NewFileName);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Moves the current document to the specified folder.
+
+ @param Folder Handle to target folder
+ @param Reason Reason for move
+ @param NewTitle New title of the file
+ @param NewFileName New filename of the file
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Move(Folder: TKTWSAPI_Folder; Reason, NewTitle,
+ NewFileName: WideString): Boolean;
+var
+ response: kt_response;
+ FolderId: Integer;
+begin
+ Result := System.False;
+ Assert(Assigned(Folder));
+ Assert(Folder.ClassNameIs('TKTWSAPI_Folder'));
+ FolderId := Folder.GetFolderId;
+
+ response := FKTAPI.SoapClient.move_document(FKTAPI.Session, FDocumentId, FolderId, Reason, NewTitle, NewFileName);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Changes the document type.
+
+ @param DocumentType DocumentType to change to
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.ChangeDocumentType(DocumentType: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.change_document_type(FKTAPI.Session, FDocumentId, DocumentType);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Renames the title of the current document.
+
+ @param NewTitle New title of the document
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.RenameTitle(NewTitle: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.rename_document_title(FKTAPI.Session, FDocumentId, NewTitle);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Renames the filename of the current document.
+
+ @param NewFilename New filename of the document
+ @return true
+*}
+function TKTWSAPI_Document.RenameFilename(NewFilename: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.rename_document_filename(FKTAPI.Session, FDocumentId, NewFilename);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Starts a workflow on the current document.
+
+ @param WorkFlow Workflow
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.StartWorkflow(WorkFlow: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.start_document_workflow(FKTAPI.Session, FDocumentId, WorkFlow);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Removes the workflow process from the current document.
+
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.DeleteWorkflow: Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.delete_document_workflow(FKTAPI.Session, FDocumentId);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Performs a transition on the current document.
+
+ @param Transition Transition
+ @param Reason Reason for transition
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.PeformWorkflowTransition(Transition,
+ Reason: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.perform_document_workflow_transition(FKTAPI.Session, FDocumentId, Transition, Reason);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Returns metadata on the document.
+
+ @return handle to metadata
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetMetadata: kt_metadata_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_metadata(FKTAPI.Session, FDocumentId);
+
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Updates the metadata on the current document.
+
+ @param Metadata Handle to metadata
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.UpdateMetadata(
+ Metadata: kt_metadata_fieldsets): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.update_document_metadata(FKTAPI.Session, FDocumentId, MetaData);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Returns the transaction history on the current document.
+
+ @return handle to transaction history
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetTransactionHistory: kt_document_transaction_history_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_transaction_history(FKTAPI.Session, FDocumentId);
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Returns the version history on the current document.
+
+ @return handle to document version history
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetVersionHistory: kt_document_version_history_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_version_history(FKTAPI.Session, FDocumentId);
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Returns the links of the current document
+
+ @return handle to document version history
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetLinks: kt_linked_document_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_links(FKTAPI.Session, FDocumentId);
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Links the current document to a DocumentId
+
+ @param DocumentId DocumentId to link to
+ @param LinkType Type of link
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Link(DocumentId: Integer;
+ const LinkType: WideString): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.link_documents(FKTAPI.Session, FDocumentId,
+ DocumentId, LinkType);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Unlinks the current document from a DocumentId
+
+ @param DocumentId DocumentId to unlink to
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.Unlink(DocumentId: Integer): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ response := FKTAPI.SoapClient.unlink_documents(FKTAPI.Session, FDocumentId,
+ DocumentId);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Checks out a document and downloads document through webservice
+
+ @param Reason Reason for checkout
+ @param LocalPath to save downloaded file to
+ @return true
+ @throws EKTWSAPI_Exception local path does not exist
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.CheckoutBase64(Reason,
+ LocalPath: WideString; DownloadFile: Boolean): Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+ if (LocalPath = '') then LocalPath := FKTAPI.GetDownloadPath;
+
+ if not DirectoryExists(LocalPath) then
+ raise EKTWSAPI_Exception.Create('local path does not exist');
+
+ // TODO check if Directory is writable
+
+ response := FKTAPI.SoapClient.checkout_base64_document(FKTAPI.Session, FDocumentId, Reason, DownloadFile);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := True;
+ if DownloadFile then
+ Result := _SaveBase64StringAsFile(response.message_, LocalPath, FFileName);
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Gets list of document types
+
+ @return handle to document types response
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetTypes: kt_document_types_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_types(FKTAPI.Session);
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Get list of document link types
+ @return handle to document types response
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.GetLinkTypes: kt_document_types_response;
+begin
+ Result := FKTAPI.SoapClient.get_document_link_types(FKTAPI.Session);
+ if (Result.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(Result.message_);
+end;
+
+{*
+ Checks in a document and uploads through webservice
+
+ @param FileName Name of file to checkin
+ @param Reason Reason for checkin
+ @param MajorUpdate Checkin as a major update (bumps major version number)
+ @return true
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI_Document.CheckinBase64(FileName, Reason: WideString;
+ MajorUpdate: Boolean): Boolean;
+var
+ Base64String, BaseName: WideString;
+ response: kt_response;
+begin
+ Result := System.False;
+ Base64String := _LoadFileAsBase64String(FileName);
+ BaseName := ExtractFileName(FileName);
+
+ response := FKTAPI.SoapClient.checkin_base64_document(FKTAPI.Session,
+ FDocumentId, BaseName, Reason, Base64String, MajorUpdate);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{ TKTWSAPI }
+
+{*
+ Constructor
+*}
+constructor Tktwsapi.Create();
+begin
+ FSoapClient := GetKnowledgeTreePort(False, KTWebServiceUrl);
+ FDownloadPath := '';
+end;
+
+{*
+ This returns the default location where documents are downloaded in download() and checkout().
+
+ @return string
+*}
+function TKTWSAPI.GetDownloadPath: WideString;
+begin
+ Result := FDownloadPath;
+end;
+
+{*
+ Allows the default location for downloaded documents to be changed.
+
+ @param DownloadPath Path to writable folder
+ @return true
+*}
+function TKTWSAPI.SetDownloadPath(DownloadPath: WideString): Boolean;
+begin
+ if (not DirectoryExists(DownloadPath)) then
+ raise EKTWSAPI_Exception.Create('local path is not writable');
+ // TODO : Check if folder is writable
+
+ FDownloadPath := DownloadPath;
+ Result := System.True;
+end;
+
+{*
+ Starts an anonymous session.
+
+ @param Ip Users Ip-adress
+ @return Active session id
+*}
+function TKTWSAPI.StartAnonymousSession(Ip: WideString): WideString;
+begin
+ Result := StartSession('anonymous', '', Ip);
+end;
+
+{*
+ Starts a user session.
+
+ @param Username Users username
+ @param Password Users password
+ @param Ip Users Ip-adress
+ @return Active session id
+ @throws EKTWSAPI_Exception KTWSAPI_ERR_SESSION_IN_USE
+ @throws EKTWSAPI_Exception Response message
+*}
+function TKTWSAPI.StartSession(Username, Password, Ip: WideString): WideString;
+var
+ response: kt_response;
+begin
+ if (FSession <> '') then
+ raise EKTWSAPI_Exception.Create(KTWSAPI_ERR_SESSION_IN_USE);
+ response := FSoapClient.login(Username, Password, Ip);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ FSession := response.message_;
+ Result := FSession;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Sets an active session.
+
+ @param Session Session id to activate
+ @param Ip Users Ip-adress
+ @return Active session id
+ @throws EKTWSAPI_Exception KTWSAPI_ERR_SESSION_IN_USE
+*}
+function TKTWSAPI.ActiveSession(Session, Ip: WideString): WideString;
+begin
+ if (FSession <> '') then
+ raise EKTWSAPI_Exception.Create(KTWSAPI_ERR_SESSION_IN_USE);
+ FSession := Session;
+ Result := FSession;
+end;
+
+{*
+ Closes an active session.
+
+ @return true
+*}
+function TKTWSAPI.Logout: Boolean;
+var
+ response: kt_response;
+begin
+ Result := System.False;
+
+ if (FSession = '') then
+ raise EKTWSAPI_Exception.Create(KTWSAPI_ERR_SESSION_NOT_STARTED);
+ response := FSoapClient.logout(FSession);
+ try
+ if (response.status_code <> 0) then
+ raise EKTWSAPI_Exception.Create(response.message_);
+ FSession := '';
+ Result := System.True;
+ finally
+ response.Free;
+ end;
+end;
+
+{*
+ Returns a reference to the root folder.
+
+ @return handle to folder
+*}
+function TKTWSAPI.GetRootFolder: TKTWSAPI_Folder;
+begin
+ Result := GetFolderById(1);
+end;
+
+{*
+ Returns a reference to a folder based on id.
+
+ @param FolderId Id of folder
+ @return handle to folder
+*}
+function TKTWSAPI.GetFolderById(FolderId: Integer): TKTWSAPI_Folder;
+begin
+ if FSession = '' then
+ raise EKTWSAPI_Exception.Create('A session is not active');
+ Result := TKTWSAPI_Folder.Get(Self, FolderId);
+end;
+
+{*
+ Returns a reference to a document based on id.
+
+ @param DocumentId Id of document
+ @return handle to document
+*}
+function TKTWSAPI.GetDocumentById(DocumentId: Integer): TKTWSAPI_Document;
+begin
+ if FSession = '' then
+ raise EKTWSAPI_Exception.Create('A session is not active');
+ Result := TKTWSAPI_Document.Get(Self, DocumentId)
+end;
+
+end.
diff --git a/ktwsapi/delphi/uwebservice.pas b/ktwsapi/delphi/uwebservice.pas
new file mode 100644
index 0000000..43b8035
--- /dev/null
+++ b/ktwsapi/delphi/uwebservice.pas
@@ -0,0 +1,701 @@
+{
+ Copyright (c) 2007, The Jam Warehouse Software (Pty) Ltd.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ i) Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ ii) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ iii) Neither the name of the The Jam Warehouse Software (Pty) Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ( INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+}
+
+{*
+ Unit auto-generated by delphi's wsdl imported
+
+ @Author Bjarte Kalstveit Vebjørnsen
+ @Version 1.0 BKV 24.09.2007 Initial revision
+*}
+
+// ************************************************************************ //
+// The types declared in this file were generated from data read from the
+// WSDL File described below:
+// WSDL : http://ktdms.trunk/ktwebservice/webservice.php?wsdl
+// Codegen : [wfDebug,wfGenerateWarnings,wfUseSerializerClassForAttrs]
+// Version : 1.0
+// (23.09.2007 21:20:12 - 1.33.2.6)
+// ************************************************************************ //
+
+unit uwebservice;
+
+interface
+
+uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
+
+type
+
+ // ************************************************************************ //
+ // The following types, referred to in the WSDL document are not being represented
+ // in this file. They are either aliases[@] of other types represented or were referred
+ // to but never[!] declared in the document. The types from the latter category
+ // typically map to predefined/known XML or Borland types; however, they could also
+ // indicate incorrect WSDL documents that failed to declare or import a schema type.
+ // ************************************************************************ //
+ // !:int - "http://www.w3.org/2001/XMLSchema"
+ // !:string - "http://www.w3.org/2001/XMLSchema"
+ // !:boolean - "http://www.w3.org/2001/XMLSchema"
+
+ kt_response = class; { "urn:KnowledgeTree" }
+ kt_folder_detail = class; { "urn:KnowledgeTree" }
+ kt_folder_item = class; { "urn:KnowledgeTree" }
+ kt_folder_contents = class; { "urn:KnowledgeTree" }
+ kt_document_detail = class; { "urn:KnowledgeTree" }
+ kt_metadata_selection_item = class; { "urn:KnowledgeTree" }
+ kt_metadata_field = class; { "urn:KnowledgeTree" }
+ kt_metadata_fieldset = class; { "urn:KnowledgeTree" }
+ kt_metadata_response = class; { "urn:KnowledgeTree" }
+ kt_document_transitions_response = class; { "urn:KnowledgeTree" }
+ kt_document_transaction_history_item = class; { "urn:KnowledgeTree" }
+ kt_linked_document = class; { "urn:KnowledgeTree" }
+ kt_linked_document_response = class; { "urn:KnowledgeTree" }
+ kt_document_transaction_history_response = class; { "urn:KnowledgeTree" }
+ kt_document_version_history_item = class; { "urn:KnowledgeTree" }
+ kt_document_version_history_response = class; { "urn:KnowledgeTree" }
+ kt_document_types_response = class; { "urn:KnowledgeTree" }
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_folder_detail = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fid: Integer;
+ Ffolder_name: WideString;
+ Fparent_id: Integer;
+ Ffull_path: WideString;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property id: Integer read Fid write Fid;
+ property folder_name: WideString read Ffolder_name write Ffolder_name;
+ property parent_id: Integer read Fparent_id write Fparent_id;
+ property full_path: WideString read Ffull_path write Ffull_path;
+ end;
+
+ kt_folder_items = array of kt_folder_item; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_folder_item = class(TRemotable)
+ private
+ Fid: Integer;
+ Fitem_type: WideString;
+ Ftitle: WideString;
+ Fcreator: WideString;
+ Fchecked_out_by: WideString;
+ Fmodified_by: WideString;
+ Ffilename: WideString;
+ Fsize: WideString;
+ Fmajor_version: WideString;
+ Fminor_version: WideString;
+ Fstorage_path: WideString;
+ Fmime_type: WideString;
+ Fmime_icon_path: WideString;
+ Fmime_display: WideString;
+ Fworkflow: WideString;
+ Fworkflow_state: WideString;
+ Fitems: kt_folder_items;
+ public
+ destructor Destroy; override;
+ published
+ property id: Integer read Fid write Fid;
+ property item_type: WideString read Fitem_type write Fitem_type;
+ property title: WideString read Ftitle write Ftitle;
+ property creator: WideString read Fcreator write Fcreator;
+ property checked_out_by: WideString read Fchecked_out_by write Fchecked_out_by;
+ property modified_by: WideString read Fmodified_by write Fmodified_by;
+ property filename: WideString read Ffilename write Ffilename;
+ property size: WideString read Fsize write Fsize;
+ property major_version: WideString read Fmajor_version write Fmajor_version;
+ property minor_version: WideString read Fminor_version write Fminor_version;
+ property storage_path: WideString read Fstorage_path write Fstorage_path;
+ property mime_type: WideString read Fmime_type write Fmime_type;
+ property mime_icon_path: WideString read Fmime_icon_path write Fmime_icon_path;
+ property mime_display: WideString read Fmime_display write Fmime_display;
+ property workflow: WideString read Fworkflow write Fworkflow;
+ property workflow_state: WideString read Fworkflow_state write Fworkflow_state;
+ property items: kt_folder_items read Fitems write Fitems;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_folder_contents = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Ffolder_id: Integer;
+ Ffolder_name: WideString;
+ Ffull_path: WideString;
+ Fitems: kt_folder_items;
+ public
+ destructor Destroy; override;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property folder_id: Integer read Ffolder_id write Ffolder_id;
+ property folder_name: WideString read Ffolder_name write Ffolder_name;
+ property full_path: WideString read Ffull_path write Ffull_path;
+ property items: kt_folder_items read Fitems write Fitems;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_detail = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Ftitle: WideString;
+ Fdocument_type: WideString;
+ Fversion: WideString;
+ Ffilename: WideString;
+ Fcreated_date: WideString;
+ Fcreated_by: WideString;
+ Fupdated_date: WideString;
+ Fupdated_by: WideString;
+ Fdocument_id: Integer;
+ Ffolder_id: Integer;
+ Fworkflow: WideString;
+ Fworkflow_state: WideString;
+ Fcheckout_by: WideString;
+ Ffull_path: WideString;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property title: WideString read Ftitle write Ftitle;
+ property document_type: WideString read Fdocument_type write Fdocument_type;
+ property version: WideString read Fversion write Fversion;
+ property filename: WideString read Ffilename write Ffilename;
+ property created_date: WideString read Fcreated_date write Fcreated_date;
+ property created_by: WideString read Fcreated_by write Fcreated_by;
+ property updated_date: WideString read Fupdated_date write Fupdated_date;
+ property updated_by: WideString read Fupdated_by write Fupdated_by;
+ property document_id: Integer read Fdocument_id write Fdocument_id;
+ property folder_id: Integer read Ffolder_id write Ffolder_id;
+ property workflow: WideString read Fworkflow write Fworkflow;
+ property workflow_state: WideString read Fworkflow_state write Fworkflow_state;
+ property checkout_by: WideString read Fcheckout_by write Fcheckout_by;
+ property full_path: WideString read Ffull_path write Ffull_path;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_metadata_selection_item = class(TRemotable)
+ private
+ Fid: Integer;
+ Fname_: WideString;
+ Fvalue: WideString;
+ Fparent_id: Integer;
+ published
+ property id: Integer read Fid write Fid;
+ property name_: WideString read Fname_ write Fname_;
+ property value: WideString read Fvalue write Fvalue;
+ property parent_id: Integer read Fparent_id write Fparent_id;
+ end;
+
+ kt_metadata_selection = array of kt_metadata_selection_item; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_metadata_field = class(TRemotable)
+ private
+ Fname_: WideString;
+ Frequired: Boolean;
+ Fvalue: WideString;
+ Fdescription: WideString;
+ Fcontrol_type: WideString;
+ Fselection: kt_metadata_selection;
+ public
+ destructor Destroy; override;
+ published
+ property name_: WideString read Fname_ write Fname_;
+ property required: Boolean read Frequired write Frequired;
+ property value: WideString read Fvalue write Fvalue;
+ property description: WideString read Fdescription write Fdescription;
+ property control_type: WideString read Fcontrol_type write Fcontrol_type;
+ property selection: kt_metadata_selection read Fselection write Fselection;
+ end;
+
+ kt_metadata_fields = array of kt_metadata_field; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_metadata_fieldset = class(TRemotable)
+ private
+ Ffieldset: WideString;
+ Fdescription: WideString;
+ Ffields: kt_metadata_fields;
+ public
+ destructor Destroy; override;
+ published
+ property fieldset: WideString read Ffieldset write Ffieldset;
+ property description: WideString read Fdescription write Fdescription;
+ property fields: kt_metadata_fields read Ffields write Ffields;
+ end;
+
+ kt_metadata_fieldsets = array of kt_metadata_fieldset; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_metadata_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fmetadata: kt_metadata_fieldsets;
+ public
+ destructor Destroy; override;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property metadata: kt_metadata_fieldsets read Fmetadata write Fmetadata;
+ end;
+
+ kt_document_transitions = array of WideString; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_transitions_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fmetadata: kt_document_transitions;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property metadata: kt_document_transitions read Fmetadata write Fmetadata;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_transaction_history_item = class(TRemotable)
+ private
+ Ftransaction_name: WideString;
+ Fusername: WideString;
+ Fversion: WideString;
+ Fcomment: WideString;
+ Fdatetime: WideString;
+ published
+ property transaction_name: WideString read Ftransaction_name write Ftransaction_name;
+ property username: WideString read Fusername write Fusername;
+ property version: WideString read Fversion write Fversion;
+ property comment: WideString read Fcomment write Fcomment;
+ property datetime: WideString read Fdatetime write Fdatetime;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_linked_document = class(TRemotable)
+ private
+ Fdocument_id: Integer;
+ Ftitle: WideString;
+ Fsize: Integer;
+ Fworkflow: WideString;
+ Fworkflow_state: WideString;
+ Flink_type: WideString;
+ published
+ property document_id: Integer read Fdocument_id write Fdocument_id;
+ property title: WideString read Ftitle write Ftitle;
+ property size: Integer read Fsize write Fsize;
+ property workflow: WideString read Fworkflow write Fworkflow;
+ property workflow_state: WideString read Fworkflow_state write Fworkflow_state;
+ property link_type: WideString read Flink_type write Flink_type;
+ end;
+
+ kt_linked_documents = array of kt_linked_document; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_linked_document_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fparent_document_id: WideString;
+ Flinks: kt_linked_documents;
+ public
+ destructor Destroy; override;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property parent_document_id: WideString read Fparent_document_id write Fparent_document_id;
+ property links: kt_linked_documents read Flinks write Flinks;
+ end;
+
+ kt_document_transaction_history = array of kt_document_transaction_history_item; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_transaction_history_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fhistory: kt_document_transaction_history;
+ public
+ destructor Destroy; override;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property history: kt_document_transaction_history read Fhistory write Fhistory;
+ end;
+
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_version_history_item = class(TRemotable)
+ private
+ Fuser: Integer;
+ Fmetadata_version: WideString;
+ Fcontent_version: WideString;
+ published
+ property user: Integer read Fuser write Fuser;
+ property metadata_version: WideString read Fmetadata_version write Fmetadata_version;
+ property content_version: WideString read Fcontent_version write Fcontent_version;
+ end;
+
+ kt_document_version_history = array of kt_document_version_history_item; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_version_history_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fhistory: kt_document_version_history;
+ public
+ destructor Destroy; override;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property history: kt_document_version_history read Fhistory write Fhistory;
+ end;
+
+ kt_document_types_array = array of WideString; { "urn:KnowledgeTree" }
+
+
+ // ************************************************************************ //
+ // Namespace : urn:KnowledgeTree
+ // ************************************************************************ //
+ kt_document_types_response = class(TRemotable)
+ private
+ Fstatus_code: Integer;
+ Fmessage_: WideString;
+ Fdocument_types: kt_document_types_array;
+ published
+ property status_code: Integer read Fstatus_code write Fstatus_code;
+ property message_: WideString read Fmessage_ write Fmessage_;
+ property document_types: kt_document_types_array read Fdocument_types write Fdocument_types;
+ end;
+
+
+ // ************************************************************************ //
+ // Namespace : http://schemas.xmlsoap.org/soap/envelope/
+ // soapAction: http://schemas.xmlsoap.org/soap/envelope/#KTWebService#%operationName%
+ // transport : http://schemas.xmlsoap.org/soap/http
+ // style : rpc
+ // binding : KnowledgeTreeBinding
+ // service : KnowledgeTreeService
+ // port : KnowledgeTreePort
+ // URL : http://ktdms.trunk/ktwebservice/webservice.php
+ // ************************************************************************ //
+ KnowledgeTreePort = interface(IInvokable)
+ ['{FA35CA60-1DC3-B3C7-6C65-BE4E3A6A8A22}']
+ function login(const username: WideString; const password: WideString; const ip: WideString): kt_response; stdcall;
+ function anonymous_login(const ip: WideString): kt_response; stdcall;
+ function logout(const session_id: WideString): kt_response; stdcall;
+ function get_folder_detail(const session_id: WideString; const folder_id: Integer): kt_folder_detail; stdcall;
+ function get_folder_detail_by_name(const session_id: WideString; const folder_name: WideString): kt_folder_detail; stdcall;
+ function get_folder_contents(const session_id: WideString; const folder_id: Integer; const depth: Integer; const what: WideString): kt_folder_contents; stdcall;
+ function create_folder(const session_id: WideString; const folder_id: Integer; const folder_name: WideString): kt_folder_detail; stdcall;
+ function delete_folder(const session_id: WideString; const folder_id: Integer; const reason: WideString): kt_response; stdcall;
+ function rename_folder(const session_id: WideString; const folder_id: Integer; const newname: WideString): kt_response; stdcall;
+ function get_document_links(const session_id: WideString; const document_id: Integer): kt_linked_document_response; stdcall;
+ function link_documents(const session_id: WideString; const parent_document_id: Integer; const child_document_id: Integer; const type_: WideString): kt_response; stdcall;
+ function unlink_documents(const session_id: WideString; const parent_document_id: Integer; const child_document_id: Integer): kt_response; stdcall;
+ function copy_folder(const session_id: WideString; const source_id: Integer; const target_id: Integer; const reason: WideString): kt_response; stdcall;
+ function move_folder(const session_id: WideString; const source_id: Integer; const target_id: Integer; const reason: WideString): kt_response; stdcall;
+ function get_document_detail(const session_id: WideString; const document_id: Integer): kt_document_detail; stdcall;
+ function checkin_document(const session_id: WideString; const document_id: Integer; const filename: WideString; const reason: WideString; const tempfilename: WideString; const major_update: Boolean): kt_response; stdcall;
+ function checkin_small_document(const session_id: WideString; const document_id: Integer; const filename: WideString; const reason: WideString; const base64: WideString; const major_update: Boolean): kt_response; stdcall;
+ function checkin_base64_document(const session_id: WideString; const document_id: Integer; const filename: WideString; const reason: WideString; const base64: WideString; const major_update: Boolean): kt_response; stdcall;
+ function add_document(const session_id: WideString; const folder_id: Integer; const title: WideString; const filename: WideString; const documentype: WideString; const tempfilename: WideString): kt_document_detail; stdcall;
+ function add_small_document(const session_id: WideString; const folder_id: Integer; const title: WideString; const filename: WideString; const documentype: WideString; const base64: WideString): kt_document_detail; stdcall;
+ function add_base64_document(const session_id: WideString; const folder_id: Integer; const title: WideString; const filename: WideString; const documentype: WideString; const base64: WideString): kt_document_detail; stdcall;
+ function get_document_detail_by_name(const session_id: WideString; const document_name: WideString; const what: WideString): kt_document_detail; stdcall;
+ function checkout_document(const session_id: WideString; const document_id: Integer; const reason: WideString): kt_response; stdcall;
+ function checkout_small_document(const session_id: WideString; const document_id: Integer; const reason: WideString; const download: Boolean): kt_response; stdcall;
+ function checkout_base64_document(const session_id: WideString; const document_id: Integer; const reason: WideString; const download: Boolean): kt_response; stdcall;
+ function undo_document_checkout(const session_id: WideString; const document_id: Integer; const reason: WideString): kt_response; stdcall;
+ function download_document(const session_id: WideString; const document_id: Integer): kt_response; stdcall;
+ function download_small_document(const session_id: WideString; const document_id: Integer): kt_response; stdcall;
+ function download_base64_document(const session_id: WideString; const document_id: Integer): kt_response; stdcall;
+ function delete_document(const session_id: WideString; const document_id: Integer; const reason: WideString): kt_response; stdcall;
+ function change_document_owner(const session_id: WideString; const document_id: Integer; const username: WideString; const reason: WideString): kt_response; stdcall;
+ function copy_document(const session_id: WideString; const document_id: Integer; const folder_id: Integer; const reason: WideString; const newtitle: WideString; const newfilename: WideString): kt_response; stdcall;
+ function move_document(const session_id: WideString; const document_id: Integer; const folder_id: Integer; const reason: WideString; const newtitle: WideString; const newfilename: WideString): kt_response; stdcall;
+ function rename_document_title(const session_id: WideString; const document_id: Integer; const newtitle: WideString): kt_response; stdcall;
+ function rename_document_filename(const session_id: WideString; const document_id: Integer; const newfilename: WideString): kt_response; stdcall;
+ function change_document_type(const session_id: WideString; const document_id: Integer; const documenttype: WideString): kt_response; stdcall;
+ function start_document_workflow(const session_id: WideString; const document_id: Integer; const workflow: WideString): kt_response; stdcall;
+ function delete_document_workflow(const session_id: WideString; const document_id: Integer): kt_response; stdcall;
+ function perform_document_workflow_transition(const session_id: WideString; const document_id: Integer; const transition: WideString; const reason: WideString): kt_response; stdcall;
+ function get_document_metadata(const session_id: WideString; const document_id: Integer): kt_metadata_response; stdcall;
+ function get_document_type_metadata(const session_id: WideString; const document_type: WideString): kt_metadata_response; stdcall;
+ function update_document_metadata(const session_id: WideString; const document_id: Integer; const metadata: kt_metadata_fieldsets): kt_response; stdcall;
+ function get_document_workflow_transitions(const session_id: WideString; const document_id: Integer): kt_document_transitions_response; stdcall;
+ function get_document_workflow_state(const session_id: WideString; const document_id: Integer): kt_response; stdcall;
+ function get_document_transaction_history(const session_id: WideString; const document_id: Integer): kt_document_transaction_history_response; stdcall;
+ function get_document_version_history(const session_id: WideString; const document_id: Integer): kt_document_version_history_response; stdcall;
+ function get_document_types(const session_id: WideString): kt_document_types_response; stdcall;
+ function get_document_link_types(const session_id: WideString): kt_document_types_response; stdcall;
+ end;
+
+function GetKnowledgeTreePort(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): KnowledgeTreePort;
+
+
+implementation
+
+function GetKnowledgeTreePort(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): KnowledgeTreePort;
+const
+ defWSDL = 'http://ktdms.trunk/ktwebservice/webservice.php?wsdl';
+ defURL = 'http://ktdms.trunk/ktwebservice/webservice.php';
+ defSvc = 'KnowledgeTreeService';
+ defPrt = 'KnowledgeTreePort';
+var
+ RIO: THTTPRIO;
+begin
+ Result := nil;
+ if (Addr = '') then
+ begin
+ if UseWSDL then
+ Addr := defWSDL
+ else
+ Addr := defURL;
+ end;
+ if HTTPRIO = nil then
+ RIO := THTTPRIO.Create(nil)
+ else
+ RIO := HTTPRIO;
+ try
+ Result := (RIO as KnowledgeTreePort);
+ if UseWSDL then
+ begin
+ RIO.WSDLLocation := Addr;
+ RIO.Service := defSvc;
+ RIO.Port := defPrt;
+ end else
+ RIO.URL := Addr;
+ finally
+ if (Result = nil) and (HTTPRIO = nil) then
+ RIO.Free;
+ end;
+end;
+
+
+destructor kt_folder_item.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fitems)-1 do
+ if Assigned(Fitems[I]) then
+ Fitems[I].Free;
+ SetLength(Fitems, 0);
+ inherited Destroy;
+end;
+
+destructor kt_folder_contents.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fitems)-1 do
+ if Assigned(Fitems[I]) then
+ Fitems[I].Free;
+ SetLength(Fitems, 0);
+ inherited Destroy;
+end;
+
+destructor kt_metadata_field.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fselection)-1 do
+ if Assigned(Fselection[I]) then
+ Fselection[I].Free;
+ SetLength(Fselection, 0);
+ inherited Destroy;
+end;
+
+destructor kt_metadata_fieldset.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Ffields)-1 do
+ if Assigned(Ffields[I]) then
+ Ffields[I].Free;
+ SetLength(Ffields, 0);
+ inherited Destroy;
+end;
+
+destructor kt_metadata_response.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fmetadata)-1 do
+ if Assigned(Fmetadata[I]) then
+ Fmetadata[I].Free;
+ SetLength(Fmetadata, 0);
+ inherited Destroy;
+end;
+
+destructor kt_linked_document_response.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Flinks)-1 do
+ if Assigned(Flinks[I]) then
+ Flinks[I].Free;
+ SetLength(Flinks, 0);
+ inherited Destroy;
+end;
+
+destructor kt_document_transaction_history_response.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fhistory)-1 do
+ if Assigned(Fhistory[I]) then
+ Fhistory[I].Free;
+ SetLength(Fhistory, 0);
+ inherited Destroy;
+end;
+
+destructor kt_document_version_history_response.Destroy;
+var
+ I: Integer;
+begin
+ for I := 0 to Length(Fhistory)-1 do
+ if Assigned(Fhistory[I]) then
+ Fhistory[I].Free;
+ SetLength(Fhistory, 0);
+ inherited Destroy;
+end;
+
+initialization
+ InvRegistry.RegisterInterface(TypeInfo(KnowledgeTreePort), 'http://schemas.xmlsoap.org/soap/envelope/', '');
+ InvRegistry.RegisterDefaultSOAPAction(TypeInfo(KnowledgeTreePort), 'http://schemas.xmlsoap.org/soap/envelope/#KTWebService#%operationName%');
+ InvRegistry.RegisterExternalParamName(TypeInfo(KnowledgeTreePort), 'link_documents', 'type_', 'type');
+ RemClassRegistry.RegisterXSClass(kt_response, 'urn:KnowledgeTree', 'kt_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSClass(kt_folder_detail, 'urn:KnowledgeTree', 'kt_folder_detail');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_folder_detail), 'message_', 'message');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_folder_items), 'urn:KnowledgeTree', 'kt_folder_items');
+ RemClassRegistry.RegisterXSClass(kt_folder_item, 'urn:KnowledgeTree', 'kt_folder_item');
+ RemClassRegistry.RegisterXSClass(kt_folder_contents, 'urn:KnowledgeTree', 'kt_folder_contents');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_folder_contents), 'message_', 'message');
+ RemClassRegistry.RegisterXSClass(kt_document_detail, 'urn:KnowledgeTree', 'kt_document_detail');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_document_detail), 'message_', 'message');
+ RemClassRegistry.RegisterXSClass(kt_metadata_selection_item, 'urn:KnowledgeTree', 'kt_metadata_selection_item');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_metadata_selection_item), 'name_', 'name');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_metadata_selection), 'urn:KnowledgeTree', 'kt_metadata_selection');
+ RemClassRegistry.RegisterXSClass(kt_metadata_field, 'urn:KnowledgeTree', 'kt_metadata_field');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_metadata_field), 'name_', 'name');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_metadata_fields), 'urn:KnowledgeTree', 'kt_metadata_fields');
+ RemClassRegistry.RegisterXSClass(kt_metadata_fieldset, 'urn:KnowledgeTree', 'kt_metadata_fieldset');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_metadata_fieldsets), 'urn:KnowledgeTree', 'kt_metadata_fieldsets');
+ RemClassRegistry.RegisterXSClass(kt_metadata_response, 'urn:KnowledgeTree', 'kt_metadata_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_metadata_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_document_transitions), 'urn:KnowledgeTree', 'kt_document_transitions');
+ RemClassRegistry.RegisterXSClass(kt_document_transitions_response, 'urn:KnowledgeTree', 'kt_document_transitions_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_document_transitions_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSClass(kt_document_transaction_history_item, 'urn:KnowledgeTree', 'kt_document_transaction_history_item');
+ RemClassRegistry.RegisterXSClass(kt_linked_document, 'urn:KnowledgeTree', 'kt_linked_document');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_linked_documents), 'urn:KnowledgeTree', 'kt_linked_documents');
+ RemClassRegistry.RegisterXSClass(kt_linked_document_response, 'urn:KnowledgeTree', 'kt_linked_document_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_linked_document_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_document_transaction_history), 'urn:KnowledgeTree', 'kt_document_transaction_history');
+ RemClassRegistry.RegisterXSClass(kt_document_transaction_history_response, 'urn:KnowledgeTree', 'kt_document_transaction_history_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_document_transaction_history_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSClass(kt_document_version_history_item, 'urn:KnowledgeTree', 'kt_document_version_history_item');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_document_version_history), 'urn:KnowledgeTree', 'kt_document_version_history');
+ RemClassRegistry.RegisterXSClass(kt_document_version_history_response, 'urn:KnowledgeTree', 'kt_document_version_history_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_document_version_history_response), 'message_', 'message');
+ RemClassRegistry.RegisterXSInfo(TypeInfo(kt_document_types_array), 'urn:KnowledgeTree', 'kt_document_types_array');
+ RemClassRegistry.RegisterXSClass(kt_document_types_response, 'urn:KnowledgeTree', 'kt_document_types_response');
+ RemClassRegistry.RegisterExternalPropName(TypeInfo(kt_document_types_response), 'message_', 'message');
+
+end.