001/******************************************************************************* 002 * Copyright 2017 The MIT Internet Trust Consortium 003 * 004 * Portions copyright 2011-2013 The MITRE Corporation 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * 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, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 *******************************************************************************/ 018package org.mitre.openid.connect.model; 019 020import java.io.IOException; 021import java.io.ObjectInputStream; 022import java.io.ObjectOutputStream; 023 024import javax.persistence.Basic; 025import javax.persistence.CascadeType; 026import javax.persistence.Column; 027import javax.persistence.Convert; 028import javax.persistence.Entity; 029import javax.persistence.GeneratedValue; 030import javax.persistence.GenerationType; 031import javax.persistence.Id; 032import javax.persistence.JoinColumn; 033import javax.persistence.NamedQueries; 034import javax.persistence.NamedQuery; 035import javax.persistence.OneToOne; 036import javax.persistence.Table; 037 038import org.mitre.openid.connect.model.convert.JsonObjectStringConverter; 039 040import com.google.gson.JsonObject; 041import com.google.gson.JsonParser; 042 043@Entity 044@Table(name="user_info") 045@NamedQueries({ 046 @NamedQuery(name=DefaultUserInfo.QUERY_BY_USERNAME, query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :" + DefaultUserInfo.PARAM_USERNAME), 047 @NamedQuery(name=DefaultUserInfo.QUERY_BY_EMAIL, query = "select u from DefaultUserInfo u WHERE u.email = :" + DefaultUserInfo.PARAM_EMAIL) 048}) 049public class DefaultUserInfo implements UserInfo { 050 051 public static final String QUERY_BY_USERNAME = "DefaultUserInfo.getByUsername"; 052 public static final String QUERY_BY_EMAIL = "DefaultUserInfo.getByEmailAddress"; 053 054 public static final String PARAM_USERNAME = "username"; 055 public static final String PARAM_EMAIL = "email"; 056 057 private static final long serialVersionUID = 6078310513185681918L; 058 059 private Long id; 060 private String sub; 061 private String preferredUsername; 062 private String name; 063 private String givenName; 064 private String familyName; 065 private String middleName; 066 private String nickname; 067 private String profile; 068 private String picture; 069 private String website; 070 private String email; 071 private Boolean emailVerified; 072 private String gender; 073 private String zoneinfo; 074 private String locale; 075 private String phoneNumber; 076 private Boolean phoneNumberVerified; 077 private DefaultAddress address; 078 private String updatedTime; 079 private String birthdate; 080 private transient JsonObject src; // source JSON if this is loaded remotely 081 082 083 /** 084 * @return the id 085 */ 086 @Id 087 @GeneratedValue(strategy=GenerationType.IDENTITY) 088 @Column(name = "id") 089 public Long getId() { 090 return id; 091 } 092 /** 093 * @param id the id to set 094 */ 095 public void setId(Long id) { 096 this.id = id; 097 } 098 /* (non-Javadoc) 099 * @see org.mitre.openid.connect.model.UserInfo#getUserId() 100 */ 101 @Override 102 @Basic 103 @Column(name="sub") 104 public String getSub() { 105 return sub; 106 } 107 /* (non-Javadoc) 108 * @see org.mitre.openid.connect.model.UserInfo#setUserId(java.lang.String) 109 */ 110 @Override 111 public void setSub(String sub) { 112 this.sub = sub; 113 } 114 /* (non-Javadoc) 115 * @see org.mitre.openid.connect.model.UserInfo#getPreferredUsername 116 */ 117 @Override 118 @Basic 119 @Column(name="preferred_username") 120 public String getPreferredUsername() { 121 return this.preferredUsername; 122 } 123 /* (non-Javadoc) 124 * @see org.mitre.openid.connect.model.UserInfo#setPreferredUsername(java.lang.String) 125 */ 126 @Override 127 public void setPreferredUsername(String preferredUsername) { 128 this.preferredUsername = preferredUsername; 129 } 130 /* (non-Javadoc) 131 * @see org.mitre.openid.connect.model.UserInfo#getName() 132 */ 133 @Override 134 @Basic 135 @Column(name = "name") 136 public String getName() { 137 return name; 138 } 139 /* (non-Javadoc) 140 * @see org.mitre.openid.connect.model.UserInfo#setName(java.lang.String) 141 */ 142 @Override 143 public void setName(String name) { 144 this.name = name; 145 } 146 /* (non-Javadoc) 147 * @see org.mitre.openid.connect.model.UserInfo#getGivenName() 148 */ 149 @Override 150 @Basic 151 @Column(name="given_name") 152 public String getGivenName() { 153 return givenName; 154 } 155 /* (non-Javadoc) 156 * @see org.mitre.openid.connect.model.UserInfo#setGivenName(java.lang.String) 157 */ 158 @Override 159 public void setGivenName(String givenName) { 160 this.givenName = givenName; 161 } 162 /* (non-Javadoc) 163 * @see org.mitre.openid.connect.model.UserInfo#getFamilyName() 164 */ 165 @Override 166 @Basic 167 @Column(name="family_name") 168 public String getFamilyName() { 169 return familyName; 170 } 171 /* (non-Javadoc) 172 * @see org.mitre.openid.connect.model.UserInfo#setFamilyName(java.lang.String) 173 */ 174 @Override 175 public void setFamilyName(String familyName) { 176 this.familyName = familyName; 177 } 178 /* (non-Javadoc) 179 * @see org.mitre.openid.connect.model.UserInfo#getMiddleName() 180 */ 181 @Override 182 @Basic 183 @Column(name="middle_name") 184 public String getMiddleName() { 185 return middleName; 186 } 187 /* (non-Javadoc) 188 * @see org.mitre.openid.connect.model.UserInfo#setMiddleName(java.lang.String) 189 */ 190 @Override 191 public void setMiddleName(String middleName) { 192 this.middleName = middleName; 193 } 194 /* (non-Javadoc) 195 * @see org.mitre.openid.connect.model.UserInfo#getNickname() 196 */ 197 @Override 198 @Basic 199 @Column(name = "nickname") 200 public String getNickname() { 201 return nickname; 202 } 203 /* (non-Javadoc) 204 * @see org.mitre.openid.connect.model.UserInfo#setNickname(java.lang.String) 205 */ 206 @Override 207 public void setNickname(String nickname) { 208 this.nickname = nickname; 209 } 210 /* (non-Javadoc) 211 * @see org.mitre.openid.connect.model.UserInfo#getProfile() 212 */ 213 @Override 214 @Basic 215 @Column(name = "profile") 216 public String getProfile() { 217 return profile; 218 } 219 /* (non-Javadoc) 220 * @see org.mitre.openid.connect.model.UserInfo#setProfile(java.lang.String) 221 */ 222 @Override 223 public void setProfile(String profile) { 224 this.profile = profile; 225 } 226 /* (non-Javadoc) 227 * @see org.mitre.openid.connect.model.UserInfo#getPicture() 228 */ 229 @Override 230 @Basic 231 @Column(name = "picture") 232 public String getPicture() { 233 return picture; 234 } 235 /* (non-Javadoc) 236 * @see org.mitre.openid.connect.model.UserInfo#setPicture(java.lang.String) 237 */ 238 @Override 239 public void setPicture(String picture) { 240 this.picture = picture; 241 } 242 /* (non-Javadoc) 243 * @see org.mitre.openid.connect.model.UserInfo#getWebsite() 244 */ 245 @Override 246 @Basic 247 @Column(name = "website") 248 public String getWebsite() { 249 return website; 250 } 251 /* (non-Javadoc) 252 * @see org.mitre.openid.connect.model.UserInfo#setWebsite(java.lang.String) 253 */ 254 @Override 255 public void setWebsite(String website) { 256 this.website = website; 257 } 258 /* (non-Javadoc) 259 * @see org.mitre.openid.connect.model.UserInfo#getEmail() 260 */ 261 @Override 262 @Basic 263 @Column(name = "email") 264 public String getEmail() { 265 return email; 266 } 267 /* (non-Javadoc) 268 * @see org.mitre.openid.connect.model.UserInfo#setEmail(java.lang.String) 269 */ 270 @Override 271 public void setEmail(String email) { 272 this.email = email; 273 } 274 /* (non-Javadoc) 275 * @see org.mitre.openid.connect.model.UserInfo#getVerified() 276 */ 277 @Override 278 @Basic 279 @Column(name="email_verified") 280 public Boolean getEmailVerified() { 281 return emailVerified; 282 } 283 /* (non-Javadoc) 284 * @see org.mitre.openid.connect.model.UserInfo#setVerified(java.lang.boolean) 285 */ 286 @Override 287 public void setEmailVerified(Boolean emailVerified) { 288 this.emailVerified = emailVerified; 289 } 290 /* (non-Javadoc) 291 * @see org.mitre.openid.connect.model.UserInfo#getGender() 292 */ 293 @Override 294 @Basic 295 @Column(name = "gender") 296 public String getGender() { 297 return gender; 298 } 299 /* (non-Javadoc) 300 * @see org.mitre.openid.connect.model.UserInfo#setGender(java.lang.String) 301 */ 302 @Override 303 public void setGender(String gender) { 304 this.gender = gender; 305 } 306 /* (non-Javadoc) 307 * @see org.mitre.openid.connect.model.UserInfo#getZoneinfo() 308 */ 309 @Override 310 @Basic 311 @Column(name="zone_info") 312 public String getZoneinfo() { 313 return zoneinfo; 314 } 315 /* (non-Javadoc) 316 * @see org.mitre.openid.connect.model.UserInfo#setZoneinfo(java.lang.String) 317 */ 318 @Override 319 public void setZoneinfo(String zoneinfo) { 320 this.zoneinfo = zoneinfo; 321 } 322 /* (non-Javadoc) 323 * @see org.mitre.openid.connect.model.UserInfo#getLocale() 324 */ 325 @Override 326 @Basic 327 @Column(name = "locale") 328 public String getLocale() { 329 return locale; 330 } 331 /* (non-Javadoc) 332 * @see org.mitre.openid.connect.model.UserInfo#setLocale(java.lang.String) 333 */ 334 @Override 335 public void setLocale(String locale) { 336 this.locale = locale; 337 } 338 /* (non-Javadoc) 339 * @see org.mitre.openid.connect.model.UserInfo#getPhoneNumber() 340 */ 341 @Override 342 @Basic 343 @Column(name="phone_number") 344 public String getPhoneNumber() { 345 return phoneNumber; 346 } 347 /* (non-Javadoc) 348 * @see org.mitre.openid.connect.model.UserInfo#setPhoneNumber(java.lang.String) 349 */ 350 @Override 351 public void setPhoneNumber(String phoneNumber) { 352 this.phoneNumber = phoneNumber; 353 } 354 /* (non-Javadoc) 355 * @see org.mitre.openid.connect.model.UserInfo#getPhoneNumberVerified() 356 */ 357 @Override 358 @Basic 359 @Column(name="phone_number_verified") 360 public Boolean getPhoneNumberVerified() { 361 return phoneNumberVerified; 362 } 363 /* (non-Javadoc) 364 * @see org.mitre.openid.connect.model.UserInfo#setPhoneNumberVerified(java.lang.Boolean) 365 */ 366 @Override 367 public void setPhoneNumberVerified(Boolean phoneNumberVerified) { 368 this.phoneNumberVerified = phoneNumberVerified; 369 } 370 /* (non-Javadoc) 371 * @see org.mitre.openid.connect.model.UserInfo#getAddress() 372 */ 373 @Override 374 @OneToOne(targetEntity = DefaultAddress.class, cascade = CascadeType.ALL) 375 @JoinColumn(name="address_id") 376 public Address getAddress() { 377 return address; 378 } 379 /* (non-Javadoc) 380 * @see org.mitre.openid.connect.model.UserInfo#setAddress(org.mitre.openid.connect.model.Address) 381 */ 382 @Override 383 public void setAddress(Address address) { 384 if (address != null) { 385 this.address = new DefaultAddress(address); 386 } else { 387 this.address = null; 388 } 389 } 390 /* (non-Javadoc) 391 * @see org.mitre.openid.connect.model.UserInfo#getUpdatedTime() 392 */ 393 @Override 394 @Basic 395 @Column(name="updated_time") 396 public String getUpdatedTime() { 397 return updatedTime; 398 } 399 /* (non-Javadoc) 400 * @see org.mitre.openid.connect.model.UserInfo#setUpdatedTime(java.lang.String) 401 */ 402 @Override 403 public void setUpdatedTime(String updatedTime) { 404 this.updatedTime = updatedTime; 405 } 406 407 /** 408 * @return the birthdate 409 */ 410 @Override 411 @Basic 412 @Column(name="birthdate") 413 public String getBirthdate() { 414 return birthdate; 415 } 416 /** 417 * @param birthdate the birthdate to set 418 */ 419 @Override 420 public void setBirthdate(String birthdate) { 421 this.birthdate = birthdate; 422 } 423 424 @Override 425 public JsonObject toJson() { 426 if (src == null) { 427 428 JsonObject obj = new JsonObject(); 429 430 obj.addProperty("sub", this.getSub()); 431 432 obj.addProperty("name", this.getName()); 433 obj.addProperty("preferred_username", this.getPreferredUsername()); 434 obj.addProperty("given_name", this.getGivenName()); 435 obj.addProperty("family_name", this.getFamilyName()); 436 obj.addProperty("middle_name", this.getMiddleName()); 437 obj.addProperty("nickname", this.getNickname()); 438 obj.addProperty("profile", this.getProfile()); 439 obj.addProperty("picture", this.getPicture()); 440 obj.addProperty("website", this.getWebsite()); 441 obj.addProperty("gender", this.getGender()); 442 obj.addProperty("zoneinfo", this.getZoneinfo()); 443 obj.addProperty("locale", this.getLocale()); 444 obj.addProperty("updated_at", this.getUpdatedTime()); 445 obj.addProperty("birthdate", this.getBirthdate()); 446 447 obj.addProperty("email", this.getEmail()); 448 obj.addProperty("email_verified", this.getEmailVerified()); 449 450 obj.addProperty("phone_number", this.getPhoneNumber()); 451 obj.addProperty("phone_number_verified", this.getPhoneNumberVerified()); 452 453 if (this.getAddress() != null) { 454 455 JsonObject addr = new JsonObject(); 456 addr.addProperty("formatted", this.getAddress().getFormatted()); 457 addr.addProperty("street_address", this.getAddress().getStreetAddress()); 458 addr.addProperty("locality", this.getAddress().getLocality()); 459 addr.addProperty("region", this.getAddress().getRegion()); 460 addr.addProperty("postal_code", this.getAddress().getPostalCode()); 461 addr.addProperty("country", this.getAddress().getCountry()); 462 463 obj.add("address", addr); 464 } 465 466 return obj; 467 } else { 468 return src; 469 } 470 471 } 472 473 /** 474 * Parse a JsonObject into a UserInfo. 475 * @param o 476 * @return 477 */ 478 public static UserInfo fromJson(JsonObject obj) { 479 DefaultUserInfo ui = new DefaultUserInfo(); 480 ui.setSource(obj); 481 482 ui.setSub(nullSafeGetString(obj, "sub")); 483 484 ui.setName(nullSafeGetString(obj, "name")); 485 ui.setPreferredUsername(nullSafeGetString(obj, "preferred_username")); 486 ui.setGivenName(nullSafeGetString(obj, "given_name")); 487 ui.setFamilyName(nullSafeGetString(obj, "family_name")); 488 ui.setMiddleName(nullSafeGetString(obj, "middle_name")); 489 ui.setNickname(nullSafeGetString(obj, "nickname")); 490 ui.setProfile(nullSafeGetString(obj, "profile")); 491 ui.setPicture(nullSafeGetString(obj, "picture")); 492 ui.setWebsite(nullSafeGetString(obj, "website")); 493 ui.setGender(nullSafeGetString(obj, "gender")); 494 ui.setZoneinfo(nullSafeGetString(obj, "zoneinfo")); 495 ui.setLocale(nullSafeGetString(obj, "locale")); 496 ui.setUpdatedTime(nullSafeGetString(obj, "updated_at")); 497 ui.setBirthdate(nullSafeGetString(obj, "birthdate")); 498 499 ui.setEmail(nullSafeGetString(obj, "email")); 500 ui.setEmailVerified(obj.has("email_verified") && obj.get("email_verified").isJsonPrimitive() ? obj.get("email_verified").getAsBoolean() : null); 501 502 ui.setPhoneNumber(nullSafeGetString(obj, "phone_number")); 503 ui.setPhoneNumberVerified(obj.has("phone_number_verified") && obj.get("phone_number_verified").isJsonPrimitive() ? obj.get("phone_number_verified").getAsBoolean() : null); 504 505 if (obj.has("address") && obj.get("address").isJsonObject()) { 506 JsonObject addr = obj.get("address").getAsJsonObject(); 507 ui.setAddress(new DefaultAddress()); 508 509 ui.getAddress().setFormatted(nullSafeGetString(addr, "formatted")); 510 ui.getAddress().setStreetAddress(nullSafeGetString(addr, "street_address")); 511 ui.getAddress().setLocality(nullSafeGetString(addr, "locality")); 512 ui.getAddress().setRegion(nullSafeGetString(addr, "region")); 513 ui.getAddress().setPostalCode(nullSafeGetString(addr, "postal_code")); 514 ui.getAddress().setCountry(nullSafeGetString(addr, "country")); 515 516 } 517 518 519 return ui; 520 521 } 522 /** 523 * @return the jsonString 524 */ 525 @Override 526 @Basic 527 @Column(name = "src") 528 @Convert(converter = JsonObjectStringConverter.class) 529 public JsonObject getSource() { 530 return src; 531 } 532 533 /** 534 * @param jsonString the jsonString to set 535 */ 536 public void setSource(JsonObject src) { 537 this.src = src; 538 } 539 540 541 private static String nullSafeGetString(JsonObject obj, String field) { 542 return obj.has(field) && obj.get(field).isJsonPrimitive() ? obj.get(field).getAsString() : null; 543 } 544 545 /* (non-Javadoc) 546 * @see java.lang.Object#hashCode() 547 */ 548 @Override 549 public int hashCode() { 550 final int prime = 31; 551 int result = 1; 552 result = prime * result + ((address == null) ? 0 : address.hashCode()); 553 result = prime * result + ((birthdate == null) ? 0 : birthdate.hashCode()); 554 result = prime * result + ((email == null) ? 0 : email.hashCode()); 555 result = prime * result + ((emailVerified == null) ? 0 : emailVerified.hashCode()); 556 result = prime * result + ((familyName == null) ? 0 : familyName.hashCode()); 557 result = prime * result + ((gender == null) ? 0 : gender.hashCode()); 558 result = prime * result + ((givenName == null) ? 0 : givenName.hashCode()); 559 result = prime * result + ((id == null) ? 0 : id.hashCode()); 560 result = prime * result + ((locale == null) ? 0 : locale.hashCode()); 561 result = prime * result + ((middleName == null) ? 0 : middleName.hashCode()); 562 result = prime * result + ((name == null) ? 0 : name.hashCode()); 563 result = prime * result + ((nickname == null) ? 0 : nickname.hashCode()); 564 result = prime * result + ((phoneNumber == null) ? 0 : phoneNumber.hashCode()); 565 result = prime * result + ((phoneNumberVerified == null) ? 0 : phoneNumberVerified.hashCode()); 566 result = prime * result + ((picture == null) ? 0 : picture.hashCode()); 567 result = prime * result + ((preferredUsername == null) ? 0 : preferredUsername.hashCode()); 568 result = prime * result + ((profile == null) ? 0 : profile.hashCode()); 569 result = prime * result + ((sub == null) ? 0 : sub.hashCode()); 570 result = prime * result + ((updatedTime == null) ? 0 : updatedTime.hashCode()); 571 result = prime * result + ((website == null) ? 0 : website.hashCode()); 572 result = prime * result + ((zoneinfo == null) ? 0 : zoneinfo.hashCode()); 573 return result; 574 } 575 576 /* (non-Javadoc) 577 * @see java.lang.Object#equals(java.lang.Object) 578 */ 579 @Override 580 public boolean equals(Object obj) { 581 if (this == obj) { 582 return true; 583 } 584 if (obj == null) { 585 return false; 586 } 587 if (!(obj instanceof DefaultUserInfo)) { 588 return false; 589 } 590 DefaultUserInfo other = (DefaultUserInfo) obj; 591 if (address == null) { 592 if (other.address != null) { 593 return false; 594 } 595 } else if (!address.equals(other.address)) { 596 return false; 597 } 598 if (birthdate == null) { 599 if (other.birthdate != null) { 600 return false; 601 } 602 } else if (!birthdate.equals(other.birthdate)) { 603 return false; 604 } 605 if (email == null) { 606 if (other.email != null) { 607 return false; 608 } 609 } else if (!email.equals(other.email)) { 610 return false; 611 } 612 if (emailVerified == null) { 613 if (other.emailVerified != null) { 614 return false; 615 } 616 } else if (!emailVerified.equals(other.emailVerified)) { 617 return false; 618 } 619 if (familyName == null) { 620 if (other.familyName != null) { 621 return false; 622 } 623 } else if (!familyName.equals(other.familyName)) { 624 return false; 625 } 626 if (gender == null) { 627 if (other.gender != null) { 628 return false; 629 } 630 } else if (!gender.equals(other.gender)) { 631 return false; 632 } 633 if (givenName == null) { 634 if (other.givenName != null) { 635 return false; 636 } 637 } else if (!givenName.equals(other.givenName)) { 638 return false; 639 } 640 if (id == null) { 641 if (other.id != null) { 642 return false; 643 } 644 } else if (!id.equals(other.id)) { 645 return false; 646 } 647 if (locale == null) { 648 if (other.locale != null) { 649 return false; 650 } 651 } else if (!locale.equals(other.locale)) { 652 return false; 653 } 654 if (middleName == null) { 655 if (other.middleName != null) { 656 return false; 657 } 658 } else if (!middleName.equals(other.middleName)) { 659 return false; 660 } 661 if (name == null) { 662 if (other.name != null) { 663 return false; 664 } 665 } else if (!name.equals(other.name)) { 666 return false; 667 } 668 if (nickname == null) { 669 if (other.nickname != null) { 670 return false; 671 } 672 } else if (!nickname.equals(other.nickname)) { 673 return false; 674 } 675 if (phoneNumber == null) { 676 if (other.phoneNumber != null) { 677 return false; 678 } 679 } else if (!phoneNumber.equals(other.phoneNumber)) { 680 return false; 681 } 682 if (phoneNumberVerified == null) { 683 if (other.phoneNumberVerified != null) { 684 return false; 685 } 686 } else if (!phoneNumberVerified.equals(other.phoneNumberVerified)) { 687 return false; 688 } 689 if (picture == null) { 690 if (other.picture != null) { 691 return false; 692 } 693 } else if (!picture.equals(other.picture)) { 694 return false; 695 } 696 if (preferredUsername == null) { 697 if (other.preferredUsername != null) { 698 return false; 699 } 700 } else if (!preferredUsername.equals(other.preferredUsername)) { 701 return false; 702 } 703 if (profile == null) { 704 if (other.profile != null) { 705 return false; 706 } 707 } else if (!profile.equals(other.profile)) { 708 return false; 709 } 710 if (sub == null) { 711 if (other.sub != null) { 712 return false; 713 } 714 } else if (!sub.equals(other.sub)) { 715 return false; 716 } 717 if (updatedTime == null) { 718 if (other.updatedTime != null) { 719 return false; 720 } 721 } else if (!updatedTime.equals(other.updatedTime)) { 722 return false; 723 } 724 if (website == null) { 725 if (other.website != null) { 726 return false; 727 } 728 } else if (!website.equals(other.website)) { 729 return false; 730 } 731 if (zoneinfo == null) { 732 if (other.zoneinfo != null) { 733 return false; 734 } 735 } else if (!zoneinfo.equals(other.zoneinfo)) { 736 return false; 737 } 738 return true; 739 } 740 741 742 /* 743 * Custom serialization to handle the JSON object 744 */ 745 private void writeObject(ObjectOutputStream out) throws IOException { 746 out.defaultWriteObject(); 747 if (src == null) { 748 out.writeObject(null); 749 } else { 750 out.writeObject(src.toString()); 751 } 752 } 753 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 754 in.defaultReadObject(); 755 Object o = in.readObject(); 756 if (o != null) { 757 JsonParser parser = new JsonParser(); 758 src = parser.parse((String)o).getAsJsonObject(); 759 } 760 } 761 762}