LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
NetworkXMLIO.m
1classdef NetworkXMLIO < handle
2 % NetworkXMLIO - MATLAB wrapper for XML import/export of Network models
3 %
4 % This class provides MATLAB interface to save and load Network models
5 % to/from XML format using the Java NetworkXMLIO implementation.
6 % Supports class switching through ClassSwitch nodes and cross-class routing.
7 %
8 % Usage:
9 % % Export a network to XML
10 % NetworkXMLIO.exportToXML(model, 'mymodel.xml');
11 %
12 % % Import a network from XML
13 % model = NetworkXMLIO.importFromXML('mymodel.xml');
14 %
15 % % Create class switching example
16 % NetworkXMLIO.demonstrateClassSwitching();
17 %
18 % Copyright (c) 2012-2026, Imperial College London
19 % All rights reserved.
20
21 methods (Static)
22
23 function exportToXML(network, filename)
24 % EXPORTTOXML(NETWORK, FILENAME)
25 %
26 % Exports a Network model to XML file
27 %
28 % Parameters:
29 % network - Network model to export
30 % filename - Output XML file path
31 %
32 % Example:
33 % model = Network('MyModel');
34 % source = Source(model, 'Source');
35 % queue = Queue(model, 'Queue', SchedStrategy.FCFS);
36 % sink = Sink(model, 'Sink');
37 % NetworkXMLIO.exportToXML(model, 'mymodel.xml');
38
39 try
40 if isa(network, 'Network')
41 if network.isJavaNative()
42 % Direct Java Network export
43 jline.io.NetworkXMLIO.exportToXML(network.implementation.obj, filename);
44 else
45 % Convert MNetwork to JNetwork for export
46 tempJNetwork = NetworkXMLIO.convertToJNetwork(network);
47 jline.io.NetworkXMLIO.exportToXML(tempJNetwork.obj, filename);
48 end
49 else
50 error('NetworkXMLIO:InvalidNetwork', 'Input must be a Network object');
51 end
52
53 fprintf('Network successfully exported to: %s\n', filename);
54
55 catch e
56 error('NetworkXMLIO:ExportFailed', 'Failed to export network: %s', e.message);
57 end
58 end
59
60 function network = importFromXML(filename)
61 % IMPORTFROMXML(FILENAME)
62 %
63 % Imports a Network model from XML file
64 %
65 % Parameters:
66 % filename - Input XML file path
67 %
68 % Returns:
69 % network - Loaded Network model
70 %
71 % Example:
72 % model = NetworkXMLIO.importFromXML('mymodel.xml');
73
74 try
75 % Import using Java implementation
76 javaNetwork = jline.io.NetworkXMLIO.importFromXML(filename);
77
78 % Wrap in MATLAB Network with Java implementation
79 network = Network(char(javaNetwork.getName()), 'java');
80 network.implementation.obj = javaNetwork;
81
82 fprintf('Network successfully imported from: %s\n', filename);
83
84 catch e
85 error('NetworkXMLIO:ImportFailed', 'Failed to import network: %s', e.message);
86 end
87 end
88
89 function validateXML(filename)
90 % VALIDATEXML(FILENAME)
91 %
92 % Validates XML file structure without full import
93 %
94 % Parameters:
95 % filename - XML file path to validate
96
97 try
98 % Basic validation by attempting to parse the XML
99 docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
100 docBuilder = docFactory.newDocumentBuilder();
101 doc = docBuilder.parse(filename);
102 doc.getDocumentElement().normalize();
103
104 root = doc.getDocumentElement();
105 if ~strcmp(char(root.getNodeName()), 'network')
106 error('NetworkXMLIO:InvalidXML', 'Root element must be <network>');
107 end
108
109 fprintf('XML file is valid: %s\n', filename);
110
111 catch e
112 error('NetworkXMLIO:ValidationFailed', 'XML validation failed: %s', e.message);
113 end
114 end
115
116 function info = getXMLInfo(filename)
117 % GETXMLINFO(FILENAME)
118 %
119 % Gets basic information about XML file without full import
120 %
121 % Parameters:
122 % filename - XML file path
123 %
124 % Returns:
125 % info - Struct with network information
126
127 try
128 docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
129 docBuilder = docFactory.newDocumentBuilder();
130 doc = docBuilder.parse(filename);
131 doc.getDocumentElement().normalize();
132
133 root = doc.getDocumentElement();
134
135 info.name = char(root.getAttribute('name'));
136 info.version = char(root.getAttribute('version'));
137
138 % Count nodes
139 nodeList = doc.getElementsByTagName('node');
140 info.nodeCount = nodeList.getLength();
141
142 % Count classes
143 classList = doc.getElementsByTagName('class');
144 info.classCount = classList.getLength();
145
146 % Count connections
147 linkList = doc.getElementsByTagName('link');
148 info.connectionCount = linkList.getLength();
149
150 % Get node types
151 info.nodeTypes = {};
152 for i = 0:nodeList.getLength()-1
153 nodeElement = nodeList.item(i);
154 nodeType = char(nodeElement.getAttribute('type'));
155 if ~any(strcmp(info.nodeTypes, nodeType))
156 info.nodeTypes{end+1} = nodeType;
157 end
158 end
159
160 % Count routing matrices (including cross-class routing)
161 matrixList = doc.getElementsByTagName('matrix');
162 info.routingMatrixCount = matrixList.getLength();
163
164 % Check for class switching features
165 info.hasClassSwitching = false;
166 info.classSwitchNodes = {};
167
168 % Check for ClassSwitch nodes
169 for i = 0:nodeList.getLength()-1
170 nodeElement = nodeList.item(i);
171 nodeType = char(nodeElement.getAttribute('type'));
172 if strcmp(nodeType, 'ClassSwitch')
173 info.hasClassSwitching = true;
174 nodeName = char(nodeElement.getAttribute('name'));
175 info.classSwitchNodes{end+1} = nodeName;
176 end
177 end
178
179 % Check for cross-class routing matrices
180 info.hasCrossClassRouting = false;
181 for i = 0:matrixList.getLength()-1
182 matrixElement = matrixList.item(i);
183 fromClass = char(matrixElement.getAttribute('fromClass'));
184 toClass = char(matrixElement.getAttribute('toClass'));
185 if ~isempty(fromClass) && ~isempty(toClass) && ~strcmp(fromClass, toClass)
186 info.hasCrossClassRouting = true;
187 info.hasClassSwitching = true;
188 break;
189 end
190 end
191
192 catch e
193 error('NetworkXMLIO:InfoFailed', 'Failed to get XML info: %s', e.message);
194 end
195 end
196
197 function demonstrateUsage()
198 % DEMONSTRATEUSAGE()
199 %
200 % Demonstrates basic usage of NetworkXMLIO with a simple example
201
202 fprintf('=== NetworkXMLIO Usage Demonstration ===\n');
203
204 % Create a simple network
205 model = Network('DemoModel');
206
207 source = Source(model, 'Source');
208 queue = Queue(model, 'Queue', SchedStrategy.FCFS);
209 sink = Sink(model, 'Sink');
210
211 jobClass = OpenClass(model, 'Class1');
212 source.setArrival(jobClass, Exp(1));
213 queue.setService(jobClass, Exp(2));
214
215 model.link(Network.serialRouting(source, queue, sink));
216
217 fprintf('Created demo network with %d nodes\n', model.getNumberOfNodes());
218
219 % Export to XML
220 filename = 'demo_network.xml';
221 NetworkXMLIO.exportToXML(model, filename);
222
223 % Show XML info
224 info = NetworkXMLIO.getXMLInfo(filename);
225 fprintf('XML Info:\n');
226 fprintf(' Name: %s\n', info.name);
227 fprintf(' Nodes: %d\n', info.nodeCount);
228 fprintf(' Classes: %d\n', info.classCount);
229 fprintf(' Node Types: %s\n', strjoin(info.nodeTypes, ', '));
230
231 % Import back
232 importedModel = NetworkXMLIO.importFromXML(filename);
233 fprintf('Imported network with %d nodes\n', importedModel.getNumberOfNodes());
234
235 fprintf('=== Demonstration Complete ===\n');
236 end
237
238 function demonstrateClassSwitching()
239 % DEMONSTRATECLASSSWITCHING()
240 %
241 % Demonstrates class switching functionality with NetworkXMLIO
242 % Creates a model similar to example_classSwitching_1.m
243
244 fprintf('=== Class Switching Demonstration ===\n');
245
246 try
247 % Create network with class switching (similar to example_classSwitching_1)
248 model = Network('ClassSwitchingDemo');
249
250 % Create nodes
251 source = Source(model, 'Source');
252 queue = Queue(model, 'Queue', SchedStrategy.FCFS);
253 sink = Sink(model, 'Sink');
254 classSwitch = ClassSwitch(model, 'ClassSwitch');
255
256 % Create job classes
257 class1 = OpenClass(model, 'Class1');
258 class2 = OpenClass(model, 'Class2');
259
260 % Set arrivals and services
261 source.setArrival(class1, Exp.fitMean(10));
262 source.setArrival(class2, Exp.fitMean(2));
263 queue.setService(class1, Exp.fitMean(1));
264 queue.setService(class2, Exp.fitMean(1));
265
266 % Set up class switching matrix
267 csmatrix = classSwitch.initClassSwitchMatrix();
268 csmatrix(class1, class1) = 0.3;
269 csmatrix(class1, class2) = 0.7;
270 csmatrix(class2, class1) = 1.0;
271 classSwitch.setClassSwitchingMatrix(csmatrix);
272
273 % Set up routing
274 P = model.initRoutingMatrix();
275 P{1,1}(source, classSwitch) = 1;
276 P{1,1}(classSwitch, queue) = 1;
277 P{1,1}(queue, sink) = 1;
278 P{2,2}(source, classSwitch) = 1;
279 P{2,2}(classSwitch, queue) = 1;
280 P{2,2}(queue, sink) = 1;
281 model.link(P);
282
283 fprintf('Created class switching network with:\n');
284 fprintf(' - %d nodes\n', model.getNumberOfNodes());
285 fprintf(' - %d classes\n', model.getNumberOfClasses());
286 fprintf(' - ClassSwitch node with switching matrix\n');
287
288 % Export to XML
289 filename = 'class_switching_demo.xml';
290 NetworkXMLIO.exportToXML(model, filename);
291
292 % Show detailed XML info
293 info = NetworkXMLIO.getXMLInfo(filename);
294 fprintf('\nXML Analysis:\n');
295 fprintf(' Model: %s\n', info.name);
296 fprintf(' Nodes: %d (%s)\n', info.nodeCount, strjoin(info.nodeTypes, ', '));
297 fprintf(' Classes: %d\n', info.classCount);
298 fprintf(' Routing matrices: %d\n', info.routingMatrixCount);
299 fprintf(' Has class switching: %s\n', NetworkXMLIO.yesNo(info.hasClassSwitching));
300
301 if info.hasClassSwitching
302 if ~isempty(info.classSwitchNodes)
303 fprintf(' ClassSwitch nodes: %s\n', strjoin(info.classSwitchNodes, ', '));
304 end
305 if info.hasCrossClassRouting
306 fprintf(' Has cross-class routing: Yes\n');
307 end
308 end
309
310 % Import back and validate
311 importedModel = NetworkXMLIO.importFromXML(filename);
312 fprintf('\nImported network with %d nodes\n', importedModel.getNumberOfNodes());
313
314 % Compare structure
315 if importedModel.getNumberOfNodes() == model.getNumberOfNodes() && ...
316 importedModel.getNumberOfClasses() == model.getNumberOfClasses()
317 fprintf('✓ Import successful - structure matches\n');
318 else
319 fprintf('⚠ Import completed but structure differs\n');
320 end
321
322 catch e
323 fprintf('Class switching demonstration failed: %s\n', e.message);
324 fprintf('Note: Class switching requires full MNetwork to JNetwork conversion\n');
325 end
326
327 fprintf('\n=== Class Switching Demonstration Complete ===\n');
328 end
329
330 function demonstrateEmbeddedClassSwitching()
331 % DEMONSTRATEEMBEDDEDCLASSSWITCHING()
332 %
333 % Demonstrates embedded class switching in routing matrices
334 % Creates a model similar to example_classSwitching_2.m
335
336 fprintf('=== Embedded Class Switching Demonstration ===\n');
337
338 try
339 % Create network with embedded class switching
340 model = Network('EmbeddedClassSwitchingDemo');
341
342 % Create nodes
343 source = Source(model, 'Source');
344 queue0 = Queue(model, 'Queue0', SchedStrategy.FCFS);
345 queue1 = Queue(model, 'Queue1', SchedStrategy.FCFS);
346 queue2 = Queue(model, 'Queue2', SchedStrategy.FCFS);
347 sink = Sink(model, 'Sink');
348
349 % Create job classes
350 class1 = OpenClass(model, 'Class1');
351 class2 = OpenClass(model, 'Class2');
352 class3 = OpenClass(model, 'Class3');
353
354 % Set arrivals and services
355 source.setArrival(class1, Exp.fitMean(1));
356 queue0.setService(class1, Exp.fitMean(10));
357 queue1.setService(class2, Exp.fitMean(20));
358 queue2.setService(class3, Exp.fitMean(30));
359
360 % Set up cross-class routing matrix (embedded class switching)
361 P = model.initRoutingMatrix();
362 P{1,1}(source, queue0) = 1;
363 P{1,1}(queue0, queue0) = 0.2; % Stay in same class
364 P{1,2}(queue0, queue1) = 0.3; % Switch to class 2
365 P{1,3}(queue0, queue2) = 0.5; % Switch to class 3
366 P{2,2}(queue1, sink) = 1;
367 P{3,3}(queue2, sink) = 1;
368 model.link(P);
369
370 fprintf('Created embedded class switching network with:\n');
371 fprintf(' - %d nodes\n', model.getNumberOfNodes());
372 fprintf(' - %d classes\n', model.getNumberOfClasses());
373 fprintf(' - Cross-class routing probabilities\n');
374
375 % Export to XML
376 filename = 'embedded_class_switching_demo.xml';
377 NetworkXMLIO.exportToXML(model, filename);
378
379 % Show detailed XML info
380 info = NetworkXMLIO.getXMLInfo(filename);
381 fprintf('\nXML Analysis:\n');
382 fprintf(' Has cross-class routing: %s\n', NetworkXMLIO.yesNo(info.hasCrossClassRouting));
383 fprintf(' Total routing matrices: %d\n', info.routingMatrixCount);
384
385 catch e
386 fprintf('Embedded class switching demonstration failed: %s\n', e.message);
387 end
388
389 fprintf('\n=== Embedded Class Switching Demonstration Complete ===\n');
390 end
391
392 function analyzeClassSwitchingXML(filename)
393 % ANALYZECLASSSWITCHINGXML(FILENAME)
394 %
395 % Analyzes an XML file for class switching features
396 %
397 % Parameters:
398 % filename - XML file to analyze
399
400 if ~exist(filename, 'file')
401 error('NetworkXMLIO:FileNotFound', 'File not found: %s', filename);
402 end
403
404 try
405 info = NetworkXMLIO.getXMLInfo(filename);
406
407 fprintf('=== Class Switching Analysis: %s ===\n', filename);
408 fprintf('Model: %s (version %s)\n', info.name, info.version);
409 fprintf('Nodes: %d\n', info.nodeCount);
410 fprintf('Classes: %d\n', info.classCount);
411 fprintf('Routing matrices: %d\n', info.routingMatrixCount);
412 fprintf('\n');
413
414 fprintf('Class Switching Features:\n');
415 fprintf(' Has class switching: %s\n', NetworkXMLIO.yesNo(info.hasClassSwitching));
416
417 if info.hasClassSwitching
418 if ~isempty(info.classSwitchNodes)
419 fprintf(' ClassSwitch nodes: %s\n', strjoin(info.classSwitchNodes, ', '));
420 end
421 fprintf(' Has cross-class routing: %s\n', NetworkXMLIO.yesNo(info.hasCrossClassRouting));
422 end
423
424 fprintf(' Node types: %s\n', strjoin(info.nodeTypes, ', '));
425
426 catch e
427 error('NetworkXMLIO:AnalysisFailed', 'Analysis failed: %s', e.message);
428 end
429 end
430
431 end
432
433 methods (Static, Access = private)
434
435 function jnetwork = convertToJNetwork(mnetwork)
436 % CONVERTTOJNETWORK(MNETWORK)
437 %
438 % Converts MNetwork to JNetwork for XML export
439 % Enhanced to handle class switching features
440
441 jnetwork = JNetwork(mnetwork.getName());
442
443 try
444 % Convert nodes
445 NetworkXMLIO.convertNodes(mnetwork, jnetwork);
446
447 % Convert classes
448 NetworkXMLIO.convertClasses(mnetwork, jnetwork);
449
450 % Convert routing matrices (including class switching)
451 NetworkXMLIO.convertRoutingMatrices(mnetwork, jnetwork);
452
453 % Convert service distributions
454 NetworkXMLIO.convertServiceDistributions(mnetwork, jnetwork);
455
456 catch e
457 warning('NetworkXMLIO:ConversionPartial', ...
458 'Partial conversion completed. Some features may not be preserved: %s', e.message);
459 end
460
461 warning('NetworkXMLIO:ConversionLimited', ...
462 'MNetwork to JNetwork conversion is simplified. Some features may not be preserved.');
463 end
464
465 function convertNodes(mnetwork, jnetwork)
466 % CONVERTNODES(MNETWORK, JNETWORK)
467 %
468 % Converts nodes from MNetwork to JNetwork
469
470 nodes = mnetwork.getNodes();
471 for i = 1:length(nodes)
472 node = nodes{i};
473 nodeName = node.getName();
474
475 % Create corresponding Java node based on type
476 if isa(node, 'Source')
477 jnode = jline.lang.nodes.Source(jnetwork, nodeName);
478 elseif isa(node, 'Queue')
479 jnode = jline.lang.nodes.Queue(jnetwork, nodeName, node.getSchedStrategy());
480 if ~isinf(node.getNumberOfServers())
481 jnode.setNumberOfServers(node.getNumberOfServers());
482 end
483 elseif isa(node, 'Sink')
484 jnode = jline.lang.nodes.Sink(jnetwork, nodeName);
485 elseif isa(node, 'Router')
486 jnode = jline.lang.nodes.Router(jnetwork, nodeName);
487 elseif isa(node, 'ClassSwitch')
488 jnode = jline.lang.nodes.ClassSwitch(jnetwork, nodeName);
489 % Note: Class switching matrix conversion would go here
490 elseif isa(node, 'Delay')
491 jnode = jline.lang.nodes.Delay(jnetwork, nodeName);
492 elseif isa(node, 'Fork')
493 jnode = jline.lang.nodes.Fork(jnetwork, nodeName);
494 elseif isa(node, 'Join')
495 % Note: Join requires Fork reference - simplified here
496 jnode = jline.lang.nodes.Join(jnetwork, nodeName, []);
497 else
498 warning('NetworkXMLIO:UnknownNodeType', 'Unknown node type: %s', class(node));
499 end
500 end
501 end
502
503 function convertClasses(mnetwork, jnetwork)
504 % CONVERTCLASSES(MNETWORK, JNETWORK)
505 %
506 % Converts job classes from MNetwork to JNetwork
507
508 classes = mnetwork.getClasses();
509 for i = 1:length(classes)
510 jobClass = classes{i};
511 className = jobClass.getName();
512 priority = jobClass.getPriority();
513
514 if isa(jobClass, 'OpenClass')
515 jclass = jline.lang.OpenClass(jnetwork, className, priority);
516 elseif isa(jobClass, 'ClosedClass')
517 population = jobClass.getPopulation();
518 % Note: Reference station conversion needed
519 refStation = []; % Simplified
520 jclass = jline.lang.ClosedClass(jnetwork, className, population, refStation, priority);
521 else
522 warning('NetworkXMLIO:UnknownClassType', 'Unknown class type: %s', class(jobClass));
523 end
524 end
525 end
526
527 function convertRoutingMatrices(mnetwork, jnetwork)
528 % CONVERTROUTINGMATRICES(MNETWORK, JNETWORK)
529 %
530 % Converts routing matrices including class switching
531
532 % Note: This is a placeholder for routing matrix conversion
533 % Full implementation would need to:
534 % 1. Extract routing probabilities P{i,j}(m,n) for all class combinations
535 % 2. Handle class switching matrices from ClassSwitch nodes
536 % 3. Convert to Java RoutingMatrix format
537
538 warning('NetworkXMLIO:RoutingConversionTodo', ...
539 'Routing matrix conversion with class switching not fully implemented');
540 end
541
542 function convertServiceDistributions(mnetwork, jnetwork)
543 % CONVERTSERVICEDISTRIBUTIONS(MNETWORK, JNETWORK)
544 %
545 % Converts service distributions from MNetwork to JNetwork
546
547 % Note: This is a placeholder for service distribution conversion
548 % Full implementation would need to:
549 % 1. Extract service distributions for each node and class
550 % 2. Convert MATLAB distribution objects to Java equivalents
551 % 3. Handle arrival processes for Source nodes
552
553 warning('NetworkXMLIO:ServiceConversionTodo', ...
554 'Service distribution conversion not fully implemented');
555 end
556
557 function result = yesNo(value)
558 % YESNO(VALUE)
559 %
560 % Converts boolean to Yes/No string
561
562 if value
563 result = 'Yes';
564 else
565 result = 'No';
566 end
567 end
568
569 end
570end
Definition mmt.m:92