1classdef NetworkXMLIO < handle
2 % NetworkXMLIO - MATLAB wrapper
for XML
import/
export of Network models
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.
9 % % Export a network to XML
10 % NetworkXMLIO.exportToXML(model,
'mymodel.xml');
12 % % Import a network from XML
13 % model = NetworkXMLIO.importFromXML(
'mymodel.xml');
15 % % Create
class switching example
16 % NetworkXMLIO.demonstrateClassSwitching();
18 % Copyright (c) 2012-2026, Imperial College London
19 % All rights reserved.
23 function exportToXML(network, filename)
24 % EXPORTTOXML(NETWORK, FILENAME)
26 % Exports a Network model to XML file
29 % network - Network model to
export
30 % filename - Output XML file path
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');
40 if isa(network,
'Network')
41 if network.isJavaNative()
42 % Direct Java Network export
43 jline.io.NetworkXMLIO.exportToXML(network.implementation.obj, filename);
45 % Convert MNetwork to JNetwork for export
46 tempJNetwork = NetworkXMLIO.convertToJNetwork(network);
47 jline.io.NetworkXMLIO.exportToXML(tempJNetwork.obj, filename);
50 error('NetworkXMLIO:InvalidNetwork', 'Input must be a Network
object');
53 fprintf('Network successfully exported to: %s\n', filename);
56 error('NetworkXMLIO:ExportFailed', 'Failed to export network: %s', e.message);
60 function network = importFromXML(filename)
61 % IMPORTFROMXML(FILENAME)
63 % Imports a Network model from XML file
66 % filename - Input XML file path
69 % network - Loaded Network model
72 % model = NetworkXMLIO.importFromXML('mymodel.xml');
75 % Import using Java implementation
76 javaNetwork = jline.io.NetworkXMLIO.importFromXML(filename);
78 % Wrap in MATLAB Network with Java implementation
79 network = Network(
char(javaNetwork.getName()), 'java');
80 network.implementation.obj = javaNetwork;
82 fprintf('Network successfully imported from: %s\n', filename);
85 error('NetworkXMLIO:ImportFailed', 'Failed to import network: %s', e.message);
89 function validateXML(filename)
90 % VALIDATEXML(FILENAME)
92 % Validates XML file structure without full import
95 % filename - XML file path to validate
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();
104 root = doc.getDocumentElement();
105 if ~strcmp(
char(root.getNodeName()), 'network')
106 error('NetworkXMLIO:InvalidXML', 'Root element must be <network>');
109 fprintf('XML file
is valid: %s\n', filename);
112 error('NetworkXMLIO:ValidationFailed', 'XML validation failed: %s', e.message);
116 function info = getXMLInfo(filename)
117 % GETXMLINFO(FILENAME)
119 % Gets basic information about XML file without full import
122 % filename - XML file path
125 % info - Struct with network information
128 docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
129 docBuilder = docFactory.newDocumentBuilder();
130 doc = docBuilder.parse(filename);
131 doc.getDocumentElement().normalize();
133 root = doc.getDocumentElement();
135 info.name =
char(root.getAttribute('name'));
136 info.version =
char(root.getAttribute('version'));
139 nodeList = doc.getElementsByTagName('node');
140 info.nodeCount = nodeList.getLength();
143 classList = doc.getElementsByTagName('class');
144 info.classCount = classList.getLength();
147 linkList = doc.getElementsByTagName('link');
148 info.connectionCount = linkList.getLength();
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;
160 % Count routing matrices (including cross-
class routing)
161 matrixList = doc.getElementsByTagName(
'matrix');
162 info.routingMatrixCount = matrixList.getLength();
164 % Check
for class switching features
165 info.hasClassSwitching =
false;
166 info.classSwitchNodes = {};
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;
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;
193 error(
'NetworkXMLIO:InfoFailed',
'Failed to get XML info: %s', e.message);
197 function demonstrateUsage()
200 % Demonstrates basic usage of NetworkXMLIO with a simple example
202 fprintf(
'=== NetworkXMLIO Usage Demonstration ===\n');
204 % Create a simple network
205 model = Network(
'DemoModel');
207 source = Source(model,
'Source');
208 queue = Queue(model,
'Queue', SchedStrategy.FCFS);
209 sink = Sink(model,
'Sink');
211 jobClass = OpenClass(model,
'Class1');
212 source.setArrival(jobClass, Exp(1));
213 queue.setService(jobClass, Exp(2));
215 model.link(Network.serialRouting(source, queue, sink));
217 fprintf(
'Created demo network with %d nodes\n', model.getNumberOfNodes());
220 filename =
'demo_network.xml';
221 NetworkXMLIO.exportToXML(model, filename);
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,
', '));
232 importedModel = NetworkXMLIO.importFromXML(filename);
233 fprintf(
'Imported network with %d nodes\n', importedModel.getNumberOfNodes());
235 fprintf(
'=== Demonstration Complete ===\n');
238 function demonstrateClassSwitching()
239 % DEMONSTRATECLASSSWITCHING()
241 % Demonstrates
class switching functionality with NetworkXMLIO
242 % Creates a model similar to example_classSwitching_1.m
244 fprintf(
'=== Class Switching Demonstration ===\n');
247 % Create network with
class switching (similar to example_classSwitching_1)
248 model = Network(
'ClassSwitchingDemo');
251 source = Source(model,
'Source');
252 queue = Queue(model,
'Queue', SchedStrategy.FCFS);
253 sink = Sink(model,
'Sink');
254 classSwitch = ClassSwitch(model,
'ClassSwitch');
257 class1 = OpenClass(model,
'Class1');
258 class2 = OpenClass(model,
'Class2');
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));
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);
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;
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');
289 filename =
'class_switching_demo.xml';
290 NetworkXMLIO.exportToXML(model, filename);
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));
301 if info.hasClassSwitching
302 if ~isempty(info.classSwitchNodes)
303 fprintf(' ClassSwitch
nodes: %s\n', strjoin(info.classSwitchNodes, ', '));
305 if info.hasCrossClassRouting
306 fprintf(' Has cross-class routing: Yes\n');
310 % Import back and validate
311 importedModel = NetworkXMLIO.importFromXML(filename);
312 fprintf('\nImported network with %d
nodes\n', importedModel.getNumberOfNodes());
315 if importedModel.getNumberOfNodes() == model.getNumberOfNodes() && ...
316 importedModel.getNumberOfClasses() == model.getNumberOfClasses()
317 fprintf('✓ Import successful - structure matches\n');
319 fprintf('⚠ Import completed but structure differs\n');
323 fprintf('Class switching demonstration failed: %s\n', e.message);
324 fprintf('Note: Class switching requires full MNetwork to JNetwork conversion\n');
327 fprintf('\n=== Class Switching Demonstration Complete ===\n');
330 function demonstrateEmbeddedClassSwitching()
331 % DEMONSTRATEEMBEDDEDCLASSSWITCHING()
333 % Demonstrates embedded class switching in routing matrices
334 % Creates a model similar to example_classSwitching_2.m
336 fprintf('=== Embedded Class Switching Demonstration ===\n');
339 % Create network with embedded class switching
340 model = Network('EmbeddedClassSwitchingDemo');
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');
350 class1 = OpenClass(model, 'Class1');
351 class2 = OpenClass(model, 'Class2');
352 class3 = OpenClass(model, 'Class3');
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));
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;
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');
376 filename =
'embedded_class_switching_demo.xml';
377 NetworkXMLIO.exportToXML(model, filename);
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);
386 fprintf(
'Embedded class switching demonstration failed: %s\n', e.message);
389 fprintf(
'\n=== Embedded Class Switching Demonstration Complete ===\n');
392 function analyzeClassSwitchingXML(filename)
393 % ANALYZECLASSSWITCHINGXML(FILENAME)
395 % Analyzes an XML file
for class switching features
398 % filename - XML file to analyze
400 if ~exist(filename,
'file')
401 error('NetworkXMLIO:FileNotFound', 'File not found: %s', filename);
405 info = NetworkXMLIO.getXMLInfo(filename);
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);
414 fprintf('Class Switching Features:\n');
415 fprintf(' Has class switching: %s\n', NetworkXMLIO.yesNo(info.hasClassSwitching));
417 if info.hasClassSwitching
418 if ~isempty(info.classSwitchNodes)
419 fprintf(' ClassSwitch
nodes: %s\n', strjoin(info.classSwitchNodes, ', '));
421 fprintf(' Has cross-class routing: %s\n', NetworkXMLIO.yesNo(info.hasCrossClassRouting));
424 fprintf(' Node types: %s\n', strjoin(info.nodeTypes, ', '));
427 error('NetworkXMLIO:AnalysisFailed', 'Analysis failed: %s', e.message);
433 methods (Static, Access = private)
435 function jnetwork = convertToJNetwork(mnetwork)
436 % CONVERTTOJNETWORK(MNETWORK)
438 % Converts MNetwork to JNetwork for XML export
439 % Enhanced to handle class switching features
441 jnetwork = JNetwork(mnetwork.getName());
445 NetworkXMLIO.convertNodes(mnetwork, jnetwork);
448 NetworkXMLIO.convertClasses(mnetwork, jnetwork);
450 % Convert routing matrices (including class switching)
451 NetworkXMLIO.convertRoutingMatrices(mnetwork, jnetwork);
453 % Convert service distributions
454 NetworkXMLIO.convertServiceDistributions(mnetwork, jnetwork);
457 warning('NetworkXMLIO:ConversionPartial', ...
458 'Partial conversion completed. Some features may not be preserved: %s', e.message);
461 warning('NetworkXMLIO:ConversionLimited', ...
462 'MNetwork to JNetwork conversion
is simplified. Some features may not be preserved.');
465 function convertNodes(mnetwork, jnetwork)
466 % CONVERTNODES(MNETWORK, JNETWORK)
468 % Converts
nodes from MNetwork to JNetwork
470 nodes = mnetwork.getNodes();
471 for i = 1:length(
nodes)
473 nodeName = node.getName();
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());
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, []);
498 warning('NetworkXMLIO:UnknownNodeType', 'Unknown node type: %s', class(node));
503 function convertClasses(mnetwork, jnetwork)
504 % CONVERTCLASSES(MNETWORK, JNETWORK)
506 % Converts job
classes from MNetwork to JNetwork
508 classes = mnetwork.getClasses();
511 className = jobClass.getName();
512 priority = jobClass.getPriority();
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);
522 warning('NetworkXMLIO:UnknownClassType', 'Unknown class type: %s', class(jobClass));
527 function convertRoutingMatrices(mnetwork, jnetwork)
528 % CONVERTROUTINGMATRICES(MNETWORK, JNETWORK)
530 % Converts routing matrices including class switching
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
538 warning(
'NetworkXMLIO:RoutingConversionTodo', ...
539 'Routing matrix conversion with class switching not fully implemented');
542 function convertServiceDistributions(mnetwork, jnetwork)
543 % CONVERTSERVICEDISTRIBUTIONS(MNETWORK, JNETWORK)
545 % Converts service distributions from MNetwork to JNetwork
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
553 warning(
'NetworkXMLIO:ServiceConversionTodo', ...
554 'Service distribution conversion not fully implemented');
557 function result = yesNo(value)
560 % Converts
boolean to Yes/No
string