View Javadoc
1   package org.eclipse.aether.internal.impl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * Manages access to a properties file.
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 }