1function outputFileName = writeJSIM(self, sn, outputFileName)
2% FNAME = WRITEJSIM(SN, FNAME)
4% Copyright (c) 2012-2026, Imperial College London
7if nargin<3 || isempty(outputFileName)
8 % Generate
default temp path
9 filePath = lineTempName(
'jsim');
10 outputFileName = [filePath, filesep,
'model.jsim'];
13[simXMLElem, simXMLDoc] = saveXMLHeader(self, self.model.getLogPath);
14[simXMLElem, simXMLDoc] = saveClasses(self, simXMLElem, simXMLDoc);
16numOfClasses = sn.nclasses;
17numOfNodes = sn.nnodes;
20 currentNode = self.model.nodes{i,1};
21 node = simXMLDoc.createElement(
'node');
22 node.setAttribute(
'name', currentNode.name);
24 nodeSections = getSections(currentNode);
25 for j=1:length(nodeSections)
26 xml_section = simXMLDoc.createElement(
'section');
27 currentSection = nodeSections{1,j};
28 if ~isempty(currentSection)
29 sectionClassName = currentSection.className;
30 % Override className
for preemptive strategies - JMT
requires PreemptiveServer
31 if strcmp(sectionClassName,
'Server') && isa(currentNode,
'Queue')
32 sched = currentNode.schedStrategy;
33 if sched == SchedStrategy.SRPT || sched == SchedStrategy.SRPTPRIO || ...
34 sched == SchedStrategy.LCFSPR || sched == SchedStrategy.LCFSPRPRIO || ...
35 sched == SchedStrategy.LCFSPI || sched == SchedStrategy.LCFSPIPRIO || ...
36 sched == SchedStrategy.FCFSPR || sched == SchedStrategy.FCFSPRPRIO || ...
37 sched == SchedStrategy.FCFSPI || sched == SchedStrategy.FCFSPIPRIO
38 sectionClassName = 'PreemptiveServer';
41 xml_section.setAttribute('className', sectionClassName);
42 switch sectionClassName
44 xml_section.setAttribute('className', 'Queue'); %overwrite with JMT class name
45 [simXMLDoc, xml_section] = saveBufferCapacity(self, simXMLDoc, xml_section, ind);
46 [simXMLDoc, xml_section] = saveDropStrategy(self, simXMLDoc, xml_section, ind); % unfinished
47 [simXMLDoc, xml_section] = saveGetStrategy(self, simXMLDoc, xml_section, ind);
48 [simXMLDoc, xml_section] = savePutStrategy(self, simXMLDoc, xml_section, ind);
49 [simXMLDoc, xml_section] = saveImpatience(self, simXMLDoc, xml_section, ind);
51 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
52 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
53 % Heterogeneous server configuration
54 [simXMLDoc, xml_section] = saveServerTypeNames(self, simXMLDoc, xml_section, ind);
55 [simXMLDoc, xml_section] = saveServersPerType(self, simXMLDoc, xml_section, ind);
56 [simXMLDoc, xml_section] = saveServerCompatibilities(self, simXMLDoc, xml_section, ind);
57 [simXMLDoc, xml_section] = saveHeteroSchedPolicy(self, simXMLDoc, xml_section, ind);
58 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
59 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
60 % Note: SwitchoverStrategy
is only supported by PollingServer in JMT
61 % Regular Server class does not support switchover times
62 if ~isempty(currentNode.switchoverTime)
63 line_warning(mfilename, 'JMT does not support switchover times for non-polling queues. Switchover times will be ignored for node %s.', currentNode.name);
65 case 'PreemptiveServer'
66 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
67 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
68 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
69 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
71 xml_section.setAttribute('className', 'PSServer'); %overwrite with JMT class name
72 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
73 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
74 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
75 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
76 [simXMLDoc, xml_section] = savePreemptiveStrategy(self, simXMLDoc, xml_section, ind);
77 [simXMLDoc, xml_section] = savePreemptiveWeights(self, simXMLDoc, xml_section, ind);
79 xml_section.setAttribute('className', 'Delay'); %overwrite with JMT class name
80 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
82 % we assume identical polling type on each buffer
83 switch sn.nodeparam{ind}{1}.pollingType
84 case PollingType.GATED
85 xml_section.setAttribute(
'className',
'GatedPollingServer'); %overwrite with JMT
class name
86 case PollingType.EXHAUSTIVE
87 xml_section.setAttribute('className', 'ExhaustivePollingServer'); %overwrite with JMT
class name
88 case PollingType.KLIMITED
89 xml_section.setAttribute('className', 'LimitedPollingServer'); %overwrite with JMT
class name
91 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
92 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
93 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
94 [simXMLDoc, xml_section] = saveSwitchoverStrategy(self, simXMLDoc, xml_section, ind);
96 [simXMLDoc, xml_section] = saveArrivalStrategy(self, simXMLDoc, xml_section, ind);
98 xml_section.setAttribute(
'className',
'Router'); %overwrite with JMT
class name
99 [simXMLDoc, xml_section] = saveRoutingStrategy(self, simXMLDoc, xml_section, ind);
100 case 'StatelessClassSwitcher'
101 xml_section.setAttribute(
'className',
'ClassSwitch'); %overwrite with JMT
class name
102 [simXMLDoc, xml_section] = saveClassSwitchStrategy(self, simXMLDoc, xml_section, ind);
104 % CacheClassSwitcher section has className=
'Cache'
105 [simXMLDoc, xml_section] = saveCacheStrategy(self, simXMLDoc, xml_section, ind);
107 [simXMLDoc, xml_section] = saveLogTunnel(self, simXMLDoc, xml_section, ind);
109 xml_section.setAttribute(
'className',
'Join'); %overwrite with JMT
class name
110 [simXMLDoc, xml_section] = saveJoinStrategy(self, simXMLDoc, xml_section, ind);
112 xml_section.setAttribute(
'className',
'Fork'); %overwrite with JMT
class name
113 [simXMLDoc, xml_section] = saveForkStrategy(self, simXMLDoc, xml_section, ind);
115 xml_section.setAttribute(
'className',
'Storage'); %overwrite with JMT
class name
116 [simXMLDoc, xml_section] = saveTotalCapacity(self, simXMLDoc, xml_section, ind);
117 [simXMLDoc, xml_section] = savePlaceCapacities(self, simXMLDoc, xml_section, ind);
118 [simXMLDoc, xml_section] = saveDropRule(self, simXMLDoc, xml_section, ind); % unfinished
119 [simXMLDoc, xml_section] = saveGetStrategy(self, simXMLDoc, xml_section, ind);
120 [simXMLDoc, xml_section] = savePutStrategies(self, simXMLDoc, xml_section, ind);
122 xml_section.setAttribute(
'className',
'Enabling'); %overwrite with JMT
class name
123 [simXMLDoc, xml_section] = saveEnablingConditions(self, simXMLDoc, xml_section, ind);
124 [simXMLDoc, xml_section] = saveInhibitingConditions(self, simXMLDoc, xml_section, ind);
126 xml_section.setAttribute(
'className',
'Firing'); %overwrite with JMT
class name
127 [simXMLDoc, xml_section] = saveFiringOutcomes(self, simXMLDoc, xml_section, ind);
129 xml_section.setAttribute(
'className',
'Timing'); %overwrite with JMT
class name
130 [simXMLDoc, xml_section] = saveModeNames(self, simXMLDoc, xml_section, ind);
131 [simXMLDoc, xml_section] = saveNumbersOfServers(self, simXMLDoc, xml_section, ind);
132 [simXMLDoc, xml_section] = saveTimingStrategies(self, simXMLDoc, xml_section, ind);
133 [simXMLDoc, xml_section] = saveFiringPriorities(self, simXMLDoc, xml_section, ind);
134 [simXMLDoc, xml_section] = saveFiringWeights(self, simXMLDoc, xml_section, ind);
136 node.appendChild(xml_section);
139 simXMLElem.appendChild(node);
142[simXMLElem, simXMLDoc] = saveMetrics(self, simXMLElem, simXMLDoc);
143[simXMLElem, simXMLDoc] = saveLinks(self, simXMLElem, simXMLDoc);
144[simXMLElem, simXMLDoc] = saveRegions(self, simXMLElem, simXMLDoc);
146hasReferenceNodes =
false;
147preloadNode = simXMLDoc.createElement(
'preload');
149numOfStations = sn.nstations;
151 isReferenceNode =
false;
152 if sn.nodetype(sn.stationToNode(i))~=NodeType.Source && sn.nodetype(sn.stationToNode(i))~=NodeType.Join
153 [~, nir] = State.toMarginal(sn, sn.stationToNode(i), s0{sn.stationToStateful(i)});
154 stationPopulationsNode = simXMLDoc.createElement(
'stationPopulations');
155 stationPopulationsNode.setAttribute(
'stationName', sn.nodenames{sn.stationToNode(i)});
156 % TODO:
this assumes that the preloading comes from the first
157 % state, but it could be that stateprior
is put on another
159 % Skip closed
classes with 0 customers, unless state has jobs via
class switching
160 if isfinite(sn.njobs(r)) && sn.njobs(r) == 0 && nir(1,r) == 0
164 classPopulationNode = simXMLDoc.createElement(
'classPopulation');
165 if isinf(sn.njobs(r))
167 isReferenceNode =
true;
168 classPopulationNode.setAttribute(
'population', sprintf(
'%d',round(nir(1,r))));
169 classPopulationNode.setAttribute(
'refClass', sn.classnames{r});
170 stationPopulationsNode.appendChild(classPopulationNode);
173 isReferenceNode =
true;
174 classPopulationNode.setAttribute(
'population', sprintf(
'%d',round(nir(1,r))));
175 classPopulationNode.setAttribute(
'refClass', sn.classnames{r});
176 stationPopulationsNode.appendChild(classPopulationNode);
181 preloadNode.appendChild(stationPopulationsNode);
183 hasReferenceNodes = hasReferenceNodes + isReferenceNode;
186 simXMLElem.appendChild(preloadNode);
190 xmlwrite(outputFileName, simXMLDoc);
192 getReport(ME,
'basic')
193 javaaddpath(which('xercesImpl-2.11.0.jar'));
194 javaaddpath(which('xml-apis-2.11.0.jar'));
196 xmlwrite(outputFileName, simXMLDoc);