123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- /* This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
- * Copyright 2011 by the AToMPM team and licensed under the LGPL
- * See COPYING.lesser and README.md in the root of this project for full details
- */
- /* delete specified file/folder */
- DataUtils = function(){
- /*
- NOTE:: information about the pathString is bundled with the request... if the
- request succeeds, it is returned along with the changelog and used to
- draw the requested connection [and center-piece]
- NOTE:: DataUtils.connect() may be called from the behaviour statechart with a single
- parameter (i.e., event.target)... in such cases, we construct an
- appropriate 2-parameter call to DataUtils.connect() and recurse
- */
- /**
- * Requests a connection of specified instances with center-piece (if and when any)
- * at center of ConnectionUtils.getConnectionPath(). In practice, before this request
- * is sent, the user is prompted to either choose a connection type (this choice is
- * made for him when exactly one type is available) or to be told that no legal
- * connection exists
- */
- this.connect = function(uri1,uri2){
- if( uri2 == undefined )
- return DataUtils.connect(ConnectionUtils.getConnectionSource(), __vobj2uri(uri1));
-
- var segments = __path2segments(ConnectionUtils.getConnectionPath()),
- pathCenter = segments.splice(1,1)[0],
- callback =
- function(connectionType)
- {
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url(connectionType,__NO_USERNAME),
- {'src':uri1,
- 'dest':uri2,
- 'pos':[pathCenter.x,pathCenter.y],
- 'segments':segments});
- };
-
- ConnectionUtils.hideConnectionPath();
- WindowManagement.openDialog(
- _LEGAL_CONNECTIONS,
- {'uri1':uri1,'uri2':uri2,'ctype':__VISUAL_LINK},
- callback);
- };
-
- /**
- * Request creation of an instance of __typeToCreate at the specified
- * x and y coordinates
- */
- this.create = function (x, y, callback) {
- if (__typeToCreate == undefined) {
- WindowManagement.openDialog(_ERROR, 'you must select a type to create');
- } else {
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url(__typeToCreate + '.type', __NO_USERNAME),
- {'pos': [x, y]},
- callback);
- }
- };
- /**
- * Deletes the current selection entities
- */
- this.del = function(){
- var requests = [];
- __selection['items'].forEach(
- function(it)
- {
- if( it in __icons )
- requests.push(
- {'method':'DELETE',
- 'uri':HttpUtils.url(it,__NO_USERNAME+__NO_WID)});
- });
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url('/batchEdit',__NO_USERNAME),
- requests);
- };
-
- /**
- * Deletes the file from the cloud storage by URI
- *
- * @param fileuri - the file/folder to delete
- * @param callback - the callback function after the operation
- * has completed
- */
- this.deleteFromCloud = function(fileuri,callback){
- HttpUtils.httpReq(
- 'DELETE',
- fileuri,
- undefined,
- callback);
- };
-
- /**
- * Create a folder
- *
- * @param fileuri - the folder to create
- * @param callback - the callback function after the operation
- * has completed
- */
- this.createFolder = function(folderuri,callback){
- HttpUtils.httpReq(
- 'POST',
- folderuri,
- undefined,
- callback);
- };
-
- /**
- * Rename a file/folder in the cloud
- *
- * @param fileuri - the file/folder to rename
- * @param newname - the new name of the file/folder
- * @param callback - the callback function after the operation
- * has completed
- */
- this.renameInCloud = function(folderuri,newname,callback){
- HttpUtils.httpReq(
- 'PUT',
- folderuri,
- newname,
- callback);
- };
-
- /**
- * Move a file/folder in the cloud
- *
- * @param fileuri - the file/folder to rename
- * @param newlocation - the new location of the file/folder (needs to start with a '/')
- * @param callback - the callback function after the operation
- * has completed
- */
- this.moveInCloud = function(folderuri,newlocation,callback){
- HttpUtils.httpReq(
- 'PUT',
- folderuri,
- newlocation,
- callback);
- };
-
- /*
- 1. retrieve and validate uri associated to 'into'
- 2. validate and/or setup 'items' (see NOTE)
- 3. prompt for connection type
- *. return connection type or undefined via 'callback'
-
- NOTE:: when 'items' is undefined, __selection.items is used as the default
- */
- /**
- * Prompt user to select a containment link type (or chooses it for him if there
- * is only one) and pass the choice to the callback function.
- *
- * @param into - where to put the connection
- * @param items - items to insert
- * @param callback - function to call when finished with the request
- */
- this.getInsertConnectionType = function(into,items,callback){
- var intouri = into.getAttribute('__csuri');
- if( intouri == undefined ||
- !(intouri in __icons) ||
- __isConnectionType(intouri) )
- return callback();
- if( (items == undefined || items.length == 0) &&
- (__selection == undefined || __selection['items'].length == 0) )
- return callback();
- items = (items || __selection['items']);
-
- WindowManagement.openDialog(
- _LEGAL_CONNECTIONS,
- {'uri1':intouri,
- 'uri2':items[0],
- 'ctype':__CONTAINMENT_LINK,
- 'forceCallback':true},
- function(ctype)
- {
- if( utils.isObject(ctype) && '$err' in ctype )
- callback();
- else
- callback(ctype);
- });
- };
-
- /*
- 1. foreach non-connection type icon in 'items' that is not already inside
- 'into' or any other icon in 'items'
- a. synthesize a path from 'into''s top-left to the icon's center
- b. save that path's center and 2 halves
- c. remove the path
- d. remember connection request
- 2. send all requests from step 1d as a single batchEdit or return them
- NOTE:: similarly to what is done in DataUtils.connect(), each connection request is
- bundled with 'pos' and 'segments'... here however, since the user drew
- no path, these are both synthesic... this serves 2 purposes: first, it
- shields the csworker from receiving different queries for containment
- and visual connections, but most importantly, it ensures that
- containment links have an existing visual representation if one is
- needed
- NOTE:: the 'context' parameter contains a list of pending changes computed by
- GeometryUtils.transformSelection() but not yet persisted onto the canvas... this
- seemingly odd passing around of pending information is necessary to
- enable atomicity of icon transformations and insertions
- */
- /**
- * Inserts 'items' into 'into' (connects them via a containment link of type
- * 'connectionType'). This sends a bundle of batched connection requets to csworker.
- */
- this.insert = function(into,items,connectionType,context,dryRun) {
- var intobbox = __getBBox(into,context),
- requests = [];
-
- items.forEach(
- function(it)
- {
- if( ! (it in __icons) ||
- __isConnectionType(it) ||
- __isDirectlyContainedIn(it,into) ||
- items.some(
- function(_it)
- {
- return __isDirectlyContainedIn(it,_it);
- }) )
- return;
-
- var itbbox = __getBBox(it,context),
- itcenter = [itbbox.x+itbbox.width/2, itbbox.y+itbbox.height/2],
- path = __canvas.path(
- 'M'+intobbox.x+','+intobbox.y+'L'+itcenter),
- segments = __path2segments(path),
- pathCenter = segments.splice(1,1)[0];
- path.remove();
-
- requests.push(
- {'method':'POST',
- 'uri':HttpUtils.url(connectionType,__NO_USERNAME+__NO_WID),
- 'reqData':
- {'src':into,
- 'dest':it,
- 'pos':[pathCenter.x,pathCenter.y],
- 'segments':segments}});
-
- __icons[it]['edgesIn'].forEach(
- function(edgeId)
- {
- var linkIn = __edgeId2ends(edgeId)[0];
- if( __isContainmentConnectionType(linkIn) ) {
- requests.push(
- {'method':'DELETE',
- 'uri':HttpUtils.url(linkIn,__NO_USERNAME+__NO_WID)});
- }
- });
- });
-
- if( dryRun )
- return requests;
- else if( requests.length > 0 )
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url('/batchEdit',__NO_USERNAME),
- requests);
- };
-
- /**
- * Loads the Button Model
- *
- * @param bm - the button model to load
- */
- this.loadbm = function (bm) {
- HttpUtils.httpReq(
- 'GET',
- HttpUtils.url(bm, true),
- undefined,
- function (statusCode, resp) {
- if (!utils.isHttpSuccessCode(statusCode)) {
- if (resp.includes("ENOENT")) {
- let err_msg = "Error! File not found: " + bm;
- WindowManagement.openDialog(_ERROR, err_msg);
- } else {
- WindowManagement.openDialog(_ERROR, resp);
- }
- return;
- }
- GUIUtils.setupAndShowToolbar(
- bm,
- eval('(' + resp + ')'),
- __BUTTON_TOOLBAR);
- });
- };
-
- /*
- 1. does the deed
- 2. if a 'missing metamodel' error is returned
- a. request that the missing metamodel be loaded
- i. if an error is returned, show it
- ii. otherwise, return to step 1. */
- /**
- * Request that the specified model be loaded
- */
- this.loadm = function (fname, insert) {
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url('/current.model', __NO_USERNAME),
- {
- 'm': HttpUtils.url(fname, __NO_WID),
- 'insert': insert
- },
- function (statusCode, resp) {
- if (utils.isHttpSuccessCode(statusCode)) {
- WindowManagement.setWindowTitle();
- return;
- }
- if ((matches = resp.match(/metamodel not loaded :: (.*)/))) {
- var missing = matches[1] + '.metamodel';
- console.warn('auto-loading missing metamodel :: ' + missing);
- DataUtils.loadmm(missing,
- function (_statusCode, _resp) {
- if (!utils.isHttpSuccessCode(_statusCode)) {
- if (_resp.includes("ENOENT")) {
- _resp = utils.jsonp(_resp);
- _resp = "Error! File not found: " + _resp['path'];
- }
- WindowManagement.openDialog(_ERROR, _resp);
- }
- else {
- DataUtils.loadm(fname, insert);
- }
- });
- } else {
- if (resp.includes("cannot read")) {
- let err_msg = "Error! File cannot be read: " + fname;
- WindowManagement.openDialog(_ERROR, err_msg);
- } else {
- WindowManagement.openDialog(_ERROR, resp);
- }
- }
- });
- };
-
- /*
- CASE 1: asmm is already loaded but with a different csmm
- > request params only contain csmm
- > triggers back-end CS-switch
-
- CASE 2: asmm is not loaded or is loaded with the specified csmm
- > request params contain asmm and csmm
- > triggers back-end metamodel (re-)load */
- /**
- * Loads (or reloads) the specified metamodel
- */
- this.loadmm = function(imm,callback){
- var asmm = __iconMetamodelToMetamodel(imm),
- sameASMM = function(mm) {
- return __isIconMetamodel(mm) &&
- __iconMetamodelToMetamodel(mm) == asmm;
- },
- params;
- if( !(imm in __loadedToolbars) &&
- utils.keys(__loadedToolbars).some(sameASMM) )
- params = {'csmm':HttpUtils.url(imm,__NO_WID)};
- else
- params = {'csmm':HttpUtils.url(imm,__NO_WID), 'asmm':HttpUtils.url(asmm,__NO_WID)};
-
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url('/current.metamodels', __NO_USERNAME),
- params,
- callback);
- };
-
- /**
- * Saves the current model to the specified file
- */
- this.savem = function(fname){
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url(fname,__FORCE_GET));
- };
-
- /**
- * Unloads the selected button model
- */
- this.unloadbm = function(bm){
- GUIUtils.removeToolbar(bm);
- };
-
- /**
- * Unloads the selected metamodel
- */
- this.unloadmm = function(mm){
- HttpUtils.httpReq(
- 'DELETE',
- HttpUtils.url(mm,__NO_USERNAME));
- };
-
- /**
- * Updates the current model with the listed
- * changes
- */
- this.update = function(uri,changes){
- if( utils.keys(changes).length > 0 )
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url(uri,__NO_USERNAME),
- {'changes':changes});
- };
-
- /**
- * Updates using a worker thread?
- */
- this.updatecs = function(uri,changes){
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url(uri+'.cs',__NO_USERNAME),
- {'changes':changes});
- };
-
- /**
- * Uploads the data to a file specified by the tofolder entry
- *
- * @param tofolder - the folder to upload the data to
- * @param data - the data to upload
- * @param callback - the callback function after the operation
- * has completed
- */
- this.uploadToCloud = function(tofolder,data,callback){
- HttpUtils.httpReq(
- 'PUT',
- HttpUtils.url(tofolder+'.file',__NO_WID),
- data,
- callback);
- };
-
- return this;
- }();
|