1 package org.eclipse.aether.internal.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.eclipse.aether.SyncContext;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.Closeable;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.IOException;
33 import java.io.RandomAccessFile;
34 import java.util.Map;
35 import java.util.Properties;
36
37
38
39
40
41 class TrackingFileManager
42 {
43
44 private static final Logger LOGGER = LoggerFactory.getLogger( TrackingFileManager.class );
45
46 public Properties read( File file )
47 {
48 FileInputStream stream = null;
49 try
50 {
51 if ( !file.exists() )
52 {
53 return null;
54 }
55
56 stream = new FileInputStream( file );
57
58 Properties props = new Properties();
59 props.load( stream );
60
61 return props;
62 }
63 catch ( IOException e )
64 {
65 LOGGER.warn( "Failed to read tracking file {}", file, e );
66 }
67 finally
68 {
69 close( stream, file );
70 }
71
72 return null;
73 }
74
75 public Properties update( File file, Map<String, String> updates )
76 {
77 Properties props = new Properties();
78
79 File directory = file.getParentFile();
80 if ( !directory.mkdirs() && !directory.exists() )
81 {
82 LOGGER.warn( "Failed to create parent directories for tracking file {}", file );
83 return props;
84 }
85
86 RandomAccessFile raf = null;
87 try
88 {
89 raf = new RandomAccessFile( file, "rw" );
90
91 if ( file.canRead() )
92 {
93 byte[] buffer = new byte[(int) raf.length()];
94
95 raf.readFully( buffer );
96
97 ByteArrayInputStream stream = new ByteArrayInputStream( buffer );
98
99 props.load( stream );
100 }
101
102 for ( Map.Entry<String, String> update : updates.entrySet() )
103 {
104 if ( update.getValue() == null )
105 {
106 props.remove( update.getKey() );
107 }
108 else
109 {
110 props.setProperty( update.getKey(), update.getValue() );
111 }
112 }
113
114 ByteArrayOutputStream stream = new ByteArrayOutputStream( 1024 * 2 );
115
116 LOGGER.debug( "Writing tracking file {}", file );
117 props.store( stream, "NOTE: This is a Maven Resolver internal implementation file"
118 + ", its format can be changed without prior notice." );
119
120 raf.seek( 0 );
121 raf.write( stream.toByteArray() );
122 raf.setLength( raf.getFilePointer() );
123 }
124 catch ( IOException e )
125 {
126 LOGGER.warn( "Failed to write tracking file {}", file, e );
127 }
128 finally
129 {
130 close( raf, file );
131 }
132
133 return props;
134 }
135
136 private void close( Closeable closeable, File file )
137 {
138 if ( closeable != null )
139 {
140 try
141 {
142 closeable.close();
143 }
144 catch ( IOException e )
145 {
146 LOGGER.warn( "Error closing tracking file {}", file, e );
147 }
148 }
149 }
150
151 }