001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.bean.atom; 018 019import static org.apache.juneau.commons.utils.CopyUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021import static org.apache.juneau.commons.utils.StringUtils.*; 022import static org.apache.juneau.marshall.xml.XmlFormat.*; 023 024import java.util.*; 025 026import org.apache.juneau.commons.time.*; 027import org.apache.juneau.marshall.xml.*; 028 029/** 030 * Base class for feed-level and entry-level Atom elements. 031 * 032 * <p> 033 * This abstract class contains properties common to {@link Feed}, {@link Entry}, and {@link Source} 034 * elements. These elements share a common set of metadata properties including authors, contributors, 035 * categories, links, and timestamps. 036 * 037 * <p> 038 * Common properties include: 039 * <ul class='spaced-list'> 040 * <li><b>id</b> (required) - Permanent, unique identifier 041 * <li><b>title</b> (required) - Human-readable title 042 * <li><b>updated</b> (required) - Last modification timestamp 043 * <li><b>authors</b> - Author information 044 * <li><b>categories</b> - Classification/tagging information 045 * <li><b>contributors</b> - Contributor information 046 * <li><b>links</b> - Related resources 047 * <li><b>rights</b> - Copyright/rights information 048 * </ul> 049 * 050 * <p> 051 * This class extends {@link Common}, inheriting the <c>xml:base</c> and <c>xml:lang</c> attributes. 052 * 053 * <h5 class='section'>See Also:</h5><ul> 054 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanAtom">juneau-bean-atom</a> 055 * <li class='extlink'><a class="doclink" href="https://tools.ietf.org/html/rfc4287">RFC 4287 - The Atom Syndication Format</a> 056 * </ul> 057 * 058 * @param <SELF> The self type for fluent setters. 059 */ 060@SuppressWarnings({ 061 "java:S119" // 'SELF' (CRTP self-type) is intentional and clearer than a single-letter name. 062}) 063public class CommonEntry<SELF extends CommonEntry<SELF>> extends Common { 064 065 private Person[] authors; 066 private Category[] categories; 067 private Person[] contributors; 068 private Id id; 069 private Link[] links; 070 private Text rights; 071 private Text title; 072 private Calendar updated; 073 074 /** Bean constructor. */ 075 public CommonEntry() {} 076 077 @SuppressWarnings({ 078 "unchecked" // CRTP self cast: SELF is bound to the concrete subclass, so (SELF) this is always valid 079 }) 080 private SELF self() { 081 return (SELF) this; 082 } 083 084 /** 085 * Normal constructor. 086 * 087 * @param id The ID of this object. Can be <jk>null</jk> to leave the property unset. 088 * @param title The title of this object. Can be <jk>null</jk> to leave the property unset. 089 * @param updated The updated timestamp of this object. Can be <jk>null</jk> to leave the property unset. 090 */ 091 public CommonEntry(Id id, Text title, Calendar updated) { 092 setId(id).setTitle(title).setUpdated(updated); 093 } 094 095 /** 096 * Normal constructor. 097 * 098 * @param id The ID of this object. Can be <jk>null</jk>, in which case the property is set to an {@link Id} with no text (not left unset). 099 * @param title The title of this object. Can be <jk>null</jk>, in which case the property is set to a {@link Text} with no text (not left unset). 100 * @param updated The updated timestamp of this object. Can be <jk>null</jk> or blank to leave the property unset. 101 */ 102 public CommonEntry(String id, String title, String updated) { 103 setId(id).setTitle(title).setUpdated(updated); 104 } 105 106 /** 107 * Bean property getter: <property>authors</property>. 108 * 109 * <p> 110 * The list of authors for this object. 111 * 112 * @return The property value, or <jk>null</jk> if it is not set. 113 */ 114 @Xml(format = COLLAPSED, childName = "author") 115 public Person[] getAuthors() { return cp(authors); } 116 117 /** 118 * Bean property getter: <property>categories</property>. 119 * 120 * <p> 121 * The list of categories of this object. 122 * 123 * @return The property value, or <jk>null</jk> if it is not set. 124 */ 125 @Xml(format = COLLAPSED, childName = "category") 126 public Category[] getCategories() { return cp(categories); } 127 128 /** 129 * Bean property getter: <property>contributors</property>. 130 * 131 * <p> 132 * The list of contributors of this object. 133 * 134 * @return The property value, or <jk>null</jk> if it is not set. 135 */ 136 @Xml(format = COLLAPSED, childName = "contributor") 137 public Person[] getContributors() { return cp(contributors); } 138 139 /** 140 * Bean property getter: <property>id</property>. 141 * 142 * <p> 143 * The ID of this object. 144 * 145 * @return The property value, or <jk>null</jk> if it is not set. 146 */ 147 public Id getId() { return id; } 148 149 /** 150 * Bean property getter: <property>links</property>. 151 * 152 * <p> 153 * The list of links of this object. 154 * 155 * @return The property value, or <jk>null</jk> if it is not set. 156 */ 157 @Xml(format = COLLAPSED) 158 public Link[] getLinks() { return cp(links); } 159 160 /** 161 * Bean property getter: <property>rights</property>. 162 * 163 * <p> 164 * The rights statement of this object. 165 * 166 * @return The property value, or <jk>null</jk> if it is not set. 167 */ 168 public Text getRights() { return rights; } 169 170 /** 171 * Bean property getter: <property>title</property>. 172 * 173 * <p> 174 * The title of this object. 175 * 176 * @return The property value, or <jk>null</jk> if it is not set. 177 */ 178 public Text getTitle() { return title; } 179 180 /** 181 * Bean property getter: <property>updated</property>. 182 * 183 * <p> 184 * The update timestamp of this object. 185 * 186 * @return The property value, or <jk>null</jk> if it is not set. 187 */ 188 public Calendar getUpdated() { return cloneOf(updated); } 189 190 /** 191 * Bean property setter: <property>authors</property>. 192 * 193 * <p> 194 * The list of authors for this object. 195 * 196 * @param value 197 * The new value for this property. 198 * <br>Can be <jk>null</jk> to unset the property. 199 * @return This object 200 */ 201 public SELF setAuthors(Person...value) { 202 authors = cp(value); 203 return self(); 204 } 205 206 @Override /* Overridden from Common */ 207 public SELF setBase(Object value) { 208 super.setBase(value); 209 return self(); 210 } 211 212 /** 213 * Bean property setter: <property>categories</property>. 214 * 215 * <p> 216 * The list of categories of this object. 217 * 218 * @param value 219 * The new value for this property. 220 * <br>Can be <jk>null</jk> to unset the property. 221 * @return This object 222 */ 223 public SELF setCategories(Category...value) { 224 categories = cp(value); 225 return self(); 226 } 227 228 /** 229 * Bean property setter: <property>contributors</property>. 230 * 231 * <p> 232 * The list of contributors of this object. 233 * 234 * @param value 235 * The new value for this property. 236 * <br>Can be <jk>null</jk> to unset the property. 237 * @return This object 238 */ 239 public SELF setContributors(Person...value) { 240 contributors = cp(value); 241 return self(); 242 } 243 244 /** 245 * Bean property setter: <property>id</property>. 246 * 247 * <p> 248 * The ID of this object. 249 * 250 * @param value 251 * The new value for this property. 252 * <br>Can be <jk>null</jk> to unset the property. 253 * @return This object 254 */ 255 public SELF setId(Id value) { 256 id = value; 257 return self(); 258 } 259 260 /** 261 * Bean property fluent setter: <property>id</property>. 262 * 263 * <p> 264 * The ID of this object. 265 * 266 * @param value 267 * The new value for this property. 268 * <br>Can be <jk>null</jk> to unset the property. 269 * @return This object. 270 */ 271 public SELF setId(String value) { 272 setId(new Id(value)); 273 return self(); 274 } 275 276 @Override /* Overridden from Common */ 277 public SELF setLang(String value) { 278 super.setLang(value); 279 return self(); 280 } 281 282 /** 283 * Bean property setter: <property>links</property>. 284 * 285 * <p> 286 * The list of links of this object. 287 * 288 * @param value 289 * The new value for this property. 290 * <br>Can be <jk>null</jk> to unset the property. 291 * @return This object 292 */ 293 public SELF setLinks(Link...value) { 294 links = cp(value); 295 return self(); 296 } 297 298 /** 299 * Bean property fluent setter: <property>rights</property>. 300 * 301 * <p> 302 * The rights statement of this object. 303 * 304 * @param value 305 * The new value for this property. 306 * <br>Can be <jk>null</jk> to unset the property. 307 * @return This object. 308 */ 309 public SELF setRights(String value) { 310 setRights(new Text().setText(value)); 311 return self(); 312 } 313 314 /** 315 * Bean property setter: <property>rights</property>. 316 * 317 * <p> 318 * The rights statement of this object. 319 * 320 * @param value 321 * The new value for this property. 322 * <br>Can be <jk>null</jk> to unset the property. 323 * @return This object 324 */ 325 public SELF setRights(Text value) { 326 rights = value; 327 return self(); 328 } 329 330 /** 331 * Bean property fluent setter: <property>title</property>. 332 * 333 * <p> 334 * The title of this object. 335 * 336 * @param value 337 * The new value for this property. 338 * <br>Can be <jk>null</jk> to unset the property. 339 * @return This object. 340 */ 341 public SELF setTitle(String value) { 342 setTitle(new Text().setText(value)); 343 return self(); 344 } 345 346 /** 347 * Bean property setter: <property>title</property>. 348 * 349 * <p> 350 * The title of this object. 351 * 352 * @param value 353 * The new value for this property. 354 * <br>Can be <jk>null</jk> to unset the property. 355 * @return This object 356 */ 357 public SELF setTitle(Text value) { 358 title = value; 359 return self(); 360 } 361 362 /** 363 * Bean property setter: <property>updated</property>. 364 * 365 * <p> 366 * The update timestamp of this object. 367 * 368 * @param value 369 * The new value for this property. 370 * <br>Can be <jk>null</jk> to unset the property. 371 * @return This object 372 */ 373 public SELF setUpdated(Calendar value) { 374 updated = cloneOf(value); 375 return self(); 376 } 377 378 /** 379 * Bean property fluent setter: <property>updated</property>. 380 * 381 * <p> 382 * The update timestamp of this object. 383 * 384 * @param value 385 * The new value for this property. 386 * <br>Can be <jk>null</jk> to unset the property. 387 * @return This object. 388 */ 389 public SELF setUpdated(String value) { 390 setUpdated(o(value).filter(x1 -> ! isBlank(x1)).map(x -> GranularZonedDateTime.of(value).getZonedDateTime()).map(GregorianCalendar::from).orElse(null)); 391 return self(); 392 } 393}