KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > pojos > WeblogEntryData


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. The ASF licenses this file to You
4  * under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. For additional information regarding
15  * copyright in this work, please see the NOTICE file in the top level
16  * directory of this distribution.
17  */

18
19 package org.apache.roller.pojos;
20
21 import java.io.Serializable JavaDoc;
22 import java.io.UnsupportedEncodingException JavaDoc;
23 import java.net.URLEncoder JavaDoc;
24 import java.sql.Timestamp JavaDoc;
25 import java.text.SimpleDateFormat JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Calendar JavaDoc;
29 import java.util.Date JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36 import java.util.TreeSet JavaDoc;
37
38 import org.apache.commons.lang.StringEscapeUtils;
39
40 import org.apache.commons.lang.StringUtils;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.apache.roller.RollerException;
44 import org.apache.roller.config.RollerRuntimeConfig;
45 import org.apache.roller.model.RollerFactory;
46 import org.apache.roller.model.UserManager;
47 import org.apache.roller.model.WeblogEntryPlugin;
48 import org.apache.roller.model.WeblogManager;
49 import org.apache.roller.util.DateUtil;
50 import org.apache.roller.util.MessageUtilities;
51 import org.apache.roller.util.URLUtilities;
52 import org.apache.roller.util.Utilities;
53
54 /**
55  * Represents a Weblog Entry.
56  *
57  * @ejb:bean name="WeblogEntryData"
58  * @struts.form include-all="true"
59  * @hibernate.class lazy="false" table="weblogentry"
60  * @hibernate.cache usage="read-write"
61  */

62 public class WeblogEntryData extends PersistentObject implements Serializable JavaDoc {
63     private static Log mLogger =
64             LogFactory.getFactory().getInstance(WeblogEntryData.class);
65     
66     public static final long serialVersionUID = 2341505386843044125L;
67     
68     public static final String JavaDoc DRAFT = "DRAFT";
69     public static final String JavaDoc PUBLISHED = "PUBLISHED";
70     public static final String JavaDoc PENDING = "PENDING";
71     
72     // Simple properies
73
private String JavaDoc id = null;
74     private String JavaDoc title = null;
75     private String JavaDoc link = null;
76     private String JavaDoc summary = null;
77     private String JavaDoc text = null;
78     private String JavaDoc contentType = null;
79     private String JavaDoc contentSrc = null;
80     private String JavaDoc anchor = null;
81     private Timestamp JavaDoc pubTime = null;
82     private Timestamp JavaDoc updateTime = null;
83     private String JavaDoc plugins = null;
84     private Boolean JavaDoc allowComments = Boolean.TRUE;
85     private Integer JavaDoc commentDays = new Integer JavaDoc(7);
86     private Boolean JavaDoc rightToLeft = Boolean.FALSE;
87     private Boolean JavaDoc pinnedToMain = Boolean.FALSE;
88     private String JavaDoc status = DRAFT;
89     private String JavaDoc locale = null;
90     
91     // Associated objects
92
private UserData creator = null;
93     private WebsiteData website = null;
94     private WeblogCategoryData category = null;
95     
96     // Collection of name/value entry attributes
97
private Map JavaDoc attMap = new HashMap JavaDoc();
98     private Set JavaDoc attSet = new TreeSet JavaDoc();
99     
100     //----------------------------------------------------------- Construction
101

102     public WeblogEntryData() {
103     }
104     
105     public WeblogEntryData(
106             String JavaDoc id,
107             WeblogCategoryData category,
108             WebsiteData website,
109             UserData creator,
110             String JavaDoc title,
111             String JavaDoc link,
112             String JavaDoc text,
113             String JavaDoc anchor,
114             Timestamp JavaDoc pubTime,
115             Timestamp JavaDoc updateTime,
116             String JavaDoc status) {
117         this.id = id;
118         this.category = category;
119         this.website = website;
120         this.creator = creator;
121         this.title = title;
122         this.link = link;
123         this.text = text;
124         this.anchor = anchor;
125         this.pubTime = pubTime;
126         this.updateTime = updateTime;
127         this.status = status;
128     }
129     
130     public WeblogEntryData(WeblogEntryData otherData) {
131         this.setData(otherData);
132     }
133     
134     //---------------------------------------------------------- Initializaion
135

136     /**
137      * Setter is needed in RollerImpl.storePersistentObject()
138      */

139     public void setData(PersistentObject otherData) {
140         WeblogEntryData other = (WeblogEntryData)otherData;
141         
142         this.id = other.getId();
143         this.category = other.getCategory();
144         this.website = other.getWebsite();
145         this.creator = other.getCreator();
146         this.title = other.getTitle();
147         this.link = other.getLink();
148         this.text = other.getText();
149         this.anchor = other.getAnchor();
150         this.pubTime = other.getPubTime();
151         this.updateTime = other.getUpdateTime();
152         this.status = other.getStatus();
153         this.plugins = other.getPlugins();
154         this.allowComments = other.getAllowComments();
155         this.commentDays = other.getCommentDays();
156         this.rightToLeft = other.getRightToLeft();
157         this.pinnedToMain = other.getPinnedToMain();
158     }
159     
160     //------------------------------------------------------ Simple properties
161

162     /**
163      * @roller.wrapPojoMethod type="simple"
164      * @ejb:persistent-field
165      * @hibernate.id column="id" generator-class="uuid.hex" unsaved-value="null"
166      */

167     public String JavaDoc getId() {
168         return this.id;
169     }
170     
171     /** @ejb:persistent-field */
172     public void setId(String JavaDoc id) {
173         this.id = id;
174     }
175     
176     /**
177      * @roller.wrapPojoMethod type="pojo"
178      * @ejb:persistent-field
179      * @hibernate.many-to-one column="categoryid" cascade="none" not-null="true"
180      */

181     public WeblogCategoryData getCategory() {
182         return this.category;
183     }
184     
185     /** @ejb:persistent-field */
186     public void setCategory(WeblogCategoryData category) {
187         this.category = category;
188     }
189     
190     /**
191      * Set weblog category via weblog category ID.
192      * @param id Weblog category ID.
193      */

194     public void setCategoryId(String JavaDoc id) throws RollerException {
195         WeblogManager wmgr = RollerFactory.getRoller().getWeblogManager();
196         setCategory(wmgr.getWeblogCategory(id));
197     }
198     
199     /**
200      * Return collection of WeblogCategoryData objects of this entry.
201      * Added for symetry with PlanetEntryData object.
202      * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.pojos.WeblogCategoryData"
203      */

204     public List JavaDoc getCategories() {
205         List JavaDoc cats = new ArrayList JavaDoc();
206         cats.add(getCategory());
207         return cats;
208     }
209     
210     /** No-op method to please XDoclet */
211     public void setCategories(List JavaDoc cats) {
212         // no-op
213
}
214     
215     /**
216      * @roller.wrapPojoMethod type="pojo"
217      * @ejb:persistent-field
218      * @hibernate.many-to-one column="websiteid" cascade="none" not-null="true"
219      */

220     public WebsiteData getWebsite() {
221         return this.website;
222     }
223     
224     /** @ejb:persistent-field */
225     public void setWebsite(WebsiteData website) {
226         this.website = website;
227     }
228     
229     /**
230      * @roller.wrapPojoMethod type="simple"
231      * @ejb:persistent-field
232      * @hibernate.many-to-one column="userid" cascade="none" not-null="true"
233      */

234     public UserData getCreator() {
235         return this.creator;
236     }
237     
238     /** @ejb:persistent-field */
239     public void setCreator(UserData creator) {
240         this.creator = creator;
241     }
242     
243     /**
244      * @roller.wrapPojoMethod type="simple"
245      * @ejb:persistent-field
246      * @hibernate.property column="title" non-null="true" unique="false"
247      */

248     public String JavaDoc getTitle() {
249         return this.title;
250     }
251     
252     /** @ejb:persistent-field */
253     public void setTitle(String JavaDoc title) {
254         this.title = title;
255     }
256     
257     /**
258      * Get summary for weblog entry (maps to RSS description and Atom summary).
259      * @roller.wrapPojoMethod type="simple"
260      * @ejb:persistent-field
261      * @hibernate.property column="summary" non-null="false" unique="false"
262      */

263     public String JavaDoc getSummary() {
264         return summary;
265     }
266     
267     /**
268      * Set summary for weblog entry (maps to RSS description and Atom summary).
269      * @ejb:persistent-field
270      */

271     public void setSummary(String JavaDoc summary) {
272         this.summary = summary;
273     }
274     
275     /**
276      * Get content text for weblog entry (maps to RSS content:encoded and Atom content).
277      * @roller.wrapPojoMethod type="simple"
278      * @ejb:persistent-field
279      * @hibernate.property column="text" non-null="true" unique="false"
280      */

281     public String JavaDoc getText() {
282         return this.text;
283     }
284     
285     /**
286      * Set content text for weblog entry (maps to RSS content:encoded and Atom content).
287      * @ejb:persistent-field
288      */

289     public void setText(String JavaDoc text) {
290         this.text = text;
291     }
292     
293     /**
294      * Get content type (text, html, xhtml or a MIME content type)
295      * @roller.wrapPojoMethod type="simple"
296      * @ejb:persistent-field
297      * @hibernate.property column="content_type" non-null="false" unique="false"
298      */

299     public String JavaDoc getContentType() {
300         return contentType;
301     }
302     
303     /**
304      * Set content type (text, html, xhtml or a MIME content type)
305      * @ejb:persistent-field
306      */

307     public void setContentType(String JavaDoc contentType) {
308         this.contentType = contentType;
309     }
310     
311     /**
312      * Get URL for out-of-line content.
313      * @roller.wrapPojoMethod type="simple"
314      * @ejb:persistent-field
315      * @hibernate.property column="content_src" non-null="false" unique="false"
316      */

317     public String JavaDoc getContentSrc() {
318         return contentSrc;
319     }
320     
321     /**
322      * Set URL for out-of-line content.
323      * @ejb:persistent-field
324      */

325     public void setContentSrc(String JavaDoc contentSrc) {
326         this.contentSrc = contentSrc;
327     }
328     
329     /**
330      * @roller.wrapPojoMethod type="simple"
331      * @ejb:persistent-field
332      * @hibernate.property column="anchor" non-null="true" unique="false"
333      */

334     public String JavaDoc getAnchor() {
335         return this.anchor;
336     }
337     
338     /** @ejb:persistent-field */
339     public void setAnchor(String JavaDoc anchor) {
340         this.anchor = anchor;
341     }
342     
343     //-------------------------------------------------------------------------
344
/**
345      * Map attributes as set because XDoclet 1.2b4 map support is broken.
346      *
347      * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.pojos.EntryAttributeData"
348      * @ejb:persistent-field
349      * @hibernate.set lazy="true" order-by="name" inverse="true" cascade="all-delete-orphan"
350      * @hibernate.collection-key column="entryid" type="String"
351      * @hibernate.collection-one-to-many class="org.apache.roller.pojos.EntryAttributeData"
352      */

353     public Set JavaDoc getEntryAttributes() {
354         return attSet;
355     }
356     /** @ejb:persistent-field */
357     public void setEntryAttributes(Set JavaDoc attSet) {
358         this.attSet = attSet;
359         
360         // copy set to map
361
if (attSet != null) {
362             this.attSet = attSet;
363             this.attMap = new HashMap JavaDoc();
364             Iterator JavaDoc iter = this.attSet.iterator();
365             while (iter.hasNext()) {
366                 EntryAttributeData att = (EntryAttributeData)iter.next();
367                 attMap.put(att.getName(), att);
368             }
369         } else {
370             this.attSet = new TreeSet JavaDoc();
371             this.attMap = new HashMap JavaDoc();
372         }
373     }
374     
375     
376     /**
377      * Would be named getEntryAttribute, but that would set off XDoclet
378      *
379      * @roller.wrapPojoMethod type="simple"
380      */

381     public String JavaDoc findEntryAttribute(String JavaDoc name) {
382         EntryAttributeData att = ((EntryAttributeData)attMap.get(name));
383         return (att != null) ? att.getValue() : null;
384     }
385     
386     
387     public void putEntryAttribute(String JavaDoc name, String JavaDoc value) throws Exception JavaDoc {
388         EntryAttributeData att = (EntryAttributeData)attMap.get(name);
389         if (att == null) {
390             att = new EntryAttributeData();
391             att.setEntry(this);
392             att.setName(name);
393             att.setValue(value);
394             attMap.put(name, att);
395             attSet.add(att);
396         } else {
397             att.setValue(value);
398         }
399     }
400     public void removeEntryAttribute(String JavaDoc name) throws RollerException {
401         EntryAttributeData att = (EntryAttributeData)attMap.get(name);
402         if (att != null) {
403             attMap.remove(att);
404             attSet.remove(att);
405         }
406     }
407     //-------------------------------------------------------------------------
408

409     /**
410      * <p>Publish time is the time that an entry is to be (or was) made available
411      * for viewing by newsfeed readers and visitors to the Roller site.</p>
412      *
413      * <p>Roller stores time using the timeZone of the server itself. When
414      * times are displayed in a user's weblog they must be translated
415      * to the user's timeZone.</p>
416      *
417      * <p>NOTE: Times are stored using the SQL TIMESTAMP datatype, which on
418      * MySQL has only a one-second resolution.</p>
419      *
420      * @roller.wrapPojoMethod type="simple"
421      * @ejb:persistent-field
422      * @hibernate.property column="pubtime" non-null="true" unique="false"
423      */

424     public Timestamp JavaDoc getPubTime() {
425         return this.pubTime;
426     }
427     
428     /** @ejb:persistent-field */
429     public void setPubTime(Timestamp JavaDoc pubTime) {
430         this.pubTime = pubTime;
431     }
432     
433     /**
434      * <p>Update time is the last time that an weblog entry was saved in the
435      * Roller weblog editor or via web services API (XML-RPC or Atom).</p>
436      *
437      * <p>Roller stores time using the timeZone of the server itself. When
438      * times are displayed in a user's weblog they must be translated
439      * to the user's timeZone.</p>
440      *
441      * <p>NOTE: Times are stored using the SQL TIMESTAMP datatype, which on
442      * MySQL has only a one-second resolution.</p>
443      *
444      * @roller.wrapPojoMethod type="simple"
445      * @ejb:persistent-field
446      * @hibernate.property column="updatetime" non-null="true" unique="false"
447      */

448     public Timestamp JavaDoc getUpdateTime() {
449         return this.updateTime;
450     }
451     
452     /** @ejb:persistent-field */
453     public void setUpdateTime(Timestamp JavaDoc updateTime) {
454         this.updateTime = updateTime;
455     }
456     
457     /**
458      * @roller.wrapPojoMethod type="simple"
459      * @ejb:persistent-field
460      * @hibernate.property column="status" non-null="true" unique="false"
461      */

462     public String JavaDoc getStatus() {
463         return this.status;
464     }
465     
466     /** @ejb:persistent-field */
467     public void setStatus(String JavaDoc status) {
468         this.status = status;
469     }
470     
471     /**
472      * Some weblog entries are about one specific link.
473      * @return Returns the link.
474      *
475      * @roller.wrapPojoMethod type="simple"
476      * @ejb:persistent-field
477      * @hibernate.property column="link" non-null="false" unique="false"
478      */

479     public String JavaDoc getLink() {
480         return link;
481     }
482     
483     /**
484      * @ejb:persistent-field
485      * @param link The link to set.
486      */

487     public void setLink(String JavaDoc link) {
488         this.link = link;
489     }
490     
491     /**
492      * Comma-delimited list of this entry's Plugins.
493      *
494      * @roller.wrapPojoMethod type="simple"
495      * @ejb:persistent-field
496      * @hibernate.property column="plugins" non-null="false" unique="false"
497      */

498     public String JavaDoc getPlugins() {
499         return plugins;
500     }
501     
502     /** @ejb:persistent-field */
503     public void setPlugins(String JavaDoc string) {
504         plugins = string;
505     }
506     
507     
508     /**
509      * True if comments are allowed on this weblog entry.
510      *
511      * @roller.wrapPojoMethod type="simple"
512      * @ejb:persistent-field
513      * @hibernate.property column="allowcomments" non-null="true" unique="false"
514      */

515     public Boolean JavaDoc getAllowComments() {
516         return allowComments;
517     }
518     /**
519      * True if comments are allowed on this weblog entry.
520      * @ejb:persistent-field
521      */

522     public void setAllowComments(Boolean JavaDoc allowComments) {
523         this.allowComments = allowComments;
524     }
525     
526     /**
527      * Number of days after pubTime that comments should be allowed, or 0 for no limit.
528      *
529      * @roller.wrapPojoMethod type="simple"
530      * @ejb:persistent-field
531      * @hibernate.property column="commentdays" non-null="true" unique="false"
532      */

533     public Integer JavaDoc getCommentDays() {
534         return commentDays;
535     }
536     /**
537      * Number of days after pubTime that comments should be allowed, or 0 for no limit.
538      * @ejb:persistent-field
539      */

540     public void setCommentDays(Integer JavaDoc commentDays) {
541         this.commentDays = commentDays;
542     }
543     
544     /**
545      * True if this entry should be rendered right to left.
546      *
547      * @roller.wrapPojoMethod type="simple"
548      * @ejb:persistent-field
549      * @hibernate.property column="righttoleft" non-null="true" unique="false"
550      */

551     public Boolean JavaDoc getRightToLeft() {
552         return rightToLeft;
553     }
554     /**
555      * True if this entry should be rendered right to left.
556      * @ejb:persistent-field
557      */

558     public void setRightToLeft(Boolean JavaDoc rightToLeft) {
559         this.rightToLeft = rightToLeft;
560     }
561     
562     /**
563      * True if story should be pinned to the top of the Roller site main blog.
564      * @return Returns the pinned.
565      *
566      * @roller.wrapPojoMethod type="simple"
567      * @ejb:persistent-field
568      * @hibernate.property column="pinnedtomain" non-null="true" unique="false"
569      */

570     public Boolean JavaDoc getPinnedToMain() {
571         return pinnedToMain;
572     }
573     /**
574      * True if story should be pinned to the top of the Roller site main blog.
575      * @param pinnedToMain The pinned to set.
576      *
577      * @ejb:persistent-field
578      */

579     public void setPinnedToMain(Boolean JavaDoc pinnedToMain) {
580         this.pinnedToMain = pinnedToMain;
581     }
582     
583     
584     /**
585      * The locale string that defines the i18n approach for this entry.
586      *
587      * @roller.wrapPojoMethod type="simple"
588      * @ejb:persistent-field
589      * @hibernate.property column="locale" non-null="false" unique="false"
590      */

591     public String JavaDoc getLocale() {
592         return locale;
593     }
594     
595     
596     public void setLocale(String JavaDoc locale) {
597         this.locale = locale;
598     }
599     
600     
601     //------------------------------------------------------------------------
602

603     /**
604      * True if comments are still allowed on this entry considering the
605      * allowComments and commentDays fields as well as the website and
606      * site-wide configs.
607      *
608      * @roller.wrapPojoMethod type="simple"
609      */

610     public boolean getCommentsStillAllowed() {
611         if(DRAFT.equals(this.status) || PENDING.equals(this.status)) {
612             return false;
613         }
614         if (!RollerRuntimeConfig.getBooleanProperty("users.comments.enabled")) {
615             return false;
616         }
617         if (website.getAllowComments() != null && !website.getAllowComments().booleanValue()) {
618             return false;
619         }
620         if (getAllowComments() != null && !getAllowComments().booleanValue()) {
621             return false;
622         }
623         boolean ret = false;
624         if (getCommentDays() == null || getCommentDays().intValue() == 0) {
625             ret = true;
626         } else {
627             Calendar JavaDoc expireCal = Calendar.getInstance(
628                     getWebsite().getLocaleInstance());
629             expireCal.setTime(getPubTime());
630             expireCal.add(Calendar.DATE, getCommentDays().intValue());
631             Date JavaDoc expireDay = expireCal.getTime();
632             Date JavaDoc today = new Date JavaDoc();
633             if (today.before(expireDay)) {
634                 ret = true;
635             }
636         }
637         return ret;
638     }
639     public void setCommentsStillAllowed(boolean ignored) {
640         // no-op
641
}
642     
643     
644     //------------------------------------------------------------------------
645

646     /**
647      * Format the publish time of this weblog entry using the specified pattern.
648      * See java.text.SimpleDateFormat for more information on this format.
649      *
650      * @roller.wrapPojoMethod type="simple"
651      * @see java.text.SimpleDateFormat
652      * @return Publish time formatted according to pattern.
653      */

654     public String JavaDoc formatPubTime(String JavaDoc pattern) {
655         try {
656             SimpleDateFormat JavaDoc format = new SimpleDateFormat JavaDoc(pattern,
657                     this.getWebsite().getLocaleInstance());
658             
659             return format.format(getPubTime());
660         } catch (RuntimeException JavaDoc e) {
661             mLogger.error("Unexpected exception", e);
662         }
663         
664         return "ERROR: formatting date";
665     }
666     
667     //------------------------------------------------------------------------
668

669     /**
670      * Format the update time of this weblog entry using the specified pattern.
671      * See java.text.SimpleDateFormat for more information on this format.
672      *
673      * @roller.wrapPojoMethod type="simple"
674      * @see java.text.SimpleDateFormat
675      * @return Update time formatted according to pattern.
676      */

677     public String JavaDoc formatUpdateTime(String JavaDoc pattern) {
678         try {
679             SimpleDateFormat JavaDoc format = new SimpleDateFormat JavaDoc(pattern);
680             
681             return format.format(getUpdateTime());
682         } catch (RuntimeException JavaDoc e) {
683             mLogger.error("Unexpected exception", e);
684         }
685         
686         return "ERROR: formatting date";
687     }
688     
689     //------------------------------------------------------------------------
690

691     /**
692      * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.pojos.CommentData"
693      */

694     public List JavaDoc getComments() {
695         return getComments(true, true);
696     }
697     
698     /**
699      * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.pojos.CommentData"
700      */

701     public List JavaDoc getComments(boolean ignoreSpam, boolean approvedOnly) {
702         List JavaDoc list = new ArrayList JavaDoc();
703         try {
704             WeblogManager wmgr = RollerFactory.getRoller().getWeblogManager();
705             return wmgr.getComments(
706                     getWebsite(),
707                     this,
708                     null, // search String
709
null, // startDate
710
null, // endDate
711
null, // pending
712
approvedOnly ? Boolean.TRUE : null, // approved
713
ignoreSpam ? Boolean.FALSE : null, // spam
714
false, // we want chrono order
715
0, // offset
716
-1); // no limit
717
} catch (RollerException alreadyLogged) {}
718         return list;
719     }
720     
721     /**
722      * @roller.wrapPojoMethod type="simple"
723      */

724     public int getCommentCount() {
725         List JavaDoc comments = getComments(true, true);
726         return comments.size();
727     }
728     
729     /** No-op to please XDoclet */
730     public void setCommentCount(int ignored) {
731         // no-op
732
}
733     
734     //------------------------------------------------------------------------
735

736     /**
737      * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.pojos.RefererData"
738      */

739     public List JavaDoc getReferers() {
740         List JavaDoc referers = null;
741         try {
742             referers = RollerFactory.getRoller().getRefererManager().getReferersToEntry(getId());
743         } catch (RollerException e) {
744             mLogger.error("Unexpected exception", e);
745         }
746         return referers;
747     }
748     
749     //------------------------------------------------------------------------
750

751     /**
752      * Returns absolute entry permalink.
753      * @roller.wrapPojoMethod type="simple"
754      */

755     public String JavaDoc getPermalink() {
756         return URLUtilities.getWeblogEntryURL(getWebsite(), null, anchor, true);
757     }
758     
759     /**
760      * Returns entry permalink, relative to Roller context.
761      * @deprecated Use getPermalink() instead.
762      * @roller.wrapPojoMethod type="simple"
763      */

764     public String JavaDoc getPermaLink() {
765         String JavaDoc lAnchor = this.getAnchor();
766         try {
767             lAnchor = URLEncoder.encode(anchor, "UTF-8");
768         } catch (UnsupportedEncodingException JavaDoc e) {
769             // go with the "no encoding" version
770
}
771         WebsiteData website = this.getWebsite();
772         return "/" + getWebsite().getHandle() + "/entry/" + lAnchor;
773     }
774     
775     /**
776      * Get relative URL to comments page.
777      * @roller.wrapPojoMethod type="simple"
778      * @deprecated Use commentLink() instead
779      */

780     public String JavaDoc getCommentsLink() {
781         return getPermaLink() + "#comments";
782     }
783     
784     /**
785      * to please XDoclet
786      * @deprecated Use commentLink() instead
787      */

788     public void setCommentsLink(String JavaDoc ignored) {}
789     
790     
791     /**
792      * Return the Title of this post, or the first 255 characters of the
793      * entry's text.
794      *
795      * @roller.wrapPojoMethod type="simple"
796      * @return String
797      */

798     public String JavaDoc getDisplayTitle() {
799         if ( getTitle()==null || getTitle().trim().equals("") ) {
800             return StringUtils.left(Utilities.removeHTML(text),255);
801         }
802         return Utilities.removeHTML(getTitle());
803     }
804     
805     //------------------------------------------------------------------------
806

807     public String JavaDoc toString() {
808         StringBuffer JavaDoc str = new StringBuffer JavaDoc("{");
809         
810         str.append("id=" + id + " " +
811                 "category=" + category + " " +
812                 "title=" + title + " " +
813                 "text=" + text + " " +
814                 "anchor=" + anchor + " " +
815                 "pubTime=" + pubTime + " " +
816                 "updateTime=" + updateTime + " " +
817                 "status=" + status + " " +
818                 "plugins=" + plugins);
819         str.append('}');
820         
821         return (str.toString());
822     }
823     
824     //------------------------------------------------------------------------
825

826     public boolean equals(Object JavaDoc pOther) {
827         if (pOther instanceof WeblogEntryData) {
828             WeblogEntryData lTest = (WeblogEntryData) pOther;
829             boolean lEquals = true;
830             
831             if (this.id == null) {
832                 lEquals = lEquals && (lTest.getId() == null);
833             } else {
834                 lEquals = lEquals && this.id.equals(lTest.getId());
835             }
836             
837             if (this.category == null) {
838                 lEquals = lEquals && (lTest.getCategory() == null);
839             } else {
840                 lEquals = lEquals && this.category.equals(lTest.getCategory());
841             }
842             
843             if (this.website == null) {
844                 lEquals = lEquals && (lTest.getWebsite() == null);
845             } else {
846                 lEquals = lEquals && this.website.equals(lTest.getWebsite());
847             }
848             
849             if (this.title == null) {
850                 lEquals = lEquals && (lTest.getTitle() == null);
851             } else {
852                 lEquals = lEquals && this.title.equals(lTest.getTitle());
853             }
854             
855             if (this.text == null) {
856                 lEquals = lEquals && (lTest.getText() == null);
857             } else {
858                 lEquals = lEquals && this.text.equals(lTest.getText());
859             }
860             
861             if (this.anchor == null) {
862                 lEquals = lEquals && (lTest.getAnchor() == null);
863             } else {
864                 lEquals = lEquals && this.anchor.equals(lTest.getAnchor());
865             }
866             
867             if (this.pubTime == null) {
868                 lEquals = lEquals && (lTest.getPubTime() == null);
869             } else {
870                 lEquals = lEquals && this.pubTime.equals(lTest.getPubTime());
871             }
872             
873             if (this.updateTime == null) {
874                 lEquals = lEquals && (lTest.getUpdateTime() == null);
875             } else {
876                 lEquals = lEquals &&
877                         this.updateTime.equals(lTest.getUpdateTime());
878             }
879             
880             if (this.status == null) {
881                 lEquals = lEquals && (lTest.getStatus() == null);
882             } else {
883                 lEquals = lEquals &&
884                         this.status.equals(lTest.getStatus());
885             }
886             
887             if (this.plugins == null) {
888                 lEquals = lEquals && (lTest.getPlugins() == null);
889             } else {
890                 lEquals = lEquals &&
891                         this.plugins.equals(lTest.getPlugins());
892             }
893             
894             
895             return lEquals;
896         } else {
897             return false;
898         }
899     }
900     
901     //------------------------------------------------------------------------
902

903     public int hashCode() {
904         int result = 17;
905         result = (37 * result) +
906                 ((this.id != null) ? this.id.hashCode() : 0);
907         result = (37 * result) +
908                 ((this.category != null) ? this.category.hashCode() : 0);
909         result = (37 * result) +
910                 ((this.website != null) ? this.website.hashCode() : 0);
911         result = (37 * result) +
912                 ((this.title != null) ? this.title.hashCode() : 0);
913         result = (37 * result) +
914                 ((this.text != null) ? this.text.hashCode() : 0);
915         result = (37 * result) +
916                 ((this.anchor != null) ? this.anchor.hashCode() : 0);
917         result = (37 * result) +
918                 ((this.pubTime != null) ? this.pubTime.hashCode() : 0);
919         result = (37 * result) +
920                 ((this.updateTime != null) ? this.updateTime.hashCode() : 0);
921         result = (37 * result) +
922                 ((this.status != null) ? this.status.hashCode() : 0);
923         result = (37 * result) +
924                 ((this.plugins != null) ? this.plugins.hashCode() : 0);
925         
926         return result;
927     }
928     
929     /**
930      * Return RSS 09x style description (escaped HTML version of entry text)
931      *
932      * @roller.wrapPojoMethod type="simple"
933      */

934     public String JavaDoc getRss09xDescription() {
935         return getRss09xDescription(-1);
936     }
937     
938     /**
939      * Return RSS 09x style description (escaped HTML version of entry text)
940      *
941      * @roller.wrapPojoMethod type="simple"
942      */

943     public String JavaDoc getRss09xDescription(int maxLength) {
944         String JavaDoc ret = StringEscapeUtils.escapeHtml(text);
945         if (maxLength != -1 && ret.length() > maxLength) {
946             ret = ret.substring(0,maxLength-3)+"...";
947         }
948         return ret;
949     }
950     
951     /** Create anchor for weblog entry, based on title or text */
952     protected String JavaDoc createAnchor() throws RollerException {
953         return RollerFactory.getRoller().getWeblogManager().createAnchor(this);
954     }
955     
956     /** Create anchor for weblog entry, based on title or text */
957     public String JavaDoc createAnchorBase() {
958         
959         // Use title or text for base anchor
960
String JavaDoc base = getTitle();
961         if (base != null) {
962             base = Utilities.replaceNonAlphanumeric(base, ' ');
963             if (StringUtils.isEmpty(base.trim())) {
964                 base = getText();
965                 if (base != null) {
966                     base = Utilities.replaceNonAlphanumeric(base, ' ');
967                 }
968             }
969         }
970
971         if (StringUtils.isEmpty(base.trim())) {
972             
973             // Use only the first 4 words
974
StringTokenizer JavaDoc toker = new StringTokenizer JavaDoc(base);
975             String JavaDoc tmp = null;
976             int count = 0;
977             while (toker.hasMoreTokens() && count < 5) {
978                 String JavaDoc s = toker.nextToken();
979                 s = s.toLowerCase();
980                 tmp = (tmp == null) ? s : tmp + "_" + s;
981                 count++;
982             }
983             base = tmp;
984         }
985         // No title or text, so instead we will use the items date
986
// in YYYYMMDD format as the base anchor
987
else {
988             base = DateUtil.format8chars(getPubTime());
989         }
990         
991         return base;
992     }
993     
994     /**
995      * A no-op. TODO: fix formbean generation so this is not needed.
996      */

997     public void setPermalink(String JavaDoc string) {}
998     
999     /**
1000     * A no-op. TODO: fix formbean generation so this is not needed.
1001     */

1002    public void setPermaLink(String JavaDoc string) {}
1003    
1004    /**
1005     * A no-op.
1006     * TODO: fix formbean generation so this is not needed.
1007     * @param string
1008     */

1009    public void setDisplayTitle(String JavaDoc string) {
1010    }
1011    
1012    /**
1013     * A no-op.
1014     * TODO: fix formbean generation so this is not needed.
1015     * @param string
1016     */

1017    public void setRss09xDescription(String JavaDoc string) {
1018    }
1019    
1020    
1021    /**
1022     * Convenience method to transform mPlugins to a List
1023     *
1024     * @roller.wrapPojoMethod type="simple"
1025     * @return
1026     */

1027    public List JavaDoc getPluginsList() {
1028        if (plugins != null) {
1029            return Arrays.asList( StringUtils.split(plugins, ",") );
1030        }
1031        return new ArrayList JavaDoc();
1032    }
1033    
1034    /**
1035     * Set creator by user id (for use in form's copyTo method)
1036     * @param creatorId
1037     */

1038    public void setCreatorId(String JavaDoc creatorId) throws RollerException {
1039        UserManager umgr = RollerFactory.getRoller().getUserManager();
1040        setCreator(umgr.getUser(creatorId));
1041    }
1042    
1043    /** Convenience method for checking status */
1044    public boolean isDraft() {
1045        return status.equals(DRAFT);
1046    }
1047    /** no-op: needed only to satisfy XDoclet, use setStatus() instead */
1048    public void setDraft(boolean value) {
1049    }
1050    
1051    /** Convenience method for checking status */
1052    public boolean isPending() {
1053        return status.equals(PENDING);
1054    }
1055    /** no-op: needed only to satisfy XDoclet, use setStatus() instead */
1056    public void setPending(boolean value) {
1057    }
1058    
1059    /** Convenience method for checking status */
1060    public boolean isPublished() {
1061        return status.equals(PUBLISHED);
1062    }
1063    /** no-op: needed only to satisfy XDoclet, use setStatus() instead */
1064    public void setPublished(boolean value) {
1065    }
1066  
1067    /**
1068     * Get entry text, transformed by plugins enabled for entry.
1069     * @roller.wrapPojoMethod type="simple"
1070     */

1071    public String JavaDoc getTransformedText() {
1072        return render(text);
1073    }
1074    /**
1075     * No-op to please XDoclet.
1076     */

1077    public void setTransformedText(String JavaDoc t) {
1078        // no-op
1079
}
1080    
1081    /**
1082     * Get entry summary, transformed by plugins enabled for entry.
1083     * @roller.wrapPojoMethod type="simple"
1084     */

1085    public String JavaDoc getTransformedSummary() {
1086        return render(summary);
1087    }
1088    /**
1089     * No-op to please XDoclet.
1090     */

1091    public void setTransformedSummary(String JavaDoc t) {
1092        // no-op
1093
}
1094    
1095    /**
1096     * Determine if the specified user has permissions to edit this entry.
1097     */

1098    public boolean hasWritePermissions(UserData user) throws RollerException {
1099        
1100        // global admins can hack whatever they want
1101
if(user.hasRole("admin")) {
1102            return true;
1103        }
1104        
1105        boolean author = getWebsite().hasUserPermissions(
1106                user, (short)(PermissionsData.AUTHOR));
1107        boolean limited = getWebsite().hasUserPermissions(
1108                user, (short)(PermissionsData.LIMITED));
1109        
1110        if (author || (limited && isDraft()) || (limited && isPending())) {
1111            return true;
1112        }
1113        
1114        return false;
1115    }
1116    
1117    /**
1118     * Transform string based on plugins enabled for this weblog entry.
1119     */

1120    private String JavaDoc render(String JavaDoc str) {
1121        String JavaDoc ret = str;
1122        mLogger.debug("Applying page plugins to string");
1123        Map JavaDoc plugins = this.website.getInitializedPlugins();
1124        if (str != null && plugins != null) {
1125            List JavaDoc entryPlugins = getPluginsList();
1126            
1127            // if no Entry plugins, don't bother looping.
1128
if (entryPlugins != null && !entryPlugins.isEmpty()) {
1129                
1130                // now loop over mPagePlugins, matching
1131
// against Entry plugins (by name):
1132
// where a match is found render Plugin.
1133
Iterator JavaDoc iter = plugins.keySet().iterator();
1134                while (iter.hasNext()) {
1135                    String JavaDoc key = (String JavaDoc)iter.next();
1136                    if (entryPlugins.contains(key)) {
1137                        WeblogEntryPlugin pagePlugin = (WeblogEntryPlugin)plugins.get(key);
1138                        try {
1139                            ret = pagePlugin.render(this, ret);
1140                        } catch (Throwable JavaDoc t) {
1141                            mLogger.error("ERROR from plugin: " + pagePlugin.getName(), t);
1142                        }
1143                    }
1144                }
1145            }
1146        }
1147        return ret;
1148    }
1149    
1150    
1151    /**
1152     * Get the right transformed display content depending on the situation.
1153     *
1154     * If the readMoreLink is specified then we assume the caller wants to
1155     * prefer summary over content and we include a "Read More" link at the
1156     * end of the summary if it exists. Otherwise, if the readMoreLink is
1157     * empty or null then we assume the caller prefers content over summary.
1158     *
1159     * @roller.wrapPojoMethod type="simple"
1160     */

1161    public String JavaDoc displayContent(String JavaDoc readMoreLink) {
1162        
1163        String JavaDoc displayContent = null;
1164        
1165        if(readMoreLink == null || readMoreLink.trim().length() < 1 ||
1166                "nil".equals(readMoreLink)) {
1167            
1168            // no readMore link means permalink, so prefer text over summary
1169
if(StringUtils.isNotEmpty(this.getText())) {
1170                displayContent = this.getTransformedText();
1171            } else {
1172                displayContent = this.getTransformedSummary();
1173            }
1174        } else {
1175            // not a permalink, so prefer summary over text
1176
// include a "read more" link if needed
1177
if(StringUtils.isNotEmpty(this.getSummary())) {
1178                displayContent = this.getTransformedSummary();
1179                if(StringUtils.isNotEmpty(this.getText())) {
1180                    // add read more
1181
List JavaDoc args = new ArrayList JavaDoc();
1182                    args.add(readMoreLink);
1183                    String JavaDoc readMore = MessageUtilities.getString("macro.weblog.readMoreLink", args);
1184                    
1185                    displayContent += readMore;
1186                }
1187            } else {
1188                displayContent = this.getTransformedText();
1189            }
1190        }
1191        
1192        return displayContent;
1193    }
1194    
1195    
1196    /**
1197     * Get the right transformed display content.
1198     *
1199     * @roller.wrapPojoMethod type="simple"
1200     */

1201    public String JavaDoc getDisplayContent() {
1202        return displayContent(null);
1203    }
1204    
1205    
1206    /** No-op method to please XDoclet */
1207    public void setDisplayContent(String JavaDoc ignored) {}
1208    
1209}
1210
Popular Tags