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   /** Bean constructor. */
094   public Link() {}
095
096   /**
097    * Normal constructor.
098    *
099    * @param rel The rel of the link.
100    * @param type The type of the link.
101    * @param href The URI of the link.
102    */
103   public Link(String rel, String type, String href) {
104      setRel(rel).setType(type).setHref(href);
105   }
106
107   /**
108    * Bean property getter:  <property>href</property>.
109    *
110    * <p>
111    * Returns the URI of the referenced resource.
112    *
113    * <p>
114    * This is the target address of the link and is a required attribute for all Atom links.
115    *
116    * @return The property value, or <jk>null</jk> if it is not set.
117    */
118   @Xml(format = ATTR)
119   public String getHref() { return href; }
120
121   /**
122    * Bean property getter:  <property>hreflang</property>.
123    *
124    * <p>
125    * Returns the language of the resource pointed to by the link.
126    *
127    * <p>
128    * The value should be a language tag as defined by RFC 3066.
129    *
130    * @return The property value, or <jk>null</jk> if it is not set.
131    */
132   @Xml(format = ATTR)
133   public String getHreflang() { return hreflang; }
134
135   /**
136    * Bean property getter:  <property>length</property>.
137    *
138    * <p>
139    * Returns an advisory size in bytes of the linked resource.
140    *
141    * <p>
142    * This is particularly useful for enclosures (podcast episodes, video files, etc.) to
143    * help clients decide whether to download the resource.
144    *
145    * @return The property value, or <jk>null</jk> if it is not set.
146    */
147   @Xml(format = ATTR)
148   public Integer getLength() { return length; }
149
150   /**
151    * Bean property getter:  <property>rel</property>.
152    *
153    * <p>
154    * Returns the link relation type.
155    *
156    * <p>
157    * The <c>rel</c> attribute indicates the type of relationship between the entry/feed and
158    * the linked resource. When not specified, the default is "alternate".
159    *
160    * @return The property value, or <jk>null</jk> if it is not set.
161    */
162   @Xml(format = ATTR)
163   public String getRel() { return rel; }
164
165   /**
166    * Bean property getter:  <property>title</property>.
167    *
168    * <p>
169    * Returns human-readable information about the link.
170    *
171    * <p>
172    * The title provides advisory information about the link, typically for display to users.
173    *
174    * @return The property value, or <jk>null</jk> if it is not set.
175    */
176   @Xml(format = ATTR)
177   public String getTitle() { return title; }
178
179   /**
180    * Bean property getter:  <property>type</property>.
181    *
182    * <p>
183    * The content type of the target of this link.
184    *
185    * @return The property value, or <jk>null</jk> if it is not set.
186    */
187   @Xml(format = ATTR)
188   public String getType() { return type; }
189
190   @Override /* Overridden from Common */
191   public Link setBase(Object value) {
192      super.setBase(value);
193      return this;
194   }
195
196   /**
197    * Bean property setter:  <property>href</property>.
198    *
199    * <p>
200    * Sets the URI of the referenced resource (required).
201    *
202    * <h5 class='section'>Example:</h5>
203    * <p class='bjava'>
204    *    Link <jv>link</jv> = <jk>new</jk> Link()
205    *       .setHref(<js>"http://example.org/posts/1"</js>);
206    * </p>
207    *
208    * @param value
209    *    The new value for this property.
210    *    <br>Can be <jk>null</jk> to unset the property.
211    * @return This object.
212    */
213   public Link setHref(String value) {
214      href = value;
215      return this;
216   }
217
218   /**
219    * Bean property setter:  <property>hreflang</property>.
220    *
221    * <p>
222    * Sets the language of the resource pointed to by the link.
223    *
224    * <h5 class='section'>Example:</h5>
225    * <p class='bjava'>
226    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"alternate"</js>, <js>"text/html"</js>, <js>"http://example.org/post1.html"</js>)
227    *       .setHreflang(<js>"en-US"</js>);
228    * </p>
229    *
230    * @param value
231    *    The new value for this property (e.g., "en", "fr", "de", "en-US").
232    *    <br>Can be <jk>null</jk> to unset the property.
233    * @return This object.
234    */
235   public Link setHreflang(String value) {
236      hreflang = value;
237      return this;
238   }
239
240   @Override /* Overridden from Common */
241   public Link setLang(String value) {
242      super.setLang(value);
243      return this;
244   }
245
246   /**
247    * Bean property setter:  <property>length</property>.
248    *
249    * <p>
250    * Sets an advisory size in bytes of the linked resource.
251    *
252    * <h5 class='section'>Example:</h5>
253    * <p class='bjava'>
254    *    <jc>// Podcast episode with file size</jc>
255    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"enclosure"</js>, <js>"audio/mpeg"</js>, <js>"http://example.org/episode1.mp3"</js>)
256    *       .setLength(24986239);  <jc>// ~24 MB</jc>
257    * </p>
258    *
259    * @param value
260    *    The new value for this property in bytes.
261    *    <br>Can be <jk>null</jk> to unset the property.
262    * @return This object.
263    */
264   public Link setLength(Integer value) {
265      length = value;
266      return this;
267   }
268
269   /**
270    * Bean property setter:  <property>rel</property>.
271    *
272    * <p>
273    * Sets the link relation type.
274    *
275    * <p>
276    * Common values include <js>"alternate"</js>, <js>"self"</js>, <js>"related"</js>,
277    * <js>"enclosure"</js>, <js>"via"</js>, <js>"first"</js>, <js>"last"</js>,
278    * <js>"previous"</js>, <js>"next"</js>.
279    *
280    * <h5 class='section'>Example:</h5>
281    * <p class='bjava'>
282    *    Link <jv>link</jv> = <jk>new</jk> Link()
283    *       .setRel(<js>"alternate"</js>)
284    *       .setHref(<js>"http://example.org/post1.html"</js>);
285    * </p>
286    *
287    * @param value
288    *    The new value for this property.
289    *    <br>Can be <jk>null</jk> to unset the property (defaults to "alternate").
290    * @return This object.
291    */
292   public Link setRel(String value) {
293      rel = value;
294      return this;
295   }
296
297   /**
298    * Bean property setter:  <property>title</property>.
299    *
300    * <p>
301    * Sets human-readable information about the link.
302    *
303    * <h5 class='section'>Example:</h5>
304    * <p class='bjava'>
305    *    Link <jv>link</jv> = <jk>new</jk> Link(<js>"related"</js>, <js>"text/html"</js>, <js>"http://example.org/related"</js>)
306    *       .setTitle(<js>"Related Article"</js>);
307    * </p>
308    *
309    * @param value
310    *    The new value for this property.
311    *    <br>Can be <jk>null</jk> to unset the property.
312    * @return This object.
313    */
314   public Link setTitle(String value) {
315      title = value;
316      return this;
317   }
318
319   /**
320    * Bean property setter:  <property>type</property>.
321    *
322    * <p>
323    * The content type of the target of this link.
324    *
325    * <p>
326    * This should be a valid MIME media type as defined by RFC 4287.
327    *
328    * <h5 class='section'>Examples:</h5>
329    * <ul class='spaced-list'>
330    *    <li><js>"text/html"</js>
331    *    <li><js>"application/pdf"</js>
332    *    <li><js>"image/jpeg"</js>
333    *    <li><js>"application/atom+xml"</js>
334    * </ul>
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 Link setType(String value) {
342      type = value;
343      return this;
344   }
345}