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.apache.syncope.client.enduser;
20  
21  import com.fasterxml.jackson.core.type.TypeReference;
22  import com.fasterxml.jackson.databind.json.JsonMapper;
23  import java.io.IOException;
24  import java.io.Serializable;
25  import java.io.StringWriter;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Base64;
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.stream.Collectors;
33  import org.apache.commons.lang3.StringUtils;
34  import org.apache.commons.lang3.math.NumberUtils;
35  import org.apache.wicket.util.cookies.CookieDefaults;
36  import org.apache.wicket.util.cookies.CookieUtils;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  public final class PreferenceManager implements Serializable {
41  
42      private static final long serialVersionUID = 3581434664555284193L;
43  
44      private static final Logger LOG = LoggerFactory.getLogger(PreferenceManager.class);
45  
46      private static final String COOKIE_NAME = "syncope2EnduserPrefs";
47  
48      private static final int ONE_YEAR_TIME = 60 * 60 * 24 * 365;
49  
50      private static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
51  
52      private static final TypeReference<Map<String, String>> MAP_TYPE_REF = new TypeReference<>() {
53      };
54  
55      private static final List<Integer> PAGINATOR_CHOICES = Arrays.asList(new Integer[] { 10, 25, 50 });
56  
57      private static final CookieUtils COOKIE_UTILS;
58  
59      static {
60          CookieDefaults cookieDefaults = new CookieDefaults();
61          cookieDefaults.setMaxAge(ONE_YEAR_TIME);
62          COOKIE_UTILS = new CookieUtils(cookieDefaults);
63      }
64  
65      public List<Integer> getPaginatorChoices() {
66          return PAGINATOR_CHOICES;
67      }
68  
69      private Map<String, String> getPrefs(final String value) {
70          Map<String, String> prefs;
71          try {
72              if (StringUtils.isNotBlank(value)) {
73                  prefs = MAPPER.readValue(value, MAP_TYPE_REF);
74              } else {
75                  throw new Exception("Invalid cookie value '" + value + "'");
76              }
77          } catch (Exception e) {
78              LOG.debug("No preferences found", e);
79              prefs = new HashMap<>();
80          }
81  
82          return prefs;
83      }
84  
85      private String setPrefs(final Map<String, String> prefs) throws IOException {
86          StringWriter writer = new StringWriter();
87          MAPPER.writeValue(writer, prefs);
88  
89          return writer.toString();
90      }
91  
92      public String get(final String key) {
93          String result = null;
94  
95          String prefString = COOKIE_UTILS.load(COOKIE_NAME);
96          if (prefString != null) {
97              Map<String, String> prefs = getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes())));
98              result = prefs.get(key);
99          }
100 
101         return result;
102     }
103 
104     public Integer getPaginatorRows(final String key) {
105         Integer result = getPaginatorChoices().get(0);
106 
107         String value = get(key);
108         if (value != null) {
109             result = NumberUtils.toInt(value, 10);
110         }
111 
112         return result;
113     }
114 
115     public List<String> getList(final String key) {
116         List<String> result = new ArrayList<>();
117 
118         String compound = get(key);
119 
120         if (StringUtils.isNotBlank(compound)) {
121             String[] items = compound.split(";");
122             result.addAll(Arrays.asList(items));
123         }
124 
125         return result;
126     }
127 
128     public void set(final Map<String, List<String>> prefs) {
129         Map<String, String> current = new HashMap<>();
130 
131         String prefString = COOKIE_UTILS.load(COOKIE_NAME);
132         if (prefString != null) {
133             current.putAll(getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes()))));
134         }
135 
136         // after retrieved previous setting in order to overwrite the key ...
137         prefs.forEach((key, values) -> current.put(key, values.stream().collect(Collectors.joining(";"))));
138 
139         try {
140             COOKIE_UTILS.save(COOKIE_NAME, Base64.getEncoder().encodeToString(setPrefs(current).getBytes()));
141         } catch (IOException e) {
142             LOG.error("Could not save {} info: {}", getClass().getSimpleName(), current, e);
143         }
144     }
145 
146     public void set(final String key, final String value) {
147         String prefString = COOKIE_UTILS.load(COOKIE_NAME);
148 
149         final Map<String, String> current = new HashMap<>();
150         if (prefString != null) {
151             current.putAll(getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes()))));
152         }
153 
154         // after retrieved previous setting in order to overwrite the key ...
155         current.put(key, value);
156 
157         try {
158             COOKIE_UTILS.save(COOKIE_NAME, Base64.getEncoder().encodeToString(setPrefs(current).getBytes()));
159         } catch (IOException e) {
160             LOG.error("Could not save {} info: {}", getClass().getSimpleName(), current, e);
161         }
162     }
163 
164     public void setList(final String key, final List<String> values) {
165         set(key, values.stream().collect(Collectors.joining(";")));
166     }
167 
168     public void setList(final Map<String, List<String>> prefs) {
169         set(prefs);
170     }
171 
172     private PreferenceManager() {
173         // private constructor for static utility class
174     }
175 }