blob: e043f240844548041ebfac99ea5a26969b3b4344 [file]
<!-- jQuery Eclipse IP approval https://dev.eclipse.org/ipzilla/show_bug.cgi?id=10801 -->
<script type="text/javascript" charset="utf8" src="../../../docs/assets/scripts/jquery-1.8.1.min.js"></script>
<script type="text/javascript" charset="utf8">
$(document).ready(function(){
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var image = images[i];
var parentElement = image.parentElement;
var a = document.createElement('a');
if (! image.getAttribute('src').includes("logo-codenvy.svg") && ! image.getAttribute('src').includes("codenvy-contribute.svg") ){
a.href = image.getAttribute('src');
a.target = "_blank";
a.appendChild(image);
parentElement.appendChild(a);
}
}
});
</script>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<title>SDK Services -
Docs
- Eclipse Che</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Jekyll v3.5.1">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
<link rel="stylesheet" href="../../../docs/assets/css/screen.css">
<link rel="icon" type="image/x-icon" href="../../../docs/assets/imgs/favicon.ico">
<!--[if lt IE 9]>
<script src="/js/html5shiv.min.js"></script>
<script src="/js/respond.min.js"></script>
<![endif]-->
</head>
<body class="wrap">
<header>
<nav class="mobile-nav show-on-mobiles">
<ul>
<li class="current">
<a href="../../../docs/index.html">Docs</a>
</li>
<li class="">
<a href="../../../docs/tutorials/multi-machine/index.html">Tutorials</a>
</li>
<li class="">
<a href="../../../docs/openshift/config/index.html">OpenShift</a>
</li>
<li>
<a href="https://github.com/eclipse/che-docs/tree/master/src/main">GitHub</a>
</li>
</ul>
</nav>
<div class="grid">
<div class="unit one-third center-on-mobiles">
<a href="https://eclipse.org/che/">
<span class="sr-only">Eclipse Che</span>
<img src="../../../docs/assets/imgs/logo-eclipseche.svg" alt="Eclipse Che Logo" width="249" height="115">
</a>
</div>
<nav class="main-nav unit two-thirds hide-on-mobiles">
<ul>
<li class="current">
<a href="../../../docs/index.html">Docs</a>
</li>
<li class="">
<a href="../../../docs/tutorials/multi-machine/index.html">Tutorials</a>
</li>
<li class="">
<a href="../../../docs/openshift/config/index.html">OpenShift</a>
</li>
<li>
<a href="https://github.com/eclipse/che-docs/tree/master/src/main">GitHub</a>
</li>
</ul>
</nav>
</div>
</header>
<section class="docs">
<div class="grid">
<div class="docs-nav-mobile unit whole show-on-mobiles">
<select onchange="if (this.value) window.location.href=this.value">
<option value="">Navigate the docs…</option>
<optgroup label="SETUP">
<ul>
<option value="../../../docs/index.html">Introduction</option>
<option value="../../../docs/setup/getting-started/index.html">Getting Started&#58 Local</option>
<option value="../../../docs/setup/getting-started-saas-cloud/index.html">Getting Started&#58 SaaS Cloud</option>
<option value="../../../docs/setup/configuration/index.html">Configuration</option>
<option value="../../../docs/setup/managing/index.html">Managing</option>
<option value="../../../docs/setup/cli/index.html">CLI Reference</option>
<option value="../../../docs/setup/glossary/index.html">Glossary</option>
<option value="../../../docs/setup/docker/index.html">Docker Installation</option>
<option value="../../../docs/setup/openshift/index.html">OpenShift Installation</option>
<option value="../../../docs/setup/selenium/index.html">How to run selenium tests</option>
</ul>
<ul>
<li class=""><a href="../../../docs/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/setup/getting-started/index.html">Getting Started&#58 Local</a></li>
<li class=""><a href="../../../docs/setup/getting-started-saas-cloud/index.html">Getting Started&#58 SaaS Cloud</a></li>
<li class=""><a href="../../../docs/setup/configuration/index.html">Configuration</a></li>
<li class=""><a href="../../../docs/setup/managing/index.html">Managing</a></li>
<li class=""><a href="../../../docs/setup/cli/index.html">CLI Reference</a></li>
<li class=""><a href="../../../docs/setup/glossary/index.html">Glossary</a></li>
<li class=""><a href="../../../docs/setup/docker/index.html">Docker Installation</a></li>
<li class=""><a href="../../../docs/setup/openshift/index.html">OpenShift Installation</a></li>
<li class=""><a href="../../../docs/setup/selenium/index.html">How to run selenium tests</a></li>
</ul>
</optgroup>
<optgroup label="WORKSPACE ADMINISTRATION">
<ul>
<option value="../../../docs/devops/intro/index.html">Introduction</option>
<option value="../../../docs/devops/runtime-stacks/index.html">Runtime Stacks</option>
<option value="../../../docs/devops/runtime-recipes/index.html">Runtime Recipes</option>
<option value="../../../docs/devops/project-samples/index.html">Project Samples</option>
<option value="../../../docs/devops/runtime-machines/index.html">Runtime Machines</option>
<option value="../../../docs/devops/volume-mounts/index.html">Volume Mounts</option>
<option value="../../../docs/devops/ws-agents/index.html">Workspace Agents</option>
<option value="../../../docs/devops/workspaces-data-model/index.html">Workspace Data Model</option>
<option value="../../../docs/devops/runtime-stacks-data-model/index.html">Runtime Stacks Data Model</option>
<option value="../../../docs/devops/project-samples-data-model/index.html">Project Samples Data Model</option>
</ul>
<ul>
<li class=""><a href="../../../docs/devops/intro/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/devops/runtime-stacks/index.html">Runtime Stacks</a></li>
<li class=""><a href="../../../docs/devops/runtime-recipes/index.html">Runtime Recipes</a></li>
<li class=""><a href="../../../docs/devops/project-samples/index.html">Project Samples</a></li>
<li class=""><a href="../../../docs/devops/runtime-machines/index.html">Runtime Machines</a></li>
<li class=""><a href="../../../docs/devops/volume-mounts/index.html">Volume Mounts</a></li>
<li class=""><a href="../../../docs/devops/ws-agents/index.html">Workspace Agents</a></li>
<li class=""><a href="../../../docs/devops/workspaces-data-model/index.html">Workspace Data Model</a></li>
<li class=""><a href="../../../docs/devops/runtime-stacks-data-model/index.html">Runtime Stacks Data Model</a></li>
<li class=""><a href="../../../docs/devops/project-samples-data-model/index.html">Project Samples Data Model</a></li>
</ul>
</optgroup>
<optgroup label="USER GUIDE">
<ul>
<option value="../../../docs/ide/projects/index.html">Projects</option>
<option value="../../../docs/ide/import-a-project/index.html">Import</option>
<option value="../../../docs/ide/ssh/index.html">SSH</option>
<option value="../../../docs/ide/sync/index.html">Local IDE Sync</option>
<option value="../../../docs/ide/editor-settings/index.html">Editor</option>
<option value="../../../docs/ide/intellisense/index.html">Intellisense</option>
<option value="../../../docs/ide/commands/index.html">Commands</option>
<option value="../../../docs/ide/git-svn/index.html">Git and SVN</option>
<option value="../../../docs/ide/previews/index.html">Previews</option>
<option value="../../../docs/ide/build/index.html">Build</option>
<option value="../../../docs/ide/run/index.html">Run</option>
<option value="../../../docs/ide/sharing/index.html">Share</option>
<option value="../../../docs/ide/debug/index.html">Debug</option>
<option value="../../../docs/ide/docker/index.html">Docker</option>
<option value="../../../docs/ide/electron/index.html">Install Che Desktop Client</option>
</ul>
<ul>
<li class=""><a href="../../../docs/ide/projects/index.html">Projects</a></li>
<li class=""><a href="../../../docs/ide/import-a-project/index.html">Import</a></li>
<li class=""><a href="../../../docs/ide/ssh/index.html">SSH</a></li>
<li class=""><a href="../../../docs/ide/sync/index.html">Local IDE Sync</a></li>
<li class=""><a href="../../../docs/ide/editor-settings/index.html">Editor</a></li>
<li class=""><a href="../../../docs/ide/intellisense/index.html">Intellisense</a></li>
<li class=""><a href="../../../docs/ide/commands/index.html">Commands</a></li>
<li class=""><a href="../../../docs/ide/git-svn/index.html">Git and SVN</a></li>
<li class=""><a href="../../../docs/ide/previews/index.html">Previews</a></li>
<li class=""><a href="../../../docs/ide/build/index.html">Build</a></li>
<li class=""><a href="../../../docs/ide/run/index.html">Run</a></li>
<li class=""><a href="../../../docs/ide/sharing/index.html">Share</a></li>
<li class=""><a href="../../../docs/ide/debug/index.html">Debug</a></li>
<li class=""><a href="../../../docs/ide/docker/index.html">Docker</a></li>
<li class=""><a href="../../../docs/ide/electron/index.html">Install Che Desktop Client</a></li>
</ul>
</optgroup>
<optgroup label="PORTABLE WORKSPACES">
<ul>
<option value="../../../docs/chedir/getting-started/index.html">Chedir - Getting Started</option>
<option value="../../../docs/chedir/why/index.html">Chedir - Why Chedir?</option>
<option value="../../../docs/chedir/installation/index.html">Chedir - Installation</option>
<option value="../../../docs/chedir/project-setup/index.html">Chedir - Project Setup</option>
<option value="../../../docs/chedir/up-and-down/index.html">Chedir - Up and Down</option>
<option value="../../../docs/chedir/chefiles/index.html">Chedir - Chefile</option>
<option value="../../../docs/chedir/ssh/index.html">Chedir - SSH</option>
<option value="../../../docs/chedir/factories/index.html">Chedir - Factories</option>
<option value="">Error Generating Page Link. Contact Maintainer./docs/factory-getting-started/</option>
<option value="">Error Generating Page Link. Contact Maintainer./docs/factory-creating/</option>
<option value="">Error Generating Page Link. Contact Maintainer./docs/factory-json-reference/</option>
</ul>
<ul>
<li class=""><a href="../../../docs/chedir/getting-started/index.html">Chedir - Getting Started</a></li>
<li class=""><a href="../../../docs/chedir/why/index.html">Chedir - Why Chedir?</a></li>
<li class=""><a href="../../../docs/chedir/installation/index.html">Chedir - Installation</a></li>
<li class=""><a href="../../../docs/chedir/project-setup/index.html">Chedir - Project Setup</a></li>
<li class=""><a href="../../../docs/chedir/up-and-down/index.html">Chedir - Up and Down</a></li>
<li class=""><a href="../../../docs/chedir/chefiles/index.html">Chedir - Chefile</a></li>
<li class=""><a href="../../../docs/chedir/ssh/index.html">Chedir - SSH</a></li>
<li class=""><a href="../../../docs/chedir/factories/index.html">Chedir - Factories</a></li>
<li class=""><a href="../../../docs/factory/getting-started/index.html">Factory - Getting Started</a></li>
<li class=""><a href="../../../docs/factory/creating/index.html">Factory - Creating</a></li>
<li class=""><a href="../../../docs/factory/json-reference/index.html">Factory - JSON Reference</a></li>
</ul>
</optgroup>
<optgroup label="DEVELOPER GUIDE - REST API">
<ul>
<option value="../../../docs/assemblies/intro/index.html">Introduction</option>
<option value="../../../docs/assemblies/archetype/index.html">Archetype</option>
<option value="../../../docs/assemblies/assembly-lifecycle/index.html">Assembly Dev Lifecycle</option>
<option value="../../../docs/assemblies/plugin-lifecycle/index.html">Plugin Lifecycle</option>
<option value="../../../docs/assemblies/sdk-rest-apis/index.html">SDK REST APIs</option>
<option value="../../../docs/assemblies/sdk-class-reference/index.html">SDK Class Reference</option>
<option value="../../../docs/assemblies/sdk-dependency-injection/index.html">SDK Dependency Injection</option>
<option value="../../../docs/assemblies/sdk-dto/index.html">SDK DTOs</option>
<option value="../../../docs/assemblies/sdk-properties/index.html">SDK Properties</option>
<option value="../../../docs/assemblies/sdk-code-editors/index.html">SDK Editors</option>
<option value="../../../docs/assemblies/sdk-embed-htmljs/index.html">SDK Embedded JavaScript</option>
<option value="../../../docs/assemblies/sdk-project-types/index.html">SDK Project Types</option>
<option value="../../../docs/assemblies/sdk-actions/index.html">SDK Actions</option>
<option value="../../../docs/assemblies/sdk-services/index.html">SDK Services</option>
<option value="../../../docs/assemblies/sdk-parts/index.html">SDK Parts</option>
<option value="../../../docs/assemblies/sdk-themes/index.html">SDK Themes</option>
<option value="../../../docs/assemblies/sdk-custom-agents/index.html">SDK Custom Agents</option>
<option value="../../../docs/assemblies/sdk-language-server-protocol/index.html">SDK Language Server Protocol</option>
<option value="../../../docs/assemblies/sdk-workspace/index.html">SDK Workspace</option>
</ul>
<ul>
<li class=""><a href="../../../docs/assemblies/intro/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/assemblies/archetype/index.html">Archetype</a></li>
<li class=""><a href="../../../docs/assemblies/assembly-lifecycle/index.html">Assembly Dev Lifecycle</a></li>
<li class=""><a href="../../../docs/assemblies/plugin-lifecycle/index.html">Plugin Lifecycle</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-rest-apis/index.html">SDK REST APIs</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-class-reference/index.html">SDK Class Reference</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-dependency-injection/index.html">SDK Dependency Injection</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-dto/index.html">SDK DTOs</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-properties/index.html">SDK Properties</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-code-editors/index.html">SDK Editors</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-embed-htmljs/index.html">SDK Embedded JavaScript</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-project-types/index.html">SDK Project Types</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-actions/index.html">SDK Actions</a></li>
<li class="current"><a href="../../../docs/assemblies/sdk-services/index.html">SDK Services</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-parts/index.html">SDK Parts</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-themes/index.html">SDK Themes</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-custom-agents/index.html">SDK Custom Agents</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-language-server-protocol/index.html">SDK Language Server Protocol</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-workspace/index.html">SDK Workspace</a></li>
</ul>
</optgroup>
</select>
</div>
<div class="unit four-fifths">
<article>
<div class="improve right hide-on-mobiles">
<a href="https://github.com/codenvy/che-docs/blob/master/src/main/_docs/assemblies/assemblies-sdk-services.md"><i class="fa fa-pencil"></i> &nbsp;Improve this page</a>
<!--<a href="https://github.com/eclipse/che/blob/master/docs/_docs/assemblies/assemblies-sdk-services.md"><i class="fa fa-pencil"></i> &nbsp;Improve this page</a>-->
</div>
<div class="doc-title">
<h1>SDK Services</h1>
<div class="doc-title-border">
</div>
</div>
<p>Many simple extensions to Che are directly implemented in the IDE running in the browser. This has the advantage that the execution of simple actions do not require any server round-trips and are therefore typically very fast.
However, more complex operations, especially when accessing resources from a project or the workspace require you to run on the server or within the workspace. Examples for such operations are validating files, compiling code, providing auto-completion or creating workspaces. All those operations are implemented as REST services and can be consumed by the client IDE.</p>
<p>Services can either be deployed on the server or directly in a workspace. Server services provide generic features which are not depending on the Workspace or its content, e.g. user management. Workspace services can access the contents of a project (e.g. source files) and also trigger operations in the workspace (such as compilation).
In the following, we will describe how to create server and workspace services and how they are consumed from the client IDE. As the specification of workspace services is a special case of specifying server services, we will start with a simple server service, including an introduction of general basics about services.
Based on that, in the subsequent section “Workspace Services”, we will describe a more complex example, which accesses the files of a specific project.
Server and Workspace services need to be deployed differently, please refer to the section <a href="../../../docs/assemblies/plugin-lifecycle/index.html">Create and build extensions</a> to learn how.</p>
<h2 id="server-services">Server Services</h2>
<p>The following diagram shows all components of server services. The classes highlighted in dark grey are to be implemented for the extension. The <code class="highlighter-rouge">ServerService</code> offers a REST service to be consumed.
The IDE plugin implements a client class (<code class="highlighter-rouge">MyClient</code>), which calls the REST service using Che helper classes. The result is made available by a Java API, which is to be defined based on the result type. By calling the client class, different components of the IDE, such as <code class="highlighter-rouge">Actions</code> or <code class="highlighter-rouge">CodeCompletionProcessors</code>, can consume the <code class="highlighter-rouge">ServerService</code> without having to deal with the REST API itself.
<img src="../../../docs/assets/imgs/image15.png" alt="image15.png" />
In the following, we will describe how to build a simple example server service that accepts a String {name} and responds with “Hello {name} !”.
Further, we will demonstrate how this service can be consumed from within the client IDE.
c
Every REST service defines the path under which it is reachable. In the following code example, the path consists of two parts. The first one identifies the service itself and is specified with the @Path annotation of the class itself, in this case “hello”.
The second part of the path defines a parameter for the @GET method to be called and is specified with the @Path annotation at the method <code class="highlighter-rouge">#sayHello</code> itself, in this case “name”.
In combination, this example will register a service that will listen to localhost:8080/api/hello/{name}, where {name} is an arbitrary String to be passed by the client.
As specified using the @PathParam annotation, the {name} parameter will be passed as an input and then be used in the return statement.</p>
<p><em>che/samples/sample-serverservice/che-sample-plugin-serverservice-server/src/main/java/org/eclipse/che/plugin/serverservice/MyService.java</em></p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="nd">@Path</span><span class="o">(</span><span class="s">"hello"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyService</span> <span class="o">{</span>
<span class="nd">@GET</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"{name}"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">String</span> <span class="nf">sayHello</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">"name"</span><span class="o">)</span> <span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"Hello "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">" !"</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span><span class="n">s</span>
</code></pre>
</div>
<p>To make the server service consumable within the IDE, we implement a client encapsulating the REST call (see following code example).
Therefore, the client will offer a method <code class="highlighter-rouge">#getHello</code>, which can be called by any IDE component with a parameter “name”. To send an asynchronous REST request, the client uses two Che utilities, the <code class="highlighter-rouge">AsyncRequestFactory</code> and the <code class="highlighter-rouge">LoaderFactory</code>, which both get injected into the constructor.</p>
<p>The <code class="highlighter-rouge">AsyncRequestFactory</code> simplifies the creation of REST calls by providing a method <code class="highlighter-rouge">#createGetRequest</code> which will create a request using the provided parameter as a path. It will automatically prefix this path with the current server URL used by the IDE, so the parameter “hello” would be bound to http://serveradress/hello.</p>
<p>The request is sent by passing in an <code class="highlighter-rouge">Unmarshaller</code>. It is responsible for unmarshalling the response from the transport format (JSON) to a Java type, e.g. a String. Che already provides a collection of <code class="highlighter-rouge">Unmarshallers</code>, please see the section <a href="../../../docs/assemblies/sdk-rest-apis/index.html">Calling Workspace APIs</a> for details.</p>
<p>Finally, the send method returns a <code class="highlighter-rouge">Promise</code>, which can be consumed by callers on <code class="highlighter-rouge">MyClient</code> (see below) to retrieve the answer from the server.</p>
<p><em>che/samples/sample-serverservice/che-sample-plugin-serverservice-ide/src/main/java/org/eclipse/che/plugin/serverservice/ide/MyServiceClient.java</em></p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="o">/</span><span class="n">che</span><span class="o">-</span><span class="n">ide</span><span class="o">-</span><span class="n">extension</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">main</span><span class="o">/</span><span class="n">java</span><span class="o">/</span><span class="n">examples</span><span class="o">/</span><span class="n">MyServiceClient</span><span class="o">.</span><span class="na">java</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyServiceClient</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">AsyncRequestFactory</span> <span class="n">asyncRequestFactory</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">helloPath</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">LoaderFactory</span> <span class="n">loaderFactory</span><span class="o">;</span>
<span class="nd">@Inject</span>
<span class="kd">public</span> <span class="nf">MyServiceClient</span><span class="o">(</span><span class="n">AsyncRequestFactory</span> <span class="n">asyncRequestFactory</span><span class="o">,</span>
<span class="n">LoaderFactory</span> <span class="n">loaderFactory</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">asyncRequestFactory</span> <span class="o">=</span> <span class="n">asyncRequestFactory</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">loaderFactory</span> <span class="o">=</span> <span class="n">loaderFactory</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">//Can be invoked by consumers</span>
<span class="kd">public</span> <span class="n">Promise</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="nf">getHello</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">asyncRequestFactory</span><span class="o">.</span><span class="na">createGetRequest</span><span class="o">(</span><span class="err">“</span><span class="n">hello</span><span class="err">”</span> <span class="o">+</span> <span class="s">"/"</span> <span class="o">+</span> <span class="n">name</span><span class="o">)</span>
<span class="o">.</span><span class="na">loader</span><span class="o">(</span><span class="n">loaderFactory</span><span class="o">.</span><span class="na">newLoader</span><span class="o">(</span><span class="s">"Waiting for hello..."</span><span class="o">))</span>
<span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="k">new</span> <span class="n">StringUnmarshaller</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Now, <code class="highlighter-rouge">MyClient</code> can be consumed from any other component in the IDE without having to deal with the REST call itself.
The following example action gets the <code class="highlighter-rouge">MyServiceClient</code> injected and calls the <code class="highlighter-rouge">#getHello</code> method to retrieve the <code class="highlighter-rouge">Promise</code>.
On the <code class="highlighter-rouge">Promise</code> you can pass in an operation to be executed if the server call has been successful using the <code class="highlighter-rouge">#then</code> method. As we have used a <code class="highlighter-rouge">StringUnmarshaller</code> before, the parameter will be the String created by the server service.
In the example, it is passed to the Che <code class="highlighter-rouge">NotificationManager</code>. Using the <code class="highlighter-rouge">#catchError</code> method on the <code class="highlighter-rouge">Promise</code>, you can define an operation to be executed on an error during the server call.</p>
<p><em>che/samples/sample-serverservice/che-sample-plugin-serverservice-ide/src/main/java/org/eclipse/che/plugin/serverservice/ide/action/MyAction.java</em></p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyAction</span> <span class="kd">extends</span> <span class="n">Action</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">NotificationManager</span> <span class="n">notificationManager</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">MyServiceClient</span> <span class="n">serviceClient</span><span class="o">;</span>
<span class="nd">@Inject</span>
<span class="kd">public</span> <span class="nf">MyAction</span><span class="o">(</span><span class="n">MyResources</span> <span class="n">resources</span><span class="o">,</span> <span class="n">NotificationManager</span>
<span class="n">notificationManager</span><span class="o">,</span> <span class="n">MyServiceClient</span> <span class="n">serviceClient</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="s">"My Action"</span><span class="o">,</span> <span class="s">"My Action Description"</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span>
<span class="n">resources</span><span class="o">.</span><span class="na">MyProjectTypeIcon</span><span class="o">());</span>
<span class="k">this</span><span class="o">.</span><span class="na">notificationManager</span> <span class="o">=</span> <span class="n">notificationManager</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">serviceClient</span> <span class="o">=</span> <span class="n">serviceClient</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">actionPerformed</span><span class="o">(</span><span class="n">ActionEvent</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// This calls the service in the workspace.</span>
<span class="c1">// This method is in our MyServiceClient class</span>
<span class="c1">// This is a Promise, so the .then() method is invoked after the response is made</span>
<span class="n">serviceClient</span><span class="o">.</span><span class="na">getHello</span><span class="o">(</span><span class="s">"CheTheAllPowerful!"</span><span class="o">).</span><span class="na">then</span><span class="o">(</span><span class="k">new</span> <span class="n">Operation</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;()</span>
<span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">apply</span><span class="o">(</span><span class="n">String</span> <span class="n">arg</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">OperationException</span> <span class="o">{</span>
<span class="c1">// This passes the response String to the notification manager.</span>
<span class="n">notificationManager</span><span class="o">.</span><span class="na">notify</span><span class="o">(</span><span class="n">arg</span><span class="o">,</span> <span class="n">StatusNotification</span><span class="o">.</span><span class="na">Status</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">,</span> <span class="n">StatusNotification</span><span class="o">.</span><span class="na">DisplayMode</span><span class="o">.</span><span class="na">FLOAT_MODE</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}).</span><span class="na">catchError</span><span class="o">(</span><span class="k">new</span> <span class="n">Operation</span><span class="o">&lt;</span><span class="n">PromiseError</span><span class="o">&gt;()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">apply</span><span class="o">(</span><span class="n">PromiseError</span> <span class="n">arg</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">OperationException</span> <span class="o">{</span>
<span class="n">notificationManager</span><span class="o">.</span><span class="na">notify</span><span class="o">(</span><span class="s">"Fail"</span><span class="o">,</span> <span class="n">StatusNotification</span><span class="o">.</span><span class="na">Status</span><span class="o">.</span><span class="na">FAIL</span><span class="o">,</span> <span class="n">StatusNotification</span><span class="o">.</span><span class="na">DisplayMode</span><span class="o">.</span><span class="na">FLOAT_MODE</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span>
</code></pre>
</div>
<h2 id="workspace-services">Workspace Services</h2>
<p>Workspace services are special types of server services, they are deployed directly within the workspace agent. Therefore, they can access the content of a workspace, e.g. projects, source files, etc. Furthermore, they can trigger native operations in the running workspace.
Besides their different scope, workspace services are developed like standard server services using REST. Therefore, we recommend to first cover the previous section about <a href="../../../docs/assemblies/sdk-services/index.html#server-services">Server Services</a>. The main difference between workspace and server services is where they are actually deployed to. Please refer to the section <a href="../../../docs/assemblies/plugin-lifecycle/index.html">Create and build extensions</a> to learn how to deploy services correctly.</p>
<p>In the following, we describe an example workspace service from the JSON example, which accesses a selected project and counts the number of lines in all JSON files. This demonstrates how to access files and their content. In a custom use case, this could be adapted to do any kind of file operation, e.g. parsing contents for auto completion. After introducing the service, we demonstrate how it can be consumed by an action from within the IDE.</p>
<p>Like a server service, workspace services need to define the path in which they are reachable at. As they are running for a specific workspace, the path includes the variable {ws-id}, which identifies the workspace the service is running in (see @Path annotation in the following code example). The example service gets the Che <code class="highlighter-rouge">ProjectManager</code> injected in the constructor. It allows to access projects and their contents. Please note that this service is not available for server services.</p>
<p>The method <code class="highlighter-rouge">#countLinesPerFile</code> receives a <code class="highlighter-rouge">projectPath</code> as a parameter for which it should count the number of lines. It uses the <code class="highlighter-rouge">ProjectManager</code> to retrieve the project. Using the project, it then navigates over all JSON files in the project and accesses the contents of those files to count the lines. Finally, it returns the result as a map.</p>
<p><em>che/samples/sample-plugin-json/che-sample-plugin-json-server/src/main/java/org/eclipse/che/plugin/jsonexample/JsonLocService.java</em></p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="n">org</span><span class="o">.</span><span class="na">eclipse</span><span class="o">.</span><span class="na">che</span><span class="o">.</span><span class="na">plugin</span><span class="o">.</span><span class="na">jsonexample</span><span class="o">.</span><span class="na">JsonLocService</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"json-example/{ws-id}"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">JsonLocService</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">ProjectManager</span> <span class="n">projectManager</span><span class="o">;</span>
<span class="nd">@Inject</span>
<span class="kd">public</span> <span class="nf">JsonLocService</span><span class="o">(</span><span class="n">ProjectManager</span> <span class="n">projectManager</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">projectManager</span> <span class="o">=</span> <span class="n">projectManager</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@GET</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"{projectPath}"</span><span class="o">)</span>
<span class="kd">public</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="nf">countLinesPerFile</span><span class="o">(</span>
<span class="nd">@PathParam</span><span class="o">(</span><span class="s">"projectPath"</span><span class="o">)</span> <span class="n">String</span> <span class="n">projectPath</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ServerException</span><span class="o">,</span> <span class="n">NotFoundException</span><span class="o">,</span> <span class="n">ForbiddenException</span> <span class="o">{</span>
<span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="n">linesPerFile</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedHashMap</span><span class="o">&lt;&gt;();</span>
<span class="n">RegisteredProject</span> <span class="n">project</span> <span class="o">=</span> <span class="n">projectManager</span><span class="o">.</span><span class="na">getProject</span><span class="o">(</span><span class="n">projectPath</span><span class="o">);</span>
<span class="k">for</span> <span class="o">(</span><span class="n">FileEntry</span> <span class="n">child</span> <span class="o">:</span> <span class="n">project</span><span class="o">.</span><span class="na">getBaseFolder</span><span class="o">().</span><span class="na">getChildFiles</span><span class="o">())</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">isJsonFile</span><span class="o">(</span><span class="n">child</span><span class="o">))</span> <span class="o">{</span>
<span class="n">linesPerFile</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">child</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="n">Integer</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="n">countLines</span><span class="o">(</span><span class="n">child</span><span class="o">)));</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">linesPerFile</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">countLines</span><span class="o">(</span><span class="n">FileEntry</span> <span class="n">fileEntry</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ServerException</span><span class="o">,</span> <span class="n">ForbiddenException</span> <span class="o">{</span>
<span class="n">String</span> <span class="n">content</span> <span class="o">=</span> <span class="n">fileEntry</span><span class="o">.</span><span class="na">getVirtualFile</span><span class="o">().</span><span class="na">getContentAsString</span><span class="o">();</span>
<span class="n">String</span><span class="o">[]</span> <span class="n">lines</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">"\r\n|\r|\n"</span><span class="o">);</span>
<span class="k">return</span> <span class="n">lines</span><span class="o">.</span><span class="na">length</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isJsonFile</span><span class="o">(</span><span class="n">FileEntry</span> <span class="n">fileEntry</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">fileEntry</span><span class="o">.</span><span class="na">getName</span><span class="o">().</span><span class="na">endsWith</span><span class="o">(</span><span class="s">"json"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>To access workspace services on the client-side, the path needs to include the workspace ID as well as the project ID. Both can be retrieved using the <code class="highlighter-rouge">AppContext</code>. Furthermore, all services running within the workspace have a basic context path which can be retrieved from the <code class="highlighter-rouge">AppContext</code>.</p>
<p>The following example creates a path, which would access the service above with the current project as a parameter:</p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="n">String</span> <span class="n">url</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">appContext</span><span class="o">.</span><span class="na">getDevMachine</span><span class="o">().</span><span class="na">getWsAgentBaseUrl</span><span class="o">()</span>
<span class="o">+</span> <span class="s">"/json-example/"</span>
<span class="o">+</span> <span class="n">appContext</span><span class="o">.</span><span class="na">getWorkspaceId</span><span class="o">()</span>
<span class="o">+</span> <span class="n">appContext</span><span class="o">.</span><span class="na">getCurrentProject</span><span class="o">().</span><span class="na">getProjectConfig</span><span class="o">().</span><span class="na">getPath</span><span class="o">();</span>
</code></pre>
</div>
<p>Besides the specific path, workspace services can be consumed like any other server service using the REST utilities of Che. Please have a look at the sections <a href="../../../docs/assemblies/sdk-services/index.html">Server Services</a> and Client Server Communication for more details.</p>
<p>The following example action consumes the workspace service defined above and shows the result using the notification manager.</p>
<p><em>che/samples/sample-plugin-json/che-sample-plugin-json-ide/src/main/java/org/eclipse/che/plugin/jsonexample/ide/action/CountLinesAction.java</em></p>
<div class="language-java highlighter-rouge"><pre class="highlight"><code><span class="n">org</span><span class="o">.</span><span class="na">eclipse</span><span class="o">.</span><span class="na">che</span><span class="o">.</span><span class="na">plugin</span><span class="o">.</span><span class="na">jsonexample</span><span class="o">.</span><span class="na">ide</span><span class="o">.</span><span class="na">action</span><span class="o">.</span><span class="na">CountLocAction</span>
<span class="nd">@Singleton</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">CountLinesAction</span> <span class="kd">extends</span> <span class="n">JsonExampleProjectAction</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">AppContext</span> <span class="n">appContext</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="n">StringMapUnmarshaller</span> <span class="n">unmarshaller</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">AsyncRequestFactory</span> <span class="n">asyncRequestFactory</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">NotificationManager</span> <span class="n">notificationManager</span><span class="o">;</span>
<span class="nd">@Inject</span>
<span class="kd">public</span> <span class="nf">CountLinesAction</span><span class="o">(</span><span class="n">AppContext</span> <span class="n">appContext</span><span class="o">,</span>
<span class="n">JsonExampleResources</span> <span class="n">resources</span><span class="o">,</span>
<span class="n">AsyncRequestFactory</span> <span class="n">asyncRequestFactory</span><span class="o">,</span>
<span class="n">NotificationManager</span> <span class="n">notificationManager</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">appContext</span><span class="o">,</span>
<span class="s">"Count JSON Lines of Code"</span><span class="o">,</span>
<span class="s">"Counts lines of code for all JSON Files in the project"</span><span class="o">,</span>
<span class="n">resources</span><span class="o">.</span><span class="na">icon</span><span class="o">());</span>
<span class="k">this</span><span class="o">.</span><span class="na">appContext</span> <span class="o">=</span> <span class="n">appContext</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">asyncRequestFactory</span> <span class="o">=</span> <span class="n">asyncRequestFactory</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">notificationManager</span> <span class="o">=</span> <span class="n">notificationManager</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">unmarshaller</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringMapUnmarshaller</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">actionPerformed</span><span class="o">(</span><span class="n">ActionEvent</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="n">String</span> <span class="n">url</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">appContext</span><span class="o">.</span><span class="na">getDevMachine</span><span class="o">().</span><span class="na">getWsAgentBaseUrl</span><span class="o">()</span>
<span class="o">+</span> <span class="s">"/json-example/"</span>
<span class="o">+</span> <span class="k">this</span><span class="o">.</span><span class="na">appContext</span><span class="o">.</span><span class="na">getWorkspaceId</span><span class="o">()</span>
<span class="o">+</span> <span class="k">this</span><span class="o">.</span><span class="na">appContext</span><span class="o">.</span><span class="na">getCurrentProject</span><span class="o">().</span><span class="na">getProjectConfig</span><span class="o">().</span><span class="na">getPath</span><span class="o">();</span>
<span class="n">asyncRequestFactory</span><span class="o">.</span><span class="na">createGetRequest</span><span class="o">(</span><span class="n">url</span><span class="o">,</span> <span class="kc">false</span><span class="o">).</span><span class="na">send</span><span class="o">(</span>
<span class="k">new</span> <span class="n">AsyncRequestCallback</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;&gt;(</span><span class="n">unmarshaller</span><span class="o">)</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onSuccess</span><span class="o">(</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="n">linesPerFile</span><span class="o">)</span> <span class="o">{</span>
<span class="k">for</span> <span class="o">(</span><span class="n">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="n">entry</span> <span class="o">:</span> <span class="n">linesPerFile</span><span class="o">.</span><span class="na">entrySet</span><span class="o">())</span> <span class="o">{</span>
<span class="n">String</span> <span class="n">fileName</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">();</span>
<span class="n">String</span> <span class="n">loc</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="na">getValue</span><span class="o">();</span>
<span class="n">notificationManager</span><span class="o">.</span><span class="na">notify</span><span class="o">(</span>
<span class="s">"File "</span> <span class="o">+</span> <span class="n">fileName</span> <span class="o">+</span> <span class="s">" has "</span> <span class="o">+</span> <span class="n">loc</span> <span class="o">+</span> <span class="s">" lines."</span><span class="o">,</span>
<span class="n">StatusNotification</span><span class="o">.</span><span class="na">Status</span><span class="o">.</span><span class="na">SUCCESS</span><span class="o">,</span>
<span class="n">StatusNotification</span><span class="o">.</span><span class="na">DisplayMode</span><span class="o">.</span><span class="na">FLOAT_MODE</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onFailure</span><span class="o">(</span><span class="n">Throwable</span> <span class="n">exception</span><span class="o">)</span> <span class="o">{</span>
<span class="n">notificationManager</span><span class="o">.</span><span class="na">notify</span><span class="o">(</span>
<span class="n">exception</span><span class="o">.</span><span class="na">getMessage</span><span class="o">(),</span>
<span class="n">StatusNotification</span><span class="o">.</span><span class="na">Status</span><span class="o">.</span><span class="na">FAIL</span><span class="o">,</span>
<span class="n">StatusNotification</span><span class="o">.</span><span class="na">DisplayMode</span><span class="o">.</span><span class="na">FLOAT_MODE</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
</article>
</div>
<div class="unit one-fifth hide-on-mobiles">
<aside>
<h4>SETUP</h4>
<ul>
<li class=""><a href="../../../docs/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/setup/getting-started/index.html">Getting Started&#58 Local</a></li>
<li class=""><a href="../../../docs/setup/getting-started-saas-cloud/index.html">Getting Started&#58 SaaS Cloud</a></li>
<li class=""><a href="../../../docs/setup/configuration/index.html">Configuration</a></li>
<li class=""><a href="../../../docs/setup/managing/index.html">Managing</a></li>
<li class=""><a href="../../../docs/setup/cli/index.html">CLI Reference</a></li>
<li class=""><a href="../../../docs/setup/glossary/index.html">Glossary</a></li>
<li class=""><a href="../../../docs/setup/docker/index.html">Docker Installation</a></li>
<li class=""><a href="../../../docs/setup/openshift/index.html">OpenShift Installation</a></li>
<li class=""><a href="../../../docs/setup/selenium/index.html">How to run selenium tests</a></li>
</ul>
<h4>WORKSPACE ADMINISTRATION</h4>
<ul>
<li class=""><a href="../../../docs/devops/intro/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/devops/runtime-stacks/index.html">Runtime Stacks</a></li>
<li class=""><a href="../../../docs/devops/runtime-recipes/index.html">Runtime Recipes</a></li>
<li class=""><a href="../../../docs/devops/project-samples/index.html">Project Samples</a></li>
<li class=""><a href="../../../docs/devops/runtime-machines/index.html">Runtime Machines</a></li>
<li class=""><a href="../../../docs/devops/volume-mounts/index.html">Volume Mounts</a></li>
<li class=""><a href="../../../docs/devops/ws-agents/index.html">Workspace Agents</a></li>
<li class=""><a href="../../../docs/devops/workspaces-data-model/index.html">Workspace Data Model</a></li>
<li class=""><a href="../../../docs/devops/runtime-stacks-data-model/index.html">Runtime Stacks Data Model</a></li>
<li class=""><a href="../../../docs/devops/project-samples-data-model/index.html">Project Samples Data Model</a></li>
</ul>
<h4>USER GUIDE</h4>
<ul>
<li class=""><a href="../../../docs/ide/projects/index.html">Projects</a></li>
<li class=""><a href="../../../docs/ide/import-a-project/index.html">Import</a></li>
<li class=""><a href="../../../docs/ide/ssh/index.html">SSH</a></li>
<li class=""><a href="../../../docs/ide/sync/index.html">Local IDE Sync</a></li>
<li class=""><a href="../../../docs/ide/editor-settings/index.html">Editor</a></li>
<li class=""><a href="../../../docs/ide/intellisense/index.html">Intellisense</a></li>
<li class=""><a href="../../../docs/ide/commands/index.html">Commands</a></li>
<li class=""><a href="../../../docs/ide/git-svn/index.html">Git and SVN</a></li>
<li class=""><a href="../../../docs/ide/previews/index.html">Previews</a></li>
<li class=""><a href="../../../docs/ide/build/index.html">Build</a></li>
<li class=""><a href="../../../docs/ide/run/index.html">Run</a></li>
<li class=""><a href="../../../docs/ide/sharing/index.html">Share</a></li>
<li class=""><a href="../../../docs/ide/debug/index.html">Debug</a></li>
<li class=""><a href="../../../docs/ide/docker/index.html">Docker</a></li>
<li class=""><a href="../../../docs/ide/electron/index.html">Install Che Desktop Client</a></li>
</ul>
<h4>PORTABLE WORKSPACES</h4>
<ul>
<li class=""><a href="../../../docs/chedir/getting-started/index.html">Chedir - Getting Started</a></li>
<li class=""><a href="../../../docs/chedir/why/index.html">Chedir - Why Chedir?</a></li>
<li class=""><a href="../../../docs/chedir/installation/index.html">Chedir - Installation</a></li>
<li class=""><a href="../../../docs/chedir/project-setup/index.html">Chedir - Project Setup</a></li>
<li class=""><a href="../../../docs/chedir/up-and-down/index.html">Chedir - Up and Down</a></li>
<li class=""><a href="../../../docs/chedir/chefiles/index.html">Chedir - Chefile</a></li>
<li class=""><a href="../../../docs/chedir/ssh/index.html">Chedir - SSH</a></li>
<li class=""><a href="../../../docs/chedir/factories/index.html">Chedir - Factories</a></li>
<li class=""><a href="../../../docs/factory/getting-started/index.html">Factory - Getting Started</a></li>
<li class=""><a href="../../../docs/factory/creating/index.html">Factory - Creating</a></li>
<li class=""><a href="../../../docs/factory/json-reference/index.html">Factory - JSON Reference</a></li>
</ul>
<h4>DEVELOPER GUIDE - REST API</h4>
<ul>
<li class=""><a href="../../../docs/assemblies/intro/index.html">Introduction</a></li>
<li class=""><a href="../../../docs/assemblies/archetype/index.html">Archetype</a></li>
<li class=""><a href="../../../docs/assemblies/assembly-lifecycle/index.html">Assembly Dev Lifecycle</a></li>
<li class=""><a href="../../../docs/assemblies/plugin-lifecycle/index.html">Plugin Lifecycle</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-rest-apis/index.html">SDK REST APIs</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-class-reference/index.html">SDK Class Reference</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-dependency-injection/index.html">SDK Dependency Injection</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-dto/index.html">SDK DTOs</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-properties/index.html">SDK Properties</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-code-editors/index.html">SDK Editors</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-embed-htmljs/index.html">SDK Embedded JavaScript</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-project-types/index.html">SDK Project Types</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-actions/index.html">SDK Actions</a></li>
<li class="current"><a href="../../../docs/assemblies/sdk-services/index.html">SDK Services</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-parts/index.html">SDK Parts</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-themes/index.html">SDK Themes</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-custom-agents/index.html">SDK Custom Agents</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-language-server-protocol/index.html">SDK Language Server Protocol</a></li>
<li class=""><a href="../../../docs/assemblies/sdk-workspace/index.html">SDK Workspace</a></li>
</ul>
</aside>
</div>
<div class="clear"></div>
</div>
</section>
<script>
var anchorForId = function (id) {
var anchor = document.createElement("a");
anchor.className = "header-link";
anchor.href = "#" + id;
anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
anchor.title = "Permalink";
return anchor;
};
var linkifyAnchors = function (level, containingElement) {
var headers = containingElement.getElementsByTagName("h" + level);
for (var h = 0; h < headers.length; h++) {
var header = headers[h];
if (typeof header.id !== "undefined" && header.id !== "") {
header.appendChild(anchorForId(header.id));
}
}
};
document.onreadystatechange = function () {
if (this.readyState === "complete") {
var contentBlock = document.getElementsByClassName("artik")[0] || document.getElementsByClassName("openshift")[0] || document.getElementsByClassName("tutorials")[0] || document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
if (!contentBlock) {
return;
}
for (var level = 1; level <= 6; level++) {
linkifyAnchors(level, contentBlock);
}
}
};
</script>
</body>
</html>