001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018: package org.apache.roller.planet.pojos;
019:
020: import java.io.Serializable;
021: import java.sql.Timestamp;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.apache.roller.config.RollerRuntimeConfig;
027: import org.apache.roller.pojos.*;
028: import org.apache.roller.util.rome.ContentModule;
029:
030: import org.apache.roller.util.Utilities;
031: import org.apache.commons.lang.StringUtils;
032: import com.sun.syndication.feed.module.DCModule;
033: import com.sun.syndication.feed.synd.SyndCategory;
034: import com.sun.syndication.feed.synd.SyndContent;
035: import com.sun.syndication.feed.synd.SyndEntry;
036: import com.sun.syndication.feed.synd.SyndFeed;
037:
038: import java.util.Map;
039: import org.apache.commons.lang.StringEscapeUtils;
040: import org.apache.roller.RollerException;
041: import org.apache.roller.business.PluginManager;
042: import org.apache.roller.business.Roller;
043: import org.apache.roller.business.RollerFactory;
044:
045: /**
046: * Represents a planet entry, i.e. an entry that was parsed out of an RSS or
047: * Atom newsfeed by Roller's built-in planet aggregator.
048: * <p>
049: * The model coded in this class simple, perhaps too simple, and in the future
050: * it should be replaced by more complete model that can fully represent all
051: * forms of RSS and Atom.
052: *
053: * @hibernate.class lazy="false" table="rag_entry"
054: */
055: public class PlanetEntryData extends PersistentObject implements
056: Serializable, Comparable {
057: protected String id;
058: protected String handle;
059: protected String title;
060: protected String guid;
061: protected String permalink;
062: protected String author;
063: protected String text = "";
064: protected Timestamp published;
065: protected Timestamp updated;
066:
067: private String categoriesString;
068: protected PlanetSubscriptionData subscription = null;
069:
070: /**
071: * Construct empty entry.
072: */
073: public PlanetEntryData() {
074: }
075:
076: /**
077: * Create entry from Rome entry.
078: */
079: public PlanetEntryData(SyndFeed romeFeed, SyndEntry romeEntry,
080: PlanetSubscriptionData sub) {
081: setSubscription(sub);
082: initFromRomeEntry(romeFeed, romeEntry);
083: }
084:
085: /**
086: * Create entry from Rome entry.
087: */
088: public PlanetEntryData(WeblogEntryData rollerEntry,
089: PlanetSubscriptionData sub, Map pagePlugins)
090: throws RollerException {
091: setSubscription(sub);
092: initFromRollerEntry(rollerEntry, pagePlugins);
093: }
094:
095: /**
096: * Init entry from Rome entry
097: */
098: private void initFromRomeEntry(SyndFeed romeFeed,
099: SyndEntry romeEntry) {
100: setTitle(romeEntry.getTitle());
101: setPermalink(romeEntry.getLink());
102:
103: // Play some games to get the author
104: DCModule entrydc = (DCModule) romeEntry.getModule(DCModule.URI);
105: DCModule feeddc = (DCModule) romeFeed.getModule(DCModule.URI);
106: if (romeEntry.getAuthor() != null) {
107: setAuthor(romeEntry.getAuthor());
108: } else {
109: setAuthor(entrydc.getCreator()); // use <dc:creator>
110: }
111:
112: // Play some games to get the date too
113: if (romeEntry.getPublishedDate() != null) {
114: setPubTime(new Timestamp(romeEntry.getPublishedDate()
115: .getTime())); // use <pubDate>
116: } else if (entrydc != null && entrydc.getDate() != null) {
117: setPubTime(new Timestamp(entrydc.getDate().getTime())); // use <dc:date>
118: }
119:
120: // get content and unescape if it is 'text/plain'
121: if (romeEntry.getContents().size() > 0) {
122: SyndContent content = (SyndContent) romeEntry.getContents()
123: .get(0);
124: if (content != null
125: && content.getType().equals("text/plain")) {
126: setText(StringEscapeUtils.unescapeHtml(content
127: .getValue()));
128: } else if (content != null) {
129: setText(content.getValue());
130: }
131: }
132:
133: // no content, then try <content:encoded>
134: if (getText() == null || getText().trim().length() == 0) {
135: ContentModule cm = (ContentModule) romeEntry
136: .getModule(ContentModule.URI);
137: if (cm != null) {
138: setText(StringEscapeUtils.unescapeHtml(cm.getEncoded()));
139: }
140: }
141:
142: // copy categories
143: if (romeEntry.getCategories().size() > 0) {
144: List list = new ArrayList();
145: Iterator cats = romeEntry.getCategories().iterator();
146: while (cats.hasNext()) {
147: SyndCategory cat = (SyndCategory) cats.next();
148: list.add(cat.getName());
149: }
150: setCategoriesString(list);
151: }
152: }
153:
154: /**
155: * Init entry from Roller entry
156: */
157: private void initFromRollerEntry(WeblogEntryData rollerEntry,
158: Map pagePlugins) throws RollerException {
159: Roller roller = RollerFactory.getRoller();
160: PluginManager ppmgr = roller.getPagePluginManager();
161:
162: String content = "";
163: if (!StringUtils.isEmpty(rollerEntry.getText())) {
164: content = rollerEntry.getText();
165: } else {
166: content = rollerEntry.getSummary();
167: }
168: content = ppmgr.applyWeblogEntryPlugins(pagePlugins,
169: rollerEntry, content);
170:
171: setAuthor(rollerEntry.getCreator().getFullName());
172: setTitle(rollerEntry.getTitle());
173: setPermalink(rollerEntry.getLink());
174: setPubTime(rollerEntry.getPubTime());
175: setText(content);
176:
177: setPermalink(RollerRuntimeConfig
178: .getProperty("site.absoluteurl")
179: + rollerEntry.getPermaLink());
180:
181: List cats = new ArrayList();
182: cats.add(rollerEntry.getCategory().getPath());
183: setCategoriesString(cats);
184: }
185:
186: //----------------------------------------------------------- persistent fields
187:
188: /**
189: * @hibernate.id column="id" generator-class="uuid.hex" unsaved-value="null"
190: * @roller.wrapPojoMethod type="simple"
191: */
192: public String getId() {
193: return id;
194: }
195:
196: public void setId(String id) {
197: this .id = id;
198: }
199:
200: /**
201: * @hibernate.property column="categories" non-null="false" unique="false"
202: * @roller.wrapPojoMethod type="simple"
203: */
204: public String getCategoriesString() {
205: return categoriesString;
206: }
207:
208: public void setCategoriesString(String categoriesString) {
209: this .categoriesString = categoriesString;
210: }
211:
212: /**
213: * @hibernate.many-to-one column="subscription_id" cascade="save-update" not-null="true"
214: */
215: public PlanetSubscriptionData getSubscription() {
216: return subscription;
217: }
218:
219: public void setSubscription(PlanetSubscriptionData subscription) {
220: this .subscription = subscription;
221: }
222:
223: /**
224: * @hibernate.property column="author" non-null="false" unique="false"
225: * @roller.wrapPojoMethod type="simple"
226: */
227: public String getAuthor() {
228: return author;
229: }
230:
231: public void setAuthor(String author) {
232: this .author = author;
233: }
234:
235: /**
236: * @hibernate.property column="content" non-null="false" unique="false"
237: * @roller.wrapPojoMethod type="simple"
238: */
239: public String getText() {
240: return text;
241: }
242:
243: public void setText(String content) {
244: this .text = content;
245: }
246:
247: /**
248: * @hibernate.property column="guid" non-null="false" unique="true"
249: * @roller.wrapPojoMethod type="simple"
250: */
251: public String getGuid() {
252: return guid;
253: }
254:
255: public void setGuid(String guid) {
256: this .guid = guid;
257: }
258:
259: /**
260: * @hibernate.property column="handle" non-null="false" unique="false"
261: * @roller.wrapPojoMethod type="simple"
262: */
263: public String getHandle() {
264: return handle;
265: }
266:
267: public void setHandle(String handle) {
268: this .handle = handle;
269: }
270:
271: /**
272: * @hibernate.property column="published" non-null="true" unique="false"
273: * @roller.wrapPojoMethod type="simple"
274: */
275: public Timestamp getPubTime() {
276: return published;
277: }
278:
279: public void setPubTime(Timestamp published) {
280: this .published = published;
281: }
282:
283: /**
284: * @hibernate.property column="permalink" non-null="true" unique="false"
285: * @roller.wrapPojoMethod type="simple"
286: */
287: public String getPermalink() {
288: return permalink;
289: }
290:
291: public void setPermalink(String permalink) {
292: this .permalink = permalink;
293: }
294:
295: /**
296: * @hibernate.property column="title" non-null="false" unique="false"
297: * @roller.wrapPojoMethod type="simple"
298: */
299: public String getTitle() {
300: return title;
301: }
302:
303: public void setTitle(String title) {
304: this .title = title;
305: }
306:
307: /**
308: * @hibernate.property column="updated" non-null="false" unique="false"
309: * @roller.wrapPojoMethod type="simple"
310: */
311: public Timestamp getUpdateTime() {
312: return updated;
313: }
314:
315: public void setUpdateTime(Timestamp updated) {
316: this .updated = updated;
317: }
318:
319: //----------------------------------------------------------------- convenience
320:
321: /**
322: * Returns true if any of entry's categories contain a specific string
323: * (case-insensitive comparison).
324: */
325: public boolean inCategory(String category) {
326: Iterator cats = getCategories().iterator();
327: while (cats.hasNext()) {
328: String catName = ((String) cats.next()).toLowerCase();
329: if (catName.indexOf(category.toLowerCase()) != -1) {
330: return true;
331: }
332: }
333: return false;
334: }
335:
336: //------------------------------------------------------------- implementation
337:
338: /**
339: * Returns categories as list of WeblogCategoryData objects.
340: */
341: public List getCategories() {
342: List list = new ArrayList();
343: if (categoriesString != null) {
344: String[] catArray = Utilities.stringToStringArray(
345: categoriesString, ",");
346: for (int i = 0; i < catArray.length; i++) {
347: WeblogCategoryData cat = new WeblogCategoryData();
348: cat.setName(catArray[i]);
349: cat.setPath(catArray[i]);
350: list.add(cat);
351: }
352: }
353: return list;
354: }
355:
356: /**
357: * Return first entry in category collection.
358: * @roller.wrapPojoMethod type="pojo"
359: */
360: public WeblogCategoryData getCategory() {
361: WeblogCategoryData cat = null;
362: List cats = getCategories();
363: if (cats.size() > 0) {
364: cat = (WeblogCategoryData) cats.get(0);
365: }
366: return cat;
367: }
368:
369: private void setCategoriesString(List categories) {
370: StringBuffer sb = new StringBuffer();
371: Iterator cats = categories.iterator();
372: while (cats.hasNext()) {
373: String cat = (String) cats.next();
374: sb.append(cat);
375: if (cats.hasNext())
376: sb.append(",");
377: }
378: categoriesString = sb.toString();
379: }
380:
381: /**
382: * Returns creator as a UserData object.
383: * @roller.wrapPojoMethod type="pojo"
384: * TODO: make planet model entry author name, email, and uri
385: */
386: public UserData getCreator() {
387: UserData user = null;
388: if (author != null) {
389: user = new UserData();
390: user.setFullName(author);
391: user.setUserName(author);
392: }
393: return user;
394: }
395:
396: /**
397: * Returns summary (always null for planet entry)
398: * @roller.wrapPojoMethod type="simple"
399: */
400: public String getSummary() {
401: return null;
402: }
403:
404: /**
405: * Compare planet entries by comparing permalinks.
406: */
407: public int compareTo(Object o) {
408: PlanetEntryData other = (PlanetEntryData) o;
409: return getPermalink().compareTo(other.getPermalink());
410: }
411:
412: /**
413: * Compare planet entries by comparing permalinks.
414: */
415: public boolean equals(Object other) {
416: if (this == other)
417: return true;
418: if (!(other instanceof PlanetEntryData))
419: return false;
420: final PlanetEntryData that = (PlanetEntryData) other;
421: return this .permalink.equals(that.getPermalink());
422: }
423:
424: /**
425: * Generate hash code based on permalink.
426: */
427: public int hashCode() {
428: return this .permalink.hashCode();
429: }
430:
431: public void setData(PersistentObject vo) {
432: }
433:
434: /**
435: * Read-only synomym for getSubscription()
436: * @roller.wrapPojoMethod type="pojo"
437: */
438: public PlanetSubscriptionData getWebsite() {
439: return this .subscription;
440: }
441:
442: public void setWebsite() {
443: // noop
444: }
445:
446: /**
447: * Return text as content, to maintain compatibility with PlanetTool templates.
448: */
449: public String getContent() {
450: return text;
451: }
452:
453: public void setContent(String ignored) {
454: // no-op
455: }
456:
457: /**
458: * Return updateTime as updated, to maintain compatibility with PlanetTool templates.
459: */
460: public Timestamp getUpdated() {
461: return updated;
462: }
463:
464: public void setUpdated(Timestamp ignored) {
465: // no-op
466: }
467:
468: /**
469: * Return pubTime as published, to maintain compatibility with PlanetTool templates.
470: */
471: public Timestamp getPublished() {
472: return published;
473: }
474:
475: public void setPublished(Timestamp ignored) {
476: // no-op
477: }
478:
479: }
|