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);
47 % Retrial and impatience use different Queue constructors:
48 % With retrial: Queue(Integer, String[], ServiceStrategy[], QueueGetStrategy, QueuePutStrategy[])
49 % With impatience: Queue(Integer, String[], QueueGetStrategy, QueuePutStrategy[], Impatience[])
50 nodeHasRetrial = false;
51 nodes = self.model.getNodes();
53 if isa(bufNode,
'Queue') && ~isempty(bufNode.retrialDelays)
54 for rr = 1:size(bufNode.retrialDelays, 2)
55 if ~isempty(bufNode.retrialDelays{1, rr})
56 nodeHasRetrial =
true;
62 [simXMLDoc, xml_section] = saveRetrialDistributions(self, simXMLDoc, xml_section, ind);
63 [simXMLDoc, xml_section] = saveGetStrategy(self, simXMLDoc, xml_section, ind);
64 [simXMLDoc, xml_section] = savePutStrategy(self, simXMLDoc, xml_section, ind);
66 [simXMLDoc, xml_section] = saveGetStrategy(self, simXMLDoc, xml_section, ind);
67 [simXMLDoc, xml_section] = savePutStrategy(self, simXMLDoc, xml_section, ind);
68 [simXMLDoc, xml_section] = saveImpatience(self, simXMLDoc, xml_section, ind);
71 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
72 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
73 % Heterogeneous server configuration
74 [simXMLDoc, xml_section] = saveServerTypeNames(self, simXMLDoc, xml_section, ind);
75 [simXMLDoc, xml_section] = saveServersPerType(self, simXMLDoc, xml_section, ind);
76 [simXMLDoc, xml_section] = saveServerCompatibilities(self, simXMLDoc, xml_section, ind);
77 [simXMLDoc, xml_section] = saveHeteroSchedPolicy(self, simXMLDoc, xml_section, ind);
78 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
79 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
80 % Note: SwitchoverStrategy
is only supported by PollingServer in JMT
81 % Regular Server
class does not support switchover times
82 if ~isempty(currentNode.switchoverTime)
83 line_warning(mfilename, 'JMT does not support switchover times for non-polling queues. Switchover times will be ignored for node %s.
', currentNode.name);
85 case 'PreemptiveServer
'
86 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
87 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
88 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
89 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
91 xml_section.setAttribute('className
', 'PSServer
'); %overwrite with JMT class name
92 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
93 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
94 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
95 [simXMLDoc, xml_section] = saveDelayOffStrategy(self, simXMLDoc, xml_section, ind);
96 [simXMLDoc, xml_section] = savePreemptiveStrategy(self, simXMLDoc, xml_section, ind);
97 [simXMLDoc, xml_section] = savePreemptiveWeights(self, simXMLDoc, xml_section, ind);
99 xml_section.setAttribute('className
', 'Delay
'); %overwrite with JMT class name
100 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
102 % we assume identical polling type on each buffer
103 switch sn.nodeparam{ind}{1}.pollingType
104 case PollingType.GATED
105 xml_section.setAttribute('className
', 'GatedPollingServer
'); %overwrite with JMT class name
106 case PollingType.EXHAUSTIVE
107 xml_section.setAttribute('className
', 'ExhaustivePollingServer
'); %overwrite with JMT class name
108 case PollingType.KLIMITED
109 xml_section.setAttribute('className
', 'LimitedPollingServer
'); %overwrite with JMT class name
110 case PollingType.DECREMENTING
111 line_error(mfilename,['JMT does not support
the decrementing
' ...
112 '(semiexhaustive) polling discipline; use
the LDES solver.
']);
114 [simXMLDoc, xml_section] = saveNumberOfServers(self, simXMLDoc, xml_section, ind);
115 [simXMLDoc, xml_section] = saveServerVisits(self, simXMLDoc, xml_section);
116 [simXMLDoc, xml_section] = saveServiceStrategy(self, simXMLDoc, xml_section, ind);
117 [simXMLDoc, xml_section] = saveSwitchoverStrategy(self, simXMLDoc, xml_section, ind);
119 [simXMLDoc, xml_section] = saveArrivalStrategy(self, simXMLDoc, xml_section, ind);
121 xml_section.setAttribute('className
', 'Router
'); %overwrite with JMT class name
122 [simXMLDoc, xml_section] = saveRoutingStrategy(self, simXMLDoc, xml_section, ind);
123 case 'StatelessClassSwitcher
'
124 xml_section.setAttribute('className
', 'ClassSwitch
'); %overwrite with JMT class name
125 [simXMLDoc, xml_section] = saveClassSwitchStrategy(self, simXMLDoc, xml_section, ind);
127 % CacheClassSwitcher section has className='Cache
'
128 [simXMLDoc, xml_section] = saveCacheStrategy(self, simXMLDoc, xml_section, ind);
130 [simXMLDoc, xml_section] = saveLogTunnel(self, simXMLDoc, xml_section, ind);
132 xml_section.setAttribute('className
', 'Join
'); %overwrite with JMT class name
133 [simXMLDoc, xml_section] = saveJoinStrategy(self, simXMLDoc, xml_section, ind);
135 xml_section.setAttribute('className
', 'Fork
'); %overwrite with JMT class name
136 [simXMLDoc, xml_section] = saveForkStrategy(self, simXMLDoc, xml_section, ind);
138 xml_section.setAttribute('className
', 'Storage
'); %overwrite with JMT class name
139 [simXMLDoc, xml_section] = saveTotalCapacity(self, simXMLDoc, xml_section, ind);
140 [simXMLDoc, xml_section] = savePlaceCapacities(self, simXMLDoc, xml_section, ind);
141 [simXMLDoc, xml_section] = saveDropRule(self, simXMLDoc, xml_section, ind); % unfinished
142 [simXMLDoc, xml_section] = saveGetStrategy(self, simXMLDoc, xml_section, ind);
143 [simXMLDoc, xml_section] = savePutStrategies(self, simXMLDoc, xml_section, ind);
145 xml_section.setAttribute('className
', 'Enabling
'); %overwrite with JMT class name
146 [simXMLDoc, xml_section] = saveEnablingConditions(self, simXMLDoc, xml_section, ind);
147 [simXMLDoc, xml_section] = saveInhibitingConditions(self, simXMLDoc, xml_section, ind);
149 xml_section.setAttribute('className
', 'Firing
'); %overwrite with JMT class name
150 [simXMLDoc, xml_section] = saveFiringOutcomes(self, simXMLDoc, xml_section, ind);
152 xml_section.setAttribute('className
', 'Timing
'); %overwrite with JMT class name
153 [simXMLDoc, xml_section] = saveModeNames(self, simXMLDoc, xml_section, ind);
154 [simXMLDoc, xml_section] = saveNumbersOfServers(self, simXMLDoc, xml_section, ind);
155 [simXMLDoc, xml_section] = saveTimingStrategies(self, simXMLDoc, xml_section, ind);
156 [simXMLDoc, xml_section] = saveFiringPriorities(self, simXMLDoc, xml_section, ind);
157 [simXMLDoc, xml_section] = saveFiringWeights(self, simXMLDoc, xml_section, ind);
159 node.appendChild(xml_section);
162 simXMLElem.appendChild(node);
165[simXMLElem, simXMLDoc] = saveMetrics(self, simXMLElem, simXMLDoc);
166[simXMLElem, simXMLDoc] = saveLinks(self, simXMLElem, simXMLDoc);
167[simXMLElem, simXMLDoc] = saveRegions(self, simXMLElem, simXMLDoc);
169hasReferenceNodes = false;
170preloadNode = simXMLDoc.createElement('preload
');
172numOfStations = sn.nstations;
174 isReferenceNode = false;
175 if sn.nodetype(sn.stationToNode(i))~=NodeType.Source && sn.nodetype(sn.stationToNode(i))~=NodeType.Join
176 [~, nir] = State.toMarginal(sn, sn.stationToNode(i), s0{sn.stationToStateful(i)});
177 stationPopulationsNode = simXMLDoc.createElement('stationPopulations
');
178 stationPopulationsNode.setAttribute('stationName
', sn.nodenames{sn.stationToNode(i)});
179 % TODO: this assumes that the preloading comes from the first
180 % state, but it could be that stateprior is put on another
182 % Skip closed classes with 0 customers, unless state has jobs via class switching
183 if isfinite(sn.njobs(r)) && sn.njobs(r) == 0 && nir(1,r) == 0
187 classPopulationNode = simXMLDoc.createElement('classPopulation
');
188 if isinf(sn.njobs(r))
190 isReferenceNode = true;
191 classPopulationNode.setAttribute('population
', sprintf('%d
',round(nir(1,r))));
192 classPopulationNode.setAttribute('refClass
', sn.classnames{r});
193 stationPopulationsNode.appendChild(classPopulationNode);
196 isReferenceNode = true;
197 classPopulationNode.setAttribute('population
', sprintf('%d
',round(nir(1,r))));
198 classPopulationNode.setAttribute('refClass
', sn.classnames{r});
199 stationPopulationsNode.appendChild(classPopulationNode);
204 preloadNode.appendChild(stationPopulationsNode);
206 hasReferenceNodes = hasReferenceNodes + isReferenceNode;
209 simXMLElem.appendChild(preloadNode);
213 xmlwrite(outputFileName, simXMLDoc);
215 getReport(ME,'basic
')
216 javaaddpath(which('xercesImpl-2.11.0.jar
'));
217 javaaddpath(which('xml-apis-2.11.0.jar
'));
219 xmlwrite(outputFileName, simXMLDoc);