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