From 2cb04309403d5fb045223fe35bf231ae29e5067a Mon Sep 17 00:00:00 2001 From: Adrien Castex Date: Mon, 15 May 2017 15:11:04 +0200 Subject: [PATCH] Implemented the MOVE method --- lib/resource/IResource.d.ts | 4 +-- lib/resource/physical/PhysicalResource.d.ts | 5 +-- lib/resource/physical/PhysicalResource.js | 28 ++++++++++++--- lib/resource/std/StandardResource.d.ts | 4 +-- lib/resource/virtual/VirtualResource.d.ts | 4 +-- lib/resource/virtual/VirtualResource.js | 22 ++++++++++-- lib/server/commands/Commands.js | 2 ++ lib/server/commands/Move.d.ts | 2 ++ lib/server/commands/Move.js | 33 +++++++++++++++++ src/resource/IResource.ts | 2 +- src/resource/physical/PhysicalResource.ts | 31 +++++++++++++--- src/resource/std/StandardResource.ts | 2 +- src/resource/virtual/VirtualResource.ts | 24 +++++++++++-- src/server/commands/Commands.ts | 2 ++ src/server/commands/Move.ts | 39 +++++++++++++++++++++ 15 files changed, 182 insertions(+), 22 deletions(-) create mode 100644 lib/server/commands/Move.d.ts create mode 100644 lib/server/commands/Move.js create mode 100644 src/server/commands/Move.ts diff --git a/lib/resource/IResource.d.ts b/lib/resource/IResource.d.ts index b941f3c5..1553429d 100644 --- a/lib/resource/IResource.d.ts +++ b/lib/resource/IResource.d.ts @@ -1,4 +1,4 @@ -import { FSManager, FSPath } from '../manager/FSManager'; +import { FSManager } from '../manager/FSManager'; import { XMLElement } from '../helper/XML'; import { LockKind } from './lock/LockKind'; import { Lock } from './lock/Lock'; @@ -23,7 +23,7 @@ export interface IResource { fsManager: FSManager; create(callback: SimpleCallback): any; delete(callback: SimpleCallback): any; - moveTo(to: FSPath, callback: Return2Callback): any; + moveTo(parent: IResource, newName: string, override: boolean, callback: SimpleCallback): any; rename(newName: string, callback: Return2Callback): any; isSame(resource: IResource, callback: ReturnCallback): any; isOnTheSameFSWith(resource: IResource, callback: ReturnCallback): any; diff --git a/lib/resource/physical/PhysicalResource.d.ts b/lib/resource/physical/PhysicalResource.d.ts index 302df712..1190130f 100644 --- a/lib/resource/physical/PhysicalResource.d.ts +++ b/lib/resource/physical/PhysicalResource.d.ts @@ -1,12 +1,13 @@ import { IResource, SimpleCallback, ReturnCallback, Return2Callback, ResourceType } from '../IResource'; -import { FSManager, FSPath } from '../../manager/FSManager'; +import { FSManager } from '../../manager/FSManager'; import { StandardResource } from '../std/StandardResource'; export declare abstract class PhysicalResource extends StandardResource { realPath: string; + name: string; constructor(realPath: string, parent?: IResource, fsManager?: FSManager); abstract create(callback: SimpleCallback): any; abstract delete(callback: SimpleCallback): any; - moveTo(to: FSPath, callback: Return2Callback): void; + moveTo(parent: IResource, newName: string, override: boolean, callback: SimpleCallback): void; rename(newName: string, callback: Return2Callback): void; webName(callback: ReturnCallback): void; abstract type(callback: ReturnCallback): any; diff --git a/lib/resource/physical/PhysicalResource.js b/lib/resource/physical/PhysicalResource.js index f2dbf0a2..2e09971c 100644 --- a/lib/resource/physical/PhysicalResource.js +++ b/lib/resource/physical/PhysicalResource.js @@ -25,10 +25,29 @@ var PhysicalResource = (function (_super) { fsManager = PhysicalFSManager_1.PhysicalFSManager.instance(); _this = _super.call(this, parent, fsManager) || this; _this.realPath = path.resolve(realPath); + _this.name = path.basename(_this.realPath); return _this; } - PhysicalResource.prototype.moveTo = function (to, callback) { - callback(new Error('Not implemented yet.'), null, null); + PhysicalResource.prototype.moveTo = function (parent, newName, override, callback) { + var _this = this; + if (parent === this.parent) { + this.rename(newName, function (e, oldName, newName) { + callback(e); + }); + return; + } + var oldName = this.name; + this.name = newName; + this.removeFromParent(function (e) { + if (e) { + _this.name = oldName; + callback(e); + } + else + parent.addChild(_this, function (e) { + callback(e); + }); + }); }; PhysicalResource.prototype.rename = function (newName, callback) { var _this = this; @@ -40,12 +59,13 @@ var PhysicalResource = (function (_super) { } var oldName = path.basename(_this.realPath); _this.realPath = newPath; + _this.name = newName; _this.updateLastModified(); - callback(e, oldName, newName); + callback(null, oldName, newName); }); }; PhysicalResource.prototype.webName = function (callback) { - callback(null, path.basename(this.realPath)); + callback(null, path.basename(this.name)); }; return PhysicalResource; }(StandardResource_1.StandardResource)); diff --git a/lib/resource/std/StandardResource.d.ts b/lib/resource/std/StandardResource.d.ts index b02ec441..242a9107 100644 --- a/lib/resource/std/StandardResource.d.ts +++ b/lib/resource/std/StandardResource.d.ts @@ -1,5 +1,5 @@ import { IResource, ReturnCallback, SimpleCallback, Return2Callback, ResourceType, ResourcePropertyValue } from '../IResource'; -import { FSManager, FSPath } from '../../manager/FSManager'; +import { FSManager } from '../../manager/FSManager'; import { LockKind } from '../lock/LockKind'; import { LockBag } from '../lock/LockBag'; import { Lock } from '../lock/Lock'; @@ -26,7 +26,7 @@ export declare abstract class StandardResource implements IResource { getProperties(callback: ReturnCallback): void; abstract create(callback: SimpleCallback): any; abstract delete(callback: SimpleCallback): any; - abstract moveTo(to: FSPath, callback: Return2Callback): any; + abstract moveTo(parent: IResource, newName: string, override: boolean, callback: SimpleCallback): any; abstract rename(newName: string, callback: Return2Callback): any; abstract append(data: Int8Array, callback: SimpleCallback): any; abstract write(data: Int8Array, callback: SimpleCallback): any; diff --git a/lib/resource/virtual/VirtualResource.d.ts b/lib/resource/virtual/VirtualResource.d.ts index 3f150e4f..1e2da72c 100644 --- a/lib/resource/virtual/VirtualResource.d.ts +++ b/lib/resource/virtual/VirtualResource.d.ts @@ -1,12 +1,12 @@ import { IResource, SimpleCallback, ReturnCallback, Return2Callback, ResourceType } from '../IResource'; -import { FSManager, FSPath } from '../../manager/FSManager'; +import { FSManager } from '../../manager/FSManager'; import { StandardResource } from '../std/StandardResource'; export declare abstract class VirtualResource extends StandardResource { name: string; constructor(name: string, parent?: IResource, fsManager?: FSManager); create(callback: SimpleCallback): void; delete(callback: SimpleCallback): void; - moveTo(to: FSPath, callback: Return2Callback): void; + moveTo(parent: IResource, newName: string, override: boolean, callback: SimpleCallback): void; rename(newName: string, callback: Return2Callback): void; webName(callback: ReturnCallback): void; abstract type(callback: ReturnCallback): any; diff --git a/lib/resource/virtual/VirtualResource.js b/lib/resource/virtual/VirtualResource.js index 5428e15b..89f5ba5c 100644 --- a/lib/resource/virtual/VirtualResource.js +++ b/lib/resource/virtual/VirtualResource.js @@ -31,8 +31,26 @@ var VirtualResource = (function (_super) { VirtualResource.prototype.delete = function (callback) { this.removeFromParent(callback); }; - VirtualResource.prototype.moveTo = function (to, callback) { - callback(new Error('Not implemented yet.'), null, null); + VirtualResource.prototype.moveTo = function (parent, newName, override, callback) { + var _this = this; + if (parent === this.parent) { + this.rename(newName, function (e, oldName, newName) { + callback(e); + }); + return; + } + var oldName = this.name; + this.name = newName; + this.removeFromParent(function (e) { + if (e) { + _this.name = oldName; + callback(e); + } + else + parent.addChild(_this, function (e) { + callback(e); + }); + }); }; VirtualResource.prototype.rename = function (newName, callback) { var oldName = this.name; diff --git a/lib/server/commands/Commands.js b/lib/server/commands/Commands.js index 27faf033..ebcf60f1 100644 --- a/lib/server/commands/Commands.js +++ b/lib/server/commands/Commands.js @@ -6,6 +6,7 @@ var Propfind_1 = require("./Propfind"); var Options_1 = require("./Options"); var Delete_1 = require("./Delete"); var Mkcol_1 = require("./Mkcol"); +var Move_1 = require("./Move"); var Head_1 = require("./Head"); var Post_1 = require("./Post"); var Put_1 = require("./Put"); @@ -17,6 +18,7 @@ exports.default = { Options: Options_1.default, Delete: Delete_1.default, Mkcol: Mkcol_1.default, + Move: Move_1.default, Head: Head_1.default, Post: Post_1.default, Put: Put_1.default, diff --git a/lib/server/commands/Move.d.ts b/lib/server/commands/Move.d.ts new file mode 100644 index 00000000..f8724433 --- /dev/null +++ b/lib/server/commands/Move.d.ts @@ -0,0 +1,2 @@ +import { MethodCallArgs } from '../WebDAVRequest'; +export default function (arg: MethodCallArgs, callback: any): void; diff --git a/lib/server/commands/Move.js b/lib/server/commands/Move.js new file mode 100644 index 00000000..27a27a7a --- /dev/null +++ b/lib/server/commands/Move.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var WebDAVRequest_1 = require("../WebDAVRequest"); +var FSManager_1 = require("../../manager/FSManager"); +function default_1(arg, callback) { + arg.getResource(function (e, r) { + if (e) { + arg.setCode(WebDAVRequest_1.HTTPCodes.NotFound); + callback(); + return; + } + var override = arg.findHeader('overwrite') === 'T'; + var destination = arg.findHeader('destination'); + if (!destination) { + arg.setCode(WebDAVRequest_1.HTTPCodes.BadRequest); + callback(); + return; + } + destination = destination.substring(destination.indexOf('://') + '://'.length); + destination = destination.substring(destination.indexOf('/')); + destination = new FSManager_1.FSPath(destination); + arg.server.getResourceFromPath(destination.getParent(), function (e, rDest) { + r.moveTo(rDest, destination.fileName(), override, function (e) { + if (e) + arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError); + else + arg.setCode(WebDAVRequest_1.HTTPCodes.Created); + callback(); + }); + }); + }); +} +exports.default = default_1; diff --git a/src/resource/IResource.ts b/src/resource/IResource.ts index bf0e6e82..263404f6 100644 --- a/src/resource/IResource.ts +++ b/src/resource/IResource.ts @@ -38,7 +38,7 @@ export interface IResource // ****************************** Actions ****************************** // create(callback : SimpleCallback) delete(callback : SimpleCallback) - moveTo(to : FSPath, callback : Return2Callback) + moveTo(parent : IResource, newName : string, override : boolean, callback : SimpleCallback) rename(newName : string, callback : Return2Callback) // ****************************** Tests ****************************** // diff --git a/src/resource/physical/PhysicalResource.ts b/src/resource/physical/PhysicalResource.ts index fd4831ca..a35a8f39 100644 --- a/src/resource/physical/PhysicalResource.ts +++ b/src/resource/physical/PhysicalResource.ts @@ -8,6 +8,7 @@ import * as fs from 'fs' export abstract class PhysicalResource extends StandardResource { realPath : string + name : string constructor(realPath : string, parent ?: IResource, fsManager ?: FSManager) { @@ -20,14 +21,35 @@ export abstract class PhysicalResource extends StandardResource super(parent, fsManager); this.realPath = path.resolve(realPath); + this.name = path.basename(this.realPath); } // ****************************** Actions ****************************** // abstract create(callback : SimpleCallback) abstract delete(callback : SimpleCallback) - moveTo(to : FSPath, callback : Return2Callback) + moveTo(parent : IResource, newName : string, override : boolean, callback : SimpleCallback) { - callback(new Error('Not implemented yet.'), null, null); + if(parent === this.parent) + { + this.rename(newName, (e, oldName, newName) => { + callback(e); + }) + return; + } + + const oldName = this.name; + this.name = newName; + this.removeFromParent((e) => { + if(e) + { + this.name = oldName; + callback(e); + } + else + parent.addChild(this, (e) => { + callback(e); + }) + }) } rename(newName : string, callback : Return2Callback) { @@ -40,15 +62,16 @@ export abstract class PhysicalResource extends StandardResource } const oldName = path.basename(this.realPath); this.realPath = newPath; + this.name = newName; this.updateLastModified(); - callback(e, oldName, newName); + callback(null, oldName, newName); }) } // ****************************** Std meta-data ****************************** // webName(callback : ReturnCallback) { - callback(null, path.basename(this.realPath)); + callback(null, path.basename(this.name)); } abstract type(callback : ReturnCallback) diff --git a/src/resource/std/StandardResource.ts b/src/resource/std/StandardResource.ts index 49679748..d4cd2135 100644 --- a/src/resource/std/StandardResource.ts +++ b/src/resource/std/StandardResource.ts @@ -151,7 +151,7 @@ export abstract class StandardResource implements IResource // ****************************** Actions ****************************** // abstract create(callback : SimpleCallback) abstract delete(callback : SimpleCallback) - abstract moveTo(to : FSPath, callback : Return2Callback) + abstract moveTo(parent : IResource, newName : string, override : boolean, callback : SimpleCallback) abstract rename(newName : string, callback : Return2Callback) // ****************************** Content ****************************** // diff --git a/src/resource/virtual/VirtualResource.ts b/src/resource/virtual/VirtualResource.ts index b28655be..d672f9e1 100644 --- a/src/resource/virtual/VirtualResource.ts +++ b/src/resource/virtual/VirtualResource.ts @@ -29,9 +29,29 @@ export abstract class VirtualResource extends StandardResource { this.removeFromParent(callback); } - moveTo(to : FSPath, callback : Return2Callback) + moveTo(parent : IResource, newName : string, override : boolean, callback : SimpleCallback) { - callback(new Error('Not implemented yet.'), null, null); + if(parent === this.parent) + { + this.rename(newName, (e, oldName, newName) => { + callback(e); + }) + return; + } + + const oldName = this.name; + this.name = newName; + this.removeFromParent((e) => { + if(e) + { + this.name = oldName; + callback(e); + } + else + parent.addChild(this, (e) => { + callback(e); + }) + }) } rename(newName : string, callback : Return2Callback) { diff --git a/src/server/commands/Commands.ts b/src/server/commands/Commands.ts index 57096024..8a806a00 100644 --- a/src/server/commands/Commands.ts +++ b/src/server/commands/Commands.ts @@ -4,6 +4,7 @@ import Propfind from './Propfind' import Options from './Options' import Delete from './Delete' import Mkcol from './Mkcol' +import Move from './Move' import Head from './Head' import Post from './Post' import Put from './Put' @@ -16,6 +17,7 @@ export default { Options, Delete, Mkcol, + Move, Head, Post, Put, diff --git a/src/server/commands/Move.ts b/src/server/commands/Move.ts new file mode 100644 index 00000000..e3359110 --- /dev/null +++ b/src/server/commands/Move.ts @@ -0,0 +1,39 @@ +import { HTTPCodes, MethodCallArgs, WebDAVRequest } from '../WebDAVRequest' +import { IResource, ResourceType } from '../../resource/Resource' +import { FSPath } from '../../manager/FSManager' + +export default function(arg : MethodCallArgs, callback) +{ + arg.getResource((e, r) => { + if(e) + { + arg.setCode(HTTPCodes.NotFound) + callback(); + return; + } + + const override = arg.findHeader('overwrite') === 'T'; + + let destination : any = arg.findHeader('destination'); + if(!destination) + { + arg.setCode(HTTPCodes.BadRequest); + callback(); + return; + } + + destination = destination.substring(destination.indexOf('://') + '://'.length) + destination = destination.substring(destination.indexOf('/')) + destination = new FSPath(destination) + + arg.server.getResourceFromPath(destination.getParent(), (e, rDest) => { + r.moveTo(rDest, destination.fileName(), override, (e) => { + if(e) + arg.setCode(HTTPCodes.InternalServerError) + else + arg.setCode(HTTPCodes.Created) + callback() + }) + }) + }) +}