View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.OutputStream;
28  import java.io.UncheckedIOException;
29  import java.nio.file.Files;
30  import java.nio.file.Path;
31  import java.util.Map;
32  import java.util.Properties;
33  
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  /**
38   * Manages access to a properties file.
39   */
40  @Singleton
41  @Named
42  public final class DefaultTrackingFileManager implements TrackingFileManager {
43      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultTrackingFileManager.class);
44  
45      @Override
46      public Properties read(File file) {
47          Path filePath = file.toPath();
48          if (Files.isReadable(filePath)) {
49              try (InputStream stream = Files.newInputStream(filePath)) {
50                  Properties props = new Properties();
51                  props.load(stream);
52                  return props;
53              } catch (IOException e) {
54                  LOGGER.warn("Failed to read tracking file '{}'", file, e);
55                  throw new UncheckedIOException(e);
56              }
57          }
58          return null;
59      }
60  
61      @Override
62      public Properties update(File file, Map<String, String> updates) {
63          Path filePath = file.toPath();
64          Properties props = new Properties();
65  
66          try {
67              Files.createDirectories(filePath.getParent());
68          } catch (IOException e) {
69              LOGGER.warn("Failed to create tracking file parent '{}'", file, e);
70              throw new UncheckedIOException(e);
71          }
72  
73          try {
74              if (Files.isReadable(filePath)) {
75                  try (InputStream stream = Files.newInputStream(filePath)) {
76                      props.load(stream);
77                  }
78              }
79  
80              for (Map.Entry<String, String> update : updates.entrySet()) {
81                  if (update.getValue() == null) {
82                      props.remove(update.getKey());
83                  } else {
84                      props.setProperty(update.getKey(), update.getValue());
85                  }
86              }
87  
88              try (OutputStream stream = Files.newOutputStream(filePath)) {
89                  LOGGER.debug("Writing tracking file '{}'", file);
90                  props.store(
91                          stream,
92                          "NOTE: This is a Maven Resolver internal implementation file"
93                                  + ", its format can be changed without prior notice.");
94              }
95          } catch (IOException e) {
96              LOGGER.warn("Failed to write tracking file '{}'", file, e);
97              throw new UncheckedIOException(e);
98          }
99  
100         return props;
101     }
102 }