src/extensions/default/AutoUpdate/StateHandler.js
/*
* Copyright (c) 2018 - present Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
define(function (require, exports, module) {
"use strict";
var FileSystem = brackets.getModule("filesystem/FileSystem"),
FileUtils = brackets.getModule("file/FileUtils");
var FILE_NOT_FOUND = 0,
FILE_NOT_READ = 1,
FILE_PARSE_EXCEPTION = 2,
FILE_READ_FAIL = 3;
/**
* @constructor
* Creates a StateHandler object for a JSON file. It maintains the following :
* path - path to the JSON file,
* state - parsed content of the file
* @param {string} path - path to the JSON file
*/
var StateHandler = function (path) {
this.path = path;
this.state = null;
};
/**
* Checks if the file exists
* @returns {$.Deferred} - a jquery deferred promise,
* that is resolved with existence or non-existence
* of json file.
*/
StateHandler.prototype.exists = function () {
var result = $.Deferred(),
_file = FileSystem.getFileForPath(this.path);
_file.exists(function (err, exists) {
if (err) {
result.reject();
} else if (exists) {
result.resolve();
} else {
result.reject();
}
});
return result.promise();
};
/**
* Parses the JSON file, and maintains a state for the parsed data
* @returns {$.Deferred} - a jquery deferred promise,
* that is resolved with a parsing success or failure
*/
StateHandler.prototype.parse = function () {
var result = $.Deferred(),
_file = FileSystem.getFileForPath(this.path);
var self = this;
this.exists()
.done(function () {
FileUtils.readAsText(_file)
.done(function (text) {
try {
if (text) {
self.state = JSON.parse(text);
result.resolve();
} else {
result.reject(FILE_READ_FAIL);
}
} catch (error) {
result.reject(FILE_PARSE_EXCEPTION);
}
})
.fail(function () {
result.reject(FILE_NOT_READ);
});
})
.fail(function () {
result.reject(FILE_NOT_FOUND);
});
return result.promise();
};
/**
* Sets the value of a key in a json file.
* @param {string} key - key for which the value is to be set
* @param {string} value - the value to be set for the given key
* @returns {$.Deferred} - a jquery deferred promise, that is resolved with a write success or failure
*/
StateHandler.prototype.set = function (key, value) {
this.state = this.state || {};
this.state[key] = value;
return this.write(true);
};
/**
* Gets the value for a given key, from the in-memory state maintained for a json file.
* @param {string} key - key for which value is to be retrieved
* @returns {string} value for the given key
*/
StateHandler.prototype.get = function (key) {
var retval = null;
if (this.state && this.state[key] !== undefined) {
retval = this.state[key];
}
return retval;
};
/**
* Reads the value of a key from a json file.
* @param {string} key - key for which the value is to be read
* @returns {$.Deferred} - a jquery deferred promise, that is resolved
* with the read value or read failure.
*/
StateHandler.prototype.refresh = function () {
var result = $.Deferred(),
self = this;
self.parse()
.done(function () {
if (self.state) {
result.resolve();
} else {
result.reject();
console.warn("AutoUpdate : updateHelper.json could not be read");
}
})
.fail(function (error) {
result.reject();
console.error("AutoUpdate : updateHelper.json could not be parsed", error);
});
return result.promise();
};
/**
* Performs the write of JSON object to a file.
* @param {string} filepath - path to JSON file
* @param {object} json - JSON object to write
* @returns {$.Deferred} - a jquery deferred promise,
* that is resolved with the write success or failure
*/
function _write(filePath, json) {
var result = $.Deferred(),
_file = FileSystem.getFileForPath(filePath);
if (_file) {
var content = JSON.stringify(json);
FileUtils.writeText(_file, content, true)
.done(function () {
result.resolve();
})
.fail(function (err) {
result.reject();
});
} else {
result.reject();
}
return result.promise();
}
/**
* Writes content into a json file
* @param {boolean} overwrite - true if file is to be overwritten, false otherwise
* @param {object} [content=this.state] - content to be written into the json file.
* @returns {$.Deferred} - a jquery deferred promise, that is resolved with a write success or failure
*/
StateHandler.prototype.write = function (overwrite) {
var result = $.Deferred(),
self = this;
function writePromise(path, contentToWrite) {
_write(path, contentToWrite)
.done(function () {
result.resolve();
})
.fail(function (err) {
result.reject();
});
}
var content = self.state;
if (overwrite) {
writePromise(self.path, content);
} else {
//check for existence
self.exists()
.fail(function () {
writePromise(self.path, content);
}).done(function () {
result.reject();
});
}
return result.promise();
};
/**
* Resets the content of the in-memory state
*/
StateHandler.prototype.reset = function () {
this.state = null;
};
exports.StateHandler = StateHandler;
exports.MessageKeys = {
FILE_NOT_FOUND: FILE_NOT_FOUND,
FILE_NOT_READ: FILE_NOT_READ,
FILE_PARSE_EXCEPTION: FILE_PARSE_EXCEPTION,
FILE_READ_FAIL: FILE_READ_FAIL
};
});