Commit d18b535dda83a475a400106be1382318be8509dd
1 parent
f792a3de
Exists in
master
and in
111 other branches
catalog draft + context menu small modifs
Showing
33 changed files
with
2307 additions
and
1055 deletions
Show diff stats
generic_data/jobs.json
... | ... | @@ -3,14 +3,14 @@ |
3 | 3 | [{"nodeType" : "bkgWorks","text" : "Plot","id" : "resPlot-treeRootNode" }, |
4 | 4 | {"nodeType" : "bkgWorks","text" : "Download","id" : "resDown-treeRootNode"}, |
5 | 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 | 9 | {"nodeType" : "bkgWorks", "text" : "Jobs in Progress", "id" : "bkgjobs-treeRootNode", "children" : |
10 | 10 | [{"nodeType" : "bkgWorks","text" : "Plot","id" : "bkgPlot-treeRootNode" }, |
11 | 11 | {"nodeType" : "bkgWorks","text" : "Download","id" : "bkgDown-treeRootNode"}, |
12 | 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 | 20 | ], |
21 | 21 | |
22 | 22 | dynamicModules: { |
23 | + statistics : { | |
24 | + id : 'statistics-win', | |
25 | + icon : 'icon-statistics', | |
26 | + title : 'Statistics', | |
27 | + source : 'amdaDesktop.StatisticsModule', | |
28 | + useLauncher : true | |
29 | + }, | |
23 | 30 | catalog : { |
24 | 31 | id : 'catalog-win', |
25 | 32 | icon : 'icon-catalog', |
26 | - title : 'Generate/Edit catalogs', | |
33 | + title : 'Manage catalogs', | |
27 | 34 | source : 'amdaDesktop.CatalogModule', |
28 | 35 | useLauncher : true |
29 | 36 | }, |
... | ... | @@ -275,12 +282,13 @@ Ext.define('amdaApp.AmdaApp', { |
275 | 282 | { name: 'Create/Modify parameter', iconCls: 'edit', module: 'param-win' }, |
276 | 283 | { name: 'Plot data', iconCls: 'plot', module: 'plot-win'}, |
277 | 284 | { name: 'Data mining', iconCls: 'search', module: 'search-win'}, |
285 | + { name: 'Statistics', iconCls: 'statistics', module: 'statistics-win'}, | |
278 | 286 | { name: 'Download data', iconCls: 'download_manager', module: 'down-win'}, |
279 | 287 | { name: 'Upload data', iconCls: 'mydata', module: 'up-win'}, |
280 | 288 | { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' }, |
281 | 289 | { name: 'TimeTables operations', iconCls: 'operations', module: 'ttsOpe-win' }, |
282 | - { name: 'Generate/Edit catalogs', iconCls: 'catalog', module: 'catalog-win'}, | |
283 | - // { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'}, | |
290 | + { name: 'Manage catalogs', iconCls: 'catalog', module: 'catalog-win'}, | |
291 | + { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'}, | |
284 | 292 | { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' } |
285 | 293 | ] |
286 | 294 | }), |
... | ... |
js/app/controllers/ExplorerModule.js
... | ... | @@ -23,6 +23,7 @@ Ext.define('amdaDesktop.ExplorerModule', { |
23 | 23 | 'amdaModel.AliasNode', |
24 | 24 | 'amdaModel.TimeTableNode', |
25 | 25 | 'amdaModel.CatalogNode', |
26 | + 'amdaModel.StatisticsNode', // singleton; not shown in the tree | |
26 | 27 | 'amdaModel.sharedTimeTableNode', |
27 | 28 | 'amdaModel.MyDataParamNode', |
28 | 29 | 'amdaModel.MyDataNode', |
... | ... | @@ -35,7 +36,8 @@ Ext.define('amdaDesktop.ExplorerModule', { |
35 | 36 | 'amdaModel.Plot', |
36 | 37 | 'amdaModel.Download', |
37 | 38 | 'amdaModel.TimeTable', |
38 | - 'amdaModel.Catalog', | |
39 | + 'amdaModel.Catalog', | |
40 | + 'amdaModel.Statistics', | |
39 | 41 | 'amdaModel.FileObject', |
40 | 42 | 'amdaModel.FileParamObject', |
41 | 43 | 'amdaModel.FilterInfo' |
... | ... |
... | ... | @@ -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 | 52 | |
53 | 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 | 57 | create: function(alias, param) { |
65 | 58 | AmdaAction.createObject({name: alias, param: param, |
... | ... |
js/app/models/BkgJobNode.js
... | ... | @@ -6,11 +6,6 @@ |
6 | 6 | * @brief Basic Model of Node corresponding to Amda processes in background |
7 | 7 | * @author elena |
8 | 8 | * @version $Id: BkgJobNode.js 1963 2013-12-06 17:50:37Z elena $ |
9 | - * @todo | |
10 | - ******************************************************************************* | |
11 | - * FT Id : Date : Name - Description | |
12 | - ******************************************************************************* | |
13 | - * : :08/07/2011: elena creation | |
14 | 9 | */ |
15 | 10 | |
16 | 11 | Ext.define('amdaModel.BkgJobNode', { |
... | ... | @@ -25,19 +20,19 @@ Ext.define('amdaModel.BkgJobNode', { |
25 | 20 | PLOT: 'request',//'plot', |
26 | 21 | CONDITION: 'condition', |
27 | 22 | DOWNLOAD: 'download', |
28 | - CATALOG: 'catalog' | |
23 | + STATISTICS: 'statistics' | |
29 | 24 | }, |
30 | 25 | JOB_ROOT_NODE: { |
31 | 26 | PLOT: 'bkgPlot-treeRootNode', |
32 | 27 | CONDITION: 'bkgSearch-treeRootNode', |
33 | 28 | DOWNLOAD: 'bkgDown-treeRootNode', |
34 | - CATALOG: 'bkgCatalog-treeRootNode' | |
29 | + STATISTICS: 'bkgStatistics-treeRootNode' | |
35 | 30 | }, |
36 | 31 | RES_ROOT_NODE: { |
37 | 32 | PLOT: 'resPlot-treeRootNode', |
38 | 33 | CONDITION: 'resSearch-treeRootNode', |
39 | 34 | DOWNLOAD: 'resDown-treeRootNode', |
40 | - CATALOG: 'resCatalog-treeRootNode' | |
35 | + STATISTICS: 'resStatistics-treeRootNode' | |
41 | 36 | }, |
42 | 37 | STATUS_LIST: { |
43 | 38 | IN_PROGRESS: 'in_progress', |
... | ... | @@ -225,12 +220,18 @@ Ext.define('amdaModel.BkgJobNode', { |
225 | 220 | var obj = null; |
226 | 221 | switch (this.get('jobType')) |
227 | 222 | { |
228 | - case 'condition' : | |
223 | + case 'condition' : | |
229 | 224 | obj = Ext.create('amdaModel.Search', |
230 | 225 | {name: result.name, |
231 | 226 | resultId : result.result, |
232 | 227 | folderId : result.folder}); |
233 | 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 | 235 | case 'request' : |
235 | 236 | obj = Ext.create('amdaModel.Plot', |
236 | 237 | {name: result.name, format: result.format, |
... | ... | @@ -355,8 +356,8 @@ Ext.define('amdaModel.BkgJobNode', { |
355 | 356 | case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: |
356 | 357 | rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.DOWNLOAD; |
357 | 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 | 361 | break; |
361 | 362 | default: |
362 | 363 | break; |
... | ... | @@ -373,8 +374,8 @@ Ext.define('amdaModel.BkgJobNode', { |
373 | 374 | case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: |
374 | 375 | rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.DOWNLOAD; |
375 | 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 | 379 | break; |
379 | 380 | default: |
380 | 381 | break; |
... | ... |
js/app/models/Catalog.js
... | ... | @@ -14,9 +14,7 @@ Ext.define('amdaModel.Catalog', { |
14 | 14 | extend: 'amdaModel.TimeTable', |
15 | 15 | |
16 | 16 | fields : [ |
17 | - { name: 'parameter' }, | |
18 | - { name: 'timeTables' }//, | |
19 | -// { name: 'timesrc', type: 'string', defaultValue : "TimeTable" } | |
17 | + { name: 'parameters' } | |
20 | 18 | ], |
21 | 19 | |
22 | 20 | getJsonValues : function (hasId) { |
... | ... | @@ -25,7 +23,7 @@ Ext.define('amdaModel.Catalog', { |
25 | 23 | values.id = this.get('id'); |
26 | 24 | } |
27 | 25 | |
28 | - values.timesrc = 'TimeTable'; | |
26 | + values.timesrc = this.get('timesrc'); | |
29 | 27 | values.name = this.get('name'); |
30 | 28 | values.created = this.get('created'); |
31 | 29 | |
... | ... | @@ -40,8 +38,7 @@ Ext.define('amdaModel.Catalog', { |
40 | 38 | values.folderId = this.get('folderId'); |
41 | 39 | values.nbIntervals = this.get('nbIntervals'); |
42 | 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 | 42 | values.leaf = true; |
46 | 43 | values.nodeType = amdaModel.CatalogNode.nodeType; |
47 | 44 | return values; |
... | ... |
js/app/models/CatalogNode.js
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | |
10 | 10 | Ext.define('amdaModel.CatalogNode', { |
11 | 11 | |
12 | - extend: 'amdaModel.ExecutableNode', | |
12 | + extend: 'amdaModel.TimeTableNode', | |
13 | 13 | |
14 | 14 | statics: { |
15 | 15 | nodeType: 'catalog', |
... | ... | @@ -23,6 +23,45 @@ Ext.define('amdaModel.CatalogNode', { |
23 | 23 | this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); |
24 | 24 | this.set('objectDataModel',amdaModel.Catalog.$className); |
25 | 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 | 53 | |
54 | 54 | getAllContextMenuItems: function(){ |
55 | 55 | |
56 | - var menuItems = this.allMenuItems(amdaModel.DerivedParamNode.objectName); | |
56 | + var menuItems = this.allMenuItems(); | |
57 | 57 | var locMenuItems = this.localMenuItems(); |
58 | 58 | |
59 | 59 | return Ext.Array.merge(menuItems,locMenuItems); |
60 | - }, | |
61 | - | |
62 | - getMultiContextMenuItems: function(){ | |
63 | - return this.allMenuMultiItems(amdaModel.DerivedParamNode.objectName); | |
64 | - }, | |
60 | + }, | |
65 | 61 | |
66 | 62 | isParameter : function(){ |
67 | 63 | return this.get('isParameter'); |
... | ... |
js/app/models/InteractiveNode.js
... | ... | @@ -369,7 +369,8 @@ Ext.define('amdaModel.InteractiveNode', { |
369 | 369 | * Generic part of Context Menu |
370 | 370 | * |
371 | 371 | */ |
372 | - allMenuItems : function(src) { | |
372 | + allMenuItems : function() { | |
373 | + var src = this.self.objectName; | |
373 | 374 | var menuItems = |
374 | 375 | [ { |
375 | 376 | fnId : 'root-createLeaf', |
... | ... | @@ -402,16 +403,24 @@ Ext.define('amdaModel.InteractiveNode', { |
402 | 403 | return menuItems; |
403 | 404 | }, |
404 | 405 | |
405 | - allMenuMultiItems : function(src) { | |
406 | + allMenuMultiItems : function() { | |
406 | 407 | var menuMulti = [ |
407 | 408 | { |
408 | 409 | fnId : 'mult-deleteMulti', |
409 | - text : 'Delete selected '+ src+'s' | |
410 | + text : 'Delete selected ' + this.self.objectName + 's' | |
410 | 411 | } |
411 | 412 | ]; |
412 | 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 | 425 | * default implementation |
417 | 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 | 126 | return menuItems; |
127 | 127 | }, |
128 | 128 | |
129 | - getAllContextMenuItems: function() | |
130 | - { | |
131 | - return this.allMenuItems(); | |
132 | - }, | |
133 | - | |
129 | + | |
134 | 130 | onMenuItemClick : function(menu,item,event) |
135 | 131 | { |
136 | 132 | switch (item.fnId) |
... | ... |
js/app/models/MyDataParamNode.js
... | ... | @@ -23,7 +23,8 @@ Ext.define('amdaModel.MyDataParamNode', { |
23 | 23 | ], |
24 | 24 | |
25 | 25 | statics:{ |
26 | - nodeType: 'myDataParam' | |
26 | + nodeType: 'myDataParam', | |
27 | + objectName : 'Parameter' | |
27 | 28 | }, |
28 | 29 | |
29 | 30 | constructor : function(config){ |
... | ... | @@ -75,12 +76,8 @@ Ext.define('amdaModel.MyDataParamNode', { |
75 | 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 | 83 | onMenuItemClick : function(menu,item,event) { |
... | ... |
js/app/models/PlotNode.js
... | ... | @@ -72,14 +72,7 @@ Ext.define('amdaModel.PlotNode', { |
72 | 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 | 76 | onMenuItemClick : function(menu,item,event) { |
84 | 77 | // fnId parsing : |
85 | 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 | 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 | 74 | onMenuItemClick : function(menu,item,event) { |
82 | 75 | // fnId parsing : |
83 | 76 | var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); |
... | ... |
... | ... | @@ -0,0 +1,75 @@ |
1 | +/** | |
2 | + * Project : AMDA-NG | |
3 | + * Name : Statistics.js | |
4 | + * Description : Statistics Object Definition | |
5 | + * @class amdaModel.Statistics | |
6 | + * @extends amdaModel.TimeTable | |
7 | + * @author elena | |
8 | + */ | |
9 | + | |
10 | + | |
11 | + | |
12 | +Ext.define('amdaModel.Statistics', { | |
13 | + | |
14 | + extend: 'amdaModel.AmdaTimeObject', | |
15 | + | |
16 | + fields : [ | |
17 | + { name: 'parameter' } , | |
18 | + { name: 'description' } | |
19 | + // { name: 'timesrc', type: 'string'} | |
20 | + ], | |
21 | + | |
22 | + getJsonValues : function (hasId) { | |
23 | + var values = new Object(); | |
24 | + if (hasId) { | |
25 | + values.id = this.get('id'); | |
26 | + } | |
27 | + | |
28 | + values.timesrc = this.get('timesrc'); | |
29 | + values.name = 'test'; //this.get('name'); | |
30 | + | |
31 | + | |
32 | + if (this.get('description').match(/[a-z,0-9]/gi) != null) { | |
33 | + values.description = this.get('description'); | |
34 | + } | |
35 | +// if (this.get('history').match(/[a-z,0-9]/gi) != null) { | |
36 | +// values.history = this.get('history'); | |
37 | +// } | |
38 | + values.objName = this.get('objName'); | |
39 | + values.objFormat = this.get('objFormat'); | |
40 | + | |
41 | +// values.cacheToken = this.get('cacheToken'); | |
42 | + values.parameter = this.get('parameter'); | |
43 | + if (values.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0]){ | |
44 | + // get complete timeTables collection | |
45 | + var timeTables = this.get('timeTables'); | |
46 | + // init an empty array for timeTables | |
47 | + values.timeTables=[]; | |
48 | + // for each interval record | |
49 | + Ext.Array.each(timeTables, function(item, index, all){ | |
50 | + if (!item.$className) { | |
51 | + values.timeTables[index] = {timeTableName : item.timeTableName, id : item.id}; | |
52 | + } | |
53 | + // get Json simplified value | |
54 | + else { | |
55 | + values.timeTables[index] = item.getJsonValues(); | |
56 | + } | |
57 | + }); | |
58 | + } else { | |
59 | + values.startDate = this.get('startDate'); | |
60 | + values.stopDate = this.get('stopDate'); | |
61 | + values.durationDay = this.get('durationDay'); | |
62 | + values.durationHour = this.get('durationHour'); | |
63 | + values.durationMin = this.get('durationMin'); | |
64 | + values.durationSec = this.get('durationSec'); | |
65 | + } | |
66 | + | |
67 | + values.leaf = true; | |
68 | + values.nodeType = 'statistics'; | |
69 | + | |
70 | + return values; | |
71 | + } | |
72 | + | |
73 | + | |
74 | + | |
75 | +}); | |
0 | 76 | \ No newline at end of file |
... | ... |
... | ... | @@ -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 | 60 | var menuItems = |
61 | 61 | [/*{ |
62 | 62 | fnId : 'mult-shareMulti', |
63 | - text : 'Share selected '+amdaModel.TimeTableNode.objectName+'s' | |
63 | + text : 'Share selected '+this.self.objectName+'s' | |
64 | 64 | },*/{ |
65 | 65 | fnId : 'mult-downloadMulti', |
66 | - text : 'Download selected '+amdaModel.TimeTableNode.objectName+'s' | |
66 | + text : 'Download selected '+this.self.objectName+'s' | |
67 | 67 | },{ |
68 | 68 | fnId : 'mult-operationsMulti', |
69 | 69 | text : 'Operations' |
... | ... | @@ -73,18 +73,21 @@ Ext.define('amdaModel.TimeTableNode', { |
73 | 73 | }, |
74 | 74 | |
75 | 75 | getAllContextMenuItems: function(){ |
76 | - | |
77 | - var menuItems = this.allMenuItems(amdaModel.TimeTableNode.objectName); | |
76 | + | |
77 | + var menuItems = this.allMenuItems(); | |
78 | 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 | 91 | onMenuItemClick : function(menu,item,event) { |
89 | 92 | |
90 | 93 | this.callParent(arguments); |
... | ... |
js/app/views/CatalogUI.js
... | ... | @@ -10,103 +10,255 @@ |
10 | 10 | Ext.define('amdaUI.CatalogUI', { |
11 | 11 | extend: 'Ext.container.Container', |
12 | 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 | 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 | 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 | 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 | 256 | this.fieldName = new Ext.form.field.Text({ |
104 | - fieldLabel: 'Name*', | |
257 | + fieldLabel: 'Name', | |
105 | 258 | allowBlank : false, |
106 | 259 | stripCharsRe: /(^\s+|\s+$)/g, |
107 | 260 | emptyText: 'Please no spaces!', |
108 | 261 | name: 'name', |
109 | - anchor: '100%', | |
110 | 262 | validateOnChange: false, |
111 | 263 | validateOnBlur: false, |
112 | 264 | validFlag: false, |
... | ... | @@ -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 | 274 | columns: [ |
298 | 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 | 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 | 331 | fieldDefaults: { labelWidth: 80, labelAlign : 'top' }, |
309 | 332 | items: [ |
310 | 333 | { |
311 | - xtype: 'form', | |
312 | - region: 'center', | |
334 | + xtype: 'form', | |
313 | 335 | flex: 1, |
314 | 336 | buttonAlign: 'left', |
315 | - bodyStyle: {background : '#dfe8f6'}, | |
316 | - padding: '5 5 5 5', | |
337 | +// title : 'Information', | |
317 | 338 | layout: {type: 'vbox', pack: 'start', align: 'stretch'}, |
318 | 339 | items : [ |
319 | - this.fieldName, | |
320 | - { | |
340 | + this.fieldName, | |
341 | + { | |
321 | 342 | xtype: 'fieldcontainer', |
322 | 343 | layout: 'hbox', |
323 | 344 | items: [ |
... | ... | @@ -328,65 +349,111 @@ Ext.define('amdaUI.CatalogUI', { |
328 | 349 | }, |
329 | 350 | { xtype: 'splitter' }, |
330 | 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 | 444 | bodyStyle: {background : '#dfe8f6'}, |
366 | - padding: '5 5 5 5', | |
445 | +// padding: '3', | |
367 | 446 | flex: 2, |
368 | 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 | 458 | var myConf = { |
392 | 459 | layout: 'border', |
... | ... |
... | ... | @@ -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('amdaUI.TabResultUI', { |
37 | 37 | break; |
38 | 38 | case 'download': var title = 'Download Results'; |
39 | 39 | break; |
40 | + case 'statistics': var title = 'Statistics Results'; | |
41 | + break; | |
40 | 42 | default: |
41 | 43 | } |
42 | 44 | var newConfig = { |
... | ... | @@ -54,7 +56,7 @@ Ext.define('amdaUI.TabResultUI', { |
54 | 56 | scope : this, |
55 | 57 | beforeclose : function() { |
56 | 58 | //delete linked nodes connected to ResultModule and corresponding to this Tab |
57 | - var module = myDesktopApp.getLoadeModule(myDesktopApp.dynamicModules.result.id); | |
59 | + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id); | |
58 | 60 | if (module.linkedNodes) { |
59 | 61 | var indices = new Array(); |
60 | 62 | var i =0; |
... | ... | @@ -105,6 +107,16 @@ Ext.define('amdaUI.ResultItem', { |
105 | 107 | this); |
106 | 108 | }, |
107 | 109 | |
110 | + saveCatalog: function(folderId,ttName) { | |
111 | + this.linkedNode = Ext.create('amdaModel.CatalogNode',{leaf : true}); | |
112 | + AmdaAction.getTmpObject( | |
113 | + folderId, | |
114 | + ttName, | |
115 | + this.linkedNode.get('nodeType'), | |
116 | + this.getResultCallback, | |
117 | + this); | |
118 | + }, | |
119 | + | |
108 | 120 | getResultCallback : function(result,remoteEvent){//result, e) { |
109 | 121 | var t = remoteEvent.getTransaction(); |
110 | 122 | //AKKA - catch error |
... | ... | @@ -120,8 +132,8 @@ Ext.define('amdaUI.ResultItem', { |
120 | 132 | return; |
121 | 133 | } |
122 | 134 | |
123 | - var paramObj = Ext.create(this.linkedNode.get('objectDataModel'), result); | |
124 | - paramObj.set('fromPlugin',true); | |
135 | + var paramObj = Ext.create(this.linkedNode.get('objectDataModel'), result); | |
136 | + paramObj.set('fromPlugin',true); | |
125 | 137 | paramObj.set('intervals',result.intervals); |
126 | 138 | // set parameter into node |
127 | 139 | this.linkedNode.set('object',paramObj); |
... | ... | @@ -130,7 +142,7 @@ Ext.define('amdaUI.ResultItem', { |
130 | 142 | myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function (module) { |
131 | 143 | module.setLinkedNode(me.linkedNode); |
132 | 144 | // Edition of parameter into parameter Module |
133 | - me.linkedNode.editInModule(); | |
145 | + me.linkedNode.editInModule(); | |
134 | 146 | }); |
135 | 147 | }, |
136 | 148 | |
... | ... | @@ -251,6 +263,35 @@ Ext.define('amdaUI.ResultItem', { |
251 | 263 | } |
252 | 264 | ] |
253 | 265 | }; |
266 | + var configCat = { | |
267 | + intId : config.title, | |
268 | + height : height, | |
269 | + title: jobtitle, | |
270 | + collapsible: true, | |
271 | + defaultType: 'button', | |
272 | + items :[ | |
273 | + { | |
274 | + xtype: 'label', | |
275 | + text: 'Catalog ' | |
276 | + }, | |
277 | + { | |
278 | + text: 'Edit/Save', | |
279 | + scope : this, | |
280 | + handler: function() { | |
281 | + this.saveCatalog(config.folderId,config.resultId); | |
282 | + } | |
283 | + }, | |
284 | + { | |
285 | + text: 'Delete', | |
286 | + scope : this, | |
287 | + handler: function() { | |
288 | + this.delete(config.processId); | |
289 | + this.ownerCt.remove(this); | |
290 | + } | |
291 | + } | |
292 | + ] | |
293 | + }; | |
294 | + | |
254 | 295 | //TODO make this properly |
255 | 296 | |
256 | 297 | var configPlot = { |
... | ... | @@ -329,6 +370,9 @@ Ext.define('amdaUI.ResultItem', { |
329 | 370 | case 'condition' : |
330 | 371 | Ext.apply(this, configTT); |
331 | 372 | break; |
373 | + case 'statistics' : | |
374 | + Ext.apply(this, configCat); | |
375 | + break; | |
332 | 376 | case 'request' : |
333 | 377 | Ext.apply(this, configPlot); |
334 | 378 | break; |
... | ... |
js/app/views/TimeTableUI.js
... | ... | @@ -30,6 +30,7 @@ Ext.define('amdaUI.TimeTableUI', { |
30 | 30 | }, |
31 | 31 | |
32 | 32 | status: null, |
33 | + isCatalog : false, | |
33 | 34 | |
34 | 35 | constructor: function(config) { |
35 | 36 | this.init(config); |
... | ... | @@ -116,7 +117,7 @@ Ext.define('amdaUI.TimeTableUI', { |
116 | 117 | else |
117 | 118 | { |
118 | 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 | 123 | else |
... | ... |
js/resources/css/amda.css
... | ... | @@ -79,6 +79,10 @@ |
79 | 79 | background-image:url( ../images/16x16/search.png ) !important; |
80 | 80 | } |
81 | 81 | |
82 | +.icon-statistics { | |
83 | + background-image:url( ../images/16x16/statistics.png ) !important; | |
84 | +} | |
85 | + | |
82 | 86 | .icon-manage-ws { |
83 | 87 | background-image:url( ../images/16x16/wsManager.png ) !important; |
84 | 88 | } |
... | ... | @@ -385,3 +389,8 @@ p + p { |
385 | 389 | font-style: italic !important; |
386 | 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 | +} | |
... | ... |
738 Bytes
838 Bytes
1.49 KB
3.68 KB
php/classes/AmdaAction.php
... | ... | @@ -581,7 +581,10 @@ class AmdaAction { |
581 | 581 | switch ($nodeType) { |
582 | 582 | case 'timeTable' : |
583 | 583 | $objectMgr = new TimeTableMgr(); |
584 | - break; | |
584 | + break; | |
585 | + case 'catalog' : | |
586 | + $objectMgr = new CatalogMgr(); | |
587 | + break; | |
585 | 588 | default: |
586 | 589 | return array("error" => $nodeType." NOT_IMPLEMENTED_YET"); |
587 | 590 | } |
... | ... | @@ -631,6 +634,9 @@ class AmdaAction { |
631 | 634 | break; |
632 | 635 | case 'timeTable' : |
633 | 636 | $objectMgr = new TimeTableMgr(); |
637 | + break; | |
638 | + case 'catalog' : | |
639 | + $objectMgr = new CatalogMgr(); | |
634 | 640 | break; |
635 | 641 | case 'condition' : |
636 | 642 | case 'request' : |
... | ... | @@ -667,6 +673,9 @@ class AmdaAction { |
667 | 673 | break; |
668 | 674 | case 'timeTable' : |
669 | 675 | $objectMgr = new TimeTableMgr(); |
676 | + break; | |
677 | + case 'catalog' : | |
678 | + $objectMgr = new Catalog(); | |
670 | 679 | break; |
671 | 680 | case 'condition' : |
672 | 681 | case 'request' : |
... | ... | @@ -698,6 +707,9 @@ class AmdaAction { |
698 | 707 | break; |
699 | 708 | case 'timeTable' : |
700 | 709 | $objectMgr = new TimeTableMgr(); |
710 | + break; | |
711 | + case 'catalog' : | |
712 | + $objectMgr = new CatalogMgr(); | |
701 | 713 | break; |
702 | 714 | case 'condition' : |
703 | 715 | case 'request' : |
... | ... | @@ -726,7 +738,10 @@ class AmdaAction { |
726 | 738 | break; |
727 | 739 | case 'timeTable' : |
728 | 740 | $objectMgr = new TimeTableMgr(); |
729 | - break; | |
741 | + break; | |
742 | + case 'catalog' : | |
743 | + $objectMgr = new CatalogMgr(); | |
744 | + break; | |
730 | 745 | case 'condition' : |
731 | 746 | case 'request' : |
732 | 747 | $objectMgr = new RequestMgr($obj->nodeType); |
... | ... | @@ -747,8 +762,12 @@ class AmdaAction { |
747 | 762 | $objectMgr = new DerivedParamMgr($obj->nodeType); |
748 | 763 | break; |
749 | 764 | case 'timeTable' : |
765 | + case 'sharedtimeTable' : | |
750 | 766 | $objectMgr = new TimeTableMgr(); |
751 | 767 | break; |
768 | + case 'catalog' : | |
769 | + $objectMgr = new CatalogMgr(); | |
770 | + break; | |
752 | 771 | case 'condition' : |
753 | 772 | case 'request' : |
754 | 773 | $objectMgr = new RequestMgr($obj->nodeType); |
... | ... | @@ -927,15 +946,27 @@ class AmdaAction { |
927 | 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 | 955 | public function initTTCacheFromTT($id, $type) |
931 | 956 | { |
932 | 957 | $cacheMgr = new TimeTableCacheMgr(); |
933 | 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 | 970 | return $cacheMgr->initFromTmpObject($folderId, $name); |
940 | 971 | } |
941 | 972 | |
... | ... | @@ -947,7 +978,9 @@ class AmdaAction { |
947 | 978 | |
948 | 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 | 984 | return $cacheMgr->getIntervals($o->start,$o->limit,$o->sort,$o->filter); |
952 | 985 | } |
953 | 986 | |
... | ... | @@ -1201,8 +1234,8 @@ class AmdaAction { |
1201 | 1234 | //AKKA - New action to clean user WS |
1202 | 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 | 1241 | public function deleteSpecialInfo($name) |
... | ... |
... | ... | @@ -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 | 320 | \ No newline at end of file |
... | ... |
... | ... | @@ -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 | 228 | \ No newline at end of file |
... | ... |
... | ... | @@ -0,0 +1,114 @@ |
1 | +<?php | |
2 | +class IntervalCacheObject | |
3 | +{ | |
4 | + protected $id = -1; | |
5 | + protected $index = -1; | |
6 | + protected $start = 0; | |
7 | + protected $stop = 0; | |
8 | + protected $isNew = false; | |
9 | + protected $isModified = false; | |
10 | + | |
11 | + function __construct($id, $index) { | |
12 | + $this->id = $id; | |
13 | + $this->index = $index; | |
14 | + } | |
15 | + | |
16 | + public function getId() { | |
17 | + return $this->id; | |
18 | + } | |
19 | + | |
20 | + public function getIndex() { | |
21 | + return $this->index; | |
22 | + } | |
23 | + | |
24 | + public function setIndex($index) { | |
25 | + $this->index = $index; | |
26 | + } | |
27 | + | |
28 | + public function getStartToStamp() { | |
29 | + return $this->start; | |
30 | + } | |
31 | + | |
32 | + public function getStartToISO() { | |
33 | + return CacheTools::stamp2iso($this->start); | |
34 | + } | |
35 | + | |
36 | + public function setStartFromStamp($stamp) { | |
37 | + $this->start = $stamp; | |
38 | + } | |
39 | + | |
40 | + public function setStartFromISO($iso) { | |
41 | + $this->start = CacheTools::iso2stamp($iso); | |
42 | + } | |
43 | + | |
44 | + public function getStopToStamp() { | |
45 | + return $this->stop; | |
46 | + } | |
47 | + | |
48 | + public function getStopToISO() { | |
49 | + return CacheTools::stamp2iso($this->stop); | |
50 | + } | |
51 | + | |
52 | + public function setStopFromStamp($stamp) { | |
53 | + $this->stop = $stamp; | |
54 | + } | |
55 | + | |
56 | + public function setStopFromISO($iso) { | |
57 | + $this->stop = CacheTools::iso2stamp($iso); | |
58 | + } | |
59 | + | |
60 | + public function getDuration() { | |
61 | + return ($this->stop-$this->start); | |
62 | + } | |
63 | + | |
64 | + public function isModified() { | |
65 | + return $this->isModified; | |
66 | + } | |
67 | + | |
68 | + public function setIsModified($isModified) { | |
69 | + $this->isModified = $isModified; | |
70 | + } | |
71 | + | |
72 | + public function isNew() { | |
73 | + return $this->isNew; | |
74 | + } | |
75 | + | |
76 | + public function setIsNew($isNew) { | |
77 | + $this->isNew = $isNew; | |
78 | + } | |
79 | + | |
80 | + public function toArray() { | |
81 | + $result = array( | |
82 | + "cacheId" => $this->id, | |
83 | + "start" => $this->getStartToISO(), | |
84 | + "stop" => $this->getStopToISO() | |
85 | + ); | |
86 | + if ($this->isNew) | |
87 | + $result["isNew"] = true; | |
88 | + if ($this->isModified) | |
89 | + $result["isModified"] = true; | |
90 | + | |
91 | + return $result; | |
92 | + } | |
93 | + | |
94 | + | |
95 | + | |
96 | + public function writeBin($handle) { | |
97 | + fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified)); | |
98 | + } | |
99 | + | |
100 | + public function loadBin($handle) { | |
101 | + $array = unpack('L6int',fread($handle,6*4)); | |
102 | + $this->id = $array['int1']; | |
103 | + $this->index = $array['int2']; | |
104 | + $this->start = $array['int3']; | |
105 | + $this->stop = $array['int4']; | |
106 | + $this->isNew = $array['int5']; | |
107 | + $this->isModified = $array['int6']; | |
108 | + } | |
109 | + | |
110 | + public function dump() { | |
111 | + echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL; | |
112 | + } | |
113 | +} | |
114 | +?> | |
0 | 115 | \ No newline at end of file |
... | ... |
php/classes/TimeTableCacheMgr.php
... | ... | @@ -27,8 +27,8 @@ class SortPartCacheObject |
27 | 27 | public static $DIRECTION_ASC = 1; |
28 | 28 | public static $DIRECTION_DES = 2; |
29 | 29 | |
30 | - private $type; | |
31 | - private $dir; | |
30 | + protected $type; | |
31 | + protected $dir; | |
32 | 32 | |
33 | 33 | function __construct() { |
34 | 34 | $this->type = self::$TYPE_UNKNOWN; |
... | ... | @@ -172,7 +172,7 @@ class SortPartCacheObject |
172 | 172 | |
173 | 173 | class SortCacheObject |
174 | 174 | { |
175 | - private $parts = array(); | |
175 | + protected $parts = array(); | |
176 | 176 | |
177 | 177 | function __construct() { |
178 | 178 | } |
... | ... | @@ -286,9 +286,9 @@ class FilterPartCacheObject |
286 | 286 | public static $OPERATION_GT = 2; |
287 | 287 | public static $OPERATION_EQ = 3; |
288 | 288 | |
289 | - private $type; | |
290 | - private $op; | |
291 | - private $value; | |
289 | + protected $type; | |
290 | + protected $op; | |
291 | + protected $value; | |
292 | 292 | |
293 | 293 | function __construct() { |
294 | 294 | $this->type = self::$TYPE_UNKNOWN; |
... | ... | @@ -470,7 +470,7 @@ class FilterPartCacheObject |
470 | 470 | |
471 | 471 | class FilterCacheObject |
472 | 472 | { |
473 | - private $parts = array(); | |
473 | + protected $parts = array(); | |
474 | 474 | |
475 | 475 | function __construct() { |
476 | 476 | |
... | ... | @@ -555,631 +555,12 @@ class FilterCacheObject |
555 | 555 | } |
556 | 556 | } |
557 | 557 | |
558 | -class IntervalCacheObject | |
558 | + class TimeTableCacheMgr | |
559 | 559 | { |
560 | - private $id = -1; | |
561 | - private $index = -1; | |
562 | - private $start = 0; | |
563 | - private $stop = 0; | |
564 | - private $isNew = false; | |
565 | - private $isModified = false; | |
566 | - | |
567 | - function __construct($id, $index) { | |
568 | - $this->id = $id; | |
569 | - $this->index = $index; | |
570 | - } | |
571 | - | |
572 | - public function getId() { | |
573 | - return $this->id; | |
574 | - } | |
575 | - | |
576 | - public function getIndex() { | |
577 | - return $this->index; | |
578 | - } | |
579 | - | |
580 | - public function setIndex($index) { | |
581 | - $this->index = $index; | |
582 | - } | |
583 | - | |
584 | - public function getStartToStamp() { | |
585 | - return $this->start; | |
586 | - } | |
587 | - | |
588 | - public function getStartToISO() { | |
589 | - return CacheTools::stamp2iso($this->start); | |
590 | - } | |
591 | - | |
592 | - public function setStartFromStamp($stamp) { | |
593 | - $this->start = $stamp; | |
594 | - } | |
595 | - | |
596 | - public function setStartFromISO($iso) { | |
597 | - $this->start = CacheTools::iso2stamp($iso); | |
598 | - } | |
599 | - | |
600 | - public function getStopToStamp() { | |
601 | - return $this->stop; | |
602 | - } | |
603 | - | |
604 | - public function getStopToISO() { | |
605 | - return CacheTools::stamp2iso($this->stop); | |
606 | - } | |
607 | - | |
608 | - public function setStopFromStamp($stamp) { | |
609 | - $this->stop = $stamp; | |
610 | - } | |
611 | - | |
612 | - public function setStopFromISO($iso) { | |
613 | - $this->stop = CacheTools::iso2stamp($iso); | |
614 | - } | |
615 | - | |
616 | - public function getDuration() { | |
617 | - return ($this->stop-$this->start); | |
618 | - } | |
619 | - | |
620 | - public function isModified() { | |
621 | - return $this->isModified; | |
622 | - } | |
623 | - | |
624 | - public function setIsModified($isModified) { | |
625 | - $this->isModified = $isModified; | |
626 | - } | |
627 | - | |
628 | - public function isNew() { | |
629 | - return $this->isNew; | |
630 | - } | |
631 | - | |
632 | - public function setIsNew($isNew) { | |
633 | - $this->isNew = $isNew; | |
634 | - } | |
635 | - | |
636 | - public function toArray() { | |
637 | - $result = array( | |
638 | - "cacheId" => $this->id, | |
639 | - "start" => $this->getStartToISO(), | |
640 | - "stop" => $this->getStopToISO() | |
641 | - ); | |
642 | - if ($this->isNew) | |
643 | - $result["isNew"] = true; | |
644 | - if ($this->isModified) | |
645 | - $result["isModified"] = true; | |
646 | - | |
647 | - return $result; | |
648 | - } | |
649 | - | |
650 | - | |
651 | - | |
652 | - public function writeBin($handle) { | |
653 | - fwrite($handle,pack('L6',$this->id,$this->index,$this->start,$this->stop,$this->isNew,$this->isModified)); | |
654 | - } | |
655 | - | |
656 | - public function loadBin($handle) { | |
657 | - $array = unpack('L6int',fread($handle,6*4)); | |
658 | - $this->id = $array['int1']; | |
659 | - $this->index = $array['int2']; | |
660 | - $this->start = $array['int3']; | |
661 | - $this->stop = $array['int4']; | |
662 | - $this->isNew = $array['int5']; | |
663 | - $this->isModified = $array['int6']; | |
664 | - } | |
665 | - | |
666 | - public function dump() { | |
667 | - echo " => Interval : id = ".$this->id.", index = ".$this->index.", start = ".$this->start.", stop = ".$this->stop.", isNew = ".$this->isNew.", isModified = ".$this->isModified.PHP_EOL; | |
668 | - } | |
669 | -} | |
670 | - | |
671 | -class TimeTableCacheObject | |
672 | -{ | |
673 | - private static $format_version = 1; | |
674 | - private static $token_len = 8; | |
675 | - | |
676 | - private $token = ""; | |
677 | - | |
678 | - private $lastId = 0; | |
679 | - | |
680 | - private $intervals = array(); | |
681 | - private $indexes = array(); | |
682 | - | |
683 | - private $isModified = false; | |
684 | - | |
685 | - private $filter = null; | |
686 | - | |
687 | - private $sort = null; | |
688 | - | |
689 | - function __construct() { | |
690 | - $this->token = $this->getRandomToken(); | |
691 | - $this->filter = new FilterCacheObject(); | |
692 | - $this->sort = new SortCacheObject(); | |
693 | - } | |
694 | - | |
695 | - public function reset() { | |
696 | - $this->lastId = 0; | |
697 | - $this->isModified = false; | |
698 | - $this->intervals = array(); | |
699 | - $this->indexes = array(); | |
700 | - unset($this->filter); | |
701 | - $this->filter = new FilterCacheObject();; | |
702 | - unset($this->sort); | |
703 | - $this->sort = new SortCacheObject(); | |
704 | - } | |
705 | - | |
706 | - public function setIsModified($isModified) { | |
707 | - $this->isModified = $isModified; | |
708 | - } | |
709 | - | |
710 | - public function addInterval($startIso, $stopIso, $isNew = false, $index = -1) { | |
711 | - $interval = new IntervalCacheObject($this->lastId, count($this->intervals)); | |
712 | - ++$this->lastId; | |
713 | - $interval->setStartFromISO($startIso); | |
714 | - $interval->setStopFromISO($stopIso); | |
715 | - $interval->setIsNew($isNew); | |
716 | - array_push($this->intervals, $interval); | |
717 | - if ($index < 0) | |
718 | - array_push($this->indexes, count($this->intervals) - 1); | |
719 | - else | |
720 | - array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1)); | |
721 | - if ($isNew) | |
722 | - $this->isModified = true; | |
723 | - return $interval; | |
724 | - } | |
725 | - | |
726 | - public function removeIntervalFromId($id) { | |
727 | - for ($i = 0; $i < count($this->intervals); ++$i) | |
728 | - { | |
729 | - if ($this->intervals[$i]->getId() == $id) | |
730 | - { | |
731 | - //Remove interval | |
732 | - array_splice($this->intervals, $i, 1); | |
733 | - //Remove interval index if exist in indexes list | |
734 | - for ($j = 0; $j < count($this->indexes); ++$j) | |
735 | - { | |
736 | - if ($this->indexes[$j] == $i) | |
737 | - { | |
738 | - array_splice($this->indexes, $j, 1); | |
739 | - break; | |
740 | - } | |
741 | - } | |
742 | - //Update indexes list | |
743 | - for ($j = 0; $j < count($this->indexes); ++$j) | |
744 | - { | |
745 | - if ($this->indexes[$j] >= $i) | |
746 | - $this->indexes[$j]--; | |
747 | - } | |
748 | - $this->isModified = true; | |
749 | - return true; | |
750 | - } | |
751 | - } | |
752 | - | |
753 | - return false; | |
754 | - } | |
755 | - | |
756 | - public function modifyIntervalFromId($id, $start, $stop) { | |
757 | - foreach ($this->intervals as $interval) | |
758 | - { | |
759 | - if ($interval->getId() == $id) | |
760 | - { | |
761 | - if (isset($start)) | |
762 | - $interval->setStartFromISO($start); | |
763 | - if (isset($stop)) | |
764 | - $interval->setStopFromISO($stop); | |
765 | - $interval->setIsModified(true); | |
766 | - $this->isModified = true; | |
767 | - return true; | |
768 | - } | |
769 | - } | |
770 | - | |
771 | - return false; | |
772 | - } | |
773 | - | |
774 | - public function operationIntervals($extendTime, $shiftTime) { | |
775 | - if (($extendTime == 0) && ($shiftTime == 0)) | |
776 | - //Nothing to do | |
777 | - return true; | |
778 | - | |
779 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
780 | - $start = $this->intervals[$this->indexes[$i]]->getStartToStamp(); | |
781 | - $start -= $extendTime; | |
782 | - $start += $shiftTime; | |
783 | - $this->intervals[$this->indexes[$i]]->setStartFromStamp($start); | |
784 | - | |
785 | - $stop = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
786 | - $stop += $extendTime; | |
787 | - $stop += $shiftTime; | |
788 | - $this->intervals[$this->indexes[$i]]->setStopFromStamp($stop); | |
789 | - | |
790 | - $this->intervals[$this->indexes[$i]]->setIsModified(true); | |
791 | - $this->isModified = true; | |
792 | - } | |
793 | - | |
794 | - return true; | |
795 | - } | |
796 | - | |
797 | - public function mergeIntervals() { | |
798 | - $this->sort->reset(); | |
799 | - | |
800 | - $this->sort->loadFromObject( | |
801 | - array( | |
802 | - (object)array("property" => "start", "direction" => "DESC") | |
803 | - ) | |
804 | - ); | |
805 | - | |
806 | - $this->updateIndexes(); | |
807 | - | |
808 | - $merged_intervals = array(); | |
809 | - | |
810 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
811 | - if (count($merged_intervals) == 0) | |
812 | - { | |
813 | - array_push($merged_intervals,array( | |
814 | - "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(), | |
815 | - "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(), | |
816 | - "mod" => FALSE) | |
817 | - ); | |
818 | - continue; | |
819 | - } | |
820 | - if (($merged_intervals[count($merged_intervals)-1]["stop"] >= $this->intervals[$this->indexes[$i]]->getStartToStamp()) && | |
821 | - ($merged_intervals[count($merged_intervals)-1]["stop"] < $this->intervals[$this->indexes[$i]]->getStopToStamp())) | |
822 | - { | |
823 | - $merged_intervals[count($merged_intervals)-1]["stop"] = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
824 | - $merged_intervals[count($merged_intervals)-1]["mod"] = TRUE; | |
825 | - } | |
826 | - else | |
827 | - array_push($merged_intervals,array( | |
828 | - "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(), | |
829 | - "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(), | |
830 | - "mod" => FALSE) | |
831 | - ); | |
832 | - } | |
833 | - | |
834 | - $this->reset(); | |
835 | - | |
836 | - foreach ($merged_intervals as $merged_interval) { | |
837 | - $interval = new IntervalCacheObject($this->lastId, count($this->intervals)); | |
838 | - ++$this->lastId; | |
839 | - $interval->setStartFromStamp($merged_interval["start"]); | |
840 | - $interval->setStopFromStamp($merged_interval["stop"]); | |
841 | - $interval->setIsNew($merged_interval["mod"]); | |
842 | - if ($merged_interval["mod"]) | |
843 | - $this->isModified = true; | |
844 | - array_push($this->intervals, $interval); | |
845 | - array_push($this->indexes, count($this->intervals) - 1); | |
846 | - } | |
847 | - | |
848 | - return true; | |
849 | - } | |
850 | - | |
851 | - public function getStatistics() { | |
852 | - $minTime = NULL; | |
853 | - $maxTime = NULL; | |
854 | - $minDuration = NULL; | |
855 | - $maxDuration = NULL; | |
856 | - $indexMinDuration = -1; | |
857 | - $indexMaxDuration = -1; | |
858 | - | |
859 | - $nbValid = 0; | |
860 | - $durationTotal = 0; | |
861 | - | |
862 | - //Min & Max | |
863 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
864 | - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
865 | - //Invalid interval | |
866 | - continue; | |
867 | - | |
868 | - ++$nbValid; | |
869 | - $durationTotal += $this->intervals[$this->indexes[$i]]->getDuration(); | |
870 | - | |
871 | - if (!isset($minTime) || ($minTime > $this->intervals[$this->indexes[$i]]->getStartToStamp())) | |
872 | - $minTime = $this->intervals[$this->indexes[$i]]->getStartToStamp(); | |
873 | - | |
874 | - if (!isset($maxTime) || ($maxTime < $this->intervals[$this->indexes[$i]]->getStopToStamp())) | |
875 | - $maxTime = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
876 | - | |
877 | - if (!isset($minDuration) || ($minDuration > $this->intervals[$this->indexes[$i]]->getDuration())) | |
878 | - { | |
879 | - $minDuration = $this->intervals[$this->indexes[$i]]->getDuration(); | |
880 | - $indexMinDuration = $i; | |
881 | - } | |
882 | - | |
883 | - if (!isset($maxDuration) || ($maxDuration < $this->intervals[$this->indexes[$i]]->getDuration())) | |
884 | - { | |
885 | - $maxDuration = $this->intervals[$this->indexes[$i]]->getDuration(); | |
886 | - $indexMaxDuration = $i; | |
887 | - } | |
888 | - } | |
889 | - | |
890 | - if (!isset($minTime)) | |
891 | - $minTime = 0; | |
892 | - if (!isset($maxTime)) | |
893 | - $maxTime = 0; | |
894 | - if (!isset($minDuration)) | |
895 | - $minDuration = 0; | |
896 | - if (!isset($maxDuration)) | |
897 | - $maxDuration = 0; | |
898 | - | |
899 | - | |
900 | - //Mean | |
901 | - if ($nbValid > 0) | |
902 | - $mean = $durationTotal / $nbValid; | |
903 | - else | |
904 | - $mean = 0; | |
905 | - | |
906 | - //Standard deviation | |
907 | - $pow = 0; | |
908 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
909 | - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
910 | - //Invalid interval | |
911 | - continue; | |
912 | - | |
913 | - $pow += pow($this->intervals[$this->indexes[$i]]->getDuration()-$mean,2); | |
914 | - } | |
915 | - if ($nbValid > 0) | |
916 | - $variance = $pow/$nbValid; | |
917 | - else | |
918 | - $variance = 0; | |
919 | - $stdev = sqrt($variance); | |
920 | - | |
921 | - //Sort by duration to get median | |
922 | - $this->sort->reset(); | |
923 | - | |
924 | - $this->sort->loadFromObject( | |
925 | - array( | |
926 | - (object)array("property" => "durationSec", "direction" => "DESC") | |
927 | - ) | |
928 | - ); | |
929 | - | |
930 | - $this->updateIndexes(); | |
931 | - | |
932 | - $durations = array(); | |
933 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
934 | - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
935 | - //Invalid interval | |
936 | - continue; | |
937 | - | |
938 | - array_push($durations, $this->intervals[$this->indexes[$i]]->getDuration()); | |
939 | - } | |
940 | - | |
941 | - if (count($durations) > 0) | |
942 | - { | |
943 | - if (count($durations)%2 > 0) { | |
944 | - $median = $durations[count($durations)/2-0.5]; | |
945 | - } else { // else the number of intervals is an even number | |
946 | - $median = ($durations[count($durations)/2-1] + $durations[count($durations)/2])/2; | |
947 | - } | |
948 | - } | |
949 | - else | |
950 | - $median = 0; | |
951 | - | |
952 | - //Merge intervals to get density | |
953 | - $this->mergeIntervals(); | |
954 | - | |
955 | - $durationMergedTotal = 0; | |
956 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
957 | - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
958 | - //Invalid interval | |
959 | - continue; | |
960 | - | |
961 | - $durationMergedTotal += $this->intervals[$this->indexes[$i]]->getDuration(); | |
962 | - } | |
963 | - | |
964 | - if (($maxTime-$minTime) > 0) | |
965 | - $density = (($durationMergedTotal/($maxTime-$minTime))); | |
966 | - else | |
967 | - $density = 0; | |
968 | - | |
969 | - return array( | |
970 | - "minDuration" => $minDuration, | |
971 | - "minDurationIndex"=> $indexMinDuration, | |
972 | - "maxDuration" => $maxDuration, | |
973 | - "maxDurationIndex"=> $indexMaxDuration, | |
974 | - "mean" => $mean, | |
975 | - "stdev" => $stdev, | |
976 | - "median" => $median, | |
977 | - "density" => $density); | |
978 | - } | |
979 | - | |
980 | - public function getStatus() { | |
981 | - $nbFiltered = count($this->intervals) - count($this->indexes); | |
982 | - | |
983 | - $nbModified = 0; | |
984 | - $nbNew = 0; | |
985 | - $nbInvalid = 0; | |
986 | - $nbValid = 0; | |
987 | - for ($i = 0; $i < count($this->indexes); ++$i) { | |
988 | - if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
989 | - ++$nbInvalid; | |
990 | - else | |
991 | - ++$nbValid; | |
992 | - if ($this->intervals[$this->indexes[$i]]->isModified()) | |
993 | - ++$nbModified; | |
994 | - if ($this->intervals[$this->indexes[$i]]->isNew()) | |
995 | - ++$nbNew; | |
996 | - } | |
997 | - | |
998 | - return array( | |
999 | - "nbFiltered" => $nbFiltered, | |
1000 | - "nbModified" => $nbModified, | |
1001 | - "nbNew" => $nbNew, | |
1002 | - "nbInvalid" => $nbInvalid, | |
1003 | - "nbValid" => $nbValid, | |
1004 | - "isModified" => $this->isModified | |
1005 | - ); | |
1006 | - } | |
1007 | - | |
1008 | - public function getIntervalsArray($startIndex, $limit,$skipInvalid = false) { | |
1009 | - $intervals = array(); | |
1010 | - | |
1011 | - if (!isset($startIndex)) | |
1012 | - $startIndex = 0; | |
1013 | - | |
1014 | - if (!isset($limit)) | |
1015 | - $limit = count($this->indexes); | |
1016 | - | |
1017 | - for ($i = 0; $i < $limit; ++$i) { | |
1018 | - if ($startIndex+$i >= count($this->indexes)) | |
1019 | - break; | |
1020 | - if ($skipInvalid && ($this->intervals[$this->indexes[$startIndex+$i]]->getDuration() <= 0)) | |
1021 | - continue; | |
1022 | - array_push($intervals, $this->intervals[$this->indexes[$startIndex+$i]]->toArray()); | |
1023 | - } | |
1024 | - return $intervals; | |
1025 | - } | |
1026 | - | |
1027 | - public function getLength() { | |
1028 | - return count($this->indexes); | |
1029 | - } | |
1030 | - | |
1031 | - public function getToken() { | |
1032 | - return $this->token; | |
1033 | - } | |
1034 | - | |
1035 | - public function getFilter() { | |
1036 | - return $this->filter; | |
1037 | - } | |
1038 | - | |
1039 | - public function getSort() { | |
1040 | - return $this->sort; | |
1041 | - } | |
1042 | - | |
1043 | - public function updateIndexes() { | |
1044 | - $this->indexes = array(); | |
1045 | - | |
1046 | - for ($i = 0; $i < count($this->intervals); ++$i) | |
1047 | - $this->intervals[$i]->setIndex($i); | |
1048 | - | |
1049 | - //Apply sort | |
1050 | - $sort_result = $this->sort->apply($this->intervals); | |
1051 | - | |
1052 | - //Apply filter | |
1053 | - for ($i = 0; $i < count($sort_result); ++$i) | |
1054 | - { | |
1055 | - if (!$this->filter->toFiltered($this->intervals[$sort_result[$i]])) | |
1056 | - array_push($this->indexes,$this->intervals[$sort_result[$i]]->getIndex()); | |
1057 | - } | |
1058 | - } | |
1059 | - | |
1060 | - public function writeBin($handle) { | |
1061 | - //Magic key ("TTC") | |
1062 | - fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C'))); | |
1063 | - | |
1064 | - //Version | |
1065 | - fwrite($handle,pack('L',TimeTableCacheObject::$format_version)); | |
1066 | - | |
1067 | - //Token | |
1068 | - for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i) | |
1069 | - fwrite($handle,pack('C',ord($this->token[$i]))); | |
1070 | - | |
1071 | - //Modified | |
1072 | - fwrite($handle,pack('L',$this->isModified)); | |
1073 | - | |
1074 | - //Filter | |
1075 | - $this->filter->writeBin($handle); | |
1076 | - | |
1077 | - //Sort | |
1078 | - $this->sort->writeBin($handle); | |
1079 | - | |
1080 | - //Intervals | |
1081 | - fwrite($handle,pack('L2',count($this->intervals), $this->lastId)); | |
1082 | - foreach($this->intervals as $interval) | |
1083 | - $interval->writeBin($handle); | |
1084 | - | |
1085 | - //Indexes | |
1086 | - fwrite($handle,pack('L',count($this->indexes))); | |
1087 | - foreach($this->indexes as $index) | |
1088 | - fwrite($handle,pack('L',$index)); | |
1089 | - } | |
1090 | - | |
1091 | - public function loadBin($handle) { | |
1092 | - //Magic key ("TTC") | |
1093 | - if (!$res = unpack('C3key',fread($handle,3))) | |
1094 | - return false; | |
1095 | - | |
1096 | - if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C'))) | |
1097 | - return false; | |
1098 | - | |
1099 | - //Version | |
1100 | - if (!$res = unpack('Lversion',fread($handle,4))) | |
1101 | - return false; | |
1102 | - if (($res['version'] != TimeTableCacheObject::$format_version)) | |
1103 | - return false; | |
1104 | - | |
1105 | - //Token | |
1106 | - $token = ""; | |
1107 | - for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i) | |
1108 | - { | |
1109 | - if (!$res = unpack('Ctoken',fread($handle,1))) | |
1110 | - return false; | |
1111 | - $token .= chr($res['token']); | |
1112 | - } | |
1113 | - $this->token = $token; | |
1114 | - | |
1115 | - //Modified | |
1116 | - if (!$res = unpack('Lmodified',fread($handle,4))) | |
1117 | - return false; | |
1118 | - $this->isModified = $res['modified']; | |
1119 | - | |
1120 | - //Filter | |
1121 | - $this->filter->loadBin($handle); | |
1122 | - | |
1123 | - //Sort | |
1124 | - $this->sort->loadBin($handle); | |
1125 | - | |
1126 | - //Intervals | |
1127 | - $res = unpack('L2data',fread($handle,2*4)); | |
1128 | - $nbIntervals = $res['data1']; | |
1129 | - $this->lastId = $res['data2']; | |
1130 | - for ($i = 0; $i < $nbIntervals; ++$i) | |
1131 | - { | |
1132 | - $interval = new IntervalCacheObject(-1); | |
1133 | - $interval->loadBin($handle); | |
1134 | - array_push($this->intervals, $interval); | |
1135 | - } | |
1136 | - | |
1137 | - //Indexes | |
1138 | - $res = unpack('Ldata',fread($handle,4)); | |
1139 | - $nbIndexes = $res['data']; | |
1140 | - for ($i = 0; $i < $nbIndexes; ++$i) | |
1141 | - { | |
1142 | - $res = unpack('Lindex',fread($handle,4)); | |
1143 | - array_push($this->indexes, $res['index']); | |
1144 | - } | |
1145 | - | |
1146 | - return true; | |
1147 | - } | |
1148 | - | |
1149 | - private function getRandomToken() { | |
1150 | - $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; | |
1151 | - return substr(str_shuffle($letters), 0, TimeTableCacheObject::$token_len); | |
1152 | - } | |
1153 | - | |
1154 | - public function dump() { | |
1155 | - echo " => TimeTableCacheObject : token = ".$this->token.", nb intervals = ".count($this->intervals).", last id = ".$this->lastId.", nb indexes = ".count($this->indexes).PHP_EOL; | |
1156 | - echo PHP_EOL; | |
1157 | - | |
1158 | - $this->filter->dump(); | |
1159 | - echo PHP_EOL; | |
1160 | - | |
1161 | - $this->sort->dump(); | |
1162 | - echo PHP_EOL; | |
1163 | - | |
1164 | - foreach ($this->intervals as $interval) | |
1165 | - $interval->dump(); | |
1166 | - echo PHP_EOL; | |
1167 | - | |
1168 | - echo " => Indexes list : "; | |
1169 | - foreach ($this->indexes as $index) | |
1170 | - { | |
1171 | - echo $index.", "; | |
1172 | - } | |
1173 | - echo PHP_EOL; | |
1174 | - } | |
1175 | -} | |
1176 | - | |
1177 | -class TimeTableCacheMgr | |
1178 | -{ | |
1179 | - private static $cache_file = "cacheTT"; | |
560 | + protected static $cache_file = "cacheTT"; | |
1180 | 561 | |
1181 | - private $ttMgr = null; | |
1182 | - private $cache = null; | |
562 | + protected $ttMgr = null; | |
563 | + protected $cache = null; | |
1183 | 564 | |
1184 | 565 | function __construct() { |
1185 | 566 | $this->ttMgr = new TimeTableMgr(); |
... | ... | @@ -1449,11 +830,11 @@ class TimeTableCacheMgr |
1449 | 830 | $this->cache->dump(); |
1450 | 831 | } |
1451 | 832 | |
1452 | - private function getCacheFilePath() { | |
833 | + protected function getCacheFilePath() { | |
1453 | 834 | return USERTTDIR.(self::$cache_file); |
1454 | 835 | } |
1455 | 836 | |
1456 | - private function saveToFile() { | |
837 | + protected function saveToFile() { | |
1457 | 838 | if (!isset($this->cache)) |
1458 | 839 | return false; |
1459 | 840 | $handle = fopen($this->getCacheFilePath(), 'wb'); |
... | ... | @@ -1468,7 +849,7 @@ class TimeTableCacheMgr |
1468 | 849 | return $result; |
1469 | 850 | } |
1470 | 851 | |
1471 | - private function loadFromFile() { | |
852 | + protected function loadFromFile() { | |
1472 | 853 | if (!file_exists($this->getCacheFilePath())) |
1473 | 854 | return false; |
1474 | 855 | $this->cache = new TimeTableCacheObject(); |
... | ... |
... | ... | @@ -0,0 +1,509 @@ |
1 | +<?php | |
2 | + | |
3 | +class TimeTableCacheObject | |
4 | +{ | |
5 | + protected static $format_version = 1; | |
6 | + protected static $token_len = 8; | |
7 | + | |
8 | + protected $token = ""; | |
9 | + | |
10 | + protected $lastId = 0; | |
11 | + | |
12 | + protected $intervals = array(); | |
13 | + protected $indexes = array(); | |
14 | + | |
15 | + protected $isModified = false; | |
16 | + | |
17 | + protected $filter = null; | |
18 | + | |
19 | + protected $sort = null; | |
20 | + | |
21 | + function __construct() { | |
22 | + $this->token = $this->getRandomToken(); | |
23 | + $this->filter = new FilterCacheObject(); | |
24 | + $this->sort = new SortCacheObject(); | |
25 | + } | |
26 | + | |
27 | + public function reset() { | |
28 | + $this->lastId = 0; | |
29 | + $this->isModified = false; | |
30 | + $this->intervals = array(); | |
31 | + $this->indexes = array(); | |
32 | + unset($this->filter); | |
33 | + $this->filter = new FilterCacheObject();; | |
34 | + unset($this->sort); | |
35 | + $this->sort = new SortCacheObject(); | |
36 | + } | |
37 | + | |
38 | + public function setIsModified($isModified) { | |
39 | + $this->isModified = $isModified; | |
40 | + } | |
41 | + | |
42 | + public function addInterval($startIso, $stopIso, $isNew = false, $index = -1) { | |
43 | + $interval = new IntervalCacheObject($this->lastId, count($this->intervals)); | |
44 | + ++$this->lastId; | |
45 | + $interval->setStartFromISO($startIso); | |
46 | + $interval->setStopFromISO($stopIso); | |
47 | + $interval->setIsNew($isNew); | |
48 | + array_push($this->intervals, $interval); | |
49 | + if ($index < 0) | |
50 | + array_push($this->indexes, count($this->intervals) - 1); | |
51 | + else | |
52 | + array_splice($this->indexes, $index, 0, array(count($this->intervals) - 1)); | |
53 | + if ($isNew) | |
54 | + $this->isModified = true; | |
55 | + return $interval; | |
56 | + } | |
57 | + | |
58 | + public function removeIntervalFromId($id) { | |
59 | + for ($i = 0; $i < count($this->intervals); ++$i) | |
60 | + { | |
61 | + if ($this->intervals[$i]->getId() == $id) | |
62 | + { | |
63 | + //Remove interval | |
64 | + array_splice($this->intervals, $i, 1); | |
65 | + //Remove interval index if exist in indexes list | |
66 | + for ($j = 0; $j < count($this->indexes); ++$j) | |
67 | + { | |
68 | + if ($this->indexes[$j] == $i) | |
69 | + { | |
70 | + array_splice($this->indexes, $j, 1); | |
71 | + break; | |
72 | + } | |
73 | + } | |
74 | + //Update indexes list | |
75 | + for ($j = 0; $j < count($this->indexes); ++$j) | |
76 | + { | |
77 | + if ($this->indexes[$j] >= $i) | |
78 | + $this->indexes[$j]--; | |
79 | + } | |
80 | + $this->isModified = true; | |
81 | + return true; | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + return false; | |
86 | + } | |
87 | + | |
88 | + public function modifyIntervalFromId($id, $start, $stop) { | |
89 | + foreach ($this->intervals as $interval) | |
90 | + { | |
91 | + if ($interval->getId() == $id) | |
92 | + { | |
93 | + if (isset($start)) | |
94 | + $interval->setStartFromISO($start); | |
95 | + if (isset($stop)) | |
96 | + $interval->setStopFromISO($stop); | |
97 | + $interval->setIsModified(true); | |
98 | + $this->isModified = true; | |
99 | + return true; | |
100 | + } | |
101 | + } | |
102 | + | |
103 | + return false; | |
104 | + } | |
105 | + | |
106 | + public function operationIntervals($extendTime, $shiftTime) { | |
107 | + if (($extendTime == 0) && ($shiftTime == 0)) | |
108 | + //Nothing to do | |
109 | + return true; | |
110 | + | |
111 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
112 | + $start = $this->intervals[$this->indexes[$i]]->getStartToStamp(); | |
113 | + $start -= $extendTime; | |
114 | + $start += $shiftTime; | |
115 | + $this->intervals[$this->indexes[$i]]->setStartFromStamp($start); | |
116 | + | |
117 | + $stop = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
118 | + $stop += $extendTime; | |
119 | + $stop += $shiftTime; | |
120 | + $this->intervals[$this->indexes[$i]]->setStopFromStamp($stop); | |
121 | + | |
122 | + $this->intervals[$this->indexes[$i]]->setIsModified(true); | |
123 | + $this->isModified = true; | |
124 | + } | |
125 | + | |
126 | + return true; | |
127 | + } | |
128 | + | |
129 | + public function mergeIntervals() { | |
130 | + $this->sort->reset(); | |
131 | + | |
132 | + $this->sort->loadFromObject( | |
133 | + array( | |
134 | + (object)array("property" => "start", "direction" => "DESC") | |
135 | + ) | |
136 | + ); | |
137 | + | |
138 | + $this->updateIndexes(); | |
139 | + | |
140 | + $merged_intervals = array(); | |
141 | + | |
142 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
143 | + if (count($merged_intervals) == 0) | |
144 | + { | |
145 | + array_push($merged_intervals,array( | |
146 | + "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(), | |
147 | + "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(), | |
148 | + "mod" => FALSE) | |
149 | + ); | |
150 | + continue; | |
151 | + } | |
152 | + if (($merged_intervals[count($merged_intervals)-1]["stop"] >= $this->intervals[$this->indexes[$i]]->getStartToStamp()) && | |
153 | + ($merged_intervals[count($merged_intervals)-1]["stop"] < $this->intervals[$this->indexes[$i]]->getStopToStamp())) | |
154 | + { | |
155 | + $merged_intervals[count($merged_intervals)-1]["stop"] = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
156 | + $merged_intervals[count($merged_intervals)-1]["mod"] = TRUE; | |
157 | + } | |
158 | + else | |
159 | + array_push($merged_intervals,array( | |
160 | + "start" => $this->intervals[$this->indexes[$i]]->getStartToStamp(), | |
161 | + "stop" => $this->intervals[$this->indexes[$i]]->getStopToStamp(), | |
162 | + "mod" => FALSE) | |
163 | + ); | |
164 | + } | |
165 | + | |
166 | + $this->reset(); | |
167 | + | |
168 | + foreach ($merged_intervals as $merged_interval) { | |
169 | + $interval = new IntervalCacheObject($this->lastId, count($this->intervals)); | |
170 | + ++$this->lastId; | |
171 | + $interval->setStartFromStamp($merged_interval["start"]); | |
172 | + $interval->setStopFromStamp($merged_interval["stop"]); | |
173 | + $interval->setIsNew($merged_interval["mod"]); | |
174 | + if ($merged_interval["mod"]) | |
175 | + $this->isModified = true; | |
176 | + array_push($this->intervals, $interval); | |
177 | + array_push($this->indexes, count($this->intervals) - 1); | |
178 | + } | |
179 | + | |
180 | + return true; | |
181 | + } | |
182 | + | |
183 | + public function getStatistics() { | |
184 | + $minTime = NULL; | |
185 | + $maxTime = NULL; | |
186 | + $minDuration = NULL; | |
187 | + $maxDuration = NULL; | |
188 | + $indexMinDuration = -1; | |
189 | + $indexMaxDuration = -1; | |
190 | + | |
191 | + $nbValid = 0; | |
192 | + $durationTotal = 0; | |
193 | + | |
194 | + //Min & Max | |
195 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
196 | + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
197 | + //Invalid interval | |
198 | + continue; | |
199 | + | |
200 | + ++$nbValid; | |
201 | + $durationTotal += $this->intervals[$this->indexes[$i]]->getDuration(); | |
202 | + | |
203 | + if (!isset($minTime) || ($minTime > $this->intervals[$this->indexes[$i]]->getStartToStamp())) | |
204 | + $minTime = $this->intervals[$this->indexes[$i]]->getStartToStamp(); | |
205 | + | |
206 | + if (!isset($maxTime) || ($maxTime < $this->intervals[$this->indexes[$i]]->getStopToStamp())) | |
207 | + $maxTime = $this->intervals[$this->indexes[$i]]->getStopToStamp(); | |
208 | + | |
209 | + if (!isset($minDuration) || ($minDuration > $this->intervals[$this->indexes[$i]]->getDuration())) | |
210 | + { | |
211 | + $minDuration = $this->intervals[$this->indexes[$i]]->getDuration(); | |
212 | + $indexMinDuration = $i; | |
213 | + } | |
214 | + | |
215 | + if (!isset($maxDuration) || ($maxDuration < $this->intervals[$this->indexes[$i]]->getDuration())) | |
216 | + { | |
217 | + $maxDuration = $this->intervals[$this->indexes[$i]]->getDuration(); | |
218 | + $indexMaxDuration = $i; | |
219 | + } | |
220 | + } | |
221 | + | |
222 | + if (!isset($minTime)) | |
223 | + $minTime = 0; | |
224 | + if (!isset($maxTime)) | |
225 | + $maxTime = 0; | |
226 | + if (!isset($minDuration)) | |
227 | + $minDuration = 0; | |
228 | + if (!isset($maxDuration)) | |
229 | + $maxDuration = 0; | |
230 | + | |
231 | + | |
232 | + //Mean | |
233 | + if ($nbValid > 0) | |
234 | + $mean = $durationTotal / $nbValid; | |
235 | + else | |
236 | + $mean = 0; | |
237 | + | |
238 | + //Standard deviation | |
239 | + $pow = 0; | |
240 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
241 | + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
242 | + //Invalid interval | |
243 | + continue; | |
244 | + | |
245 | + $pow += pow($this->intervals[$this->indexes[$i]]->getDuration()-$mean,2); | |
246 | + } | |
247 | + if ($nbValid > 0) | |
248 | + $variance = $pow/$nbValid; | |
249 | + else | |
250 | + $variance = 0; | |
251 | + $stdev = sqrt($variance); | |
252 | + | |
253 | + //Sort by duration to get median | |
254 | + $this->sort->reset(); | |
255 | + | |
256 | + $this->sort->loadFromObject( | |
257 | + array( | |
258 | + (object)array("property" => "durationSec", "direction" => "DESC") | |
259 | + ) | |
260 | + ); | |
261 | + | |
262 | + $this->updateIndexes(); | |
263 | + | |
264 | + $durations = array(); | |
265 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
266 | + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
267 | + //Invalid interval | |
268 | + continue; | |
269 | + | |
270 | + array_push($durations, $this->intervals[$this->indexes[$i]]->getDuration()); | |
271 | + } | |
272 | + | |
273 | + if (count($durations) > 0) | |
274 | + { | |
275 | + if (count($durations)%2 > 0) { | |
276 | + $median = $durations[count($durations)/2-0.5]; | |
277 | + } else { // else the number of intervals is an even number | |
278 | + $median = ($durations[count($durations)/2-1] + $durations[count($durations)/2])/2; | |
279 | + } | |
280 | + } | |
281 | + else | |
282 | + $median = 0; | |
283 | + | |
284 | + //Merge intervals to get density | |
285 | + $this->mergeIntervals(); | |
286 | + | |
287 | + $durationMergedTotal = 0; | |
288 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
289 | + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
290 | + //Invalid interval | |
291 | + continue; | |
292 | + | |
293 | + $durationMergedTotal += $this->intervals[$this->indexes[$i]]->getDuration(); | |
294 | + } | |
295 | + | |
296 | + if (($maxTime-$minTime) > 0) | |
297 | + $density = (($durationMergedTotal/($maxTime-$minTime))); | |
298 | + else | |
299 | + $density = 0; | |
300 | + | |
301 | + return array( | |
302 | + "minDuration" => $minDuration, | |
303 | + "minDurationIndex"=> $indexMinDuration, | |
304 | + "maxDuration" => $maxDuration, | |
305 | + "maxDurationIndex"=> $indexMaxDuration, | |
306 | + "mean" => $mean, | |
307 | + "stdev" => $stdev, | |
308 | + "median" => $median, | |
309 | + "density" => $density); | |
310 | + } | |
311 | + | |
312 | + public function getStatus() { | |
313 | + $nbFiltered = count($this->intervals) - count($this->indexes); | |
314 | + | |
315 | + $nbModified = 0; | |
316 | + $nbNew = 0; | |
317 | + $nbInvalid = 0; | |
318 | + $nbValid = 0; | |
319 | + for ($i = 0; $i < count($this->indexes); ++$i) { | |
320 | + if ($this->intervals[$this->indexes[$i]]->getDuration() <= 0) | |
321 | + ++$nbInvalid; | |
322 | + else | |
323 | + ++$nbValid; | |
324 | + if ($this->intervals[$this->indexes[$i]]->isModified()) | |
325 | + ++$nbModified; | |
326 | + if ($this->intervals[$this->indexes[$i]]->isNew()) | |
327 | + ++$nbNew; | |
328 | + } | |
329 | + | |
330 | + return array( | |
331 | + "nbFiltered" => $nbFiltered, | |
332 | + "nbModified" => $nbModified, | |
333 | + "nbNew" => $nbNew, | |
334 | + "nbInvalid" => $nbInvalid, | |
335 | + "nbValid" => $nbValid, | |
336 | + "isModified" => $this->isModified | |
337 | + ); | |
338 | + } | |
339 | + | |
340 | + public function getIntervalsArray($startIndex, $limit,$skipInvalid = false) { | |
341 | + $intervals = array(); | |
342 | + | |
343 | + if (!isset($startIndex)) | |
344 | + $startIndex = 0; | |
345 | + | |
346 | + if (!isset($limit)) | |
347 | + $limit = count($this->indexes); | |
348 | + | |
349 | + for ($i = 0; $i < $limit; ++$i) { | |
350 | + if ($startIndex+$i >= count($this->indexes)) | |
351 | + break; | |
352 | + if ($skipInvalid && ($this->intervals[$this->indexes[$startIndex+$i]]->getDuration() <= 0)) | |
353 | + continue; | |
354 | + array_push($intervals, $this->intervals[$this->indexes[$startIndex+$i]]->toArray()); | |
355 | + } | |
356 | + return $intervals; | |
357 | + } | |
358 | + | |
359 | + public function getLength() { | |
360 | + return count($this->indexes); | |
361 | + } | |
362 | + | |
363 | + public function getToken() { | |
364 | + return $this->token; | |
365 | + } | |
366 | + | |
367 | + public function getFilter() { | |
368 | + return $this->filter; | |
369 | + } | |
370 | + | |
371 | + public function getSort() { | |
372 | + return $this->sort; | |
373 | + } | |
374 | + | |
375 | + public function updateIndexes() { | |
376 | + $this->indexes = array(); | |
377 | + | |
378 | + for ($i = 0; $i < count($this->intervals); ++$i) | |
379 | + $this->intervals[$i]->setIndex($i); | |
380 | + | |
381 | + //Apply sort | |
382 | + $sort_result = $this->sort->apply($this->intervals); | |
383 | + | |
384 | + //Apply filter | |
385 | + for ($i = 0; $i < count($sort_result); ++$i) | |
386 | + { | |
387 | + if (!$this->filter->toFiltered($this->intervals[$sort_result[$i]])) | |
388 | + array_push($this->indexes,$this->intervals[$sort_result[$i]]->getIndex()); | |
389 | + } | |
390 | + } | |
391 | + | |
392 | + public function writeBin($handle) { | |
393 | + //Magic key ("TTC") | |
394 | + fwrite($handle,pack('C3',ord('T'),ord('T'),ord('C'))); | |
395 | + | |
396 | + //Version | |
397 | + fwrite($handle,pack('L',TimeTableCacheObject::$format_version)); | |
398 | + | |
399 | + //Token | |
400 | + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i) | |
401 | + fwrite($handle,pack('C',ord($this->token[$i]))); | |
402 | + | |
403 | + //Modified | |
404 | + fwrite($handle,pack('L',$this->isModified)); | |
405 | + | |
406 | + //Filter | |
407 | + $this->filter->writeBin($handle); | |
408 | + | |
409 | + //Sort | |
410 | + $this->sort->writeBin($handle); | |
411 | + | |
412 | + //Intervals | |
413 | + fwrite($handle,pack('L2',count($this->intervals), $this->lastId)); | |
414 | + foreach($this->intervals as $interval) | |
415 | + $interval->writeBin($handle); | |
416 | + | |
417 | + //Indexes | |
418 | + fwrite($handle,pack('L',count($this->indexes))); | |
419 | + foreach($this->indexes as $index) | |
420 | + fwrite($handle,pack('L',$index)); | |
421 | + } | |
422 | + | |
423 | + public function loadBin($handle) { | |
424 | + //Magic key ("TTC") | |
425 | + if (!$res = unpack('C3key',fread($handle,3))) | |
426 | + return false; | |
427 | + | |
428 | + if (($res['key1'] != ord('T')) || ($res['key2'] != ord('T')) || ($res['key3'] != ord('C'))) | |
429 | + return false; | |
430 | + | |
431 | + //Version | |
432 | + if (!$res = unpack('Lversion',fread($handle,4))) | |
433 | + return false; | |
434 | + if (($res['version'] != TimeTableCacheObject::$format_version)) | |
435 | + return false; | |
436 | + | |
437 | + //Token | |
438 | + $token = ""; | |
439 | + for ($i = 0; $i < TimeTableCacheObject::$token_len; ++$i) | |
440 | + { | |
441 | + if (!$res = unpack('Ctoken',fread($handle,1))) | |
442 | + return false; | |
443 | + $token .= chr($res['token']); | |
444 | + } | |
445 | + $this->token = $token; | |
446 | + | |
447 | + //Modified | |
448 | + if (!$res = unpack('Lmodified',fread($handle,4))) | |
449 | + return false; | |
450 | + $this->isModified = $res['modified']; | |
451 | + | |
452 | + //Filter | |
453 | + $this->filter->loadBin($handle); | |
454 | + | |
455 | + //Sort | |
456 | + $this->sort->loadBin($handle); | |
457 | + | |
458 | + //Intervals | |
459 | + $res = unpack('L2data',fread($handle,2*4)); | |
460 | + $nbIntervals = $res['data1']; | |
461 | + $this->lastId = $res['data2']; | |
462 | + for ($i = 0; $i < $nbIntervals; ++$i) | |
463 | + { | |
464 | + $interval = new IntervalCacheObject(-1); | |
465 | + $interval->loadBin($handle); | |
466 | + array_push($this->intervals, $interval); | |
467 | + } | |
468 | + | |
469 | + //Indexes | |
470 | + $res = unpack('Ldata',fread($handle,4)); | |
471 | + $nbIndexes = $res['data']; | |
472 | + for ($i = 0; $i < $nbIndexes; ++$i) | |
473 | + { | |
474 | + $res = unpack('Lindex',fread($handle,4)); | |
475 | + array_push($this->indexes, $res['index']); | |
476 | + } | |
477 | + | |
478 | + return true; | |
479 | + } | |
480 | + | |
481 | + protected function getRandomToken() { | |
482 | + $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; | |
483 | + return substr(str_shuffle($letters), 0, TimeTableCacheObject::$token_len); | |
484 | + } | |
485 | + | |
486 | + public function dump() { | |
487 | + echo " => TimeTableCacheObject : token = ".$this->token.", nb intervals = ".count($this->intervals).", last id = ".$this->lastId.", nb indexes = ".count($this->indexes).PHP_EOL; | |
488 | + echo PHP_EOL; | |
489 | + | |
490 | + $this->filter->dump(); | |
491 | + echo PHP_EOL; | |
492 | + | |
493 | + $this->sort->dump(); | |
494 | + echo PHP_EOL; | |
495 | + | |
496 | + foreach ($this->intervals as $interval) | |
497 | + $interval->dump(); | |
498 | + echo PHP_EOL; | |
499 | + | |
500 | + echo " => Indexes list : "; | |
501 | + foreach ($this->indexes as $index) | |
502 | + { | |
503 | + echo $index.", "; | |
504 | + } | |
505 | + echo PHP_EOL; | |
506 | + } | |
507 | +} | |
508 | + | |
509 | +?> | |
0 | 510 | \ No newline at end of file |
... | ... |
php/classes/TimeTableMgr.php
... | ... | @@ -22,8 +22,6 @@ function timeFormat($myString) { |
22 | 22 | |
23 | 23 | class TimeTableMgr extends AmdaObjectMgr { |
24 | 24 | |
25 | -//TODO add catalogs as for requestMgr | |
26 | - | |
27 | 25 | |
28 | 26 | function __construct($user) { |
29 | 27 | parent::__construct('Tt.xml'); |
... | ... | @@ -82,8 +80,13 @@ class TimeTableMgr extends AmdaObjectMgr { |
82 | 80 | //if (!($p->intervals)) return true; |
83 | 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 | 91 | * Create Time Table |
89 | 92 | */ |
... | ... | @@ -95,12 +98,15 @@ class TimeTableMgr extends AmdaObjectMgr { |
95 | 98 | $this->id = $this->setId(); |
96 | 99 | $this->created = date('Y-m-d\TH:i:s'); |
97 | 100 | if (!$this->id) return array('error' => ID_CREATION_ERROR); |
101 | + | |
98 | 102 | $this->resFileName = USERTTDIR.$this->id.'.xml'; |
103 | + //TODO catalog root element = 'timetable' | |
99 | 104 | $rootElement = $this->objectDom->createElement('timetable'); |
100 | 105 | $rootElement->setAttribute('xml:id',$this->id); |
101 | 106 | |
102 | 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 | 110 | if ($key == 'created') { |
105 | 111 | $rootElement->appendChild($this->objectDom->createElement($key, $this->created)); |
106 | 112 | } |
... | ... | @@ -114,8 +120,14 @@ class TimeTableMgr extends AmdaObjectMgr { |
114 | 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 | 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 | 133 | $this->objectDom->appendChild($rootElement); |
... | ... | @@ -418,12 +430,20 @@ class TimeTableMgr extends AmdaObjectMgr { |
418 | 430 | 'totalCount' => $intervals->length, |
419 | 431 | 'intervals' => $result, |
420 | 432 | 'start' => isset($start) ? $start : 0, |
421 | - 'limit' => isset($limit) ? $limit : 0, | |
433 | + 'limit' => isset($limit) ? $limit : 0, | |
422 | 434 | 'success' => true |
423 | 435 | ); |
424 | 436 | |
425 | 437 | } |
426 | - | |
438 | + | |
439 | + protected function createIntervalElement($interval) { | |
440 | + | |
441 | + $newInterval = $this->objectDom->createElement('intervals'); | |
442 | + $newInterval->appendChild($this->objectDom->createElement('start',$interval->start)); | |
443 | + $newInterval->appendChild($this->objectDom->createElement('stop',$interval->stop)); | |
444 | + return $newInterval; | |
445 | + } | |
446 | + | |
427 | 447 | public function saveIntervals($id,$intervals,$action) |
428 | 448 | { |
429 | 449 | if (substr($id,0,6) == 'shared') { |
... | ... | @@ -457,11 +477,9 @@ class TimeTableMgr extends AmdaObjectMgr { |
457 | 477 | |
458 | 478 | //add new intervals |
459 | 479 | foreach ($intervals as $interval) |
460 | - { | |
461 | - $newInterval = $this->objectDom->createElement('intervals'); | |
462 | - $newInterval->appendChild($this->objectDom->createElement('start',$interval->start)); | |
463 | - $newInterval->appendChild($this->objectDom->createElement('stop',$interval->stop)); | |
464 | - $this->objectDom->documentElement->appendChild($newInterval); | |
480 | + { | |
481 | + $newInterval = $this-> createIntervalElement($interval); | |
482 | + $this->objectDom->documentElement->appendChild($newInterval); | |
465 | 483 | } |
466 | 484 | |
467 | 485 | //save modifications |
... | ... |