source: vlo/trunk/vlo-web-app/src/main/java/eu/clarin/cmdi/vlo/wicket/CachingConverter.java @ 6006

Last change on this file since 6006 was 6006, checked in by Twan Goosen, 9 years ago

implemented a caching converter, using it when sorting the field values

File size: 4.1 KB
Line 
1/*
2 * Copyright (C) 2015 CLARIN
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17package eu.clarin.cmdi.vlo.wicket;
18
19import com.google.common.cache.CacheBuilder;
20import com.google.common.cache.CacheLoader;
21import com.google.common.cache.LoadingCache;
22import java.util.Locale;
23import java.util.Objects;
24import java.util.concurrent.ExecutionException;
25import org.apache.wicket.util.convert.ConversionException;
26import org.apache.wicket.util.convert.IConverter;
27
28/**
29 * Converter that wraps an arbitrary converter and caches the conversion output
30 * so that each conversion in a certain direction given a set of a value and
31 * locale or string representation and locale happens only once.
32 *
33 * @author Twan Goosen <twan.goosen@mpi.nl>
34 * @param <C> The object to convert from and to String
35 * @see Cache
36 */
37public class CachingConverter<C> implements IConverter<C> {
38
39    private final IConverter<C> inner;
40
41    private final LoadingCache<Key<String, Locale>, C> toObjectCache = CacheBuilder.newBuilder().
42            build(
43                    new CacheLoader<Key<String, Locale>, C>() {
44
45                        @Override
46                        public C load(Key<String, Locale> key) throws Exception {
47                            return inner.convertToObject(key.getKey1(), key.getKey2());
48                        }
49                    }
50            );
51
52    private final LoadingCache<Key<C, Locale>, String> toStringCache = CacheBuilder.newBuilder().
53            build(
54                    new CacheLoader<Key<C, Locale>, String>() {
55
56                        @Override
57                        public String load(Key<C, Locale> key) throws Exception {
58                            return inner.convertToString(key.getKey1(), key.getKey2());
59                        }
60                    }
61            );
62
63    /**
64     *
65     * @param converter converter to cache conversion results for
66     */
67    public CachingConverter(IConverter<C> converter) {
68        this.inner = converter;
69    }
70
71    @Override
72    public C convertToObject(String value, Locale locale) throws ConversionException {
73        try {
74            return toObjectCache.get(new Key<>(value, locale));
75        } catch (ExecutionException ex) {
76            throw new ConversionException(ex);
77        }
78    }
79
80    @Override
81    public String convertToString(C value, Locale locale) {
82        try {
83            return toStringCache.get(new Key<>(value, locale));
84        } catch (ExecutionException ex) {
85            throw new ConversionException(ex);
86        }
87    }
88
89    private static class Key<K1, K2> {
90
91        private final K1 key1;
92        private final K2 key2;
93
94        public Key(K1 key1, K2 key2) {
95            this.key1 = key1;
96            this.key2 = key2;
97        }
98
99        public K1 getKey1() {
100            return key1;
101        }
102
103        public K2 getKey2() {
104            return key2;
105        }
106
107        @Override
108        public int hashCode() {
109            int hash = 7;
110            hash = 41 * hash + Objects.hashCode(this.key1);
111            hash = 41 * hash + Objects.hashCode(this.key2);
112            return hash;
113        }
114
115        @Override
116        public boolean equals(Object obj) {
117            if (obj == null) {
118                return false;
119            }
120            if (getClass() != obj.getClass()) {
121                return false;
122            }
123            final Key<?, ?> other = (Key<?, ?>) obj;
124            if (!Objects.equals(this.key1, other.key1)) {
125                return false;
126            }
127            if (!Objects.equals(this.key2, other.key2)) {
128                return false;
129            }
130            return true;
131        }
132
133    }
134
135}
Note: See TracBrowser for help on using the repository browser.