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}