001: /*
002: * Created on Jan 31, 2005
003: *
004: */
005: package net.sf.thingamablog.generator;
006:
007: import java.util.ArrayList;
008: import java.util.Calendar;
009: import java.util.Date;
010: import java.util.Hashtable;
011: import java.util.List;
012: import java.util.Vector;
013:
014: import net.sf.thingamablog.blog.ArchiveRange;
015: import net.sf.thingamablog.blog.Author;
016: import net.sf.thingamablog.blog.BackendException;
017: import net.sf.thingamablog.blog.BlogEntry;
018: import net.sf.thingamablog.blog.EntryEnumeration;
019: import net.sf.thingamablog.blog.TBWeblog;
020: import net.sf.thingamablog.blog.WeblogBackend;
021:
022: /**
023: * @author Owner
024: *
025: */
026: public class BlogEntryContainer extends ListContainer {
027: /** Constant for front page entries */
028: public static final int FRONT_PAGE = 0;
029:
030: /** Constant for the feed */
031: public static final int RSS_PAGE = 3;
032:
033: /** Constant indicating an archive page */
034: public static final int ARC_PAGE = 1;
035:
036: /** Constant indicating a category page */
037: public static final int CAT_PAGE = 2;
038:
039: public static final int ENTRY_PAGE = 4;
040:
041: /** The name of the container */
042: public static final String NAME = "BlogEntry";
043: private static final String LIMIT = "limit";
044: private static final String LIMIT_BY = "limit_by";
045:
046: private int pageType;
047: private String cat = "";
048: private ArchiveRange arc;
049: private long entryID;
050:
051: private TemplateTag entryBodyTag = new HyperTextTag("EntryBody");
052: private TemplateTag entryTitleTag = new HyperTextTag("EntryTitle");
053: private TemplateTag entryIDTag = new TextTag("EntryID");
054: private TemplateTag entryAuthorTag = new TextTag("EntryAuthor");
055: private TemplateTag entryAuthorEmailTag = new EmailTag(
056: "EntryAuthorEmail");
057: private TemplateTag entryAuthorUrlTag = new TextTag(
058: "EntryAuthorURL");
059: private TemplateTag entryArchivePageTag = new TextTag(
060: "EntryArchivePage");
061: private TemplateTag entryPermalinkTag = new TextTag(
062: "EntryPermalink");
063: private DateTag entryDateTag = new DateTag("EntryDate");
064: private DateTag entryTimeTag = new DateTag("EntryTime");
065: private DateTag entryDateTimeTag = new DateTag("EntryDateTime");
066:
067: private TBWeblog blog;
068: private Vector entryIDs = new Vector();
069:
070: private Calendar cal = Calendar.getInstance();
071: private int currentDay;
072: private BlogEntry curEntry = null;
073:
074: private Vector tags = new Vector();
075:
076: private DayFooterContainer dayFooter;
077: private EntryTitleContainer entryTitle;
078:
079: public BlogEntryContainer(TBWeblog blog, int type) {
080: super (NAME);
081: initContainer(blog, type);
082: }
083:
084: public BlogEntryContainer(TBWeblog blog, String cat) {
085: super (NAME);
086: this .cat = cat;
087: initContainer(blog, CAT_PAGE);
088: }
089:
090: public BlogEntryContainer(TBWeblog blog, ArchiveRange arc) {
091: super (NAME);
092: this .arc = arc;
093: initContainer(blog, ARC_PAGE);
094: }
095:
096: public BlogEntryContainer(TBWeblog blog, long id) {
097: super (NAME);
098: entryID = id;
099: initContainer(blog, ENTRY_PAGE);
100: }
101:
102: private void initContainer(TBWeblog b, int type) {
103: this .blog = b;
104: tags.add(entryBodyTag);
105: tags.add(entryTitleTag);
106: tags.add(entryIDTag);
107: tags.add(entryAuthorTag);
108: tags.add(entryAuthorEmailTag);
109: tags.add(entryAuthorUrlTag);
110: tags.add(entryArchivePageTag);
111: tags.add(entryDateTag);
112: tags.add(entryTimeTag);
113: tags.add(entryDateTimeTag);
114: tags.add(entryPermalinkTag);
115:
116: entryDateTag.setLocale(blog.getLocale());
117: entryTimeTag.setLocale(blog.getLocale());
118: entryDateTimeTag.setLocale(blog.getLocale());
119:
120: dayFooter = new DayFooterContainer();
121: entryTitle = new EntryTitleContainer();
122:
123: pageType = type;
124:
125: defaults.put(LIMIT, "1");
126: defaults.put(LIMIT_BY, "10");
127: }
128:
129: /**
130: * Sets the default date format for entry dates. Can be overriden
131: * in the templates
132: *
133: * @param format The date format string that should work with SimpleDateFormat
134: */
135: public void setDefaultDateFormat(String format) {
136: Hashtable def = entryDateTag.getDefaultAttributes();
137: def.put(DateTag.FORMAT, format);
138:
139: updateDateTimeFormat();
140: }
141:
142: /**
143: * Sets the default time format
144: *
145: * @param format The default time format
146: */
147: public void setDefaultTimeFormat(String format) {
148: Hashtable def = entryTimeTag.getDefaultAttributes();
149: def.put(DateTag.FORMAT, format);
150:
151: updateDateTimeFormat();
152: }
153:
154: private void updateDateTimeFormat() {
155: Hashtable ht = entryDateTimeTag.getDefaultAttributes();
156: String dformat = entryDateTag.getDefaultAttributes().get(
157: DateTag.FORMAT).toString();
158: String tformat = entryTimeTag.getDefaultAttributes().get(
159: DateTag.FORMAT).toString();
160: ht.put(DateTag.FORMAT, dformat + " " + tformat);
161: }
162:
163: /**
164: * Sets the default chronological order of the entries.
165: * This can be overriden in the template with the attribute "sort_order"
166: *
167: * @param ascending The chronological order
168: */
169: public void setDefaultSortOrder(boolean ascending) {
170: if (ascending)
171: defaults.put(SORT_ORDER, "ascend");
172: else
173: defaults.put(SORT_ORDER, "descend");
174: }
175:
176: /**
177: * Sets the default limit attribute. The limit attribute
178: * specifies if the number of entries per page should be
179: * limited. This can be overriden in the template.
180: * A value of "1" limits the entries.
181: *
182: * @param limit true to limit, false otherwise
183: */
184: public void setDefaultIsLimit(boolean limit) {
185: if (limit)
186: defaults.put(LIMIT, "1");
187: else
188: defaults.put(LIMIT, "0");
189: }
190:
191: /**
192: * Sets the default number to limit entries by
193: *
194: * @param limit The number to limit entries to
195: */
196: public void setDefaultLimitBy(int limit) {
197: if (limit >= 0)
198: defaults.put(LIMIT_BY, limit + "");
199: }
200:
201: /**
202: * Indicates whether or not entries on RSS pages should be truncated
203: * Can be overriden in the RSS template
204: *
205: * @param b true to limit RSS entry bodies, false otherwise
206: */
207: public void setLimitEntryBody(boolean b) {
208: if (pageType == RSS_PAGE) {
209: String lim = "0";
210: if (b)
211: lim = "20";
212: entryBodyTag.getDefaultAttributes().put(HyperTextTag.WORDS,
213: lim);
214: }
215: }
216:
217: /**
218: * Indicates if RSS entry bodies will be limited
219: *
220: * @return
221: */
222: public boolean isLimtEntryBody() {
223: boolean limit = !entryBodyTag.getDefaultAttributes().get(
224: HyperTextTag.WORDS).equals("0");
225: return limit && pageType == RSS_PAGE;
226: }
227:
228: private EntryEnumeration getEntriesForPage(boolean sortAsc)
229: throws BackendException {
230: WeblogBackend backend = blog.getBackend();
231: EntryEnumeration eEnum = null;
232: if (pageType == ARC_PAGE)
233: eEnum = backend.getEntriesBetween(blog.getKey(), arc
234: .getStartDate(), arc.getExpirationDate(), sortAsc);
235: else if (pageType == CAT_PAGE)
236: eEnum = backend.getEntriesFromCategory(blog.getKey(), cat,
237: sortAsc);
238: else
239: eEnum = backend.getEntries(blog.getKey(), sortAsc);
240:
241: return eEnum;
242: }
243:
244: /* (non-Javadoc)
245: * @see net.sf.thingamablog.generator1.TemplateContainer#init(java.util.Hashtable)
246: */
247: public void initListData(boolean asc, Hashtable attribs) {
248: entryIDs.removeAllElements();
249: if (pageType == ENTRY_PAGE) {
250: ListElement ele = new ListElement();
251: ele.id = entryID;
252: ele.isFooterVisible = true;
253: ele.isHeaderVisible = true;
254: entryIDs.add(ele);
255: } else
256: initEntryIDs(asc, attribs);
257:
258: if (!entryIDs.isEmpty()) {
259: ((ListElement) entryIDs.lastElement()).isFooterVisible = true;
260: }
261: }
262:
263: private void initEntryIDs(boolean asc, Hashtable attribs) {
264: String attr = attribs.get(LIMIT).toString();
265: boolean shouldLimit = attr.equals("1") && pageType != ARC_PAGE;
266: int entryLimit = 10;
267: try {
268: entryLimit = Integer.parseInt(attribs.get(LIMIT_BY)
269: .toString());
270: } catch (Exception ex) {
271: }
272:
273: currentDay = 0;
274:
275: try {
276: EntryEnumeration eEnum = null;
277: if (!shouldLimit) {
278: eEnum = getEntriesForPage(asc);
279: while (eEnum.hasMoreEntries()) {
280: BlogEntry be = eEnum.nextEntry();
281: if (be.getDate().before(blog.getArchiveBaseDate()))
282: continue;
283: addListElement(be);
284: }
285: } else {
286: eEnum = getEntriesForPage(false);//newest first
287: int count = 0;
288: if (!asc) //newest first
289: {
290: while (eEnum.hasMoreEntries()) {
291: BlogEntry be = eEnum.nextEntry();
292: if (count >= entryLimit
293: || be.getDate().before(
294: blog.getArchiveBaseDate()))
295: break;
296: addListElement(be);
297: count++;
298: }
299: } else //oldest first
300: {
301: //Vectorize
302: Long h[] = new Long[entryLimit];
303: while (eEnum.hasMoreEntries()) {
304: if (count >= entryLimit)
305: break;
306: BlogEntry be = eEnum.nextEntry();
307: h[count++] = new Long(be.getID());
308: //System.out.println(h[count]);
309: }
310: for (int i = (h.length - 1); i > -1; --i) {
311: if (h[i] != null) {
312: BlogEntry be = blog.getEntry(h[i]
313: .longValue());
314: if (be.getDate().before(
315: blog.getArchiveBaseDate()))
316: continue;
317: addListElement(be);
318: }
319: }
320: }
321: }
322: eEnum.close();
323: } catch (Exception ex) {
324: ex.printStackTrace();
325: }
326: }
327:
328: private void addListElement(BlogEntry be) {
329: cal.setTime(be.getDate());
330: ListElement ele = new ListElement();
331: ele.id = be.getID();
332: if (entryIDs.size() == 0) {
333: currentDay = cal.get(Calendar.DAY_OF_YEAR);
334: ele.isHeaderVisible = true;
335: } else if (currentDay != cal.get(Calendar.DAY_OF_YEAR)) {
336: ((ListElement) entryIDs.lastElement()).isFooterVisible = true;
337: ele.isHeaderVisible = true;
338: currentDay = cal.get(Calendar.DAY_OF_YEAR);
339: }
340:
341: entryIDs.add(ele);
342: }
343:
344: public int getListDataSize() {
345: return entryIDs.size();
346: }
347:
348: public Object getValueForTag(TemplateTag tag, int index) {
349: //this method is called first, so we can init curEntry here
350: ListElement e = (ListElement) entryIDs.elementAt(index);
351: try {
352: curEntry = blog.getEntry(e.id);
353: Author auth = curEntry.getAuthor();
354: if (auth == null)
355: auth = new Author();
356:
357: if (tag == entryIDTag)
358: return Long.toString(curEntry.getID());
359: if (tag == entryAuthorTag)
360: return auth.getName();
361: if (tag == entryAuthorEmailTag)
362: return auth.getEmailAddress();
363: if (tag == entryAuthorUrlTag)
364: return auth.getUrl();
365: if (tag == entryDateTag || tag == entryTimeTag
366: || tag == entryDateTimeTag)
367: return curEntry.getDate();
368: if (tag == entryBodyTag)
369: return curEntry.getText();
370: if (tag == entryTitleTag && curEntry.getTitle() != null)
371: return curEntry.getTitle();
372: else if (tag == entryPermalinkTag) {
373: return blog.getUrlForEntry(curEntry);
374: }
375: if (tag == entryArchivePageTag) {
376: ArchiveRange ar = blog.getArchiveForDate(curEntry
377: .getDate());
378: return blog.getArchiveUrl()
379: + blog.getArchiveFileName(ar);
380: }
381:
382: } catch (Exception ex) {
383: ex.printStackTrace();
384: }
385:
386: return "";
387: }
388:
389: /* (non-Javadoc)
390: * @see net.sf.thingamablog.generator1.TemplateContainer#getTags()
391: */
392: public List getTags() {
393: return tags;
394: }
395:
396: /* (non-Javadoc)
397: * @see net.sf.thingamablog.generator1.TemplateContainer#getContainers()
398: */
399: public List getContainers() {
400: ListElement le = (ListElement) entryIDs
401: .elementAt(currentIndex());
402:
403: DayHeaderContainer dayHeader = new DayHeaderContainer();
404: dayHeader.setDate(curEntry.getDate());
405: dayHeader.setVisible(le.isHeaderVisible);
406:
407: dayFooter.setVisible(le.isFooterVisible);
408: entryTitle.setTitle(curEntry.getTitle());
409:
410: EntryModifiedDateContainer entryModified = new EntryModifiedDateContainer();
411: entryModified.setDate(curEntry.getLastModified());
412:
413: ArrayList list = new ArrayList(5);
414: list.add(dayHeader);
415: list.add(dayFooter);
416: list.add(entryTitle);
417: list.add(entryModified);
418: list.add(new CategoryListContainer(blog, curEntry));
419:
420: return list;
421: }
422:
423: public boolean isVisible() {
424: return !entryIDs.isEmpty();
425: }
426:
427: private class ListElement {
428: public long id;
429: public boolean isHeaderVisible;
430: public boolean isFooterVisible;
431: }
432:
433: private class DayFooterContainer extends BasicContainer {
434: private boolean visible;
435:
436: public DayFooterContainer() {
437: super ("DayFooter");
438: }
439:
440: public Object getValueForTag(TemplateTag t) {
441: return "";
442: }
443:
444: //override from super class
445: public boolean isVisible() {
446: return visible;
447: }
448:
449: public void setVisible(boolean b) {
450: visible = b;
451: }
452: }
453:
454: private class DayHeaderContainer extends BasicContainer {
455: private boolean visible;
456: private Date date;
457: private DateTag dayHeaderDate = new DateTag("DayHeaderDate");
458:
459: public DayHeaderContainer() {
460: super ("DayHeader");
461: dayHeaderDate.setLocale(blog.getLocale());
462: String format = entryDateTag.getDefaultAttributes().get(
463: DateTag.FORMAT).toString();
464: Hashtable def = dayHeaderDate.getDefaultAttributes();
465: def.put(DateTag.FORMAT, format);
466: registerTag(dayHeaderDate);
467: }
468:
469: public void setVisible(boolean b) {
470: visible = b;
471: }
472:
473: public void setDate(Date d) {
474: date = d;
475: }
476:
477: public Object getValueForTag(TemplateTag t) {
478: if (t == dayHeaderDate)
479: return date;
480: return "";
481: }
482:
483: //overridden from super class
484: public boolean isVisible() {
485: return visible;
486: }
487: }
488:
489: private class EntryTitleContainer extends BasicContainer {
490: private HyperTextTag titleTag = new HyperTextTag("EntryTitle");
491: private String title = "";
492:
493: public EntryTitleContainer() {
494: super ("EntryTitle");
495: registerTag(titleTag);
496: }
497:
498: public void setTitle(String t) {
499: title = t;
500: }
501:
502: public Object getValueForTag(TemplateTag t) {
503: if (t == titleTag)
504: return title;
505:
506: return "";
507: }
508:
509: public boolean isVisible() {
510: return title != null && !title.equals("");
511: }
512: }
513:
514: private class EntryModifiedDateContainer extends BasicContainer {
515: private Date modDate = null;
516: private DateTag entryModifiedDateTag = new DateTag(
517: "EntryModifiedDate");
518:
519: public EntryModifiedDateContainer() {
520: super ("EntryModifiedDate");
521: entryModifiedDateTag.setLocale(blog.getLocale());
522: String format = entryDateTimeTag.getDefaultAttributes()
523: .get(DateTag.FORMAT).toString();
524: Hashtable def = entryModifiedDateTag.getDefaultAttributes();
525: def.put(DateTag.FORMAT, format);
526: registerTag(entryModifiedDateTag);
527: }
528:
529: public boolean isVisible() {
530: return modDate != null;
531: }
532:
533: public void setDate(Date d) {
534: modDate = d;
535: }
536:
537: public Object getValueForTag(TemplateTag t) {
538: if (t == entryModifiedDateTag)
539: return modDate;
540: return "";
541: }
542: }
543: }
|