Source Code Cross Referenced for RSSItem.java in  » RSS-RDF » curn » org » clapper » curn » parser » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » RSS RDF » curn » org.clapper.curn.parser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*---------------------------------------------------------------------------*\
002:          $Id: RSSItem.java 7041 2007-09-09 01:04:47Z bmc $
003:          ---------------------------------------------------------------------------
004:          This software is released under a BSD-style license:
005:
006:          Copyright (c) 2004-2007 Brian M. Clapper. All rights reserved.
007:
008:          Redistribution and use in source and binary forms, with or without
009:          modification, are permitted provided that the following conditions are
010:          met:
011:
012:          1. Redistributions of source code must retain the above copyright notice,
013:             this list of conditions and the following disclaimer.
014:
015:          2. The end-user documentation included with the redistribution, if any,
016:             must include the following acknowlegement:
017:
018:                "This product includes software developed by Brian M. Clapper
019:                (bmc@clapper.org, http://www.clapper.org/bmc/). That software is
020:                copyright (c) 2004-2007 Brian M. Clapper."
021:
022:             Alternately, this acknowlegement may appear in the software itself,
023:             if wherever such third-party acknowlegements normally appear.
024:
025:          3. Neither the names "clapper.org", "curn", nor any of the names of the
026:             project contributors may be used to endorse or promote products
027:             derived from this software without prior written permission. For
028:             written permission, please contact bmc@clapper.org.
029:
030:          4. Products derived from this software may not be called "curn", nor may
031:             "clapper.org" appear in their names without prior written permission
032:             of Brian M. Clapper.
033:
034:          THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035:          WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
036:          MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
037:          NO EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT,
038:          INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
039:          NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
040:          DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
041:          THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042:          (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043:          THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044:        \*---------------------------------------------------------------------------*/
045:
046:        package org.clapper.curn.parser;
047:
048:        import org.clapper.util.text.TextUtil;
049:
050:        import java.util.Collection;
051:        import java.util.Date;
052:        import java.util.HashMap;
053:        import java.util.Map;
054:
055:        /**
056:         * This abstract class defines a simplified view of an RSS item, providing
057:         * only the methods necessary for <i>curn</i> to work. <i>curn</i> uses the
058:         * {@link RSSParserFactory} class to get a specific implementation of
059:         * <tt>RSSParser</tt>, which returns <tt>RSSChannel</tt>-conforming objects
060:         * that, in turn, return item objects that subclass <tt>RSSItem</tt>. This
061:         * strategy isolates the bulk of the code from the underlying RSS parser,
062:         * making it easier to substitute different parsers as more of them become
063:         * available. <tt>RSSItem</tt>. This strategy isolates the bulk of the code
064:         * from the underlying RSS parser, making it easier to substitute different
065:         * parsers as more of them become available.
066:         *
067:         * @see RSSParserFactory
068:         * @see RSSParser
069:         * @see RSSChannel
070:         *
071:         * @version <tt>$Revision: 7041 $</tt>
072:         */
073:        public abstract class RSSItem extends RSSElement implements  Cloneable,
074:                Comparable {
075:            /*----------------------------------------------------------------------*\
076:                                         Constants
077:            \*----------------------------------------------------------------------*/
078:
079:            /**
080:             * Constant defining the pseudo-MIME type to use for default content.
081:             */
082:            public static final String DEFAULT_CONTENT_TYPE = "*";
083:
084:            /**
085:             * Unlimited summary size
086:             */
087:            public static final int NO_SUMMARY_LIMIT = 0;
088:
089:            /*----------------------------------------------------------------------*\
090:                                   Private Instance Data
091:            \*----------------------------------------------------------------------*/
092:
093:            private HashMap<String, String> contentMap = null;
094:
095:            /*----------------------------------------------------------------------*\
096:                                      Constructor
097:            \*----------------------------------------------------------------------*/
098:
099:            /**
100:             * Default constructor
101:             */
102:            protected RSSItem() {
103:                super ();
104:            }
105:
106:            /*----------------------------------------------------------------------*\
107:                                      Public Methods
108:            \*----------------------------------------------------------------------*/
109:
110:            /**
111:             * Clone this channel. This method simply calls the type-safe
112:             * {@link #makeCopy} method. The clone is a deep-clone (i.e., the items
113:             * are cloned, too).
114:             *
115:             * @return the cloned <tt>RSSChannel</tt>
116:             *
117:             * @throws CloneNotSupportedException  doesn't, actually, but the
118:             *                                     <tt>Cloneable</tt> interface
119:             *                                     requires that this exception
120:             *                                     be declared
121:             *
122:             * @see #makeCopy
123:             */
124:            @Override
125:            public Object clone() throws CloneNotSupportedException {
126:                return makeCopy(getParentChannel());
127:            }
128:
129:            /**
130:             * Make a deep copy of this <tt>RSSItem</tt> object.
131:             *
132:             * @param parentChannel  the parent channel to assign to the new instance
133:             *
134:             * @return the copy
135:             */
136:            public RSSItem makeCopy(RSSChannel parentChannel) {
137:                RSSItem copy = newInstance(parentChannel);
138:
139:                initContentMap();
140:                copy.contentMap = new HashMap<String, String>();
141:                for (String key : this .contentMap.keySet())
142:                    copy.contentMap.put(key, this .contentMap.get(key));
143:
144:                copyPrivateFields(copy);
145:                copy.setTitle(this .getTitle());
146:                copy.setSummary(this .getSummary());
147:                copy.setLinks(this .getLinks());
148:                copy.setCategories(this .getCategories());
149:                copy.setPublicationDate(this .getPublicationDate());
150:                copy.setID(this .getID());
151:
152:                Collection<String> authors = this .getAuthors();
153:                if (authors != null) {
154:                    for (String author : authors) {
155:                        if (author != null)
156:                            copy.addAuthor(author);
157:                    }
158:                }
159:
160:                return copy;
161:            }
162:
163:            /**
164:             * Get the item's content, if available. Some feed types (e.g., Atom)
165:             * support multiple content sections, each with its own MIME type; the
166:             * <tt>mimeType</tt> parameter specifies the caller's desired MIME
167:             * type.
168:             *
169:             * @param mimeType  the desired MIME type
170:             *
171:             * @return the content (or the default content), or null if no content
172:             *         of the desired MIME type is available
173:             *
174:             * @see #clearContent
175:             * @see #getFirstContentOfType
176:             * @see #setContent
177:             */
178:            public String getContent(String mimeType) {
179:                String result = null;
180:
181:                initContentMap();
182:                result = contentMap.get(mimeType);
183:                if (result == null)
184:                    result = contentMap.get(DEFAULT_CONTENT_TYPE);
185:
186:                return result;
187:            }
188:
189:            /**
190:             * Get the first content item that matches one of a list of MIME types.
191:             *
192:             * @param mimeTypes  an array of MIME types to match, in order
193:             *
194:             * @return the first matching content string, or null if none was found.
195:             *         Returns the default content (if set), if there's no exact
196:             *         match.
197:             *
198:             * @see #getContent
199:             * @see #clearContent
200:             * @see #setContent
201:             */
202:            public final String getFirstContentOfType(String... mimeTypes) {
203:                String result = null;
204:
205:                initContentMap();
206:                for (int i = 0; i < mimeTypes.length; i++) {
207:                    result = contentMap.get(mimeTypes[i]);
208:                    if (!TextUtil.stringIsEmpty(result))
209:                        break;
210:                }
211:
212:                if (result == null)
213:                    result = contentMap.get(DEFAULT_CONTENT_TYPE);
214:
215:                return result;
216:            }
217:
218:            /**
219:             * Set the content for a specific MIME type. If the
220:             * <tt>isDefault</tt> flag is <tt>true</tt>, then this content
221:             * is served up as the default whenever content for a specific MIME type
222:             * is requested but isn't available.
223:             *
224:             * @param content    the content string
225:             * @param mimeType   the MIME type to associate with the content
226:             *
227:             * @see #getContent
228:             * @see #getFirstContentOfType
229:             * @see #clearContent
230:             */
231:            public void setContent(String content, String mimeType) {
232:                initContentMap();
233:                contentMap.put(mimeType, content);
234:            }
235:
236:            /**
237:             * Clear the stored content for all MIME types, without clearing any
238:             * other fields. (In particular, the summary is not cleared.)
239:             *
240:             * @see #getContent
241:             * @see #getFirstContentOfType
242:             * @see #setContent
243:             */
244:            public void clearContent() {
245:                if (contentMap != null)
246:                    contentMap.clear();
247:            }
248:
249:            /**
250:             * Compare two items for order. The channels are ordered first by
251:             * publication date (if any), then by title, then by unique ID,
252:             * then by hash code (if all else is equal).
253:             *
254:             * @param other  the other object
255:             *
256:             * @return negative number: this item is less than <tt>other</tt>;<br>
257:             *         0: this item is equivalent to <tt>other</tt><br>
258:             *         positive unmber: this item is greater than <tt>other</tt>
259:             */
260:            public int compareTo(Object other) {
261:                RSSItem otherItem = (RSSItem) other;
262:
263:                Date otherDate = otherItem.getPublicationDate();
264:                Date this Date = this .getPublicationDate();
265:                Date now = new Date();
266:
267:                if (otherDate == null)
268:                    otherDate = now;
269:
270:                if (this Date == null)
271:                    this Date = now;
272:
273:                int cmp = this Date.compareTo(otherDate);
274:                if (cmp == 0) {
275:                    String otherTitle = otherItem.getTitle();
276:                    String this Title = this .getTitle();
277:
278:                    if (otherTitle == null)
279:                        otherTitle = "";
280:
281:                    if (this Title == null)
282:                        this Title = "";
283:
284:                    if ((cmp = this Title.compareTo(otherTitle)) == 0) {
285:                        String otherID = otherItem.getID();
286:                        String this ID = this .getID();
287:
288:                        if (otherID == null)
289:                            otherID = "";
290:
291:                        if (this ID == null)
292:                            this ID = "";
293:
294:                        if ((cmp = this ID.compareTo(otherID)) == 0)
295:                            cmp = this .hashCode() - other.hashCode();
296:                    }
297:                }
298:
299:                return cmp;
300:            }
301:
302:            /**
303:             * Generate a hash code for this item.
304:             *
305:             * @return the hash code
306:             */
307:            @Override
308:            public int hashCode() {
309:                int hc;
310:                String id = getIdentifier();
311:
312:                if (id == null)
313:                    hc = super .hashCode();
314:                else
315:                    hc = id.hashCode();
316:
317:                return hc;
318:            }
319:
320:            /**
321:             * Compare this item to some other object for equality.
322:             *
323:             * @param o the object
324:             *
325:             * @return <tt>true</tt> if the objects are equal, <tt>false</tt> if not
326:             */
327:            @Override
328:            public boolean equals(Object o) {
329:                boolean eq = false;
330:
331:                if (o instanceof  RSSItem)
332:                    eq = getIdentifier().equals(((RSSItem) o).getIdentifier());
333:
334:                return eq;
335:            }
336:
337:            /**
338:             * Return the string value of the item (which, right now, is its
339:             * title).
340:             *
341:             * @return the title
342:             */
343:            @Override
344:            public String toString() {
345:                return getIdentifier();
346:            }
347:
348:            /*----------------------------------------------------------------------*\
349:                                  Public Abstract Methods
350:            \*----------------------------------------------------------------------*/
351:
352:            /**
353:             * Create a new, empty instance of the underlying concrete
354:             * class.
355:             *
356:             * @param channel  the parent channel
357:             *
358:             * @return the new instance
359:             */
360:            public abstract RSSItem newInstance(RSSChannel channel);
361:
362:            /**
363:             * Get the parent channel
364:             *
365:             * @return the parent channel
366:             */
367:            public abstract RSSChannel getParentChannel();
368:
369:            /**
370:             * Get the item's title
371:             *
372:             * @return the item's title, or null if there isn't one
373:             *
374:             * @see #setTitle
375:             */
376:            public abstract String getTitle();
377:
378:            /**
379:             * Set the item's title
380:             *
381:             * @param newTitle  the item's title, or null if there isn't one
382:             *
383:             * @see #getTitle
384:             */
385:            public abstract void setTitle(String newTitle);
386:
387:            /**
388:             * Get the item's summary (also sometimes called the description or
389:             * synopsis).
390:             *
391:             * @return the summary, or null if not available
392:             *
393:             * @see #setSummary
394:             */
395:            public abstract String getSummary();
396:
397:            /**
398:             * Set the item's summary (also sometimes called the description or
399:             * synopsis).
400:             *
401:             * @param newSummary the summary, or null if not available
402:             *
403:             * @see #getSummary
404:             */
405:            public abstract void setSummary(String newSummary);
406:
407:            /**
408:             * Get the item's author list.
409:             *
410:             * @return the authors, or null (or an empty <tt>Collection</tt>) if
411:             *         not available
412:             *
413:             * @see #addAuthor
414:             * @see #clearAuthors
415:             * @see #setAuthors
416:             */
417:            public abstract Collection<String> getAuthors();
418:
419:            /**
420:             * Add to the item's author list.
421:             *
422:             * @param author  another author string to add
423:             *
424:             * @see #getAuthors
425:             * @see #clearAuthors
426:             * @see #setAuthors
427:             */
428:            public abstract void addAuthor(String author);
429:
430:            /**
431:             * Clear the authors list.
432:             *
433:             * @see #getAuthors
434:             * @see #addAuthor
435:             * @see #setAuthors
436:             */
437:            public abstract void clearAuthors();
438:
439:            /**
440:             * Get the item's published links.
441:             *
442:             * @return the collection of links, or an empty collection
443:             *
444:             * @see #setLinks
445:             */
446:            public abstract Collection<RSSLink> getLinks();
447:
448:            /**
449:             * Set the item's published links.
450:             *
451:             * @param links the collection of links, or an empty collection (or null)
452:             *
453:             * @see #getLinks
454:             */
455:            public abstract void setLinks(Collection<RSSLink> links);
456:
457:            /**
458:             * Get the categories the item belongs to.
459:             *
460:             * @return a <tt>Collection</tt> of category strings (<tt>String</tt>
461:             *         objects) or null if not applicable
462:             *
463:             * @see #setCategories
464:             */
465:            public abstract Collection<String> getCategories();
466:
467:            /**
468:             * Set the categories the item belongs to.
469:             *
470:             * @param categories a <tt>Collection</tt> of category strings
471:             *                   or null if not applicable
472:             *
473:             * @see #getCategories
474:             */
475:            public abstract void setCategories(Collection<String> categories);
476:
477:            /**
478:             * Get the item's publication date.
479:             *
480:             * @return the date, or null if not available
481:             *
482:             * @see #getPublicationDate
483:             */
484:            public abstract Date getPublicationDate();
485:
486:            /**
487:             * Set the item's publication date.
488:             *
489:             * @param date  the new date, or null to clear
490:             *
491:             * @see #getPublicationDate
492:             */
493:            public abstract void setPublicationDate(Date date);
494:
495:            /**
496:             * Get the item's ID field, if any.
497:             *
498:             * @return the ID field, or null if not set
499:             *
500:             * @see #setID
501:             */
502:            @Override
503:            public abstract String getID();
504:
505:            /**
506:             * Set the item's ID field, if any.
507:             *
508:             * @param id the ID field, or null
509:             */
510:            public abstract void setID(String id);
511:
512:            /*----------------------------------------------------------------------*\
513:                                      Protected Methods
514:            \*----------------------------------------------------------------------*/
515:
516:            /**
517:             * Get all content associated with this item.
518:             *
519:             * @return a <tt>Collection</tt> of {@link RSSContent} objects
520:             */
521:            protected abstract Collection<RSSContent> getContent();
522:
523:            /**
524:             * Used by {@link #makeCopy}, this method copies any subclass fields
525:             * that aren't visible to this class.
526:             *
527:             * @param toItem  the other {@link RSSItem} into which to copy fields.
528:             *                <tt>item</tt> will have been created by a call to
529:             *                {@link #newInstance}
530:             */
531:            protected abstract void copyPrivateFields(RSSItem toItem);
532:
533:            /*----------------------------------------------------------------------*\
534:                                       Private Methods
535:            \*----------------------------------------------------------------------*/
536:
537:            /**
538:             * Get a unique identifier for this RSSItem. This method will return the
539:             * ID (see getID()), if it's set; otherwise, it'll return the URL. If
540:             * there's no URL, it'll return the title. If there's no title, it returns
541:             * null.
542:             *
543:             * @return a unique identifier
544:             */
545:            private String getIdentifier() {
546:                String id = getID();
547:                if (id == null) {
548:                    RSSLink url = getURL();
549:                    if (url != null)
550:                        id = url.toString();
551:                    else {
552:                        // No URL. Use the hash code of the title, if present.
553:
554:                        id = getTitle();
555:                    }
556:                }
557:
558:                return id;
559:            }
560:
561:            /**
562:             * Initialize the content map.
563:             */
564:            private void initContentMap() {
565:                if (contentMap == null) {
566:                    contentMap = new HashMap<String, String>();
567:
568:                    Collection<RSSContent> content = getContent();
569:                    if ((content != null) && (content.size() > 0)) {
570:                        RSSContent first = null;
571:                        for (RSSContent contentItem : content) {
572:                            contentMap.put(contentItem.getMIMEType(),
573:                                    contentItem.getTextContent());
574:                            if (first == null)
575:                                first = contentItem;
576:                        }
577:
578:                        // The default content is the first one.
579:
580:                        contentMap.put(DEFAULT_CONTENT_TYPE, first
581:                                .getTextContent());
582:                    }
583:                }
584:            }
585:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.