Commit d18b535dda83a475a400106be1382318be8509dd

Authored by elena
1 parent f792a3de

catalog draft + context menu small modifs

generic_data/jobs.json
@@ -3,14 +3,14 @@ @@ -3,14 +3,14 @@
3 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "resPlot-treeRootNode" }, 3 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "resPlot-treeRootNode" },
4 {"nodeType" : "bkgWorks","text" : "Download","id" : "resDown-treeRootNode"}, 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" : "Catalog","id" : "resCatalog-treeRootNode"} 6 + {"nodeType" : "bkgWorks","text" : "Statistics","id" : "resStatistics-treeRootNode"}
7 ] 7 ]
8 }, 8 },
9 {"nodeType" : "bkgWorks", "text" : "Jobs in Progress", "id" : "bkgjobs-treeRootNode", "children" : 9 {"nodeType" : "bkgWorks", "text" : "Jobs in Progress", "id" : "bkgjobs-treeRootNode", "children" :
10 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "bkgPlot-treeRootNode" }, 10 [{"nodeType" : "bkgWorks","text" : "Plot","id" : "bkgPlot-treeRootNode" },
11 {"nodeType" : "bkgWorks","text" : "Download","id" : "bkgDown-treeRootNode"}, 11 {"nodeType" : "bkgWorks","text" : "Download","id" : "bkgDown-treeRootNode"},
12 {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"}, 12 {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"},
13 - {"nodeType" : "bkgWorks","text" : "Catalog","id" : "bkgCatalog-treeRootNode"} 13 + {"nodeType" : "bkgWorks","text" : "Statistics","id" : "bkgStatistics-treeRootNode"}
14 ] 14 ]
15 } 15 }
16 ]} 16 ]}
js/app/AmdaApp.js
@@ -20,10 +20,17 @@ Ext.define('amdaApp.AmdaApp', { @@ -20,10 +20,17 @@ Ext.define('amdaApp.AmdaApp', {
20 ], 20 ],
21 21
22 dynamicModules: { 22 dynamicModules: {
  23 + statistics : {
  24 + id : 'statistics-win',
  25 + icon : 'icon-statistics',
  26 + title : 'Statistics',
  27 + source : 'amdaDesktop.StatisticsModule',
  28 + useLauncher : true
  29 + },
23 catalog : { 30 catalog : {
24 id : 'catalog-win', 31 id : 'catalog-win',
25 icon : 'icon-catalog', 32 icon : 'icon-catalog',
26 - title : 'Generate/Edit catalogs', 33 + title : 'Manage catalogs',
27 source : 'amdaDesktop.CatalogModule', 34 source : 'amdaDesktop.CatalogModule',
28 useLauncher : true 35 useLauncher : true
29 }, 36 },
@@ -275,12 +282,13 @@ Ext.define('amdaApp.AmdaApp', { @@ -275,12 +282,13 @@ Ext.define('amdaApp.AmdaApp', {
275 { name: 'Create/Modify parameter', iconCls: 'edit', module: 'param-win' }, 282 { name: 'Create/Modify parameter', iconCls: 'edit', module: 'param-win' },
276 { name: 'Plot data', iconCls: 'plot', module: 'plot-win'}, 283 { name: 'Plot data', iconCls: 'plot', module: 'plot-win'},
277 { name: 'Data mining', iconCls: 'search', module: 'search-win'}, 284 { name: 'Data mining', iconCls: 'search', module: 'search-win'},
  285 + { name: 'Statistics', iconCls: 'statistics', module: 'statistics-win'},
278 { name: 'Download data', iconCls: 'download_manager', module: 'down-win'}, 286 { name: 'Download data', iconCls: 'download_manager', module: 'down-win'},
279 { name: 'Upload data', iconCls: 'mydata', module: 'up-win'}, 287 { name: 'Upload data', iconCls: 'mydata', module: 'up-win'},
280 { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' }, 288 { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' },
281 { name: 'TimeTables operations', iconCls: 'operations', module: 'ttsOpe-win' }, 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 { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' } 292 { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' }
285 ] 293 ]
286 }), 294 }),
js/app/controllers/ExplorerModule.js
@@ -23,6 +23,7 @@ Ext.define('amdaDesktop.ExplorerModule', { @@ -23,6 +23,7 @@ Ext.define('amdaDesktop.ExplorerModule', {
23 'amdaModel.AliasNode', 23 'amdaModel.AliasNode',
24 'amdaModel.TimeTableNode', 24 'amdaModel.TimeTableNode',
25 'amdaModel.CatalogNode', 25 'amdaModel.CatalogNode',
  26 + 'amdaModel.StatisticsNode', // singleton; not shown in the tree
26 'amdaModel.sharedTimeTableNode', 27 'amdaModel.sharedTimeTableNode',
27 'amdaModel.MyDataParamNode', 28 'amdaModel.MyDataParamNode',
28 'amdaModel.MyDataNode', 29 'amdaModel.MyDataNode',
@@ -35,7 +36,8 @@ Ext.define('amdaDesktop.ExplorerModule', { @@ -35,7 +36,8 @@ Ext.define('amdaDesktop.ExplorerModule', {
35 'amdaModel.Plot', 36 'amdaModel.Plot',
36 'amdaModel.Download', 37 'amdaModel.Download',
37 'amdaModel.TimeTable', 38 'amdaModel.TimeTable',
38 - 'amdaModel.Catalog', 39 + 'amdaModel.Catalog',
  40 + 'amdaModel.Statistics',
39 'amdaModel.FileObject', 41 'amdaModel.FileObject',
40 'amdaModel.FileParamObject', 42 'amdaModel.FileParamObject',
41 'amdaModel.FilterInfo' 43 'amdaModel.FilterInfo'
js/app/controllers/StatisticsModule.js 0 โ†’ 100644
@@ -0,0 +1,45 @@ @@ -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
@@ -52,14 +52,7 @@ Ext.define('amdaModel.AliasNode', { @@ -52,14 +52,7 @@ Ext.define('amdaModel.AliasNode', {
52 52
53 return menuItems; 53 return menuItems;
54 }, 54 },
55 -  
56 - getAllContextMenuItems: function(){  
57 - return this.allMenuItems();  
58 - },  
59 -  
60 - getMultiContextMenuItems: function(){  
61 - return this.allMenuMultiItems(amdaModel.AliasNode.objectName);  
62 - }, 55 +
63 56
64 create: function(alias, param) { 57 create: function(alias, param) {
65 AmdaAction.createObject({name: alias, param: param, 58 AmdaAction.createObject({name: alias, param: param,
js/app/models/BkgJobNode.js
@@ -6,11 +6,6 @@ @@ -6,11 +6,6 @@
6 * @brief Basic Model of Node corresponding to Amda processes in background 6 * @brief Basic Model of Node corresponding to Amda processes in background
7 * @author elena 7 * @author elena
8 * @version $Id: BkgJobNode.js 1963 2013-12-06 17:50:37Z elena $ 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 Ext.define('amdaModel.BkgJobNode', { 11 Ext.define('amdaModel.BkgJobNode', {
@@ -25,19 +20,19 @@ Ext.define('amdaModel.BkgJobNode', { @@ -25,19 +20,19 @@ Ext.define('amdaModel.BkgJobNode', {
25 PLOT: 'request',//'plot', 20 PLOT: 'request',//'plot',
26 CONDITION: 'condition', 21 CONDITION: 'condition',
27 DOWNLOAD: 'download', 22 DOWNLOAD: 'download',
28 - CATALOG: 'catalog' 23 + STATISTICS: 'statistics'
29 }, 24 },
30 JOB_ROOT_NODE: { 25 JOB_ROOT_NODE: {
31 PLOT: 'bkgPlot-treeRootNode', 26 PLOT: 'bkgPlot-treeRootNode',
32 CONDITION: 'bkgSearch-treeRootNode', 27 CONDITION: 'bkgSearch-treeRootNode',
33 DOWNLOAD: 'bkgDown-treeRootNode', 28 DOWNLOAD: 'bkgDown-treeRootNode',
34 - CATALOG: 'bkgCatalog-treeRootNode' 29 + STATISTICS: 'bkgStatistics-treeRootNode'
35 }, 30 },
36 RES_ROOT_NODE: { 31 RES_ROOT_NODE: {
37 PLOT: 'resPlot-treeRootNode', 32 PLOT: 'resPlot-treeRootNode',
38 CONDITION: 'resSearch-treeRootNode', 33 CONDITION: 'resSearch-treeRootNode',
39 DOWNLOAD: 'resDown-treeRootNode', 34 DOWNLOAD: 'resDown-treeRootNode',
40 - CATALOG: 'resCatalog-treeRootNode' 35 + STATISTICS: 'resStatistics-treeRootNode'
41 }, 36 },
42 STATUS_LIST: { 37 STATUS_LIST: {
43 IN_PROGRESS: 'in_progress', 38 IN_PROGRESS: 'in_progress',
@@ -225,12 +220,18 @@ Ext.define('amdaModel.BkgJobNode', { @@ -225,12 +220,18 @@ Ext.define('amdaModel.BkgJobNode', {
225 var obj = null; 220 var obj = null;
226 switch (this.get('jobType')) 221 switch (this.get('jobType'))
227 { 222 {
228 - case 'condition' : 223 + case 'condition' :
229 obj = Ext.create('amdaModel.Search', 224 obj = Ext.create('amdaModel.Search',
230 {name: result.name, 225 {name: result.name,
231 resultId : result.result, 226 resultId : result.result,
232 folderId : result.folder}); 227 folderId : result.folder});
233 break; 228 break;
  229 + case 'statistics' :
  230 + obj = Ext.create('amdaModel.Statistics',
  231 + {name: result.name,
  232 + resultId : result.result,
  233 + folderId : result.folder});
  234 + break;
234 case 'request' : 235 case 'request' :
235 obj = Ext.create('amdaModel.Plot', 236 obj = Ext.create('amdaModel.Plot',
236 {name: result.name, format: result.format, 237 {name: result.name, format: result.format,
@@ -355,8 +356,8 @@ Ext.define('amdaModel.BkgJobNode', { @@ -355,8 +356,8 @@ Ext.define('amdaModel.BkgJobNode', {
355 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: 356 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD:
356 rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.DOWNLOAD; 357 rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.DOWNLOAD;
357 break; 358 break;
358 - case amdaModel.BkgJobNode.JOB_TYPES.CATALOG:  
359 - rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.CATALOG; 359 + case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS:
  360 + rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.STATISTICS;
360 break; 361 break;
361 default: 362 default:
362 break; 363 break;
@@ -373,8 +374,8 @@ Ext.define('amdaModel.BkgJobNode', { @@ -373,8 +374,8 @@ Ext.define('amdaModel.BkgJobNode', {
373 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: 374 case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD:
374 rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.DOWNLOAD; 375 rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.DOWNLOAD;
375 break; 376 break;
376 - case amdaModel.BkgJobNode.JOB_TYPES.CATALOG:  
377 - rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.CATALOG; 377 + case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS:
  378 + rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.STATISTICS;
378 break; 379 break;
379 default: 380 default:
380 break; 381 break;
js/app/models/Catalog.js
@@ -14,9 +14,7 @@ Ext.define('amdaModel.Catalog', { @@ -14,9 +14,7 @@ Ext.define('amdaModel.Catalog', {
14 extend: 'amdaModel.TimeTable', 14 extend: 'amdaModel.TimeTable',
15 15
16 fields : [ 16 fields : [
17 - { name: 'parameter' },  
18 - { name: 'timeTables' }//,  
19 -// { name: 'timesrc', type: 'string', defaultValue : "TimeTable" } 17 + { name: 'parameters' }
20 ], 18 ],
21 19
22 getJsonValues : function (hasId) { 20 getJsonValues : function (hasId) {
@@ -25,7 +23,7 @@ Ext.define('amdaModel.Catalog', { @@ -25,7 +23,7 @@ Ext.define('amdaModel.Catalog', {
25 values.id = this.get('id'); 23 values.id = this.get('id');
26 } 24 }
27 25
28 - values.timesrc = 'TimeTable'; 26 + values.timesrc = this.get('timesrc');
29 values.name = this.get('name'); 27 values.name = this.get('name');
30 values.created = this.get('created'); 28 values.created = this.get('created');
31 29
@@ -40,8 +38,7 @@ Ext.define('amdaModel.Catalog', { @@ -40,8 +38,7 @@ Ext.define('amdaModel.Catalog', {
40 values.folderId = this.get('folderId'); 38 values.folderId = this.get('folderId');
41 values.nbIntervals = this.get('nbIntervals'); 39 values.nbIntervals = this.get('nbIntervals');
42 values.cacheToken = this.get('cacheToken'); 40 values.cacheToken = this.get('cacheToken');
43 - values.parameter = this.get('parameter');  
44 - values.timeTables = this.get('timetable'); 41 + values.parameters = this.get('parameters');
45 values.leaf = true; 42 values.leaf = true;
46 values.nodeType = amdaModel.CatalogNode.nodeType; 43 values.nodeType = amdaModel.CatalogNode.nodeType;
47 return values; 44 return values;
js/app/models/CatalogNode.js
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 9
10 Ext.define('amdaModel.CatalogNode', { 10 Ext.define('amdaModel.CatalogNode', {
11 11
12 - extend: 'amdaModel.ExecutableNode', 12 + extend: 'amdaModel.TimeTableNode',
13 13
14 statics: { 14 statics: {
15 nodeType: 'catalog', 15 nodeType: 'catalog',
@@ -23,6 +23,45 @@ Ext.define('amdaModel.CatalogNode', { @@ -23,6 +23,45 @@ Ext.define('amdaModel.CatalogNode', {
23 this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); 23 this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
24 this.set('objectDataModel',amdaModel.Catalog.$className); 24 this.set('objectDataModel',amdaModel.Catalog.$className);
25 if (this.get('leaf')) this.set('iconCls', 'icon-catalog'); 25 if (this.get('leaf')) this.set('iconCls', 'icon-catalog');
  26 + },
  27 +
  28 + localMenuItems : function() {
  29 + var menuItems =
  30 + [/*{
  31 + fnId : 'dire-shareNode',
  32 + text : 'Share content',
  33 + hidden : true
  34 + },{
  35 + fnId : 'leaf-shareLeaf',
  36 + text : 'Share '+this.self.objectName,
  37 + hidden : true
  38 + },*/{
  39 + fnId : 'leaf-download',
  40 + text : 'Download '+ this.self.objectName,
  41 + hidden : true
  42 + }/*,{
  43 + fnId : 'leaf-operations',
  44 + text : 'Operations',
  45 + hidden : true
  46 + }*/];
  47 +
  48 + return menuItems;
  49 + },
  50 +
  51 + localMultiMenuItems : function() {
  52 + var menuItems =
  53 + [/*{
  54 + fnId : 'mult-shareMulti',
  55 + text : 'Share selected '+this.self.objectName+'s'
  56 + },*/{
  57 + fnId : 'mult-downloadMulti',
  58 + text : 'Download selected '+this.self.objectName+'s'
  59 + }/*,{
  60 + fnId : 'mult-operationsMulti',
  61 + text : 'Operations'
  62 + }*/];
  63 +
  64 + return menuItems;
26 } 65 }
27 - 66 +
28 }); 67 });
js/app/models/DerivedParamNode.js
@@ -53,15 +53,11 @@ Ext.define('amdaModel.DerivedParamNode', { @@ -53,15 +53,11 @@ Ext.define('amdaModel.DerivedParamNode', {
53 53
54 getAllContextMenuItems: function(){ 54 getAllContextMenuItems: function(){
55 55
56 - var menuItems = this.allMenuItems(amdaModel.DerivedParamNode.objectName); 56 + var menuItems = this.allMenuItems();
57 var locMenuItems = this.localMenuItems(); 57 var locMenuItems = this.localMenuItems();
58 58
59 return Ext.Array.merge(menuItems,locMenuItems); 59 return Ext.Array.merge(menuItems,locMenuItems);
60 - },  
61 -  
62 - getMultiContextMenuItems: function(){  
63 - return this.allMenuMultiItems(amdaModel.DerivedParamNode.objectName);  
64 - }, 60 + },
65 61
66 isParameter : function(){ 62 isParameter : function(){
67 return this.get('isParameter'); 63 return this.get('isParameter');
js/app/models/InteractiveNode.js
@@ -369,7 +369,8 @@ Ext.define('amdaModel.InteractiveNode', { @@ -369,7 +369,8 @@ Ext.define('amdaModel.InteractiveNode', {
369 * Generic part of Context Menu 369 * Generic part of Context Menu
370 * 370 *
371 */ 371 */
372 - allMenuItems : function(src) { 372 + allMenuItems : function() {
  373 + var src = this.self.objectName;
373 var menuItems = 374 var menuItems =
374 [ { 375 [ {
375 fnId : 'root-createLeaf', 376 fnId : 'root-createLeaf',
@@ -402,16 +403,24 @@ Ext.define('amdaModel.InteractiveNode', { @@ -402,16 +403,24 @@ Ext.define('amdaModel.InteractiveNode', {
402 return menuItems; 403 return menuItems;
403 }, 404 },
404 405
405 - allMenuMultiItems : function(src) { 406 + allMenuMultiItems : function() {
406 var menuMulti = [ 407 var menuMulti = [
407 { 408 {
408 fnId : 'mult-deleteMulti', 409 fnId : 'mult-deleteMulti',
409 - text : 'Delete selected '+ src+'s' 410 + text : 'Delete selected ' + this.self.objectName + 's'
410 } 411 }
411 ]; 412 ];
412 return menuMulti; 413 return menuMulti;
413 }, 414 },
414 415
  416 + getAllContextMenuItems: function(){
  417 + return this.allMenuItems();
  418 + },
  419 +
  420 + getMultiContextMenuItems: function(){
  421 + return this.allMenuMultiItems();
  422 + },
  423 +
415 /** 424 /**
416 * default implementation 425 * default implementation
417 * no menu display if there's no override of this function 426 * no menu display if there's no override of this function
js/app/models/LocalParamNode.js
@@ -126,11 +126,7 @@ Ext.define('amdaModel.LocalParamNode', @@ -126,11 +126,7 @@ Ext.define('amdaModel.LocalParamNode',
126 return menuItems; 126 return menuItems;
127 }, 127 },
128 128
129 - getAllContextMenuItems: function()  
130 - {  
131 - return this.allMenuItems();  
132 - },  
133 - 129 +
134 onMenuItemClick : function(menu,item,event) 130 onMenuItemClick : function(menu,item,event)
135 { 131 {
136 switch (item.fnId) 132 switch (item.fnId)
js/app/models/MyDataParamNode.js
@@ -23,7 +23,8 @@ Ext.define('amdaModel.MyDataParamNode', { @@ -23,7 +23,8 @@ Ext.define('amdaModel.MyDataParamNode', {
23 ], 23 ],
24 24
25 statics:{ 25 statics:{
26 - nodeType: 'myDataParam' 26 + nodeType: 'myDataParam',
  27 + objectName : 'Parameter'
27 }, 28 },
28 29
29 constructor : function(config){ 30 constructor : function(config){
@@ -75,12 +76,8 @@ Ext.define('amdaModel.MyDataParamNode', { @@ -75,12 +76,8 @@ Ext.define('amdaModel.MyDataParamNode', {
75 return menuItems; 76 return menuItems;
76 }, 77 },
77 78
78 - getAllContextMenuItems: function(){  
79 -  
80 - var menuItems = this.allMenuItems('Parameter');  
81 - var locMenuItems = this.localMenuItems();  
82 -  
83 - return Ext.Array.merge(menuItems,locMenuItems); 79 + getAllContextMenuItems: function(){
  80 + return this.localMenuItems();
84 }, 81 },
85 82
86 onMenuItemClick : function(menu,item,event) { 83 onMenuItemClick : function(menu,item,event) {
js/app/models/PlotNode.js
@@ -72,14 +72,7 @@ Ext.define('amdaModel.PlotNode', { @@ -72,14 +72,7 @@ Ext.define('amdaModel.PlotNode', {
72 return menuMulti; 72 return menuMulti;
73 }, 73 },
74 74
75 - getAllContextMenuItems: function(){  
76 - return this.allMenuItems();  
77 - },  
78 -  
79 - getMultiContextMenuItems: function(){  
80 - return this.allMenuMultiItems();  
81 - },  
82 - 75 +
83 onMenuItemClick : function(menu,item,event) { 76 onMenuItemClick : function(menu,item,event) {
84 // fnId parsing : 77 // fnId parsing :
85 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); 78 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
js/app/models/SearchNode.js
@@ -70,14 +70,7 @@ Ext.define('amdaModel.SearchNode', { @@ -70,14 +70,7 @@ Ext.define('amdaModel.SearchNode', {
70 return menuMulti; 70 return menuMulti;
71 }, 71 },
72 72
73 - getAllContextMenuItems: function(){  
74 - return this.allMenuItems();  
75 - },  
76 -  
77 - getMultiContextMenuItems: function(){  
78 - return this.allMenuMultiItems();  
79 - },  
80 - 73 +
81 onMenuItemClick : function(menu,item,event) { 74 onMenuItemClick : function(menu,item,event) {
82 // fnId parsing : 75 // fnId parsing :
83 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); 76 var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
js/app/models/Statistics.js 0 โ†’ 100644
@@ -0,0 +1,75 @@ @@ -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 \ No newline at end of file 76 \ No newline at end of file
js/app/models/StatisticsNode.js 0 โ†’ 100644
@@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : StatisticsNode.js
  4 + * @class amdaModel.StatisticsNode
  5 + * @extends amdaModel.TimeTableNode
  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 +
  17 + fields: [ {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 + isExecutable: function(){
  27 + return true;
  28 + }
  29 + /*,
  30 +
  31 + constructor : function(config){//
  32 + this.callParent(arguments);
  33 + this.set('nodeType',amdaModel.StatisticsNode.nodeType);
  34 + this.set('moduleId',myDesktopApp.dynamicModules.statistics.id);
  35 + this.set('ownerTreeId',amdaUI.ExplorerUI.OPE_TAB.TREE_ID);
  36 + this.set('objectDataModel',amdaModel.Statistics.$className);
  37 +// if (this.get('leaf')) this.set('iconCls', 'icon-catalog');
  38 + }
  39 + */
  40 +});
js/app/models/TimeTableNode.js
@@ -60,10 +60,10 @@ Ext.define('amdaModel.TimeTableNode', { @@ -60,10 +60,10 @@ Ext.define('amdaModel.TimeTableNode', {
60 var menuItems = 60 var menuItems =
61 [/*{ 61 [/*{
62 fnId : 'mult-shareMulti', 62 fnId : 'mult-shareMulti',
63 - text : 'Share selected '+amdaModel.TimeTableNode.objectName+'s' 63 + text : 'Share selected '+this.self.objectName+'s'
64 },*/{ 64 },*/{
65 fnId : 'mult-downloadMulti', 65 fnId : 'mult-downloadMulti',
66 - text : 'Download selected '+amdaModel.TimeTableNode.objectName+'s' 66 + text : 'Download selected '+this.self.objectName+'s'
67 },{ 67 },{
68 fnId : 'mult-operationsMulti', 68 fnId : 'mult-operationsMulti',
69 text : 'Operations' 69 text : 'Operations'
@@ -73,18 +73,21 @@ Ext.define('amdaModel.TimeTableNode', { @@ -73,18 +73,21 @@ Ext.define('amdaModel.TimeTableNode', {
73 }, 73 },
74 74
75 getAllContextMenuItems: function(){ 75 getAllContextMenuItems: function(){
76 -  
77 - var menuItems = this.allMenuItems(amdaModel.TimeTableNode.objectName); 76 +
  77 + var menuItems = this.allMenuItems();
78 var locMenuItems = this.localMenuItems(); 78 var locMenuItems = this.localMenuItems();
79 - return Ext.Array.merge(menuItems,locMenuItems); 79 +
  80 + return Ext.Array.merge(menuItems,locMenuItems);
80 }, 81 },
81 82
82 - getMultiContextMenuItems: function(){  
83 - var multiMenu = this.allMenuMultiItems(amdaModel.TimeTableNode.objectName);  
84 - var locMultiMenuItems = this.localMultiMenuItems();  
85 - return Ext.Array.merge(multiMenu,locMultiMenuItems); 83 + getMultiContextMenuItems: function(){
  84 +
  85 + var menuItems = this.allMenuMultiItems();
  86 + var locMenuItems = this.localMultiMenuItems();
  87 +
  88 + return Ext.Array.merge(menuItems,locMenuItems);
86 }, 89 },
87 - 90 +
88 onMenuItemClick : function(menu,item,event) { 91 onMenuItemClick : function(menu,item,event) {
89 92
90 this.callParent(arguments); 93 this.callParent(arguments);
js/app/views/CatalogUI.js
@@ -10,103 +10,255 @@ @@ -10,103 +10,255 @@
10 Ext.define('amdaUI.CatalogUI', { 10 Ext.define('amdaUI.CatalogUI', {
11 extend: 'Ext.container.Container', 11 extend: 'Ext.container.Container',
12 alias: 'widget.panelCatalog', 12 alias: 'widget.panelCatalog',
  13 +
  14 + isCatalog : true,
13 15
14 - requires : [  
15 -// 'amdaModel.Function'  
16 - ],  
17 -  
18 - statics : {  
19 -// functionStore : null  
20 - },  
21 -  
22 constructor: function(config) { 16 constructor: function(config) {
23 - this.init(config);  
24 - this.callParent(arguments);  
25 - // if (this.object) this.loadObject(); 17 + this.init(config);
  18 + this.callParent(arguments);;
  19 + if (this.object) this.loadObject();
26 }, 20 },
27 21
28 - addParam : function(ParamName,isLeaf)  
29 - {  
30 - var r = Ext.create('amdaModel.AmdaObject', { name: ParamName });  
31 - this.paramGrid.getStore().add(r);  
32 - this.paramGrid.getSelectionModel().select(this.paramGrid.getStore().getCount()-1);  
33 - },  
34 22
35 - addTT : function(TTname,TTid)  
36 - {  
37 - Ext.define('tempObject', {  
38 - extend: 'Ext.data.Model',  
39 - fields: [  
40 - {name: 'name', type: 'string'},  
41 - {name: 'hidden_id', type: 'string'}  
42 - ]});  
43 - var r = Ext.create('tempObject', { name:TTname, hidden_id : TTid });  
44 - this.ttGrid.getStore().add(r);  
45 - this.ttGrid.getSelectionModel().select(this.paramGrid.getStore().getCount()-1);  
46 -  
47 - },  
48 -  
49 - generateCatalog : function(){  
50 - var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);  
51 - if (module)  
52 - module.linkedNode.execute(); 23 + /**
  24 + * set params description into this.object
  25 + */
  26 + setParamInfo : function(parameters) {
  27 +
  28 + var params = [];
  29 + Ext.Array.each(parameters, function(item, index) {
  30 + params[index] = item;
  31 + }, this);
  32 +
  33 + this.object.set('parameters', params);
  34 +
53 }, 35 },
54 36
55 /** 37 /**
56 * update this.object from form 38 * update this.object from form
57 - */ 39 + */
  40 + updateObject : function(){
  41 + // get the basic form
  42 + var basicForm = this.formPanel.getForm();
  43 + var updateStatus = true;
  44 +
  45 + var fieldsWithoutName = basicForm.getFields().items;
  46 + Ext.Array.each(fieldsWithoutName, function(item, index,allItems){
  47 + if(item !== this.fieldName) {
  48 + if (!item.isValid()) {
  49 + // set update isn't allowed
  50 + updateStatus = false;
  51 + }
  52 + }
  53 + }, this);
  54 + // if the update is allowed
  55 + if (updateStatus) {
  56 + /// real object update
  57 + // update TimeTable object with the content of form
  58 + basicForm.updateRecord(this.object);
  59 + }
  60 + // return the update status
  61 + return updateStatus;
  62 + },
58 63
59 - updateObject : function(){  
60 - // get the basic form of the left  
61 - var basicForm = this.formPanel.items.items[0].getForm();  
62 -  
63 - var formValues = basicForm.getValues();  
64 - this.object.set('name',formValues.name);  
65 - this.object.set('description',formValues.description);  
66 -  
67 - var recs = this.paramGrid.getStore().getNewRecords();  
68 - var paramArr = new Array();  
69 - Ext.Array.each(recs, function(rec, index,allItems){  
70 - var obj = new Object();  
71 - obj.param = rec.get('name');  
72 - obj.function = rec.get('function');  
73 - paramArr.push(obj);  
74 - });  
75 - this.object.set('parameter', paramArr); 64 +
  65 + updateCount : function() {
  66 + this.object.set('nbIntervals',this.TTGrid.getStore().getTotalCount());
  67 + this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals'));
  68 + },
  69 +
  70 + /**
  71 + * load object catalog into this view
  72 + */
  73 + loadObject : function(){
  74 + // load object into form
  75 + this.formPanel.getForm().loadRecord(this.object);
  76 +
  77 + this.status = null;
  78 +
  79 + var me = this;
  80 +
  81 + var onAfterInit = function(result, e) {
  82 +
  83 + if (!result || !result.success)
  84 + {
  85 + if (result.message)
  86 + myDesktopApp.errorMsg(result.message);
  87 + else
  88 + myDesktopApp.errorMsg('Unknown error during catalog cache initialisation');
  89 + return;
  90 + }
  91 +
  92 +
  93 + var fields = [], columns = [], i = 2, width, index;
76 94
77 - // hidden_id - if real 'id' - getNewRecords (and other getRecords) methods doesn't work  
78 - var tts = this.ttGrid.getStore().getNewRecords();  
79 - var ttArr = new Array();  
80 - Ext.Array.each(tts, function(rec, index, allItems){  
81 - var obj = new Object();  
82 - obj.id = rec.get('hidden_id');  
83 - ttArr.push(obj);  
84 - });  
85 - this.object.set('timetable', ttArr); 95 + fields[0] = Ext.create('Ext.data.Field',{ name : 'start' });
  96 + fields[1] = Ext.create('Ext.data.Field',{ name : 'stop' });
  97 +
  98 + columns[0] = Ext.create('Ext.grid.column.RowNumberer');
86 99
87 - var updateStatus = true; 100 + columns[1] = Ext.create('Ext.grid.column.Column', { text: 'Start Time', sortable : false, dataIndex: 'start',
  101 + width : 120, menuDisabled: true });
  102 + columns[2] = Ext.create('Ext.grid.column.Column', { text: 'Stop Time', sortable : false, dataIndex: 'stop',
  103 + width : 120, menuDisabled: true });
88 104
89 - return updateStatus; 105 + Ext.Array.each(result.parameters, function(obj) {
  106 + index = 'param'+i.toString();
  107 + fields[i] = Ext.create('Ext.data.Field',{ name : index });
  108 + width = 50. * parseInt(obj.size);
  109 + columns[i+1] = Ext.create('Ext.grid.column.Column', { text: obj.name, sortable : false, dataIndex: index,
  110 + width : width, menuDisabled: true });
  111 + i++;
  112 + });
  113 +
  114 +
  115 + var store = Ext.create('Ext.data.Store', {
  116 + fields: fields,
  117 + autoDestroy: false,
  118 + pageSize : 200,
  119 + buffered : true,
  120 + purgePageCount: 0,
  121 + remoteSort: true,
  122 + proxy: {
  123 + type: 'direct',
  124 + api :
  125 + {
  126 + read : AmdaAction.readTTCacheIntervals
  127 + },
  128 + // remplir automatiquement tt, sharedtt , catalog, shared catalog
  129 + extraParams : {'typeTT' : 'catalog'},
  130 + reader:
  131 + {
  132 + type: 'json',
  133 + root: 'intervals',
  134 + totalProperty : 'totalCount'
  135 + }
  136 + },
  137 + listeners: {
  138 + scope : me,
  139 + load: function(store,records) {
  140 + // myDesktopApp.EventManager.fireEvent('refresh');
  141 + me.TTGrid.getView().refresh();
  142 + me.TTGrid.getSelectionModel().refresh();
  143 + me.updateCount();
  144 + //Statistical plugin
  145 + // this.fireEvent("refresh");
  146 + }
  147 + }
  148 + });
  149 +
  150 + me.TTGrid.reconfigure(store, columns);
  151 +
  152 +//
  153 +// me.TTGrid.getSelectionModel().deselectAll();
  154 +//
  155 +// // clear filters
  156 +// me.TTGrid.getStore().clearFilter(true);
  157 +//
  158 +// //clear sort
  159 +// me.TTGrid.getStore().sorters.clear();
  160 +// //me.TTGrid.getStore().sorters = new Ext.util.MixedCollection();
  161 +//
  162 + //set cache token to the Catalog object
  163 + me.object.set('cacheToken', result.token);
  164 + me.setParamInfo(result.parameters);
  165 +
  166 + me.TTGrid.getStore().load();
  167 +
  168 + me.status = result.status;
  169 +
  170 + };
  171 +
  172 + if (this.object.get('fromPlugin'))
  173 + {
  174 + if (this.object.get('objFormat') && this.object.get('objFormat') != '')
  175 + {
  176 + //From uploaded file
  177 + //AmdaAction.initTTCacheFromUploadedFile(this.object.get('objName'), this.object.get('objFormat'), onAfterInit);
  178 + }
  179 + else
  180 + {
  181 + //From tmp object (ie Search result)
  182 + AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, onAfterInit);
  183 + }
  184 + }
  185 + else
  186 + {
  187 + var typeTT = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.tt.id).linkedNode.data.nodeType;
  188 + if (this.object.get('id') == '')
  189 + {
  190 + //Init empty cache
  191 + //AmdaAction.initTTCache(onAfterInit);
  192 + }
  193 + else
  194 + {
  195 + //From existing TT file
  196 + //AmdaAction.initTTCacheFromTT(this.object.get('id'), typeTT, onAfterInit);
  197 + }
  198 + }
  199 + },
  200 + checkIntervalsStatusForSave : function(onStatusOk) {
  201 + onStatusOk();
  202 + },
  203 +
  204 + /*
  205 + * save method called by Save button
  206 + */
  207 + saveProcess : function(toRename){
  208 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);
  209 +
  210 + // if the name has been modified this is a creation
  211 + if (this.fclose()) {
  212 +
  213 + if (this.object.isModified('name') || this.object.get('fromPlugin')) {
  214 +
  215 + // if object already has an id : it's a 'rename' of an existing
  216 + if (this.object.get('id')){
  217 + // the context Node is the parent node of current edited one
  218 + var contextNode = module.linkedNode.parentNode;
  219 + // link a new node to the TimeTableModule
  220 + module.createLinkedNode();
  221 + // set the contextNode
  222 + module.linkedNode.set('contextNode',contextNode);
  223 + // create a new object linked
  224 + module.createObject(this.object.getJsonValues());
  225 +
  226 + var obj = module.linkedNode.get('object');
  227 + // synchronisation of objects
  228 + this.object = obj;
  229 + if (toRename) module.linkedNode.toRename = true;
  230 + }
  231 + module.linkedNode.create({callback : function() {module.linkedNode.update();}, scope : this});
  232 + } else {
  233 + //update
  234 + module.linkedNode.update();
  235 + }
  236 + }
90 }, 237 },
91 238
  239 + /**
  240 + * Check if changes were made before closing window
  241 + * @return true if changes
  242 + */
  243 + fclose : function() {
  244 + if (this.status == null)
  245 + return false;
  246 +
  247 + var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0);
  248 + return isDirty;
  249 + },
  250 +
  251 +
92 init : function (config) { 252 init : function (config) {
93 253
94 -// var functions = Ext.create('Ext.data.Store', {  
95 -// fields: ['id', 'name'],  
96 -// data : [  
97 -// {"id":"min", "name":"MIN"},  
98 -// {"id":"max", "name":"MAX"},  
99 -// {"id":"mean","name":"MEAN"}  
100 -// ]  
101 -// });  
102 - 254 + this.object = config.object;
  255 +
103 this.fieldName = new Ext.form.field.Text({ 256 this.fieldName = new Ext.form.field.Text({
104 - fieldLabel: 'Name*', 257 + fieldLabel: 'Name',
105 allowBlank : false, 258 allowBlank : false,
106 stripCharsRe: /(^\s+|\s+$)/g, 259 stripCharsRe: /(^\s+|\s+$)/g,
107 emptyText: 'Please no spaces!', 260 emptyText: 'Please no spaces!',
108 name: 'name', 261 name: 'name',
109 - anchor: '100%',  
110 validateOnChange: false, 262 validateOnChange: false,
111 validateOnBlur: false, 263 validateOnBlur: false,
112 validFlag: false, 264 validFlag: false,
@@ -115,209 +267,78 @@ Ext.define('amdaUI.CatalogUI', { @@ -115,209 +267,78 @@ Ext.define('amdaUI.CatalogUI', {
115 } 267 }
116 }); 268 });
117 269
118 - var ttStore = Ext.create('Ext.data.Store',  
119 - {  
120 - fields: [ 'name', 'hidden_id']  
121 - });  
122 -  
123 - this.ttGrid = Ext.create('Ext.grid.Panel', {  
124 - title: 'Select Time Table',  
125 - height: 100,  
126 - store : ttStore,  
127 - columns: [  
128 - { xtype: 'rownumberer' },  
129 - { header: "Time Table Name", dataIndex: 'name', flex:1, sortable : false, menuDisabled: true },  
130 - { menuDisabled: true, width: 30, renderer: function()  
131 - {  
132 - return '<div class="icon-remover" style="width: 15px; height: 15px;"></div>';  
133 - }  
134 - }  
135 - ],  
136 - listeners : {  
137 - render : function(o,op) {  
138 - var me = this;  
139 - var el = me.getEl();  
140 - var dropTarget = Ext.create('Ext.dd.DropTarget', el, {  
141 - ddGroup: 'explorerTree',  
142 - notifyOver : function(ddSource, e, data)  
143 - {  
144 - if ((data.records[0].get('nodeType') == 'timeTable' || data.records[0].get('nodeType') == 'sharedtimeTable') && (data.records[0].get('leaf')))  
145 - {  
146 - this.valid = true;  
147 - return this.dropAllowed;  
148 - }  
149 - this.valid = false;  
150 - return this.dropNotAllowed;  
151 - },  
152 - notifyDrop : function(ddSource, e, data)  
153 - {  
154 - if (!this.valid) return false;  
155 -  
156 - var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);  
157 - if (module)  
158 - {  
159 - module.getUiContent().addTT(data.records[0].get('text'),data.records[0].get('id'));  
160 - }  
161 - return true;  
162 - }  
163 - });  
164 - },  
165 -  
166 - cellclick : function(grid, cell, cellIndex, record){  
167 - if (cellIndex == 2)  
168 - grid.getStore().remove(record);  
169 - }  
170 - }  
171 - });  
172 -  
173 - var store = Ext.create('Ext.data.Store',  
174 - {  
175 - fields: ['name', 'function']  
176 - });  
177 -  
178 - this.paramGrid = Ext.create('Ext.grid.Panel', {  
179 - title: 'Select Parameter & Apply Function',  
180 - selType : 'rowmodel',  
181 - height: 200,  
182 - store : store,  
183 - columns: [  
184 - { xtype: 'rownumberer' },  
185 - { header: 'parameter', dataIndex: 'name', menuDisabled : true, sortable : false },  
186 - { header: 'function', dataIndex: 'function', menuDisabled : true, sortable : false,  
187 - editor: {  
188 - xtype: 'combo', queryMode : 'local',  
189 -// emptyText : 'please click to select function',  
190 - store: [ 'min', 'max', 'mean' ],  
191 - triggerAction: 'all',  
192 -// lazyInit: false,  
193 - listeners: {  
194 - focus: function(obj) {  
195 - obj.expand();  
196 - }  
197 - }  
198 - },  
199 - renderer: function(v)  
200 - {  
201 - if(v != null && v.length > 0 )  
202 - return v;  
203 - else  
204 - return 'click to select';  
205 - }  
206 - },  
207 - { menuDisabled : true, width: 30, renderer: function(){  
208 - return '<div class="icon-remover" style="width: 15px; height: 15px;"></div>';  
209 - }  
210 - }  
211 - ],  
212 - plugins: [  
213 - Ext.create('Ext.grid.plugin.CellEditing', {  
214 - clicksToEdit: 1  
215 - })  
216 - ],  
217 - listeners :  
218 - {  
219 - render : function(o,op)  
220 - {  
221 - var me = this;  
222 - var el = me.body.dom;  
223 - var dropTarget = Ext.create('Ext.dd.DropTarget', el, {  
224 - ddGroup: 'explorerTree',  
225 - notifyOver : function(ddSource, e, data)  
226 - {  
227 - if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet')) {  
228 - this.valid = false;  
229 - return this.dropNotAllowed;  
230 - }  
231 - if (((data.records[0].data.nodeType == 'localParam') ||  
232 - (data.records[0].data.nodeType == 'remoteParam') ||  
233 - (data.records[0].data.nodeType == 'remoteSimuParam') ||  
234 - (data.records[0].data.nodeType == 'derivedParam') ||  
235 - (data.records[0].data.nodeType == 'myDataParam') ||  
236 - (data.records[0].data.nodeType == 'alias'))&&  
237 - (data.records[0].isLeaf() || data.records[0].data.isParameter) &&  
238 - !data.records[0].data.disable)  
239 - {  
240 - this.valid = true;  
241 - return this.dropAllowed;  
242 - }  
243 -  
244 - this.valid = false;  
245 - return this.dropNotAllowed;  
246 - },  
247 - notifyDrop : function(ddSource, e, data)  
248 - {  
249 - if (!this.valid)  
250 - return false;  
251 - var nameToSent;  
252 - switch (data.records[0].data.nodeType)  
253 - {  
254 - case 'localParam' :  
255 - case 'remoteParam':  
256 - case 'remoteSimuParam':  
257 - nameToSent = data.records[0].get('id');  
258 - if (data.records[0].get('alias')!= "" )  
259 - var nameToSent = "#"+data.records[0].get('alias');  
260 - break;  
261 - case 'alias' :  
262 - nameToSent = "#"+data.records[0].get('text');  
263 - break;  
264 - case 'derivedParam' :  
265 - nameToSent = "ws_"+data.records[0].get('text');  
266 - break;  
267 - case 'myDataParam' :  
268 - nameToSent = "wsd_"+data.records[0].get('text');  
269 - break;  
270 - default :  
271 - return false;  
272 - }  
273 - var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);  
274 - if (module)  
275 - {  
276 - if (data.records[0].get('needsArgs') && !data.records[0].get('isSpectra')) {  
277 - module.getUiContent().fireEvent('openParamEditor',nameToSent);  
278 - }  
279 - else {  
280 - module.addParam(nameToSent,true);  
281 - }  
282 - }  
283 - return true;  
284 - }  
285 - });  
286 - },  
287 - cellclick : function(grid, cell, cellIndex, record){  
288 - if (cellIndex == 3)  
289 - grid.getStore().remove(record);  
290 - }  
291 - }  
292 - });  
293 -  
294 - this.catalogGrid = Ext.create('Ext.grid.Panel', {  
295 - title: 'Catalog',  
296 - height: 500, 270 +
  271 + this.TTGrid = Ext.create('Ext.grid.Panel', {
  272 +// title: 'Catalog',
  273 + height: 530,
297 columns: [ 274 columns: [
298 { text: '', dataIndex: '' } 275 { text: '', dataIndex: '' }
299 276
300 - ] 277 + ],
  278 + frame: true,
  279 + dockedItems: [{
  280 + xtype: 'toolbar',
  281 + items: [{
  282 + iconCls: 'icon-add',
  283 + scope: this,
  284 + handler: function(){
  285 +// cellEditing.cancelEdit();
  286 +//
  287 +// var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0];
  288 +// var row = 0;
  289 +// if (selection)
  290 +// row = store.indexOf(selection) + 1;
  291 +// this.TTGrid.getSelectionModel().deselectAll();
  292 +//
  293 +// var me = this;
  294 +// AmdaAction.addTTCacheInterval({'index' : row}, function (result, e) {
  295 +// this.status = result.status;
  296 +// this.TTGrid.getStore().reload({
  297 +// callback : function(records, options, success) {
  298 +// me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function() {
  299 +// me.TTGrid.getView().select(row);
  300 +// cellEditing.startEditByPosition({row: row, column: 1});
  301 +// }, me);
  302 +// }
  303 +// });
  304 +// }, this);
  305 + }
  306 + }, {
  307 + iconCls: 'icon-delete',
  308 + disabled: true,
  309 + itemId: 'delete',
  310 + scope: this,
  311 + handler: function(){
  312 +// var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0];
  313 +// if (selection) {
  314 +// var rowId = selection.get('cacheId');
  315 +// this.TTGrid.getSelectionModel().deselectAll();
  316 +// AmdaAction.removeTTCacheIntervalFromId(rowId, function (result, e) {
  317 +// this.status = result.status;
  318 +// this.TTGrid.getStore().reload();
  319 +// }, this);
  320 +// }
  321 + }
  322 + }]
  323 + }]
301 }); 324 });
302 325
303 this.formPanel = Ext.create('Ext.form.Panel', { 326 this.formPanel = Ext.create('Ext.form.Panel', {
304 - height: 550,  
305 - width: 800,  
306 - layout: 'border',  
307 - defaults: { layout: 'fit', border: false }, 327 + region : 'center',
  328 + layout: 'hbox',
  329 + bodyStyle: {background : '#dfe8f6'},
  330 + defaults: { border : false, align: 'stretch', bodyStyle: {background : '#dfe8f6'}, padding: '3'},
308 fieldDefaults: { labelWidth: 80, labelAlign : 'top' }, 331 fieldDefaults: { labelWidth: 80, labelAlign : 'top' },
309 items: [ 332 items: [
310 { 333 {
311 - xtype: 'form',  
312 - region: 'center', 334 + xtype: 'form',
313 flex: 1, 335 flex: 1,
314 buttonAlign: 'left', 336 buttonAlign: 'left',
315 - bodyStyle: {background : '#dfe8f6'},  
316 - padding: '5 5 5 5', 337 +// title : 'Information',
317 layout: {type: 'vbox', pack: 'start', align: 'stretch'}, 338 layout: {type: 'vbox', pack: 'start', align: 'stretch'},
318 items : [ 339 items : [
319 - this.fieldName,  
320 - { 340 + this.fieldName,
  341 + {
321 xtype: 'fieldcontainer', 342 xtype: 'fieldcontainer',
322 layout: 'hbox', 343 layout: 'hbox',
323 items: [ 344 items: [
@@ -328,65 +349,111 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, { @@ -328,65 +349,111 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
328 }, 349 },
329 { xtype: 'splitter' }, 350 { xtype: 'splitter' },
330 { xtype:'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true} 351 { xtype:'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true}
331 - ]  
332 - },  
333 - {  
334 - xtype: 'textarea',  
335 - name: 'description',  
336 - fieldLabel: 'Description',  
337 -// anchor: '100% 50%'  
338 - },  
339 -  
340 - this.paramGrid,  
341 - this.ttGrid  
342 - ],  
343 - fbar:[  
344 - {  
345 - type: 'button',  
346 - text: 'Generate Catalog',  
347 - scope : this,  
348 - handler: function(button){  
349 - // update object with user's values  
350 - // if the return is true (object had been updated)  
351 - // if(this.updateObject()){  
352 - this.updateObject();  
353 - this.generateCatalog();  
354 - // }  
355 - }  
356 - },  
357 - {  
358 - type: 'button',  
359 - text: 'Reset'  
360 - }  
361 - ] 352 + ]
  353 + },
  354 + {
  355 + xtype: 'textarea',
  356 + name: 'description',
  357 + fieldLabel: 'Description',
  358 + height: 200
  359 + },
  360 + {
  361 + xtype: 'component',
  362 + height: 180
  363 + }
  364 + ],
  365 + fbar:[
  366 + {
  367 + type: 'button',
  368 + text: 'Save',
  369 + scope : this,
  370 + handler: function () {
  371 + if (this.updateObject()){
  372 +
  373 + var basicForm = this.formPanel.getForm();
  374 + // if there's at least one record in the store of TTGrid
  375 + if (this.TTGrid.getStore().getTotalCount() > 0) {
  376 + // update TimeTable object which the content of form
  377 + basicForm.updateRecord(this.object);
  378 +
  379 + var me = this;
  380 + this.checkIntervalsStatusForSave(function () {
  381 + //Name validation
  382 + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);
  383 + if (!module)
  384 + return;
  385 + module.linkedNode.isValidName(me.fieldName.getValue(), function (res) {
  386 + if (!res)
  387 + {
  388 + me.fieldName.validFlag = 'Error during object validation';
  389 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  390 + me.fieldName.validate();
  391 + return;
  392 + }
  393 +
  394 + if (!res.valid)
  395 + {
  396 + if (res.error)
  397 + {
  398 + if (res.error.search('subtree') != -1) {
  399 + Ext.MessageBox.show({title:'Warning',
  400 + msg: res.error+'<br/>Do you want to overwrite it?',
  401 + width: 300,
  402 + buttons: Ext.MessageBox.OKCANCEL,
  403 + fn : me.overwriteProcess,
  404 + icon: Ext.MessageBox.WARNING,
  405 + scope : me
  406 + });
  407 + me.fieldName.validFlag = true;
  408 + }
  409 + else
  410 + me.fieldName.validFlag = res.error;
  411 + }
  412 + else
  413 + {
  414 + me.fieldName.validFlag = 'Invalid object name';
  415 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  416 + }
  417 + me.fieldName.validate();
  418 + return;
  419 + }
  420 +
  421 + me.fieldName.validFlag = true;
  422 + me.fieldName.validate();
  423 + me.saveProcess(false);
  424 + });
  425 + });
  426 + } else {
  427 + // warning:
  428 + Ext.Msg.alert('No intervals', 'Your time table is invalid, <br>you must have at least one interval');
  429 + }
  430 + }
  431 + }
  432 + },{
  433 + type: 'button',
  434 + text: 'Share',
  435 + disabled: true
  436 + },
  437 + {
  438 + type: 'button',
  439 + text: 'Visualize'
  440 + }
  441 + ]
362 }, { 442 }, {
363 - xtype: 'form',  
364 - region: 'east', 443 + xtype: 'form',
365 bodyStyle: {background : '#dfe8f6'}, 444 bodyStyle: {background : '#dfe8f6'},
366 - padding: '5 5 5 5', 445 +// padding: '3',
367 flex: 2, 446 flex: 2,
368 items : [ 447 items : [
369 - this.catalogGrid  
370 - ],  
371 - fbar:[  
372 - {  
373 - type: 'button',  
374 - text: 'Save'  
375 - },{  
376 - type: 'button',  
377 - text: 'Share',  
378 - disabled: true  
379 - },  
380 - {  
381 - type: 'button',  
382 - text: 'Visualize'  
383 - }  
384 - ] 448 + this.TTGrid
  449 + ]
385 } 450 }
386 ] 451 ]
387 }); 452 });
388 453
389 - 454 + this.TTGrid.getSelectionModel().on('selectionchange', function(selModel,selections){
  455 + this.TTGrid.down('#delete').setDisabled(selections.length === 0);
  456 + }, this);
390 457
391 var myConf = { 458 var myConf = {
392 layout: 'border', 459 layout: 'border',
js/app/views/StatisticsUI.js 0 โ†’ 100644
@@ -0,0 +1,343 @@ @@ -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+'downloadHOWTO'
  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,6 +37,8 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, {
37 break; 37 break;
38 case 'download': var title = 'Download Results'; 38 case 'download': var title = 'Download Results';
39 break; 39 break;
  40 + case 'statistics': var title = 'Statistics Results';
  41 + break;
40 default: 42 default:
41 } 43 }
42 var newConfig = { 44 var newConfig = {
@@ -54,7 +56,7 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, { @@ -54,7 +56,7 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, {
54 scope : this, 56 scope : this,
55 beforeclose : function() { 57 beforeclose : function() {
56 //delete linked nodes connected to ResultModule and corresponding to this Tab 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 if (module.linkedNodes) { 60 if (module.linkedNodes) {
59 var indices = new Array(); 61 var indices = new Array();
60 var i =0; 62 var i =0;
@@ -105,6 +107,16 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, { @@ -105,6 +107,16 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
105 this); 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 getResultCallback : function(result,remoteEvent){//result, e) { 120 getResultCallback : function(result,remoteEvent){//result, e) {
109 var t = remoteEvent.getTransaction(); 121 var t = remoteEvent.getTransaction();
110 //AKKA - catch error 122 //AKKA - catch error
@@ -120,8 +132,8 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, { @@ -120,8 +132,8 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
120 return; 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 paramObj.set('intervals',result.intervals); 137 paramObj.set('intervals',result.intervals);
126 // set parameter into node 138 // set parameter into node
127 this.linkedNode.set('object',paramObj); 139 this.linkedNode.set('object',paramObj);
@@ -130,7 +142,7 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, { @@ -130,7 +142,7 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
130 myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function (module) { 142 myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function (module) {
131 module.setLinkedNode(me.linkedNode); 143 module.setLinkedNode(me.linkedNode);
132 // Edition of parameter into parameter Module 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,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 //TODO make this properly 295 //TODO make this properly
255 296
256 var configPlot = { 297 var configPlot = {
@@ -329,6 +370,9 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, { @@ -329,6 +370,9 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
329 case 'condition' : 370 case 'condition' :
330 Ext.apply(this, configTT); 371 Ext.apply(this, configTT);
331 break; 372 break;
  373 + case 'statistics' :
  374 + Ext.apply(this, configCat);
  375 + break;
332 case 'request' : 376 case 'request' :
333 Ext.apply(this, configPlot); 377 Ext.apply(this, configPlot);
334 break; 378 break;
js/app/views/TimeTableUI.js
@@ -30,6 +30,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, { @@ -30,6 +30,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
30 }, 30 },
31 31
32 status: null, 32 status: null,
  33 + isCatalog : false,
33 34
34 constructor: function(config) { 35 constructor: function(config) {
35 this.init(config); 36 this.init(config);
@@ -116,7 +117,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, { @@ -116,7 +117,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
116 else 117 else
117 { 118 {
118 //From tmp object (ie Search result) 119 //From tmp object (ie Search result)
119 - AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), onAfterInit); 120 + AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, onAfterInit);
120 } 121 }
121 } 122 }
122 else 123 else
js/resources/css/amda.css
@@ -79,6 +79,10 @@ @@ -79,6 +79,10 @@
79 background-image:url( ../images/16x16/search.png ) !important; 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 .icon-manage-ws { 86 .icon-manage-ws {
83 background-image:url( ../images/16x16/wsManager.png ) !important; 87 background-image:url( ../images/16x16/wsManager.png ) !important;
84 } 88 }
@@ -385,3 +389,8 @@ p + p { @@ -385,3 +389,8 @@ p + p {
385 font-style: italic !important; 389 font-style: italic !important;
386 font-weight: bold !important; 390 font-weight: bold !important;
387 } 391 }
  392 +
  393 +.x-item-disabled .x-form-item-label {
  394 + filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100) !important;
  395 + opacity: 1.0 !important;
  396 +}
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,7 +581,10 @@ class AmdaAction {
581 switch ($nodeType) { 581 switch ($nodeType) {
582 case 'timeTable' : 582 case 'timeTable' :
583 $objectMgr = new TimeTableMgr(); 583 $objectMgr = new TimeTableMgr();
584 - break; 584 + break;
  585 + case 'catalog' :
  586 + $objectMgr = new CatalogMgr();
  587 + break;
585 default: 588 default:
586 return array("error" => $nodeType." NOT_IMPLEMENTED_YET"); 589 return array("error" => $nodeType." NOT_IMPLEMENTED_YET");
587 } 590 }
@@ -631,6 +634,9 @@ class AmdaAction { @@ -631,6 +634,9 @@ class AmdaAction {
631 break; 634 break;
632 case 'timeTable' : 635 case 'timeTable' :
633 $objectMgr = new TimeTableMgr(); 636 $objectMgr = new TimeTableMgr();
  637 + break;
  638 + case 'catalog' :
  639 + $objectMgr = new CatalogMgr();
634 break; 640 break;
635 case 'condition' : 641 case 'condition' :
636 case 'request' : 642 case 'request' :
@@ -667,6 +673,9 @@ class AmdaAction { @@ -667,6 +673,9 @@ class AmdaAction {
667 break; 673 break;
668 case 'timeTable' : 674 case 'timeTable' :
669 $objectMgr = new TimeTableMgr(); 675 $objectMgr = new TimeTableMgr();
  676 + break;
  677 + case 'catalog' :
  678 + $objectMgr = new Catalog();
670 break; 679 break;
671 case 'condition' : 680 case 'condition' :
672 case 'request' : 681 case 'request' :
@@ -698,6 +707,9 @@ class AmdaAction { @@ -698,6 +707,9 @@ class AmdaAction {
698 break; 707 break;
699 case 'timeTable' : 708 case 'timeTable' :
700 $objectMgr = new TimeTableMgr(); 709 $objectMgr = new TimeTableMgr();
  710 + break;
  711 + case 'catalog' :
  712 + $objectMgr = new CatalogMgr();
701 break; 713 break;
702 case 'condition' : 714 case 'condition' :
703 case 'request' : 715 case 'request' :
@@ -726,7 +738,10 @@ class AmdaAction { @@ -726,7 +738,10 @@ class AmdaAction {
726 break; 738 break;
727 case 'timeTable' : 739 case 'timeTable' :
728 $objectMgr = new TimeTableMgr(); 740 $objectMgr = new TimeTableMgr();
729 - break; 741 + break;
  742 + case 'catalog' :
  743 + $objectMgr = new CatalogMgr();
  744 + break;
730 case 'condition' : 745 case 'condition' :
731 case 'request' : 746 case 'request' :
732 $objectMgr = new RequestMgr($obj->nodeType); 747 $objectMgr = new RequestMgr($obj->nodeType);
@@ -747,8 +762,12 @@ class AmdaAction { @@ -747,8 +762,12 @@ class AmdaAction {
747 $objectMgr = new DerivedParamMgr($obj->nodeType); 762 $objectMgr = new DerivedParamMgr($obj->nodeType);
748 break; 763 break;
749 case 'timeTable' : 764 case 'timeTable' :
  765 + case 'sharedtimeTable' :
750 $objectMgr = new TimeTableMgr(); 766 $objectMgr = new TimeTableMgr();
751 break; 767 break;
  768 + case 'catalog' :
  769 + $objectMgr = new CatalogMgr();
  770 + break;
752 case 'condition' : 771 case 'condition' :
753 case 'request' : 772 case 'request' :
754 $objectMgr = new RequestMgr($obj->nodeType); 773 $objectMgr = new RequestMgr($obj->nodeType);
@@ -927,15 +946,27 @@ class AmdaAction { @@ -927,15 +946,27 @@ class AmdaAction {
927 return $cacheMgr->initTTCache(); 946 return $cacheMgr->initTTCache();
928 } 947 }
929 948
  949 +// public function initCatalogGridFromTmpObject($folderId, $name)
  950 +// {
  951 +// $objMgr = new CatalogMgr();
  952 +// return $objMgr->initCatalogGridFromTmpObject($folderId, $name);
  953 +// }
  954 +
930 public function initTTCacheFromTT($id, $type) 955 public function initTTCacheFromTT($id, $type)
931 { 956 {
932 $cacheMgr = new TimeTableCacheMgr(); 957 $cacheMgr = new TimeTableCacheMgr();
933 return $cacheMgr->initFromTT($id, $type); 958 return $cacheMgr->initFromTT($id, $type);
934 } 959 }
935 960
936 - public function initTTCacheFromTmpObject($folderId, $name) 961 + public function initTTCacheFromTmpObject($folderId, $name, $isCatalog = false)
937 { 962 {
938 - $cacheMgr = new TimeTableCacheMgr(); 963 + error_reporting(E_ERROR | E_WARNING | E_PARSE);
  964 + if (!$isCatalog) $cacheMgr = new TimeTableCacheMgr();
  965 +
  966 + else $cacheMgr = new CatalogCacheMgr();
  967 +
  968 +
  969 +
939 return $cacheMgr->initFromTmpObject($folderId, $name); 970 return $cacheMgr->initFromTmpObject($folderId, $name);
940 } 971 }
941 972
@@ -947,7 +978,9 @@ class AmdaAction { @@ -947,7 +978,9 @@ class AmdaAction {
947 978
948 public function readTTCacheIntervals($o) 979 public function readTTCacheIntervals($o)
949 { 980 {
950 - $cacheMgr = new TimeTableCacheMgr(); 981 + if ($o->typeTT == 'catalog') $cacheMgr = new CatalogCacheMgr();
  982 + else $cacheMgr = new TimeTableCacheMgr();
  983 +
951 return $cacheMgr->getIntervals($o->start,$o->limit,$o->sort,$o->filter); 984 return $cacheMgr->getIntervals($o->start,$o->limit,$o->sort,$o->filter);
952 } 985 }
953 986
@@ -1201,8 +1234,8 @@ class AmdaAction { @@ -1201,8 +1234,8 @@ class AmdaAction {
1201 //AKKA - New action to clean user WS 1234 //AKKA - New action to clean user WS
1202 public function cleanUserWS() 1235 public function cleanUserWS()
1203 { 1236 {
1204 - require_once(INTEGRATION_SRC_DIR."RequestManager.php");  
1205 - return $this->executeRequest($obj, FunctionTypeEnumClass::PROCESSCLEAN); 1237 +// require_once(INTEGRATION_SRC_DIR."RequestManager.php");
  1238 +// return $this->executeRequest($obj, FunctionTypeEnumClass::PROCESSCLEAN);
1206 } 1239 }
1207 1240
1208 public function deleteSpecialInfo($name) 1241 public function deleteSpecialInfo($name)
php/classes/CatalogCacheMgr.php 0 โ†’ 100644
@@ -0,0 +1,319 @@ @@ -0,0 +1,319 @@
  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 + $result = array(
  15 + "cacheId" => $this->id,
  16 + "start" => $this->getStartToISO(),
  17 + "stop" => $this->getStopToISO()
  18 + );
  19 + if ($this->isNew)
  20 + $result["isNew"] = true;
  21 + if ($this->isModified)
  22 + $result["isModified"] = true;
  23 +
  24 + for ($i = 0; $i < count($this->params); $i++) {
  25 + $paramObject = array();
  26 + $index = 'param'.sprintf("%d",$i+2);
  27 + $result[$index] = $this->params[$i];
  28 + }
  29 + return $result;
  30 + }
  31 +
  32 + // for catalog
  33 + public function setParams($params) {
  34 + $this->params = $params;
  35 +
  36 + }
  37 +
  38 + public function getParams() {
  39 + return $this->params;
  40 + }
  41 +
  42 + public function writeBin($handle, $paramsNumber, $paramsSizes) {
  43 + fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified));
  44 + for ($i = 0; $i < $paramsNumber; $i++) {
  45 + $paramString = $this->params[$i];
  46 + $paramArray = explode(',',$this->params[$i]);
  47 + for ($j = 0; $j < $paramsSizes[$i]; $j++) fwrite($handle,pack('d', $paramArray[$j]));
  48 + }
  49 +
  50 + }
  51 +
  52 + public function loadBin($handle, $paramsNumber, $paramsSizes) {
  53 + $array = unpack('L6int',fread($handle,6*4));
  54 + $this->id = $array['int1'];
  55 + $this->index = $array['int2'];
  56 + $this->start = $array['int3'];
  57 + $this->stop = $array['int4'];
  58 + $this->isNew = $array['int5'];
  59 + $this->isModified = $array['int6'];
  60 +
  61 + for ($i = 0; $i < $paramsNumber; $i++) {
  62 + $this->params[$i] = null;
  63 + for ($j = 0; $j < $paramsSizes[$i]; $j++) {
  64 + $val = unpack('dval',fread($handle,8));
  65 + $this->params[$i] .= $val['val'];
  66 + if ($j != $paramsSizes[$i] - 1) $this->params[$i] .= ',';
  67 + }
  68 + }
  69 +
  70 + }
  71 +
  72 + public function dump() {
  73 + echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL;
  74 + }
  75 +}
  76 +
  77 +class CatalogCacheObject extends TimeTableCacheObject
  78 +{
  79 + private $paramsNumber;
  80 + private $paramsSizes = array();
  81 +
  82 + public function addInterval($startIso, $stopIso, $params, $isNew = false, $index = -1) {
  83 + $interval = new CatIntervalCacheObject($this->lastId, count($this->intervals));
  84 + ++$this->lastId;
  85 + $interval->setStartFromISO($startIso);
  86 + $interval->setStopFromISO($stopIso);
  87 + // for catalog
  88 + $interval->setParams($params);
  89 +
  90 + $interval->setIsNew($isNew);
  91 + array_push($this->intervals, $interval);
  92 + if ($index < 0)
  93 + array_push($this->indexes, count($this->intervals) - 1);
  94 + else
  95 + array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1));
  96 + if ($isNew)
  97 + $this->isModified = true;
  98 +
  99 + return $interval;
  100 + }
  101 +
  102 + public function setParamsNumber($number){
  103 + $this->paramsNumber = $number;
  104 + }
  105 +
  106 + public function setParamsSizes($params){
  107 + for ($i = 0; $i < $this->paramsNumber; $i++)
  108 + $this->paramsSizes[$i] = $params[$i]['size'];
  109 + }
  110 +
  111 + public function writeBin($handle) {
  112 + //Magic key ("TTC")
  113 + fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C')));
  114 +
  115 + //Version
  116 + fwrite($handle,pack('L',TimeTableCacheObject::$format_version));
  117 +
  118 + //Token
  119 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  120 + fwrite($handle,pack('C',ord($this->token[$i])));
  121 +
  122 + //Modified
  123 + fwrite($handle,pack('L',$this->isModified));
  124 +
  125 + //Filter
  126 + $this->filter->writeBin($handle);
  127 +
  128 + //Sort
  129 + $this->sort->writeBin($handle);
  130 +
  131 + //Params Number
  132 + fwrite($handle,pack('L',$this->paramsNumber));
  133 +
  134 + //Params Sizes
  135 + for ($i = 0; $i < $this->paramsNumber; $i++)
  136 + fwrite($handle,pack('L',$this->paramsSizes[$i]));
  137 +
  138 + //Intervals
  139 + fwrite($handle,pack('L2',count($this->intervals), $this->lastId));
  140 +
  141 +
  142 + foreach($this->intervals as $interval)
  143 + $interval->writeBin($handle,$this->paramsNumber,$this->paramsSizes);
  144 +
  145 + //Indexes
  146 + fwrite($handle,pack('L',count($this->indexes)));
  147 + foreach($this->indexes as $index)
  148 + fwrite($handle,pack('L',$index));
  149 + }
  150 +
  151 + public function loadBin($handle) {
  152 + //Magic key ("TTC")
  153 + if (!$res = unpack('C3key',fread($handle,3)))
  154 + return false;
  155 +
  156 + if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C')))
  157 + return false;
  158 +
  159 + //Version
  160 + if (!$res = unpack('Lversion',fread($handle,4)))
  161 + return false;
  162 + if (($res['version'] != TimeTableCacheObject::$format_version))
  163 + return false;
  164 +
  165 + //Token
  166 + $token = "";
  167 + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i)
  168 + {
  169 + if (!$res = unpack('Ctoken',fread($handle,1)))
  170 + return false;
  171 + $token .= chr($res['token']);
  172 + }
  173 + $this->token = $token;
  174 +
  175 + //Modified
  176 + if (!$res = unpack('Lmodified',fread($handle,4)))
  177 + return false;
  178 + $this->isModified = $res['modified'];
  179 +
  180 + //Filter
  181 + $this->filter->loadBin($handle);
  182 +
  183 + //Sort
  184 + $this->sort->loadBin($handle);
  185 +
  186 + //ParamsNumber
  187 + if (!$res = unpack('Lnumber',fread($handle,4)))
  188 + return false;
  189 + $this->paramsNumber = $res['number'];
  190 +
  191 + //ParamsSizes
  192 + for ($i = 0; $i < $this->paramsNumber; $i++) {
  193 + if (!$res = unpack('Lsize',fread($handle,4)))
  194 + return false;
  195 + $this->paramsSizes[$i] = $res['size'];
  196 + }
  197 +
  198 + //Intervals
  199 + $res = unpack('L2data',fread($handle,2*4));
  200 + $nbIntervals = $res['data1'];
  201 + $this->lastId = $res['data2'];
  202 +
  203 + for ($i = 0; $i < $nbIntervals; ++$i)
  204 + {
  205 + $interval = new CatIntervalCacheObject(-1);
  206 + $interval->loadBin($handle, $this->paramsNumber, $this->paramsSizes);
  207 + array_push($this->intervals, $interval);
  208 + }
  209 +
  210 + //Indexes
  211 + $res = unpack('Ldata',fread($handle,4));
  212 + $nbIndexes = $res['data'];
  213 + for ($i = 0; $i < $nbIndexes; ++$i)
  214 + {
  215 + $res = unpack('Lindex',fread($handle,4));
  216 + array_push($this->indexes, $res['index']);
  217 + }
  218 +
  219 + return true;
  220 + }
  221 +
  222 +}
  223 +
  224 +class CatalogCacheMgr extends TimeTableCacheMgr
  225 +{
  226 +
  227 + protected static $cache_file = "cacheCat";
  228 +
  229 + protected $ttMgr = null;
  230 + protected $cache = null;
  231 +
  232 + function __construct() {
  233 +
  234 + $this->ttMgr = new CatalogMgr();
  235 + }
  236 +
  237 +
  238 + public function initFromTmpObject($folderId, $name) {
  239 +
  240 + //Create new cache
  241 + $this->cache = new CatalogCacheObject();
  242 +
  243 + //Load intervals from TmpObject file (Statistics Module)
  244 + $intervals_res = $this->ttMgr->getTmpObject($folderId, $name);
  245 +
  246 + if (!isset($intervals_res))
  247 + return array('success' => false, 'message' => 'Cannot get Tmp Object');
  248 +
  249 + if (array_key_exists('intervals', $intervals_res))
  250 + {
  251 + foreach ($intervals_res['intervals'] as $interval)
  252 + {
  253 + //Add interval
  254 + $this->cache->addInterval($interval['start'], $interval['stop'], $interval['paramTable']);
  255 +
  256 + }
  257 + }
  258 +
  259 + $this->cache->setIsModified(true);
  260 +
  261 + $paramHeaders = $intervals_res['parameters'];
  262 +
  263 + $this->cache->setParamsNumber(count($paramHeaders));
  264 + $this->cache->setParamsSizes($paramHeaders);
  265 +
  266 + unset($intervals_res);
  267 +
  268 + //Update cache
  269 + $this->cache->updateIndexes();
  270 +
  271 + //Save cache file
  272 + return array('success' => $this->saveToFile(), 'token' => $this->cache->getToken(),
  273 + 'status' => $this->cache->getStatus(), 'parameters' => $paramHeaders);
  274 + }
  275 +
  276 +
  277 + protected function loadFromFile() {
  278 +
  279 + if (!file_exists($this->getCacheFilePath()))
  280 + return false;
  281 + $this->cache = new CatalogCacheObject();
  282 + $handle = fopen($this->getCacheFilePath(), 'rb');
  283 + $result = false;
  284 + if (flock($handle, LOCK_SH))
  285 + {
  286 + $this->cache->loadBin($handle);
  287 + flock( $handle, LOCK_UN );
  288 + $result = true;
  289 + }
  290 + fclose($handle);
  291 + return $result;
  292 + }
  293 +
  294 + protected function getCacheFilePath() {
  295 + return USERTTDIR.(self::$cache_file);
  296 + }
  297 +
  298 + public function saveInTT($id, $action, $token) {
  299 +
  300 + if (!$this->loadFromFile())
  301 + return array('success' => false, 'message' => 'Cannot load cache file');
  302 +
  303 + if ($token != $this->cache->getToken())
  304 + return array('success' => false, 'message' => 'Cache token check error');
  305 +
  306 + $this->cache->updateIndexes();
  307 + $this->saveToFile();
  308 +
  309 + $intervals = $this->cache->getIntervalsArray(NULL,NULL,true);
  310 +
  311 + $this->cache->reset();
  312 +
  313 + return $this->ttMgr->saveIntervals($id, $intervals, $action);
  314 + }
  315 +
  316 +
  317 +
  318 + }
  319 +?>
0 \ No newline at end of file 320 \ No newline at end of file
php/classes/CatalogMgr.php 0 โ†’ 100644
@@ -0,0 +1,227 @@ @@ -0,0 +1,227 @@
  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 + }
  107 +
  108 + return $attributesToReturn;
  109 + }
  110 +
  111 +
  112 +// public function loadIntervalsFromTT($id,$typeTT,$start = NULL, $limit = NULL)
  113 +// {
  114 +//
  115 +// if ($typeTT == 'sharedtimeTable') {
  116 +// $pathid = SHAREDPATH.'TT/'.$id;
  117 +// }
  118 +// else {
  119 +// $pathid = USERTTDIR.$id;
  120 +// }
  121 +//
  122 +// //load intervals from TT id
  123 +// if (!file_exists($pathid.'.xml'))
  124 +// return array('success' => false, 'message' => "Cannot find TT file ".$id);
  125 +//
  126 +// $this->objectDom -> load($pathid.'.xml');
  127 +//
  128 +// if (!($objToGet = $this->objectDom->getElementById($id)))
  129 +// return array('success' => false, 'message' => NO_SUCH_ID." ".$id);
  130 +//
  131 +// $xpath = new DOMXPath($this->objectDom);
  132 +// $intervals = $xpath->query('//intervals');
  133 +//
  134 +// $result = array();
  135 +//
  136 +// if (!isset($start) || !isset($limit))
  137 +// {
  138 +// foreach ($intervals as $interval)
  139 +// {
  140 +// $startTime = $interval->getElementsByTagName('start')->item(0)->nodeValue;
  141 +// $stopTime = $interval->getElementsByTagName('stop')->item(0)->nodeValue;
  142 +// array_push($result, array('start' => $startTime, 'stop' => $stopTime));
  143 +// }
  144 +// }
  145 +// else
  146 +// {
  147 +// for ($i = 0; $i < $limit; ++$i)
  148 +// {
  149 +// if ($start+$i >= $intervals->length)
  150 +// break;
  151 +// $startTime = $intervals->item($start+$i)->getElementsByTagName('start')->item(0)->nodeValue;
  152 +// $stopTime = $intervals->item($start+$i)->getElementsByTagName('stop')->item(0)->nodeValue;
  153 +// array_push($result, array('start' => $startTime, 'stop' => $stopTime));
  154 +// }
  155 +// }
  156 +//
  157 +// return array(
  158 +// 'totalCount' => $intervals->length,
  159 +// 'intervals' => $result,
  160 +// 'start' => isset($start) ? $start : 0,
  161 +// 'limit' => isset($limit) ? $limit : 0,
  162 +// 'success' => true
  163 +// );
  164 +//
  165 +// }
  166 +
  167 + /*
  168 + * catalog header
  169 + */
  170 + protected function setParamDescription($params) {
  171 +
  172 + $paramsElement = $this->objectDom->createElement('parametres');
  173 + foreach ($params as $param) {
  174 + $paramElement = $this->objectDom->createElement('param');
  175 + $attrArray = (array)$param;
  176 + foreach ($attrArray as $key => $value)
  177 + $paramElement->setAttribute($key, $value);
  178 + $paramsElement->appendChild($paramElement);
  179 + }
  180 +
  181 + return $paramsElement;
  182 + }
  183 +
  184 + protected function createIntervalElement($interval) {
  185 + $newInterval = $this->objectDom->createElement('intervals');
  186 + $newInterval->appendChild($this->objectDom->createElement('start',$interval['start']));
  187 + $newInterval->appendChild($this->objectDom->createElement('stop',$interval['stop']));
  188 + foreach ($interval as $key =>$value) {
  189 + if (substr($key,0,5) == 'param')
  190 + $newInterval->appendChild($this->objectDom->createElement('param', $value));
  191 +
  192 + }
  193 + return $newInterval;
  194 + }
  195 +
  196 + public function createObject($p, $folder){
  197 +
  198 + if ($p -> leaf)
  199 + {
  200 + $result = $this->createParameter($p, $folder);
  201 + if ($result['error'])
  202 + return $result;
  203 +
  204 + $cacheMgr = new CatalogCacheMgr();
  205 +
  206 + if (isset($p->cacheToken) && ($p->cacheToken != ''))
  207 + {
  208 + $resultSaveInt = $cacheMgr->saveInTT($result['id'], "update", $p->cacheToken);
  209 + if (!$resultSaveInt['success'])
  210 + {
  211 + if ($resultSaveInt['message'])
  212 + return array('error' => $resultSaveInt['message']);
  213 + else
  214 + return array('error' => 'Unknown error during intervals save');
  215 + }
  216 + }
  217 + return $result;
  218 + }
  219 + // else return $this->createFolder($p);
  220 + //TODO check if this is possible?
  221 + else return array('error' => 'createFolder should be called from RENAME');
  222 +
  223 + }
  224 +
  225 +
  226 +}
  227 +?>
0 \ No newline at end of file 228 \ No newline at end of file
php/classes/IntervalCacheObject.php 0 โ†’ 100644
@@ -0,0 +1,114 @@ @@ -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 \ No newline at end of file 115 \ No newline at end of file
php/classes/TimeTableCacheMgr.php
@@ -27,8 +27,8 @@ class SortPartCacheObject @@ -27,8 +27,8 @@ class SortPartCacheObject
27 public static $DIRECTION_ASC = 1; 27 public static $DIRECTION_ASC = 1;
28 public static $DIRECTION_DES = 2; 28 public static $DIRECTION_DES = 2;
29 29
30 - private $type;  
31 - private $dir; 30 + protected $type;
  31 + protected $dir;
32 32
33 function __construct() { 33 function __construct() {
34 $this->type = self::$TYPE_UNKNOWN; 34 $this->type = self::$TYPE_UNKNOWN;
@@ -172,7 +172,7 @@ class SortPartCacheObject @@ -172,7 +172,7 @@ class SortPartCacheObject
172 172
173 class SortCacheObject 173 class SortCacheObject
174 { 174 {
175 - private $parts = array(); 175 + protected $parts = array();
176 176
177 function __construct() { 177 function __construct() {
178 } 178 }
@@ -286,9 +286,9 @@ class FilterPartCacheObject @@ -286,9 +286,9 @@ class FilterPartCacheObject
286 public static $OPERATION_GT = 2; 286 public static $OPERATION_GT = 2;
287 public static $OPERATION_EQ = 3; 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 function __construct() { 293 function __construct() {
294 $this->type = self::$TYPE_UNKNOWN; 294 $this->type = self::$TYPE_UNKNOWN;
@@ -470,7 +470,7 @@ class FilterPartCacheObject @@ -470,7 +470,7 @@ class FilterPartCacheObject
470 470
471 class FilterCacheObject 471 class FilterCacheObject
472 { 472 {
473 - private $parts = array(); 473 + protected $parts = array();
474 474
475 function __construct() { 475 function __construct() {
476 476
@@ -555,631 +555,12 @@ class FilterCacheObject @@ -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 function __construct() { 565 function __construct() {
1185 $this->ttMgr = new TimeTableMgr(); 566 $this->ttMgr = new TimeTableMgr();
@@ -1449,11 +830,11 @@ class TimeTableCacheMgr @@ -1449,11 +830,11 @@ class TimeTableCacheMgr
1449 $this->cache->dump(); 830 $this->cache->dump();
1450 } 831 }
1451 832
1452 - private function getCacheFilePath() { 833 + protected function getCacheFilePath() {
1453 return USERTTDIR.(self::$cache_file); 834 return USERTTDIR.(self::$cache_file);
1454 } 835 }
1455 836
1456 - private function saveToFile() { 837 + protected function saveToFile() {
1457 if (!isset($this->cache)) 838 if (!isset($this->cache))
1458 return false; 839 return false;
1459 $handle = fopen($this->getCacheFilePath(), 'wb'); 840 $handle = fopen($this->getCacheFilePath(), 'wb');
@@ -1468,7 +849,7 @@ class TimeTableCacheMgr @@ -1468,7 +849,7 @@ class TimeTableCacheMgr
1468 return $result; 849 return $result;
1469 } 850 }
1470 851
1471 - private function loadFromFile() { 852 + protected function loadFromFile() {
1472 if (!file_exists($this->getCacheFilePath())) 853 if (!file_exists($this->getCacheFilePath()))
1473 return false; 854 return false;
1474 $this->cache = new TimeTableCacheObject(); 855 $this->cache = new TimeTableCacheObject();
php/classes/TimeTableCacheObject.php 0 โ†’ 100644
@@ -0,0 +1,509 @@ @@ -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 \ No newline at end of file 510 \ No newline at end of file
php/classes/TimeTableMgr.php
@@ -22,8 +22,6 @@ function timeFormat($myString) { @@ -22,8 +22,6 @@ function timeFormat($myString) {
22 22
23 class TimeTableMgr extends AmdaObjectMgr { 23 class TimeTableMgr extends AmdaObjectMgr {
24 24
25 -//TODO add catalogs as for requestMgr  
26 -  
27 25
28 function __construct($user) { 26 function __construct($user) {
29 parent::__construct('Tt.xml'); 27 parent::__construct('Tt.xml');
@@ -82,8 +80,13 @@ class TimeTableMgr extends AmdaObjectMgr { @@ -82,8 +80,13 @@ class TimeTableMgr extends AmdaObjectMgr {
82 //if (!($p->intervals)) return true; 80 //if (!($p->intervals)) return true;
83 return false; 81 return false;
84 } 82 }
  83 +
  84 + /*
  85 + * In case of catalogs
  86 + */
  87 + protected function setParamDescription($param) { }
85 88
86 - 89 +
87 /* 90 /*
88 * Create Time Table 91 * Create Time Table
89 */ 92 */
@@ -95,12 +98,15 @@ class TimeTableMgr extends AmdaObjectMgr { @@ -95,12 +98,15 @@ class TimeTableMgr extends AmdaObjectMgr {
95 $this->id = $this->setId(); 98 $this->id = $this->setId();
96 $this->created = date('Y-m-d\TH:i:s'); 99 $this->created = date('Y-m-d\TH:i:s');
97 if (!$this->id) return array('error' => ID_CREATION_ERROR); 100 if (!$this->id) return array('error' => ID_CREATION_ERROR);
  101 +
98 $this->resFileName = USERTTDIR.$this->id.'.xml'; 102 $this->resFileName = USERTTDIR.$this->id.'.xml';
  103 + //TODO catalog root element = 'timetable'
99 $rootElement = $this->objectDom->createElement('timetable'); 104 $rootElement = $this->objectDom->createElement('timetable');
100 $rootElement->setAttribute('xml:id',$this->id); 105 $rootElement->setAttribute('xml:id',$this->id);
101 106
102 foreach ($p as $key => $value) 107 foreach ($p as $key => $value)
103 - if ($key != 'id' && $key != 'leaf' && $key != 'nodeType') { 108 + if ($key != 'id' && $key != 'leaf' && $key != 'nodeType' &&
  109 + $key != 'objName' && $key != 'objFormat' && $key != 'folderId' && $key != 'cacheToken') {
104 if ($key == 'created') { 110 if ($key == 'created') {
105 $rootElement->appendChild($this->objectDom->createElement($key, $this->created)); 111 $rootElement->appendChild($this->objectDom->createElement($key, $this->created));
106 } 112 }
@@ -114,8 +120,14 @@ class TimeTableMgr extends AmdaObjectMgr { @@ -114,8 +120,14 @@ class TimeTableMgr extends AmdaObjectMgr {
114 $n_int++; 120 $n_int++;
115 } 121 }
116 }*/ 122 }*/
  123 + // it is catalog
  124 + else if ($key == 'parameters') {
  125 + $paramsElement = $this->setParamDescription($value);
  126 + if ($paramsElement) $rootElement->appendChild($paramsElement);
  127 +
  128 + }
117 else if ($key != 'intervals') 129 else if ($key != 'intervals')
118 - $rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value))); 130 + $rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
119 } 131 }
120 132
121 $this->objectDom->appendChild($rootElement); 133 $this->objectDom->appendChild($rootElement);
@@ -418,12 +430,20 @@ class TimeTableMgr extends AmdaObjectMgr { @@ -418,12 +430,20 @@ class TimeTableMgr extends AmdaObjectMgr {
418 'totalCount' => $intervals->length, 430 'totalCount' => $intervals->length,
419 'intervals' => $result, 431 'intervals' => $result,
420 'start' => isset($start) ? $start : 0, 432 'start' => isset($start) ? $start : 0,
421 - 'limit' => isset($limit) ? $limit : 0, 433 + 'limit' => isset($limit) ? $limit : 0,
422 'success' => true 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 public function saveIntervals($id,$intervals,$action) 447 public function saveIntervals($id,$intervals,$action)
428 { 448 {
429 if (substr($id,0,6) == 'shared') { 449 if (substr($id,0,6) == 'shared') {
@@ -457,11 +477,9 @@ class TimeTableMgr extends AmdaObjectMgr { @@ -457,11 +477,9 @@ class TimeTableMgr extends AmdaObjectMgr {
457 477
458 //add new intervals 478 //add new intervals
459 foreach ($intervals as $interval) 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 //save modifications 485 //save modifications