Skip to content

Commit

Permalink
existing transport support
Browse files Browse the repository at this point in the history
  • Loading branch information
marcellourbani committed Nov 8, 2018
1 parent bb42331 commit a23470c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 29 deletions.
64 changes: 48 additions & 16 deletions src/abap/AbapObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export interface AbapMetaData {
masterLanguage?: string
masterSystem?: string
}
export enum TransportStatus {
UNKNOWN,
REQUIRED,
LOCAL
}
interface MainProgram {
"adtcore:uri": string
"adtcore:type": string
Expand All @@ -43,6 +48,8 @@ export class AbapObject {
readonly techName: string
readonly path: string
readonly expandable: boolean
lockId?: string
transport: TransportStatus | string = TransportStatus.UNKNOWN
metaData?: AbapMetaData
protected sapguiOnly: boolean

Expand Down Expand Up @@ -117,15 +124,8 @@ export class AbapObject {
)
}

async setContents(
connection: AdtConnection,
contents: Uint8Array
): Promise<void> {
if (!this.isLeaf()) throw FileSystemError.FileIsADirectory(this.vsName())
if (this.sapguiOnly)
throw FileSystemError.FileNotFound(
`${this.name} can only be edited in SAPGUI`
)
async lock(connection: AdtConnection) {
this.checkWritable()
let contentUri = this.getContentsUri(connection)

const response = await connection.request(
Expand All @@ -134,17 +134,49 @@ export class AbapObject {
{ headers: { "X-sap-adt-sessiontype": "stateful" } }
)
const lockRecord = await parsetoPromise(adtLockParser)(response.body)
const lock = encodeURIComponent(lockRecord.LOCK_HANDLE)

this.lockId = lockRecord.LOCK_HANDLE
this.transport =
lockRecord.CORRNR ||
(lockRecord.IS_LOCAL ? TransportStatus.LOCAL : TransportStatus.REQUIRED)
}
async unlock(connection: AdtConnection) {
this.checkWritable()
if (!this.lockId) return
let contentUri = this.getContentsUri(connection)
await connection.request(
contentUri.with({ query: `lockHandle=${lock}` }),
"PUT",
{ body: contents }
contentUri.with({
query: `_action=UNLOCK&lockHandle=${encodeURIComponent(this.lockId)}`
}),
"POST"
)
}

protected checkWritable() {
if (!this.isLeaf()) throw FileSystemError.FileIsADirectory(this.vsName())
if (this.sapguiOnly)
throw FileSystemError.FileNotFound(
`${this.name} can only be edited in SAPGUI`
)
}

async setContents(
connection: AdtConnection,
contents: Uint8Array
): Promise<void> {
this.checkWritable()
let contentUri = this.getContentsUri(connection)

const trselection =
typeof this.transport === "string" ? `&corrNr=${this.transport}` : ""

await connection.request(
contentUri.with({ query: `_action=UNLOCK&lockHandle=${lock}` }),
"POST"
contentUri.with({
query: `lockHandle=${encodeURIComponent(
this.lockId || ""
)}${trselection}`
}),
"PUT",
{ body: contents }
)
}

Expand Down
21 changes: 20 additions & 1 deletion src/adt/AdtServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AdtConnection } from "./AdtConnection"
import { Uri, FileSystemError, FileType, window, commands } from "vscode"
import { MetaFolder } from "../fs/MetaFolder"
import { AbapObjectNode, AbapNode, isAbap } from "../fs/AbapNode"
import { AbapObject } from "../abap/AbapObject"
import { AbapObject, TransportStatus } from "../abap/AbapObject"
import { getRemoteList } from "../config"
export const ADTBASEURL = "/sap/bc/adt/repository/nodestructure"

Expand Down Expand Up @@ -49,6 +49,25 @@ export class AdtServer {
new AbapObjectNode(new AbapObject("DEVC/K", "", ADTBASEURL, "X"))
)
}

async saveFile(file: AbapNode, content: Uint8Array): Promise<void> {
if (file.isFolder()) throw FileSystemError.FileIsADirectory()
if (!isAbap(file))
throw FileSystemError.NoPermissions("Can only save source code")

const conn = await this.connectionP
await file.abapObject.lock(conn)
if (file.abapObject.transport === TransportStatus.REQUIRED)
throw new Error("transport selection not supported(yet)")

await file.abapObject.setContents(conn, content)

await file.abapObject.unlock(conn)
await file.stat(conn)
//might have a race condition with user changing editor...
commands.executeCommand("setContext", "abapfs:objectInactive", true)
}

findNode(uri: Uri): AbapNode {
const parts = uriParts(uri)
return parts.reduce((current: any, name) => {
Expand Down
6 changes: 1 addition & 5 deletions src/fs/AbapNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,7 @@ export class AbapObjectNode implements FileStat, Iterable<[string, AbapNode]> {
return Promise.reject(e)
}
}
public save(connection: AdtConnection, contents: Uint8Array) {
if (this.isFolder()) throw FileSystemError.FileIsADirectory()
//returning a promise will allow the exceptions to propagate
return this.abapObject.setContents(connection, contents)
}

public refresh(connection: AdtConnection): Promise<AbapNode> {
return this.abapObject.getChildren(connection).then(objects => {
refreshObjects(this, objects)
Expand Down
9 changes: 2 additions & 7 deletions src/fs/FsProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from "vscode"
import { fromUri } from "../adt/AdtServer"
import { FileSystemError, commands } from "vscode"
import { FileSystemError } from "vscode"

export class FsProvider implements vscode.FileSystemProvider {
private _eventEmitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>()
Expand Down Expand Up @@ -58,12 +58,7 @@ export class FsProvider implements vscode.FileSystemProvider {
"Not a real filesystem, file creation is not supported"
)
if (!file) throw FileSystemError.FileNotFound(uri)
const connection = await server.connectionP
await file.save(connection, content)
//not active anymore... update the status. By the book we should check if it's set by this object first...
//TODO: move this logic somewhere else...
await this.stat(uri)
commands.executeCommand("setContext", "abapfs:objectInactive", true)
return server.saveFile(file, content)
}
delete(
uri: vscode.Uri,
Expand Down

0 comments on commit a23470c

Please sign in to comment.