1+ package com .contentstack .cms .stack ;
2+ import java .util .Arrays ;
3+ import java .util .HashMap ;
4+ import java .util .List ;
5+ import java .util .Map ;
6+
7+ import org .jetbrains .annotations .NotNull ;
8+ import org .json .simple .JSONArray ;
9+ import org .json .simple .JSONObject ;
10+
11+ import com .contentstack .cms .BaseImplementation ;
12+
13+ import okhttp3 .ResponseBody ;
14+ import retrofit2 .Call ;
15+ import retrofit2 .Retrofit ;
16+
17+ /**
18+ * The VariantGroup class provides functionality to manage variant groups in Contentstack.
19+ * Variant groups allow you to manage different versions of your content for various use cases,
20+ * such as A/B testing, localization, or personalization.
21+ */
22+ public class VariantGroup implements BaseImplementation <VariantGroup > {
23+ protected final VariantsService service ;
24+ protected final Map <String , Object > headers ;
25+ protected Map <String , Object > params ;
26+ private final Retrofit instance ;
27+ private String variantGroupUid ;
28+ private List <String > branches ;
29+
30+ /**
31+ * Creates a new VariantGroup instance without a specific variant group UID.
32+ * This constructor is used when creating new variant groups.
33+ *
34+ * @param instance The Retrofit instance for making API calls
35+ * @param headers The headers to be included in API requests
36+ */
37+ protected VariantGroup (Retrofit instance , Map <String , Object > headers ) {
38+ this .headers = new HashMap <>();
39+ this .headers .putAll (headers );
40+ this .params = new HashMap <>();
41+ this .instance = instance ;
42+ this .service = instance .create (VariantsService .class );
43+ this .branches = Arrays .asList ("main" ); // Default to main branch
44+ }
45+
46+ /**
47+ * Creates a new VariantGroup instance with a specific variant group UID.
48+ * This constructor is used when working with existing variant groups.
49+ *
50+ * @param instance The Retrofit instance for making API calls
51+ * @param headers The headers to be included in API requests
52+ * @param variantGroupUid The unique identifier of the variant group
53+ */
54+ protected VariantGroup (Retrofit instance , Map <String , Object > headers , String variantGroupUid ) {
55+ this .headers = new HashMap <>();
56+ this .headers .putAll (headers );
57+ this .params = new HashMap <>();
58+ this .instance = instance ;
59+ this .variantGroupUid = variantGroupUid ;
60+ this .service = instance .create (VariantsService .class );
61+ this .branches = Arrays .asList ("main" ); // Default to main branch
62+ }
63+
64+ /**
65+ * Validates that the variant group UID is not null or empty.
66+ * This method is called before operations that require a valid variant group UID.
67+ *
68+ * @throws IllegalAccessError if the variant group UID is null or empty
69+ */
70+ void validate () {
71+ if (this .variantGroupUid == null || this .variantGroupUid .isEmpty ())
72+ throw new IllegalAccessError ("Variant group uid can not be null or empty" );
73+ }
74+
75+ /**
76+ * Sets the branches for the variant group using a List of branch names.
77+ * These branches will be used when linking or unlinking content types to the variant group.
78+ *
79+ * @param branches A List of String values representing the branch names
80+ * @return The current VariantGroup instance for method chaining
81+ */
82+ public VariantGroup setBranches (List <String > branches ) {
83+ this .branches = branches ;
84+ return this ;
85+ }
86+
87+ /**
88+ * Sets the branches for the variant group using varargs (variable number of arguments).
89+ * This is a convenience method that allows passing branch names directly as arguments.
90+ * These branches will be used when linking or unlinking content types to the variant group.
91+ *
92+ * @param branches Variable number of String arguments representing branch names
93+ * @return The current VariantGroup instance for method chaining
94+ */
95+ public VariantGroup setBranches (String ... branches ) {
96+ this .branches = Arrays .asList (branches );
97+ return this ;
98+ }
99+
100+ /**
101+ * @param key A string representing the key of the parameter. It cannot be
102+ * null and must be
103+ * provided as a non-null value.
104+ * @param value The "value" parameter is of type Object, which means it can
105+ * accept any type of
106+ * object as its value.
107+ * @return instance of VariantGroup
108+ */
109+ @ Override
110+ public VariantGroup addParam (@ NotNull String key , @ NotNull Object value ) {
111+ this .params .put (key , value );
112+ return this ;
113+ }
114+
115+ /**
116+ * @param key The key parameter is a string that represents the name or
117+ * identifier of the header.
118+ * It is used to specify the type of information being sent in the
119+ * header.
120+ * @param value The value parameter is a string that represents the value of the
121+ * header.
122+ * @return instance of VariantGroup
123+ */
124+ @ Override
125+ public VariantGroup addHeader (@ NotNull String key , @ NotNull String value ) {
126+ this .headers .put (key , value );
127+ return this ;
128+ }
129+
130+ /**
131+ * @param headers A HashMap containing key-value pairs of headers, where the key
132+ * is a String
133+ * representing the header name and the value is a String
134+ * representing the header value.
135+ * @return instance of VariantGroup
136+ */
137+ @ Override
138+ public VariantGroup addHeaders (@ NotNull HashMap <String , String > headers ) {
139+ this .headers .putAll (headers );
140+ return this ;
141+ }
142+
143+
144+ /**
145+ * @param headers The "params" parameter is a HashMap that maps String keys to
146+ * Object values. It is
147+ * annotated with @NotNull, indicating that it cannot be null.
148+ * @return instance of VariantGroup
149+ */
150+ @ Override
151+ public VariantGroup addParams (@ NotNull HashMap <String , Object > headers ) {
152+ this .params .putAll (headers );
153+ return this ;
154+ }
155+
156+
157+ /**
158+ * clears all params in the request
159+ */
160+ protected void clearParams () {
161+ this .params .clear ();
162+ }
163+
164+ /**
165+ * Retrieves a list of all variant groups.
166+ * This method does not require a variant group UID to be set.
167+ *
168+ * @return A Call object that can be executed to perform the API request to fetch all variant groups
169+ */
170+ public Call <ResponseBody > find () {
171+ return this .service .fetchVariantGroups (this .headers , this .params );
172+ }
173+
174+ /**
175+ * Links content types to the variant group.
176+ *
177+ * @param contentTypeUids Array of content type UIDs to link to the variant group
178+ * @return A Call object that can be executed to perform the API request
179+ * @throws IllegalAccessError if the variant group UID is not set
180+ * @throws IllegalArgumentException if contentTypeUids is empty
181+ */
182+ public Call <ResponseBody > linkContentTypes (@ NotNull String ... contentTypeUids ) {
183+ if (contentTypeUids .length == 0 ) {
184+ throw new IllegalArgumentException ("Content type UIDs cannot be empty" );
185+ }
186+ return updateContentTypeLinks (contentTypeUids , true );
187+ }
188+
189+ /**
190+ * Unlinks content types from the variant group.
191+ *
192+ * @param contentTypeUids Array of content type UIDs to unlink from the variant group
193+ * @return A Call object that can be executed to perform the API request
194+ * @throws IllegalAccessError if the variant group UID is not set
195+ * @throws IllegalArgumentException if contentTypeUids is empty
196+ */
197+ public Call <ResponseBody > unlinkContentTypes (@ NotNull String ... contentTypeUids ) {
198+ if (contentTypeUids .length == 0 ) {
199+ throw new IllegalArgumentException ("Content type UIDs cannot be empty" );
200+ }
201+ return updateContentTypeLinks (contentTypeUids , false );
202+ }
203+
204+ /**
205+ * Updates the linking status of content types to a variant group.
206+ * This private method handles both linking and unlinking operations.
207+ *
208+ * @param contentTypeUids Array of content type UIDs to update
209+ * @param isLink true to link content types, false to unlink
210+ * @return A Call object that can be executed to perform the API request
211+ * @throws IllegalAccessError if the variant group UID is not set
212+ */
213+ @ SuppressWarnings ("unchecked" )
214+ private Call <ResponseBody > updateContentTypeLinks (String [] contentTypeUids , boolean isLink ) {
215+ validate ();
216+
217+ // Construct the request body
218+ JSONObject requestBody = new JSONObject ();
219+ JSONArray contentTypes = new JSONArray ();
220+ JSONArray branches = new JSONArray ();
221+ for (String branch : this .branches ) {
222+ branches .add (branch );
223+ }
224+
225+ for (String uid : contentTypeUids ) {
226+ JSONObject contentType = new JSONObject ();
227+ contentType .put ("uid" , uid );
228+ contentType .put ("status" , isLink ? "linked" : "unlinked" );
229+ contentTypes .add (contentType );
230+ }
231+ requestBody .put ("uid" , this .variantGroupUid );
232+ requestBody .put ("branches" , branches );
233+ requestBody .put ("content_types" , contentTypes );
234+ return this .service .updateVariantGroupContentTypes (this .headers , this .variantGroupUid , this .params , requestBody );
235+ }
236+ }
0 commit comments