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.xml.annotation.XmlFormat.*;
020
021import org.apache.juneau.annotation.*;
022import org.apache.juneau.xml.annotation.*;
023
024/**
025 * Represents a reference from an entry or feed to a Web resource.
026 *
027 * <p>
028 * Atom links define references to related resources such as alternate representations, 
029 * related documents, enclosures (for podcasts), and navigation links. Links are one of the 
030 * fundamental components of Atom and enable rich hypermedia relationships between resources.
031 *
032 * <p>
033 * The link's <c>rel</c> attribute defines the relationship type, while <c>href</c> provides 
034 * the target URI. Common relationship types include:
035 * <ul class='spaced-list'>
036 *    <li><c>alternate</c> - An alternate representation (e.g., HTML version of entry)
037 *    <li><c>self</c> - The feed/entry itself
038 *    <li><c>related</c> - A related resource
039 *    <li><c>enclosure</c> - A related resource to be downloaded (e.g., podcast audio)
040 *    <li><c>via</c> - The source of the information
041 * </ul>
042 *
043 * <h5 class='figure'>Schema</h5>
044 * <p class='bschema'>
045 *    atomLink =
046 *       element atom:link {
047 *          atomCommonAttributes,
048 *          attribute href { atomUri },
049 *          attribute rel { atomNCName | atomUri }?,
050 *          attribute type { atomMediaType }?,
051 *          attribute hreflang { atomLanguageTag }?,
052 *          attribute title { text }?,
053 *          attribute length { text }?,
054 *          undefinedContent
055 *       }
056 * </p>
057 *
058 * <h5 class='section'>Example:</h5>
059 * <p class='bjava'>
060 *    <jc>// Create links for an entry</jc>
061 *    Entry <jv>entry</jv> = <jk>new</jk> Entry(...)
062 *       .setLinks(
063 *          <jc>// Link to HTML version</jc>
064 *          <jk>new</jk> Link(<js>"alternate"</js>, <js>"text/html"</js>, <js>"http://example.org/post1.html"</js>)
065 *             .setHreflang(<js>"en"</js>),
066 *          <jc>// Podcast enclosure</jc>
067 *          <jk>new</jk> Link(<js>"enclosure"</js>, <js>"audio/mpeg"</js>, <js>"http://example.org/episode1.mp3"</js>)
068 *             .setLength(24986239)
069 *       );
070 * </p>
071 *
072 * <h5 class='section'>Specification:</h5>
073 * <p>
074 * Represents an <c>atomLink</c> construct in the 
075 * <a class="doclink" href="https://tools.ietf.org/html/rfc4287#section-4.2.7">RFC 4287 - Section 4.2.7</a> specification.
076 *
077 * <h5 class='section'>See Also:</h5><ul>
078 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanAtom">juneau-bean-atom</a>
079 *    <li class='extlink'><a class="doclink" href="https://tools.ietf.org/html/rfc4287">RFC 4287 - The Atom Syndication Format</a>
080 *    <li class='extlink'><a class="doclink" href="https://www.iana.org/assignments/link-relations/link-relations.xhtml">IANA Link Relations</a>
081 * </ul>
082 */
083@Bean(typeName="link")
084public class Link extends Common {
085
086   private String href;
087   private String rel;
088   private String type;
089   private String hreflang;
090   private String title;
091   private Integer length;
092
093
094   /**
095    * Normal constructor.
096    *
097    * @param rel The rel of the link.
098    * @param type The type of the link.
099    * @param href The URI of the link.
100    */
101   public Link(String rel, String type, String href) {
102      setRel(rel).setType(type).setHref(href);
103   }
104
105   /** Bean constructor. */
106   public Link() {}
107
108
109   //-----------------------------------------------------------------------------------------------------------------
110   // Bean properties
111   //-----------------------------------------------------------------------------------------------------------------
112
113   /**
114    * Bean property getter:  <property>href</property>.
115    *
116    * <p>
117    * Returns the URI of the referenced resource.
118    *
119    * <p>
120    * This is the target address of the link and is a required attribute for all Atom links.
121    *
122    * @return The property value, or <jk>null</jk> if it is not set.
123    */
124   @Xml(format=ATTR)
125   public String getHref() {
126      return href;
127   }
128
129   /**
130    * Bean property setter:  <property>href</property>.
131    *
132    * <p>
133    * Sets the URI of the referenced resource (required).
134    *
135    * <h5 class='section'>Example:</h5>
136    * <p class='bjava'>
137    *    Link <jv>link</jv> = <jk>new</jk> Link()
138    *       .setHref(<js>"http://example.org/posts/1"</js>);
139    * </p>
140    *
141    * @param value
142    *    The new value for this property.
143    *    <br>Can be <jk>null</jk> to unset the property.
144    * @return This object.
145    */
146   public Link setHref(String value) {
147      this.href = value;
148      return this;
149   }
150
151   /**
152    * Bean property getter:  <property>rel</property>.
153    *
154    * <p>
155    * Returns the link relation type.
156    *
157    * <p>
158    * The <c>rel</c> attribute indicates the type of relationship between the entry/feed and 
159    * the linked resource. When not specified, the default is "alternate".
160    *
161    * @return The property value, or <jk>null</jk> if it is not set.
162    */
163   @Xml(format=ATTR)
164   public String getRel() {
165      return rel;
166   }
167
168   /**
169    * Bean property setter:  <property>rel</property>.
170    *
171    * <p>
172    * Sets the link relation type.
173    *
174    * <p>
175    * Common values include <js>"alternate"</js>, <js>"self"</js>, <js>"related"</js>, 
176    * <js>"enclosure"</js>, <js>"via"</js>, <js>"first"</js>, <js>"last"</js>, 
177    * <js>"previous"</js>, <js>"next"</js>.
178    *
179    * <h5 class='section'>Example:</h5>
180    * <p class='bjava'>
181    *    Link <jv>link</jv> = <jk>new</jk> Link()
182    *       .setRel(<js>"alternate"</js>)
183    *       .setHref(<js>"http://example.org/post1.html"</js>);
184    * </p>
185    *
186    * @param value
187    *    The new value for this property.
188    *    <br>Can be <jk>null</jk> to unset the property (defaults to "alternate").
189    * @return This object.
190    */
191   public Link setRel(String value) {
192      this.rel = value;
193      return this;
194   }
195
196   /**
197    * Bean property getter:  <property>type</property>.
198    *
199    * <p>
200    * The content type of the target of this link.
201    *
202    * @return The property value, or <jk>null</jk> if it is not set.
203    */
204   @Xml(format=ATTR)
205   public String getType() {
206      return type;
207   }
208
209   /**
210    * Bean property setter:  <property>type</property>.
211    *
212    * <p>
213    * The content type of the target of this link.
214    *
215    * <p>
216    * This should be a valid MIME media type as defined by RFC 4287.
217    *
218    * <h5 class='section'>Examples:</h5>
219    * <ul class='spaced-list'>
220    *    <li><js>"text/html"</js>
221    *    <li><js>"application/pdf"</js>
222    *    <li><js>"image/jpeg"</js>
223    *    <li><js>"application/atom+xml"</js>
224    * </ul>
225    *
226    * @param value
227    *    The new value for this property.
228    *    <br>Can be <jk>null</jk> to unset the property.
229    * @return This object
230    */
231   public Link setType(String value) {
232      this.type = value;
233      return this;
234   }
235
236   /**
237    * Bean property getter:  <property>hreflang</property>.
238    *
239    * <p>
240    * Returns the language of the resource pointed to by the link.
241    *
242    * <p>
243    * The value should be a language tag as defined by RFC 3066.
244    *
245    * @return The property value, or <jk>null</jk> if it is not set.
246    */
247   @Xml(format=ATTR)
248   public String getHreflang() {
249      return hreflang;
250   }
251
252   /**
253    * Bean property setter:  <property>hreflang</property>.
254    *
255    * <p>
256    * Sets the language of the resource pointed to by the link.
257    *
258    * <h5 class='section'>Example:</h5>
259    * <p class='bjava'>
260    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"alternate"</js>, <js>"text/html"</js>, <js>"http://example.org/post1.html"</js>)
261    *       .setHreflang(<js>"en-US"</js>);
262    * </p>
263    *
264    * @param value
265    *    The new value for this property (e.g., "en", "fr", "de", "en-US").
266    *    <br>Can be <jk>null</jk> to unset the property.
267    * @return This object.
268    */
269   public Link setHreflang(String value) {
270      this.hreflang = value;
271      return this;
272   }
273
274   /**
275    * Bean property getter:  <property>title</property>.
276    *
277    * <p>
278    * Returns human-readable information about the link.
279    *
280    * <p>
281    * The title provides advisory information about the link, typically for display to users.
282    *
283    * @return The property value, or <jk>null</jk> if it is not set.
284    */
285   @Xml(format=ATTR)
286   public String getTitle() {
287      return title;
288   }
289
290   /**
291    * Bean property setter:  <property>title</property>.
292    *
293    * <p>
294    * Sets human-readable information about the link.
295    *
296    * <h5 class='section'>Example:</h5>
297    * <p class='bjava'>
298    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"related"</js>, <js>"text/html"</js>, <js>"http://example.org/related"</js>)
299    *       .setTitle(<js>"Related Article"</js>);
300    * </p>
301    *
302    * @param value
303    *    The new value for this property.
304    *    <br>Can be <jk>null</jk> to unset the property.
305    * @return This object.
306    */
307   public Link setTitle(String value) {
308      this.title = value;
309      return this;
310   }
311
312   /**
313    * Bean property getter:  <property>length</property>.
314    *
315    * <p>
316    * Returns an advisory size in bytes of the linked resource.
317    *
318    * <p>
319    * This is particularly useful for enclosures (podcast episodes, video files, etc.) to 
320    * help clients decide whether to download the resource.
321    *
322    * @return The property value, or <jk>null</jk> if it is not set.
323    */
324   @Xml(format=ATTR)
325   public Integer getLength() {
326      return length;
327   }
328
329   /**
330    * Bean property setter:  <property>length</property>.
331    *
332    * <p>
333    * Sets an advisory size in bytes of the linked resource.
334    *
335    * <h5 class='section'>Example:</h5>
336    * <p class='bjava'>
337    *    <jc>// Podcast episode with file size</jc>
338    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"enclosure"</js>, <js>"audio/mpeg"</js>, <js>"http://example.org/episode1.mp3"</js>)
339    *       .setLength(24986239);  <jc>// ~24 MB</jc>
340    * </p>
341    *
342    * @param value
343    *    The new value for this property in bytes.
344    *    <br>Can be <jk>null</jk> to unset the property.
345    * @return This object.
346    */
347   public Link setLength(Integer value) {
348      this.length = value;
349      return this;
350   }
351
352   //-----------------------------------------------------------------------------------------------------------------
353   // Overridden setters (to simplify method chaining)
354   //-----------------------------------------------------------------------------------------------------------------
355
356   @Override /* Overridden from Common */
357   public Link setBase(Object value) {
358      super.setBase(value);
359      return this;
360   }
361
362   @Override /* Overridden from Common */
363   public Link setLang(String value) {
364      super.setLang(value);
365      return this;
366   }
367}