001/*
002 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels.
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a copy
005 * of this software and associated documentation files (the "Software"), to deal
006 * in the Software without restriction, including without limitation the rights
007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008 * copies of the Software, and to permit persons to whom the Software is
009 * furnished to do so, subject to the following conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in
012 * all copies or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
020 * THE SOFTWARE.
021 */
022package com.restfb.types.webhook;
023
024import static com.restfb.logging.RestFBLogger.VALUE_FACTORY_LOGGER;
025
026import com.restfb.JsonMapper;
027import com.restfb.json.Json;
028import com.restfb.json.JsonObject;
029import com.restfb.json.JsonValue;
030import com.restfb.types.webhook.instagram.InstagramCommentsValue;
031import com.restfb.types.webhook.instagram.InstagramMentionsValue;
032import com.restfb.types.webhook.instagram.InstagramStoryInsightsValue;
033import com.restfb.types.webhook.whatsapp.*;
034
035/**
036 * Factory to convert the value field of the change into a class with special fields
037 */
038public class ChangeValueFactory {
039
040  private String field;
041
042  private JsonValue value;
043
044  private ChangeValue.Verb userObjectVerb;
045
046  public ChangeValueFactory setField(String field) {
047    this.field = field;
048    return this;
049  }
050
051  public ChangeValueFactory setValue(String value) {
052    if (value != null && (value.startsWith("{") || value.startsWith("["))) {
053      this.value = Json.parse(value);
054    } else {
055      this.value = Json.value(value);
056    }
057
058    return this;
059  }
060
061  public ChangeValueFactory setUserObjectVerb(ChangeValue.Verb userObjectVerb) {
062    this.userObjectVerb = userObjectVerb;
063    return this;
064  }
065
066  public ChangeValue buildWithMapper(JsonMapper mapper) {
067
068    if (value.isString()) {
069      return new SimpleStringChangeValue(value.asString());
070    }
071
072    if (value.isArray()) {
073      return new ListJsonChangeValue(value.asArray().values());
074    }
075
076    if (value.isObject()) {
077
078      JsonObject objValue = value.asObject();
079      String classDefinition;
080      if (objValue != null && field != null) {
081        classDefinition = field.toUpperCase();
082        if (objValue.get("item") != null) {
083          classDefinition += "_" + objValue.get("item").asString().toUpperCase();
084        }
085        if (objValue.get("verb") != null) {
086          classDefinition += "_" + objValue.get("verb").asString().toUpperCase();
087        }
088        if (userObjectVerb != null) {
089          classDefinition += "_" + userObjectVerb.name();
090        }
091        if (objValue.get("messaging_product") != null) {
092          classDefinition += "_" + objValue.get("messaging_product").asString().toUpperCase();
093        }
094
095        // special handling for permissions
096        String verbString = (objValue.get("verb") != null && objValue.get("verb").isString()) ? objValue.get("verb").asString() : "";
097        if (verbString.equals("granted") || verbString.equals("revoked")) {
098          classDefinition = verbString.toUpperCase();
099        }
100
101        try {
102          ChangeValueEnumeration changeValueEnum = ChangeValueEnumeration.valueOf(classDefinition);
103          return mapper.toJavaObject(objValue.toString(), changeValueEnum.getValueClass());
104        } catch (IllegalArgumentException iae) {
105          VALUE_FACTORY_LOGGER.warn("undefined change value detected: {}", classDefinition);
106          VALUE_FACTORY_LOGGER.warn("please provide this information to the restfb team: {}", objValue.toString());
107          return new FallBackChangeValue(objValue);
108        }
109      }
110    }
111
112    return null;
113  }
114
115  enum ChangeValueEnumeration {
116    FEED_ALBUM_ADD(FeedAlbumAddValue.class), //
117    FEED_ALBUM_EDITED(FeedAlbumEditedValue.class), //
118    FEED_COMMENT_ADD(FeedCommentValue.class), //
119    FEED_COMMENT_EDITED(FeedCommentValue.class), //
120    FEED_COMMENT_REMOVE(FeedCommentValue.class), //
121    FEED_COMMENT_HIDE(FeedCommentValue.class), //
122    FEED_COMMENT_UNHIDE(FeedCommentValue.class), //
123    FEED_EVENT_ADD(FeedEventValue.class), //
124    FEED_PHOTO_ADD(FeedPhotoAddValue.class), //
125    FEED_PHOTO_REMOVE(FeedPhotoRemoveValue.class), //
126    FEED_PHOTO_EDITED(FeedPhotoAddValue.class), //
127    FEED_PHOTO_HIDE(FeedPhotoAddValue.class), //
128    FEED_PHOTO_UNHIDE(FeedPhotoAddValue.class), //
129    FEED_VIDEO_ADD(FeedVideoValue.class), //
130    FEED_VIDEO_EDITED(FeedVideoValue.class), //
131    FEED_VIDEO_HIDE(FeedVideoValue.class), //
132    FEED_VIDEO_UNHIDE(FeedVideoValue.class), //
133    FEED_VIDEO_REMOVE(FeedVideoRemoveValue.class), //
134    FEED_VIDEO_UNBLOCK(FeedVideoBlockMute.class), //
135    FEED_VIDEO_BLOCK(FeedVideoBlockMute.class), //
136    FEED_VIDEO_MUTE(FeedVideoBlockMute.class), //
137    FEED_STATUS_ADD(FeedStatusValue.class), //
138    FEED_STATUS_EDITED(FeedStatusValue.class), //
139    FEED_STATUS_HIDE(FeedStatusValue.class), //
140    FEED_STATUS_UNHIDE(FeedStatusValue.class), //
141    FEED_POST_ADD(FeedPostValue.class), //
142    FEED_POST_EDITED(FeedPostValue.class), //
143    FEED_POST_EDIT(FeedPostValue.class), //
144    FEED_POST_HIDE(FeedPostValue.class), //
145    FEED_POST_REMOVE(FeedPostValue.class), //
146    FEED_POST_UNHIDE(FeedPostValue.class), //
147    FEED_REACTION_ADD(FeedReactionValue.class), //
148    FEED_REACTION_EDIT(FeedReactionValue.class), //
149    FEED_REACTION_REMOVE(FeedReactionValue.class), //
150    FEED_SHARE_ADD(FeedShareValue.class), //
151    FEED_SHARE_EDITED(FeedShareValue.class), //
152    FEED_SHARE_HIDE(FeedShareValue.class), //
153    FEED_SHARE_REMOVE(FeedShareValue.class), //
154    FEED_SHARE_UNHIDE(FeedShareValue.class), //
155    FEED_LIKE_ADD(FeedLikeValue.class), //
156    FEED_LIKE_REMOVE(FeedLikeValue.class), //
157    MENTION_POST_ADD(MentionPostAddValue.class), //
158    MENTION_COMMENT_ADD(MentionCommentAddValue.class), //
159    RATINGS_RATING_ADD(RatingsRatingValue.class), //
160    RATINGS_RATING_EDIT(RatingsRatingValue.class), //
161    RATINGS_RATING_REMOVE(RatingsRatingValue.class), //
162    RATINGS_COMMENT_ADD(RatingsCommentValue.class), //
163    RATINGS_COMMENT_EDITED(RatingsCommentValue.class), //
164    RATINGS_COMMENT_REMOVE(RatingsCommentValue.class), //
165    RATINGS_LIKE_ADD(RatingsLikeValue.class), //
166    RATINGS_LIKE_REMOVE(RatingsLikeValue.class), //
167    RATINGS_REACTION_ADD(RatingsReactionValue.class), //
168    RATINGS_REACTION_REMOVE(RatingsReactionValue.class), //
169    RATINGS_REACTION_EDIT(RatingsReactionValue.class), //
170    LEADGEN(PageLeadgen.class), //
171
172    // Instagram
173    STORY_INSIGHTS(InstagramStoryInsightsValue.class), //
174    MENTIONS(InstagramMentionsValue.class), //
175    COMMENTS(InstagramCommentsValue.class), //
176    LIVE_COMMENTS(InstagramCommentsValue.class), //
177
178    // User
179    HOMETOWN_ADD(UserPageValue.class), //
180    MOVIES_ADD(UserPageValue.class), //
181    LIKES_ADD(UserPageValue.class), //
182    LOCATION_ADD(UserPageValue.class), //
183    TELEVISION_ADD(UserPageValue.class), //
184    GRANTED(PermissionChangeValue.class), //
185    REVOKED(PermissionChangeValue.class), //
186
187    // Whatsapp Business Account
188    MESSAGE_TEMPLATE_STATUS_UPDATE(MessageTemplateStatusUpdateValue.class), //
189    PHONE_NUMBER_NAME_UPDATE(PhoneNumberNameUpdateValue.class), //
190    PHONE_NUMBER_QUALITY_UPDATE(PhoneNumberQualityUpdateValue.class), //
191    ACCOUNT_UPDATE(AccountUpdateValue.class), //
192    ACCOUNT_REVIEW_UPDATE(AccountReviewUpdateValue.class),//
193
194    // Whatsapp Business Platform
195    MESSAGES_WHATSAPP(WhatsappMessagesValue.class);
196
197    private Class<ChangeValue> valueClass;
198
199    ChangeValueEnumeration(Class valueClass) {
200      this.valueClass = valueClass;
201    }
202
203    public Class<ChangeValue> getValueClass() {
204      return valueClass;
205    }
206  }
207}