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 javax.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 java.nio.file.Paths;
38  import it.tidalwave.util.Key;
39  import it.tidalwave.util.PreferencesHandler;
40  import lombok.Getter;
41  import lombok.RequiredArgsConstructor;
42  
43  /***************************************************************************************************************************************************************
44   *
45   * @author  Fabrizio Giudici
46   *
47   **************************************************************************************************************************************************************/
48  @RequiredArgsConstructor
49  // PreferencesHandler can be used to programmatically set the log folder, so don't inject logger
50  public class DefaultPreferencesHandler implements PreferencesHandler
51    {
52      @Getter
53      private final Path appFolder;
54  
55      @Getter
56      private final Path logFolder;
57  
58      private final Map<Key<?>, Object> properties = new HashMap<>();
59  
60      public DefaultPreferencesHandler()
61        {
62          try
63            {
64              final var appName = System.getProperty(PROP_APP_NAME);
65              Objects.requireNonNull(appName, "You must call PreferencesHandler.setAppName(\"...\") before getting here");
66  
67              final var osName = System.getProperty("os.name").toLowerCase(Locale.getDefault());
68              var pattern = "";
69  
70              switch (osName)
71                {
72                  case "linux":
73                    pattern = "%s/.%s/";
74                    break;
75  
76                  case "mac os x":
77                    pattern = "%s/Library/Application Support/%s/";
78                    break;
79  
80                  case "windows":
81                    pattern = "%s/AppData/Local/%s/";
82                    break;
83  
84                  default:
85                    throw new ExceptionInInitializerError("Unknown o.s.: " + osName);
86                }
87  
88              final var home = System.getProperty("user.home", "/tmp");
89              appFolder = Paths.get(String.format(pattern, home, appName)).toAbsolutePath();
90              logFolder = appFolder.resolve("logs").toAbsolutePath();
91              Files.createDirectories(logFolder);
92              // PreferencesHandler can be used to programmatically set the log folder, so don't log yet
93              if (!Boolean.getBoolean(PROP_SUPPRESS_CONSOLE))
94                {
95                  System.out.printf("App folder: %s%n", appFolder);
96                  System.out.printf("Logging folder: %s%n", logFolder);
97                }
98            }
99          catch (IOException e)
100           {
101             throw new RuntimeException(e);
102           }
103       }
104 
105     @Override @Nonnull
106     public <T> Optional<T> getProperty (@Nonnull final Key<T> name)
107       {
108         return Optional.ofNullable((T)properties.get(name));
109       }
110 
111     @Override
112     public <T> void setProperty (@Nonnull final Key<T> name, @Nonnull final T value)
113       {
114         properties.put(name, value);
115         // FIXME: should be made persistent (JSON?)
116       }
117 
118     @Override
119     public <T> void setDefaultProperty (@Nonnull final Key<T> name, @Nonnull final T value)
120       {
121         if (!properties.containsKey(name))
122           {
123             setProperty(name, value);
124           }
125       }
126   }