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 */
019package org.apache.isis.viewer.restfulobjects.applib.util;
020
021import java.text.ParseException;
022import java.text.SimpleDateFormat;
023import java.util.Arrays;
024import java.util.Collections;
025import java.util.Date;
026import java.util.List;
027
028import javax.ws.rs.core.CacheControl;
029import javax.ws.rs.core.MediaType;
030
031import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
032
033import com.google.common.base.Function;
034import com.google.common.base.Joiner;
035import com.google.common.base.Splitter;
036import com.google.common.collect.Iterables;
037import com.google.common.collect.Lists;
038
039public 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> forJaxRsMediaType() {
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<com.google.common.net.MediaType> forGuavaMediaType() {
153        return new Parser<com.google.common.net.MediaType>() {
154            @Override
155            public com.google.common.net.MediaType valueOf(final String str) {
156                if (str == null) {
157                    return null;
158                }
159                return com.google.common.net.MediaType.parse(str);
160            }
161
162            @Override
163            public String asString(final com.google.common.net.MediaType t) {
164                return t.toString();
165            }
166        };
167    }
168
169    public static Parser<Boolean> forBoolean() {
170        return new Parser<Boolean>() {
171            @Override
172            public Boolean valueOf(final String str) {
173                if (str == null) {
174                    return null;
175                }
176                return str.equals("yes") ? Boolean.TRUE : Boolean.FALSE;
177            }
178
179            @Override
180            public String asString(final Boolean t) {
181                return t ? "yes" : "no";
182            }
183
184        };
185    }
186
187    public static Parser<Integer> forInteger() {
188        return new Parser<Integer>() {
189
190            @Override
191            public Integer valueOf(final String str) {
192                if (str == null) {
193                    return null;
194                }
195                return Integer.valueOf(str);
196            }
197
198            @Override
199            public String asString(final Integer t) {
200                return t.toString();
201            }
202        };
203    }
204
205    public static Parser<List<String>> forListOfStrings() {
206        return new Parser<List<String>>() {
207
208            @Override
209            public List<String> valueOf(final List<String> strings) {
210                if (strings == null) {
211                    return Collections.emptyList();
212                }
213                if (strings.size() == 1) {
214                    // special case processing to handle comma-separated values
215                    return valueOf(strings.get(0));
216                }
217                return strings;
218            }
219
220            @Override
221            public List<String> valueOf(final String[] strings) {
222                if (strings == null) {
223                    return Collections.emptyList();
224                }
225                if (strings.length == 1) {
226                    // special case processing to handle comma-separated values
227                    return valueOf(strings[0]);
228                }
229                return Arrays.asList(strings);
230            }
231
232            @Override
233            public List<String> valueOf(final String str) {
234                if (str == null) {
235                    return Collections.emptyList();
236                }
237                return Lists.newArrayList(Splitter.on(",").split(str));
238            }
239
240            @Override
241            public String asString(final List<String> strings) {
242                return Joiner.on(",").join(strings);
243            }
244        };
245    }
246
247    public static Parser<List<List<String>>> forListOfListOfStrings() {
248        return new Parser<List<List<String>>>() {
249
250            @Override
251            public List<List<String>> valueOf(final List<String> str) {
252                if (str == null) {
253                    return null;
254                }
255                if (str.size() == 0) {
256                    return null;
257                }
258                final List<List<String>> listOfLists = Lists.newArrayList();
259                for (final String s : str) {
260                    listOfLists.add(PathNode.split(s));
261                }
262                return listOfLists;
263            }
264
265            @Override
266            public List<List<String>> valueOf(final String[] str) {
267                if (str == null) {
268                    return null;
269                }
270                if (str.length == 0) {
271                    return null;
272                }
273                return valueOf(Arrays.asList(str));
274            }
275
276            @Override
277            public List<List<String>> valueOf(final String str) {
278                if (str == null || str.isEmpty()) {
279                    return Collections.emptyList();
280                }
281                final Iterable<String> listOfStrings = Splitter.on(',').split(str);
282                return Lists.transform(Lists.newArrayList(listOfStrings), new Function<String, List<String>>() {
283
284                    @Override
285                    public List<String> apply(final String input) {
286                        return PathNode.split(input);
287                    }
288                });
289            }
290
291            @Override
292            public String asString(final List<List<String>> listOfLists) {
293                final List<String> listOfStrings = Lists.transform(listOfLists, new Function<List<String>, String>() {
294                    @Override
295                    public String apply(final List<String> listOfStrings) {
296                        return Joiner.on('.').join(listOfStrings);
297                    }
298                });
299                return Joiner.on(',').join(listOfStrings);
300            }
301        };
302    }
303
304    public static Parser<String[]> forArrayOfStrings() {
305        return new Parser<String[]>() {
306
307            @Override
308            public String[] valueOf(final List<String> strings) {
309                if (strings == null) {
310                    return new String[] {};
311                }
312                if (strings.size() == 1) {
313                    // special case processing to handle comma-separated values
314                    return valueOf(strings.get(0));
315                }
316                return strings.toArray(new String[] {});
317            }
318
319            @Override
320            public String[] valueOf(final String[] strings) {
321                if (strings == null) {
322                    return new String[] {};
323                }
324                if (strings.length == 1) {
325                    // special case processing to handle comma-separated values
326                    return valueOf(strings[0]);
327                }
328                return strings;
329            }
330
331            @Override
332            public String[] valueOf(final String str) {
333                if (str == null) {
334                    return new String[] {};
335                }
336                final Iterable<String> split = Splitter.on(",").split(str);
337                return Iterables.toArray(split, String.class);
338            }
339
340            @Override
341            public String asString(final String[] strings) {
342                return Joiner.on(",").join(strings);
343            }
344        };
345    }
346
347    public static Parser<List<MediaType>> forListOfJaxRsMediaTypes() {
348        return new Parser<List<MediaType>>() {
349
350            @Override
351            public List<MediaType> valueOf(final String str) {
352                if (str == null) {
353                    return Collections.emptyList();
354                }
355                final List<String> strings = Lists.newArrayList(Splitter.on(",").split(str));
356                return Lists.transform(strings, new Function<String, MediaType>() {
357
358                    @Override
359                    public MediaType apply(final String input) {
360                        return MediaType.valueOf(input);
361                    }
362                });
363            }
364
365            @Override
366            public String asString(final List<MediaType> listOfMediaTypes) {
367                final List<String> strings = Lists.transform(listOfMediaTypes, new Function<MediaType, String>() {
368                    @Override
369                    public String apply(final MediaType input) {
370                        return input.toString();
371                    }
372                });
373                return Joiner.on(",").join(strings);
374            }
375        };
376    }
377
378    public static Parser<List<com.google.common.net.MediaType>> forListOfGuavaMediaTypes() {
379        return new Parser<List<com.google.common.net.MediaType>>() {
380
381            @Override
382            public List<com.google.common.net.MediaType> valueOf(final String str) {
383                if (str == null) {
384                    return Collections.emptyList();
385                }
386                final List<String> strings = Lists.newArrayList(Splitter.on(",").split(str));
387                return Lists.transform(strings, new Function<String, com.google.common.net.MediaType>() {
388
389                    @Override
390                    public com.google.common.net.MediaType apply(final String input) {
391                        return com.google.common.net.MediaType.parse(input);
392                    }
393                });
394            }
395
396            @Override
397            public String asString(final List<com.google.common.net.MediaType> listOfMediaTypes) {
398                final List<String> strings = Lists.transform(listOfMediaTypes, new Function<com.google.common.net.MediaType, String>() {
399                    @Override
400                    public String apply(final com.google.common.net.MediaType input) {
401                        return input.toString();
402                    }
403                });
404                return Joiner.on(",").join(strings);
405            }
406        };
407    }
408
409    public static Parser<String> forETag() {
410        return new Parser<String>(){
411
412            private final static String WEAK_PREFIX="W/";
413            
414            @Override
415            public String valueOf(String str) {
416                if(str == null) { 
417                    return null;
418                }
419                return null;
420            }
421
422            @Override
423            public String asString(String t) {
424                // TODO Auto-generated method stub
425                return null;
426            }};
427    }
428
429}