View Javadoc
1   /*
2    * *************************************************************************************************************************************************************
3    *
4    * TheseFoolishThings: Miscellaneous utilities
5    * http://tidalwave.it/projects/thesefoolishthings
6    *
7    * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8    *
9    * *************************************************************************************************************************************************************
10   *
11   * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12   * You may obtain a copy of the License at
13   *
14   *     http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17   * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
18   *
19   * *************************************************************************************************************************************************************
20   *
21   * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
22   * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23   *
24   * *************************************************************************************************************************************************************
25   */
26  package it.tidalwave.util.impl;
27  
28  import jakarta.annotation.Nonnull;
29  import java.util.HashMap;
30  import java.util.Locale;
31  import java.util.Map;
32  import java.util.Objects;
33  import java.util.Optional;
34  import java.io.IOException;
35  import java.nio.file.Files;
36  import java.nio.file.Path;
37  import it.tidalwave.util.Key;
38  import it.tidalwave.util.PreferencesHandler;
39  import lombok.Getter;
40  import lombok.RequiredArgsConstructor;
41  
42  /***************************************************************************************************************************************************************
43   *
44   * @author  Fabrizio Giudici
45   *
46   **************************************************************************************************************************************************************/
47  @RequiredArgsConstructor
48  // PreferencesHandler can be used to programmatically set the log folder, so don't inject logger
49  public class DefaultPreferencesHandler implements PreferencesHandler
50    {
51      @Getter
52      private final Path appFolder;
53  
54      @Getter
55      private final Path logFolder;
56  
57      private final Map<Key<?>, Object> properties = new HashMap<>();
58  
59      public DefaultPreferencesHandler()
60        {
61          try
62            {
63              final var appName = System.getProperty(PROP_APP_NAME);
64              Objects.requireNonNull(appName, "You must call PreferencesHandler.setAppName(\"...\") before getting here");
65  
66              final var osName = System.getProperty("os.name").toLowerCase(Locale.getDefault());
67              var pattern = "";
68  
69              switch (osName)
70                {
71                  case "linux":
72                    pattern = "%s/.%s/";
73                    break;
74  
75                  case "mac os x":
76                    pattern = "%s/Library/Application Support/%s/";
77                    break;
78  
79                  case "windows":
80                    pattern = "%s/AppData/Local/%s/";
81                    break;
82  
83                  default:
84                    throw new ExceptionInInitializerError("Unknown o.s.: " + osName);
85                }
86  
87              final var home = System.getProperty("user.home", "/tmp");
88              appFolder = Path.of(String.format(pattern, home, appName)).toAbsolutePath();
89              logFolder = appFolder.resolve("logs").toAbsolutePath();
90              Files.createDirectories(logFolder);
91              // PreferencesHandler can be used to programmatically set the log folder, so don't log yet
92              if (!Boolean.getBoolean(PROP_SUPPRESS_CONSOLE))
93                {
94                  System.out.printf("App folder: %s%n", appFolder);
95                  System.out.printf("Logging folder: %s%n", logFolder);
96                }
97            }
98          catch (IOException e)
99            {
100             throw new RuntimeException(e);
101           }
102       }
103 
104     @Override @Nonnull
105     public <T> Optional<T> getProperty (@Nonnull final Key<T> name)
106       {
107         return Optional.ofNullable((T)properties.get(name));
108       }
109 
110     @Override
111     public <T> void setProperty (@Nonnull final Key<T> name, @Nonnull final T value)
112       {
113         properties.put(name, value);
114         // FIXME: should be made persistent (JSON?)
115       }
116 
117     @Override
118     public <T> void setDefaultProperty (@Nonnull final Key<T> name, @Nonnull final T value)
119       {
120         if (!properties.containsKey(name))
121           {
122             setProperty(name, value);
123           }
124       }
125   }