Mercurial > hg > ltpda
comparison m-toolbox/classes/@ltpda_uo/submit.m @ 20:d58813ab1b92 database-connection-manager
Update ltpda_uo.submit
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Mon, 05 Dec 2011 16:20:06 +0100 |
parents | f0afece42f48 |
children | ca0b8d4dcdb6 |
comparison
equal
deleted
inserted
replaced
19:69e3d49b4b0c | 20:d58813ab1b92 |
---|---|
40 % new table in the database. Then this list is passed to validate so that | 40 % new table in the database. Then this list is passed to validate so that |
41 % if the 'validate' plist option (which needs to be added) is set to true, | 41 % if the 'validate' plist option (which needs to be added) is set to true, |
42 % then we call validate on the object before submitting. If validate is | 42 % then we call validate on the object before submitting. If validate is |
43 % true, then we set the validated flag in the database after submission if | 43 % true, then we set the validated flag in the database after submission if |
44 % it passes. | 44 % it passes. |
45 % | 45 % |
46 % | 46 % |
47 | 47 |
48 | 48 |
49 function varargout = submit(varargin) | 49 function varargout = submit(varargin) |
50 | 50 |
51 % check if this is a call for parameters | 51 % check if this is a call for parameters |
52 if utils.helper.isinfocall(varargin{:}) | 52 if utils.helper.isinfocall(varargin{:}) |
53 varargout{1} = getInfo(varargin{3}); | 53 varargout{1} = getInfo(varargin{3}); |
54 return | 54 return |
55 end | 55 end |
56 | 56 |
57 import utils.const.* | 57 import utils.const.* |
58 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); | 58 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); |
59 | 59 |
60 % collect all AOs | 60 % collect all AOs |
61 [pls, invars, rest] = utils.helper.collect_objects(varargin(:), 'plist'); | 61 [pls, invars, rest] = utils.helper.collect_objects(varargin(:), 'plist'); |
62 [sinfo, invars, objs] = utils.helper.collect_objects(rest(:), 'struct'); | 62 [sinfo, invars, objs] = utils.helper.collect_objects(rest(:), 'struct'); |
63 | 63 |
64 % identify plists which are only used for the submission process | 64 % identify plists which are only used for the submission process |
65 mask = false(numel(pls), 1); | 65 mask = false(numel(pls), 1); |
66 for ii = 1:numel(pls) | 66 for ii = 1:numel(pls) |
67 if ~utils.helper.isSubmissionPlist(pls(ii)) | 67 if ~utils.helper.isSubmissionPlist(pls(ii)) |
68 mask(ii) = true; | 68 mask(ii) = true; |
75 end | 75 end |
76 % keep all the other as parameters plist | 76 % keep all the other as parameters plist |
77 if sum(~mask) | 77 if sum(~mask) |
78 pls = combine(pls(~mask)); | 78 pls = combine(pls(~mask)); |
79 end | 79 end |
80 | 80 |
81 % rearrange nested objects lists into a single cell array | 81 % rearrange nested objects lists into a single cell array |
82 objs = flatten(objs); | 82 objs = flatten(objs); |
83 | 83 |
84 if isempty(objs) | 84 if isempty(objs) |
85 error('### input at least one object to submit to the repository'); | 85 error('### input at least one object to submit to the repository'); |
86 end | 86 end |
87 | 87 |
88 % combine user plist with default | 88 % combine user plist with default |
89 pls = fixPlist(pls); | 89 pls = fixPlist(pls); |
90 dpl = getDefaultPlist(); | 90 dpl = getDefaultPlist(); |
91 pls = combine(pls, dpl.pset('HOSTNAME', '')); | 91 pls = combine(pls, dpl.pset('HOSTNAME', '')); |
92 | 92 |
93 % for backwards compatibility convert any user supplied sinfo-structure into a plist | 93 % for backwards compatibility convert any user supplied sinfo-structure into a plist |
94 pls = ltpda_uo.convertSinfo2Plist(pls, sinfo); | 94 pls = ltpda_uo.convertSinfo2Plist(pls, sinfo); |
95 | 95 |
96 % read XML submission informations file | 96 % read XML submission informations file |
97 filename = pls.find('sinfo filename'); | 97 filename = pls.find('sinfo filename'); |
98 if ~isempty(filename) | 98 if ~isempty(filename) |
99 try | 99 try |
100 pl = fixPlist(utils.xml.read_sinfo_xml(filename)); | 100 pl = fixPlist(utils.xml.read_sinfo_xml(filename)); |
101 pls = combine(pl, pls); | 101 pls = combine(pl, pls); |
102 catch err | 102 catch err |
103 error('### unable to read specified file: %s', filename); | 103 error('### unable to read specified file: %s', filename); |
104 end | 104 end |
105 end | 105 end |
106 | 106 |
107 % collect additional informations | 107 % collect additional informations |
108 sinfo = ltpda_uo.submitDialog(pls); | 108 sinfo = ltpda_uo.submitDialog(pls); |
109 if isempty(sinfo) | 109 if isempty(sinfo) |
110 [varargout{1}, varargout{2}] = userCanceled(); | 110 [varargout{1}, varargout{2}] = userCanceled(); |
111 return | 111 return |
112 end | 112 end |
113 | 113 |
114 % check completeness of user supplied informations | 114 % check completeness of user supplied informations |
115 sinfo = checkSinfo(sinfo); | 115 sinfo = checkSinfo(sinfo); |
116 | 116 |
117 % user supplied connection | 117 % database connection |
118 conn = find(pls, 'conn'); | 118 c = LTPDADatabaseConnectionManager().connect(pls); |
119 | 119 |
120 % obtain a connection from the connection manager | |
121 rm = LTPDARepositoryManager(); | |
122 | |
123 if isempty(conn) | |
124 connections = rm.findConnections(pls); | |
125 if isempty(connections) | |
126 % no connection found. create a new one | |
127 conn = rm.newConnection(pls); | |
128 if isempty(conn) | |
129 [varargout{1}, varargout{2}] = userCanceled(); | |
130 return | |
131 end | |
132 elseif numel(connections) == 1 && ~utils.prog.yes2true(pls.find('use selector')) | |
133 % found only one connection and we are not forcing the use of the selector | |
134 conn = connections(1); | |
135 else | |
136 % make the user select the desired database connection | |
137 conn = rm.manager.selectConnection([]); | |
138 if isempty(conn) | |
139 [varargout{1}, varargout{2}] = userCanceled(); | |
140 return | |
141 end | |
142 end | |
143 end | |
144 | |
145 % avoid to ask for a password if one was specified in the plist | |
146 if isjava(conn) && ~conn.isConnected() | |
147 passwd = pls.find('password'); | |
148 if ~isempty(passwd) | |
149 conn.setPassword(passwd); | |
150 end | |
151 end | |
152 | |
153 % connect to the database | |
154 if isempty(conn.openConnection()) | |
155 error('### unable to connect to the database') | |
156 end | |
157 | |
158 utils.helper.msg(msg.PROC1, 'submitting %d objects to repository', numel(objs)); | 120 utils.helper.msg(msg.PROC1, 'submitting %d objects to repository', numel(objs)); |
159 | 121 |
160 try | 122 try |
161 % lock connection to avoid expire during processing | 123 % get username and userid |
162 conn.setLocked(true); | 124 [username, userid] = utils.repository.getUser(c); |
163 | |
164 % reload connection table if we have a GUI | |
165 if ~isempty(rm.gui) | |
166 rm.gui.reloadConnectionTable(); | |
167 end | |
168 | |
169 % look-up user id | |
170 userid = utils.jmysql.getUserID(conn); | |
171 username = conn.getUsername(); | |
172 | |
173 utils.helper.msg(msg.PROC1, 'got user id %d for user: %s', userid, char(username)); | |
174 if userid < 1 || isnan(userid) || strcmp(userid, 'No Data') || ischar(userid) | |
175 error('### Unknown username.'); | |
176 end | |
177 | 125 |
178 % author of the data: let's take the username | 126 % author of the data: let's take the username |
179 author = username; | 127 author = username; |
180 | 128 |
181 % date for the transaction.transdata and objmeta.submitted columns as UTC time string | 129 % date for the transaction.transdata and objmeta.submitted columns as UTC time string |
182 t = time(); | 130 t = time(); |
183 tdate = format(t, 'yyyy-mm-dd HH:MM:SS', 'UTC'); | 131 tdate = format(t, 'yyyy-mm-dd HH:MM:SS', 'UTC'); |
184 | 132 |
185 % machine details | 133 % machine details |
186 prov = provenance(); | 134 prov = provenance(); |
187 | 135 |
188 utils.helper.msg(msg.IMPORTANT, 'submitting to %s@%s:%s', ... | |
189 char(conn.getUsername), char(conn.getHostname), char(conn.getDatabase)); | |
190 | |
191 % obtain the underlying connection | |
192 c = conn.getConn(); | |
193 | |
194 % start a transaction. either we submitt all objects or we roll back all changes | 136 % start a transaction. either we submitt all objects or we roll back all changes |
195 c.setAutoCommit(false); | 137 c.setAutoCommit(false); |
196 | 138 |
197 % process each object and collect id numbers | 139 % process each object and collect id numbers |
198 ids = zeros(numel(objs), 1); cid = []; | 140 ids = zeros(numel(objs), 1); cid = []; |
199 for kk = 1:numel(objs) | 141 for kk = 1:numel(objs) |
200 | 142 |
201 % this object | 143 % this object |
202 obj = objs{kk}; | 144 obj = objs{kk}; |
203 | 145 |
204 utils.helper.msg(msg.PROC1, 'submitting object: %s / %s', class(obj), obj.name); | 146 utils.helper.msg(msg.PROC1, 'submitting object: %s / %s', class(obj), obj.name); |
205 | 147 |
206 % format object creation time as UTC time string | 148 % format object creation time as UTC time string |
207 if isa(obj, 'plist') | 149 if isa(obj, 'plist') |
208 % plist-objects stores creatins time as milli secs since the epoch | 150 % plist-objects stores creatins time as milli secs since the epoch |
209 created = time().format('yyyy-mm-dd HH:MM:SS', 'UTC'); | 151 created = time().format('yyyy-mm-dd HH:MM:SS', 'UTC'); |
210 else | 152 else |
211 created = obj.created.format('yyyy-mm-dd HH:MM:SS', 'UTC'); | 153 created = obj.created.format('yyyy-mm-dd HH:MM:SS', 'UTC'); |
212 end | 154 end |
213 | 155 |
214 % Set the UUID if it is empty. This should only happen for PLIST | 156 % Set the UUID if it is empty. This should only happen for PLIST |
215 % objects. | 157 % objects. |
216 if isempty(obj.UUID) | 158 if isempty(obj.UUID) |
217 obj.UUID = char(java.util.UUID.randomUUID); | 159 obj.UUID = char(java.util.UUID.randomUUID); |
218 end | 160 end |
219 | 161 |
220 % create an XML representaion of the object | 162 % create an XML representaion of the object |
221 if utils.prog.yes2true(pls.find('binary')); | 163 if utils.prog.yes2true(pls.find('binary')); |
222 utils.helper.msg(msg.PROC2, 'binary submit'); | 164 utils.helper.msg(msg.PROC2, 'binary submit'); |
223 otxt = ['binary submit ' datestr(now)]; | 165 otxt = ['binary submit ' datestr(now)]; |
224 else | 166 else |
225 utils.helper.msg(msg.PROC2, 'xml submit'); | 167 utils.helper.msg(msg.PROC2, 'xml submit'); |
226 otxt = utils.prog.obj2xml(obj); | 168 otxt = utils.prog.obj2xml(obj); |
227 end | 169 end |
228 | 170 |
229 % create an MD5 hash of the xml representation | 171 % create an MD5 hash of the xml representation |
230 md5hash = utils.prog.hash(otxt, 'MD5'); | 172 md5hash = utils.prog.hash(otxt, 'MD5'); |
231 | 173 |
232 % create a binary representaion of the object | 174 % create a binary representaion of the object |
233 bobj = utils.prog.obj2binary(obj); | 175 bobj = utils.prog.obj2binary(obj); |
234 if isempty(bobj) | 176 if isempty(bobj) |
235 error('### failed to obtain a binary representation'); | 177 error('### failed to obtain a binary representation'); |
236 end | 178 end |
237 | 179 |
238 % submit object to objs table | 180 % submit object to objs table |
239 stmt = c.prepareStatement(... | 181 stmt = c.prepareStatement(... |
240 'INSERT INTO objs (xml, hash, uuid) VALUES (?, ?, ?)'); | 182 'INSERT INTO objs (xml, hash, uuid) VALUES (?, ?, ?)'); |
241 stmt.setObject(1, otxt); | 183 stmt.setObject(1, otxt); |
242 stmt.setObject(2, char(md5hash)); | 184 stmt.setObject(2, char(md5hash)); |
243 stmt.setObject(3, obj.UUID); | 185 stmt.setObject(3, obj.UUID); |
244 stmt.executeUpdate(); | 186 stmt.executeUpdate(); |
245 | 187 |
246 % obtain object id | 188 % obtain object id |
247 rs = stmt.getGeneratedKeys(); | 189 rs = stmt.getGeneratedKeys(); |
248 if rs.next() | 190 if rs.next() |
249 objid = rs.getInt(1); | 191 objid = rs.getInt(1); |
250 else | 192 else |
251 objid = []; | 193 objid = []; |
252 end | 194 end |
253 rs.close(); | 195 rs.close(); |
254 stmt.close(); | 196 stmt.close(); |
255 | 197 |
256 % insert binary representation | 198 % insert binary representation |
257 stmt = c.prepareStatement(... | 199 stmt = c.prepareStatement(... |
258 'INSERT INTO bobjs (obj_id, mat) VALUES (?,?)'); | 200 'INSERT INTO bobjs (obj_id, mat) VALUES (?,?)'); |
259 stmt.setObject(1, objid); | 201 stmt.setObject(1, objid); |
260 stmt.setObject(2, bobj); | 202 stmt.setObject(2, bobj); |
261 stmt.execute(); | 203 stmt.execute(); |
262 stmt.close(); | 204 stmt.close(); |
263 | 205 |
264 % reference IDs are stored in a CSV string | 206 % reference IDs are stored in a CSV string |
265 if ischar(sinfo.reference_ids) | 207 if ischar(sinfo.reference_ids) |
266 refids = sinfo.reference_ids; | 208 refids = sinfo.reference_ids; |
267 else | 209 else |
268 refids = utils.prog.csv(sinfo.reference_ids); | 210 refids = utils.prog.csv(sinfo.reference_ids); |
269 end | 211 end |
270 | 212 |
271 % insert object meta data | 213 % insert object meta data |
272 stmt = c.prepareStatement(... | 214 stmt = c.prepareStatement(... |
273 [ 'INSERT INTO objmeta (obj_id, obj_type, name, created, version, ' ... | 215 [ 'INSERT INTO objmeta (obj_id, obj_type, name, created, version, ' ... |
274 'ip, hostname, os, submitted, experiment_title, experiment_desc, ' ... | 216 'ip, hostname, os, submitted, experiment_title, experiment_desc, ' ... |
275 'reference_ids, additional_comments, additional_authors, keywords, ' ... | 217 'reference_ids, additional_comments, additional_authors, keywords, ' ... |
292 stmt.setObject(16, java.lang.String(sinfo.quantity)); | 234 stmt.setObject(16, java.lang.String(sinfo.quantity)); |
293 stmt.setObject(17, java.lang.String(sinfo.analysis_description)); | 235 stmt.setObject(17, java.lang.String(sinfo.analysis_description)); |
294 stmt.setObject(18, java.lang.String(author)); | 236 stmt.setObject(18, java.lang.String(author)); |
295 stmt.execute(); | 237 stmt.execute(); |
296 stmt.close(); | 238 stmt.close(); |
297 | 239 |
298 % update other meta-data tables | 240 % update other meta-data tables |
299 cols = utils.jmysql.execute(c, 'SHOW COLUMNS FROM tsdata'); | 241 cols = utils.mysql.execute(c, 'SHOW COLUMNS FROM tsdata'); |
300 if utils.helper.ismember('obj_id', cols(:,1)) | 242 if utils.helper.ismember('obj_id', cols(:,1)) |
301 % the tsdata table contains an obj id column. use the new database schema | 243 % the tsdata table contains an obj id column. use the new database schema |
302 utils.jmysql.insertObjMetadata(c, obj, objid); | 244 utils.repository.insertObjMetadata(c, obj, objid); |
303 else | 245 else |
304 % otherwise use the old one | 246 % otherwise use the old one |
305 utils.helper.msg(msg.PROC2, 'using back-compatibility code'); | 247 utils.helper.msg(msg.PROC2, 'using back-compatibility code'); |
306 utils.jmysql.insertObjMetadataV1(c, obj, objid); | 248 utils.repository.insertObjMetadataV1(c, obj, objid); |
307 end | 249 end |
308 | 250 |
309 % update transactions table | 251 % update transactions table |
310 stmt = c.prepareStatement(... | 252 stmt = c.prepareStatement(... |
311 'INSERT INTO transactions (obj_id, user_id, transdate, direction) VALUES (?, ?, ?, ?)'); | 253 'INSERT INTO transactions (obj_id, user_id, transdate, direction) VALUES (?, ?, ?, ?)'); |
312 stmt.setObject(1, objid); | 254 stmt.setObject(1, objid); |
313 stmt.setObject(2, userid); | 255 stmt.setObject(2, userid); |
314 stmt.setObject(3, java.lang.String(tdate)); | 256 stmt.setObject(3, java.lang.String(tdate)); |
315 stmt.setObject(4, java.lang.String('in')); | 257 stmt.setObject(4, java.lang.String('in')); |
316 stmt.execute(); | 258 stmt.execute(); |
317 stmt.close(); | 259 stmt.close(); |
318 | 260 |
319 % collect the id of the submitted object | 261 % collect the id of the submitted object |
320 ids(kk) = objid; | 262 ids(kk) = objid; |
321 end | 263 end |
322 | 264 |
323 % make collection entry | 265 % make collection entry |
324 if numel(objs) > 1 | 266 if numel(objs) > 1 |
325 | 267 |
326 % insert record into collections table | 268 % insert record into collections table |
327 stmt = c.prepareStatement(... | 269 stmt = c.prepareStatement(... |
328 'INSERT INTO collections (nobjs, obj_ids) VALUES (?, ?)'); | 270 'INSERT INTO collections (nobjs, obj_ids) VALUES (?, ?)'); |
329 stmt.setObject(1, length(ids)); | 271 stmt.setObject(1, length(ids)); |
330 stmt.setObject(2, java.lang.String(utils.prog.csv(ids))); | 272 stmt.setObject(2, java.lang.String(utils.prog.csv(ids))); |
331 stmt.executeUpdate(); | 273 stmt.executeUpdate(); |
332 | 274 |
333 % obtain collection id | 275 % obtain collection id |
334 rs = stmt.getGeneratedKeys(); | 276 rs = stmt.getGeneratedKeys(); |
335 if rs.next() | 277 if rs.next() |
336 cid = rs.getInt(1); | 278 cid = rs.getInt(1); |
337 else | 279 else |
338 cid = []; | 280 cid = []; |
339 end | 281 end |
340 rs.close(); | 282 rs.close(); |
341 stmt.close(); | 283 stmt.close(); |
342 | 284 |
343 end | 285 end |
344 | 286 |
345 catch ex | 287 catch ex |
346 utils.helper.msg(msg.IMPORTANT, 'submission error. no object submitted') | 288 utils.helper.msg(msg.IMPORTANT, 'submission error. no object submitted') |
347 c.close() | 289 c.close() |
348 conn.setLocked(false); | |
349 rethrow(ex) | 290 rethrow(ex) |
350 end | 291 end |
351 | 292 |
352 % commit the transaction | 293 % commit the transaction |
353 c.commit(); | 294 c.commit(); |
354 | 295 |
296 % close the connection if we own it | |
297 if isempty(find(pls, 'conn')) | |
298 c.close(); | |
299 end | |
300 | |
355 % report IDs of the inserted objects | 301 % report IDs of the inserted objects |
356 for kk = 1:numel(objs) | 302 for kk = 1:numel(objs) |
357 utils.helper.msg(msg.IMPORTANT, 'submitted %s object with ID: %d, UUID: %s, name: %s', ... | 303 utils.helper.msg(msg.IMPORTANT, 'submitted %s object with ID: %d UUID: %s name: %s', ... |
358 class(objs{kk}), ids(kk), objs{kk}.UUID, objs{kk}.name); | 304 class(objs{kk}), ids(kk), objs{kk}.UUID, objs{kk}.name); |
359 end | 305 end |
360 if ~isempty(cid) | 306 if ~isempty(cid) |
361 utils.helper.msg(msg.IMPORTANT, 'made collection entry with ID: %d', cid); | 307 utils.helper.msg(msg.IMPORTANT, 'made collection entry with ID: %d', cid); |
362 end | 308 end |
363 | 309 |
364 % unlock connection expire | |
365 conn.setLocked(false); | |
366 | |
367 % reset timer | |
368 LTPDARepositoryManager.resetTimer(rm.timerClearPass, conn); | |
369 LTPDARepositoryManager.resetTimer(rm.timerDisconnect, conn); | |
370 | |
371 % pass back outputs | 310 % pass back outputs |
372 if nargout > 0 | 311 if nargout > 0 |
373 varargout{1} = ids; | 312 varargout{1} = ids; |
374 end | 313 end |
375 if nargout > 1 | 314 if nargout > 1 |
387 end | 326 end |
388 | 327 |
389 | 328 |
390 function sinfo = checkSinfo(sinfo) | 329 function sinfo = checkSinfo(sinfo) |
391 % check sinfo structure | 330 % check sinfo structure |
392 | 331 |
393 import utils.const.* | 332 import utils.const.* |
394 | 333 |
395 % fieldnames | 334 % fieldnames |
396 mainfields = {'experiment_title', 'experiment_description', 'analysis_description'}; | 335 mainfields = {'experiment_title', 'experiment_description', 'analysis_description'}; |
397 extrafields = {'quantity', 'keywords', 'reference_ids', 'additional_comments', 'author', 'additional_authors'}; | 336 extrafields = {'quantity', 'keywords', 'reference_ids', 'additional_comments', 'author', 'additional_authors'}; |
398 | 337 |
399 % fieldnames of the input structure | 338 % fieldnames of the input structure |
400 fnames = fieldnames(sinfo); | 339 fnames = fieldnames(sinfo); |
401 | 340 |
402 % check mandatory fields | 341 % check mandatory fields |
403 for jj = 1:length(mainfields) | 342 for jj = 1:length(mainfields) |
404 if ~ismember(fnames, mainfields{jj}) | 343 if ~ismember(fnames, mainfields{jj}) |
405 error('### the sinfo structure should contain a ''%s'' field', mainfields{jj}); | 344 error('### the sinfo structure should contain a ''%s'' field', mainfields{jj}); |
406 end | 345 end |
407 end | 346 end |
408 | 347 |
409 % check extra fields | 348 % check extra fields |
410 for jj = 1:length(extrafields) | 349 for jj = 1:length(extrafields) |
411 if ~ismember(fnames, extrafields{jj}) | 350 if ~ismember(fnames, extrafields{jj}) |
412 utils.helper.msg(msg.PROC2, 'setting default for field %s', extrafields{jj}); | 351 utils.helper.msg(msg.PROC2, 'setting default for field %s', extrafields{jj}); |
413 sinfo.(extrafields{jj}) = ''; | 352 sinfo.(extrafields{jj}) = ''; |
414 end | 353 end |
415 end | 354 end |
416 | 355 |
417 % additional checks | 356 % additional checks |
418 if length(sinfo.experiment_title) < 5 | 357 if length(sinfo.experiment_title) < 5 |
419 error('### ''experiment title'' should be at least 5 characters long'); | 358 error('### ''experiment title'' should be at least 5 characters long'); |
420 end | 359 end |
421 if length(sinfo.experiment_description) < 10 | 360 if length(sinfo.experiment_description) < 10 |
422 error('### ''experiment description'' should be at least 10 characters long'); | 361 error('### ''experiment description'' should be at least 10 characters long'); |
423 end | 362 end |
424 if length(sinfo.analysis_description) < 10 | 363 if length(sinfo.analysis_description) < 10 |
425 error('### ''analysis description'' should be at least 10 characters long'); | 364 error('### ''analysis description'' should be at least 10 characters long'); |
426 end | 365 end |
427 | 366 |
428 end | 367 end |
429 | 368 |
430 | 369 |
431 function ii = getInfo(varargin) | 370 function ii = getInfo(varargin) |
432 if nargin == 1 && strcmpi(varargin{1}, 'None') | 371 if nargin == 1 && strcmpi(varargin{1}, 'None') |
449 end | 388 end |
450 plout = pl; | 389 plout = pl; |
451 end | 390 end |
452 | 391 |
453 function plo = buildplist() | 392 function plo = buildplist() |
454 | 393 |
455 plo = plist.TO_REPOSITORY_PLIST; | 394 plo = plist.TO_REPOSITORY_PLIST; |
456 | 395 |
457 p = param({'sinfo filename', 'Path to an XML file containing submission metadata'}, paramValue.EMPTY_STRING); | 396 p = param({'sinfo filename', 'Path to an XML file containing submission metadata'}, paramValue.EMPTY_STRING); |
458 plo.append(p); | 397 plo.append(p); |
459 | 398 |
460 p = param({'binary', 'Submit only binary version of the objects'}, paramValue.FALSE_TRUE); | 399 p = param({'binary', 'Submit only binary version of the objects'}, paramValue.FALSE_TRUE); |
461 plo.append(p); | 400 plo.append(p); |
462 end | 401 end |
463 | 402 |
464 | 403 |
472 end | 411 end |
473 | 412 |
474 | 413 |
475 function flat = flatten(objs) | 414 function flat = flatten(objs) |
476 % flatten nested lists into a single cell array | 415 % flatten nested lists into a single cell array |
477 | 416 |
478 flat = {}; | 417 flat = {}; |
479 | 418 |
480 while iscell(objs) && numel(objs) == 1 | 419 while iscell(objs) && numel(objs) == 1 |
481 objs = objs{1}; | 420 objs = objs{1}; |
482 end | 421 end |
483 | 422 |
484 if numel(objs) == 1 | 423 if numel(objs) == 1 |
485 flat = {objs}; | 424 flat = {objs}; |
486 return; | 425 return; |
487 end | 426 end |
488 | 427 |
489 for jj = 1:numel(objs) | 428 for jj = 1:numel(objs) |
490 obj = flatten(objs(jj)); | 429 obj = flatten(objs(jj)); |
491 for kk = 1:numel(obj) | 430 for kk = 1:numel(obj) |
492 flat = [ flat obj(kk) ]; | 431 flat = [ flat obj(kk) ]; |
493 end | 432 end |
494 end | 433 end |
495 | 434 |
496 end | 435 end |