24
24
import java .io .IOException ;
25
25
import java .net .URI ;
26
26
import java .util .HashMap ;
27
+ import java .util .LinkedHashMap ;
27
28
import java .util .Map ;
29
+ import java .util .Map .Entry ;
28
30
import org .eclipse .core .filesystem .URIUtil ;
31
+ import org .eclipse .core .internal .events .BuildCommand ;
29
32
import org .eclipse .core .internal .localstore .SafeChunkyInputStream ;
30
33
import org .eclipse .core .internal .localstore .SafeChunkyOutputStream ;
31
34
import org .eclipse .core .internal .utils .Messages ;
32
35
import org .eclipse .core .internal .utils .Policy ;
33
36
import org .eclipse .core .resources .IBuildConfiguration ;
37
+ import org .eclipse .core .resources .ICommand ;
34
38
import org .eclipse .core .resources .IProject ;
35
39
import org .eclipse .core .resources .IResource ;
36
40
import org .eclipse .core .resources .IResourceStatus ;
@@ -330,6 +334,8 @@ public ProjectDescription readOldDescription(IProject project) throws CoreExcept
330
334
* location should be used. In the case of failure, log the exception and
331
335
* return silently, thus reverting to using the default location and no
332
336
* dynamic references. The current format of the location file is:
337
+ *
338
+ * <pre>
333
339
* UTF - project location
334
340
* int - number of dynamic project references
335
341
* UTF - project reference 1
@@ -347,6 +353,19 @@ public ProjectDescription readOldDescription(IProject project) throws CoreExcept
347
353
* UTF - configName if hasConfigName
348
354
* ... repeat for number of referenced configurations
349
355
* ... repeat for number of build configurations with references
356
+ * since 3.23:
357
+ * bool - private flag if project should only be read from its private project configuration
358
+ * int - number of natures
359
+ * UTF - nature id
360
+ * ... repeated for N natures
361
+ * int - number of buildspecs
362
+ * byte - type of buildspec
363
+ * (type 1) UTF - name of builder
364
+ * int - number of arguments
365
+ * UTF arg key
366
+ * UTF arg value
367
+ * UTF - triggers string
368
+ * </pre>
350
369
*/
351
370
public void readPrivateDescription (IProject target , ProjectDescription description ) {
352
371
IPath locationFile = locationFor (target ).append (F_PROJECT_LOCATION );
@@ -357,6 +376,17 @@ public void readPrivateDescription(IProject target, ProjectDescription descripti
357
376
if (!file .exists ())
358
377
return ;
359
378
}
379
+ try {
380
+ readFromFile (target , description , file );
381
+ } catch (IOException e ) {
382
+ //ignore - this is an old location file or an exception occurred
383
+ // closing the stream
384
+ }
385
+ }
386
+
387
+ @ SuppressWarnings ("deprecation" )
388
+ public void readFromFile (IProject target , ProjectDescription description , java .io .File file ) throws IOException {
389
+ description .setName (target .getName ());
360
390
try (DataInputStream dataIn = new DataInputStream (new SafeChunkyInputStream (file , 500 ))) {
361
391
try {
362
392
String location = dataIn .readUTF ();
@@ -408,9 +438,34 @@ public void readPrivateDescription(IProject target, ProjectDescription descripti
408
438
m .put (configName , refs );
409
439
}
410
440
description .setBuildConfigReferences (m );
411
- } catch (IOException e ) {
412
- //ignore - this is an old location file or an exception occurred
413
- // closing the stream
441
+ // read parts since 3.23
442
+ int natures = dataIn .readInt ();
443
+ String [] natureIds = new String [natures ];
444
+ for (int i = 0 ; i < natures ; i ++) {
445
+ natureIds [i ] = dataIn .readUTF ();
446
+ }
447
+ description .setNatureIds (natureIds );
448
+ int buildspecs = dataIn .readInt ();
449
+ ICommand [] buildSpecData = new ICommand [buildspecs ];
450
+ for (int i = 0 ; i < buildspecs ; i ++) {
451
+ BuildCommand command = new BuildCommand ();
452
+ buildSpecData [i ] = command ;
453
+ int type = dataIn .read ();
454
+ if (type == 1 ) {
455
+ command .setName (dataIn .readUTF ());
456
+ int args = dataIn .readInt ();
457
+ Map <String , String > map = new LinkedHashMap <>();
458
+ for (int j = 0 ; j < args ; j ++) {
459
+ map .put (dataIn .readUTF (), dataIn .readUTF ());
460
+ }
461
+ command .setArguments (map );
462
+ String trigger = dataIn .readUTF ();
463
+ if (!trigger .isEmpty ()) {
464
+ ProjectDescriptionReader .parseBuildTriggers (command , trigger );
465
+ }
466
+ }
467
+ }
468
+ description .setBuildSpec (buildSpecData );
414
469
}
415
470
}
416
471
@@ -426,13 +481,25 @@ public void writePrivateDescription(IProject target) throws CoreException {
426
481
Workspace .clear (file );
427
482
//don't write anything if there is no interesting private metadata
428
483
ProjectDescription desc = ((Project ) target ).internalGetDescription ();
484
+ try {
485
+ writeToFile (desc , file );
486
+ } catch (IOException e ) {
487
+ String message = NLS .bind (Messages .resources_exSaveProjectLocation , target .getName ());
488
+ throw new ResourceException (IResourceStatus .INTERNAL_ERROR , null , message , e );
489
+ }
490
+ }
491
+
492
+ public void writeToFile (ProjectDescription desc , java .io .File file ) throws IOException {
429
493
if (desc == null )
430
494
return ;
431
495
final URI projectLocation = desc .getLocationURI ();
432
496
final IProject [] prjRefs = desc .getDynamicReferences (false );
433
497
final String [] buildConfigs = desc .configNames ;
434
498
final Map <String , IBuildConfiguration []> configRefs = desc .getBuildConfigReferences (false );
435
- if (projectLocation == null && prjRefs .length == 0 && buildConfigs .length == 0 && configRefs .isEmpty ())
499
+ final String [] natureIds = desc .getNatureIds ();
500
+ final ICommand [] buildSpec = desc .getBuildSpec (false );
501
+ if (projectLocation == null && prjRefs .length == 0 && buildConfigs .length == 0 && configRefs .isEmpty ()
502
+ && natureIds .length == 0 && buildSpec .length == 0 )
436
503
return ;
437
504
//write the private metadata file
438
505
try (SafeChunkyOutputStream output = new SafeChunkyOutputStream (file ); DataOutputStream dataOut = new DataOutputStream (output );) {
@@ -470,10 +537,33 @@ public void writePrivateDescription(IProject target) throws CoreException {
470
537
}
471
538
}
472
539
}
540
+ // write parts since 3.23
541
+ dataOut .writeInt (natureIds .length );
542
+ for (String id : natureIds ) {
543
+ dataOut .writeUTF (id );
544
+ }
545
+ dataOut .writeInt (buildSpec .length );
546
+ for (ICommand command : buildSpec ) {
547
+ if (command instanceof BuildCommand b ) {
548
+ dataOut .write (1 );
549
+ dataOut .writeUTF (b .getName ());
550
+ Map <String , String > arguments = b .getArguments ();
551
+ dataOut .writeInt (arguments .size ());
552
+ for (Entry <String , String > entry : arguments .entrySet ()) {
553
+ dataOut .writeUTF (entry .getKey ());
554
+ dataOut .writeUTF (entry .getValue ());
555
+ }
556
+ if (ModelObjectWriter .shouldWriteTriggers (b )) {
557
+ dataOut .writeUTF (ModelObjectWriter .triggerString (b ));
558
+ } else {
559
+ dataOut .writeUTF ("" ); //$NON-NLS-1$
560
+ }
561
+ } else {
562
+ dataOut .write (0 );
563
+ }
564
+ }
565
+ dataOut .flush ();
473
566
output .succeed ();
474
- } catch (IOException e ) {
475
- String message = NLS .bind (Messages .resources_exSaveProjectLocation , target .getName ());
476
- throw new ResourceException (IResourceStatus .INTERNAL_ERROR , null , message , e );
477
567
}
478
568
}
479
569
}
0 commit comments