<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://filesys.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tommygonk</id>
	<title>FileSys.Org Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://filesys.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tommygonk"/>
	<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php/Special:Contributions/Tommygonk"/>
	<updated>2026-10-07T04:09:59Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.4</generator>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=How_to_build_and_deploy_the_fileServersNG_subsystem&amp;diff=309</id>
		<title>How to build and deploy the fileServersNG subsystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=How_to_build_and_deploy_the_fileServersNG_subsystem&amp;diff=309"/>
		<updated>2026-07-09T15:24:40Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;fileServersNG is a replacement for the Alfresco file servers subsystem that uses the JFileServer code, and optionally JFileServer Enterprise add-on, to provide the file server capabilities for Alfresco (currently SMB and FTP/FTPS protocols). The fileServersNG subsystem is built as an AMP (Alfresco Module Package) that can then be deployed into an Alfresco Content Management Server setup.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG subsystem contains the JFileServer Enterprise add-on but requires a licence key to enable the additional functionality. With no valid licence key the file server subsystem will use the standard JFileServer protocols and functionality.&lt;br /&gt;
&lt;br /&gt;
There are Docker images available with Alfresco 5.x and 6.0 servers configures with the fileServersNG file server subsystem, for more details see [[Using the fileServersNG Docker Image|here]].&lt;br /&gt;
&lt;br /&gt;
== The fileServersNG v5 Subsystem ==&lt;br /&gt;
For Alfresco version v5.x, and v4.x, use the fileServersNG-v5 project to build the AMP.&lt;br /&gt;
&lt;br /&gt;
=== Building the fileServersNG v5 AMP ===&lt;br /&gt;
To build the fileServersNG-v5 AMP for use with Alfresco v5.x and v4.x.&lt;br /&gt;
&lt;br /&gt;
* Clone, or download the project zip file and unpack it, from the GitHub project at https://github.com/FileSysOrg/fileServersNG-v5.&lt;br /&gt;
* Get your Alfresco version number&lt;br /&gt;
One way to get the Alfresco version is to login using Share, click on the Alfresco logo at the bottom of the page, in the popup window you should see the Alfresco version, for example '5.2.f'.&lt;br /&gt;
* Edit the pom.xml&lt;br /&gt;
In the fileServersNG-v5 project folder edit the pom.xml file, set the &amp;lt;alfresco.platform.version&amp;gt; to match your Alfresco version.&lt;br /&gt;
* Build the AMP file&lt;br /&gt;
Using the command :-&lt;br /&gt;
&lt;br /&gt;
 mvn clean package&lt;br /&gt;
&lt;br /&gt;
This should generate the AMP file in the target/ folder with the name ''fileServersNG-v5-1.x.x.amp''.&lt;br /&gt;
&lt;br /&gt;
=== Deploying the fileServersNG v5 Subsystem ===&lt;br /&gt;
* Copy the fileServersNG-v5.1.x.x.amp file to the alfresco/amps folder of your Alfresco server setup&lt;br /&gt;
* Register the AMP using the following command&lt;br /&gt;
&lt;br /&gt;
 java -jar /alfresco/bin/alfresco-mmt.jar install &amp;lt;path-to-fileServersNG-amp-file&amp;gt; &amp;lt;path-to-alfresco-war-file&amp;gt; [-nobackup] [-force]&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;path-to-fileServersNG-amp-file&amp;gt; is the path to the fileServersNG-v5-1.x.x.amp file in the alfresco/amps folder, and &amp;lt;path-to-alfresco-war-file&amp;gt; is the path to the original Alfresco WAR file that was deployed to the web server. If you used the Alfresco installer this would usually be the tomcat/webapps/alfresco.war file.&lt;br /&gt;
&lt;br /&gt;
* Update your Alfresco configuration&lt;br /&gt;
Usually done via the alfresco-global.properties file.&lt;br /&gt;
Disable the original file servers subsystem using :-&lt;br /&gt;
&lt;br /&gt;
 cifs.enabled=false&lt;br /&gt;
 ftp.enabled=false&lt;br /&gt;
&lt;br /&gt;
Enable and configure the fileServersNG subsystem, for example :-&lt;br /&gt;
&lt;br /&gt;
 smb.enabled=true&lt;br /&gt;
 ftpng.enabled=true&lt;br /&gt;
 &lt;br /&gt;
 smb.tcpipSMB.port=1445&lt;br /&gt;
 smb.dialects=SMB1&lt;br /&gt;
 smb.sessionDebug=Negotiate,Socket&lt;br /&gt;
 &lt;br /&gt;
 ftp.port=1121&lt;br /&gt;
 ftp.sessionDebug=State,PktType&lt;br /&gt;
&lt;br /&gt;
==== Additional Setup For The JFileServer Enterprise Add-On ====&lt;br /&gt;
The JFileServer Enterprise add-on requires a valid licence key to enable it. Create the folder for the licence file at ''tomcat/shared/classes/license''. Copy your JFileServer licence file, named jfileserver.lic, into the ''tomcat/shared/classes/license'' folder.&lt;br /&gt;
&lt;br /&gt;
With the JFileServer Enterprise add-on the ''smb.dialects'' setting can also include ''SMB2 and ''SMB3 to enable the SMB2 protocol and SMB3 encryption. Use a comma delimited list of the SMB dialects to enable.&lt;br /&gt;
&lt;br /&gt;
== The fileServersNG v6 Subsystem ==&lt;br /&gt;
For Alfresco version v6.0 use the fileServersNG-v6 project to build the AMP.&lt;br /&gt;
&lt;br /&gt;
=== Building the fileServersNG v6 AMP ===&lt;br /&gt;
To build the fileServersNG-v6 AMP for use with Alfresco v6.0.&lt;br /&gt;
&lt;br /&gt;
* Clone, or download the project zip file and unpack it, from the GitHub project at https://github.com/FileSysOrg/fileServersNG-v6.&lt;br /&gt;
* Build the AMP file&lt;br /&gt;
Using the command :-&lt;br /&gt;
&lt;br /&gt;
 mvn clean package&lt;br /&gt;
&lt;br /&gt;
This should generate the AMP file in the target/ folder with the name ''fileServersNG-v6-1.x.x.amp''.&lt;br /&gt;
&lt;br /&gt;
=== Deploying the fileServersNG v6 Subsystem ===&lt;br /&gt;
* Copy the fileServersNG-v6.1.x.x.amp file to the alfresco/amps folder of your Alfresco server setup&lt;br /&gt;
* Register the AMP using the following command&lt;br /&gt;
&lt;br /&gt;
 java -jar /alfresco/bin/alfresco-mmt-6.0.jar install &amp;lt;path-to-fileServersNG-amp-file&amp;gt; &amp;lt;path-to-alfresco-webapp&amp;gt; [-nobackup] [-force]&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;path-to-fileServersNG-amp-file&amp;gt; is the path to the fileServersNG-v6-1.x.x.amp file in the alfresco/amps folder, and &amp;lt;path-to-alfresco-webapp&amp;gt; is the path to the Alfresco webapp folder on the web server.&lt;br /&gt;
&lt;br /&gt;
Alfresco v6.x uses a containerised setup where a number of Docker images run the Alfresco repository, database server, indexing service and Share UI. See the wiki page about running the fileServersNG-v6 Docker image for details on how to run and configure the fileServersNG-v6 file servers subsystem [[Using the fileServersNG Docker Images#fileServersNG v6|here]].&lt;br /&gt;
&lt;br /&gt;
== The fileServersNG v6.1 Subsystem ==&lt;br /&gt;
For Alfresco version v6.1 use the fileServersNG-v61 project to build the AMP.&lt;br /&gt;
&lt;br /&gt;
=== Building the fileServersNG v6.1 AMP ===&lt;br /&gt;
To build the fileServersNG-v61 AMP for use with Alfresco v6.1.&lt;br /&gt;
&lt;br /&gt;
* Clone, or download the project zip file and unpack it, from the GitHub project at https://github.com/FileSysOrg/fileServersNG-v61.&lt;br /&gt;
* Build the AMP file&lt;br /&gt;
Using the command :-&lt;br /&gt;
&lt;br /&gt;
 mvn clean package&lt;br /&gt;
&lt;br /&gt;
This should generate the AMP file in the target/ folder with the name ''fileserversng-v61-1.x.x.amp''.&lt;br /&gt;
&lt;br /&gt;
=== Deploying the fileServersNG v6.1 Subsystem ===&lt;br /&gt;
* Copy the fileserversng-v6.1.x.x.amp file to the alfresco/amps folder of your Alfresco server setup&lt;br /&gt;
* Register the AMP using the following command&lt;br /&gt;
&lt;br /&gt;
 java -jar /alfresco/bin/alfresco-mmt-6.0.jar install &amp;lt;path-to-fileServersNG-amp-file&amp;gt; &amp;lt;path-to-alfresco-webapp&amp;gt; [-nobackup] [-force]&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;path-to-fileServersNG-amp-file&amp;gt; is the path to the fileserversng-v6-1.x.x.amp file in the alfresco/amps folder, and &amp;lt;path-to-alfresco-webapp&amp;gt; is the path to the Alfresco webapp folder on the web server.&lt;br /&gt;
&lt;br /&gt;
Alfresco v6.x uses a containerised setup where a number of Docker images run the Alfresco repository, database server, indexing service and Share UI. See the wiki page about running the fileServersNG-v61 Docker image for details on how to run and configure the fileServersNG-v61 file servers subsystem [[Using the fileServersNG Docker Images#fileServersNG v61|here]].&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Configuring_JFileServer&amp;diff=308</id>
		<title>Configuring JFileServer</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Configuring_JFileServer&amp;diff=308"/>
		<updated>2026-06-26T08:13:14Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: /* SMB Server Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;JFileServer file server is configured using a simple XML file, the same configuration format is used by the Enterprise version of the file server.&lt;br /&gt;
&lt;br /&gt;
The configuration is contained within the &amp;lt;fileserver&amp;gt; main section with various sub-sections to configure which file server protocols are enabled, configuration for each protocol, security and debug logging. Here's an overview of the XML configuration file :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;fileserver&amp;gt;&lt;br /&gt;
     &amp;lt;servers&amp;gt;...&amp;lt;/servers&amp;gt;&lt;br /&gt;
     &amp;lt;SMB&amp;gt;...&amp;lt;/SMB&amp;gt;&lt;br /&gt;
     &amp;lt;FTP&amp;gt;...&amp;lt;/FTP&amp;gt;&lt;br /&gt;
     &amp;lt;NFS&amp;gt;...&amp;lt;/NFS&amp;gt;&lt;br /&gt;
     &amp;lt;shares&amp;gt;...&amp;lt;/shares&amp;gt;&lt;br /&gt;
     &amp;lt;debug&amp;gt;...&amp;lt;/debug&amp;gt;&lt;br /&gt;
     &amp;lt;security&amp;gt;...&amp;lt;/security&amp;gt;&lt;br /&gt;
     &amp;lt;licence&amp;gt;...&amp;lt;/licence&amp;gt;&lt;br /&gt;
     &amp;lt;server-core...&amp;lt;/server-core&amp;gt;&lt;br /&gt;
 &amp;lt;/fileserver&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Environment variables may be used in attributes and values within the XML configuration using the syntax ''${env-var-name}''.&lt;br /&gt;
&lt;br /&gt;
Some configuration settings allow an optional ''platforms=&amp;quot;...&amp;quot;'' attribute, this allows a configuration to be used on multiple platforms. If the current platform that the JFileServer is running on is not listed in the ''platforms=&amp;quot;...&amp;quot;'' list then the setting will be ignored.&lt;br /&gt;
&lt;br /&gt;
The available platform values are Windows, Linux, MacOSX and Solaris. The platforms value is a comma delimited list of valid platforms for the current setting.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;server&amp;gt; configuration section is used to enable or disable which file server protocols are available. The syntax has changed from the JLAN configuration as each protocol now has an ''enable=&amp;quot;true|false&amp;quot;'' attribute, this makes it easier to use an environment variable to control whether a particular file server protocol is enabled.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;servers&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;servers&amp;gt;&lt;br /&gt;
     &amp;lt;SMB enable=&amp;quot;true|false&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;FTP enable=&amp;quot;true|false&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;NFS enable=&amp;quot;true|false&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/servers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SMB Server Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB&amp;gt; configuration section is used to configure the SMB protocol server that allows a drive or mount to be mapped to the JFileServer file server which can then be accessed as if it were a local drive on the client system.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;SMB&amp;gt;&lt;br /&gt;
     &amp;lt;host&amp;gt;&lt;br /&gt;
         &amp;lt;broadcast&amp;gt;...&amp;lt;/broadcast&amp;gt;&lt;br /&gt;
         &amp;lt;smbdialects&amp;gt;...&amp;lt;/smbdialects&amp;gt;&lt;br /&gt;
         &amp;lt;comment&amp;gt;...&amp;lt;/comment&amp;gt;&lt;br /&gt;
         &amp;lt;netBIOSSMB .../&amp;gt;&lt;br /&gt;
         &amp;lt;tcpipSMB .../&amp;gt;&lt;br /&gt;
         &amp;lt;hostAnnounce .../&amp;gt;&lt;br /&gt;
         &amp;lt;idleCheckOpenFiles/&amp;gt;&lt;br /&gt;
     &amp;lt;/host&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;requireSigning/&amp;gt;&lt;br /&gt;
     &amp;lt;disableEncryption/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;authenticator ...&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
     &amp;lt;/authenticator&amp;gt;&lt;br /&gt;
     &amp;lt;sessionDebug .../&amp;gt;&lt;br /&gt;
  &amp;lt;/SMB&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The JLAN XML configuration has &amp;lt;Win32NetBIOS/&amp;gt; and &amp;lt;Win32Announce/&amp;gt; configuration options, these are currently ignored by JFileServer as the Win32 NetBIOS legacy code has been moved out into a seperate add-on project. With most clients using native SMB connections on port 445, and SMB2/SMB3 connections requiring native SMB connections, there are only a small number of special cases where the Win32 NetBIOS interface is of use.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;requireSigning/&amp;gt; configuration setting indicates that the server will only accept SMB2 connections that have signing enabled. It is only currently relevant when the SMB2 dialect is enabled.&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;host&amp;gt; Configuration Section ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;host&amp;gt; sub-section contains the main networking and protocol configuration settings.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;broadcast&amp;gt; setting specifies the network broadcast mask that is required to send broadcast datagrams, used by the NetBIOS protocol and host announcement. JFileServer now accepts the setting of 'AUTO' where the broadcast mask will be determined automatically. In some cases this may not work, you will then need to specify the broadcast mask. For eample if your network addresses are in the 192.168.1.x/8 range the broadcast mask would be 192.168.1.255.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;smbdialects&amp;gt; setting configures which SMB dialects the file server will negotiate with a client. The value should be a comma delimited list of dialect names. The high level dialect names available are SMB1 for the standard server, plus SMB2 and SMB3 for the Enterprise server.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;comment&amp;gt; setting provides a comment that is visible to clients when displaying the server properties.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;netBIOSSMB .../&amp;gt; setting configures the SMB file server to use the TCPIP socket based NetBIOS protocol. The default setting of &amp;lt;netBIOSSMB/&amp;gt; will enable the TCPIP NetBIOS interface using TCP port 139 and UDP ports 137 and 138. These settings can be overridden using the sessionPort=&amp;quot;...&amp;quot;, namingPort=&amp;quot;...&amp;quot; and datagramPort=&amp;quot;...&amp;quot; attributes. For example, if running  JFileServer on a linux or Mac system as a normal user the server will not be able to bind the privileged ports 137/138/139, so we may use the following configuration and use firewall rules to forward the network traffic to the unprivileged ports :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;netBIOSSMB sessionPort=&amp;quot;1139&amp;quot; namingPort=&amp;quot;1137&amp;quot; datagramPort=&amp;quot;1138&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An optional platforms=&amp;quot;...&amp;quot; attribute may be used for the NetBIOS SMB setting.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tcpipSMB&amp;gt; setting configures the SMB file server to use the native SMB socket based protocol. The default setting of &amp;lt;tcpipSMB/&amp;gt; will enable the native SMB interface using TCP port 445. This setting can be overridden using the port=&amp;quot;...&amp;quot; attribute. For example, if running JFileServer on a linux or Mac system as a normal user the server will not be able to bind the privileged port 445, so we may use the following configuration and use firewall rules to forward the network traffic to the unprivileged port :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tcpipSMB port=&amp;quot;1445&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An optional platforms=&amp;quot;...&amp;quot; attribute may be used for the TCPIP SMB setting.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;hostAnnounce .../&amp;gt; setting is used to enable the TCPIP NetBIOS host announcer that periodically broadcasts the server details to the local network. This allows the server to show up in the local network list or workgroup.&lt;br /&gt;
&lt;br /&gt;
The default host announcement is broadcast every minute, the announcement interval can be set using the optional interval=&amp;quot;...&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;idleCheckOpenFiles/&amp;gt; setting is used to prevent sessions with open files from being removed when the idle session check is run to remove sessions that have not had any I/O within the session timeout interval (default 15 minutes).&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;authenticator&amp;gt; Configuration Section ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;authenticator type=&amp;quot;...&amp;quot;&amp;gt; section configures how the SMB server handles user authentication. The optional type=&amp;quot;...&amp;quot; attribute can have the values &amp;quot;enterprise&amp;quot; or &amp;quot;local&amp;quot;, or it is possible to specify your own authenticator class. The enterprise authenticator setting provides the latest authentication methods such as NTLMv2 and Kerberos via the NTLMSSP and SPNEGO mechanisms. The local authenticator setting provides support for older LanMan and NTLMv1 authentication, these are considered to be insecure these days so it is recommended to use the &amp;quot;enterprise&amp;quot; setting.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;enterprise&amp;quot; setting the authenticator configuration has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;authenticator type=&amp;quot;enterprise&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;disableNTLM/&amp;gt;&lt;br /&gt;
     &amp;lt;useSPNEGO/&amp;gt;&lt;br /&gt;
     &amp;lt;disallowNTLMv1&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
     &amp;lt;-- Kerberos related settings --&amp;gt;&lt;br /&gt;
     &amp;lt;Realm&amp;gt;...&amp;lt;/Realm&amp;gt;&lt;br /&gt;
     &amp;lt;Password&amp;gt;...&amp;lt;/Password&amp;gt;&lt;br /&gt;
     &amp;lt;LoginEntry&amp;gt;...&amp;lt;/LoginEntry&amp;gt;&lt;br /&gt;
     &amp;lt;kerberosDebug/&amp;gt;&lt;br /&gt;
     &amp;lt;KerberosConfig&amp;gt;...&amp;lt;/KerberosConfig&amp;gt;&lt;br /&gt;
     &amp;lt;LoginConfig&amp;gt;...&amp;lt;/LoginConfig&amp;gt;&lt;br /&gt;
 &amp;lt;/authenticator&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default the Enterprise authenticator enables NTLM logons, either NTLMv1 or NTLMv2. To only allow the more secure NTLMv2 logons use the &amp;lt;disallowNTLMv1&amp;gt; configuration setting.&lt;br /&gt;
&lt;br /&gt;
To enable Kerberos logons to the SMB file server the &amp;lt;Realm&amp;gt;, &amp;lt;Password&amp;gt; and &amp;lt;LoginEntry&amp;gt; values are required. The &amp;lt;Realm&amp;gt; setting should contain the Kerberos realm, usually the domain name in uppercase. The &amp;lt;Password&amp;gt; setting is used to access the server Kerberos setup. The &amp;lt;LoginEntry&amp;gt; setting specifies the Java JAAS login entry name to use for the SMB server service logon, the default value is ''FileServerSMB''.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;kerberosDebug/&amp;gt; setting is a convenience setting that enables various Java debug output levels by setting the required properties.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;KerberosConfig&amp;gt; setting allows a JFileServer specific Kerberos configuration file to be used. The setting takes the full path to the Kerberos configuration file. This is the equivalent of using the Java property ''java.security.krb5.conf''.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;LoginConfig&amp;gt; setting allows a JFileServer specific Java login configuration file to be used without editing the global Java security settings file. The setting takes the full path to the login configuration file. This is the equivalent of using the Java property ''java.security.auth.login.config''. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;useSPNEGO/&amp;gt; setting enables the use of SPNEGO (Simple Protected NEGOtiation) as well as the default NTLMSSP. If you have enabled Kerberos logons then SPNEGO will be enabled automatically.&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;sessionDebug&amp;gt; Configuration Setting ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;sessionDebug flags=&amp;quot;...&amp;quot;/&amp;gt; setting is used to enable SMB server debug output. The flags=&amp;quot;...&amp;quot; value is a comma delimited list of debug output level names from the following list :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| PKTTYPE&lt;br /&gt;
| Received packet type&lt;br /&gt;
|-&lt;br /&gt;
| STATE&lt;br /&gt;
| Session state changes&lt;br /&gt;
|-&lt;br /&gt;
| RXDATA&lt;br /&gt;
| Dump received data packet&lt;br /&gt;
|-&lt;br /&gt;
| TXDATA&lt;br /&gt;
| Dump sent packet data&lt;br /&gt;
|-&lt;br /&gt;
| DUMPDATA&lt;br /&gt;
| Dump data packets&lt;br /&gt;
|-&lt;br /&gt;
| NEGOTIATE&lt;br /&gt;
| Protocol negotiate phase&lt;br /&gt;
|-&lt;br /&gt;
| TREE&lt;br /&gt;
| Tree connection/disconnection&lt;br /&gt;
|-&lt;br /&gt;
| SEARCH&lt;br /&gt;
| File/directory searches&lt;br /&gt;
|-&lt;br /&gt;
| INFO&lt;br /&gt;
| File/directory information requests&lt;br /&gt;
|-&lt;br /&gt;
| FILE&lt;br /&gt;
| File open/close/information requests&lt;br /&gt;
|-&lt;br /&gt;
| FILEIO&lt;br /&gt;
| File read/write&lt;br /&gt;
|-&lt;br /&gt;
| TRAN&lt;br /&gt;
| SMB transactions&lt;br /&gt;
|-&lt;br /&gt;
| ECHO&lt;br /&gt;
| Echo requests&lt;br /&gt;
|-&lt;br /&gt;
| ERROR&lt;br /&gt;
| Errors returned to the client&lt;br /&gt;
|-&lt;br /&gt;
| IPC&lt;br /&gt;
| IPC$ named pipe requests&lt;br /&gt;
|-&lt;br /&gt;
| LOCK&lt;br /&gt;
| Lock/unlock requests&lt;br /&gt;
|-&lt;br /&gt;
| DCERPC&lt;br /&gt;
| DCE/RPC request processing&lt;br /&gt;
|-&lt;br /&gt;
| STATECACHE&lt;br /&gt;
| File state cache&lt;br /&gt;
|-&lt;br /&gt;
| TIMING&lt;br /&gt;
| Time packet processing&lt;br /&gt;
|-&lt;br /&gt;
| NOTIFY&lt;br /&gt;
| Asynchronous change notifications&lt;br /&gt;
|-&lt;br /&gt;
| STREAMS&lt;br /&gt;
| NTFS streams handling&lt;br /&gt;
|-&lt;br /&gt;
| SOCKET&lt;br /&gt;
| Socket connections&lt;br /&gt;
|-&lt;br /&gt;
| PKTPOOL&lt;br /&gt;
| Memory pool allocate/release&lt;br /&gt;
|-&lt;br /&gt;
| PKTSTATS&lt;br /&gt;
| Memory pool statistics&lt;br /&gt;
|-&lt;br /&gt;
| THREADPOOL&lt;br /&gt;
| Thread pool handling&lt;br /&gt;
|-&lt;br /&gt;
| BENCHMARK&lt;br /&gt;
| Benchmarking requests&lt;br /&gt;
|-&lt;br /&gt;
| OPLOCK&lt;br /&gt;
| Opportunistic lock handling&lt;br /&gt;
|-&lt;br /&gt;
| PKTALLOC&lt;br /&gt;
| Memory pool handling&lt;br /&gt;
|-&lt;br /&gt;
| COMPOUND&lt;br /&gt;
| Compound request handling (Enterprise only)&lt;br /&gt;
|-&lt;br /&gt;
| CANCEL&lt;br /&gt;
| Cancel request handling (Enterprise only)&lt;br /&gt;
|-&lt;br /&gt;
| SIGNING&lt;br /&gt;
| Packet signing (Enterprise only)&lt;br /&gt;
|-&lt;br /&gt;
| ENCRYPTION&lt;br /&gt;
| Encryption handling (Enterprise only)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, to enable SMB server debug output to help with logon and connection issues you could use the following setting :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;sessionDebug flags=&amp;quot;Negotiate,Socket,State,Error&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SMB2/SMB3 Configuration ===&lt;br /&gt;
&lt;br /&gt;
There are SMB2 and SMB3 specific configuration values within the &amp;lt;server-core&amp;gt; configuration section, which is separate to the &amp;lt;SMB&amp;gt; configuration section. SMB2 and SMB3 are only available when using the JFileServer Enterprise file server.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;server-core&amp;gt; configuration section has the following syntax, all settings are optional :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;server-core&amp;gt;&lt;br /&gt;
     &amp;lt;SMB2&amp;gt;&lt;br /&gt;
         &amp;lt;maxPacketSize&amp;gt;2M&amp;lt;/maxPacketSize&amp;gt;&lt;br /&gt;
         &amp;lt;requireSigning/&amp;gt;&lt;br /&gt;
     &amp;lt;/SMB2&amp;gt;&lt;br /&gt;
     &amp;lt;SMB3&amp;gt;&lt;br /&gt;
         &amp;lt;encryptionTypes&amp;gt;CCM,GCM&amp;lt;/encryptionTypes&amp;gt;&lt;br /&gt;
         &amp;lt;disableEncryption/&amp;gt;&lt;br /&gt;
         &amp;lt;useAESProvider&amp;gt;SunJCE&amp;lt;/useAESProvider&amp;gt;&lt;br /&gt;
     &amp;lt;/SMB3&amp;gt;&lt;br /&gt;
 &amp;lt;/server-core&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB2&amp;gt; &amp;lt;maxPacketSize&amp;gt; setting sets the maximum packet size that the server will negotiate with the client. The value can be specified as 'nM' for megabytes, or 'nK' for kilobytes or as the number of bytes. Most clients will use a value between 2 to 8 megabytes.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB2&amp;gt; &amp;lt;requireSigning/&amp;gt; setting forces clients to use SMB2 signing. If the client does not support SMB2 signing the session connection will be rejected.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB3&amp;gt; &amp;lt;encryptionTypes&amp;gt; value specifies which SMB3 encryption types are enabled, and the preferred order as a comma delimited list. The valid values are 'GCM' for AES/GCM/128 bit and 'CCM' for AES/CCM/128 bit.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB3&amp;gt; &amp;lt;disableEncryption/&amp;gt; setting will allow an SMB3 connection without encryption to be established with the server.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;SMB3&amp;gt; &amp;lt;useAESProvider&amp;gt; setting is used to specify the name of the JCE provider that will be used by the AES/GCM/128 bit encryption mode. Using a value of 'SunJCE' will use the Sun/Oracle/OpenJDK hardware accelerated implementation. The default setting will use the BouncyCastle JCE provider which only provides a software based implementation of the AES/GCM cipher.&lt;br /&gt;
&lt;br /&gt;
== FTP Server Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;FTP&amp;gt; configuration section is used to configure the FTP protocol server that allows a client to connect using any FTP client application. A standard FTP connection sends plaintext commands, and details including username and password, so it is recommended to use FTPS so that the commands are sent over an encrypted SSL connection.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;FTP&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;FTP&amp;gt;&lt;br /&gt;
     &amp;lt;port&amp;gt;...&amp;lt;/port&amp;gt;&lt;br /&gt;
     &amp;lt;allowAnonymous/&amp;gt;&lt;br /&gt;
     &amp;lt;debug .../&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
     &amp;lt;!-- FTPS support --&amp;gt;&lt;br /&gt;
     &amp;lt;keyStore&amp;gt;...&amp;lt;/keyStore&amp;gt;&lt;br /&gt;
     &amp;lt;keyStoreType&amp;gt;...&amp;lt;/keyStoreType&amp;gt;&lt;br /&gt;
     &amp;lt;keyStorePassphrase&amp;gt;...&amp;lt;/keyStorePassphrase&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
     &amp;lt;requireSecureSession&amp;gt;&lt;br /&gt;
     &amp;lt;sslEngineDebug/&amp;gt;&lt;br /&gt;
 &amp;lt;/FTP&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;port&amp;gt; setting defines the port that the FTP server will listen for connections on, if not specified the default FTP port of 21 will be used. If running JFileServer file server as a normal user on a linux or Mac system you will need to use a non-privileged port, 1024 or above.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;allowAnonymous/&amp;gt; setting specifies that anonymous guest logons are allowed to the FTP server.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;debug flags=&amp;quot;...&amp;quot;/&amp;gt; setting is used to enable FTP server debug output. The flags=&amp;quot;...&amp;quot; value is a comma delimited list of debug output level names from the following list :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| STATE&lt;br /&gt;
| Session state changes&lt;br /&gt;
|-&lt;br /&gt;
| RXDATA&lt;br /&gt;
| Dump received data packet&lt;br /&gt;
|-&lt;br /&gt;
| TXDATA&lt;br /&gt;
| Dump sent packet data&lt;br /&gt;
|-&lt;br /&gt;
| DUMPDATA&lt;br /&gt;
| Dump data packets&lt;br /&gt;
|-&lt;br /&gt;
| SEARCH&lt;br /&gt;
| File/directory searches&lt;br /&gt;
|-&lt;br /&gt;
| INFO&lt;br /&gt;
| Information requests&lt;br /&gt;
|-&lt;br /&gt;
| FILE&lt;br /&gt;
| File open/close/information requests&lt;br /&gt;
|-&lt;br /&gt;
| FILEIO&lt;br /&gt;
| File read/write requests&lt;br /&gt;
|-&lt;br /&gt;
| ERROR&lt;br /&gt;
| Errors sent back to the client&lt;br /&gt;
|-&lt;br /&gt;
| PKTTYPE&lt;br /&gt;
| Received packet type&lt;br /&gt;
|-&lt;br /&gt;
| TIMING&lt;br /&gt;
| Time packet processing&lt;br /&gt;
|-&lt;br /&gt;
| DATAPORT&lt;br /&gt;
| Data port handling&lt;br /&gt;
|-&lt;br /&gt;
| DIRECTORY&lt;br /&gt;
| Directory commands&lt;br /&gt;
|-&lt;br /&gt;
| SSL&lt;br /&gt;
| Secure sessions&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FTPS Server Configuration ===&lt;br /&gt;
&lt;br /&gt;
The FTP server allows connections to switch into secure SSL mode after connecting to the configured FTP server port.&lt;br /&gt;
&lt;br /&gt;
To enable FTPS we need to create a keystore for the SSL connections. To create a keystore using the JKS format keystore type use the following commands, filling in the required details when prompted :-&lt;br /&gt;
&lt;br /&gt;
 $ keytool -genkeypair -alias jfsftp -keyalg RSA -keystore FTPSKeyStore&lt;br /&gt;
                &lt;br /&gt;
 Enter keystore password: &lt;br /&gt;
 Re-enter new password:&lt;br /&gt;
 What is your first and last name?&lt;br /&gt;
 [Unknown]: Your Name&lt;br /&gt;
 What is the name of your organizational unit?&lt;br /&gt;
 [Unknown]: OrgUnit&lt;br /&gt;
 What is the name of your organization?&lt;br /&gt;
 [Unknown]: Company&lt;br /&gt;
 What is the name of your City or Locality?&lt;br /&gt;
 [Unknown]: City&lt;br /&gt;
 What is the name of your State or Province?&lt;br /&gt;
 [Unknown]: Province&lt;br /&gt;
 What is the two-letter country code for this unit?&lt;br /&gt;
 [Unknown]: CC&lt;br /&gt;
 Is CN=You Name, OU=OrgUnit, O=Company, L=City, ST=Province, C=CC correct?&lt;br /&gt;
 [no]:yes&lt;br /&gt;
 &lt;br /&gt;
 Enter key password for &amp;lt;client&amp;gt;&lt;br /&gt;
 (RETURN if same as keystore password): &lt;br /&gt;
 Re-enter new password:&lt;br /&gt;
&lt;br /&gt;
You can now fill in the JFileServer configuration to enable FTPS :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!-- FTPS support --&amp;gt;&lt;br /&gt;
 &amp;lt;keyStore&amp;gt;/path/to/FTPSKeyStore&amp;lt;/keyStore&amp;gt;&lt;br /&gt;
 &amp;lt;keyStoreType&amp;gt;JKS&amp;lt;/keyStoreType&amp;gt;&lt;br /&gt;
 &amp;lt;keyStorePassphrase&amp;gt;keystore-password&amp;lt;/keyStorePassphrase&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The &amp;lt;requireSecureSession/&amp;gt; configuration setting will only allow connections that use the FTP SSL mode to logon.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;sslEngineDebug/&amp;gt; setting is used to enable additional debug output from the Java JSSE SSL session processing.&lt;br /&gt;
&lt;br /&gt;
== NFS Server Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;NFS&amp;gt; configuration section is used to configure the NFS protocol server that allows a client to mount a JFileServer filesystem which can then be accessed as if it were on a local drive on the client system.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;NFS&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;NFS&amp;gt;&lt;br /&gt;
     &amp;lt;enablePortMapper/&amp;gt;&lt;br /&gt;
     &amp;lt;disablePortMapperRegistration/&amp;gt;&lt;br /&gt;
     &amp;lt;PortMapperPort&amp;gt;...&amp;lt;/PortMapperPort&amp;gt;&lt;br /&gt;
     &amp;lt;MountServerPort&amp;gt;...&amp;lt;/MountServerPort&amp;gt;&lt;br /&gt;
     &amp;lt;NFSServerPort&amp;gt;...&amp;lt;/NFSServerPort&amp;gt;&lt;br /&gt;
     &amp;lt;RPCRegisterPort&amp;gt;...&amp;lt;/RPCRegisterPort&amp;gt;&lt;br /&gt;
     &amp;lt;rpcAuthenticator&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
     &amp;lt;/rpcAuthenticator&amp;gt;&lt;br /&gt;
     &amp;lt;debug .../&amp;gt;&lt;br /&gt;
     &amp;lt;mountServerDebug/&amp;gt;&lt;br /&gt;
     &amp;lt;portMapperDebug/&amp;gt;&lt;br /&gt;
     &amp;lt;FileCache&amp;gt;...&amp;lt;/FileCache&amp;gt;&lt;br /&gt;
     &amp;lt;fileCacheDebug/&amp;gt;&lt;br /&gt;
 &amp;lt;/NFS&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO:''' NFS configuration settings&lt;br /&gt;
&lt;br /&gt;
== Shares Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;shares&amp;gt; configuration section is used to define the virtual filesystems that are available to the various protocol servers.&lt;br /&gt;
&lt;br /&gt;
A virtual filesystem requires a ''driver'' class that implements the core filesystem interface, plus optional interfaces for advanced features.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;shares&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;shares&amp;gt;&lt;br /&gt;
     &amp;lt;diskshare name=&amp;quot;...&amp;quot; comment=&amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;driver&amp;gt;&lt;br /&gt;
             &amp;lt;class&amp;gt;...&amp;lt;/class&amp;gt;&lt;br /&gt;
             ...&lt;br /&gt;
         &amp;lt;/driver&amp;gt;&lt;br /&gt;
     &amp;lt;/diskshare&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;diskshare name-&amp;quot;...&amp;quot; comment=&amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;lt;/diskshare&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
 &amp;lt;/shares&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Multiple virtual filesystems can be defined each using a seperate &amp;lt;diskshare&amp;gt; configuration section. The virtual filesystems can use different driver classes. Each driver class can have its own set of configuration items. Each &amp;lt;diskshare&amp;gt; definition must have a unique name, and can have an optional comment.&lt;br /&gt;
&lt;br /&gt;
There are a number of virtual filesystems included in the JFileServer jar file. The ''org.filesys.smb.server.disk.JavaNIODiskDriver'' virtual filesystem uses the Java I/O classes to create a network filesystem that is mapped to a folder on the local filesystem.&lt;br /&gt;
&lt;br /&gt;
=== JavaNIODiskDriver Configuration ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;driver&amp;gt; configuration section for the ''org.filesys.smb.server.disk.JavaNIODiskDriver'' virtual filesystem has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;driver&amp;gt;&lt;br /&gt;
     &amp;lt;!-- Required configuration values --&amp;gt;&lt;br /&gt;
     &amp;lt;class&amp;gt;org.filesys.smb.server.disk.JavaNIODiskDriver&amp;lt;/class&amp;gt;&lt;br /&gt;
     &amp;lt;LocalPath&amp;gt;...&amp;lt;/LocalPath&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;!-- Optional configuration values --&amp;gt;&lt;br /&gt;
     &amp;lt;LargeFileSize&amp;gt;...&amp;lt;/LargeFileSize&amp;gt;&lt;br /&gt;
     &amp;lt;TrashcanPath&amp;gt;...&amp;lt;/TrashcanPath&amp;gt;&lt;br /&gt;
     &amp;lt;Debug/&amp;gt;&lt;br /&gt;
 &amp;lt;/driver&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;LocalPath&amp;gt; setting specifies the local path of the folder to be shared, the folder must exist. The path may be an absolute path or a relative path, for example a path of ''./''.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;LargeFileSize&amp;gt; setting specifies the file size where file delete and truncate operations are performed using a background thread to help with server response. The file size can be specified as bytes, or ''nK'' for kilobytes, ''nM'' for megabytes, ''nG'' for gigabytes.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;TrashCanPath&amp;gt; setting specifies the folder to be used for background delete of large files. The path must be on the same physical volume as the folder specified by &amp;lt;LocalPath&amp;gt; as files are renamed into the trashcan folder where they will then be deleted via a background thread.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;Debug/&amp;gt; setting enables debug output for this instance of the virtual filesystem driver.&lt;br /&gt;
&lt;br /&gt;
== Debug Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;debug&amp;gt; configuration section is used to define how debug output is handled and where it is sent to. The &amp;lt;debug&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;debug&amp;gt;&lt;br /&gt;
     &amp;lt;output type=&amp;quot;Console|File|JDK&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;class&amp;gt;...&amp;lt;/class&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
     &amp;lt;/output&amp;gt;&lt;br /&gt;
 &amp;lt;/debug&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following pre-defined debug output types are available for the ''type=&amp;quot;...&amp;quot;'' value :-&lt;br /&gt;
* Console&amp;lt;br/&amp;gt;Output to the console&lt;br /&gt;
* File&amp;lt;br/&amp;gt;Output to the file defined by the &amp;lt;logfile&amp;gt;...&amp;lt;/logfile&amp;gt; parameter. An optional &amp;lt;append/&amp;gt; parameter can be specified to append to an existing log file.&lt;br /&gt;
* JDK&amp;lt;br/&amp;gt;Use Java JDK logging, use the &amp;lt;Properties&amp;gt;...&amp;lt;/Properties&amp;gt; parameter to specify the location of the logging properties file.&lt;br /&gt;
&lt;br /&gt;
It is also possible to provide your own custom debug output class by implementing the ''org.filesys.debug.DebugInterface'' interface. You would then use the &amp;lt;class&amp;gt;...&amp;lt;/class&amp;gt; setting to specify the debug class, and not use the ''type=&amp;quot;...&amp;quot;'' setting. Any parameters defined within the &amp;lt;output&amp;gt; section will be passed to the debug interface implementation ''initialize()'' method.&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;security&amp;gt; configuration section is used to define the JCE provider for the file server and to define server users when using local authentication.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;security&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;security&amp;gt;&lt;br /&gt;
     &amp;lt;JCEProvider&amp;gt;...&amp;lt;/JCEProvider&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;users&amp;gt;&lt;br /&gt;
         &amp;lt;user name=&amp;quot;...&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;password&amp;gt;...&amp;lt;/password&amp;gt;&lt;br /&gt;
             &amp;lt;!-- or --&amp;gt;&lt;br /&gt;
             &amp;lt;md4&amp;gt;...&amp;lt;/md4&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
             &amp;lt;!-- Optional user configuration --&amp;gt;&lt;br /&gt;
             &amp;lt;administrator/&amp;gt;&lt;br /&gt;
             &amp;lt;comment&amp;gt;...&amp;lt;/comment&amp;gt;&lt;br /&gt;
             &amp;lt;realname&amp;gt;...&amp;lt;/realname&amp;gt;&lt;br /&gt;
             &amp;lt;home&amp;gt;...&amp;lt;/home&amp;gt;&lt;br /&gt;
         &amp;lt;/user&amp;gt;&lt;br /&gt;
     &amp;lt;/users&amp;gt;&lt;br /&gt;
 &amp;lt;/security&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;JCEProvider&amp;gt; setting specifies the class that provides standard encryption support that the file server requires. The default setting is to use the BouncyCastle JCE provider library via the class ''org.bouncycastle.jce.provider.BouncyCastleProvider''.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;users&amp;gt; section defines local user accounts on the file server when local authentication is being used. If you are using Kerberos authentication the list of users will be ignored.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;user&amp;gt; section defines a local user, the ''name=&amp;quot;...&amp;quot;'' value is required and must be unique within the list of user names. The &amp;lt;password&amp;gt;...&amp;lt;password&amp;gt; setting species the user password in plaintext or you can specify the password using the MD4 value via a hex-ASCII value.&lt;br /&gt;
&lt;br /&gt;
The optional &amp;lt;home&amp;gt;...&amp;lt;/home&amp;gt; setting specifies the local path of the users home folder.&lt;br /&gt;
&lt;br /&gt;
== Licence Configuration ==&lt;br /&gt;
&lt;br /&gt;
To use the JFileServer Enterprise features a licence is required, this is configured via the &amp;lt;licence&amp;gt; configuration section.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;licence&amp;gt; configuration section has the following syntax :-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;licence&amp;gt;&lt;br /&gt;
     &amp;lt;!-- Use an embedded licence --&amp;gt;&lt;br /&gt;
     &amp;lt;licenceKey&amp;gt;...&amp;lt;/licenceKey&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;!-- Use an external licence key file --&amp;gt;&lt;br /&gt;
     &amp;lt;licencePath&amp;gt;...&amp;lt;/licencePath&amp;gt;&lt;br /&gt;
 &amp;lt;/licence&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To specify a licence key that is embedded within the server configuration file use the &amp;lt;licenceKey&amp;gt;...&amp;lt;/licenceKey&amp;gt; configuration section, the licence key text can be split onto multiple lines.&lt;br /&gt;
&lt;br /&gt;
To specify a licence key that is in an external file use the &amp;lt;licencePath&amp;gt;.../&amp;lt;licencePath&amp;gt; configuration section with the full path to the licence file.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Configuring_Kerberos/AD_Authentication_For_The_SMB_Server&amp;diff=307</id>
		<title>Configuring Kerberos/AD Authentication For The SMB Server</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Configuring_Kerberos/AD_Authentication_For_The_SMB_Server&amp;diff=307"/>
		<updated>2024-11-02T14:07:29Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;By default the JFileServer SMB server uses NTLM authentication, for more secure and single signon authentication you can configure the SMB server to use Kerberos logons.&lt;br /&gt;
&lt;br /&gt;
This document details how to configure the JFileServer, and JFileServer Enterprise, SMB server to use Kerberos authentication using a Windows Active Directory (AD) server setup.&lt;br /&gt;
&lt;br /&gt;
== Setting Up The File Server User Account ==&lt;br /&gt;
The JFileServer SMB server requires an AD user account to map a service principal name to that the client will request when accessing the SMB server.&lt;br /&gt;
&lt;br /&gt;
Create a user account on the AD server, fill in the user logon name eg. ''jfileserver'', disable the 'User must change password at next logon' option, and enable the 'Password never expires' option. Set a password for the new account.&lt;br /&gt;
&lt;br /&gt;
The user account can be configured with the 'Do not require Kerberos pre-authentication' option, or you can use pre-authentication. If pre-authentication is required you will need to specify the AD account password in the JFileServer ''&amp;lt;authenticator&amp;gt;'' configuration section using the ''&amp;lt;Password&amp;gt;...&amp;lt;/Password&amp;gt;'' setting.&lt;br /&gt;
&lt;br /&gt;
If there are options for AES 128 bit and AES 256 bit encryption then enable both options.&lt;br /&gt;
&lt;br /&gt;
[[File:KerberosADOptions.jpg|border]]&lt;br /&gt;
&lt;br /&gt;
The file server host also requires a DNS entry with the AD server.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If you are using an older Java VM that does not have the high strength encryption policy enabled then do not enable AES 256 bit encryption for the account. This may be earlier versions of Java 8 or pre Java 8 versions. If in doubt then do not enable AES 256 bit encryption. Only Windows 11 and the latest macOS clients support AES 256 encryption, and JFileServer does not currently support or negotiate AES 256, it will negotiate to use AES 128 only.&lt;br /&gt;
&lt;br /&gt;
== Generate The Keytab and Service Principal Name ==&lt;br /&gt;
Generate a key table for the file server using the ''ktpass'' command.&lt;br /&gt;
&lt;br /&gt;
 ktpass -princ cifs/&amp;lt;file-server-host-name&amp;gt;.&amp;lt;domain&amp;gt;@&amp;lt;REALM&amp;gt;&lt;br /&gt;
  -pass &amp;lt;file-server-account-password&amp;gt;&lt;br /&gt;
  -mapuser &amp;lt;domain&amp;gt;\&amp;lt;file-server-account-name&amp;gt;&lt;br /&gt;
  -crypto ALL&lt;br /&gt;
  -ptype KRB5_NT_PRINCIPAL&lt;br /&gt;
  -out &amp;lt;output-file-name&amp;gt;&lt;br /&gt;
  -kvno 0&lt;br /&gt;
&lt;br /&gt;
If you only want to use a particular encryption type then use ''-crypto AES128-SHA1'' or ''-crypto AES256-SHA1''. The older encryption setting of ''-crypto RC4-HMAC-NT'' can be used but may not allow some newer clients to access the file server.&lt;br /&gt;
&lt;br /&gt;
The generated key table will be used by the SMB server to authenticate the server so it will then be able to authenticate the client logons.&lt;br /&gt;
&lt;br /&gt;
Copy the key table to the file server host system.&lt;br /&gt;
&lt;br /&gt;
Create the service principal name mapping, that clients will use to connect to the SMB file server service, using the ''setspn'' utility. Newer versions of the ''ktpass'' command will set the SPN when generating the key table.&lt;br /&gt;
&lt;br /&gt;
To check if the SPN is set use&lt;br /&gt;
&lt;br /&gt;
 setspn -Q cifs/&amp;lt;file-server-host-name&amp;gt;.&amp;lt;domain&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the SPN has not been set then use the following commands to set the SPNs&lt;br /&gt;
&lt;br /&gt;
 setspn cifs/&amp;lt;file-server-host-name&amp;gt; &amp;lt;file-server-account-name&amp;gt;&lt;br /&gt;
 setspn cifs/&amp;lt;file-server-host-name&amp;gt;.&amp;lt;domain&amp;gt; &amp;lt;file-server-account-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure Kerberos On The File Server ==&lt;br /&gt;
The Java authentication APIs require a Kerberos configuration file, this can either be in the default location such as ''/etc/krb5.conf'' on linux and macOS, ''C:\winnt\krb5.ini'' on Windows, the location can be specified on the Java command line using the ''java.security.krb5.conf'' property, or using the JFileServer configuration value &amp;lt;KerberosConfig&amp;gt; to specify the configuration file path and name.&lt;br /&gt;
&lt;br /&gt;
A sample Kerberos configuration file is shown below, the Kerberos realm is always specified in uppercase.&lt;br /&gt;
&lt;br /&gt;
 [libdefaults]&lt;br /&gt;
 default_realm = FILESYS.ORG&lt;br /&gt;
 &lt;br /&gt;
 [realms]&lt;br /&gt;
 FILESYS.ORG = {&lt;br /&gt;
   kdc = adsrv.filesys.org&lt;br /&gt;
   admin_server = adsrv.filesys.org&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 [domain-realm]&lt;br /&gt;
 adsrv.filesys.org = FILESYS.ORG&lt;br /&gt;
 .adsrv.filesys.org = FILESYS.ORG&lt;br /&gt;
&lt;br /&gt;
== Setup The Java Login Configuration ==&lt;br /&gt;
The Java login configuration is used by the file server application to logon the server application using Kerberos by using the details in the key table that was generated on the Windows AD server.&lt;br /&gt;
&lt;br /&gt;
The Java login configuration file can be stored in your user home folder or a system folder such as ''/etc''. Create a new file called ''jfileserver.login.conf''. The default Java login configuration section name is ''FileServerSMB''. A sample Java login configuration file is shown below :-&lt;br /&gt;
&lt;br /&gt;
 FileServerSMB {&lt;br /&gt;
  com.sun.security.auth.module.Krb5LoginModule required&lt;br /&gt;
  debug=false&lt;br /&gt;
  storeKey=true&lt;br /&gt;
  useKeyTab=true&lt;br /&gt;
  keyTab=&amp;quot;&amp;lt;path-to-the-key-table-file&amp;gt;&amp;quot;&lt;br /&gt;
  principal=&amp;quot;cifs/&amp;lt;file-server-host-name&amp;gt;.&amp;lt;domain&amp;gt;&amp;quot;;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Note: Use spaces in the Java login configuration file, tab characters cause problems.&lt;br /&gt;
&lt;br /&gt;
To enable the Java login configuration use the JFileServer configuration value &amp;lt;LoginConfig&amp;gt; to specify the path to the login configuration file.&lt;br /&gt;
&lt;br /&gt;
You can also set the login configuration file by updating the main Java security configuration file. This is usually located in the ''&amp;lt;JRE-folder&amp;gt;/lib/security/java.security'' file.&lt;br /&gt;
&lt;br /&gt;
Look for the example configuration line that starts with ''#java.login.config.url.1=...''. Uncomment the line, or add a new line, similar to the value shown:-&lt;br /&gt;
&lt;br /&gt;
 java.login.config.url.1=&amp;lt;path-to-the-java-login-configuration-file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure The JFileServer SMB Authentication ==&lt;br /&gt;
In the JFileServer XML configuration file enable the SMB server Kerberos authentication via the &amp;lt;authenticator&amp;gt; configuration section within the &amp;lt;fileserver&amp;gt; &amp;lt;SMB&amp;gt; section of the configuration. A minimal sample configuration section is shown below:-&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;fileserver&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
   &amp;lt;SMB&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;authenticator type=&amp;quot;enterprise&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;!-- Kerberos/Active Directory Setup --&amp;gt;&lt;br /&gt;
       &amp;lt;Realm&amp;gt;FILESYS.ORG&amp;lt;/Realm&amp;gt;&lt;br /&gt;
     &amp;lt;/authenticator&amp;gt;&lt;br /&gt;
   &amp;lt;/SMB&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/fileserver&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following configuration tags are available for the SMB authenticator:-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;useSPNEGO/&amp;gt;&lt;br /&gt;
| Force Simple Protected Negotiation to be used for the authentication, this will be selected automatically if Kerberos authentication is enabled. If only NTLM authentication is enabled the default is to use NTLMSSP in the authentication exchanges.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;mode&amp;gt;...&amp;lt;/mode&amp;gt;&lt;br /&gt;
| Server mode, should always be 'USER'&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;Realm&amp;gt;...&amp;lt;/Realm&amp;gt;&lt;br /&gt;
| Kerberos realm, always uppercase&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;LoginEntry&amp;gt;...&amp;lt;/LoginEntry&amp;gt;&lt;br /&gt;
| Specifies the Java login configuration entry name if the default name of 'FileServerSMB' is not used&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;Password&amp;gt;...&amp;lt;/Password&amp;gt;&lt;br /&gt;
| Kerberos file server account password. Not required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;disallowNTLMv1/&amp;gt;&lt;br /&gt;
| Do not allow the weaker NTLM v1 logons, only NTLM v2 logons will be accepted&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;disableNTLM/&amp;gt;&lt;br /&gt;
| Only allow Kerberos authentication. NTLM authentication will not be advertised by the server or accepted&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;Debug/&amp;gt;&lt;br /&gt;
| Enable authentication debug output&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;kerberosDebug/&amp;gt;&lt;br /&gt;
| Enables the Java authentication API debug output. Equivalent of setting the Java system properties 'sun.security.jgss.debug' and 'sun.security.krb5.debug'&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;KerberosConfig&amp;gt;...&amp;lt;/KerberosConfig&amp;gt;&lt;br /&gt;
| Specifies the location and name of the Kerberos configuration file&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;LoginConfig&amp;gt;...&amp;lt;/LoginConfig&amp;gt;&lt;br /&gt;
| Specifies the location and name of the Java login configuration file&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=306</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=306"/>
		<updated>2024-10-02T14:41:57Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunActionResponse'' class has many convenience methods to set the various sections of the response :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 40%;&amp;quot;| Method&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| setSuccess()&lt;br /&gt;
| If the server action only needs to indicate it ran successfully then this method will set the status to indicate success and the client action to ''NoAction''.&lt;br /&gt;
|-&lt;br /&gt;
| setError(String)&lt;br /&gt;
| Return an error to the client with the specified error message to be displayed on the client.&amp;lt;br&amp;gt;There is also the ''RunActionResponse.createErrorResponse(String) method that will create a ''RunActionResponse'' object with the specified error message.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean)&lt;br /&gt;
| Indicates if the client should refresh the original path(s) file details in File Explorer views.&lt;br /&gt;
|-&lt;br /&gt;
| setClientAction(ServerAction.ClientAction,List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setClientAction(ServerAction.ClientAction,String)&lt;br /&gt;
| Set a client action with the specified parameter string(s).&lt;br /&gt;
|-&lt;br /&gt;
| setOpenURL(String)&lt;br /&gt;
| Set a client action to open the specified URL on the client.&lt;br /&gt;
|-&lt;br /&gt;
| setMessage(String msg)&amp;lt;br&amp;gt;setMessage(String title,String msg)&amp;lt;br&amp;gt;setMessage(String title, String msg, ServerAction.MessageLevel)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client. &amp;lt;br&amp;gt;If the ''ServerAction.MessageLevel'' is not specified the message will be shown with an informational level.&lt;br /&gt;
|-&lt;br /&gt;
| setWarningMessage(String msg)&amp;lt;br&amp;gt;setWarningMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with a warning level.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&amp;lt;br&amp;gt;setErrorMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with an error level.&lt;br /&gt;
|-&lt;br /&gt;
| setExecute(String operation, String app)&amp;lt;br&amp;gt;setExecute(String operation, String app, String param)&lt;br /&gt;
| Set an application to be run on the client, using the Windows ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatePaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setCreatedPaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setDeletedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Set a list of paths that were updated, created or deleted by the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&amp;lt;br&amp;gt;setNotification(String title, String msg)&lt;br /&gt;
| Set the notification to be displayed on the client.&amp;lt;br&amp;gt;If the notification title is not specified the client application name will be used.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Client API Implementation ===&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=305</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=305"/>
		<updated>2024-10-02T14:41:30Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunActionResponse'' class has many convenience methods to set the various sections of the response :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 40%;&amp;quot;| Method&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| setSuccess()&lt;br /&gt;
| If the server action only needs to indicate it ran successfully then this method will set the status to indicate success and the client action to ''NoAction''.&lt;br /&gt;
|-&lt;br /&gt;
| setError(String)&lt;br /&gt;
| Return an error to the client with the specified error message to be displayed on the client.&amp;lt;br&amp;gt;There is also the ''RunActionResponse.createErrorResponse(String) method that will create a ''RunActionResponse'' object with the specified error message.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean)&lt;br /&gt;
| Indicates if the client should refresh the original path(s) file details in File Explorer views.&lt;br /&gt;
|-&lt;br /&gt;
| setClientAction(ServerAction.ClientAction,List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setClientAction(ServerAction.ClientAction,String)&lt;br /&gt;
| Set a client action with the specified parameter string(s).&lt;br /&gt;
|-&lt;br /&gt;
| setOpenURL(String)&lt;br /&gt;
| Set a client action to open the specified URL on the client.&lt;br /&gt;
|-&lt;br /&gt;
| setMessage(String msg)&amp;lt;br&amp;gt;setMessage(String title,String msg)&amp;lt;br&amp;gt;setMessage(String title, String msg, ServerAction.MessageLevel)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client. &amp;lt;br&amp;gt;If the ''ServerAction.MessageLevel'' is not specified the message will be shown with an informational level.&lt;br /&gt;
|-&lt;br /&gt;
| setWarningMessage(String msg)&amp;lt;br&amp;gt;setWarningMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with a warning level.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&amp;lt;br&amp;gt;setErrorMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with an error level.&lt;br /&gt;
|-&lt;br /&gt;
| setExecute(String operation, String app)&amp;lt;br&amp;gt;setExecute(String operation, String app, String param)&lt;br /&gt;
| Set an application to be run on the client, using the Windows ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatePaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setCreatedPaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setDeletedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Set a list of paths that were updated, created or deleted by the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&amp;lt;br&amp;gt;setNotification(String title, String msg)&lt;br /&gt;
| Set the notification to be displayed on the client.&amp;lt;br&amp;gt;If the notification title is not specified the client application name will be used.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Client API Implementation ====&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=304</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=304"/>
		<updated>2024-10-02T14:37:05Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunActionResponse'' class has many convenience methods to set the various sections of the response :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 40%;&amp;quot;| Method&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| setSuccess()&lt;br /&gt;
| If the server action only needs to indicate it ran successfully then this method will set the status to indicate success and the client action to ''NoAction''.&lt;br /&gt;
|-&lt;br /&gt;
| setError(String)&lt;br /&gt;
| Return an error to the client with the specified error message to be displayed on the client.&amp;lt;br&amp;gt;There is also the ''RunActionResponse.createErrorResponse(String) method that will create a ''RunActionResponse'' object with the specified error message.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean)&lt;br /&gt;
| Indicates if the client should refresh the original path(s) file details in File Explorer views.&lt;br /&gt;
|-&lt;br /&gt;
| setClientAction(ServerAction.ClientAction,List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setClientAction(ServerAction.ClientAction,String)&lt;br /&gt;
| Set a client action with the specified parameter string(s).&lt;br /&gt;
|-&lt;br /&gt;
| setOpenURL(String)&lt;br /&gt;
| Set a client action to open the specified URL on the client.&lt;br /&gt;
|-&lt;br /&gt;
| setMessage(String msg)&amp;lt;br&amp;gt;setMessage(String title,String msg)&amp;lt;br&amp;gt;setMessage(String title, String msg, ServerAction.MessageLevel)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client. &amp;lt;br&amp;gt;If the ''ServerAction.MessageLevel'' is not specified the message will be shown with an informational level.&lt;br /&gt;
|-&lt;br /&gt;
| setWarningMessage(String msg)&amp;lt;br&amp;gt;setWarningMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with a warning level.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&amp;lt;br&amp;gt;setErrorMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with an error level.&lt;br /&gt;
|-&lt;br /&gt;
| setExecute(String operation, String app)&amp;lt;br&amp;gt;setExecute(String operation, String app, String param)&lt;br /&gt;
| Set an application to be run on the client, using the Windows ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatePaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setCreatedPaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setDeletedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Set a list of paths that were updated, created or deleted by the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&amp;lt;br&amp;gt;setNotification(String title, String msg)&lt;br /&gt;
| Set the notification to be displayed on the client.&amp;lt;br&amp;gt;If the notification title is not specified the client application name will be used.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=303</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=303"/>
		<updated>2024-10-02T14:36:37Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunActionResponse'' class has many convenience methods to set the various sections of the response :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 40%;&amp;quot;| Method&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| setSuccess()&lt;br /&gt;
| If the server action only needs to indicate it ran successfully then this method will set the status to indicate success and the client action to ''NoAction''.&lt;br /&gt;
|-&lt;br /&gt;
| setError(String)&lt;br /&gt;
| Return an error to the client with the specified error message to be displayed on the client.&amp;lt;br&amp;gt;There is also the ''RunActionResponse.createErrorResponse(String) method that will create a ''RunActionResponse'' object with the specified error message.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean)&lt;br /&gt;
| Indicates if the client should refresh the original path(s) file details in File Explorer views.&lt;br /&gt;
|-&lt;br /&gt;
| setClientAction(ServerAction.ClientAction,List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setClientAction(ServerAction.ClientAction,String)&lt;br /&gt;
| Set a client action with the specified parameter string(s).&lt;br /&gt;
|-&lt;br /&gt;
| setOpenURL(String)&lt;br /&gt;
| Set a client action to open the specified URL on the client.&lt;br /&gt;
|-&lt;br /&gt;
| setMessage(String msg)&amp;lt;br&amp;gt;setMessage(String title,String msg)&amp;lt;br&amp;gt;setMessage(String title, String msg, ServerAction.MessageLevel)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client. &amp;lt;br&amp;gt;If the ''ServerAction.MessageLevel'' is not specified the message will be shown with an informational level.&lt;br /&gt;
|-&lt;br /&gt;
| setWarningMessage(String msg)&amp;lt;br&amp;gt;setWarningMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with a warning level.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&amp;lt;br&amp;gt;setErrorMessage(String title,String msg)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client with an error level.&lt;br /&gt;
|-&lt;br /&gt;
| setExecute(String operation, String app)&amp;lt;br&amp;gt;setExecute(String operation, String app, String param)&lt;br /&gt;
| Set an application to be run on the client, using the Windows ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatePaths(List&amp;lt;String)&amp;lt;br&amp;gt;setCreatedPaths(List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setDeletedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Set a list of paths that were updated, created or deleted by the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&amp;lt;br&amp;gt;setNotification(String title, String msg)&lt;br /&gt;
| Set the notification to be displayed on the client.&amp;lt;br&amp;gt;If the notification title is not specified the client application name will be used.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=302</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=302"/>
		<updated>2024-10-02T14:30:38Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunActionResponse'' class has many convenience methods to set the various sections of the response :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 40%;&amp;quot;| Method&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| setSuccess()&lt;br /&gt;
| If the server action only needs to indicate it ran successfully then this method will set the status to indicate success and the client action to ''NoAction''.&lt;br /&gt;
|-&lt;br /&gt;
| setError(String)&lt;br /&gt;
| Return an error to the client with the specified error message to be displayed on the client.&amp;lt;br&amp;gt;There is also the ''RunActionResponse.createErrorResponse(String) method that will create a ''RunActionResponse'' object with the specified error message.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean)&lt;br /&gt;
| Indicates if the client should refresh the original path(s) file details in File Explorer views.&lt;br /&gt;
|-&lt;br /&gt;
| setClientAction(ServerAction.ClientAction,List&amp;lt;String&amp;gt;)&amp;lt;br&amp;gt;setClientAction(ServerAction.ClientAction,String)&lt;br /&gt;
| Set a client action with the specified parameter string(s).&lt;br /&gt;
|-&lt;br /&gt;
| setOpenURL(String)&lt;br /&gt;
| Set a client action to open the specified URL on the client.&lt;br /&gt;
|-&lt;br /&gt;
| setMessage(String msg)&amp;lt;br&amp;gt;setMessage(String title,String msg)&amp;lt;br&amp;gt;setMessage(String title, String msg, ServerAction.MessageLevel)&lt;br /&gt;
| Set a client message to be displayed in a message box dialog on the client. If the ''ServerAction.MessageLevel'' is not specified the message will be shown with an informational level.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=301</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=301"/>
		<updated>2024-10-02T14:16:45Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;ClientUIAction&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action uses the same ''ClientUIAction'' class that is used when defining a ''ServerAction'', as documented [[#ClientUIAction|here]]&lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=300</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=300"/>
		<updated>2024-10-02T14:02:13Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementing ServerAction runAction() ===&lt;br /&gt;
When the user selects an action on the client API sub-menu, the client will show the user interface item if the action has the optional ''UIAction'' configured, then if the action is not cancelled by the user or there is no user interface item to be displayed the request to run the action is sent to the server. &lt;br /&gt;
&lt;br /&gt;
To run the action on the server the client will write a ''RunActionRequest'' object, in JSON format, to the client API file. The ''RunActionRequest'' contains the action name, the list of the selected files/folder paths and an optional list of parameter values. The ''JSONClientAPI.processRequest()'' method will be triggered that will pass the ''RunActionRequest'' object to the ''processRunAction()'' method which must be implemented in your own client API implementation. The default implementation of ''processRunAction()'' in the ''JSONClientAPI'' class will return a ''Not Implemented'' error to the client.&lt;br /&gt;
&lt;br /&gt;
In your ''processRunAction()'' method you need to map the action name to the corresponding ''ServerAction'' object, then call the ''runAction()'' method with the ''RunActionRequest'' object and the ''ClientAPINetworkFile'' object. The ''runAction()'' method should either return a ''RunActionResponse'' object, or other object that extends the ''ClientAPIResponse'' class, or throw a ''ClientAPIException''.&lt;br /&gt;
&lt;br /&gt;
==== RunActionResponse ====&lt;br /&gt;
The ''RunActionResponse'' object holds the response details that are sent back to the client that indicate if the server action was successful and has various optional actions that the client can be instructed to do with a list of associated parameters, an optional user interface action such as displaying a message box dialog on the client, an optional notification to be displayed on the client, and a flag to indicate if the original selected files/folder details should be refreshed on the client.&lt;br /&gt;
&lt;br /&gt;
The available client actions are listed below, from the ServerAction.ClientAction enum class :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Action&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NoAction&lt;br /&gt;
| No action required on the client.&lt;br /&gt;
|-&lt;br /&gt;
| OpenURL&lt;br /&gt;
| Open a URL on the client, the URL value is the first parameter value.&lt;br /&gt;
|-&lt;br /&gt;
| OpenApplication&lt;br /&gt;
| Open an application on the client. The parameter values contain the operation name, application name and an optional parameter for the application.&amp;lt;br&amp;gt;The application will be launched using the Windows ShellExceute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| UIAction&lt;br /&gt;
| Indicates a user interface action on the client. The details of the user interface action are in the &lt;br /&gt;
|-&lt;br /&gt;
| UpdatedPaths&lt;br /&gt;
| The parameter list contains a list of paths that have been updated by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| NewPaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been created by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
| DeletePaths&lt;br /&gt;
| The parameter list contains a list of the paths that have been deleted by the server action, the client will refresh File Explorer views for the updated paths.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=299</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=299"/>
		<updated>2024-10-02T13:28:20Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a more complete client API implementation see the fileServersNG source code :-&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/AlfrescoClientApi.java AlfrescoClientAPI]&amp;lt;br&amp;gt;Extends the JSONClientAPI base class, adds check in/out and open in Share server actions plus ability to run scripted actions written in Javascript.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckOutServerAction.java Check Out Server Action]&amp;lt;br&amp;gt;Check out files from an Alfresco repository, refresh the original file details, refresh the File Explorer via to show newly created working copy files, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/CheckInServerAction.java Check In Server Action]&amp;lt;br&amp;gt;Check working copy files in to an Alfresco repository, or cancel the check out of the files, remove the working copies from File Explorer views, update the original file details, display a notification on the client.&lt;br /&gt;
* [https://github.com/FileSysOrg/fileServersNG/blob/main/src/main/java/org/filesys/alfresco/repo/clientapi/OpenInShareServerAction.java Open In Share Server Action]&amp;lt;br&amp;gt;Returns a URL for the selected file/folder for the client to open a web browser showing the file/folder in the Share web application.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=298</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=298"/>
		<updated>2024-10-02T11:03:14Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;br /&gt;
&lt;br /&gt;
Here is example source code of how to create a simple ''ContextMenu'' :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public class MyServerAction extends ServerAction {&lt;br /&gt;
  public MyServerAction() {&lt;br /&gt;
    super(&amp;quot;Server Action&amp;quot;, &amp;quot;A sample server action&amp;quot;, EnumSet.of( Flags.Files));&lt;br /&gt;
&lt;br /&gt;
    setIcon( ActionIcon.createShellIcon( ActionIcon.SHELLICON_INFORMATION);&lt;br /&gt;
    setUIAction( new ClientUIAction( UIAction.YesNoDialog, &amp;quot;Run MyServerAction&amp;quot;,&lt;br /&gt;
                         &amp;quot;Run the example server action ?&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public ClientAPIResponse runAction(RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
    throws ClientAPIException {&lt;br /&gt;
    ..&lt;br /&gt;
    ..&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public ContextMenu getContextMenu() {&lt;br /&gt;
  ContextMenu ctxMenu = new ContextMenu( &amp;quot;JFileServer Actions&amp;quot;, &amp;quot;Sample API context menu&amp;quot;,&lt;br /&gt;
                                      ActionIcon.createAppIcon( ActionIcon.APPICON_FILESYSORG));&lt;br /&gt;
&lt;br /&gt;
  List&amp;lt;ServerAction&amp;gt; actions = new ArrayList&amp;lt;ServerAction&amp;gt;();&lt;br /&gt;
  actions.add( new MyServerAction());&lt;br /&gt;
&lt;br /&gt;
  ctxMenu.addActions( actions);&lt;br /&gt;
&lt;br /&gt;
  return ctxMenu;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=297</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=297"/>
		<updated>2024-10-02T10:41:39Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;font-size:80%;&amp;quot;&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=296</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=296"/>
		<updated>2024-10-02T10:36:49Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;br /&gt;
&lt;br /&gt;
For the message box dialog user interface actions a message level can be specified to indicate whether the message is an informational, warning or error message. The message box dialog will show a different icon depending on the message level. The available values are defined in the ''ServerAction.MessageLevel'' enum class, with values of ''Info'', ''Warn'' and ''Error''.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=295</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=295"/>
		<updated>2024-10-02T10:32:36Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Undo Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
&amp;lt;br&amp;gt;[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Undo Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:CheckInDialog.png&amp;diff=294</id>
		<title>File:CheckInDialog.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:CheckInDialog.png&amp;diff=294"/>
		<updated>2024-10-02T10:30:39Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=293</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=293"/>
		<updated>2024-10-02T10:30:12Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;br /&gt;
&lt;br /&gt;
To create a server-side action you must extend the ''ServerAction'' class. The ''ServerAction'' class requires an action name, that will be used as the menu title, a description and a set of flags that define what combination of file/folder selections the action accepts. The ''ServerAction.Flags'' enum class defines the available flags, which are also defined below :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| Flag&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| Action accepts file selections&lt;br /&gt;
|-&lt;br /&gt;
| Folders&lt;br /&gt;
| Action accepts folder selections&lt;br /&gt;
|-&lt;br /&gt;
| MultiSelect&lt;br /&gt;
| Action accepts multiple file and/or folder selections&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a flags value of ''EnumSet.of( Flags.Files)'' would indicate the action only accepts a single file selection. If multiple files are selected on the client, or a folder is selected, the server action sub-menu will be greyed out and not selectable by the user. A flags value of ''EnumSet.of( Flags.Files, Flags.MultiSelect)'' would indicate the action accepts file selections with one or more files selected.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional icon defined, using the same ''ActionIcon'' class that the top level context menu uses. Set the icon using the appropriate ''ServerAction'' constructor, or using the ''setIcon(ActionIcon)'' method. If no icon is defined for a server action the sub-menu item will be shown with no icon.&lt;br /&gt;
&lt;br /&gt;
A ''ServerAction'' can have an optional user interface action that will instruct the client application to display a user interface item such as a message box. If the user interface item has an option to cancel such as Ok/Cancel buttons then the action will not be triggered on the server if the cancel option is selected by the user.&lt;br /&gt;
&lt;br /&gt;
A user interface action is configured for a server action using the ''setUIAction(ClientUIAction)'' method. The ''ClientUIAction'' has the type of user interface item to be displayed with an optional title, message text and the message severity for message box dialogs. The available ''ClientUIAction.UIAction'' types are shown below :- &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 10%;&amp;quot;| UIAction&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| MessageDialog&lt;br /&gt;
| Display a message box dialog with an ''Ok'' button. &lt;br /&gt;
|-&lt;br /&gt;
| YesNoDialog&lt;br /&gt;
| Display a message box dialog with ''Yes'' and ''No'' buttons. If the ''No'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| OkCancelDialog&lt;br /&gt;
| Display a message box dialog with ''Ok'' and ''Cancel'' buttons. If the ''Cancel'' button is selected by the user the action will not be run.&lt;br /&gt;
|-&lt;br /&gt;
| CheckInDialog&lt;br /&gt;
| Displays a custom dialog that lists the selected file(s) with a comment input field and buttons ''Check In'', ''Cancel Checkout'' and ''Cancel''.&lt;br /&gt;
&amp;lt;br&amp;gt;An example of the check in dialog :-&lt;br /&gt;
[[File:CheckInDialog.png|250px|border]]&lt;br /&gt;
&amp;lt;br&amp;gt;If the ''Check In'' button is selected the action is run with the request parameters containing a value of ''checkin'', if the ''Cancel Checkout'' button is selected the action is run with the request parameters containing a value of ''cancel''. Selecting the ''Cancel'' button will not run the server action.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If the title is not set for a ''ClientUIAction'' the client application name will be used.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=292</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=292"/>
		<updated>2024-10-02T09:35:02Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementing getSupportedRequests() ===&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implements a ''GetAPIInfo'' request that is used by the client to probe that the network drive supports the client API, and returns information about the API including the context menu title, description and icon details plus the sub-menu details that includes details of each server action.&lt;br /&gt;
&lt;br /&gt;
Here is a sample context menu from the fileServersNG client API implementation :-&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
In the fileServersNG context menu example the context menu title is ''Alfresco Drive'' with a custom icon. The sub-menu contains the list of server actions such as ''Check In'' and ''Check Out''.&lt;br /&gt;
&lt;br /&gt;
Each server action on the sub-menu has an action name, description, details about the file and/or folder selections the action accepts, an optional user interface action to be run before the action request is sent to the server and an optional icon definition.&lt;br /&gt;
&lt;br /&gt;
As the ''JSONClientAPI'' implements the ''GetAPIInfo'' request, that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation. A sample implementation of the getSupportedRequests() method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests() {&lt;br /&gt;
  return EnumSet.of ( ApiRequest.GetApiInfo, ApiRequest.RunAction);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getClientAPIVersion() ===&lt;br /&gt;
&lt;br /&gt;
The ''getClientAPIVersion()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method should return a version string with the format ''&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;''.&lt;br /&gt;
&lt;br /&gt;
A sample implementation of the ''getClientAPIVersion()'' method :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getClientAPIVersion() {&lt;br /&gt;
  return &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Implementing getContextMenu() ===&lt;br /&gt;
&lt;br /&gt;
The ''getContextMenu()'' method is called by the ''GetAPIInfo'' request processing when collecting details about the client API implementation. The method returns a ''ContextMenu'' object that defines the top level context menu and the server actions used for the sub-menu.&lt;br /&gt;
&lt;br /&gt;
A ''ContextMenu'' object is created using the constructor ''ContextMenu(String title, String description, ActionIcon icon)'' where ''title'' is the menu title that will be shown on the File Explorer right click context menu, ''description'' may be used as a tooltip, and ''icon'' defines the icon to be displayed for the context menu.&lt;br /&gt;
&lt;br /&gt;
The ''ContextMenu'' needs a list of ''ServerAction'' objects to be attached using the ''setActions( List&amp;lt;ServerAction&amp;gt;)'' method, this defines the items that will be shown on the sub-menu of the context menu.&lt;br /&gt;
&lt;br /&gt;
==== ActionIcon ====&lt;br /&gt;
The ''ActionIcon'' class defines an icon on the client. The icon may be included in the client API context menu DLL, in the Windows shell32.dll system file or you can define a custom icon from another Windows system DLL.&lt;br /&gt;
&lt;br /&gt;
There are convenience methods on the ''ActionIcon'' class for creating the different types of icon. To define an icon that is contained in the client API context menu DLL use the ''ActionIcon.createAppIcon(int)'' method, to define an icon that is contained in the Windows shell32.dll system file use the ''ActionIcon.createShellIcon(int)'' method, and to create a custom icon use the ''ActionIcon.createCustomIcon(int, String)''. For a custom icon the values are the index of the icon (should be a negative number) and the name of the Windows system file that contains the icon (without any path).&lt;br /&gt;
&lt;br /&gt;
An ''ActionIcon'' can also be created using a name, using the ''ActionIcon.createByName(String)'' method, this is useful if the context menu is defined a configuration file.&lt;br /&gt;
&lt;br /&gt;
The table below lists the available ActionIcon types, ids and names. Id types are ''ActionIcon.IconType'' enum values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Type&lt;br /&gt;
! Id&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_SCRIPT&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_WEBBROWSER&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_FOLDER&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_PRINTER&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MAGNIFY&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_STAR&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_LOCK&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_MOVIE&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_AUDIO&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_CAMERA&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_INFORMATION&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_HOME&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Shell&lt;br /&gt;
| ActionIcon.SHELLICON_GEAR&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG_ALFRESCO&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_FILESYSORG&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKIN&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| App&lt;br /&gt;
| ActionIcon.APPICON_ALFRESCO_CHECKOUT&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ServerAction ====&lt;br /&gt;
&lt;br /&gt;
The ''ServerAction'' class defines a server-side action that will be displayed on the client context menu sub-menu, this includes details of the menu name, description and icon plus details of what type of file/folder selections the action accepts, and an optional user interface action for the client to run before sending the action request to the server, such as displaying an acknowledgement message dialog with Ok/Cancel buttons.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=291</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=291"/>
		<updated>2024-10-02T08:04:27Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The source code for the client API interfaces and classes is available [https://github.com/FileSysOrg/jfileserver/tree/master/src/main/java/org/filesys/server/filesys/clientapi here].&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=290</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=290"/>
		<updated>2024-10-01T16:27:01Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=289</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=289"/>
		<updated>2024-10-01T16:23:28Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; vertical-align:top; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=288</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=288"/>
		<updated>2024-10-01T16:20:21Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI'' implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=287</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=287"/>
		<updated>2024-10-01T16:18:02Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send a request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI''. implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=286</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=286"/>
		<updated>2024-10-01T16:12:22Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI''. implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
&amp;lt;br&amp;gt;The ''JSONClientAPI'' implements the ''GetAPIInfo'' request, so that must be included in the supported requests list. The ''RunAction'' API request should be included if you want to handle custom actions in your API implementation.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=285</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=285"/>
		<updated>2024-10-01T16:07:22Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI''. implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width:40%;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=284</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=284"/>
		<updated>2024-10-01T15:55:39Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, for the ''JSONClientAPI''. implementation the special path is ''\__JSONAPI__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''JSONClientAPI'' implementation handles all of the ''ClientAPIInterface'' methods, and adds the following methods that must be implemented or can be overridden :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public EnumSet&amp;lt;ApiRequest&amp;gt; getSupportedRequests()&lt;br /&gt;
| Returns the set of API requests that this implementation supports. The APIRequest enum has the values ''GetAPIInfo'', ''GetURLForPath'', ''GetPathStatus'' and ''RunAction''. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public ContextMenu getContextMenu()&lt;br /&gt;
| Return the context menu details with the top level menu title and icon, plus the list of server actions that will be displayed on a sub-menu of the client context menu. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIVersion()&lt;br /&gt;
| Return the client API version in ''n.n.n.n'' format. This method must be implemented.&lt;br /&gt;
|-&lt;br /&gt;
| protected void preProcessRequest( ClientAPINetworkFile netFile, ClientAPIRequest req)&lt;br /&gt;
| Optional method that can be overridden to handle a client request before the main request handler processes the request.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetURLForPath( GetURLForPathRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetURLForPath'' API request is supported. The ''GetURLForPathRequest'' object contains the relative path of the file or folder that was selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processGetPathStatus( GetPathStatusRequest req)&lt;br /&gt;
| Optional method that should be overridden if the client API ''GetPathStatus'' API request is supported. The ''GetPathStatusRequest'' object contains a list of the relative paths that were selected on the client and a check type value for the path status to be checked.&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIResponse processRunAction( RunActionRequest req, ClientAPINetworkFile netFile)&lt;br /&gt;
| This method handles processes running a server side action associated with a context menu. The ''RunActionRequest'' object contains the action name, a list of one or more relative paths that were selected on the client and an optional list of parameter values.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=283</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=283"/>
		<updated>2024-10-01T15:04:28Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPI'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPI'' interface has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled for this filesystem, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The base ''ClientAPIInterface'' interface has the following methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Method&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;|Description&lt;br /&gt;
|-&lt;br /&gt;
| public String getClientAPIPath()&lt;br /&gt;
| Returns the special path that the client will write requests and receive responses via. The path should be a path that is relative to the root of the filesystem, eg. ''\__CLIENT_API__''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPINetworkFile openClientAPIFile(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree, FileOpenParams params)&lt;br /&gt;
| Returns a special in-memory file that represents a file open to the special client API path. The in-memory file is created per file open, it is not shared between users or sessions&lt;br /&gt;
|-&lt;br /&gt;
| public void processRequest( ClientAPINetworkFile netFile)&lt;br /&gt;
| Process a client request received via the specified client API file. The request data can be retrieved using the ''byte[] netFile.getRequestData()'' method. The response is written to the client API file using the ''setResponseData( byte[])'' method.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=282</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=282"/>
		<updated>2024-10-01T14:48:32Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPI'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPIInterface'' has two methods :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:left;&amp;quot;&lt;br /&gt;
| Method&lt;br /&gt;
| Description&lt;br /&gt;
|-&lt;br /&gt;
| public boolean isClientAPIEnabled()&lt;br /&gt;
| Returns ''true'' is the client API is enabled, else ''false''&lt;br /&gt;
|-&lt;br /&gt;
| public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
| Returns the ''ClientAPI'' implementation that handles the requests from the client&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=281</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=281"/>
		<updated>2024-10-01T14:35:29Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPI'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPIInterface'' has two methods :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public boolean isClientAPIEnabled()&lt;br /&gt;
public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=280</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=280"/>
		<updated>2024-10-01T14:31:58Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPI'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPIInterface'' has two methods :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public boolean isClientAPIEnabled()&lt;br /&gt;
public ClientAPIInterface getClientAPI(SrvSession&amp;lt;?&amp;gt; sess, TreeConnection tree)&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=279</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=279"/>
		<updated>2024-10-01T14:29:38Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
== Filesystem Requirements ==&lt;br /&gt;
To enable client API support a filesystem must implement the optional ''org.filesys.server.filesys.clientapi.ClientAPIInterface'' interface, with a client API implementation class that either implements the base ''org.filesys.server.filesys.clientapi.ClientAPI'' interface or extends the ''org.filesys.server.filesys.clientapi.json.JSONClientAPI'' abstract class.&lt;br /&gt;
&lt;br /&gt;
The ''ClientAPIInterface'' has two methods :-&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=278</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=278"/>
		<updated>2024-10-01T14:24:35Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, extending the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;br /&gt;
&lt;br /&gt;
This document describes how to implement a client API by extending the ''JSONClientAPI'' implementation.&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=277</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=277"/>
		<updated>2024-10-01T14:18:50Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, using the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[File Explorer Menu for Alfresco|here]], and the source code for the fileServersNG implementation is [https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here].&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=276</id>
		<title>Adding Client API Support To A Filesystem</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Adding_Client_API_Support_To_A_Filesystem&amp;diff=276"/>
		<updated>2024-10-01T14:17:06Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: Created page with &amp;quot;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface a...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The client API feature was added in the JFileServer 1.4.0/JFileServer Enterprise 1.3.0 release, as an optional interface a filesystem can implement. The client API interface allows a client to send requests to the file server over existing protocols, currently SMB2 and SMB3 protocols are supported. A filesystem must implement the core ''DiskInterface'', and can then add other functionality using optional interfaces such as to implement file locking, or in this case the client API interface.&lt;br /&gt;
&lt;br /&gt;
The client API uses a special path on the server that the client can write a request into, and receives the response from the server. The special path is not visible in folder listings. The main implementation uses JSON format to send request and for the response, but you can implement your own format of request and response by implementing the lower level ''ClientAPIInterface'', rather than extending the ''JSONClientAPI'' implementation.&lt;br /&gt;
&lt;br /&gt;
The JSON client API has a client side application, currently for Windows 10 and 11, that provides a right click context menu into the Windows File Explorer application, with a configurable set of sub-menus that trigger server side actions. The client side application is also able to display message boxes and other user interface items before and after an action has run, show notifications, run applications and open URLs all under control of the server side actions.&lt;br /&gt;
&lt;br /&gt;
The fileServersNG Alfresco add-on module contains a reference implementation of a client API, using the ''JSONClientAPI''. There is a Wiki document that describes the fileServersNG client API implementation [[ here]], and the source code for the fileServersNG implementation is [[https://github.com/FileSysOrg/fileServersNG/tree/main/src/main/java/org/filesys/alfresco/repo/clientapi here]].&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=Welcome_to_the_Filesys.org_Wiki&amp;diff=275</id>
		<title>Welcome to the Filesys.org Wiki</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=Welcome_to_the_Filesys.org_Wiki&amp;diff=275"/>
		<updated>2024-10-01T13:42:52Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: /* JFileServer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here you will find articles, how-to's and other documentation for the JFileServer file server, JFileServer Enterprise add-on and fileServersNG replacement Alfresco file servers subsystem.&lt;br /&gt;
&lt;br /&gt;
== JFileServer ==&lt;br /&gt;
* [[How to convert a JLAN filesystem]]&lt;br /&gt;
* [[Configuring JFileServer]]&lt;br /&gt;
* [[Using JFileServer From The Command Line]]&lt;br /&gt;
* [[Using the JFileServer Docker Images]]&lt;br /&gt;
* [[Configuring Kerberos/AD Authentication For The SMB Server]]&lt;br /&gt;
* [[Using filesystem access controls]]&lt;br /&gt;
* [[Adding Client API Support To A Filesystem]]&lt;br /&gt;
&lt;br /&gt;
== JFileServer Enterprise ==&lt;br /&gt;
* [[Using JFileServer Enterprise From The Command Line]]&lt;br /&gt;
* [[Using the JFileServer Enterprise Docker Image]]&lt;br /&gt;
&lt;br /&gt;
== fileServersNG ==&lt;br /&gt;
* [[How to build and deploy the fileServersNG subsystem]]&lt;br /&gt;
* [[Using the fileServersNG Docker Images]]&lt;br /&gt;
* [[Configuring Kerberos/AD Authentication For The fileServersNG SMB Server]]&lt;br /&gt;
* [[File Explorer Menu for Alfresco]]&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=274</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=274"/>
		<updated>2024-10-01T13:24:22Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the fileServersNG module, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here], and requires fileServersNG 24.3 or newer to be installed on the Alfresco server (fileServersNG 24.3 AMP available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/fileserversng-24.3.amp here]).&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script that generates a URL to the Share details page for the selected file/folder, which the client application then opens in a web browser :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=273</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=273"/>
		<updated>2024-10-01T13:21:40Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the fileServersNG module, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here], and requires fileServersNG 24.3 or newer to be installed on the Alfresco server (fileServersNG 24.3 AMP available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/fileserversng-24.3.amp here]).&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script that generates a URL to the Share details page for the selected file/folder, which the client application then opens in a web browser on the client :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=272</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=272"/>
		<updated>2024-10-01T13:16:38Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the fileServersNG module, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here], and requires fileServersNG 24.3 or newer to be installed on the Alfresco server (fileServersNG 24.3 AMP available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/fileserversng-24.3.amp here]).&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=271</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=271"/>
		<updated>2024-10-01T13:16:14Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to fileServersNG module, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here], and requires fileServersNG 24.3 or newer to be installed on the Alfresco server (fileServersNG 24.3 AMP available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/fileserversng-24.3.amp here]).&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=270</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=270"/>
		<updated>2024-10-01T10:44:11Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here], and requires fileServersNG 24.3 or newer to be installed on the Alfresco server (fileServersNG 24.3 AMP available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/fileserversng-24.3.amp here]).&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=269</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=269"/>
		<updated>2024-10-01T10:41:13Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here].&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side actions that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=268</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=268"/>
		<updated>2024-10-01T10:37:44Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file, available [https://www.filesys.org/kits/fileserversng/alfresco-6.2-to-latest/FileExplorerMenu_x64_1.0.0.msix here].&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side scripted actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side scripts that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=267</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=267"/>
		<updated>2024-09-25T11:24:10Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file.&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side scripted actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side scripts that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines. A notification can be returned with other actions (messages, open URL, execute, set paths).&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=266</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=266"/>
		<updated>2024-09-25T11:21:47Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file.&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side scripted actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side scripts that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setWarningMessage(String title, String msg)&lt;br /&gt;
| Return a warning message to the client application to be displayed using the standard client warning message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| setErrorMessage(String title, String msg)&lt;br /&gt;
| Return an error message to the client application to be displayed using the standard client error message dialog, with the specified title for the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| setRefreshOriginal(boolean) &lt;br /&gt;
| Refresh the details of the files/folders on the client for files/folders that were selected for the server action.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String msg)&lt;br /&gt;
| Show a notification on the client with the specified message. The message text may be up to 4 lines.&lt;br /&gt;
|-&lt;br /&gt;
| setNotification(String title, String msg)&lt;br /&gt;
| Show a notification on the client with the specified title and message. The message text may be up to 4 lines.&lt;br /&gt;
|-&lt;br /&gt;
| setCreatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of new files/folders that have been created on the server so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setUpdatedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been updated by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
| setRemovedPaths(List&amp;lt;String&amp;gt;)&lt;br /&gt;
| Notifies the client of a list of files/folders that have been removed by the server-side action so the client can refresh view(s).&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=265</id>
		<title>File Explorer Menu for Alfresco</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File_Explorer_Menu_for_Alfresco&amp;diff=265"/>
		<updated>2024-09-25T10:17:17Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The File Explorer Menu for Alfresco is a Windows 10/11 client side extension for the fileServersNG module. The extension provides a right click context menu for Alfresco mounted drives within the File Explorer application.&lt;br /&gt;
&lt;br /&gt;
[[File:ContextMenu.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
On the Alfresco Drive context menu are a number of actions, some of the actions are built in to the client application, such as the ability to check a file out of Alfresco, create a working copy of the file and lock the original file on the server so that others cannot alter it. Other actions can be provided using server-side scripts.&lt;br /&gt;
&lt;br /&gt;
The current list of built-in actions is :-&lt;br /&gt;
* Check file(s) out of Alfresco&amp;lt;br&amp;gt;Creates a working copy for each file, and locks the original file(s) on the server.&lt;br /&gt;
* Check file(s) in to Alfresco&amp;lt;br&amp;gt;Check working copy files back into Alfresco, updating the original document, removing the working copy file(s) and lock(s) on the original file(s).&amp;lt;br&amp;gt;Also has an option to cancel the check out so that any changes to the working copy file(s) are lost, working copy file(s) and lock(s) are removed.&lt;br /&gt;
* Open file in Alfresco&amp;lt;br&amp;gt;Opens the selected file in a web browser using the Alfresco Share interface.&lt;br /&gt;
&lt;br /&gt;
The context menu actions work on the files and/or folders that are selected within File Explorer when an item is right clicked. Actions may work on files only, folders only, files and folders, and may work on single selected files or folders, or multiple selections. If an action does not support the list of items selected within File Explorer then the action menu will be shown disabled to indicate that the action is not available.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The File Explorer Menu for Alfresco application is installed using a standard Windows installer file.&lt;br /&gt;
&lt;br /&gt;
After installation, on Windows 10 you will need to reboot the system, on Windows 11 you can either close all File Explorer windows or reboot the system.&lt;br /&gt;
&lt;br /&gt;
== Client Application ==&lt;br /&gt;
The File Explorer Menu for Alfresco application consists of a shell extension that provides the right click context menu within the File Explorer application, and a system tray menu application that processes the actions, and can display any dialogs, or other user interface items, before or after the action has been run by the server.&lt;br /&gt;
&lt;br /&gt;
[[File:TrayIconMenu.png|200px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''About'' menu will display version information about the application, and if an Alfresco drive is currently mapped, it will display details about the client application interface, such as the version, supported actions and configured server-side scripted actions.&lt;br /&gt;
&lt;br /&gt;
[[File:AboutDialog.png|400px|border]]&lt;br /&gt;
&lt;br /&gt;
The ''Copy and Close'' option will copy the application version information, and client application interface details if an Alfresco drive is mapped, to the clipboard. This can be pasted into an email for support if requested.&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
There are a number of server configuration values that control the setup of the File Explorer Menu for Alfresco application. The current list of server configuration values :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Configuration Property&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.enabled&lt;br /&gt;
| Enable the client API interface, set to either ''true'' or ''false'', defaults to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.shareBaseURL&lt;br /&gt;
| URL of the top level of the Share interface, in http://host:port/share or https://host:port/share format.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.scriptsDir&lt;br /&gt;
| The path of the scripts folder where the scripts configuration file, scripts.toml, and the server-side scripts files are located.&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.debug&lt;br /&gt;
| Enable debug output from the server-side client API processing, set the value to ''true''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_title&lt;br /&gt;
| The context menu title, defaults to ''Alfresco Drive''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_description&lt;br /&gt;
| The context menu description, defaults to ''Alfresco Drive File Explorer menu''&lt;br /&gt;
|-&lt;br /&gt;
| smb.clientAPI.menu_icon&lt;br /&gt;
| The context menu icon, defaults to the Filesys.org Alfresco icon (value ''FileSysOrgAlfresco'')&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''smb.clientAPI.shareBaseURL'' value is used by the ''Open in Alfresco'' action to open the selected file/folder in a Share browser view. The value is also available for server-side scripts to use to build URLs.&lt;br /&gt;
&lt;br /&gt;
The built-in actions and server-side scripted actions are configured using a TOML format file called ''scripts.toml'' in the ''smb.clientAPI.scriptsDir'' folder. The server-side script files are placed in the same folder as the ''scripts.toml'' file.&lt;br /&gt;
&lt;br /&gt;
=== scripts.toml ===&lt;br /&gt;
The ''scripts.toml'' file configures which built-in actions (such as check in/out) are available to the File Explorer Menu for Alfresco client application, and also defines server-side scripts that are made available on the File Explorer context menu.&lt;br /&gt;
&lt;br /&gt;
The ''scripts.toml'' file has the following format :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [BuiltInActions]&lt;br /&gt;
   CheckInOut = true|false&lt;br /&gt;
   OpenInBrowser = true|false&lt;br /&gt;
 &lt;br /&gt;
 [[Action]]&lt;br /&gt;
 name = &amp;quot;&amp;lt;Action name that appears on the context menu&amp;gt;&amp;quot;&lt;br /&gt;
 description = &amp;quot;&amp;lt;description&amp;gt;&amp;quot;&lt;br /&gt;
 script = &amp;quot;&amp;lt;script-file-name&amp;gt;&amp;quot;&lt;br /&gt;
 attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&lt;br /&gt;
 icon = &amp;quot;&amp;lt;icon-name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 [[Action]]&lt;br /&gt;
 ..&lt;br /&gt;
 ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the ''[BuiltInActions]'' section is not specified then all built-in actions are enabled by default.&lt;br /&gt;
&lt;br /&gt;
If the ''scripts.toml'' file is modified whilst the Alfresco server is running the configuration will be reloaded without needing to restart the server.&lt;br /&gt;
&lt;br /&gt;
The ''attributes'' setting of a scripted action defines what types of selections the action context menu will be enabled for. ''Files'' indicates the action works on a file, ''Folders'' indicates the action works on folders, ''MultiSelect'' indicates the action works on multiple selections of files and/or folders.&lt;br /&gt;
&lt;br /&gt;
If the selected item(s) in File Explorer do not match the action attributes the action menu will be disabled.&lt;br /&gt;
&lt;br /&gt;
The possible ''attributes'' settings :-&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected file item&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action only accepts a single selected folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;]&amp;lt;br&amp;gt;Action accepts either a single selected file or folder item&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file items&lt;br /&gt;
* attributes = [&amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected folder items&lt;br /&gt;
* attributes = [&amp;quot;Files&amp;quot;, &amp;quot;Folders&amp;quot;, &amp;quot;MultiSelect&amp;quot;]&amp;lt;br&amp;gt;Action accepts one or more selected file and/or folder items, the selection may be a mixture of files and folders&lt;br /&gt;
&lt;br /&gt;
The ''icon'' setting is optional, it is used to specify the context menu icon to be used for the action. There are a number of preset icon names available or a custom icon can be specified using the syntax ''Custom:&amp;lt;dll-name&amp;gt;,&amp;lt;icon-index&amp;gt;'', where ''&amp;lt;dll-name&amp;gt;'' is the name of a Windows system DLL that contains the icon, and ''&amp;lt;icon-index&amp;gt;'' is the index of the icon resource within the DLL.&lt;br /&gt;
&lt;br /&gt;
The Windows ''shell32.dll'' has many icons available. &lt;br /&gt;
&lt;br /&gt;
The following preset icon names are available to configure actions :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 5%;&amp;quot;| Icon&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellScript.png|20px]]&lt;br /&gt;
| ShellScript&lt;br /&gt;
| Script icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellWebBrowser.png|20px]]&lt;br /&gt;
| ShellWebBrowser&lt;br /&gt;
| Web browser icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellFolder.png|20px]]&lt;br /&gt;
| ShellFolder&lt;br /&gt;
| Folder icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellPrinter.png|20px]]&lt;br /&gt;
| ShellPrinter&lt;br /&gt;
| Printer icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMagnify.png|20px]]&lt;br /&gt;
| ShellMagnify&lt;br /&gt;
| Magnifying glass icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellStar.png|20px]]&lt;br /&gt;
| ShellStar&lt;br /&gt;
| Star icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellLock.png|20px]]&lt;br /&gt;
| ShellLock&lt;br /&gt;
| Lock icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellMovie.png|20px]]&lt;br /&gt;
| ShellMovie&lt;br /&gt;
| Movie icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellAudio.png|20px]]&lt;br /&gt;
| ShellAudio&lt;br /&gt;
| Audio icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellCamera.png|20px]]&lt;br /&gt;
| ShellCamera&lt;br /&gt;
| Camera icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellInformation.png|20px]]&lt;br /&gt;
| ShellInformation&lt;br /&gt;
| Information icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellHome.png|20px]]&lt;br /&gt;
| ShellHome&lt;br /&gt;
| Home icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:ShellGear.png|20px]]&lt;br /&gt;
| ShellGear&lt;br /&gt;
| Gear icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrgAlfresco.png|20px]]&lt;br /&gt;
| FileSysOrgAlfresco&lt;br /&gt;
| Filesys.org Alfresco application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:FileSysOrg.png|20px]]&lt;br /&gt;
| FileSysOrg&lt;br /&gt;
| Filesys.org application icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckIn.png|20px]]&lt;br /&gt;
| AlfrescoCheckIn&lt;br /&gt;
| Alfresco check in icon&lt;br /&gt;
|-&lt;br /&gt;
|[[File:AlfrescoCheckOut.png|20px]]&lt;br /&gt;
| AlfrescoCheckOut&lt;br /&gt;
| Alfresco check out icon&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Server-side Scripts ===&lt;br /&gt;
The server-side scripted actions are written using JavaScript. A simple server-side script :-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function runAction()&lt;br /&gt;
{&lt;br /&gt;
  var urlStr = shareURL + &amp;quot;page/document-details?nodeRef=&amp;quot; + params.getTarget(0).getNode().getStoreRef()&lt;br /&gt;
    + params.getTarget(0).getNode().getId();&lt;br /&gt;
&lt;br /&gt;
  result.setSuccess();&lt;br /&gt;
  result.setClientOpenURL( urlStr);&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = runAction();&lt;br /&gt;
&lt;br /&gt;
result;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A number of Java objects are made available to the server-side script, to pass in details of the selected item(s) and to return a result to the client application.&lt;br /&gt;
&lt;br /&gt;
The following Java objects are passed to the server-side script environment :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left; width: 15%;&amp;quot;| Java Object Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| params&lt;br /&gt;
| A ''DesktopParams'' object containing details of the folder node that the script is running in, plus the list of selected target nodes from the client side selection.&lt;br /&gt;
See below for a list of the useful methods on the ''DesktopParams'' object.&lt;br /&gt;
|-&lt;br /&gt;
| result&lt;br /&gt;
| A ''RunScriptResponse'' object that contains the server-side script response to be sent to the client application. The response indicates if the script was successful, and actions the client application may take, such as opening the returned URL in a web browser on the client in the example script above.&lt;br /&gt;
See below for a list of useful methods on the ''RunScriptResponse'' object.&lt;br /&gt;
|-&lt;br /&gt;
| out&lt;br /&gt;
| The Java System.out stream value, allowing the script to output to the Alfresco log file.&lt;br /&gt;
|-&lt;br /&gt;
| shareURL&lt;br /&gt;
| Value of the ''smb.clientAPI.shareBaseURL'' value, if configured.&lt;br /&gt;
|-&lt;br /&gt;
| registry&lt;br /&gt;
| The ''ServiceRegistry'' object, useful to get hold of Alfresco service objects&lt;br /&gt;
|-&lt;br /&gt;
| nodes&lt;br /&gt;
| A convenience object to get node information using the ''NodeRef''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopParams'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getFolderNode()&lt;br /&gt;
| Returns the parent folder NodeRef that the script is running in.&lt;br /&gt;
|-&lt;br /&gt;
| int numberOfTargetNodes()&lt;br /&gt;
| The number of nodes selected on the client.&lt;br /&gt;
|-&lt;br /&gt;
| DesktopTarget getTarget(int idx)&lt;br /&gt;
| Get the details of the specified selected node, as a ''DesktopTarget'' object.&lt;br /&gt;
See below for a list of useful methods on the ''DesktopTarget'' object.&lt;br /&gt;
|-&lt;br /&gt;
| String getPathAt(int idx)&lt;br /&gt;
| Return the relative path of the specified selected node.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''DesktopTarget'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFile()&lt;br /&gt;
| Returns ''true'' if the node is a file.&lt;br /&gt;
|-&lt;br /&gt;
| boolean isFolder()&lt;br /&gt;
| Returns ''true'' if the node is a folder.&lt;br /&gt;
|-&lt;br /&gt;
| String getPath()&lt;br /&gt;
| Return the relative path of the target node.&lt;br /&gt;
|-&lt;br /&gt;
| String getExtension()&lt;br /&gt;
| Return the file extension of the file node, ie. the part after the last dot in the file path.&lt;br /&gt;
|-&lt;br /&gt;
| String getParentPath()&lt;br /&gt;
| Return the relative parent path of this node.&lt;br /&gt;
|-&lt;br /&gt;
| NodeRef getNode()&lt;br /&gt;
| Return the node for the selected file/folder.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''Nodes'' object has the following useful methods that a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| isVersionable( NodeRef)&lt;br /&gt;
| Check if the node has the ''Versionable'' aspect&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopy( NodeRef)&lt;br /&gt;
| Check if the node is a working copy&lt;br /&gt;
|-&lt;br /&gt;
| isWorkingCopyOriginal( NodeRef)&lt;br /&gt;
| Check if the node is the original document of a working copy, the document will be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLockable( NodeRef)&lt;br /&gt;
| Check if the node can be locked&lt;br /&gt;
|-&lt;br /&gt;
| isLocked( NodeRef)&lt;br /&gt;
| Check if the node is locked&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ''RunScriptResponse'' object has the following useful methods a server-side script can call :-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Method Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| void setSuccess()&lt;br /&gt;
| Return a success status to the client application.&lt;br /&gt;
|-&lt;br /&gt;
| void setError(String errMsg)&lt;br /&gt;
| Return an error status to the client application with the specified error message that will be displayed on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setClientOpenURL(String url)&lt;br /&gt;
| Return a success to the client application with a URL to be opened in a web browser on the client.&lt;br /&gt;
|-&lt;br /&gt;
| void setClientMessage(String msg)&lt;br /&gt;
| Return an informational message to the client application to be displayed using the standard client message dialog.&lt;br /&gt;
|-&lt;br /&gt;
| void setClientMessage(String msg, String msgLevel)&lt;br /&gt;
| Return a message to the client application to be displayed using the standard client message dialog, with a message level of either ''Info'', ''Warn'' or ''Error''. The client message dialog will display a different icon depending on the ''msgLevel'' value.&lt;br /&gt;
|-&lt;br /&gt;
| void setClientExecute(String operation, String app)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
| void setClientExecute(String operation, String app, String param)&lt;br /&gt;
| Return details of an application to be opened on the client with the specified operation and parameter.&lt;br /&gt;
On Windows clients the application will be started using the ShellExecute() API call.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:AlfrescoCheckOut.png&amp;diff=264</id>
		<title>File:AlfrescoCheckOut.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:AlfrescoCheckOut.png&amp;diff=264"/>
		<updated>2024-09-25T10:08:27Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:AlfrescoCheckIn.png&amp;diff=263</id>
		<title>File:AlfrescoCheckIn.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:AlfrescoCheckIn.png&amp;diff=263"/>
		<updated>2024-09-25T10:08:10Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:FileSysOrg.png&amp;diff=262</id>
		<title>File:FileSysOrg.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:FileSysOrg.png&amp;diff=262"/>
		<updated>2024-09-25T10:07:59Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:FileSysOrgAlfresco.png&amp;diff=261</id>
		<title>File:FileSysOrgAlfresco.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:FileSysOrgAlfresco.png&amp;diff=261"/>
		<updated>2024-09-25T10:07:45Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
	<entry>
		<id>http://filesys.org/wiki/index.php?title=File:ShellGear.png&amp;diff=260</id>
		<title>File:ShellGear.png</title>
		<link rel="alternate" type="text/html" href="http://filesys.org/wiki/index.php?title=File:ShellGear.png&amp;diff=260"/>
		<updated>2024-09-25T10:07:31Z</updated>

		<summary type="html">&lt;p&gt;Tommygonk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tommygonk</name></author>
		
	</entry>
</feed>