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.*;
034import com.restfb.types.webhook.whatsapp.WhatsappMessagesValue;
035
036/**
037 * Factory to convert the value field of the change into a class with special fields
038 */
039public class ChangeValueFactory {
040
041  private String field;
042
043  private JsonValue value;
044
045  private ChangeValue.Verb userObjectVerb;
046
047  public ChangeValueFactory setField(String field) {
048    this.field = field;
049    return this;
050  }
051
052  public ChangeValueFactory setValue(String value) {
053    if (value != null && (value.startsWith("{") || value.startsWith("["))) {
054      this.value = Json.parse(value);
055    } else {
056      this.value = Json.value(value);
057    }
058
059    return this;
060  }
061
062  public ChangeValueFactory setUserObjectVerb(ChangeValue.Verb userObjectVerb) {
063    this.userObjectVerb = userObjectVerb;
064    return this;
065  }
066
067  public ChangeValue buildWithMapper(JsonMapper mapper) {
068
069    if (value.isString()) {
070      return new SimpleStringChangeValue(value.asString());
071    }
072
073    if (value.isArray()) {
074      return new ListJsonChangeValue(value.asArray().values());
075    }
076
077    if (value.isObject()) {
078
079      JsonObject objValue = value.asObject();
080      String classDefinition;
081      if (objValue != null && field != null) {
082        classDefinition = field.toUpperCase();
083        if (objValue.get("item") != null) {
084          classDefinition += "_" + objValue.get("item").asString().toUpperCase();
085        }
086        if (objValue.get("verb") != null) {
087          classDefinition += "_" + objValue.get("verb").asString().toUpperCase();
088        }
089        if (userObjectVerb != null) {
090          classDefinition += "_" + userObjectVerb.name();
091        }
092        if (objValue.get("messaging_product") != null) {
093          classDefinition += "_" + objValue.get("messaging_product").asString().toUpperCase();
094        }
095
096        // special handling for permissions
097        String verbString = (objValue.get("verb") != null && objValue.get("verb").isString()) ? objValue.get("verb").asString() : "";
098        if (verbString.equals("granted") || verbString.equals("revoked")) {
099          classDefinition = verbString.toUpperCase();
100        }
101
102        try {
103          ChangeValueEnumeration changeValueEnum = ChangeValueEnumeration.valueOf(classDefinition);
104          return mapper.toJavaObject(objValue.toString(), changeValueEnum.getValueClass());
105        } catch (IllegalArgumentException iae) {
106          VALUE_FACTORY_LOGGER.warn("undefined change value detected: {}", classDefinition);
107          VALUE_FACTORY_LOGGER.warn("please provide this information to the restfb team: {}", objValue.toString());
108          return new FallBackChangeValue(objValue);
109        }
110      }
111    }
112
113    return null;
114  }
115
116  enum ChangeValueEnumeration {
117    FEED_ALBUM_ADD(FeedAlbumAddValue.class), //
118    FEED_ALBUM_EDITED(FeedAlbumEditedValue.class), //
119    FEED_COMMENT_ADD(FeedCommentValue.class), //
120    FEED_COMMENT_EDITED(FeedCommentValue.class), //
121    FEED_COMMENT_REMOVE(FeedCommentValue.class), //
122    FEED_COMMENT_HIDE(FeedCommentValue.class), //
123    FEED_COMMENT_UNHIDE(FeedCommentValue.class), //
124    FEED_EVENT_ADD(FeedEventValue.class), //
125    FEED_PHOTO_ADD(FeedPhotoAddValue.class), //
126    FEED_PHOTO_REMOVE(FeedPhotoRemoveValue.class), //
127    FEED_PHOTO_EDITED(FeedPhotoAddValue.class), //
128    FEED_PHOTO_HIDE(FeedPhotoAddValue.class), //
129    FEED_PHOTO_UNHIDE(FeedPhotoAddValue.class), //
130    FEED_VIDEO_ADD(FeedVideoValue.class), //
131    FEED_VIDEO_EDITED(FeedVideoValue.class), //
132    FEED_VIDEO_HIDE(FeedVideoValue.class), //
133    FEED_VIDEO_UNHIDE(FeedVideoValue.class), //
134    FEED_VIDEO_REMOVE(FeedVideoRemoveValue.class), //
135    FEED_VIDEO_UNBLOCK(FeedVideoBlockMute.class), //
136    FEED_VIDEO_BLOCK(FeedVideoBlockMute.class), //
137    FEED_VIDEO_MUTE(FeedVideoBlockMute.class), //
138    FEED_STATUS_ADD(FeedStatusValue.class), //
139    FEED_STATUS_EDITED(FeedStatusValue.class), //
140    FEED_STATUS_HIDE(FeedStatusValue.class), //
141    FEED_STATUS_UNHIDE(FeedStatusValue.class), //
142    FEED_POST_ADD(FeedPostValue.class), //
143    FEED_POST_EDITED(FeedPostValue.class), //
144    FEED_POST_EDIT(FeedPostValue.class), //
145    FEED_POST_HIDE(FeedPostValue.class), //
146    FEED_POST_REMOVE(FeedPostValue.class), //
147    FEED_POST_UNHIDE(FeedPostValue.class), //
148    FEED_REACTION_ADD(FeedReactionValue.class), //
149    FEED_REACTION_EDIT(FeedReactionValue.class), //
150    FEED_REACTION_REMOVE(FeedReactionValue.class), //
151    FEED_SHARE_ADD(FeedShareValue.class), //
152    FEED_SHARE_EDITED(FeedShareValue.class), //
153    FEED_SHARE_HIDE(FeedShareValue.class), //
154    FEED_SHARE_REMOVE(FeedShareValue.class), //
155    FEED_SHARE_UNHIDE(FeedShareValue.class), //
156    FEED_LIKE_ADD(FeedLikeValue.class), //
157    FEED_LIKE_REMOVE(FeedLikeValue.class), //
158    MENTION_POST_ADD(MentionPostAddValue.class), //
159    MENTION_COMMENT_ADD(MentionCommentAddValue.class), //
160    RATINGS_RATING_ADD(RatingsRatingValue.class), //
161    RATINGS_RATING_EDIT(RatingsRatingValue.class), //
162    RATINGS_RATING_REMOVE(RatingsRatingValue.class), //
163    RATINGS_COMMENT_ADD(RatingsCommentValue.class), //
164    RATINGS_COMMENT_EDITED(RatingsCommentValue.class), //
165    RATINGS_COMMENT_REMOVE(RatingsCommentValue.class), //
166    RATINGS_LIKE_ADD(RatingsLikeValue.class), //
167    RATINGS_LIKE_REMOVE(RatingsLikeValue.class), //
168    RATINGS_REACTION_ADD(RatingsReactionValue.class), //
169    RATINGS_REACTION_REMOVE(RatingsReactionValue.class), //
170    RATINGS_REACTION_EDIT(RatingsReactionValue.class), //
171    LEADGEN(PageLeadgen.class), //
172
173    // Instagram
174    STORY_INSIGHTS(InstagramStoryInsightsValue.class), //
175    MENTIONS(InstagramMentionsValue.class), //
176    COMMENTS(InstagramCommentsValue.class), //
177    LIVE_COMMENTS(InstagramCommentsValue.class), //
178
179    // User
180    HOMETOWN_ADD(UserPageValue.class), //
181    MOVIES_ADD(UserPageValue.class), //
182    LIKES_ADD(UserPageValue.class), //
183    LOCATION_ADD(UserPageValue.class), //
184    TELEVISION_ADD(UserPageValue.class), //
185    GRANTED(PermissionChangeValue.class), //
186    REVOKED(PermissionChangeValue.class), //
187
188    // Whatsapp Business Account
189    MESSAGE_TEMPLATE_STATUS_UPDATE(MessageTemplateStatusUpdateValue.class), //
190    PHONE_NUMBER_NAME_UPDATE(PhoneNumberNameUpdateValue.class), //
191    PHONE_NUMBER_QUALITY_UPDATE(PhoneNumberQualityUpdateValue.class), //
192    ACCOUNT_UPDATE(AccountUpdateValue.class), //
193    ACCOUNT_REVIEW_UPDATE(AccountReviewUpdateValue.class),//
194
195    // Whatsapp Business Platform
196    MESSAGES_WHATSAPP(WhatsappMessagesValue.class);
197
198    private Class<ChangeValue> valueClass;
199
200    ChangeValueEnumeration(Class valueClass) {
201      this.valueClass = valueClass;
202    }
203
204    public Class<ChangeValue> getValueClass() {
205      return valueClass;
206    }
207  }
208}