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