View Javadoc
1   /**
2    * This file Copyright (c) 2020 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.datasource.locale;
35  
36  import info.magnolia.context.Context;
37  import info.magnolia.icons.MagnoliaIcons;
38  import info.magnolia.ui.editor.LocaleContext;
39  import info.magnolia.ui.field.SelectFieldSupport;
40  
41  import java.util.Locale;
42  import java.util.Optional;
43  import java.util.stream.Stream;
44  
45  import javax.inject.Inject;
46  
47  import com.vaadin.data.Converter;
48  import com.vaadin.data.Result;
49  import com.vaadin.data.ValueContext;
50  import com.vaadin.data.provider.AbstractDataProvider;
51  import com.vaadin.data.provider.Query;
52  import com.vaadin.ui.IconGenerator;
53  import com.vaadin.ui.ItemCaptionGenerator;
54  
55  /**
56   * {@link info.magnolia.ui.field.SelectFieldSupport} implementation based on available {@link java.util.Locale}s for content.
57   * {@link #defaultConverter()} uses IETF BCP 47 language tag. See {@link Locale#toLanguageTag()} and {@link Locale#forLanguageTag(String)}.
58   */
59  public class LocaleSelectFieldSupport implements SelectFieldSupport<Locale> {
60  
61      private final LocaleContext localeContext;
62      private final Context context;
63  
64      @Inject
65      public LocaleSelectFieldSupport(LocaleContext localeContext, Context context) {
66          this.localeContext = localeContext;
67          this.context = context;
68      }
69  
70      @Override
71      public LocaleListProvider getDataProvider() {
72          return new LocaleListProvider(localeContext);
73      }
74  
75      @Override
76      public ItemCaptionGenerator<Locale> getItemCaptionGenerator() {
77          return locale -> {
78              String label = locale.getDisplayLanguage(context.getLocale());
79              String displayCountry = locale.getDisplayCountry(context.getLocale());
80  
81              return displayCountry.isEmpty() ? label : label + " (" + displayCountry + ")";
82          };
83      }
84  
85      @Override
86      public IconGenerator<Locale> getIconGenerator() {
87          return locale -> MagnoliaIcons.LANGUAGE_APP;
88      }
89  
90      @Override
91      public Converter<Locale, String> defaultConverter() {
92          return new Converter<Locale, String>() {
93              @Override
94              public Result<String> convertToModel(Locale value, ValueContext context) {
95                  return Result.ok(
96                          Optional.ofNullable(value)
97                                  .map(Locale::toLanguageTag)
98                                  .orElse(null));
99              }
100 
101             @Override
102             public Locale convertToPresentation(String value, ValueContext context) {
103                 return Optional.ofNullable(value)
104                         .map(Locale::forLanguageTag)
105                         .orElse(null);
106             }
107         };
108     }
109 
110     private static class LocaleListProvider extends AbstractDataProvider<Locale, String> {
111 
112         private final LocaleContext localeContext;
113 
114         public LocaleListProvider(LocaleContext localeContext) {
115             this.localeContext = localeContext;
116 
117             localeContext.availableLocales().observe(locales -> this.refreshAll());
118         }
119 
120         @Override
121         public boolean isInMemory() {
122             return true;
123         }
124 
125         @Override
126         public int size(Query<Locale, String> query) {
127             return (int) fetch(query).count();
128         }
129 
130         @Override
131         public Stream<Locale> fetch(Query<Locale, String> query) {
132             return localeContext.getAvailableLocales().skip(query.getOffset()).limit(query.getLimit());
133         }
134     }
135 
136 }