Commit 80af19f086b07dd28f994180728993b5207921a5

Authored by Benjamin Renard
2 parents 437c4dbc ebb4d6a4

Merge branch 'master' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM

Conflicts:
	js/app/AmdaApp.js
	js/resources/css/amda.css
generic_data/jobs.json
... ... @@ -2,12 +2,15 @@
2 2 {"nodeType" : "bkgWorks", "text" : "Finished Jobs / Results", "id" : "result-treeRootNode", "children" :
3 3 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "resPlot-treeRootNode" },
4 4 {"nodeType" : "bkgWorks","text" : "Download","id" : "resDown-treeRootNode"},
5   - {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "resSearch-treeRootNode"}
  5 + {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "resSearch-treeRootNode"},
  6 + {"nodeType" : "bkgWorks","text" : "Statistics","id" : "resStatistics-treeRootNode"}
6 7 ]
7 8 },
8 9 {"nodeType" : "bkgWorks", "text" : "Jobs in Progress", "id" : "bkgjobs-treeRootNode", "children" :
9 10 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "bkgPlot-treeRootNode" },
10 11 {"nodeType" : "bkgWorks","text" : "Download","id" : "bkgDown-treeRootNode"},
11   - {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"}]
  12 + {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"},
  13 + {"nodeType" : "bkgWorks","text" : "Statistics","id" : "bkgStatistics-treeRootNode"}
  14 + ]
12 15 }
13 16 ]}
... ...
generic_data/resources.json
... ... @@ -14,5 +14,11 @@
14 14 { "nodeType" : "sharedtimeTable", "text" : "Shared Time Tables", "id" : "sharedtimeTable-treeRootNode"}
15 15 ]
16 16 },
  17 + {"nodeType" : "","text" : "Catalogs","id" : "catalog-treeBase",
  18 + "children" : [
  19 + { "nodeType" : "catalog", "text" : "My Catalogs", "id" : "catalog-treeRootNode"},
  20 + { "nodeType" : "sharedCatalog", "text" : "Shared Catalogs", "id" : "sharedCatalog-treeRootNode"}
  21 + ]
  22 + },
17 23 {"nodeType" : "myData","text" : "My Files", "id" : "myData-treeRootNode"}
18 24 ]}
... ...
help/catalogHOWTO 0 โ†’ 100644
... ... @@ -0,0 +1,3 @@
  1 +TBD
  2 +
  3 +
... ...
help/statisticsHOWTO 0 โ†’ 100644
... ... @@ -0,0 +1,3 @@
  1 +TBD
  2 +
  3 +
... ...
js/app/AmdaApp.js
... ... @@ -5,20 +5,13 @@
5 5 * @extends Ext.ux.desktop.App
6 6 * @brief Main class defining Amda Desktop and its Modules
7 7 * @author Ext JS Library 4.0 Copyright(c) 2006-2011 Sencha Inc. licensing@sencha.com
8   - * @version $Id: AmdaApp.js 2932 2015-06-02 09:35:47Z elena $
9   - * @todo Load/Unload Modules on need
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :07/06/2011: elena - First Modifs for Amda Application
14 8 */
15 9  
16 10  
17 11 Ext.define('amdaApp.AmdaApp', {
18 12 extend: 'Ext.ux.desktop.App',
19 13  
20   - requires: [
21   -
  14 + requires: [
22 15 'Ext.window.MessageBox',
23 16 'Ext.ux.desktop.ShortcutModel',
24 17 'amdaUI.SampToolBarUI',
... ... @@ -27,6 +20,20 @@ Ext.define('amdaApp.AmdaApp', {
27 20 ],
28 21  
29 22 dynamicModules: {
  23 + statistics : {
  24 + id : 'statistics-win',
  25 + icon : 'icon-statistics',
  26 + title : 'Statistics',
  27 + source : 'amdaDesktop.StatisticsModule',
  28 + useLauncher : true
  29 + },
  30 + catalog : {
  31 + id : 'catalog-win',
  32 + icon : 'icon-catalog',
  33 + title : 'Manage catalogs',
  34 + source : 'amdaDesktop.CatalogModule',
  35 + useLauncher : true
  36 + },
30 37 param : {
31 38 id : 'param-win',
32 39 icon : 'icon-parameters',
... ... @@ -49,24 +56,24 @@ Ext.define('amdaApp.AmdaApp', {
49 56 useLauncher : true
50 57 },
51 58 plot : {
52   - id : 'new-plot-win',
  59 + id : 'new-plot-win',
53 60 icon : 'icon-plot',
54 61 title : 'Plot Manager',
55 62 source : 'amdaDesktop.NewPlotModule',
56 63 useLauncher : true
57 64 },
58 65 search : {
59   - id : 'search-win',
  66 + id : 'search-win',
60 67 icon : 'icon-search',
61 68 title : 'Data Mining',
62 69 source : 'amdaDesktop.SearchModule',
63 70 useLauncher : true
64 71 },
65 72 download : {
66   - id : 'down-win',
  73 + id : 'down-win',
67 74 icon : 'icon-download',
68 75 title : 'Download data',
69   - source : 'amdaDesktop.DownloadModule',
  76 + source : 'amdaDesktop.DownloadModule',
70 77 useLauncher : true
71 78 },
72 79 upload : {
... ... @@ -275,12 +282,13 @@ Ext.define('amdaApp.AmdaApp', {
275 282 { name: 'Create/Modify parameter', iconCls: 'edit', module: 'param-win' },
276 283 { name: 'Plot data', iconCls: 'plot', module: 'new-plot-win'},
277 284 { name: 'Data mining', iconCls: 'search', module: 'search-win'},
  285 + { name: 'Statistics', iconCls: 'statistics', module: 'statistics-win'},
278 286 { name: 'Download data', iconCls: 'download_manager', module: 'down-win'},
279 287 { name: 'Upload data', iconCls: 'mydata', module: 'up-win'},
280 288 { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' },
281 289 { name: 'TimeTables operations', iconCls: 'operations', module: 'ttsOpe-win' },
282   - // { name: 'Generate/Edit catalogs', iconCls: 'catalog', module: 'catalog-win'},
283   - // { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'},
  290 + { name: 'Manage catalogs', iconCls: 'catalog', module: 'catalog-win'},
  291 + { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'},
284 292 { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' }
285 293 ]
286 294 }),
... ...
js/app/controllers/CatalogModule.js 0 โ†’ 100644
... ... @@ -0,0 +1,35 @@
  1 +/**
  2 + * Project  AMDA-NG
  3 + * Name CatalogModule.js
  4 + * @class amdaDesktop.CatalogModule
  5 + * @extends amdaDesktop.InteractiveModule
  6 + * @brief Catalog Module controller definition
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaDesktop.CatalogModule', {
  11 + extend: 'amdaDesktop.InteractiveModule',
  12 +
  13 + requires: [
  14 + 'amdaUI.CatalogUI'
  15 + ],
  16 +
  17 + contentId : 'catalogUI',
  18 +
  19 + /**
  20 + * @cfg {String} data models
  21 + * @required
  22 + */
  23 + nodeDataModel : 'amdaModel.CatalogNode',
  24 +
  25 + /**
  26 + * @cfg {String} window definitions
  27 + * @required
  28 + */
  29 + width : 800,
  30 + height: 700,
  31 + uiType : 'panelCatalog',
  32 + helpTitle : 'Help on Catalog Module',
  33 + helpFile : 'catalogHelp'
  34 +
  35 +});
... ...
js/app/controllers/ExplorerModule.js
1 1 /**
2   - * Project : AMDA-NG4
  2 + * Project : AMDA-NG
3 3 * Name : ExplorerModule.js
4 4 * @class amdaDesktop.ExplorerModule
5 5 * @extends amdaDesktop.AmdaModule
6 6 * @brief Explorer Module controller definition
7 7 * @author CDA
8   - * @version $Id: ExplorerModule.js 2239 2014-03-26 12:31:32Z elena $
9 8 */
10 9  
11 10 Ext.define('amdaDesktop.ExplorerModule', {
... ... @@ -23,6 +22,8 @@ Ext.define('amdaDesktop.ExplorerModule', {
23 22 'amdaModel.RemoteSimuParamNode',
24 23 'amdaModel.AliasNode',
25 24 'amdaModel.TimeTableNode',
  25 + 'amdaModel.CatalogNode',
  26 + 'amdaModel.StatisticsNode', // singleton; not shown in the tree
26 27 'amdaModel.sharedTimeTableNode',
27 28 'amdaModel.MyDataParamNode',
28 29 'amdaModel.MyDataNode',
... ... @@ -35,6 +36,8 @@ Ext.define('amdaDesktop.ExplorerModule', {
35 36 'amdaModel.Plot',
36 37 'amdaModel.Download',
37 38 'amdaModel.TimeTable',
  39 + 'amdaModel.Catalog',
  40 + 'amdaModel.Statistics',
38 41 'amdaModel.FileObject',
39 42 'amdaModel.FileParamObject',
40 43 'amdaModel.FilterInfo'
... ...
js/app/controllers/StatisticsModule.js 0 โ†’ 100644
... ... @@ -0,0 +1,45 @@
  1 +/**
  2 + * Project  AMDA-NG
  3 + * Name StatisticsModule.js
  4 + * @class amdaDesktop.StatisticsModule
  5 + * @extends amdaDesktop.InteractiveModule
  6 + * @brief Statistics Module controller definition
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaDesktop.StatisticsModule', {
  11 + extend: 'amdaDesktop.InteractiveModule',
  12 +
  13 + requires: [
  14 + 'amdaUI.StatisticsUI'
  15 + ],
  16 +
  17 + contentId : 'statisticsUI',
  18 +
  19 + /**
  20 + * @cfg {String} data models
  21 + * @required
  22 + */
  23 + nodeDataModel : 'amdaModel.StatisticsNode',
  24 + objectDataModel : 'amdaModel.Statistics',
  25 + /**
  26 + * @cfg {String} window definitions
  27 + * @required
  28 + */
  29 + width : 550,
  30 + height: 550,
  31 + uiType : 'panelStatistics',
  32 + helpTitle : 'Help on Statistics Module',
  33 + helpFile : 'statisticsHelp',
  34 + /**
  35 + * @override
  36 + */
  37 + createWindow : function() {
  38 + if (!this.linkedNode){
  39 + this.setLinkedNode(amdaModel.StatisticsNode);
  40 + }
  41 + this.callParent(arguments);
  42 + },
  43 +
  44 +
  45 +});
... ...
js/app/models/AliasNode.js
... ... @@ -6,32 +6,25 @@
6 6 * @brief Basic Model of Node corresponding to an alias
7 7 * @author Myriam
8 8 * @version $Id: AliasNode.js 2615 2014-10-23 15:03:48Z myriam $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :14/10/2011: Myriam - file creation
14 9 */
15 10  
16 11 Ext.define('amdaModel.AliasNode', {
17 12  
18   - extend: 'amdaModel.InteractiveNode',
19   -
20   - statics: {
21   - nodeType: 'alias',
22   - objectName: 'Alias',
23   - deletedAliases : null
24   - },
  13 + extend: 'amdaModel.InteractiveNode',
  14 +
  15 + statics: {
  16 + nodeType: 'alias',
  17 + objectName: 'Alias',
  18 + deletedAliases : null
  19 + },
25 20  
26 21 fields: [
27 22 {name: 'isScatter', type: 'boolean', defaultValue: true}
28 23 ],
29 24  
30   - constructor : function(config){
31   -
32   - this.callParent(arguments);
33   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
34   - this.set('nodeType',amdaModel.AliasNode.nodeType);
  25 + constructor : function(config)
  26 + {
  27 + this.callParent(arguments);
35 28 if (this.get('leaf')) this.set('iconCls', 'icon-scalar');
36 29 },
37 30  
... ... @@ -52,14 +45,7 @@ Ext.define('amdaModel.AliasNode', {
52 45  
53 46 return menuItems;
54 47 },
55   -
56   - getAllContextMenuItems: function(){
57   - return this.allMenuItems();
58   - },
59   -
60   - getMultiContextMenuItems: function(){
61   - return this.allMenuMultiItems(amdaModel.AliasNode.objectName);
62   - },
  48 +
63 49  
64 50 create: function(alias, param) {
65 51 AmdaAction.createObject({name: alias, param: param,
... ...
js/app/models/BkgJobNode.js
... ... @@ -6,11 +6,6 @@
6 6 * @brief Basic Model of Node corresponding to Amda processes in background
7 7 * @author elena
8 8 * @version $Id: BkgJobNode.js 1963 2013-12-06 17:50:37Z elena $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :08/07/2011: elena creation
14 9 */
15 10  
16 11 Ext.define('amdaModel.BkgJobNode', {
... ... @@ -25,19 +20,19 @@ Ext.define('amdaModel.BkgJobNode', {
25 20 PLOT: 'request',//'plot',
26 21 CONDITION: 'condition',
27 22 DOWNLOAD: 'download',
28   - CATALOG: 'catalog'
  23 + STATISTICS: 'statistics'
29 24 },
30 25 JOB_ROOT_NODE: {
31 26 PLOT: 'bkgPlot-treeRootNode',
32 27 CONDITION: 'bkgSearch-treeRootNode',
33 28 DOWNLOAD: 'bkgDown-treeRootNode',
34   - CATALOG: 'bkgCatalog-treeRootNode'
  29 + STATISTICS: 'bkgStatistics-treeRootNode'
35 30 },
36 31 RES_ROOT_NODE: {
37 32 PLOT: 'resPlot-treeRootNode',
38 33 CONDITION: 'resSearch-treeRootNode',
39   - DOWNLOAD: 'resDown-treeRootNode',
40   - CATALOG: 'resCatalog-treeRootNode'
  34 + DOWNLOAD: 'resDown-treeRootNode',
  35 + STATISTICS: 'resStatistics-treeRootNode'
41 36 },
42 37 STATUS_LIST: {
43 38 IN_PROGRESS: 'in_progress',
... ... @@ -48,24 +43,22 @@ Ext.define('amdaModel.BkgJobNode', {
48 43 fields: [
49 44 // name, id, moduleId, object> from parent
50 45 { name : 'jobType', type : 'string' },
51   - { name : 'processId', type : 'string' },
52   - { name : 'status', type : 'string' },
  46 + { name : 'processId', type : 'string' },
  47 + { name : 'status', type : 'string' },
53 48 { name : 'percentDone', type : 'string', defaultValue : '0' },
54   - { name : 'start', type: 'date' },
55   - // { name : 'duration', type: 'int' , defaultValue: -1}
56   - { name : 'stop', type: 'date', defaultValue: null },
  49 + { name : 'start', type: 'date' },
  50 + // { name : 'duration', type: 'int' , defaultValue: -1}
  51 + { name : 'stop', type: 'date', defaultValue: null },
57 52 { name : 'rawname', type: 'string'},
58 53 { name : 'tabId', type: 'string'},
59 54 { name : 'info', type: 'string'}
60   -
61 55 ],
62 56  
63 57 constructor : function(config){
64 58  
65 59 this.callParent(arguments);
66 60 this.set('ownerTreeId', amdaUI.ExplorerUI.JOB_TAB.TREE_ID);
67   - this.set('nodeType', amdaModel.BkgJobNode.nodeType);
68   -
  61 +
69 62 if (this.isLeaf()) {
70 63 switch (this.get('status')) {
71 64 case amdaModel.BkgJobNode.STATUS_LIST.ERROR:
... ... @@ -225,12 +218,18 @@ Ext.define('amdaModel.BkgJobNode', {
225 218 var obj = null;
226 219 switch (this.get('jobType'))
227 220 {
228   - case 'condition' :
  221 + case 'condition' :
229 222 obj = Ext.create('amdaModel.Search',
230 223 {name: result.name,
231 224 resultId : result.result,
232 225 folderId : result.folder});
233 226 break;
  227 + case 'statistics' :
  228 + obj = Ext.create('amdaModel.Statistics',
  229 + {name: result.name,
  230 + resultId : result.result,
  231 + folderId : result.folder});
  232 + break;
234 233 case 'request' :
235 234 obj = Ext.create('amdaModel.Plot',
236 235 {name: result.name, format: result.format,
... ... @@ -355,8 +354,8 @@ Ext.define('amdaModel.BkgJobNode', {
355 354 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD:
356 355 rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.DOWNLOAD;
357 356 break;
358   - case amdaModel.BkgJobNode.JOB_TYPES.CATALOG:
359   - rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.CATALOG;
  357 + case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS:
  358 + rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.STATISTICS;
360 359 break;
361 360 default:
362 361 break;
... ... @@ -373,8 +372,8 @@ Ext.define('amdaModel.BkgJobNode', {
373 372 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD:
374 373 rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.DOWNLOAD;
375 374 break;
376   - case amdaModel.BkgJobNode.JOB_TYPES.CATALOG:
377   - rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.CATALOG;
  375 + case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS:
  376 + rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.STATISTICS;
378 377 break;
379 378 default:
380 379 break;
... ...
js/app/models/Catalog.js 0 โ†’ 100644
... ... @@ -0,0 +1,49 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : Catalog.js
  4 + * Description : Catalog Object Definition
  5 + * @class amdaModel.Catalog
  6 + * @extends amdaModel.TimeTable
  7 + * @author elena
  8 + */
  9 +
  10 +
  11 +
  12 +Ext.define('amdaModel.Catalog', {
  13 +
  14 + extend: 'amdaModel.TimeTable',
  15 +
  16 + fields : [
  17 + { name: 'parameters' }
  18 + ],
  19 +
  20 + getJsonValues : function (hasId) {
  21 + var values = new Object();
  22 + if (hasId) {
  23 + values.id = this.get('id');
  24 + }
  25 +
  26 + values.timesrc = this.get('timesrc');
  27 + values.name = this.get('name');
  28 + values.created = this.get('created');
  29 +
  30 + if (this.get('description').match(/[a-z,0-9]/gi) != null) {
  31 + values.description = this.get('description');
  32 + }
  33 +// if (this.get('history').match(/[a-z,0-9]/gi) != null) {
  34 +// values.history = this.get('history');
  35 +// }
  36 + values.objName = this.get('objName');
  37 + values.objFormat = this.get('objFormat');
  38 + values.folderId = this.get('folderId');
  39 + values.nbIntervals = this.get('nbIntervals');
  40 + values.cacheToken = this.get('cacheToken');
  41 + values.parameters = this.get('parameters');
  42 + values.leaf = true;
  43 + values.nodeType = amdaModel.CatalogNode.nodeType;
  44 + return values;
  45 + }
  46 +
  47 +
  48 +
  49 +});
0 50 \ No newline at end of file
... ...
js/app/models/CatalogNode.js 0 โ†’ 100644
... ... @@ -0,0 +1,73 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : CatalogNode.js
  4 + * @class amdaModel.CatalogNode
  5 + * @extends amdaModel.TimeTableNode
  6 + * @brief Basic Model of Node corresponding to a amda catalog
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaModel.CatalogNode', {
  11 +
  12 + extend: 'amdaModel.TimeTableNode',
  13 +
  14 + statics: {
  15 + nodeType: 'catalog',
  16 + objectName: 'Catalog'
  17 + },
  18 +
  19 + constructor : function(config)
  20 + {
  21 + this.callParent(arguments)
  22 + this.set('moduleId',myDesktopApp.dynamicModules.catalog.id);
  23 + this.set('objectDataModel',amdaModel.Catalog.$className);
  24 + if (this.get('leaf')) this.set('iconCls', 'icon-catalog');
  25 + },
  26 +
  27 + localMenuItems : function() {
  28 + var menuItems =
  29 + [/*{
  30 + fnId : 'dire-shareNode',
  31 + text : 'Share content',
  32 + hidden : true
  33 + },{
  34 + fnId : 'leaf-shareLeaf',
  35 + text : 'Share '+this.self.objectName,
  36 + hidden : true
  37 + },*/{
  38 + fnId : 'leaf-download',
  39 + text : 'Download '+ this.self.objectName,
  40 + hidden : true
  41 + }/*,{
  42 + fnId : 'leaf-operations',
  43 + text : 'Operations',
  44 + hidden : true
  45 + }*/];
  46 +
  47 + return menuItems;
  48 + },
  49 +
  50 + localMultiMenuItems : function() {
  51 + var menuItems =
  52 + [/*{
  53 + fnId : 'mult-shareMulti',
  54 + text : 'Share selected '+this.self.objectName+'s'
  55 + },*/{
  56 + fnId : 'mult-downloadMulti',
  57 + text : 'Download selected '+this.self.objectName+'s'
  58 + }/*,{
  59 + fnId : 'mult-operationsMulti',
  60 + text : 'Operations'
  61 + }*/];
  62 +
  63 + return menuItems;
  64 + },
  65 +
  66 + ttDownload : function() {
  67 + alert('NOT IMPLEMENTED YET');
  68 + },
  69 +
  70 + downloadMulti: function() {
  71 + alert('NOT IMPLEMENTED YET');
  72 + }
  73 +});
... ...
js/app/models/DerivedParamNode.js
... ... @@ -6,12 +6,6 @@
6 6 * @brief Model of Node corresponding to a derived parameter
7 7 * @author CDA
8 8 * @version $Id: DerivedParamNode.js 2544 2014-10-03 10:21:56Z elena $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :08/06/2011: CDA - Migration extjs4
14   - * : :09/06/2011: elena - all generic methods are now of InteractiveNode class
15 9 */
16 10  
17 11 Ext.define('amdaModel.DerivedParamNode', {
... ... @@ -28,13 +22,11 @@ Ext.define('amdaModel.DerivedParamNode', {
28 22 ],
29 23  
30 24 constructor : function(config){
31   - this.callParent(arguments);
32   -
33   - this.set('nodeType',amdaModel.DerivedParamNode.nodeType);
  25 + this.callParent(arguments);
34 26 this.set('moduleId',myDesktopApp.dynamicModules.param.id);
35 27 this.set('objectDataModel',amdaModel.Parameter.$className);
36 28 this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
37   - if (this.get('leaf')) this.set('iconCls', 'icon-scalar');
  29 + if (this.get('leaf')) this.set('iconCls', 'icon-scalar');
38 30 },
39 31  
40 32 localMenuItems : function() {
... ... @@ -53,15 +45,11 @@ Ext.define('amdaModel.DerivedParamNode', {
53 45  
54 46 getAllContextMenuItems: function(){
55 47  
56   - var menuItems = this.allMenuItems(amdaModel.DerivedParamNode.objectName);
  48 + var menuItems = this.allMenuItems();
57 49 var locMenuItems = this.localMenuItems();
58 50  
59 51 return Ext.Array.merge(menuItems,locMenuItems);
60   - },
61   -
62   - getMultiContextMenuItems: function(){
63   - return this.allMenuMultiItems(amdaModel.DerivedParamNode.objectName);
64   - },
  52 + },
65 53  
66 54 isParameter : function(){
67 55 return this.get('isParameter');
... ...
js/app/models/DownloadNode.js
... ... @@ -14,14 +14,14 @@ Ext.define('amdaModel.DownloadNode', {
14 14  
15 15 singleton: true,
16 16  
17   - fields: [ {name : 'downloadType', type : 'string'},
18   - {name: 'object', type: 'object'},
19   - {name: 'realLinkedNode', type: 'amdaModel.AmdaNode'},
20   - {name: 'moduleId', type: 'string', defaultValue:'down-win'},
21   - {name: 'nodeType', type: 'string', defaultValue: 'download'},
22   - {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Download'},
23   - {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
24   - ],
  17 + fields:[{name : 'downloadType', type : 'string'},
  18 + {name: 'object', type: 'object'},
  19 + {name: 'realLinkedNode', type: 'amdaModel.AmdaNode'},
  20 + {name: 'moduleId', type: 'string', defaultValue:'down-win'},
  21 + {name: 'nodeType', type: 'string', defaultValue: 'download'},
  22 + {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Download'},
  23 + {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
  24 + ],
25 25  
26 26 isExecutable: function(){
27 27 return true;
... ...
js/app/models/ExecutableNode.js
... ... @@ -24,7 +24,8 @@ Ext.define('amdaModel.ExecutableNode', {
24 24 statics: { jobTreeLoaded : false },
25 25  
26 26 constructor : function(config) {
27   - this.callParent(arguments);
  27 + this.callParent(arguments);
  28 + this.set('ownerTreeId',amdaUI.ExplorerUI.OPE_TAB.TREE_ID);
28 29 this.set('jobNode', amdaModel.BkgJobNode.$className);
29 30 },
30 31  
... ...
js/app/models/InteractiveNode.js
... ... @@ -82,7 +82,9 @@ Ext.define('amdaModel.InteractiveNode', {
82 82  
83 83 constructor : function(config)
84 84 {
85   - this.callParent(arguments);
  85 + this.callParent(arguments);
  86 + this.set('nodeType',this.self.nodeType);
  87 + this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
86 88 // if id of this node have root category suffix
87 89 if (Ext.util.Format.substr(this.get('id'), -(amdaUI.ExplorerUI.CAT_SUFFIX.length), this.get('id').length) === amdaUI.ExplorerUI.CAT_SUFFIX)
88 90 {
... ... @@ -369,7 +371,8 @@ Ext.define('amdaModel.InteractiveNode', {
369 371 * Generic part of Context Menu
370 372 *
371 373 */
372   - allMenuItems : function(src) {
  374 + allMenuItems : function() {
  375 + var src = this.self.objectName;
373 376 var menuItems =
374 377 [ {
375 378 fnId : 'root-createLeaf',
... ... @@ -402,16 +405,24 @@ Ext.define('amdaModel.InteractiveNode', {
402 405 return menuItems;
403 406 },
404 407  
405   - allMenuMultiItems : function(src) {
  408 + allMenuMultiItems : function() {
406 409 var menuMulti = [
407 410 {
408 411 fnId : 'mult-deleteMulti',
409   - text : 'Delete selected '+ src+'s'
  412 + text : 'Delete selected ' + this.self.objectName + 's'
410 413 }
411 414 ];
412 415 return menuMulti;
413 416 },
414 417  
  418 + getAllContextMenuItems: function(){
  419 + return this.allMenuItems();
  420 + },
  421 +
  422 + getMultiContextMenuItems: function(){
  423 + return this.allMenuMultiItems();
  424 + },
  425 +
415 426 /**
416 427 * default implementation
417 428 * no menu display if there's no override of this function
... ...
js/app/models/LocalParamNode.js
... ... @@ -39,9 +39,7 @@ Ext.define('amdaModel.LocalParamNode',
39 39 this.set('allowDrop', true);
40 40 this.set('moduleId',myDesktopApp.dynamicModules.param.id);
41 41 this.set('objectDataModel',amdaModel.Parameter.$className);
42   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
43   - this.set('nodeType',amdaModel.LocalParamNode.nodeType);
44   -
  42 +
45 43 // if future missions or 'depending on mission'
46 44 if (this.get('globalStart')) {
47 45 var now = Ext.Date.format(new Date(), 'Y/m/d');
... ... @@ -126,11 +124,7 @@ Ext.define('amdaModel.LocalParamNode',
126 124 return menuItems;
127 125 },
128 126  
129   - getAllContextMenuItems: function()
130   - {
131   - return this.allMenuItems();
132   - },
133   -
  127 +
134 128 onMenuItemClick : function(menu,item,event)
135 129 {
136 130 switch (item.fnId)
... ...
js/app/models/MyDataNode.js
... ... @@ -17,26 +17,24 @@ Ext.define('amdaModel.MyDataNode', {
17 17  
18 18 extend: 'amdaModel.InteractiveNode',
19 19  
  20 + statics:{
  21 + nodeType: 'myData'
  22 + },
  23 +
20 24 fields:
21 25 [
22 26 {name: 'globalStart', type: 'string', persist: false},
23 27 {name: 'globalStop', type: 'string', persist: false}
24 28 ],
25 29  
  30 + dependentRootNodeId : 'myDataParam-treeRootNode',
  31 +
26 32 constructor : function(config){
27 33 this.callParent(arguments);
28 34 this.set('moduleId',myDesktopApp.dynamicModules.my_data.id);
29 35 this.set('objectDataModel','amdaModel.FileObject');
30   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
31   - this.set('nodeType',amdaModel.MyDataNode.nodeType);
32   - },
33   -
34   - statics:{
35   - nodeType: 'myData'
36 36 },
37   -
38   - dependentRootNodeId : 'myDataParam-treeRootNode',
39   -
  37 +
40 38 localMenuItems : function() {
41 39 var menuItems =
42 40 [{
... ...
js/app/models/MyDataParamNode.js
... ... @@ -13,32 +13,31 @@
13 13  
14 14 Ext.define('amdaModel.MyDataParamNode', {
15 15  
16   - extend: 'amdaModel.InteractiveNode',
17   -
18   - fields : [ // { name : 'linkedFile', persist: false},
19   - { name : 'linkedMask', persist: false},
20   - { name : 'fileObject', persist: false},
21   - { name : 'size', persist: false},
22   - { name : 'isSpectra', type: 'boolean', defaultValue: false, persist: false }
23   - ],
  16 + extend: 'amdaModel.InteractiveNode',
  17 +
  18 + fields : [ // { name : 'linkedFile', persist: false},
  19 + { name : 'linkedMask', persist: false},
  20 + { name : 'fileObject', persist: false},
  21 + { name : 'size', persist: false},
  22 + { name : 'isSpectra', type: 'boolean', defaultValue: false, persist: false }
  23 + ],
24 24  
25   - statics:{
26   - nodeType: 'myDataParam'
27   - },
  25 + statics:{
  26 + nodeType: 'myDataParam',
  27 + objectName : 'Parameter'
  28 + },
28 29  
29   - constructor : function(config){
  30 + constructor : function(config)
  31 + {
30 32 this.callParent(arguments);
31 33 this.set('moduleId',myDesktopApp.dynamicModules.my_data.id);
32   - this.set('objectDataModel','amdaModel.FileParamObject');
33   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
34   - this.set('nodeType',amdaModel.MyDataParamNode.nodeType);
  34 + this.set('objectDataModel','amdaModel.FileParamObject');
35 35 if (this.get('isParameter')) {
36 36 if (this.get('size') == 1) this.set('iconCls', 'icon-scalar');
37 37 else this.set('iconCls', 'icon-unknowntype');
38 38 }
39 39 //TODO this.set('iconCls', 'icon-vector');
40   - if (this.get('isSpectra')) this.set('iconCls', 'icon-spectra');
41   -
  40 + if (this.get('isSpectra')) this.set('iconCls', 'icon-spectra');
42 41 },
43 42  
44 43 localMenuItems : function() {
... ... @@ -75,12 +74,8 @@ Ext.define('amdaModel.MyDataParamNode', {
75 74 return menuItems;
76 75 },
77 76  
78   - getAllContextMenuItems: function(){
79   -
80   - var menuItems = this.allMenuItems('Parameter');
81   - var locMenuItems = this.localMenuItems();
82   -
83   - return Ext.Array.merge(menuItems,locMenuItems);
  77 + getAllContextMenuItems: function(){
  78 + return this.localMenuItems();
84 79 },
85 80  
86 81 onMenuItemClick : function(menu,item,event) {
... ...
js/app/models/PlotNode.js
... ... @@ -6,11 +6,6 @@
6 6 * @brief Basic Model of Node corresponding to a plot request
7 7 * @author Caroline DARMON
8 8 * @version $Id: $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :08/09/2011: CDA - file creation
14 9 */
15 10  
16 11 Ext.define('amdaModel.PlotNode', {
... ... @@ -19,16 +14,13 @@ Ext.define('amdaModel.PlotNode', {
19 14  
20 15 statics: {
21 16 nodeType: 'request'
22   - // objectName: 'Plot Request',
23 17 },
24 18  
25   - constructor : function(config){
26   -
  19 + constructor : function(config)
  20 + {
27 21 this.callParent(arguments);
28 22 this.set('moduleId',myDesktopApp.dynamicModules.plot.id);
29 23 this.set('objectDataModel',amdaModel.Plot.$className);
30   - this.set('ownerTreeId',amdaUI.ExplorerUI.OPE_TAB.TREE_ID);
31   - this.set('nodeType',amdaModel.PlotNode.nodeType);
32 24 },
33 25  
34 26 allMenuItems : function() {
... ... @@ -72,14 +64,7 @@ Ext.define('amdaModel.PlotNode', {
72 64 return menuMulti;
73 65 },
74 66  
75   - getAllContextMenuItems: function(){
76   - return this.allMenuItems();
77   - },
78   -
79   - getMultiContextMenuItems: function(){
80   - return this.allMenuMultiItems();
81   - },
82   -
  67 +
83 68 onMenuItemClick : function(menu,item,event) {
84 69 // fnId parsing :
85 70 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
... ...
js/app/models/RemoteParamNode.js
... ... @@ -12,14 +12,17 @@ Ext.define('amdaModel.RemoteParamNode', {
12 12  
13 13 extend: 'amdaModel.LocalParamNode',
14 14  
  15 + statics:{
  16 + nodeType: 'remoteParam'
  17 + },
  18 +
15 19 fields: [
16 20 {name: 'isRemoteDataSet', type:'boolean', persist: false, defaultValue: false},
17 21 {name: 'isSimulation', type:'boolean', defaultValue: false}
18 22 ],
19 23  
20 24 constructor : function(config){
21   - this.callParent(arguments);
22   - this.set('nodeType',amdaModel.RemoteParamNode.nodeType);
  25 + this.callParent(arguments);
23 26 //TODO only for INTEROPER TREE
24 27 if (!this.get('leaf')) this.set('allowDrag', false);
25 28 if (this.get('isParameter')) this.set('allowDrag',true);
... ... @@ -30,10 +33,7 @@ Ext.define('amdaModel.RemoteParamNode', {
30 33 }
31 34 },
32 35  
33   - statics:{
34   - nodeType: 'remoteParam'
35   - },
36   -
  36 +
37 37 allMenuItems : function() {
38 38 var menuItems =
39 39 [{
... ...
js/app/models/RemoteSimuParamNode.js
... ... @@ -12,6 +12,10 @@ Ext.define('amdaModel.RemoteSimuParamNode', {
12 12  
13 13 extend: 'amdaModel.LocalParamNode',
14 14  
  15 + statics:{
  16 + nodeType: 'remoteSimuParam'
  17 + },
  18 +
15 19 requires: 'amdaUI.InteropImpexUI',
16 20  
17 21 fields: [
... ... @@ -23,10 +27,9 @@ Ext.define('amdaModel.RemoteSimuParamNode', {
23 27 ],
24 28  
25 29 constructor : function(config){
26   - this.callParent(arguments);
27   - this.set('nodeType',amdaModel.RemoteSimuParamNode.nodeType);
  30 + this.callParent(arguments);
28 31 if (this.get('isParameter')) this.set('needsArgs',this.get('needsArgs'));
29   - if (this.get('leaf') && this.get('isSpectra')) this.set('iconCls', 'icon-spectra');
  32 + if (this.get('leaf') && this.get('isSpectra')) this.set('iconCls', 'icon-spectra');
30 33 if (this.get('disable')) {
31 34 this.set('cls', 'icon-disabled');
32 35 this.set('allowDrag', false);
... ... @@ -48,10 +51,7 @@ Ext.define('amdaModel.RemoteSimuParamNode', {
48 51 }
49 52 },
50 53  
51   - statics:{
52   - nodeType: 'remoteSimuParam'
53   - },
54   -
  54 +
55 55 allMenuItems : function() {
56 56 var menuItems =
57 57 [ {
... ...
js/app/models/SearchNode.js
... ... @@ -6,11 +6,6 @@
6 6 * @brief Basic Model of Node corresponding to a amda condition
7 7 * @author
8 8 * @version $Id: SearchNode.js 1739 2013-09-09 14:47:10Z myriam $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :23/06/2011: myriam - Migration extjs4
14 9 */
15 10  
16 11 Ext.define('amdaModel.SearchNode', {
... ... @@ -21,15 +16,12 @@ Ext.define('amdaModel.SearchNode', {
21 16 nodeType: 'condition'
22 17 },
23 18  
24   - constructor : function(config){
25   -
  19 + constructor : function(config)
  20 + {
26 21 this.callParent(arguments);
27 22 this.set('moduleId',myDesktopApp.dynamicModules.search.id);
28   - this.set('objectDataModel',amdaModel.Search.$className);
29   - this.set('ownerTreeId',amdaUI.ExplorerUI.OPE_TAB.TREE_ID);
30   - this.set('nodeType',amdaModel.SearchNode.nodeType);
31   - this.set('resultModel',amdaModel.TimeTable.$className);
32   -
  23 + this.set('objectDataModel',amdaModel.Search.$className);
  24 + this.set('resultModel',amdaModel.TimeTable.$className);
33 25 },
34 26  
35 27 allMenuItems : function() {
... ... @@ -70,14 +62,7 @@ Ext.define('amdaModel.SearchNode', {
70 62 return menuMulti;
71 63 },
72 64  
73   - getAllContextMenuItems: function(){
74   - return this.allMenuItems();
75   - },
76   -
77   - getMultiContextMenuItems: function(){
78   - return this.allMenuMultiItems();
79   - },
80   -
  65 +
81 66 onMenuItemClick : function(menu,item,event) {
82 67 // fnId parsing :
83 68 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
... ...
js/app/models/Statistics.js 0 โ†’ 100644
... ... @@ -0,0 +1,75 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : Statistics.js
  4 + * Description : Statistics Object Definition
  5 + * @class amdaModel.Statistics
  6 + * @extends amdaModel.TimeTable
  7 + * @author elena
  8 + */
  9 +
  10 +
  11 +
  12 +Ext.define('amdaModel.Statistics', {
  13 +
  14 + extend: 'amdaModel.AmdaTimeObject',
  15 +
  16 + fields : [
  17 + { name: 'parameter' } ,
  18 + { name: 'description' }
  19 + // { name: 'timesrc', type: 'string'}
  20 + ],
  21 +
  22 + getJsonValues : function (hasId) {
  23 + var values = new Object();
  24 + if (hasId) {
  25 + values.id = this.get('id');
  26 + }
  27 +
  28 + values.timesrc = this.get('timesrc');
  29 + values.name = 'test'; //this.get('name');
  30 +
  31 +
  32 + if (this.get('description').match(/[a-z,0-9]/gi) != null) {
  33 + values.description = this.get('description');
  34 + }
  35 +// if (this.get('history').match(/[a-z,0-9]/gi) != null) {
  36 +// values.history = this.get('history');
  37 +// }
  38 + values.objName = this.get('objName');
  39 + values.objFormat = this.get('objFormat');
  40 +
  41 +// values.cacheToken = this.get('cacheToken');
  42 + values.parameter = this.get('parameter');
  43 + if (values.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0]){
  44 + // get complete timeTables collection
  45 + var timeTables = this.get('timeTables');
  46 + // init an empty array for timeTables
  47 + values.timeTables=[];
  48 + // for each interval record
  49 + Ext.Array.each(timeTables, function(item, index, all){
  50 + if (!item.$className) {
  51 + values.timeTables[index] = {timeTableName : item.timeTableName, id : item.id};
  52 + }
  53 + // get Json simplified value
  54 + else {
  55 + values.timeTables[index] = item.getJsonValues();
  56 + }
  57 + });
  58 + } else {
  59 + values.startDate = this.get('startDate');
  60 + values.stopDate = this.get('stopDate');
  61 + values.durationDay = this.get('durationDay');
  62 + values.durationHour = this.get('durationHour');
  63 + values.durationMin = this.get('durationMin');
  64 + values.durationSec = this.get('durationSec');
  65 + }
  66 +
  67 + values.leaf = true;
  68 + values.nodeType = 'statistics';
  69 +
  70 + return values;
  71 + }
  72 +
  73 +
  74 +
  75 +});
0 76 \ No newline at end of file
... ...
js/app/models/StatisticsNode.js 0 โ†’ 100644
... ... @@ -0,0 +1,33 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : StatisticsNode.js
  4 + * @class amdaModel.StatisticsNode
  5 + * @extends amdaModel.ExecutableNode
  6 + * @brief Basic Model of Node corresponding to a amda statistics operation
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaModel.StatisticsNode', {
  11 +
  12 + extend: 'amdaModel.ExecutableNode',
  13 +
  14 + singleton: true,
  15 +
  16 + fields: [
  17 + {name: 'downloadType', type : 'string'},
  18 + {name: 'object', type: 'object'},
  19 + {name: 'realLinkedNode', type: 'amdaModel.AmdaNode'},
  20 + {name: 'moduleId', type: 'string', defaultValue:'statistics-win'},
  21 + {name: 'nodeType', type: 'string', defaultValue: 'statistics'},
  22 + {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Statistics'},
  23 + {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
  24 + ],
  25 +
  26 + constructor: function(config) {
  27 + this.callParent(arguments);
  28 + this.set('nodeType','statistics');
  29 + },
  30 + isExecutable: function(){
  31 + return true;
  32 + }
  33 +});
... ...
js/app/models/TimeTableNode.js
... ... @@ -6,12 +6,6 @@
6 6 * @brief Basic Model of Node corresponding to a amda Time Table
7 7 * @author
8 8 * @version $Id: TimeTableNode.js 1904 2013-11-25 12:42:02Z elena $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :08/06/2011: CDA - Migration extjs4
14   - * : :09/06/2011: elena - all generic methods are now of InteractiveNode class
15 9 */
16 10  
17 11 Ext.define('amdaModel.TimeTableNode', {
... ... @@ -23,17 +17,16 @@ Ext.define('amdaModel.TimeTableNode', {
23 17 objectName: 'Time Table'
24 18 },
25 19  
26   - constructor : function(config){
  20 + constructor : function(config)
  21 + {
27 22 this.callParent(arguments);
28   -
29   - this.set('nodeType',amdaModel.TimeTableNode.nodeType);
30   - this.set('moduleId',myDesktopApp.dynamicModules.tt.id);//'timetab-win');
31   - this.set('objectDataModel','amdaModel.TimeTable');
32   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  23 + this.set('moduleId',myDesktopApp.dynamicModules.tt.id);
  24 + this.set('objectDataModel','amdaModel.TimeTable');
33 25 if (this.get('leaf')) this.set('iconCls', 'icon-timetable');
34 26 },
35 27  
36   - localMenuItems : function() {
  28 + localMenuItems : function()
  29 + {
37 30 var menuItems =
38 31 [/*{
39 32 fnId : 'dire-shareNode',
... ... @@ -60,10 +53,10 @@ Ext.define('amdaModel.TimeTableNode', {
60 53 var menuItems =
61 54 [/*{
62 55 fnId : 'mult-shareMulti',
63   - text : 'Share selected '+amdaModel.TimeTableNode.objectName+'s'
  56 + text : 'Share selected '+this.self.objectName+'s'
64 57 },*/{
65 58 fnId : 'mult-downloadMulti',
66   - text : 'Download selected '+amdaModel.TimeTableNode.objectName+'s'
  59 + text : 'Download selected '+this.self.objectName+'s'
67 60 },{
68 61 fnId : 'mult-operationsMulti',
69 62 text : 'Operations'
... ... @@ -73,18 +66,21 @@ Ext.define('amdaModel.TimeTableNode', {
73 66 },
74 67  
75 68 getAllContextMenuItems: function(){
76   -
77   - var menuItems = this.allMenuItems(amdaModel.TimeTableNode.objectName);
  69 +
  70 + var menuItems = this.allMenuItems();
78 71 var locMenuItems = this.localMenuItems();
79   - return Ext.Array.merge(menuItems,locMenuItems);
  72 +
  73 + return Ext.Array.merge(menuItems,locMenuItems);
80 74 },
81 75  
82   - getMultiContextMenuItems: function(){
83   - var multiMenu = this.allMenuMultiItems(amdaModel.TimeTableNode.objectName);
84   - var locMultiMenuItems = this.localMultiMenuItems();
85   - return Ext.Array.merge(multiMenu,locMultiMenuItems);
  76 + getMultiContextMenuItems: function(){
  77 +
  78 + var menuItems = this.allMenuMultiItems();
  79 + var locMenuItems = this.localMultiMenuItems();
  80 +
  81 + return Ext.Array.merge(menuItems,locMenuItems);
86 82 },
87   -
  83 +
88 84 onMenuItemClick : function(menu,item,event) {
89 85  
90 86 this.callParent(arguments);
... ...
js/app/models/sharedTimeTableNode.js
... ... @@ -6,12 +6,6 @@
6 6 * @brief Basic Model of Node corresponding to a amda Time Table
7 7 * @author
8 8 * @version $Id: sharedTimeTableNode.js 1916 2013-11-26 10:58:49Z elena $
9   - * @todo
10   - *******************************************************************************
11   - * FT Id : Date : Name - Description
12   - *******************************************************************************
13   - * : :08/06/2011: CDA - Migration extjs4
14   - * : :09/06/2011: elena - all generic methods are now of InteractiveNode class
15 9 */
16 10  
17 11 Ext.define('amdaModel.sharedTimeTableNode', {
... ... @@ -19,17 +13,14 @@ Ext.define('amdaModel.sharedTimeTableNode', {
19 13 extend: 'amdaModel.InteractiveNode',
20 14  
21 15 statics: {
22   - nodeType: 'sharedtimeTable',
  16 + nodeType: 'sharedtimeTable',
23 17 objectName: 'Time Table'
24 18 },
25 19  
26 20 constructor : function(config){
27 21 this.callParent(arguments);
28   -
29   - this.set('nodeType',amdaModel.sharedTimeTableNode.nodeType);
30   - this.set('moduleId',myDesktopApp.dynamicModules.tt.id);//'timetab-win');
31   - this.set('objectDataModel','amdaModel.TimeTable');
32   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  22 + this.set('moduleId',myDesktopApp.dynamicModules.tt.id);
  23 + this.set('objectDataModel','amdaModel.TimeTable');
33 24 if (this.get('leaf')) this.set('iconCls', 'icon-timetable');
34 25 },
35 26  
... ...
js/app/stores/ExplorerReader.js
... ... @@ -37,6 +37,8 @@ Ext.define('amdaReader.ExplorerReader', {
37 37 return amdaModel.AliasNode;
38 38 case 'timeTable' :
39 39 return amdaModel.TimeTableNode;
  40 + case 'catalog' :
  41 + return amdaModel.CatalogNode;
40 42 case 'sharedtimeTable' :
41 43 return amdaModel.sharedTimeTableNode;
42 44 case 'condition' :
... ...
js/app/views/CatalogUI.js 0 โ†’ 100644
... ... @@ -0,0 +1,497 @@
  1 +/**
  2 + * Project AMDA-NG
  3 + * Name CatalogUI.js
  4 + * @class amdaUI.catalogUI
  5 + * @extends Ext.container.Container
  6 + * @brief Catalog Module UI definition (View)
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaUI.CatalogUI', {
  11 + extend: 'Ext.container.Container',
  12 + alias: 'widget.panelCatalog',
  13 +
  14 + isCatalog : true,
  15 +
  16 + constructor: function(config)
  17 + {
  18 + this.init(config);
  19 + this.callParent(arguments);;
  20 + if (this.object) this.loadObject();
  21 + },
  22 +
  23 + setObject : function (object)
  24 + {
  25 + // set object
  26 + this.object = object;
  27 +
  28 + // load object into view
  29 + this.loadObject();
  30 + },
  31 +
  32 + /**
  33 + * set params description into this.object
  34 + */
  35 + setParamInfo : function(parameters)
  36 + {
  37 + var params = [];
  38 + Ext.Array.each(parameters, function(item, index) {
  39 + params[index] = item;
  40 + }, this);
  41 +
  42 + this.object.set('parameters', params);
  43 + },
  44 +
  45 + /**
  46 + * update this.object from form
  47 + */
  48 + updateObject : function()
  49 + {
  50 + // get the basic form
  51 + var basicForm = this.formPanel.getForm();
  52 + var updateStatus = true;
  53 +
  54 + var fieldsWithoutName = basicForm.getFields().items;
  55 + Ext.Array.each(fieldsWithoutName, function(item, index,allItems){
  56 + if(item !== this.fieldName) {
  57 + if (!item.isValid()) {
  58 + // set update isn't allowed
  59 + updateStatus = false;
  60 + }
  61 + }
  62 + }, this);
  63 + // if the update is allowed
  64 + if (updateStatus) {
  65 + /// real object update
  66 + // update TimeTable object with the content of form
  67 + basicForm.updateRecord(this.object);
  68 + }
  69 + // return the update status
  70 + return updateStatus;
  71 + },
  72 +
  73 +
  74 + updateCount : function()
  75 + {
  76 + this.object.set('nbIntervals',this.TTGrid.getStore().getTotalCount());
  77 + this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals'));
  78 + },
  79 +
  80 + /**
  81 + * load object catalog into this view
  82 + */
  83 + loadObject : function()
  84 + {
  85 + // load object into form
  86 + this.formPanel.getForm().loadRecord(this.object);
  87 +
  88 + this.status = null;
  89 +
  90 + var me = this;
  91 +
  92 + var onAfterInit = function(result, e)
  93 + {
  94 + if (!result || !result.success)
  95 + {
  96 + if (result.message)
  97 + myDesktopApp.errorMsg(result.message);
  98 + else
  99 + myDesktopApp.errorMsg('Unknown error during catalog cache initialisation');
  100 + return;
  101 + }
  102 +
  103 + var fields = [], columns = [], i = 3, width, index;
  104 +
  105 + var fieldsConfig = [{ name : 'start' },{ name : 'stop' },{ name: 'cacheId', type : 'int'},
  106 + { name: 'isNew', type : 'boolean', defaultValue: false },
  107 + { name: 'isModified', type : 'boolean', defaultValue: false}
  108 + ];
  109 +
  110 + for (var j = 0; j < 5; j++) fields[j] = Ext.create('Ext.data.Field', fieldsConfig[j]);
  111 +
  112 + columns[0] = Ext.create('Ext.grid.column.RowNumberer');
  113 +
  114 + columns[1] = Ext.create('Ext.grid.column.Column', { text: 'Start Time', sortable : false, dataIndex: 'start',
  115 + width : 120, menuDisabled: true });
  116 + columns[2] = Ext.create('Ext.grid.column.Column', { text: 'Stop Time', sortable : false, dataIndex: 'stop',
  117 + width : 120, menuDisabled: true });
  118 +
  119 + Ext.Array.each(result.parameters, function(obj)
  120 + {
  121 + index = 'param'+(i-1).toString();
  122 + fields[i+2] = Ext.create('Ext.data.Field',{ name : index });
  123 + width = 50. * parseInt(obj.size);
  124 + columns[i] = Ext.create('Ext.grid.column.Column', { text: obj.name, sortable : false, dataIndex: index,
  125 + width : width, menuDisabled: true });
  126 + i++;
  127 + });
  128 +
  129 +
  130 +
  131 + var store = Ext.create('Ext.data.Store', {
  132 + fields: fields,
  133 + autoDestroy: false,
  134 + pageSize : 200,
  135 + buffered : true,
  136 + purgePageCount: 0,
  137 + remoteSort: true,
  138 + proxy: {
  139 + type: 'direct',
  140 + api :
  141 + {
  142 + read : AmdaAction.readTTCacheIntervals
  143 + },
  144 + // remplir automatiquement tt, sharedtt , catalog, shared catalog
  145 + extraParams : {'typeTT' : 'catalog'},
  146 + reader:
  147 + {
  148 + type: 'json',
  149 + root: 'intervals',
  150 + totalProperty : 'totalCount'
  151 + }
  152 + },
  153 + listeners: {
  154 + scope : me,
  155 + load: function(store,records) {
  156 + // myDesktopApp.EventManager.fireEvent('refresh');
  157 + me.TTGrid.getView().refresh();
  158 + me.TTGrid.getSelectionModel().refresh();
  159 + me.updateCount();
  160 + //Statistical plugin
  161 + // this.fireEvent("refresh");
  162 + }
  163 + }
  164 + });
  165 +
  166 + me.TTGrid.reconfigure(store, columns);
  167 +
  168 + me.TTGrid.getSelectionModel().deselectAll();
  169 + //
  170 + // // clear filters
  171 + // me.TTGrid.getStore().clearFilter(true);
  172 + //
  173 + // //clear sort
  174 + // me.TTGrid.getStore().sorters.clear();
  175 + // //me.TTGrid.getStore().sorters = new Ext.util.MixedCollection();
  176 + //
  177 + //set cache token to the Catalog object
  178 + me.object.set('cacheToken', result.token);
  179 + me.setParamInfo(result.parameters);
  180 +
  181 + me.TTGrid.getStore().load();
  182 +
  183 + me.status = result.status;
  184 + };
  185 +
  186 + if (this.object.get('fromPlugin'))
  187 + {
  188 + if (this.object.get('objFormat') && this.object.get('objFormat') != '')
  189 + {
  190 + //From uploaded file
  191 + //AmdaAction.initTTCacheFromUploadedFile(this.object.get('objName'), this.object.get('objFormat'), onAfterInit);
  192 + }
  193 + else
  194 + {
  195 + //From tmp object (ie Search result)
  196 + AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, onAfterInit);
  197 + }
  198 + }
  199 + else
  200 + {
  201 + var typeTT = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id).linkedNode.data.nodeType;
  202 + if (this.object.get('id') == '')
  203 + {
  204 + //Init empty cache
  205 + AmdaAction.initTTCache(this.isCatalog, onAfterInit);
  206 + }
  207 + else
  208 + {
  209 + //From existing TT file
  210 + AmdaAction.initTTCacheFromTT(this.object.get('id'), 'catalog', onAfterInit);
  211 + }
  212 + }
  213 + },
  214 +
  215 + checkIntervalsStatusForSave : function(onStatusOk) {
  216 + onStatusOk();
  217 + },
  218 +
  219 + /*
  220 + * save method called by Save button
  221 + */
  222 + saveProcess : function(toRename)
  223 + {
  224 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);
  225 +
  226 + // if the name has been modified this is a creation
  227 + if (this.fclose())
  228 + {
  229 + if (this.object.isModified('name') || this.object.get('fromPlugin')) {
  230 + // if object already has an id : it's a 'rename' of an existing
  231 + if (this.object.get('id')){
  232 + // the context Node is the parent node of current edited one
  233 + var contextNode = module.linkedNode.parentNode;
  234 + // link a new node to the TimeTableModule
  235 + module.createLinkedNode();
  236 + // set the contextNode
  237 + module.linkedNode.set('contextNode',contextNode);
  238 + // create a new object linked
  239 + module.createObject(this.object.getJsonValues());
  240 +
  241 + var obj = module.linkedNode.get('object');
  242 + // synchronisation of objects
  243 + this.object = obj;
  244 + if (toRename) module.linkedNode.toRename = true;
  245 + }
  246 + module.linkedNode.create({callback : function() {module.linkedNode.update();}, scope : this});
  247 + } else {
  248 + //update
  249 + module.linkedNode.update();
  250 + }
  251 + }
  252 + },
  253 +
  254 + /**
  255 + * Check if changes were made before closing window
  256 + * @return true if changes
  257 + */
  258 + fclose : function()
  259 + {
  260 + if (this.status == null)
  261 + return false;
  262 +
  263 + var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0);
  264 + return isDirty;
  265 + },
  266 +
  267 +
  268 + init : function (config)
  269 + {
  270 + this.object = config.object;
  271 +
  272 + this.fieldName = new Ext.form.field.Text({
  273 + fieldLabel: 'Name',
  274 + allowBlank : false,
  275 + stripCharsRe: /(^\s+|\s+$)/g,
  276 + emptyText: 'Please no spaces!',
  277 + name: 'name',
  278 + validateOnChange: false,
  279 + validateOnBlur: false,
  280 + validFlag: false,
  281 + validator : function() {
  282 + return this.validFlag;
  283 + }
  284 + });
  285 +
  286 +
  287 + this.TTGrid = Ext.create('Ext.grid.Panel', {
  288 + height: 530,
  289 + columns: [ ],
  290 + frame: true,
  291 + dockedItems: [{
  292 + xtype: 'toolbar',
  293 + items: [{
  294 + iconCls: 'icon-add',
  295 + scope: this,
  296 + handler: function(){
  297 + alert('NOT IMPLEMENTED YET');
  298 + // cellEditing.cancelEdit();
  299 + //
  300 + // var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0];
  301 + // var row = 0;
  302 + // if (selection)
  303 + // row = store.indexOf(selection) + 1;
  304 + // this.TTGrid.getSelectionModel().deselectAll();
  305 + //
  306 + // var me = this;
  307 + // AmdaAction.addTTCacheInterval({'index' : row}, function (result, e) {
  308 + // this.status = result.status;
  309 + // this.TTGrid.getStore().reload({
  310 + // callback : function(records, options, success) {
  311 + // me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function() {
  312 + // me.TTGrid.getView().select(row);
  313 + // cellEditing.startEditByPosition({row: row, column: 1});
  314 + // }, me);
  315 + // }
  316 + // });
  317 + // }, this);
  318 + }
  319 + },{
  320 + iconCls: 'icon-delete',
  321 + disabled: true,
  322 + itemId: 'delete',
  323 + scope: this,
  324 + handler: function(){
  325 + var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0];
  326 + if (selection)
  327 + {
  328 + var rowId = selection.get('cacheId');
  329 + console.log(selection);
  330 + this.TTGrid.getSelectionModel().deselectAll();
  331 + AmdaAction.removeTTCacheIntervalFromId(rowId, this.isCatalog, function (result, e) {
  332 + this.status = result.status;
  333 + this.TTGrid.getStore().reload();
  334 + }, this);
  335 + }
  336 + }
  337 + }]
  338 + }]
  339 + });
  340 +
  341 + this.formPanel = Ext.create('Ext.form.Panel', {
  342 + region : 'center',
  343 + layout: 'hbox',
  344 + bodyStyle: {background : '#dfe8f6'},
  345 + defaults: { border : false, align: 'stretch', bodyStyle: {background : '#dfe8f6'}, padding: '3'},
  346 + fieldDefaults: { labelWidth: 80, labelAlign : 'top' },
  347 + items: [
  348 + {
  349 + xtype: 'form',
  350 + flex: 1,
  351 + buttonAlign: 'left',
  352 +// title : 'Information',
  353 + layout: {type: 'vbox', pack: 'start', align: 'stretch'},
  354 + items : [
  355 + this.fieldName,
  356 + {
  357 + xtype: 'fieldcontainer',
  358 + layout: 'hbox',
  359 + items: [
  360 + {
  361 + xtype:'datefield', fieldLabel:'Creation date',
  362 + name: 'created', disabled: true,
  363 + hideTrigger: true, format: 'Y/m/d H:i:s'
  364 + },
  365 + { xtype: 'splitter' },
  366 + { xtype:'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true}
  367 + ]
  368 + },
  369 + {
  370 + xtype: 'textarea',
  371 + name: 'description',
  372 + fieldLabel: 'Description',
  373 + height: 200
  374 + },
  375 + {
  376 + xtype: 'component',
  377 + height: 180
  378 + }
  379 + ],
  380 + fbar:[
  381 + {
  382 + type: 'button',
  383 + text: 'Save',
  384 + scope : this,
  385 + handler: function () {
  386 + if (this.updateObject()){
  387 +
  388 + var basicForm = this.formPanel.getForm();
  389 + // if there's at least one record in the store of TTGrid
  390 + if (this.TTGrid.getStore().getTotalCount() > 0) {
  391 + // update TimeTable object which the content of form
  392 + basicForm.updateRecord(this.object);
  393 +
  394 + var me = this;
  395 + this.checkIntervalsStatusForSave(function () {
  396 + //Name validation
  397 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);
  398 + if (!module)
  399 + return;
  400 + module.linkedNode.isValidName(me.fieldName.getValue(), function (res) {
  401 + if (!res)
  402 + {
  403 + me.fieldName.validFlag = 'Error during object validation';
  404 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  405 + me.fieldName.validate();
  406 + return;
  407 + }
  408 +
  409 + if (!res.valid)
  410 + {
  411 + if (res.error)
  412 + {
  413 + if (res.error.search('subtree') != -1) {
  414 + Ext.MessageBox.show({title:'Warning',
  415 + msg: res.error+'<br/>Do you want to overwrite it?',
  416 + width: 300,
  417 + buttons: Ext.MessageBox.OKCANCEL,
  418 + fn : me.overwriteProcess,
  419 + icon: Ext.MessageBox.WARNING,
  420 + scope : me
  421 + });
  422 + me.fieldName.validFlag = true;
  423 + }
  424 + else
  425 + me.fieldName.validFlag = res.error;
  426 + }
  427 + else
  428 + {
  429 + me.fieldName.validFlag = 'Invalid object name';
  430 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  431 + }
  432 + me.fieldName.validate();
  433 + return;
  434 + }
  435 +
  436 + me.fieldName.validFlag = true;
  437 + me.fieldName.validate();
  438 + me.saveProcess(false);
  439 + });
  440 + });
  441 + } else {
  442 + // warning:
  443 + Ext.Msg.alert('No intervals', 'Your time table is invalid, <br>you must have at least one interval');
  444 + }
  445 + }
  446 + }
  447 + },{
  448 + type: 'button',
  449 + text: 'Share',
  450 + disabled: true
  451 + },
  452 + {
  453 + type: 'button',
  454 + text: 'Visualize'
  455 + }
  456 + ]
  457 + }, {
  458 + xtype: 'form',
  459 + bodyStyle: {background : '#dfe8f6'},
  460 +// padding: '3',
  461 + flex: 2,
  462 + items : [
  463 + this.TTGrid
  464 + ]
  465 + }
  466 + ]
  467 + });
  468 +
  469 + this.TTGrid.getSelectionModel().on('selectionchange', function(selModel,selections){
  470 + this.TTGrid.down('#delete').setDisabled(selections.length === 0);
  471 + }, this);
  472 +
  473 + var myConf = {
  474 + layout: 'border',
  475 + items: [
  476 + this.formPanel,
  477 + {
  478 + xtype: 'panel',
  479 + region: 'south',
  480 + title: 'Information',
  481 + collapsible: true,
  482 + height: 100,
  483 + autoHide: false,
  484 + bodyStyle: 'padding:5px',
  485 + iconCls: 'icon-information',
  486 + loader: {
  487 + autoLoad: true,
  488 + url: helpDir+'catalogHOWTO'
  489 + }
  490 + }
  491 + ]
  492 + };
  493 +
  494 + Ext.apply (this, Ext.apply(arguments, myConf));
  495 + }
  496 +
  497 +});
... ...
js/app/views/StatisticsUI.js 0 โ†’ 100644
... ... @@ -0,0 +1,343 @@
  1 +/**
  2 + * Project AMDA-NG
  3 + * Name StatisticsUI.js
  4 + * @class amdaUI.statisticsUI
  5 + * @extends Ext.container.Container
  6 + * @brief Statistics Module UI definition (View)
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaUI.StatisticsUI', {
  11 + extend: 'Ext.container.Container',
  12 + alias: 'widget.panelStatistics',
  13 +
  14 + requires : [
  15 +// 'amdaModel.Function'
  16 + 'amdaUI.TimeSelectorUI'
  17 + ],
  18 +
  19 + statics : {
  20 +// functionStore : null
  21 + },
  22 +
  23 + constructor: function(config) {
  24 + this.init(config);
  25 + this.callParent(arguments);
  26 + // if (this.object) this.loadObject();
  27 + },
  28 +
  29 + addParam : function(ParamName,isLeaf)
  30 + {
  31 + var r = Ext.create('amdaModel.AmdaObject', { name: ParamName });
  32 + this.paramGrid.getStore().add(r);
  33 + this.paramGrid.getSelectionModel().select(this.paramGrid.getStore().getCount()-1);
  34 + },
  35 +
  36 + addTT : function(TTname,TTid)
  37 + {
  38 + this.timeSelector.addTT(TTname, TTid); ;
  39 +
  40 + },
  41 +
  42 + generateCatalog : function(){
  43 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.statistics.id);
  44 + if (module)
  45 + module.linkedNode.execute();
  46 + },
  47 +
  48 + /**
  49 + * update this.object from form
  50 + */
  51 +
  52 + updateObject : function(){
  53 + // get the basic form of the left
  54 + var basicForm = this.formPanel.items.items[0].getForm();
  55 + var updateStatus = true;
  56 +
  57 + var formValues = basicForm.getValues();
  58 + // this.object.set('name',formValues.name);
  59 + // this.object.set('description',formValues.description);
  60 +
  61 + var recs = this.paramGrid.getStore().getNewRecords();
  62 + var paramArr = new Array();
  63 + Ext.Array.each(recs, function(rec, index,allItems){
  64 + var obj = new Object();
  65 + obj.param = rec.get('name');
  66 + obj.function = rec.get('function');
  67 + paramArr.push(obj);
  68 + });
  69 + this.object.set('parameter', paramArr);
  70 +
  71 + var timeSource = formValues.timesrc_statisticsTimeSelector;
  72 +
  73 + if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0] // timeSource 'TimeTable'
  74 + && this.timeSelector.TTGrid.getStore().count() == 0) {
  75 + myDesktopApp.warningMsg('You\'ve chosen Time Selection `by TimeTable` but no timeTable was added!'
  76 + +'<br>You must add one or choose Time Selection `by Interval`');
  77 + return false;
  78 + }
  79 +
  80 + // basicForm.updateRecord(this.object);
  81 + this.object.set('timesrc', timeSource);
  82 + // set valid intervals into TimeTable object
  83 + if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0])
  84 + this.object.set('timeTables',this.timeSelector.TTGrid.getStore().data.items);
  85 +
  86 + return updateStatus;
  87 + },
  88 +
  89 + /**
  90 + * Check if changes were made before closing window
  91 + * @return true if changes
  92 + */
  93 + fclose : function() {
  94 + if (this.status == null)
  95 + return false;
  96 +
  97 + var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0);
  98 + return isDirty;
  99 + },
  100 +
  101 + /**
  102 + * View configuration
  103 + */
  104 + init : function (config) {
  105 +
  106 +// var functions = Ext.create('Ext.data.Store', {
  107 +// fields: ['id', 'name'],
  108 +// data : [
  109 +// {"id":"min", "name":"MIN"},
  110 +// {"id":"max", "name":"MAX"},
  111 +// {"id":"mean","name":"MEAN"}
  112 +// ]
  113 +// });
  114 +
  115 + this.fieldName = new Ext.form.field.Text({
  116 + fieldLabel: 'Catalog Name',
  117 + allowBlank : false,
  118 + stripCharsRe: /(^\s+|\s+$)/g,
  119 + emptyText: 'Please no spaces!',
  120 + name: 'name',
  121 +// anchor: '100%',
  122 + validateOnChange: false,
  123 + validateOnBlur: false,
  124 + validFlag: false,
  125 + validator : function() {
  126 + return this.validFlag;
  127 + }
  128 + });
  129 +
  130 + var ttStore = Ext.create('Ext.data.Store',
  131 + {
  132 + fields: [ 'name', 'hidden_id']
  133 + });
  134 +
  135 + this.timeSelector = new amdaUI.TimeSelectorUI({id: 'statisticsTimeSelector', height : 160});
  136 +
  137 + var store = Ext.create('Ext.data.Store',
  138 + {
  139 + fields: ['name', 'function']
  140 + });
  141 +
  142 + this.paramGrid = Ext.create('Ext.grid.Panel', {
  143 + title: 'Select Parameter & Apply Function',
  144 + selType : 'rowmodel',
  145 +// flex: 2,
  146 + height :250,
  147 + store : store,
  148 + columns: [
  149 + { xtype: 'rownumberer' },
  150 + { header: 'parameter', dataIndex: 'name', menuDisabled : true, sortable : false },
  151 + { header: 'function', dataIndex: 'function', menuDisabled : true, sortable : false,
  152 + editor: {
  153 + xtype: 'combo', queryMode : 'local',
  154 +// emptyText : 'please click to select function',
  155 + store: [ 'min', 'max', 'mean' ],
  156 + triggerAction: 'all',
  157 +// lazyInit: false,
  158 + listeners: {
  159 + focus: function(obj) {
  160 + obj.expand();
  161 + }
  162 + }
  163 + },
  164 + renderer: function(v)
  165 + {
  166 + if(v != null && v.length > 0 )
  167 + return v;
  168 + else
  169 + return 'click to select';
  170 + }
  171 + },
  172 + { menuDisabled : true, width: 30, renderer: function(){
  173 + return '<div class="icon-remover" style="width: 15px; height: 15px;"></div>';
  174 + }
  175 + }
  176 + ],
  177 + plugins: [
  178 + Ext.create('Ext.grid.plugin.CellEditing', {
  179 + clicksToEdit: 1
  180 + })
  181 + ],
  182 + listeners :
  183 + {
  184 + render : function(o,op)
  185 + {
  186 + var me = this;
  187 + var el = me.body.dom;
  188 + var dropTarget = Ext.create('Ext.dd.DropTarget', el, {
  189 + ddGroup: 'explorerTree',
  190 + notifyOver : function(ddSource, e, data)
  191 + {
  192 + if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet')) {
  193 + this.valid = false;
  194 + return this.dropNotAllowed;
  195 + }
  196 + if (((data.records[0].data.nodeType == 'localParam') ||
  197 + (data.records[0].data.nodeType == 'remoteParam') ||
  198 + (data.records[0].data.nodeType == 'remoteSimuParam') ||
  199 + (data.records[0].data.nodeType == 'derivedParam') ||
  200 + (data.records[0].data.nodeType == 'myDataParam') ||
  201 + (data.records[0].data.nodeType == 'alias'))&&
  202 + (data.records[0].isLeaf() || data.records[0].data.isParameter) &&
  203 + !data.records[0].data.disable)
  204 + {
  205 + this.valid = true;
  206 + return this.dropAllowed;
  207 + }
  208 +
  209 + this.valid = false;
  210 + return this.dropNotAllowed;
  211 + },
  212 + notifyDrop : function(ddSource, e, data)
  213 + {
  214 + if (!this.valid)
  215 + return false;
  216 + var nameToSent;
  217 + switch (data.records[0].data.nodeType)
  218 + {
  219 + case 'localParam' :
  220 + case 'remoteParam':
  221 + case 'remoteSimuParam':
  222 + nameToSent = data.records[0].get('id');
  223 + if (data.records[0].get('alias')!= "" )
  224 + var nameToSent = "#"+data.records[0].get('alias');
  225 + break;
  226 + case 'alias' :
  227 + nameToSent = "#"+data.records[0].get('text');
  228 + break;
  229 + case 'derivedParam' :
  230 + nameToSent = "ws_"+data.records[0].get('text');
  231 + break;
  232 + case 'myDataParam' :
  233 + nameToSent = "wsd_"+data.records[0].get('text');
  234 + break;
  235 + default :
  236 + return false;
  237 + }
  238 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.statistics.id);
  239 + if (module)
  240 + {
  241 + if (data.records[0].get('needsArgs') && !data.records[0].get('isSpectra')) {
  242 + module.getUiContent().fireEvent('openParamEditor',nameToSent);
  243 + }
  244 + else {
  245 + module.addParam(nameToSent,true);
  246 + }
  247 + }
  248 + return true;
  249 + }
  250 + });
  251 + },
  252 + cellclick : function(grid, cell, cellIndex, record){
  253 + if (cellIndex == 3)
  254 + grid.getStore().remove(record);
  255 + }
  256 + }
  257 + });
  258 +
  259 +
  260 + this.formPanel = Ext.create('Ext.form.Panel', {
  261 + region: 'center',
  262 + layout: 'hbox',
  263 +// bodyStyle: {background : '#dfe8f6'},
  264 + defaults: { bodyStyle: {background : '#dfe8f6'}, padding : '3'},
  265 + fieldDefaults: { labelWidth: 80, labelAlign : 'top' },
  266 + items: [
  267 + {
  268 + xtype: 'form',
  269 + flex : 1,
  270 + layout: {type: 'vbox', pack: 'start', align: 'stretch'},
  271 + items : [
  272 + this.paramGrid,
  273 + this.timeSelector
  274 + ]
  275 + },
  276 + {
  277 + xtype: 'form',
  278 + title: 'Additional Information',
  279 + flex : 1,
  280 + layout: {type: 'vbox', pack: 'start', align: 'stretch', padding : '3'},
  281 + items : [
  282 + this.fieldName,
  283 + {
  284 + xtype: 'textarea',
  285 + name: 'description',
  286 + fieldLabel: 'Description',
  287 + height: 200
  288 + }
  289 + ],
  290 + fbar:
  291 + [
  292 + {
  293 + type: 'button',
  294 + text: 'Generate Catalog',
  295 + scope : this,
  296 + handler: function(){
  297 + // update object with user's values
  298 + // if the return is true (object had been updated)
  299 + // if(this.updateObject()){
  300 + this.updateObject();
  301 + this.generateCatalog();
  302 + // }
  303 + }
  304 + },
  305 + {
  306 + type: 'button',
  307 + text: 'Reset',
  308 + scope : this,
  309 + handler: function() {
  310 + }
  311 + }
  312 + ]
  313 + }
  314 + ]
  315 + });
  316 +
  317 +
  318 +
  319 + var myConf = {
  320 + layout: 'border',
  321 + items: [
  322 + this.formPanel,
  323 + {
  324 + xtype: 'panel',
  325 + region: 'south',
  326 + title: 'Information',
  327 + collapsible: true,
  328 + height: 100,
  329 + autoHide: false,
  330 + bodyStyle: 'padding:5px',
  331 + iconCls: 'icon-information',
  332 + loader: {
  333 + autoLoad: true,
  334 + url: helpDir+'statisticsHOWTO'
  335 + }
  336 + }
  337 + ]
  338 + };
  339 +
  340 + Ext.apply (this, Ext.apply(arguments, myConf));
  341 + }
  342 +
  343 +});
... ...
js/app/views/TabResultUI.js
... ... @@ -37,6 +37,8 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, {
37 37 break;
38 38 case 'download': var title = 'Download Results';
39 39 break;
  40 + case 'statistics': var title = 'Statistics Results';
  41 + break;
40 42 default:
41 43 }
42 44 var newConfig = {
... ... @@ -54,7 +56,7 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, {
54 56 scope : this,
55 57 beforeclose : function() {
56 58 //delete linked nodes connected to ResultModule and corresponding to this Tab
57   - var module = myDesktopApp.getLoadeModule(myDesktopApp.dynamicModules.result.id);
  59 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id);
58 60 if (module.linkedNodes) {
59 61 var indices = new Array();
60 62 var i =0;
... ... @@ -105,6 +107,16 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
105 107 this);
106 108 },
107 109  
  110 + saveCatalog: function(folderId,ttName) {
  111 + this.linkedNode = Ext.create('amdaModel.CatalogNode',{leaf : true});
  112 + AmdaAction.getTmpObject(
  113 + folderId,
  114 + ttName,
  115 + this.linkedNode.get('nodeType'),
  116 + this.getResultCallback,
  117 + this);
  118 + },
  119 +
108 120 getResultCallback : function(result,remoteEvent){//result, e) {
109 121 var t = remoteEvent.getTransaction();
110 122 //AKKA - catch error
... ... @@ -120,8 +132,8 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
120 132 return;
121 133 }
122 134  
123   - var paramObj = Ext.create(this.linkedNode.get('objectDataModel'), result);
124   - paramObj.set('fromPlugin',true);
  135 + var paramObj = Ext.create(this.linkedNode.get('objectDataModel'), result);
  136 + paramObj.set('fromPlugin',true);
125 137 paramObj.set('intervals',result.intervals);
126 138 // set parameter into node
127 139 this.linkedNode.set('object',paramObj);
... ... @@ -130,7 +142,7 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
130 142 myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function (module) {
131 143 module.setLinkedNode(me.linkedNode);
132 144 // Edition of parameter into parameter Module
133   - me.linkedNode.editInModule();
  145 + me.linkedNode.editInModule();
134 146 });
135 147 },
136 148  
... ... @@ -251,6 +263,35 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
251 263 }
252 264 ]
253 265 };
  266 + var configCat = {
  267 + intId : config.title,
  268 + height : height,
  269 + title: jobtitle,
  270 + collapsible: true,
  271 + defaultType: 'button',
  272 + items :[
  273 + {
  274 + xtype: 'label',
  275 + text: 'Catalog '
  276 + },
  277 + {
  278 + text: 'Edit/Save',
  279 + scope : this,
  280 + handler: function() {
  281 + this.saveCatalog(config.folderId,config.resultId);
  282 + }
  283 + },
  284 + {
  285 + text: 'Delete',
  286 + scope : this,
  287 + handler: function() {
  288 + this.delete(config.processId);
  289 + this.ownerCt.remove(this);
  290 + }
  291 + }
  292 + ]
  293 + };
  294 +
254 295 //TODO make this properly
255 296  
256 297 var configPlot = {
... ... @@ -329,6 +370,9 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
329 370 case 'condition' :
330 371 Ext.apply(this, configTT);
331 372 break;
  373 + case 'statistics' :
  374 + Ext.apply(this, configCat);
  375 + break;
332 376 case 'request' :
333 377 Ext.apply(this, configPlot);
334 378 break;
... ...
js/app/views/TimeTableUI.js
... ... @@ -2,14 +2,10 @@
2 2 * Project  : AMDA-NG
3 3 * Name : TimeTableUI.js
4 4 * @class amdaUI.TimeTableUI
5   - * @extends Ext.container.Container
  5 + * @extends Ext.container.Container
6 6 * @brief Time Table Module UI definition (View)
7 7 * @author Myriam
8 8 * @version $Id: TimeTableUI.js 2075 2014-02-11 11:30:14Z elena $
9   - ********************************************************************************
10   - * FT Id : Date : Name - Description
11   - *******************************************************************************
12   - * 08/06/2011: Myriam - Migration extjs4
13 9 */
14 10  
15 11 Ext.define('amdaUI.TimeTableUI', {
... ... @@ -17,19 +13,19 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
17 13 alias: 'widget.panelTimeTable',
18 14  
19 15 requires: [
20   - 'Ext.ux.grid.FiltersFeature',
21   - 'Ext.ux.grid.filter.DateFilter',
22   - 'Ext.ux.grid.filter.NumericFilter',
23   - 'amdaUI.OperationsTT',
24   - 'amdaUI.StatisticalPlug',
25   - 'Ext.grid.plugin.BufferedRenderer'
  16 + 'Ext.ux.grid.FiltersFeature',
  17 + 'Ext.ux.grid.filter.DateFilter',
  18 + 'Ext.ux.grid.filter.NumericFilter',
  19 + 'amdaUI.OperationsTT',
  20 + 'amdaUI.StatisticalPlug',
  21 + 'Ext.grid.plugin.BufferedRenderer'
26 22 ],
27 23  
28 24 statics: {
29   - COL_TO_HIDE : 'colToHide'
30   - },
  25 + COL_TO_HIDE : 'colToHide'
  26 + },
31 27  
32   - status: null,
  28 + status: null,
33 29  
34 30 constructor: function(config) {
35 31 this.init(config);
... ... @@ -42,7 +38,8 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
42 38 * set the current editing object
43 39 * this method will be used on timetable edition when this win is already opened
44 40 */
45   - setObject : function (object) {
  41 + setObject : function (object)
  42 + {
46 43 // set object
47 44 this.object = object;
48 45  
... ... @@ -138,33 +135,35 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
138 135 /**
139 136 * update this.object from form
140 137 */
141   - updateObject : function(){
  138 + updateObject : function()
  139 + {
142 140 this.updateCount();
143 141  
144 142 // get the basic form
145   - var basicForm = this.formPanel.getForm();
146   - var updateStatus = true;
  143 + var basicForm = this.formPanel.getForm();
  144 + var updateStatus = true;
147 145  
148   - var fieldsWithoutName = basicForm.getFields().items;
149   - Ext.Array.each(fieldsWithoutName, function(item, index,allItems){
150   - if(item !== this.fieldName) {
151   - if (!item.isValid()) {
152   - // set update isn't allowed
153   - updateStatus = false;
154   - }
155   - }
156   - }, this);
  146 + var fieldsWithoutName = basicForm.getFields().items;
  147 + Ext.Array.each(fieldsWithoutName, function(item, index,allItems){
  148 + if(item !== this.fieldName) {
  149 + if (!item.isValid()) {
  150 + // set update isn't allowed
  151 + updateStatus = false;
  152 + }
  153 + }
  154 + }, this);
157 155 // if the update is allowed
158   - if (updateStatus) {
159   - /// real object update
160   - // update TimeTable object with the content of form
161   - basicForm.updateRecord(this.object);
162   - }
163   - // return the update status
164   - return updateStatus;
  156 + if (updateStatus) {
  157 + /// real object update
  158 + // update TimeTable object with the content of form
  159 + basicForm.updateRecord(this.object);
  160 + }
  161 + // return the update status
  162 + return updateStatus;
165 163 },
166 164  
167   - updateCount : function() {
  165 + updateCount : function()
  166 + {
168 167 this.object.set('nbIntervals',this.TTGrid.getStore().getTotalCount());
169 168 this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals'));
170 169 },
... ... @@ -172,7 +171,8 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
172 171 /*
173 172 * save method called by Save button
174 173 */
175   - saveProcess : function(toRename){
  174 + saveProcess : function(toRename)
  175 + {
176 176 var timeTableModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.tt.id);
177 177  
178 178 // if the name has been modified this is a creation
... ... @@ -181,8 +181,8 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
181 181 timeTableModule.createLinkedNode();
182 182 timeTableModule.createObject(this.object.getJsonValues());
183 183 var ttobj = timeTableModule.linkedNode.get('object');
184   - // synchronisation of objects
185   - this.object = ttobj;
  184 + // synchronisation of objects
  185 + this.object = ttobj;
186 186 timeTableModule.linkedNode.create();
187 187 }
188 188 else if (this.fclose() /*TimeTable object has been modified*/) {
... ... @@ -215,24 +215,26 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
215 215 /**
216 216 * overwrite metod called by Save button
217 217 */
218   - overwriteProcess : function(btn){
  218 + overwriteProcess : function(btn)
  219 + {
219 220 if (btn == 'cancel') return;
220 221  
221   - this.fieldName.clearInvalid();
  222 + this.fieldName.clearInvalid();
222 223 this.saveProcess(true);
223 224  
224 225 },
225 226  
226   - addInterval : function(start, stop) {
  227 + addInterval : function(start, stop)
  228 + {
227 229 this.TTGrid.getSelectionModel().deselectAll();
228   - AmdaAction.addTTCacheInterval({'start' : start, 'stop' : stop},function (result, e) {
  230 + AmdaAction.addTTCacheInterval({'start' : start, 'stop' : stop},function (result, e) {
229 231 this.TTGrid.getStore().reload();
230 232 this.status = result.status;
231   - }, this);
  233 + }, this);
232 234 },
233 235  
234   - init : function(config) {
235   -
  236 + init : function(config)
  237 + {
236 238 this.object = config.object;
237 239  
238 240 this.fieldName = new Ext.form.field.Text({
... ...
js/resources/css/amda.css
... ... @@ -79,6 +79,10 @@
79 79 background-image:url( ../images/16x16/search.png ) !important;
80 80 }
81 81  
  82 +.icon-statistics {
  83 + background-image:url( ../images/16x16/statistics.png ) !important;
  84 +}
  85 +
82 86 .icon-manage-ws {
83 87 background-image:url( ../images/16x16/wsManager.png ) !important;
84 88 }
... ... @@ -386,7 +390,6 @@ p + p {
386 390 font-weight: bold !important;
387 391 }
388 392  
389   -
390 393 .icon-plot-page {
391 394 background-image:url( ../images/16x16/plot_page.png ) !important;
392 395 }
... ... @@ -413,4 +416,9 @@ p + p {
413 416  
414 417 .icon-plot-axis-t {
415 418 background-image:url( ../images/16x16/plot_axis_t.png ) !important;
416   -}
417 419 \ No newline at end of file
  420 +}
  421 +
  422 +.x-item-disabled .x-form-item-label {
  423 + filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100) !important;
  424 + opacity: 1.0 !important;
  425 +}
... ...
js/resources/images/16x16/statistics.png 0 โ†’ 100644

738 Bytes

js/resources/images/16x16/visu_catalog.png 0 โ†’ 100644

838 Bytes

js/resources/images/64x64/statistics.png 0 โ†’ 100644

1.49 KB

js/resources/images/64x64/visu_catalog.png 0 โ†’ 100644

3.68 KB

php/classes/AmdaAction.php
... ... @@ -581,7 +581,10 @@ class AmdaAction {
581 581 switch ($nodeType) {
582 582 case 'timeTable' :
583 583 $objectMgr = new TimeTableMgr();
584   - break;
  584 + break;
  585 + case 'catalog' :
  586 + $objectMgr = new CatalogMgr();
  587 + break;
585 588 default:
586 589 return array("error" => $nodeType." NOT_IMPLEMENTED_YET");
587 590 }
... ... @@ -600,6 +603,9 @@ class AmdaAction {
600 603 case 'timeTable' :
601 604 case 'sharedtimeTable' :
602 605 $objectMgr = new TimeTableMgr();
  606 + break;
  607 + case 'catalog' :
  608 + $objectMgr = new CatalogMgr();
603 609 break;
604 610 case 'condition' :
605 611 case 'request' :
... ... @@ -631,6 +637,9 @@ class AmdaAction {
631 637 break;
632 638 case 'timeTable' :
633 639 $objectMgr = new TimeTableMgr();
  640 + break;
  641 + case 'catalog' :
  642 + $objectMgr = new CatalogMgr();
634 643 break;
635 644 case 'condition' :
636 645 case 'request' :
... ... @@ -667,6 +676,9 @@ class AmdaAction {
667 676 break;
668 677 case 'timeTable' :
669 678 $objectMgr = new TimeTableMgr();
  679 + break;
  680 + case 'catalog' :
  681 + $objectMgr = new Catalog();
670 682 break;
671 683 case 'condition' :
672 684 case 'request' :
... ... @@ -698,6 +710,9 @@ class AmdaAction {
698 710 break;
699 711 case 'timeTable' :
700 712 $objectMgr = new TimeTableMgr();
  713 + break;
  714 + case 'catalog' :
  715 + $objectMgr = new CatalogMgr();
701 716 break;
702 717 case 'condition' :
703 718 case 'request' :
... ... @@ -726,7 +741,10 @@ class AmdaAction {
726 741 break;
727 742 case 'timeTable' :
728 743 $objectMgr = new TimeTableMgr();
729   - break;
  744 + break;
  745 + case 'catalog' :
  746 + $objectMgr = new CatalogMgr();
  747 + break;
730 748 case 'condition' :
731 749 case 'request' :
732 750 $objectMgr = new RequestMgr($obj->nodeType);
... ... @@ -747,8 +765,12 @@ class AmdaAction {
747 765 $objectMgr = new DerivedParamMgr($obj->nodeType);
748 766 break;
749 767 case 'timeTable' :
  768 + case 'sharedtimeTable' :
750 769 $objectMgr = new TimeTableMgr();
751 770 break;
  771 + case 'catalog' :
  772 + $objectMgr = new CatalogMgr();
  773 + break;
752 774 case 'condition' :
753 775 case 'request' :
754 776 $objectMgr = new RequestMgr($obj->nodeType);
... ... @@ -921,21 +943,32 @@ class AmdaAction {
921 943  
922 944 return $result;
923 945 }
924   - public function initTTCache()
  946 +
  947 + public function initTTCache($isCatalog = false)
925 948 {
926   - $cacheMgr = new TimeTableCacheMgr();
  949 + if (!$isCatalog) $cacheMgr = new TimeTableCacheMgr();
  950 + else $cacheMgr = new CatalogCacheMgr();
  951 +
927 952 return $cacheMgr->initTTCache();
928 953 }
929 954  
  955 +
930 956 public function initTTCacheFromTT($id, $type)
931 957 {
932   - $cacheMgr = new TimeTableCacheMgr();
  958 + if ($type == 'catalog') $cacheMgr = new CatalogCacheMgr();
  959 + else $cacheMgr = new TimeTableCacheMgr();
  960 +
933 961 return $cacheMgr->initFromTT($id, $type);
934 962 }
935 963  
936   - public function initTTCacheFromTmpObject($folderId, $name)
  964 + public function initTTCacheFromTmpObject($folderId, $name, $isCatalog = false)
937 965 {
938   - $cacheMgr = new TimeTableCacheMgr();
  966 + if (!$isCatalog) $cacheMgr = new TimeTableCacheMgr();
  967 +
  968 + else $cacheMgr = new CatalogCacheMgr();
  969 +
  970 +
  971 +
939 972 return $cacheMgr->initFromTmpObject($folderId, $name);
940 973 }
941 974  
... ... @@ -947,7 +980,9 @@ class AmdaAction {
947 980  
948 981 public function readTTCacheIntervals($o)
949 982 {
950   - $cacheMgr = new TimeTableCacheMgr();
  983 + if ($o->typeTT == 'catalog') $cacheMgr = new CatalogCacheMgr();
  984 + else $cacheMgr = new TimeTableCacheMgr();
  985 +
951 986 return $cacheMgr->getIntervals($o->start,$o->limit,$o->sort,$o->filter);
952 987 }
953 988  
... ... @@ -963,9 +998,11 @@ class AmdaAction {
963 998 return $cacheMgr->addInterval($o->index, $o->start, $o->stop);
964 999 }
965 1000  
966   - public function removeTTCacheIntervalFromId($id)
  1001 + public function removeTTCacheIntervalFromId($id, $isCatalog = false)
967 1002 {
968   - $cacheMgr = new TimeTableCacheMgr();
  1003 + if ($isCatalog) $cacheMgr = new CatalogCacheMgr();
  1004 + else $cacheMgr = new TimeTableCacheMgr();
  1005 +
969 1006 return $cacheMgr->removeIntervalFromId($id);
970 1007 }
971 1008  
... ... @@ -1201,8 +1238,8 @@ class AmdaAction {
1201 1238 //AKKA - New action to clean user WS
1202 1239 public function cleanUserWS()
1203 1240 {
1204   - require_once(INTEGRATION_SRC_DIR."RequestManager.php");
1205   - return $this->executeRequest($obj, FunctionTypeEnumClass::PROCESSCLEAN);
  1241 + require_once(INTEGRATION_SRC_DIR."RequestManager.php");
  1242 + return $this->executeRequest($obj, FunctionTypeEnumClass::PROCESSCLEAN);
1206 1243 }
1207 1244  
1208 1245 public function deleteSpecialInfo($name)
... ...
php/classes/CatalogCacheMgr.php 0 โ†’ 100644
... ... @@ -0,0 +1,355 @@
  1 +<?php
  2 +
  3 +/**
  4 + * @class CatalogCacheMgr
  5 + */
  6 +
  7 +
  8 +class CatIntervalCacheObject extends IntervalCacheObject
  9 +{
  10 + // for catalog
  11 + private $params = array();
  12 +
  13 + public function toArray()
  14 + {
  15 + $result = array(
  16 + "cacheId" => $this->id,
  17 + "start" => $this->getStartToISO(),
  18 + "stop" => $this->getStopToISO()
  19 + );
  20 + if ($this->isNew)
  21 + $result["isNew"] = true;
  22 + if ($this->isModified)
  23 + $result["isModified"] = true;
  24 +
  25 + for ($i = 0; $i < count($this->params); $i++) {
  26 + $paramObject = array();
  27 + $index = 'param'.sprintf("%d",$i+2);
  28 + $result[$index] = $this->params[$i];
  29 + }
  30 + return $result;
  31 + }
  32 +
  33 + // for catalog
  34 + public function setParams($params)
  35 + {
  36 + $this->params = $params;
  37 + }
  38 +
  39 + public function getParams()
  40 + {
  41 + return $this->params;
  42 + }
  43 +
  44 + public function writeBin($handle, $paramsNumber, $paramsSizes)
  45 + {
  46 + fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified));
  47 + for ($i = 0; $i < $paramsNumber; $i++) {
  48 + $paramString = $this->params[$i];
  49 + $paramArray = explode(',',$this->params[$i]);
  50 + for ($j = 0; $j < $paramsSizes[$i]; $j++) fwrite($handle,pack('d', $paramArray[$j]));
  51 + }
  52 + }
  53 +
  54 + public function loadBin($handle, $paramsNumber, $paramsSizes)
  55 + {
  56 + $array = unpack('L6int',fread($handle,6*4));
  57 + $this->id = $array['int1'];
  58 + $this->index = $array['int2'];
  59 + $this->start = $array['int3'];
  60 + $this->stop = $array['int4'];
  61 + $this->isNew = $array['int5'];
  62 + $this->isModified = $array['int6'];
  63 +
  64 + for ($i = 0; $i < $paramsNumber; $i++) {
  65 + $this->params[$i] = null;
  66 + for ($j = 0; $j < $paramsSizes[$i]; $j++) {
  67 + $val = unpack('dval',fread($handle,8));
  68 + $this->params[$i] .= $val['val'];
  69 + if ($j != $paramsSizes[$i] - 1) $this->params[$i] .= ',';
  70 + }
  71 + }
  72 +
  73 + }
  74 +
  75 + public function dump()
  76 + {
  77 + echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL;
  78 + }
  79 +}
  80 +
  81 +class CatalogCacheObject extends TimeTableCacheObject
  82 +{
  83 + private $paramsNumber;
  84 + private $paramsSizes = array();
  85 +
  86 + public function addInterval($startIso, $stopIso, $params, $isNew = false, $index = -1)
  87 + {
  88 + $interval = new CatIntervalCacheObject($this->lastId, count($this->intervals));
  89 + ++$this->lastId;
  90 + $interval->setStartFromISO($startIso);
  91 + $interval->setStopFromISO($stopIso);
  92 + // for catalog
  93 + $interval->setParams($params);
  94 +
  95 + $interval->setIsNew($isNew);
  96 + array_push($this->intervals, $interval);
  97 + if ($index < 0)
  98 + array_push($this->indexes, count($this->intervals) - 1);
  99 + else
  100 + array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1));
  101 + if ($isNew)
  102 + $this->isModified = true;
  103 +
  104 + return $interval;
  105 + }
  106 +
  107 + public function setParamsNumber($number)
  108 + {
  109 + $this->paramsNumber = $number;
  110 + }
  111 +
  112 + public function setParamsSizes($params)
  113 + {
  114 + for ($i = 0; $i < $this->paramsNumber; $i++)
  115 + $this->paramsSizes[$i] = $params[$i]['size'];
  116 + }
  117 +
  118 + public function writeBin($handle)
  119 + {
  120 + //Magic key ("TTC")
  121 + fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C')));
  122 +
  123 + //Version
  124 + fwrite($handle,pack('L',TimeTableCacheObject::$format_version));
  125 +
  126 + //Token
  127 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  128 + fwrite($handle,pack('C',ord($this->token[$i])));
  129 +
  130 + //Modified
  131 + fwrite($handle,pack('L',$this->isModified));
  132 +
  133 + //Filter
  134 + $this->filter->writeBin($handle);
  135 +
  136 + //Sort
  137 + $this->sort->writeBin($handle);
  138 +
  139 + //Params Number
  140 + fwrite($handle,pack('L',$this->paramsNumber));
  141 +
  142 + //Params Sizes
  143 + for ($i = 0; $i < $this->paramsNumber; $i++)
  144 + fwrite($handle,pack('L',$this->paramsSizes[$i]));
  145 +
  146 + //Intervals
  147 + fwrite($handle,pack('L2',count($this->intervals), $this->lastId));
  148 +
  149 +
  150 + foreach($this->intervals as $interval)
  151 + $interval->writeBin($handle,$this->paramsNumber,$this->paramsSizes);
  152 +
  153 + //Indexes
  154 + fwrite($handle,pack('L',count($this->indexes)));
  155 + foreach($this->indexes as $index)
  156 + fwrite($handle,pack('L',$index));
  157 + }
  158 +
  159 + public function loadBin($handle) {
  160 + //Magic key ("TTC")
  161 + if (!$res = unpack('C3key',fread($handle,3)))
  162 + return false;
  163 +
  164 + if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C')))
  165 + return false;
  166 +
  167 + //Version
  168 + if (!$res = unpack('Lversion',fread($handle,4)))
  169 + return false;
  170 + if (($res['version'] != TimeTableCacheObject::$format_version))
  171 + return false;
  172 +
  173 + //Token
  174 + $token = "";
  175 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  176 + {
  177 + if (!$res = unpack('Ctoken',fread($handle,1)))
  178 + return false;
  179 + $token .= chr($res['token']);
  180 + }
  181 + $this->token = $token;
  182 +
  183 + //Modified
  184 + if (!$res = unpack('Lmodified',fread($handle,4)))
  185 + return false;
  186 + $this->isModified = $res['modified'];
  187 +
  188 + //Filter
  189 + $this->filter->loadBin($handle);
  190 +
  191 + //Sort
  192 + $this->sort->loadBin($handle);
  193 +
  194 + //ParamsNumber
  195 + if (!$res = unpack('Lnumber',fread($handle,4)))
  196 + return false;
  197 + $this->paramsNumber = $res['number'];
  198 +
  199 + //ParamsSizes
  200 + for ($i = 0; $i < $this->paramsNumber; $i++) {
  201 + if (!$res = unpack('Lsize',fread($handle,4)))
  202 + return false;
  203 + $this->paramsSizes[$i] = $res['size'];
  204 + }
  205 +
  206 + //Intervals
  207 + $res = unpack('L2data',fread($handle,2*4));
  208 + $nbIntervals = $res['data1'];
  209 + $this->lastId = $res['data2'];
  210 +
  211 + for ($i = 0; $i < $nbIntervals; ++$i)
  212 + {
  213 + $interval = new CatIntervalCacheObject(-1);
  214 + $interval->loadBin($handle, $this->paramsNumber, $this->paramsSizes);
  215 + array_push($this->intervals, $interval);
  216 + }
  217 +
  218 + //Indexes
  219 + $res = unpack('Ldata',fread($handle,4));
  220 + $nbIndexes = $res['data'];
  221 + for ($i = 0; $i < $nbIndexes; ++$i)
  222 + {
  223 + $res = unpack('Lindex',fread($handle,4));
  224 + array_push($this->indexes, $res['index']);
  225 + }
  226 +
  227 + return true;
  228 + }
  229 +}
  230 +
  231 +class CatalogCacheMgr extends TimeTableCacheMgr
  232 +{
  233 +
  234 + protected static $cache_file = "cacheCat";
  235 +
  236 + protected $ttMgr = null;
  237 + protected $cache = null;
  238 +
  239 + function __construct() {
  240 +
  241 + $this->ttMgr = new CatalogMgr();
  242 + }
  243 +
  244 +
  245 + public function initFromTmpObject($folderId, $name) {
  246 +
  247 + //Create new cache
  248 + $this->cache = new CatalogCacheObject();
  249 +
  250 + //Load intervals from TmpObject file (Statistics Module)
  251 + $intervals_res = $this->ttMgr->getTmpObject($folderId, $name);
  252 +
  253 + if (!isset($intervals_res))
  254 + return array('success' => false, 'message' => 'Cannot get Tmp Object');
  255 +
  256 + if (array_key_exists('intervals', $intervals_res))
  257 + {
  258 + foreach ($intervals_res['intervals'] as $interval)
  259 + {
  260 + //Add interval
  261 + $this->cache->addInterval($interval['start'], $interval['stop'], $interval['paramTable']);
  262 +
  263 + }
  264 + }
  265 +
  266 + $this->cache->setIsModified(true);
  267 +
  268 + $paramHeaders = $intervals_res['parameters'];
  269 +
  270 + $this->cache->setParamsNumber(count($paramHeaders));
  271 + $this->cache->setParamsSizes($paramHeaders);
  272 +
  273 + unset($intervals_res);
  274 +
  275 + //Update cache
  276 + $this->cache->updateIndexes();
  277 +
  278 + //Save cache file
  279 + return array('success' => $this->saveToFile(), 'token' => $this->cache->getToken(),
  280 + 'status' => $this->cache->getStatus(), 'parameters' => $paramHeaders);
  281 + }
  282 +
  283 + public function initFromTT($id, $typeTT)
  284 + {
  285 + //Create new cache
  286 + $this->cache = new CatalogCacheObject();
  287 +
  288 + //Load intervals from catalog file and add to cache
  289 + $intervals_res = $this->ttMgr->loadIntervalsFromTT($id,$typeTT);
  290 +
  291 + if (!$intervals_res['success'])
  292 + return $intervals_res;
  293 +
  294 + foreach ($intervals_res['intervals'] as $interval)
  295 + {
  296 + //Add interval
  297 + $this->cache->addInterval($interval['start'], $interval['stop'], $interval['paramTable']);
  298 + }
  299 +
  300 + $paramHeaders = $intervals_res['parameters'];
  301 +
  302 + $this->cache->setParamsNumber(count($paramHeaders));
  303 + $this->cache->setParamsSizes($paramHeaders);
  304 + unset($intervals_res);
  305 +
  306 + //Update cache
  307 + $this->cache->updateIndexes();
  308 +
  309 + //Save cache file
  310 + return array('success' => $this->saveToFile(), 'token' => $this->cache->getToken(),
  311 + 'status' => $this->cache->getStatus(),'parameters' => $paramHeaders);
  312 + }
  313 +
  314 +
  315 + protected function loadFromFile()
  316 + {
  317 + if (!file_exists($this->getCacheFilePath()))
  318 + return false;
  319 + $this->cache = new CatalogCacheObject();
  320 + $handle = fopen($this->getCacheFilePath(), 'rb');
  321 + $result = false;
  322 + if (flock($handle, LOCK_SH))
  323 + {
  324 + $this->cache->loadBin($handle);
  325 + flock( $handle, LOCK_UN );
  326 + $result = true;
  327 + }
  328 + fclose($handle);
  329 + return $result;
  330 + }
  331 +
  332 + protected function getCacheFilePath()
  333 + {
  334 + return USERTTDIR.(self::$cache_file);
  335 + }
  336 +
  337 + public function saveInTT($id, $action, $token)
  338 + {
  339 + if (!$this->loadFromFile())
  340 + return array('success' => false, 'message' => 'Cannot load cache file');
  341 +
  342 + if ($token != $this->cache->getToken())
  343 + return array('success' => false, 'message' => 'Cache token check error');
  344 +
  345 + $this->cache->updateIndexes();
  346 + $this->saveToFile();
  347 +
  348 + $intervals = $this->cache->getIntervalsArray(NULL,NULL,true);
  349 +
  350 + $this->cache->reset();
  351 +
  352 + return $this->ttMgr->saveIntervals($id, $intervals, $action);
  353 + }
  354 + }
  355 +?>
0 356 \ No newline at end of file
... ...
php/classes/CatalogMgr.php 0 โ†’ 100644
... ... @@ -0,0 +1,254 @@
  1 +<?php
  2 +
  3 +/**
  4 + * @class CatalogMgr
  5 + */
  6 +
  7 +class CatalogMgr extends TimeTableMgr {
  8 +
  9 + function __construct() {
  10 + parent::__construct('Tt.xml');
  11 + $this->contentRootId = 'catalog-treeRootNode';
  12 + $this->contentRootTag = 'catalogList';
  13 + $this->attributes = array('name' => '', 'intervals' => ''); // + 'parameters'
  14 + $this->optionalAttributes = array();
  15 + $this->objTagName = 'catalog';
  16 + $this->id_prefix = 'cat_'; // 'tt_' ?
  17 +
  18 + if (!file_exists($this->xmlName)) {
  19 + $this->createDom();
  20 + $this->xp = new domxpath($this->contentDom);
  21 + }
  22 + }
  23 +
  24 + public function getTmpObject($folderId, $name, $onlyDescription = false) {
  25 +
  26 + $filePath = USERWORKINGDIR.$folderId.'/'.$name.'.xml';
  27 +
  28 + if (!file_exists($filePath))
  29 + return array('error' => 'Cannot find result file');
  30 +
  31 + $dom = new DomDocument('1.0');
  32 + $dom->formatOutput = true;
  33 +
  34 + if (!$dom -> load($filePath))
  35 + return array('error' => 'Cannot load result file');
  36 + $nameNodes = $dom->getElementsByTagName('name');
  37 + if ($nameNodes->length > 0)
  38 + $attributesToReturn['name'] = $nameNodes->item(0)->nodeValue;
  39 +
  40 + $descNodes = $dom->getElementsByTagName('description');
  41 + if ($descNodes->length > 0)
  42 + $attributesToReturn['description'] = $descNodes->item(0)->nodeValue;
  43 +
  44 + $creatNodes = $dom->getElementsByTagName('created');
  45 + if ($creatNodes->length > 0)
  46 + $attributesToReturn['created'] = $creatNodes->item(0)->nodeValue;
  47 +
  48 + $histNodes = $dom->getElementsByTagName('history');
  49 + if ($histNodes->length > 0)
  50 + $attributesToReturn['history'] = $histNodes->item(0)->nodeValue;
  51 +
  52 + $attributesToReturn['objName'] = $name;
  53 + $attributesToReturn['folderId'] = $folderId;
  54 + $attributesToReturn['success'] = true;
  55 +
  56 + if (!$onlyDescription)
  57 + {
  58 + $intNodes = $dom->getElementsByTagName('intervals');
  59 + foreach ($intNodes as $intNode)
  60 + {
  61 + $startNodes = $intNode->getElementsByTagName('start');
  62 + if ($startNodes->length <= 0)
  63 + return array('error' => 'Error detected in result file');
  64 +
  65 + $stopNodes = $intNode->getElementsByTagName('stop');
  66 + if ($stopNodes->length <= 0)
  67 + return array('error' => 'Error detected in result file');
  68 +
  69 + // for catalog
  70 + $paramNodes = $intNode->getElementsByTagName('param');
  71 + $params = array();
  72 + if ($paramNodes->length > 0)
  73 + foreach ( $paramNodes as $paramNode ) $params[] = $paramNode->nodeValue;
  74 +
  75 +
  76 + $attributesToReturn['intervals'][] = array('start' => $startNodes->item(0)->nodeValue,
  77 + 'stop' => $stopNodes->item(0)->nodeValue,
  78 + 'paramTable' => $params);
  79 + }
  80 + // for catalog
  81 + $paramsNodes = $dom->getElementsByTagName('parameter');
  82 +
  83 + if ($paramsNodes->length > 0){
  84 +
  85 + $paramsArray = array();
  86 + foreach ($paramsNodes as $paramNode) {
  87 +
  88 + $oneParam = array();
  89 + foreach ($paramNode->attributes as $attr)
  90 + $oneParam[$attr->nodeName] = $attr->nodeValue;
  91 +
  92 + if (substr($paramNode->getAttribute('id'),0,8) == 'stat_cov') {
  93 + $oneParam['size'] = '1';
  94 + $oneParam['name'] = 'Flag';
  95 + }
  96 +
  97 + $paramsArray[] = $oneParam;
  98 + }
  99 + $attributesToReturn['success'] = true;
  100 + $attributesToReturn['parameters'] = $paramsArray;
  101 + }
  102 + else
  103 + return array('error' => 'No information on parameters in result file');
  104 + }
  105 +
  106 + return $attributesToReturn;
  107 + }
  108 +
  109 +
  110 + public function loadIntervalsFromTT($id, $typeTT, $start = NULL, $limit = NULL)
  111 + {
  112 + if ($typeTT == 'sharedcatalog') {
  113 + $pathid = SHAREDPATH.'TT/'.$id;
  114 + }
  115 + else {
  116 + $pathid = USERTTDIR.$id;
  117 + }
  118 +
  119 + //load intervals from TT id
  120 + if (!file_exists($pathid.'.xml'))
  121 + return array('success' => false, 'message' => "Cannot find Catalog file ".$id);
  122 +
  123 + $this->objectDom->load($pathid.'.xml');
  124 +
  125 + if (!($objToGet = $this->objectDom->getElementById($id)))
  126 + return array('success' => false, 'message' => NO_SUCH_ID." ".$id);
  127 +
  128 + $xpath = new DOMXPath($this->objectDom);
  129 + $intervals = $xpath->query('//intervals');
  130 +
  131 + $result = array();
  132 +
  133 + if (!isset($start) || !isset($limit))
  134 + {
  135 + foreach ($intervals as $interval)
  136 + {
  137 + $startTime = $interval->getElementsByTagName('start')->item(0)->nodeValue;
  138 + $stopTime = $interval->getElementsByTagName('stop')->item(0)->nodeValue;
  139 + // for catalog
  140 + $paramNodes = $interval->getElementsByTagName('param');
  141 + $params = array();
  142 + if ($paramNodes->length > 0)
  143 + foreach ( $paramNodes as $paramNode ) $params[] = $paramNode->nodeValue;
  144 +
  145 + array_push($result, array('start' => $startTime, 'stop' => $stopTime,'paramTable' => $params));
  146 +
  147 + }
  148 + }
  149 + else
  150 + {
  151 + for ($i = 0; $i < $limit; ++$i)
  152 + {
  153 + if ($start+$i >= $intervals->length)
  154 + break;
  155 + $startTime = $intervals->item($start+$i)->getElementsByTagName('start')->item(0)->nodeValue;
  156 + $stopTime = $intervals->item($start+$i)->getElementsByTagName('stop')->item(0)->nodeValue;
  157 + // for catalog
  158 + $paramNodes = $intervals->item($start+$i)->getElementsByTagName('param');
  159 + $params = array();
  160 + if ($paramNodes->length > 0)
  161 + foreach ( $paramNodes as $paramNode ) $params[] = $paramNode->nodeValue;
  162 +
  163 + array_push($result, array('start' => $startTime, 'stop' => $stopTime,'paramTable' => $params));
  164 + }
  165 + }
  166 + // for catalog : params header
  167 + $paramsNodes = $xpath->query('//parametres/param');
  168 + $paramsArray = array();
  169 +
  170 + if ($paramsNodes->length > 0)
  171 + {
  172 + foreach ($paramsNodes as $paramNode)
  173 + {
  174 + $oneParam = array();
  175 + foreach ($paramNode->attributes as $attr)
  176 + $oneParam[$attr->nodeName] = $attr->nodeValue;
  177 + $paramsArray[] = $oneParam;
  178 + }
  179 + }
  180 +
  181 + return array(
  182 + 'totalCount' => $intervals->length,
  183 + 'intervals' => $result,
  184 + 'parameters' => $paramsArray,
  185 + 'start' => isset($start) ? $start : 0,
  186 + 'limit' => isset($limit) ? $limit : 0,
  187 + 'success' => true
  188 + );
  189 +
  190 + }
  191 +
  192 + /*
  193 + * catalog header
  194 + */
  195 + protected function setParamDescription($params)
  196 + {
  197 + $paramsElement = $this->objectDom->createElement('parametres');
  198 + foreach ($params as $param)
  199 + {
  200 + $paramElement = $this->objectDom->createElement('param');
  201 + $attrArray = (array)$param;
  202 + foreach ($attrArray as $key => $value)
  203 + $paramElement->setAttribute($key, $value);
  204 + $paramsElement->appendChild($paramElement);
  205 + }
  206 +
  207 + return $paramsElement;
  208 + }
  209 +
  210 + protected function createIntervalElement($interval)
  211 + {
  212 + $newInterval = $this->objectDom->createElement('intervals');
  213 + $newInterval->appendChild($this->objectDom->createElement('start',$interval['start']));
  214 + $newInterval->appendChild($this->objectDom->createElement('stop',$interval['stop']));
  215 + foreach ($interval as $key =>$value) {
  216 + if (substr($key,0,5) == 'param')
  217 + $newInterval->appendChild($this->objectDom->createElement('param', $value));
  218 +
  219 + }
  220 + return $newInterval;
  221 + }
  222 +
  223 + public function createObject($p, $folder)
  224 + {
  225 + if ($p -> leaf)
  226 + {
  227 + $result = $this->createParameter($p, $folder);
  228 + if ($result['error'])
  229 + return $result;
  230 +
  231 + $cacheMgr = new CatalogCacheMgr();
  232 +
  233 + if (isset($p->cacheToken) && ($p->cacheToken != ''))
  234 + {
  235 + $resultSaveInt = $cacheMgr->saveInTT($result['id'], "update", $p->cacheToken);
  236 + if (!$resultSaveInt['success'])
  237 + {
  238 + if ($resultSaveInt['message'])
  239 + return array('error' => $resultSaveInt['message']);
  240 + else
  241 + return array('error' => 'Unknown error during intervals save');
  242 + }
  243 + }
  244 + return $result;
  245 + }
  246 + // else return $this->createFolder($p);
  247 + //TODO check if this is possible?
  248 + else return array('error' => 'createFolder should be called from RENAME');
  249 +
  250 + }
  251 +
  252 +
  253 +}
  254 +?>
0 255 \ No newline at end of file
... ...
php/classes/IntervalCacheObject.php 0 โ†’ 100644
... ... @@ -0,0 +1,114 @@
  1 +<?php
  2 +class IntervalCacheObject
  3 +{
  4 + protected $id = -1;
  5 + protected $index = -1;
  6 + protected $start = 0;
  7 + protected $stop = 0;
  8 + protected $isNew = false;
  9 + protected $isModified = false;
  10 +
  11 + function __construct($id, $index) {
  12 + $this->id = $id;
  13 + $this->index = $index;
  14 + }
  15 +
  16 + public function getId() {
  17 + return $this->id;
  18 + }
  19 +
  20 + public function getIndex() {
  21 + return $this->index;
  22 + }
  23 +
  24 + public function setIndex($index) {
  25 + $this->index = $index;
  26 + }
  27 +
  28 + public function getStartToStamp() {
  29 + return $this->start;
  30 + }
  31 +
  32 + public function getStartToISO() {
  33 + return CacheTools::stamp2iso($this->start);
  34 + }
  35 +
  36 + public function setStartFromStamp($stamp) {
  37 + $this->start = $stamp;
  38 + }
  39 +
  40 + public function setStartFromISO($iso) {
  41 + $this->start = CacheTools::iso2stamp($iso);
  42 + }
  43 +
  44 + public function getStopToStamp() {
  45 + return $this->stop;
  46 + }
  47 +
  48 + public function getStopToISO() {
  49 + return CacheTools::stamp2iso($this->stop);
  50 + }
  51 +
  52 + public function setStopFromStamp($stamp) {
  53 + $this->stop = $stamp;
  54 + }
  55 +
  56 + public function setStopFromISO($iso) {
  57 + $this->stop = CacheTools::iso2stamp($iso);
  58 + }
  59 +
  60 + public function getDuration() {
  61 + return ($this->stop-$this->start);
  62 + }
  63 +
  64 + public function isModified() {
  65 + return $this->isModified;
  66 + }
  67 +
  68 + public function setIsModified($isModified) {
  69 + $this->isModified = $isModified;
  70 + }
  71 +
  72 + public function isNew() {
  73 + return $this->isNew;
  74 + }
  75 +
  76 + public function setIsNew($isNew) {
  77 + $this->isNew = $isNew;
  78 + }
  79 +
  80 + public function toArray() {
  81 + $result = array(
  82 + "cacheId" => $this->id,
  83 + "start" => $this->getStartToISO(),
  84 + "stop" => $this->getStopToISO()
  85 + );
  86 + if ($this->isNew)
  87 + $result["isNew"] = true;
  88 + if ($this->isModified)
  89 + $result["isModified"] = true;
  90 +
  91 + return $result;
  92 + }
  93 +
  94 +
  95 +
  96 + public function writeBin($handle) {
  97 + fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified));
  98 + }
  99 +
  100 + public function loadBin($handle) {
  101 + $array = unpack('L6int',fread($handle,6*4));
  102 + $this->id = $array['int1'];
  103 + $this->index = $array['int2'];
  104 + $this->start = $array['int3'];
  105 + $this->stop = $array['int4'];
  106 + $this->isNew = $array['int5'];
  107 + $this->isModified = $array['int6'];
  108 + }
  109 +
  110 + public function dump() {
  111 + echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL;
  112 + }
  113 +}
  114 +?>
0 115 \ No newline at end of file
... ...
php/classes/TimeTableCacheMgr.php
... ... @@ -27,8 +27,8 @@ class SortPartCacheObject
27 27 public static $DIRECTION_ASC = 1;
28 28 public static $DIRECTION_DES = 2;
29 29  
30   - private $type;
31   - private $dir;
  30 + protected $type;
  31 + protected $dir;
32 32  
33 33 function __construct() {
34 34 $this->type = self::$TYPE_UNKNOWN;
... ... @@ -172,7 +172,7 @@ class SortPartCacheObject
172 172  
173 173 class SortCacheObject
174 174 {
175   - private $parts = array();
  175 + protected $parts = array();
176 176  
177 177 function __construct() {
178 178 }
... ... @@ -286,9 +286,9 @@ class FilterPartCacheObject
286 286 public static $OPERATION_GT = 2;
287 287 public static $OPERATION_EQ = 3;
288 288  
289   - private $type;
290   - private $op;
291   - private $value;
  289 + protected $type;
  290 + protected $op;
  291 + protected $value;
292 292  
293 293 function __construct() {
294 294 $this->type = self::$TYPE_UNKNOWN;
... ... @@ -470,7 +470,7 @@ class FilterPartCacheObject
470 470  
471 471 class FilterCacheObject
472 472 {
473   - private $parts = array();
  473 + protected $parts = array();
474 474  
475 475 function __construct() {
476 476  
... ... @@ -555,631 +555,12 @@ class FilterCacheObject
555 555 }
556 556 }
557 557  
558   -class IntervalCacheObject
  558 + class TimeTableCacheMgr
559 559 {
560   - private $id = -1;
561   - private $index = -1;
562   - private $start = 0;
563   - private $stop = 0;
564   - private $isNew = false;
565   - private $isModified = false;
566   -
567   - function __construct($id, $index) {
568   - $this->id = $id;
569   - $this->index = $index;
570   - }
571   -
572   - public function getId() {
573   - return $this->id;
574   - }
575   -
576   - public function getIndex() {
577   - return $this->index;
578   - }
579   -
580   - public function setIndex($index) {
581   - $this->index = $index;
582   - }
583   -
584   - public function getStartToStamp() {
585   - return $this->start;
586   - }
587   -
588   - public function getStartToISO() {
589   - return CacheTools::stamp2iso($this->start);
590   - }
591   -
592   - public function setStartFromStamp($stamp) {
593   - $this->start = $stamp;
594   - }
595   -
596   - public function setStartFromISO($iso) {
597   - $this->start = CacheTools::iso2stamp($iso);
598   - }
599   -
600   - public function getStopToStamp() {
601   - return $this->stop;
602   - }
603   -
604   - public function getStopToISO() {
605   - return CacheTools::stamp2iso($this->stop);
606   - }
607   -
608   - public function setStopFromStamp($stamp) {
609   - $this->stop = $stamp;
610   - }
611   -
612   - public function setStopFromISO($iso) {
613   - $this->stop = CacheTools::iso2stamp($iso);
614   - }
615   -
616   - public function getDuration() {
617   - return ($this->stop-$this->start);
618   - }
619   -
620   - public function isModified() {
621   - return $this->isModified;
622   - }
623   -
624   - public function setIsModified($isModified) {
625   - $this->isModified = $isModified;
626   - }
627   -
628   - public function isNew() {
629   - return $this->isNew;
630   - }
631   -
632   - public function setIsNew($isNew) {
633   - $this->isNew = $isNew;
634   - }
635   -
636   - public function toArray() {
637   - $result = array(
638   - "cacheId" => $this->id,
639   - "start" => $this->getStartToISO(),
640   - "stop" => $this->getStopToISO()
641   - );
642   - if ($this->isNew)
643   - $result["isNew"] = true;
644   - if ($this->isModified)
645   - $result["isModified"] = true;
646   -
647   - return $result;
648   - }
649   -
650   -
651   -
652   - public function writeBin($handle) {
653   - fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified));
654   - }
655   -
656   - public function loadBin($handle) {
657   - $array = unpack('L6int',fread($handle,6*4));
658   - $this->id = $array['int1'];
659   - $this->index = $array['int2'];
660   - $this->start = $array['int3'];
661   - $this->stop = $array['int4'];
662   - $this->isNew = $array['int5'];
663   - $this->isModified = $array['int6'];
664   - }
665   -
666   - public function dump() {
667   - echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL;
668   - }
669   -}
670   -
671   -class TimeTableCacheObject
672   -{
673   - private static $format_version = 1;
674   - private static $token_len = 8;
675   -
676   - private $token = "";
677   -
678   - private $lastId = 0;
679   -
680   - private $intervals = array();
681   - private $indexes = array();
682   -
683   - private $isModified = false;
684   -
685   - private $filter = null;
686   -
687   - private $sort = null;
688   -
689   - function __construct() {
690   - $this->token = $this->getRandomToken();
691   - $this->filter = new FilterCacheObject();
692   - $this->sort = new SortCacheObject();
693   - }
694   -
695   - public function reset() {
696   - $this->lastId = 0;
697   - $this->isModified = false;
698   - $this->intervals = array();
699   - $this->indexes = array();
700   - unset($this->filter);
701   - $this->filter = new FilterCacheObject();;
702   - unset($this->sort);
703   - $this->sort = new SortCacheObject();
704   - }
705   -
706   - public function setIsModified($isModified) {
707   - $this->isModified = $isModified;
708   - }
709   -
710   - public function addInterval($startIso, $stopIso, $isNew = false, $index = -1) {
711   - $interval = new IntervalCacheObject($this->lastId, count($this->intervals));
712   - ++$this->lastId;
713   - $interval->setStartFromISO($startIso);
714   - $interval->setStopFromISO($stopIso);
715   - $interval->setIsNew($isNew);
716   - array_push($this->intervals, $interval);
717   - if ($index < 0)
718   - array_push($this->indexes, count($this->intervals) - 1);
719   - else
720   - array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1));
721   - if ($isNew)
722   - $this->isModified = true;
723   - return $interval;
724   - }
725   -
726   - public function removeIntervalFromId($id) {
727   - for ($i = 0; $i < count($this->intervals); ++$i)
728   - {
729   - if ($this->intervals[$i]->getId() == $id)
730   - {
731   - //Remove interval
732   - array_splice($this->intervals, $i, 1);
733   - //Remove interval index if exist in indexes list
734   - for ($j = 0; $j < count($this->indexes); ++$j)
735   - {
736   - if ($this->indexes[$j] == $i)
737   - {
738   - array_splice($this->indexes, $j, 1);
739   - break;
740   - }
741   - }
742   - //Update indexes list
743   - for ($j = 0; $j < count($this->indexes); ++$j)
744   - {
745   - if ($this->indexes[$j] >= $i)
746   - $this->indexes[$j]--;
747   - }
748   - $this->isModified = true;
749   - return true;
750   - }
751   - }
752   -
753   - return false;
754   - }
755   -
756   - public function modifyIntervalFromId($id, $start, $stop) {
757   - foreach ($this->intervals as $interval)
758   - {
759   - if ($interval->getId() == $id)
760   - {
761   - if (isset($start))
762   - $interval->setStartFromISO($start);
763   - if (isset($stop))
764   - $interval->setStopFromISO($stop);
765   - $interval->setIsModified(true);
766   - $this->isModified = true;
767   - return true;
768   - }
769   - }
770   -
771   - return false;
772   - }
773   -
774   - public function operationIntervals($extendTime, $shiftTime) {
775   - if (($extendTime == 0) && ($shiftTime == 0))
776   - //Nothing to do
777   - return true;
778   -
779   - for ($i = 0; $i < count($this->indexes); ++$i) {
780   - $start = $this->intervals[$this->indexes[$i]]->getStartToStamp();
781   - $start -= $extendTime;
782   - $start += $shiftTime;
783   - $this->intervals[$this->indexes[$i]]->setStartFromStamp($start);
784   -
785   - $stop = $this->intervals[$this->indexes[$i]]->getStopToStamp();
786   - $stop += $extendTime;
787   - $stop += $shiftTime;
788   - $this->intervals[$this->indexes[$i]]->setStopFromStamp($stop);
789   -
790   - $this->intervals[$this->indexes[$i]]->setIsModified(true);
791   - $this->isModified = true;
792   - }
793   -
794   - return true;
795   - }
796   -
797   - public function mergeIntervals() {
798   - $this->sort->reset();
799   -
800   - $this->sort->loadFromObject(
801   - array(
802   - (object)array("property" => "start", "direction" => "DESC")
803   - )
804   - );
805   -
806   - $this->updateIndexes();
807   -
808   - $merged_intervals = array();
809   -
810   - for ($i = 0; $i < count($this->indexes); ++$i) {
811   - if (count($merged_intervals) == 0)
812   - {
813   - array_push($merged_intervals,array(
814   - "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(),
815   - "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(),
816   - "mod" => FALSE)
817   - );
818   - continue;
819   - }
820   - if (($merged_intervals[count($merged_intervals)-1]["stop"] >= $this->intervals[$this->indexes[$i]]->getStartToStamp()) &&
821   - ($merged_intervals[count($merged_intervals)-1]["stop"] < $this->intervals[$this->indexes[$i]]->getStopToStamp()))
822   - {
823   - $merged_intervals[count($merged_intervals)-1]["stop"] = $this->intervals[$this->indexes[$i]]->getStopToStamp();
824   - $merged_intervals[count($merged_intervals)-1]["mod"] = TRUE;
825   - }
826   - else
827   - array_push($merged_intervals,array(
828   - "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(),
829   - "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(),
830   - "mod" => FALSE)
831   - );
832   - }
833   -
834   - $this->reset();
835   -
836   - foreach ($merged_intervals as $merged_interval) {
837   - $interval = new IntervalCacheObject($this->lastId, count($this->intervals));
838   - ++$this->lastId;
839   - $interval->setStartFromStamp($merged_interval["start"]);
840   - $interval->setStopFromStamp($merged_interval["stop"]);
841   - $interval->setIsNew($merged_interval["mod"]);
842   - if ($merged_interval["mod"])
843   - $this->isModified = true;
844   - array_push($this->intervals, $interval);
845   - array_push($this->indexes, count($this->intervals) - 1);
846   - }
847   -
848   - return true;
849   - }
850   -
851   - public function getStatistics() {
852   - $minTime = NULL;
853   - $maxTime = NULL;
854   - $minDuration = NULL;
855   - $maxDuration = NULL;
856   - $indexMinDuration = -1;
857   - $indexMaxDuration = -1;
858   -
859   - $nbValid = 0;
860   - $durationTotal = 0;
861   -
862   - //Min & Max
863   - for ($i = 0; $i < count($this->indexes); ++$i) {
864   - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
865   - //Invalid interval
866   - continue;
867   -
868   - ++$nbValid;
869   - $durationTotal += $this->intervals[$this->indexes[$i]]->getDuration();
870   -
871   - if (!isset($minTime) || ($minTime > $this->intervals[$this->indexes[$i]]->getStartToStamp()))
872   - $minTime = $this->intervals[$this->indexes[$i]]->getStartToStamp();
873   -
874   - if (!isset($maxTime) || ($maxTime < $this->intervals[$this->indexes[$i]]->getStopToStamp()))
875   - $maxTime = $this->intervals[$this->indexes[$i]]->getStopToStamp();
876   -
877   - if (!isset($minDuration) || ($minDuration > $this->intervals[$this->indexes[$i]]->getDuration()))
878   - {
879   - $minDuration = $this->intervals[$this->indexes[$i]]->getDuration();
880   - $indexMinDuration = $i;
881   - }
882   -
883   - if (!isset($maxDuration) || ($maxDuration < $this->intervals[$this->indexes[$i]]->getDuration()))
884   - {
885   - $maxDuration = $this->intervals[$this->indexes[$i]]->getDuration();
886   - $indexMaxDuration = $i;
887   - }
888   - }
889   -
890   - if (!isset($minTime))
891   - $minTime = 0;
892   - if (!isset($maxTime))
893   - $maxTime = 0;
894   - if (!isset($minDuration))
895   - $minDuration = 0;
896   - if (!isset($maxDuration))
897   - $maxDuration = 0;
898   -
899   -
900   - //Mean
901   - if ($nbValid > 0)
902   - $mean = $durationTotal / $nbValid;
903   - else
904   - $mean = 0;
905   -
906   - //Standard deviation
907   - $pow = 0;
908   - for ($i = 0; $i < count($this->indexes); ++$i) {
909   - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
910   - //Invalid interval
911   - continue;
912   -
913   - $pow += pow($this->intervals[$this->indexes[$i]]->getDuration()-$mean,2);
914   - }
915   - if ($nbValid > 0)
916   - $variance = $pow/$nbValid;
917   - else
918   - $variance = 0;
919   - $stdev = sqrt($variance);
920   -
921   - //Sort by duration to get median
922   - $this->sort->reset();
923   -
924   - $this->sort->loadFromObject(
925   - array(
926   - (object)array("property" => "durationSec", "direction" => "DESC")
927   - )
928   - );
929   -
930   - $this->updateIndexes();
931   -
932   - $durations = array();
933   - for ($i = 0; $i < count($this->indexes); ++$i) {
934   - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
935   - //Invalid interval
936   - continue;
937   -
938   - array_push($durations, $this->intervals[$this->indexes[$i]]->getDuration());
939   - }
940   -
941   - if (count($durations) > 0)
942   - {
943   - if (count($durations)%2 > 0) {
944   - $median = $durations[count($durations)/2-0.5];
945   - } else { // else the number of intervals is an even number
946   - $median = ($durations[count($durations)/2-1] + $durations[count($durations)/2])/2;
947   - }
948   - }
949   - else
950   - $median = 0;
951   -
952   - //Merge intervals to get density
953   - $this->mergeIntervals();
954   -
955   - $durationMergedTotal = 0;
956   - for ($i = 0; $i < count($this->indexes); ++$i) {
957   - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
958   - //Invalid interval
959   - continue;
960   -
961   - $durationMergedTotal += $this->intervals[$this->indexes[$i]]->getDuration();
962   - }
963   -
964   - if (($maxTime-$minTime) > 0)
965   - $density = (($durationMergedTotal/($maxTime-$minTime)));
966   - else
967   - $density = 0;
968   -
969   - return array(
970   - "minDuration" => $minDuration,
971   - "minDurationIndex"=> $indexMinDuration,
972   - "maxDuration" => $maxDuration,
973   - "maxDurationIndex"=> $indexMaxDuration,
974   - "mean" => $mean,
975   - "stdev" => $stdev,
976   - "median" => $median,
977   - "density" => $density);
978   - }
979   -
980   - public function getStatus() {
981   - $nbFiltered = count($this->intervals) - count($this->indexes);
982   -
983   - $nbModified = 0;
984   - $nbNew = 0;
985   - $nbInvalid = 0;
986   - $nbValid = 0;
987   - for ($i = 0; $i < count($this->indexes); ++$i) {
988   - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
989   - ++$nbInvalid;
990   - else
991   - ++$nbValid;
992   - if ($this->intervals[$this->indexes[$i]]->isModified())
993   - ++$nbModified;
994   - if ($this->intervals[$this->indexes[$i]]->isNew())
995   - ++$nbNew;
996   - }
997   -
998   - return array(
999   - "nbFiltered" => $nbFiltered,
1000   - "nbModified" => $nbModified,
1001   - "nbNew" => $nbNew,
1002   - "nbInvalid" => $nbInvalid,
1003   - "nbValid" => $nbValid,
1004   - "isModified" => $this->isModified
1005   - );
1006   - }
1007   -
1008   - public function getIntervalsArray($startIndex, $limit,$skipInvalid = false) {
1009   - $intervals = array();
1010   -
1011   - if (!isset($startIndex))
1012   - $startIndex = 0;
1013   -
1014   - if (!isset($limit))
1015   - $limit = count($this->indexes);
1016   -
1017   - for ($i = 0; $i < $limit; ++$i) {
1018   - if ($startIndex+$i >= count($this->indexes))
1019   - break;
1020   - if ($skipInvalid && ($this->intervals[$this->indexes[$startIndex+$i]]->getDuration() <= 0))
1021   - continue;
1022   - array_push($intervals, $this->intervals[$this->indexes[$startIndex+$i]]->toArray());
1023   - }
1024   - return $intervals;
1025   - }
1026   -
1027   - public function getLength() {
1028   - return count($this->indexes);
1029   - }
1030   -
1031   - public function getToken() {
1032   - return $this->token;
1033   - }
1034   -
1035   - public function getFilter() {
1036   - return $this->filter;
1037   - }
1038   -
1039   - public function getSort() {
1040   - return $this->sort;
1041   - }
1042   -
1043   - public function updateIndexes() {
1044   - $this->indexes = array();
1045   -
1046   - for ($i = 0; $i < count($this->intervals); ++$i)
1047   - $this->intervals[$i]->setIndex($i);
1048   -
1049   - //Apply sort
1050   - $sort_result = $this->sort->apply($this->intervals);
1051   -
1052   - //Apply filter
1053   - for ($i = 0; $i < count($sort_result); ++$i)
1054   - {
1055   - if (!$this->filter->toFiltered($this->intervals[$sort_result[$i]]))
1056   - array_push($this->indexes,$this->intervals[$sort_result[$i]]->getIndex());
1057   - }
1058   - }
1059   -
1060   - public function writeBin($handle) {
1061   - //Magic key ("TTC")
1062   - fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C')));
1063   -
1064   - //Version
1065   - fwrite($handle,pack('L',TimeTableCacheObject::$format_version));
1066   -
1067   - //Token
1068   - for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
1069   - fwrite($handle,pack('C',ord($this->token[$i])));
1070   -
1071   - //Modified
1072   - fwrite($handle,pack('L',$this->isModified));
1073   -
1074   - //Filter
1075   - $this->filter->writeBin($handle);
1076   -
1077   - //Sort
1078   - $this->sort->writeBin($handle);
1079   -
1080   - //Intervals
1081   - fwrite($handle,pack('L2',count($this->intervals), $this->lastId));
1082   - foreach($this->intervals as $interval)
1083   - $interval->writeBin($handle);
1084   -
1085   - //Indexes
1086   - fwrite($handle,pack('L',count($this->indexes)));
1087   - foreach($this->indexes as $index)
1088   - fwrite($handle,pack('L',$index));
1089   - }
1090   -
1091   - public function loadBin($handle) {
1092   - //Magic key ("TTC")
1093   - if (!$res = unpack('C3key',fread($handle,3)))
1094   - return false;
1095   -
1096   - if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C')))
1097   - return false;
1098   -
1099   - //Version
1100   - if (!$res = unpack('Lversion',fread($handle,4)))
1101   - return false;
1102   - if (($res['version'] != TimeTableCacheObject::$format_version))
1103   - return false;
1104   -
1105   - //Token
1106   - $token = "";
1107   - for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
1108   - {
1109   - if (!$res = unpack('Ctoken',fread($handle,1)))
1110   - return false;
1111   - $token .= chr($res['token']);
1112   - }
1113   - $this->token = $token;
1114   -
1115   - //Modified
1116   - if (!$res = unpack('Lmodified',fread($handle,4)))
1117   - return false;
1118   - $this->isModified = $res['modified'];
1119   -
1120   - //Filter
1121   - $this->filter->loadBin($handle);
1122   -
1123   - //Sort
1124   - $this->sort->loadBin($handle);
1125   -
1126   - //Intervals
1127   - $res = unpack('L2data',fread($handle,2*4));
1128   - $nbIntervals = $res['data1'];
1129   - $this->lastId = $res['data2'];
1130   - for ($i = 0; $i < $nbIntervals; ++$i)
1131   - {
1132   - $interval = new IntervalCacheObject(-1);
1133   - $interval->loadBin($handle);
1134   - array_push($this->intervals, $interval);
1135   - }
1136   -
1137   - //Indexes
1138   - $res = unpack('Ldata',fread($handle,4));
1139   - $nbIndexes = $res['data'];
1140   - for ($i = 0; $i < $nbIndexes; ++$i)
1141   - {
1142   - $res = unpack('Lindex',fread($handle,4));
1143   - array_push($this->indexes, $res['index']);
1144   - }
1145   -
1146   - return true;
1147   - }
1148   -
1149   - private function getRandomToken() {
1150   - $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
1151   - return substr(str_shuffle($letters), 0, TimeTableCacheObject::$token_len);
1152   - }
1153   -
1154   - public function dump() {
1155   - echo " => TimeTableCacheObject : token = ".$this->token.", nb intervals = ".count($this->intervals).", last id = ".$this->lastId.", nb indexes = ".count($this->indexes).PHP_EOL;
1156   - echo PHP_EOL;
1157   -
1158   - $this->filter->dump();
1159   - echo PHP_EOL;
1160   -
1161   - $this->sort->dump();
1162   - echo PHP_EOL;
1163   -
1164   - foreach ($this->intervals as $interval)
1165   - $interval->dump();
1166   - echo PHP_EOL;
1167   -
1168   - echo " => Indexes list : ";
1169   - foreach ($this->indexes as $index)
1170   - {
1171   - echo $index.", ";
1172   - }
1173   - echo PHP_EOL;
1174   - }
1175   -}
1176   -
1177   -class TimeTableCacheMgr
1178   -{
1179   - private static $cache_file = "cacheTT";
  560 + protected static $cache_file = "cacheTT";
1180 561  
1181   - private $ttMgr = null;
1182   - private $cache = null;
  562 + protected $ttMgr = null;
  563 + protected $cache = null;
1183 564  
1184 565 function __construct() {
1185 566 $this->ttMgr = new TimeTableMgr();
... ... @@ -1449,11 +830,11 @@ class TimeTableCacheMgr
1449 830 $this->cache->dump();
1450 831 }
1451 832  
1452   - private function getCacheFilePath() {
  833 + protected function getCacheFilePath() {
1453 834 return USERTTDIR.(self::$cache_file);
1454 835 }
1455 836  
1456   - private function saveToFile() {
  837 + protected function saveToFile() {
1457 838 if (!isset($this->cache))
1458 839 return false;
1459 840 $handle = fopen($this->getCacheFilePath(), 'wb');
... ... @@ -1468,7 +849,7 @@ class TimeTableCacheMgr
1468 849 return $result;
1469 850 }
1470 851  
1471   - private function loadFromFile() {
  852 + protected function loadFromFile() {
1472 853 if (!file_exists($this->getCacheFilePath()))
1473 854 return false;
1474 855 $this->cache = new TimeTableCacheObject();
... ...
php/classes/TimeTableCacheObject.php 0 โ†’ 100644
... ... @@ -0,0 +1,509 @@
  1 +<?php
  2 +
  3 +class TimeTableCacheObject
  4 +{
  5 + protected static $format_version = 1;
  6 + protected static $token_len = 8;
  7 +
  8 + protected $token = "";
  9 +
  10 + protected $lastId = 0;
  11 +
  12 + protected $intervals = array();
  13 + protected $indexes = array();
  14 +
  15 + protected $isModified = false;
  16 +
  17 + protected $filter = null;
  18 +
  19 + protected $sort = null;
  20 +
  21 + function __construct() {
  22 + $this->token = $this->getRandomToken();
  23 + $this->filter = new FilterCacheObject();
  24 + $this->sort = new SortCacheObject();
  25 + }
  26 +
  27 + public function reset() {
  28 + $this->lastId = 0;
  29 + $this->isModified = false;
  30 + $this->intervals = array();
  31 + $this->indexes = array();
  32 + unset($this->filter);
  33 + $this->filter = new FilterCacheObject();;
  34 + unset($this->sort);
  35 + $this->sort = new SortCacheObject();
  36 + }
  37 +
  38 + public function setIsModified($isModified) {
  39 + $this->isModified = $isModified;
  40 + }
  41 +
  42 + public function addInterval($startIso, $stopIso, $isNew = false, $index = -1) {
  43 + $interval = new IntervalCacheObject($this->lastId, count($this->intervals));
  44 + ++$this->lastId;
  45 + $interval->setStartFromISO($startIso);
  46 + $interval->setStopFromISO($stopIso);
  47 + $interval->setIsNew($isNew);
  48 + array_push($this->intervals, $interval);
  49 + if ($index < 0)
  50 + array_push($this->indexes, count($this->intervals) - 1);
  51 + else
  52 + array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1));
  53 + if ($isNew)
  54 + $this->isModified = true;
  55 + return $interval;
  56 + }
  57 +
  58 + public function removeIntervalFromId($id) {
  59 + for ($i = 0; $i < count($this->intervals); ++$i)
  60 + {
  61 + if ($this->intervals[$i]->getId() == $id)
  62 + {
  63 + //Remove interval
  64 + array_splice($this->intervals, $i, 1);
  65 + //Remove interval index if exist in indexes list
  66 + for ($j = 0; $j < count($this->indexes); ++$j)
  67 + {
  68 + if ($this->indexes[$j] == $i)
  69 + {
  70 + array_splice($this->indexes, $j, 1);
  71 + break;
  72 + }
  73 + }
  74 + //Update indexes list
  75 + for ($j = 0; $j < count($this->indexes); ++$j)
  76 + {
  77 + if ($this->indexes[$j] >= $i)
  78 + $this->indexes[$j]--;
  79 + }
  80 + $this->isModified = true;
  81 + return true;
  82 + }
  83 + }
  84 +
  85 + return false;
  86 + }
  87 +
  88 + public function modifyIntervalFromId($id, $start, $stop) {
  89 + foreach ($this->intervals as $interval)
  90 + {
  91 + if ($interval->getId() == $id)
  92 + {
  93 + if (isset($start))
  94 + $interval->setStartFromISO($start);
  95 + if (isset($stop))
  96 + $interval->setStopFromISO($stop);
  97 + $interval->setIsModified(true);
  98 + $this->isModified = true;
  99 + return true;
  100 + }
  101 + }
  102 +
  103 + return false;
  104 + }
  105 +
  106 + public function operationIntervals($extendTime, $shiftTime) {
  107 + if (($extendTime == 0) && ($shiftTime == 0))
  108 + //Nothing to do
  109 + return true;
  110 +
  111 + for ($i = 0; $i < count($this->indexes); ++$i) {
  112 + $start = $this->intervals[$this->indexes[$i]]->getStartToStamp();
  113 + $start -= $extendTime;
  114 + $start += $shiftTime;
  115 + $this->intervals[$this->indexes[$i]]->setStartFromStamp($start);
  116 +
  117 + $stop = $this->intervals[$this->indexes[$i]]->getStopToStamp();
  118 + $stop += $extendTime;
  119 + $stop += $shiftTime;
  120 + $this->intervals[$this->indexes[$i]]->setStopFromStamp($stop);
  121 +
  122 + $this->intervals[$this->indexes[$i]]->setIsModified(true);
  123 + $this->isModified = true;
  124 + }
  125 +
  126 + return true;
  127 + }
  128 +
  129 + public function mergeIntervals() {
  130 + $this->sort->reset();
  131 +
  132 + $this->sort->loadFromObject(
  133 + array(
  134 + (object)array("property" => "start", "direction" => "DESC")
  135 + )
  136 + );
  137 +
  138 + $this->updateIndexes();
  139 +
  140 + $merged_intervals = array();
  141 +
  142 + for ($i = 0; $i < count($this->indexes); ++$i) {
  143 + if (count($merged_intervals) == 0)
  144 + {
  145 + array_push($merged_intervals,array(
  146 + "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(),
  147 + "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(),
  148 + "mod" => FALSE)
  149 + );
  150 + continue;
  151 + }
  152 + if (($merged_intervals[count($merged_intervals)-1]["stop"] >= $this->intervals[$this->indexes[$i]]->getStartToStamp()) &&
  153 + ($merged_intervals[count($merged_intervals)-1]["stop"] < $this->intervals[$this->indexes[$i]]->getStopToStamp()))
  154 + {
  155 + $merged_intervals[count($merged_intervals)-1]["stop"] = $this->intervals[$this->indexes[$i]]->getStopToStamp();
  156 + $merged_intervals[count($merged_intervals)-1]["mod"] = TRUE;
  157 + }
  158 + else
  159 + array_push($merged_intervals,array(
  160 + "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(),
  161 + "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(),
  162 + "mod" => FALSE)
  163 + );
  164 + }
  165 +
  166 + $this->reset();
  167 +
  168 + foreach ($merged_intervals as $merged_interval) {
  169 + $interval = new IntervalCacheObject($this->lastId, count($this->intervals));
  170 + ++$this->lastId;
  171 + $interval->setStartFromStamp($merged_interval["start"]);
  172 + $interval->setStopFromStamp($merged_interval["stop"]);
  173 + $interval->setIsNew($merged_interval["mod"]);
  174 + if ($merged_interval["mod"])
  175 + $this->isModified = true;
  176 + array_push($this->intervals, $interval);
  177 + array_push($this->indexes, count($this->intervals) - 1);
  178 + }
  179 +
  180 + return true;
  181 + }
  182 +
  183 + public function getStatistics() {
  184 + $minTime = NULL;
  185 + $maxTime = NULL;
  186 + $minDuration = NULL;
  187 + $maxDuration = NULL;
  188 + $indexMinDuration = -1;
  189 + $indexMaxDuration = -1;
  190 +
  191 + $nbValid = 0;
  192 + $durationTotal = 0;
  193 +
  194 + //Min & Max
  195 + for ($i = 0; $i < count($this->indexes); ++$i) {
  196 + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
  197 + //Invalid interval
  198 + continue;
  199 +
  200 + ++$nbValid;
  201 + $durationTotal += $this->intervals[$this->indexes[$i]]->getDuration();
  202 +
  203 + if (!isset($minTime) || ($minTime > $this->intervals[$this->indexes[$i]]->getStartToStamp()))
  204 + $minTime = $this->intervals[$this->indexes[$i]]->getStartToStamp();
  205 +
  206 + if (!isset($maxTime) || ($maxTime < $this->intervals[$this->indexes[$i]]->getStopToStamp()))
  207 + $maxTime = $this->intervals[$this->indexes[$i]]->getStopToStamp();
  208 +
  209 + if (!isset($minDuration) || ($minDuration > $this->intervals[$this->indexes[$i]]->getDuration()))
  210 + {
  211 + $minDuration = $this->intervals[$this->indexes[$i]]->getDuration();
  212 + $indexMinDuration = $i;
  213 + }
  214 +
  215 + if (!isset($maxDuration) || ($maxDuration < $this->intervals[$this->indexes[$i]]->getDuration()))
  216 + {
  217 + $maxDuration = $this->intervals[$this->indexes[$i]]->getDuration();
  218 + $indexMaxDuration = $i;
  219 + }
  220 + }
  221 +
  222 + if (!isset($minTime))
  223 + $minTime = 0;
  224 + if (!isset($maxTime))
  225 + $maxTime = 0;
  226 + if (!isset($minDuration))
  227 + $minDuration = 0;
  228 + if (!isset($maxDuration))
  229 + $maxDuration = 0;
  230 +
  231 +
  232 + //Mean
  233 + if ($nbValid > 0)
  234 + $mean = $durationTotal / $nbValid;
  235 + else
  236 + $mean = 0;
  237 +
  238 + //Standard deviation
  239 + $pow = 0;
  240 + for ($i = 0; $i < count($this->indexes); ++$i) {
  241 + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
  242 + //Invalid interval
  243 + continue;
  244 +
  245 + $pow += pow($this->intervals[$this->indexes[$i]]->getDuration()-$mean,2);
  246 + }
  247 + if ($nbValid > 0)
  248 + $variance = $pow/$nbValid;
  249 + else
  250 + $variance = 0;
  251 + $stdev = sqrt($variance);
  252 +
  253 + //Sort by duration to get median
  254 + $this->sort->reset();
  255 +
  256 + $this->sort->loadFromObject(
  257 + array(
  258 + (object)array("property" => "durationSec", "direction" => "DESC")
  259 + )
  260 + );
  261 +
  262 + $this->updateIndexes();
  263 +
  264 + $durations = array();
  265 + for ($i = 0; $i < count($this->indexes); ++$i) {
  266 + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
  267 + //Invalid interval
  268 + continue;
  269 +
  270 + array_push($durations, $this->intervals[$this->indexes[$i]]->getDuration());
  271 + }
  272 +
  273 + if (count($durations) > 0)
  274 + {
  275 + if (count($durations)%2 > 0) {
  276 + $median = $durations[count($durations)/2-0.5];
  277 + } else { // else the number of intervals is an even number
  278 + $median = ($durations[count($durations)/2-1] + $durations[count($durations)/2])/2;
  279 + }
  280 + }
  281 + else
  282 + $median = 0;
  283 +
  284 + //Merge intervals to get density
  285 + $this->mergeIntervals();
  286 +
  287 + $durationMergedTotal = 0;
  288 + for ($i = 0; $i < count($this->indexes); ++$i) {
  289 + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
  290 + //Invalid interval
  291 + continue;
  292 +
  293 + $durationMergedTotal += $this->intervals[$this->indexes[$i]]->getDuration();
  294 + }
  295 +
  296 + if (($maxTime-$minTime) > 0)
  297 + $density = (($durationMergedTotal/($maxTime-$minTime)));
  298 + else
  299 + $density = 0;
  300 +
  301 + return array(
  302 + "minDuration" => $minDuration,
  303 + "minDurationIndex"=> $indexMinDuration,
  304 + "maxDuration" => $maxDuration,
  305 + "maxDurationIndex"=> $indexMaxDuration,
  306 + "mean" => $mean,
  307 + "stdev" => $stdev,
  308 + "median" => $median,
  309 + "density" => $density);
  310 + }
  311 +
  312 + public function getStatus() {
  313 + $nbFiltered = count($this->intervals) - count($this->indexes);
  314 +
  315 + $nbModified = 0;
  316 + $nbNew = 0;
  317 + $nbInvalid = 0;
  318 + $nbValid = 0;
  319 + for ($i = 0; $i < count($this->indexes); ++$i) {
  320 + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0)
  321 + ++$nbInvalid;
  322 + else
  323 + ++$nbValid;
  324 + if ($this->intervals[$this->indexes[$i]]->isModified())
  325 + ++$nbModified;
  326 + if ($this->intervals[$this->indexes[$i]]->isNew())
  327 + ++$nbNew;
  328 + }
  329 +
  330 + return array(
  331 + "nbFiltered" => $nbFiltered,
  332 + "nbModified" => $nbModified,
  333 + "nbNew" => $nbNew,
  334 + "nbInvalid" => $nbInvalid,
  335 + "nbValid" => $nbValid,
  336 + "isModified" => $this->isModified
  337 + );
  338 + }
  339 +
  340 + public function getIntervalsArray($startIndex, $limit,$skipInvalid = false) {
  341 + $intervals = array();
  342 +
  343 + if (!isset($startIndex))
  344 + $startIndex = 0;
  345 +
  346 + if (!isset($limit))
  347 + $limit = count($this->indexes);
  348 +
  349 + for ($i = 0; $i < $limit; ++$i) {
  350 + if ($startIndex+$i >= count($this->indexes))
  351 + break;
  352 + if ($skipInvalid && ($this->intervals[$this->indexes[$startIndex+$i]]->getDuration() <= 0))
  353 + continue;
  354 + array_push($intervals, $this->intervals[$this->indexes[$startIndex+$i]]->toArray());
  355 + }
  356 + return $intervals;
  357 + }
  358 +
  359 + public function getLength() {
  360 + return count($this->indexes);
  361 + }
  362 +
  363 + public function getToken() {
  364 + return $this->token;
  365 + }
  366 +
  367 + public function getFilter() {
  368 + return $this->filter;
  369 + }
  370 +
  371 + public function getSort() {
  372 + return $this->sort;
  373 + }
  374 +
  375 + public function updateIndexes() {
  376 + $this->indexes = array();
  377 +
  378 + for ($i = 0; $i < count($this->intervals); ++$i)
  379 + $this->intervals[$i]->setIndex($i);
  380 +
  381 + //Apply sort
  382 + $sort_result = $this->sort->apply($this->intervals);
  383 +
  384 + //Apply filter
  385 + for ($i = 0; $i < count($sort_result); ++$i)
  386 + {
  387 + if (!$this->filter->toFiltered($this->intervals[$sort_result[$i]]))
  388 + array_push($this->indexes,$this->intervals[$sort_result[$i]]->getIndex());
  389 + }
  390 + }
  391 +
  392 + public function writeBin($handle) {
  393 + //Magic key ("TTC")
  394 + fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C')));
  395 +
  396 + //Version
  397 + fwrite($handle,pack('L',TimeTableCacheObject::$format_version));
  398 +
  399 + //Token
  400 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  401 + fwrite($handle,pack('C',ord($this->token[$i])));
  402 +
  403 + //Modified
  404 + fwrite($handle,pack('L',$this->isModified));
  405 +
  406 + //Filter
  407 + $this->filter->writeBin($handle);
  408 +
  409 + //Sort
  410 + $this->sort->writeBin($handle);
  411 +
  412 + //Intervals
  413 + fwrite($handle,pack('L2',count($this->intervals), $this->lastId));
  414 + foreach($this->intervals as $interval)
  415 + $interval->writeBin($handle);
  416 +
  417 + //Indexes
  418 + fwrite($handle,pack('L',count($this->indexes)));
  419 + foreach($this->indexes as $index)
  420 + fwrite($handle,pack('L',$index));
  421 + }
  422 +
  423 + public function loadBin($handle) {
  424 + //Magic key ("TTC")
  425 + if (!$res = unpack('C3key',fread($handle,3)))
  426 + return false;
  427 +
  428 + if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C')))
  429 + return false;
  430 +
  431 + //Version
  432 + if (!$res = unpack('Lversion',fread($handle,4)))
  433 + return false;
  434 + if (($res['version'] != TimeTableCacheObject::$format_version))
  435 + return false;
  436 +
  437 + //Token
  438 + $token = "";
  439 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  440 + {
  441 + if (!$res = unpack('Ctoken',fread($handle,1)))
  442 + return false;
  443 + $token .= chr($res['token']);
  444 + }
  445 + $this->token = $token;
  446 +
  447 + //Modified
  448 + if (!$res = unpack('Lmodified',fread($handle,4)))
  449 + return false;
  450 + $this->isModified = $res['modified'];
  451 +
  452 + //Filter
  453 + $this->filter->loadBin($handle);
  454 +
  455 + //Sort
  456 + $this->sort->loadBin($handle);
  457 +
  458 + //Intervals
  459 + $res = unpack('L2data',fread($handle,2*4));
  460 + $nbIntervals = $res['data1'];
  461 + $this->lastId = $res['data2'];
  462 + for ($i = 0; $i < $nbIntervals; ++$i)
  463 + {
  464 + $interval = new IntervalCacheObject(-1);
  465 + $interval->loadBin($handle);
  466 + array_push($this->intervals, $interval);
  467 + }
  468 +
  469 + //Indexes
  470 + $res = unpack('Ldata',fread($handle,4));
  471 + $nbIndexes = $res['data'];
  472 + for ($i = 0; $i < $nbIndexes; ++$i)
  473 + {
  474 + $res = unpack('Lindex',fread($handle,4));
  475 + array_push($this->indexes, $res['index']);
  476 + }
  477 +
  478 + return true;
  479 + }
  480 +
  481 + protected function getRandomToken() {
  482 + $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
  483 + return substr(str_shuffle($letters), 0, TimeTableCacheObject::$token_len);
  484 + }
  485 +
  486 + public function dump() {
  487 + echo " => TimeTableCacheObject : token = ".$this->token.", nb intervals = ".count($this->intervals).", last id = ".$this->lastId.", nb indexes = ".count($this->indexes).PHP_EOL;
  488 + echo PHP_EOL;
  489 +
  490 + $this->filter->dump();
  491 + echo PHP_EOL;
  492 +
  493 + $this->sort->dump();
  494 + echo PHP_EOL;
  495 +
  496 + foreach ($this->intervals as $interval)
  497 + $interval->dump();
  498 + echo PHP_EOL;
  499 +
  500 + echo " => Indexes list : ";
  501 + foreach ($this->indexes as $index)
  502 + {
  503 + echo $index.", ";
  504 + }
  505 + echo PHP_EOL;
  506 + }
  507 +}
  508 +
  509 +?>
0 510 \ No newline at end of file
... ...
php/classes/TimeTableMgr.php
... ... @@ -7,25 +7,23 @@
7 7 *
8 8 */
9 9  
10   -function timeFormat($myString) {
11   - if (format == "Y z H i s") {
12   - $tt = getdate(strtotime($myString));
13   - return sprintf("%04d",$tt["year"])." "
14   - .sprintf("%03d",$tt["yday"]+1)." "
15   - .sprintf("%02d",$tt["hours"])." "
16   - .sprintf("%02d",$tt["minutes"])." "
17   - .sprintf("%02d",$tt["seconds"]);
18   - }
19   - return date(format,strtotime($myString));
20   -
21   - }
22   -
23   -class TimeTableMgr extends AmdaObjectMgr {
24   -
25   -//TODO add catalogs as for requestMgr
26   -
  10 +function timeFormat($myString)
  11 +{
  12 + if (format == "Y z H i s") {
  13 + $tt = getdate(strtotime($myString));
  14 + return sprintf("%04d",$tt["year"])." "
  15 + .sprintf("%03d",$tt["yday"]+1)." "
  16 + .sprintf("%02d",$tt["hours"])." "
  17 + .sprintf("%02d",$tt["minutes"])." "
  18 + .sprintf("%02d",$tt["seconds"]);
  19 + }
  20 + return date(format,strtotime($myString));
  21 +}
27 22  
28   - function __construct($user) {
  23 +class TimeTableMgr extends AmdaObjectMgr
  24 +{
  25 + function __construct($user)
  26 + {
29 27 parent::__construct('Tt.xml');
30 28 $this->contentRootId = 'timeTable-treeRootNode';
31 29 $this->contentRootTag = 'timetabList';
... ... @@ -40,7 +38,6 @@ class TimeTableMgr extends AmdaObjectMgr {
40 38 }
41 39 }
42 40  
43   -
44 41 protected function createDom() {
45 42  
46 43 $types = array('timetab' => 'timeTable', 'catalog' => 'catalog');
... ... @@ -53,14 +50,15 @@ class TimeTableMgr extends AmdaObjectMgr {
53 50 $typeElement->setAttribute('xml:id', $contentId);
54 51 $rootElement->appendChild($typeElement);
55 52 }
56   - $this->contentDom->appendChild($rootElement);
  53 + $this->contentDom->appendChild($rootElement);
57 54 $this->contentDom->save($this->xmlName);
58 55 }
59 56  
60 57 /*
61   - * rename Time Table in id.xml
62   - */
63   - protected function renameInResource($name, $id) {
  58 + * rename Time Table in id.xml
  59 + */
  60 + protected function renameInResource($name, $id)
  61 + {
64 62 if (!file_exists(USERTTDIR.$id.'.xml')) return false;
65 63  
66 64 $this->objectDom -> load(USERTTDIR.$id.'.xml');
... ... @@ -71,23 +69,30 @@ class TimeTableMgr extends AmdaObjectMgr {
71 69 return true;
72 70 }
73 71  
74   - protected function deleteParameter($id){
  72 + protected function deleteParameter($id)
  73 + {
75 74 if (file_exists(USERTTDIR.$id.'.xml')) unlink(USERTTDIR.$id.'.xml');
76 75 }
77 76  
78 77 /*
79   - * Check if difference is name and info only
80   - */
  78 + * Check if difference is name and info only
  79 + */
81 80 protected function renameOnly($p) {
82 81 //if (!($p->intervals)) return true;
83 82 return false;
84 83 }
  84 +
  85 + /*
  86 + * In case of catalogs
  87 + */
  88 + protected function setParamDescription($param) { }
85 89  
86   -
  90 +
87 91 /*
88 92 * Create Time Table
89 93 */
90   - protected function createParameter($p, $folder){
  94 + protected function createParameter($p, $folder)
  95 + {
91 96 if ($this -> objectExistsByName($p->name)) {
92 97 $p -> id = $this -> getObjectIdByName($p->name);
93 98 $this -> deleteObject($p);
... ... @@ -95,12 +100,15 @@ class TimeTableMgr extends AmdaObjectMgr {
95 100 $this->id = $this->setId();
96 101 $this->created = date('Y-m-d\TH:i:s');
97 102 if (!$this->id) return array('error' => ID_CREATION_ERROR);
  103 +
98 104 $this->resFileName = USERTTDIR.$this->id.'.xml';
  105 + //TODO catalog root element = 'timetable'
99 106 $rootElement = $this->objectDom->createElement('timetable');
100 107 $rootElement->setAttribute('xml:id',$this->id);
101 108  
102 109 foreach ($p as $key => $value)
103   - if ($key != 'id' && $key != 'leaf' && $key != 'nodeType') {
  110 + if ($key != 'id' && $key != 'leaf' && $key != 'nodeType' &&
  111 + $key != 'objName' && $key != 'objFormat' && $key != 'folderId' && $key != 'cacheToken') {
104 112 if ($key == 'created') {
105 113 $rootElement->appendChild($this->objectDom->createElement($key, $this->created));
106 114 }
... ... @@ -114,8 +122,14 @@ class TimeTableMgr extends AmdaObjectMgr {
114 122 $n_int++;
115 123 }
116 124 }*/
  125 + // it is catalog
  126 + else if ($key == 'parameters') {
  127 + $paramsElement = $this->setParamDescription($value);
  128 + if ($paramsElement) $rootElement->appendChild($paramsElement);
  129 +
  130 + }
117 131 else if ($key != 'intervals')
118   - $rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
  132 + $rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
119 133 }
120 134  
121 135 $this->objectDom->appendChild($rootElement);
... ... @@ -125,119 +139,117 @@ class TimeTableMgr extends AmdaObjectMgr {
125 139 $obj->intervals = $p->nbIntervals;
126 140 $this -> addToContent($obj, $folder);
127 141 return array('id' => $this->id,'created' => $this->created,'info' =>$obj->intervals.' intervals' );
128   -
129 142 }
130 143  
131   - protected function call_intersection($fst, $snd) {
132   - $inf = ( $fst[0] > $snd[0] ) ? $fst[0] : $snd[0];
133   - $sup = ( $fst[1] < $snd[1] ) ? $fst[1] : $snd[1];
134   - if ( $inf >= $sup ) { $inter[] = array(0,0); }
135   - else {$inter[] = array($inf,$sup); }
136   - return $inter;
137   - }
  144 + protected function call_intersection($fst, $snd)
  145 + {
  146 + $inf = ( $fst[0] > $snd[0] ) ? $fst[0] : $snd[0];
  147 + $sup = ( $fst[1] < $snd[1] ) ? $fst[1] : $snd[1];
  148 + if ( $inf >= $sup ) { $inter[] = array(0,0); }
  149 + else {$inter[] = array($inf,$sup); }
  150 + return $inter;
  151 + }
138 152  
139 153 /*
140 154 * For TT download : file format in text
141 155 */
142   - protected function xsl2text($file,$format) {
143   - define("format", $format);
144   - $xslt = new XSLTProcessor();
  156 + protected function xsl2text($file,$format)
  157 + {
  158 + define("format", $format);
  159 + $xslt = new XSLTProcessor();
145 160  
146   - // add PHP functions to XSLT functions
147   - $xslt -> registerPHPFunctions();
148   -
149   - // Load Time table
150   - $xml = new domDocument("1.0");
151   - $xml->load($file);
152   -
153   - // Load XSL file
154   - $xsl = new domDocument("1.0");
155   - if ($format == "Y-m-dTH:i:s") $xslName = "xml2iso.xsl";
156   - else $xslName = "xml2all.xsl";
157   - $xsl->load(XMLPATH.$xslName);
158   -
159   - // Import XSL and write output file in text format
160   - $xslt -> importStylesheet($xsl);
161   - $filename = $xml->getElementsByTagName('name')->item(0)->nodeValue.".txt";
162   - $output=fopen(USERWORKINGDIR.$filename, "w");
163   - fwrite($output, trim($xslt -> transformToDoc($xml)->firstChild->wholeText));
164   - fclose($output);
  161 + // add PHP functions to XSLT functions
  162 + $xslt -> registerPHPFunctions();
  163 +
  164 + // Load Time table
  165 + $xml = new domDocument("1.0");
  166 + $xml->load($file);
  167 +
  168 + // Load XSL file
  169 + $xsl = new domDocument("1.0");
  170 + if ($format == "Y-m-dTH:i:s") $xslName = "xml2iso.xsl";
  171 + else $xslName = "xml2all.xsl";
  172 + $xsl->load(XMLPATH.$xslName);
  173 +
  174 + // Import XSL and write output file in text format
  175 + $xslt -> importStylesheet($xsl);
  176 + $filename = $xml->getElementsByTagName('name')->item(0)->nodeValue.".txt";
  177 + $output=fopen(USERWORKINGDIR.$filename, "w");
  178 + fwrite($output, trim($xslt -> transformToDoc($xml)->firstChild->wholeText));
  179 + fclose($output);
165 180  
166 181 return USERWORKINGDIR.$filename;
167 182 }
168 183  
169 184 /*
170   - * For TT download : file format in vot
  185 + * For TT download : file format in vot
171 186 */
172   - public function xsl2vot($file,$format) {
  187 + public function xsl2vot($file,$format)
  188 + {
173 189 $xslt = new XSLTProcessor();
174 190  
175   - // Load Time table
176   - $xml = new domDocument("1.0");
177   - $xml->load($file);
178   -
179   - // Load XSL file
180   - $xsl = new domDocument("1.0");
181   - $xsl->load(XMLPATH.'xml2vot.xsl');
182   -
183   - // Import XSL and write output file in vot format
184   - $xslt -> importStylesheet($xsl);
185   - $vot = new domDocument("1.0");
186   - $vot -> loadXML($xslt -> transformToXML($xml));
187   - $filename = $xml->getElementsByTagName('name')->item(0)->nodeValue.".xml";
188   - $vot -> save(USERWORKINGDIR.$filename);
189   -
190   - return USERWORKINGDIR.$filename;
  191 + // Load Time table
  192 + $xml = new domDocument("1.0");
  193 + $xml->load($file);
  194 +
  195 + // Load XSL file
  196 + $xsl = new domDocument("1.0");
  197 + $xsl->load(XMLPATH.'xml2vot.xsl');
  198 +
  199 + // Import XSL and write output file in vot format
  200 + $xslt -> importStylesheet($xsl);
  201 + $vot = new domDocument("1.0");
  202 + $vot -> loadXML($xslt -> transformToXML($xml));
  203 + $filename = $xml->getElementsByTagName('name')->item(0)->nodeValue.".xml";
  204 + $vot -> save(USERWORKINGDIR.$filename);
  205 +
  206 + return USERWORKINGDIR.$filename;
191 207 }
192 208  
193 209 /*
194 210 * Uploaded text file => convert to array
195 211 */
196   - protected function text2amda($tmp_file, $onlyDescription = false) {
197   -
198   -
199   - $suffix = explode('.', basename($tmp_file));
200   -
201   - $lines = file($tmp_file,FILE_SKIP_EMPTY_LINES);
202   -
203   - $description="Uploaded Time Table".PHP_EOL;
204   -
205   - foreach ($lines as $line){
206   - if ($line[0] == '#') $description=$description."\n".substr($line,1,-1);
207   - else {
208   - $date = explode(' ',$line);
209   - if (!strtotime(trim($date[0]))) {
210   - $description=$description."\n".$line;
211   - continue;
212   - }
213   -// check if it is ISO format
214   - if (!isset($isIso)) $isIso = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/', trim($date[0]));
215   - if (!$isIso) {
  212 + protected function text2amda($tmp_file, $onlyDescription = false)
  213 + {
  214 + $suffix = explode('.', basename($tmp_file));
  215 + $lines = file($tmp_file,FILE_SKIP_EMPTY_LINES);
  216 + $description="Uploaded Time Table".PHP_EOL;
  217 +
  218 + foreach ($lines as $line){
  219 + if ($line[0] == '#') $description=$description."\n".substr($line,1,-1);
  220 + else {
  221 + $date = explode(' ',$line);
  222 + if (!strtotime(trim($date[0]))) {
  223 + $description=$description."\n".$line;
  224 + continue;
  225 + }
  226 + // check if it is ISO format
  227 + if (!isset($isIso)) $isIso = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/', trim($date[0]));
  228 + if (!$isIso) {
216 229 $tempT = strtotime(trim($date[0]));
217 230 $startDate = date('Y-m-d',$tempT)."T".date('H:i:s',$tempT);
218 231 $tempT = strtotime(trim($date[1]));
219 232 $stopDate = date('Y-m-d',$tempT)."T".date('H:i:s',$tempT);
220   -//TODO convert time into non standard formats
221   - // $startDate = DateTime::createFromFormat($timeFormat, trim($date[0]);
222   - // $start = $startDate->format('Y-m-d')."T".$startDate->format('H:i:s');
223   - // $stopDate = DateTime::createFromFormat($timeFormat, trim($date[1]);
224   - // $stop = $stopDate->format('Y-m-d')."T".$stopDate->format('H:i:s');
225   - if (!$onlyDescription)
226   - $attributesToReturn['intervals'][] = array('start' => $startDate, 'stop' => $stopDate);
227   - }
228   - else {
229   - if (!$onlyDescription)
  233 + //TODO convert time into non standard formats
  234 + // $startDate = DateTime::createFromFormat($timeFormat, trim($date[0]);
  235 + // $start = $startDate->format('Y-m-d')."T".$startDate->format('H:i:s');
  236 + // $stopDate = DateTime::createFromFormat($timeFormat, trim($date[1]);
  237 + // $stop = $stopDate->format('Y-m-d')."T".$stopDate->format('H:i:s');
  238 + if (!$onlyDescription)
  239 + $attributesToReturn['intervals'][] = array('start' => $startDate, 'stop' => $stopDate);
  240 + }
  241 + else {
  242 + if (!$onlyDescription)
230 243 $attributesToReturn['intervals'][] = array('start' => trim($date[0]), 'stop' => trim($date[1]));
231 244 }
232 245 }
233 246 }
234 247  
235   - $attributesToReturn['description'] = $description;
236   - $attributesToReturn['name'] = basename($tmp_file, '.'.$suffix[1]);
237   - $attributesToReturn['created'] = date('Y-m-d')."T".date('H:i:s');
  248 + $attributesToReturn['description'] = $description;
  249 + $attributesToReturn['name'] = basename($tmp_file, '.'.$suffix[1]);
  250 + $attributesToReturn['created'] = date('Y-m-d')."T".date('H:i:s');
238 251  
239 252 return $attributesToReturn;
240   -
241 253 }
242 254  
243 255  
... ... @@ -276,7 +288,7 @@ class TimeTableMgr extends AmdaObjectMgr {
276 288  
277 289 function getObject($id, $nodeType) {
278 290  
279   - if ($nodeType == 'sharedtimeTable') {
  291 + if (substr($nodeType,0,6) == 'shared') {
280 292 $pathid = SHAREDPATH.'TT/'.$id;
281 293 }
282 294 else {
... ... @@ -291,20 +303,20 @@ class TimeTableMgr extends AmdaObjectMgr {
291 303  
292 304 $nbInt = 0;
293 305 foreach($attributes as $attribute)
294   - if($attribute->nodeType == XML_ELEMENT_NODE){
295   - /*if ($attribute->tagName == 'intervals') {
296   - $start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
297   - $stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
298   - $attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
299   - }
300   - else
301   - $attributesToReturn[$attribute->tagName] = $attribute->nodeValue;*/
302   - //BRE - load all except intervals - Intervals will be loaded later with 'loadIntervalsFromTT' function
303   - if ($attribute->tagName != 'intervals')
304   - $attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
305   - else
306   - $nbInt++;
307   - }
  306 + if($attribute->nodeType == XML_ELEMENT_NODE){
  307 + /*if ($attribute->tagName == 'intervals') {
  308 + $start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
  309 + $stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
  310 + $attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
  311 + }
  312 + else
  313 + $attributesToReturn[$attribute->tagName] = $attribute->nodeValue;*/
  314 + //BRE - load all except intervals - Intervals will be loaded later with 'loadIntervalsFromTT' function
  315 + if ($attribute->tagName != 'intervals')
  316 + $attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
  317 + else
  318 + $nbInt++;
  319 + }
308 320  
309 321 $attributesToReturn['nbIntervals'] = $nbInt;
310 322  
... ... @@ -418,12 +430,20 @@ class TimeTableMgr extends AmdaObjectMgr {
418 430 'totalCount' => $intervals->length,
419 431 'intervals' => $result,
420 432 'start' => isset($start) ? $start : 0,
421   - 'limit' => isset($limit) ? $limit : 0,
  433 + 'limit' => isset($limit) ? $limit : 0,
422 434 'success' => true
423 435 );
424 436  
425 437 }
426   -
  438 +
  439 + protected function createIntervalElement($interval) {
  440 +
  441 + $newInterval = $this->objectDom->createElement('intervals');
  442 + $newInterval->appendChild($this->objectDom->createElement('start',$interval->start));
  443 + $newInterval->appendChild($this->objectDom->createElement('stop',$interval->stop));
  444 + return $newInterval;
  445 + }
  446 +
427 447 public function saveIntervals($id,$intervals,$action)
428 448 {
429 449 if (substr($id,0,6) == 'shared') {
... ... @@ -457,11 +477,9 @@ class TimeTableMgr extends AmdaObjectMgr {
457 477  
458 478 //add new intervals
459 479 foreach ($intervals as $interval)
460   - {
461   - $newInterval = $this->objectDom->createElement('intervals');
462   - $newInterval->appendChild($this->objectDom->createElement('start',$interval->start));
463   - $newInterval->appendChild($this->objectDom->createElement('stop',$interval->stop));
464   - $this->objectDom->documentElement->appendChild($newInterval);
  480 + {
  481 + $newInterval = $this-> createIntervalElement($interval);
  482 + $this->objectDom->documentElement->appendChild($newInterval);
465 483 }
466 484  
467 485 //save modifications
... ... @@ -751,7 +769,7 @@ class TimeTableMgr extends AmdaObjectMgr {
751 769  
752 770 $transform = "xsl2".$obj->fileformat;
753 771 $format = $obj->timeformat;
754   -// shared or my
  772 + // shared or my
755 773  
756 774  
757 775 for ($i=0; $i < count($obj->list); $i++) {
... ...
php/config.php
... ... @@ -251,12 +251,12 @@ $API = array(
251 251 'len'=>2
252 252 // 'formHandler'=>true
253 253 ),
254   - 'compilParam' => array(
255   - 'len'=>1
256   - ),
257   - 'compilParamDelete' => array(
258   - 'len'=>1
259   - ),
  254 + 'compilParam' => array(
  255 + 'len'=>1
  256 + ),
  257 + 'compilParamDelete' => array(
  258 + 'len'=>1
  259 + ),
260 260 'killPlotRequest' =>array(
261 261 'len'=>1
262 262 ),
... ... @@ -268,43 +268,43 @@ $API = array(
268 268 ),
269 269 'loadTTIntervals'=>array(
270 270 'len'=>1
  271 + ),
  272 + 'saveTTCacheIntervalsInTT'=>array(
  273 + 'len'=>1
271 274 ),
272   - 'saveTTCacheIntervalsInTT'=>array(
273   - 'len'=>1
274   - ),
275   - 'initTTCache' => array (
276   - 'len'=>0
277   - ) ,
278   - 'initTTCacheFromTT' => array(
279   - 'len'=>2
280   - ),
281   - 'initTTCacheFromTmpObject' => array(
282   - 'len'=>2
283   - ),
284   - 'initTTCacheFromUploadedFile' => array(
285   - 'len'=>2
286   - ),
287   - 'readTTCacheIntervals'=>array(
288   - 'len'=>1
289   - ),
290   - 'addTTCacheInterval'=>array (
291   - 'len'=>1
292   - ),
293   - 'removeTTCacheIntervalFromId'=>array (
294   - 'len'=>1
295   - ),
296   - 'modifyTTCacheInterval' => array(
297   - 'len'=>1
298   - ),
299   - 'operationTTCacheIntervals' => array(
300   - 'len'=>2
301   - ),
302   - 'mergeTTCacheIntervals' => array (
303   - 'len'=>0
304   - ),
305   - 'getTTCacheStatistics' => array (
306   - 'len'=>0
307   - ),
  275 + 'initTTCache' => array (
  276 + 'len'=>1
  277 + ) ,
  278 + 'initTTCacheFromTT' => array(
  279 + 'len'=>2
  280 + ),
  281 + 'initTTCacheFromTmpObject' => array(
  282 + 'len'=>3
  283 + ),
  284 + 'initTTCacheFromUploadedFile' => array(
  285 + 'len'=>2
  286 + ),
  287 + 'readTTCacheIntervals'=>array(
  288 + 'len'=>1
  289 + ),
  290 + 'addTTCacheInterval'=>array (
  291 + 'len'=>1
  292 + ),
  293 + 'removeTTCacheIntervalFromId'=>array (
  294 + 'len'=>2
  295 + ),
  296 + 'modifyTTCacheInterval' => array(
  297 + 'len'=>1
  298 + ),
  299 + 'operationTTCacheIntervals' => array(
  300 + 'len'=>2
  301 + ),
  302 + 'mergeTTCacheIntervals' => array (
  303 + 'len'=>0
  304 + ),
  305 + 'getTTCacheStatistics' => array (
  306 + 'len'=>0
  307 + ),
308 308 'sendFeedback'=>array(
309 309 'len'=>1
310 310 ),
... ... @@ -356,23 +356,23 @@ $API = array(
356 356 'getUserInfo'=>array(
357 357 'len'=>0
358 358 ),
359   - 'convertWS'=>array(
360   - 'len'=>0
361   - ),
362   - 'getRun'=>array(
363   - 'len'=>1
364   - ),
365   - 'addRun'=>array(
366   - 'len'=>1
367   - ),
368   - //AKKA - New action to clean user WS
369   - 'cleanUserWS'=>array(
370   - 'len'=>0
371   - ),
372   - 'deleteSpecialInfo'=>array(
373   - 'len'=>1
374   - )
375   - )
  359 + 'convertWS'=>array(
  360 + 'len'=>0
  361 + ),
  362 + 'getRun'=>array(
  363 + 'len'=>1
  364 + ),
  365 + 'addRun'=>array(
  366 + 'len'=>1
  367 + ),
  368 + //AKKA - New action to clean user WS
  369 + 'cleanUserWS'=>array(
  370 + 'len'=>0
  371 + ),
  372 + 'deleteSpecialInfo'=>array(
  373 + 'len'=>1
  374 + )
  375 + )
376 376 )
377 377 );
378 378 ?>
... ...