Skip to content

Commit 2bb7a4b

Browse files
committed
Implemented the static methods 'standardMoveWithoutCopy', 'standardMoveByCopy', 'standardFindChildByName', 'standardFindChildren' and 'standardAddToParent' in the 'StandardResource' class + Use the 'standardMoveByCopy' in 'standardMoveTo' static method + Implemented a default method for 'moveTo' in the 'StandardResource' class
1 parent 1a38d52 commit 2bb7a4b

File tree

3 files changed

+483
-109
lines changed

3 files changed

+483
-109
lines changed

lib/resource/std/StandardResource.d.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import { LockBag } from '../lock/LockBag';
88
import { Lock } from '../lock/Lock';
99
export declare abstract class StandardResource implements IResource {
1010
static sizeOfSubFiles(resource: IResource, targetSource: boolean, callback: ReturnCallback<number>): void;
11+
dateLastModified: number;
12+
deleteOnMoved: boolean;
13+
dateCreation: number;
1114
properties: object;
1215
fsManager: FSManager;
1316
lockBag: LockBag;
1417
parent: IResource;
15-
dateCreation: number;
16-
dateLastModified: number;
1718
constructor(parent: IResource, fsManager: FSManager);
1819
getAvailableLocks(callback: ReturnCallback<LockKind[]>): void;
1920
getLocks(callback: ReturnCallback<Lock[]>): void;
@@ -26,8 +27,8 @@ export declare abstract class StandardResource implements IResource {
2627
getProperties(callback: ReturnCallback<object>): void;
2728
abstract create(callback: SimpleCallback): any;
2829
abstract delete(callback: SimpleCallback): any;
29-
abstract moveTo(parent: IResource, newName: string, overwrite: boolean, callback: SimpleCallback): any;
3030
abstract rename(newName: string, callback: Return2Callback<string, string>): any;
31+
moveTo(parent: IResource, newName: string, overwrite: boolean, callback: SimpleCallback): void;
3132
abstract write(targetSource: boolean, callback: ReturnCallback<Writable>): any;
3233
abstract read(targetSource: boolean, callback: ReturnCallback<Readable>): any;
3334
abstract mimeType(targetSource: boolean, callback: ReturnCallback<string>): any;
@@ -42,7 +43,16 @@ export declare abstract class StandardResource implements IResource {
4243
gateway?(arg: MethodCallArgs, path: FSPath, callback: (error: Error, resource?: IResource) => void): any;
4344
protected updateLastModified(): void;
4445
protected removeFromParent(callback: SimpleCallback): void;
46+
protected addToParent(parent: IResource, callback: SimpleCallback): void;
4547
static standardRemoveFromParent(resource: IResource, callback: SimpleCallback): void;
48+
static standardAddToParent(resource: IResource, parent: IResource, callback: SimpleCallback): void;
49+
static standardFindChildren(parent: IResource, predicate: (resource: IResource, callback: (error: Error, isMatching?: boolean) => void) => void, callback: ReturnCallback<IResource[]>): void;
50+
static standardFindChildByName(parent: IResource, name: string, callback: ReturnCallback<IResource>): void;
51+
static standardMoveByCopy(resource: IResource, parent: IResource, newName: string, overwrite: boolean, deleteSource: boolean, callback: ReturnCallback<IResource>): void;
4652
static standardMoveTo(resource: IResource, parent: IResource, newName: string, overwrite: boolean, callback: SimpleCallback): void;
53+
/**
54+
* @deprecated Prefer calling 'standardMoveByCopy(...)' instead to avoid compatibility issue between file systems.
55+
*/
56+
static standardMoveWithoutCopy(resource: IResource, parent: IResource, newName: string, overwrite: boolean, callback: SimpleCallback): void;
4757
static standardMimeType(resource: IResource, targetSource: boolean, callback: ReturnCallback<string>): void;
4858
}

lib/resource/std/StandardResource.js

Lines changed: 207 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ var Errors_1 = require("../../Errors");
99
var mimeTypes = require("mime-types");
1010
var StandardResource = (function () {
1111
function StandardResource(parent, fsManager) {
12+
this.deleteOnMoved = true;
1213
this.dateCreation = Date.now();
1314
this.properties = {};
1415
this.fsManager = fsManager;
@@ -30,6 +31,7 @@ var StandardResource = (function () {
3031
.done(function (sizes) { return callback(null, sizes.reduce(function (o, s) { return o + s; }, 0)); });
3132
});
3233
};
34+
// ****************************** Locks ****************************** //
3335
StandardResource.prototype.getAvailableLocks = function (callback) {
3436
callback(null, [
3537
new LockKind_1.LockKind(LockScope_1.LockScope.Exclusive, LockType_1.LockType.Write),
@@ -52,6 +54,7 @@ var StandardResource = (function () {
5254
StandardResource.prototype.getLock = function (uuid, callback) {
5355
callback(null, this.lockBag.getLock(uuid));
5456
};
57+
// ****************************** Properties ****************************** //
5558
StandardResource.prototype.setProperty = function (name, value, callback) {
5659
this.properties[name] = value;
5760
this.updateLastModified();
@@ -72,6 +75,10 @@ var StandardResource = (function () {
7275
StandardResource.prototype.getProperties = function (callback) {
7376
callback(null, this.properties);
7477
};
78+
StandardResource.prototype.moveTo = function (parent, newName, overwrite, callback) {
79+
StandardResource.standardMoveByCopy(this, parent, newName, overwrite, this.deleteOnMoved, callback);
80+
};
81+
// ****************************** Std meta-data ****************************** //
7582
StandardResource.prototype.creationDate = function (callback) {
7683
callback(null, this.dateCreation);
7784
};
@@ -84,72 +91,229 @@ var StandardResource = (function () {
8491
StandardResource.prototype.removeFromParent = function (callback) {
8592
StandardResource.standardRemoveFromParent(this, callback);
8693
};
94+
StandardResource.prototype.addToParent = function (parent, callback) {
95+
StandardResource.standardAddToParent(this, parent, callback);
96+
};
8797
StandardResource.standardRemoveFromParent = function (resource, callback) {
8898
var parent = resource.parent;
8999
if (parent)
90100
parent.removeChild(resource, function (e) {
91-
if (e) {
92-
callback(e);
93-
return;
94-
}
95-
if (resource.parent === parent)
101+
if (!e && resource.parent === parent)
96102
resource.parent = null;
97-
callback(null);
103+
callback(e);
98104
});
99105
else
100106
callback(null);
101107
};
102-
StandardResource.standardMoveTo = function (resource, parent, newName, overwrite, callback) {
108+
StandardResource.standardAddToParent = function (resource, parent, callback) {
109+
parent.addChild(resource, function (e) {
110+
if (!e)
111+
resource.parent = parent;
112+
callback(e);
113+
});
114+
};
115+
StandardResource.standardFindChildren = function (parent, predicate, callback) {
103116
parent.getChildren(function (e, children) {
117+
if (e) {
118+
callback(e, null);
119+
return;
120+
}
104121
new Workflow_1.Workflow()
105-
.each(children, function (child, cb) { return child.webName(function (e, name) {
122+
.each(children, function (child, cb) {
123+
predicate(child, function (e, isMatching) { return cb(e, isMatching ? child : null); });
124+
})
125+
.error(function (e) { return callback(e, null); })
126+
.done(function (conflictingChildren) { return callback(null, conflictingChildren.filter(function (c) { return !!c; })); });
127+
});
128+
};
129+
StandardResource.standardFindChildByName = function (parent, name, callback) {
130+
this.standardFindChildren(parent, function (r, cb) { return r.webName(function (e, rname) {
131+
if (e)
132+
cb(e);
133+
else if (name === rname)
134+
cb(null, true);
135+
else
136+
cb(null, false);
137+
}); }, function (e, rs) {
138+
if (e)
139+
callback(e, null);
140+
else if (rs.length > 0)
141+
callback(null, rs[0]);
142+
else
143+
callback(Errors_1.Errors.ResourceNotFound, null);
144+
});
145+
};
146+
StandardResource.standardMoveByCopy = function (resource, parent, newName, overwrite, deleteSource, callback) {
147+
StandardResource.standardFindChildByName(parent, newName, function (e, r) {
148+
if (e === Errors_1.Errors.ResourceNotFound)
149+
copy();
150+
else if (e)
151+
callback(e, null);
152+
else if (!overwrite)
153+
callback(Errors_1.Errors.ResourceAlreadyExists, null);
154+
else
155+
r.delete(function (e) {
156+
if (e)
157+
callback(e, null);
158+
else
159+
copy();
160+
});
161+
});
162+
function copy() {
163+
resource.type(function (e, type) {
164+
if (e) {
165+
callback(e, null);
166+
return;
167+
}
168+
var destination = parent.fsManager.newResource(null, newName, type, parent);
169+
destination.create(function (e) {
170+
if (e) {
171+
callback(e, null);
172+
return;
173+
}
174+
parent.addChild(destination, function (e) {
175+
if (e) {
176+
callback(e, null);
177+
return;
178+
}
179+
if (type.isDirectory)
180+
copyDir(destination);
181+
else
182+
copyFile(destination);
183+
});
184+
});
185+
});
186+
}
187+
function copyProperties(destination, callback) {
188+
resource.getProperties(function (e, props) {
189+
if (e) {
190+
callback(e);
191+
return;
192+
}
193+
new Workflow_1.Workflow()
194+
.each(Object.keys(props), function (key, cb) { return destination.setProperty(key, props[key], cb); })
195+
.error(callback)
196+
.done(function () { return callback(null); });
197+
});
198+
}
199+
function copyLocks(destination, callback) {
200+
resource.getLocks(function (e, locks) {
201+
if (e === Errors_1.Errors.MustIgnore) {
202+
callback(null);
203+
return;
204+
}
205+
if (e) {
206+
callback(e);
207+
return;
208+
}
209+
new Workflow_1.Workflow()
210+
.each(locks, function (lock, cb) { return destination.setLock(lock, cb); })
211+
.error(callback)
212+
.done(function () { return callback(null); });
213+
});
214+
}
215+
function finalizeCopy(destination) {
216+
copyProperties(destination, function (e) {
106217
if (e)
107-
cb(e);
108-
else if (name === newName && !overwrite)
109-
cb(Errors_1.Errors.ResourceAlreadyExists);
110-
else if (name === newName && overwrite)
111-
cb(null, child);
218+
callback(e, null);
112219
else
113-
cb();
114-
}); })
115-
.error(callback)
116-
.done(function (conflictingChildren) {
117-
conflictingChildren = conflictingChildren.filter(function (c) { return !!c; });
220+
copyLocks(destination, function (e) {
221+
if (e)
222+
callback(e, null);
223+
else if (deleteSource)
224+
resource.delete(function (e) { return callback(e, destination); });
225+
else
226+
resource.parent.removeChild(resource, function (e) { return callback(e, destination); });
227+
});
228+
});
229+
}
230+
function copyDir(destination) {
231+
resource.getChildren(function (e, children) {
232+
if (e) {
233+
callback(e, null);
234+
return;
235+
}
118236
new Workflow_1.Workflow()
119-
.each(conflictingChildren, function (child, cb) { return child.delete(cb); })
120-
.error(callback)
121-
.done(function () {
122-
if (parent === resource.parent) {
123-
resource.rename(newName, function (e, oldName, newName) {
237+
.each(children, function (child, cb) { return child.webName(function (e, name) {
238+
if (e)
239+
cb(e);
240+
else
241+
child.moveTo(destination, name, overwrite, cb);
242+
}); })
243+
.error(function (e) { return callback(e, null); })
244+
.done(function () { return finalizeCopy(destination); });
245+
});
246+
}
247+
function copyFile(destination) {
248+
resource.read(true, function (e, rStream) {
249+
if (e) {
250+
callback(e, null);
251+
return;
252+
}
253+
destination.write(true, function (e, wStream) {
254+
if (e) {
255+
callback(e, null);
256+
return;
257+
}
258+
rStream.pipe(wStream);
259+
wStream.on('error', callback);
260+
wStream.on('finish', function () { return finalizeCopy(destination); });
261+
});
262+
});
263+
}
264+
};
265+
StandardResource.standardMoveTo = function (resource, parent, newName, overwrite, callback) {
266+
StandardResource.standardMoveByCopy(resource, parent, newName, overwrite, true, callback);
267+
};
268+
/**
269+
* @deprecated Prefer calling 'standardMoveByCopy(...)' instead to avoid compatibility issue between file systems.
270+
*/
271+
StandardResource.standardMoveWithoutCopy = function (resource, parent, newName, overwrite, callback) {
272+
StandardResource.standardFindChildByName(parent, newName, function (e, r) {
273+
if (e === Errors_1.Errors.ResourceNotFound)
274+
move();
275+
else if (e)
276+
callback(e);
277+
else if (!overwrite)
278+
callback(Errors_1.Errors.ResourceAlreadyExists);
279+
else
280+
r.delete(function (e) {
281+
if (e)
282+
callback(e);
283+
else
284+
move();
285+
});
286+
});
287+
function move() {
288+
if (parent === resource.parent) {
289+
resource.rename(newName, function (e, oldName, newName) {
290+
callback(e);
291+
});
292+
return;
293+
}
294+
StandardResource.standardRemoveFromParent(resource, function (e) {
295+
if (e) {
296+
callback(e);
297+
return;
298+
}
299+
resource.webName(function (e, name) {
300+
if (e || name === newName) {
301+
parent.addChild(resource, function (e) {
124302
callback(e);
125303
});
126304
return;
127305
}
128-
StandardResource.standardRemoveFromParent(resource, function (e) {
129-
if (e) {
306+
resource.rename(newName, function (e, oldName, newName) {
307+
if (e)
130308
callback(e);
131-
return;
132-
}
133-
resource.webName(function (e, name) {
134-
if (e || name === newName) {
135-
parent.addChild(resource, function (e) {
136-
callback(e);
137-
});
138-
return;
139-
}
140-
resource.rename(newName, function (e, oldName, newName) {
141-
if (e)
142-
callback(e);
143-
else
144-
parent.addChild(resource, function (e) {
145-
callback(e);
146-
});
309+
else
310+
parent.addChild(resource, function (e) {
311+
callback(e);
147312
});
148-
});
149313
});
150314
});
151315
});
152-
});
316+
}
153317
};
154318
StandardResource.standardMimeType = function (resource, targetSource, callback) {
155319
resource.type(function (e, type) {

0 commit comments

Comments
 (0)