2424import java .io .IOException ;
2525import java .net .URI ;
2626import java .util .HashMap ;
27+ import java .util .LinkedHashMap ;
2728import java .util .Map ;
29+ import java .util .Map .Entry ;
2830import org .eclipse .core .filesystem .URIUtil ;
31+ import org .eclipse .core .internal .events .BuildCommand ;
2932import org .eclipse .core .internal .localstore .SafeChunkyInputStream ;
3033import org .eclipse .core .internal .localstore .SafeChunkyOutputStream ;
3134import org .eclipse .core .internal .utils .Messages ;
3235import org .eclipse .core .internal .utils .Policy ;
3336import org .eclipse .core .resources .IBuildConfiguration ;
37+ import org .eclipse .core .resources .ICommand ;
3438import org .eclipse .core .resources .IProject ;
3539import org .eclipse .core .resources .IResource ;
3640import org .eclipse .core .resources .IResourceStatus ;
@@ -330,6 +334,8 @@ public ProjectDescription readOldDescription(IProject project) throws CoreExcept
330334 * location should be used. In the case of failure, log the exception and
331335 * return silently, thus reverting to using the default location and no
332336 * dynamic references. The current format of the location file is:
337+ *
338+ * <pre>
333339 * UTF - project location
334340 * int - number of dynamic project references
335341 * UTF - project reference 1
@@ -347,6 +353,19 @@ public ProjectDescription readOldDescription(IProject project) throws CoreExcept
347353 * UTF - configName if hasConfigName
348354 * ... repeat for number of referenced configurations
349355 * ... 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>
350369 */
351370 public void readPrivateDescription (IProject target , ProjectDescription description ) {
352371 IPath locationFile = locationFor (target ).append (F_PROJECT_LOCATION );
@@ -357,6 +376,7 @@ public void readPrivateDescription(IProject target, ProjectDescription descripti
357376 if (!file .exists ())
358377 return ;
359378 }
379+ description .setName (target .getName ());
360380 try (DataInputStream dataIn = new DataInputStream (new SafeChunkyInputStream (file , 500 ))) {
361381 try {
362382 String location = dataIn .readUTF ();
@@ -408,6 +428,33 @@ public void readPrivateDescription(IProject target, ProjectDescription descripti
408428 m .put (configName , refs );
409429 }
410430 description .setBuildConfigReferences (m );
431+ // read parts since 3.23
432+ String [] natureIds = new String [dataIn .readInt ()];
433+ for (int i = 0 ; i < natureIds .length ; i ++) {
434+ natureIds [i ] = dataIn .readUTF ();
435+ }
436+ description .setNatureIds (natureIds );
437+ int buildspecs = dataIn .readInt ();
438+ ICommand [] buildSpecData = new ICommand [buildspecs ];
439+ for (int i = 0 ; i < buildSpecData .length ; i ++) {
440+ BuildCommand command = new BuildCommand ();
441+ buildSpecData [i ] = command ;
442+ int type = dataIn .read ();
443+ if (type == 1 ) {
444+ command .setName (dataIn .readUTF ());
445+ int args = dataIn .readInt ();
446+ Map <String , String > map = new LinkedHashMap <>();
447+ for (int j = 0 ; j < args ; j ++) {
448+ map .put (dataIn .readUTF (), dataIn .readUTF ());
449+ }
450+ command .setArguments (map );
451+ String trigger = dataIn .readUTF ();
452+ if (!trigger .isEmpty ()) {
453+ ProjectDescriptionReader .parseBuildTriggers (command , trigger );
454+ }
455+ }
456+ description .setBuildSpec (buildSpecData );
457+ }
411458 } catch (IOException e ) {
412459 //ignore - this is an old location file or an exception occurred
413460 // closing the stream
@@ -470,6 +517,34 @@ public void writePrivateDescription(IProject target) throws CoreException {
470517 }
471518 }
472519 }
520+ // write parts since 3.23
521+ String [] natureIds = desc .getNatureIds ();
522+ dataOut .writeInt (natureIds .length );
523+ for (String id : natureIds ) {
524+ dataOut .writeUTF (id );
525+ }
526+ ICommand [] buildSpec = desc .getBuildSpec (false );
527+ dataOut .write (buildSpec .length );
528+ for (ICommand command : buildSpec ) {
529+ if (command instanceof BuildCommand b ) {
530+ dataOut .write (1 );
531+ dataOut .writeUTF (b .getName ());
532+ Map <String , String > arguments = b .getArguments ();
533+ dataOut .writeInt (arguments .size ());
534+ for (Entry <String , String > entry : arguments .entrySet ()) {
535+ dataOut .writeUTF (entry .getKey ());
536+ dataOut .writeUTF (entry .getValue ());
537+ }
538+ if (ModelObjectWriter .shouldWriteTriggers (b )) {
539+ dataOut .writeUTF (ModelObjectWriter .triggerString (b ));
540+ } else {
541+ dataOut .writeUTF ("" ); //$NON-NLS-1$
542+ }
543+ } else {
544+ dataOut .write (0 );
545+ }
546+ }
547+ dataOut .flush ();
473548 output .succeed ();
474549 } catch (IOException e ) {
475550 String message = NLS .bind (Messages .resources_exSaveProjectLocation , target .getName ());
0 commit comments