001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *
010     *        http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License.
018     */
019    package org.apache.isis.viewer.restfulobjects.applib.util;
020    
021    import java.text.ParseException;
022    import java.text.SimpleDateFormat;
023    import java.util.Arrays;
024    import java.util.Collections;
025    import java.util.Date;
026    import java.util.List;
027    
028    import javax.ws.rs.core.CacheControl;
029    import javax.ws.rs.core.MediaType;
030    
031    import com.google.common.base.Function;
032    import com.google.common.base.Joiner;
033    import com.google.common.base.Splitter;
034    import com.google.common.collect.Iterables;
035    import com.google.common.collect.Lists;
036    
037    import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
038    
039    public abstract class Parser<T> {
040        public T valueOf(final List<String> str) {
041            if (str == null) {
042                return null;
043            }
044            if (str.size() == 0) {
045                return null;
046            }
047            return valueOf(str.get(0));
048        }
049    
050        public T valueOf(final String[] str) {
051            if (str == null) {
052                return null;
053            }
054            if (str.length == 0) {
055                return null;
056            }
057            return valueOf(str[0]);
058        }
059    
060        public T valueOf(final JsonRepresentation jsonRepresentation) {
061            if (jsonRepresentation == null) {
062                return null;
063            }
064            return valueOf(jsonRepresentation.asString());
065        }
066    
067        public JsonRepresentation asJsonRepresentation(final T t) {
068            return JsonRepresentation.newMap("dummy", asString(t)).getRepresentation("dummy");
069        }
070    
071        public abstract T valueOf(String str);
072    
073        public abstract String asString(T t);
074    
075        public final static Parser<String> forString() {
076            return new Parser<String>() {
077                @Override
078                public String valueOf(final String str) {
079                    return str;
080                }
081    
082                @Override
083                public String asString(final String t) {
084                    return t;
085                }
086            };
087        }
088    
089        public static Parser<Date> forDate() {
090    
091            return new Parser<Date>() {
092                private final SimpleDateFormat RFC1123_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z");
093    
094                @Override
095                public Date valueOf(final String str) {
096                    if (str == null) {
097                        return null;
098                    }
099                    try {
100                        return RFC1123_DATE_FORMAT.parse(str);
101                    } catch (final ParseException e) {
102                        return null;
103                    }
104                }
105    
106                @Override
107                public String asString(final Date t) {
108                    return RFC1123_DATE_FORMAT.format(t);
109                }
110            };
111        }
112    
113        public static Parser<CacheControl> forCacheControl() {
114            return new Parser<CacheControl>() {
115                @Override
116                public CacheControl valueOf(final String str) {
117                    if (str == null) {
118                        return null;
119                    }
120                    final CacheControl cacheControl = CacheControl.valueOf(str);
121                    // workaround for bug in CacheControl's equals() method
122                    cacheControl.getCacheExtension();
123                    cacheControl.getNoCacheFields();
124                    return cacheControl;
125                }
126    
127                @Override
128                public String asString(final CacheControl cacheControl) {
129                    return cacheControl.toString();
130                }
131            };
132        }
133    
134        public static Parser<MediaType> forMediaType() {
135            return new Parser<MediaType>() {
136                @Override
137                public MediaType valueOf(final String str) {
138                    if (str == null) {
139                        return null;
140                    }
141                    return MediaType.valueOf(str);
142                }
143    
144                @Override
145                public String asString(final MediaType t) {
146                    return t.toString();
147                }
148    
149            };
150        }
151    
152        public static Parser<Boolean> forBoolean() {
153            return new Parser<Boolean>() {
154                @Override
155                public Boolean valueOf(final String str) {
156                    if (str == null) {
157                        return null;
158                    }
159                    return str.equals("yes") ? Boolean.TRUE : Boolean.FALSE;
160                }
161    
162                @Override
163                public String asString(final Boolean t) {
164                    return t ? "yes" : "no";
165                }
166    
167            };
168        }
169    
170        public static Parser<Integer> forInteger() {
171            return new Parser<Integer>() {
172    
173                @Override
174                public Integer valueOf(final String str) {
175                    if (str == null) {
176                        return null;
177                    }
178                    return Integer.valueOf(str);
179                }
180    
181                @Override
182                public String asString(final Integer t) {
183                    return t.toString();
184                }
185            };
186        }
187    
188        public static Parser<List<String>> forListOfStrings() {
189            return new Parser<List<String>>() {
190    
191                @Override
192                public List<String> valueOf(final List<String> strings) {
193                    if (strings == null) {
194                        return Collections.emptyList();
195                    }
196                    if (strings.size() == 1) {
197                        // special case processing to handle comma-separated values
198                        return valueOf(strings.get(0));
199                    }
200                    return strings;
201                }
202    
203                @Override
204                public List<String> valueOf(final String[] strings) {
205                    if (strings == null) {
206                        return Collections.emptyList();
207                    }
208                    if (strings.length == 1) {
209                        // special case processing to handle comma-separated values
210                        return valueOf(strings[0]);
211                    }
212                    return Arrays.asList(strings);
213                }
214    
215                @Override
216                public List<String> valueOf(final String str) {
217                    if (str == null) {
218                        return Collections.emptyList();
219                    }
220                    return Lists.newArrayList(Splitter.on(",").split(str));
221                }
222    
223                @Override
224                public String asString(final List<String> strings) {
225                    return Joiner.on(",").join(strings);
226                }
227            };
228        }
229    
230        public static Parser<List<List<String>>> forListOfListOfStrings() {
231            return new Parser<List<List<String>>>() {
232    
233                @Override
234                public List<List<String>> valueOf(final List<String> str) {
235                    if (str == null) {
236                        return null;
237                    }
238                    if (str.size() == 0) {
239                        return null;
240                    }
241                    final List<List<String>> listOfLists = Lists.newArrayList();
242                    for (final String s : str) {
243                        final Iterable<String> split = Splitter.on('.').split(s);
244                        listOfLists.add(Lists.newArrayList(split));
245                    }
246                    return listOfLists;
247                }
248    
249                @Override
250                public List<List<String>> valueOf(final String[] str) {
251                    if (str == null) {
252                        return null;
253                    }
254                    if (str.length == 0) {
255                        return null;
256                    }
257                    return valueOf(Arrays.asList(str));
258                }
259    
260                @Override
261                public List<List<String>> valueOf(final String str) {
262                    if (str == null || str.isEmpty()) {
263                        return Collections.emptyList();
264                    }
265                    final Iterable<String> listOfStrings = Splitter.on(',').split(str);
266                    return Lists.transform(Lists.newArrayList(listOfStrings), new Function<String, List<String>>() {
267    
268                        @Override
269                        public List<String> apply(final String input) {
270                            return Lists.newArrayList(Splitter.on('.').split(input));
271                        }
272                    });
273                }
274    
275                @Override
276                public String asString(final List<List<String>> listOfLists) {
277                    final List<String> listOfStrings = Lists.transform(listOfLists, new Function<List<String>, String>() {
278                        @Override
279                        public String apply(final List<String> listOfStrings) {
280                            return Joiner.on('.').join(listOfStrings);
281                        }
282                    });
283                    return Joiner.on(',').join(listOfStrings);
284                }
285            };
286        }
287    
288        public static Parser<String[]> forArrayOfStrings() {
289            return new Parser<String[]>() {
290    
291                @Override
292                public String[] valueOf(final List<String> strings) {
293                    if (strings == null) {
294                        return new String[] {};
295                    }
296                    if (strings.size() == 1) {
297                        // special case processing to handle comma-separated values
298                        return valueOf(strings.get(0));
299                    }
300                    return strings.toArray(new String[] {});
301                }
302    
303                @Override
304                public String[] valueOf(final String[] strings) {
305                    if (strings == null) {
306                        return new String[] {};
307                    }
308                    if (strings.length == 1) {
309                        // special case processing to handle comma-separated values
310                        return valueOf(strings[0]);
311                    }
312                    return strings;
313                }
314    
315                @Override
316                public String[] valueOf(final String str) {
317                    if (str == null) {
318                        return new String[] {};
319                    }
320                    final Iterable<String> split = Splitter.on(",").split(str);
321                    return Iterables.toArray(split, String.class);
322                }
323    
324                @Override
325                public String asString(final String[] strings) {
326                    return Joiner.on(",").join(strings);
327                }
328            };
329        }
330    
331        public static Parser<List<MediaType>> forListOfMediaTypes() {
332            return new Parser<List<MediaType>>() {
333    
334                @Override
335                public List<MediaType> valueOf(final String str) {
336                    if (str == null) {
337                        return Collections.emptyList();
338                    }
339                    final List<String> strings = Lists.newArrayList(Splitter.on(",").split(str));
340                    return Lists.transform(strings, new Function<String, MediaType>() {
341    
342                        @Override
343                        public MediaType apply(final String input) {
344                            return MediaType.valueOf(input);
345                        }
346                    });
347                }
348    
349                @Override
350                public String asString(final List<MediaType> listOfMediaTypes) {
351                    final List<String> strings = Lists.transform(listOfMediaTypes, new Function<MediaType, String>() {
352                        @Override
353                        public String apply(final MediaType input) {
354                            return input.toString();
355                        }
356                    });
357                    return Joiner.on(",").join(strings);
358                }
359            };
360        }
361    
362    }