1 package net.sourceforge.phpeclipse.news;
3 import java.text.DateFormat;
4 import java.text.SimpleDateFormat;
5 import java.util.Calendar;
7 import java.util.GregorianCalendar;
8 import java.util.Locale;
10 import org.eclipse.swt.SWT;
11 import org.eclipse.swt.widgets.Table;
12 import org.eclipse.swt.widgets.TableItem;
13 import org.w3c.dom.Element;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
16 import org.w3c.dom.Text;
19 * @author jnegre - http://www.jnegre.org/
21 * (c)Copyright 2002 J�r�me N�gre
26 protected static DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);
27 protected static SimpleDateFormat pubDateParser = new SimpleDateFormat("EEE, d MMM yy hh:mm:ss z", new Locale("en","US"));
29 protected Channel channel;
31 protected String title;
32 protected String link;
33 protected String description;
34 protected String author;
35 protected String guid;
36 protected boolean isPermaLink = true;
37 protected String date;
39 protected boolean readFlag = false;
42 * Constructor for Item.
44 public Item(Channel channel, Element itemElement) {
45 this.channel = channel;
46 this.title = readValue("title", itemElement, 0);
47 this.link = readValue("link", itemElement, 0);
49 String simpleDescription = readValue("description", itemElement, 0);
50 String contentEncoded = readValue("content:encoded", itemElement, 0);
51 this.description = contentEncoded!=null?contentEncoded:simpleDescription;
53 this.author = readValue("author", itemElement, 0);
54 this.guid = readValue("guid", itemElement, 1);
55 String pubDate = readValue("pubDate", itemElement, 0);
56 String dcDate = readValue("dc:date", itemElement, 0);
61 theDate = pubDateParser.parse(pubDate);
62 } else if(dcDate != null) {
63 theDate = decodeDCDate(dcDate);
67 this.date = dateFormat.format(theDate);
68 } catch(Exception e) {
71 } else if(dcDate != null) {
74 this.date = e.toString();
76 Plugin.logInfo("Unable to parse date",e);
80 protected String readValue(String elementName, Element parent, int type) {
81 Element element = (Element)parent.getElementsByTagName(elementName).item(0);
86 if(element.hasAttribute("isPermaLink") && element.getAttribute("isPermaLink").equals("false")) {
87 this.isPermaLink = false;
91 NodeList children = element.getChildNodes();
92 StringBuffer buffer = new StringBuffer();
93 for(int i=0; i<children.getLength(); i++) {
94 Node node = children.item(i);
95 if(node.getNodeType()==Node.TEXT_NODE || node.getNodeType()==Node.CDATA_SECTION_NODE) {
96 buffer.append(((Text)node).getData());
99 return buffer.toString().trim();
105 public String getUsableTitle() {
108 } else if (description != null) {
111 return "!! No title in feed !!";
115 public String getUsableLink() {
118 } else if (guid != null && isPermaLink) {
121 return "about:blank";
125 public boolean isBanned() {
126 return Plugin.getDefault().isBannedTitle(title);
129 public TableItem toTableItem(Table table) {
130 TableItem tableItem = new TableItem(table, SWT.NONE);
131 fillTableItem(tableItem);
135 public void fillTableItem(TableItem tableItem) {
136 tableItem.setText(new String[] {date,readFlag?"":"*",getUsableTitle()});
137 tableItem.setData(this);
141 * Sets the readFlag and notifies the listeners
142 * that the status changed.
143 * @param readFlag The readFlag to set
145 public void setReadFlag(boolean readFlag) {
146 if(readFlag != this.readFlag) {
147 this.readFlag = readFlag;
148 channel.computeUnRead();
153 * @see java.lang.Object#equals(Object)
155 public boolean equals(Object obj) {
156 return (obj instanceof Item)
157 && ((Item)obj).getUID().equals(this.getUID());
160 protected static Date decodeDCDate(String string) throws Exception {
161 GregorianCalendar calendar = new GregorianCalendar(readInt(string,0,4),0,1,0,0,0);
162 calendar.set(Calendar.MILLISECOND,0);
163 calendar.set(Calendar.DST_OFFSET,0);
164 if(checkChar(string,4,'-')) {
165 calendar.set(Calendar.MONTH,readInt(string,5,2)-1);
166 if(checkChar(string,7,'-')) {
167 calendar.set(Calendar.DATE,readInt(string,8,2));
168 if(checkChar(string,10,'T')) {
169 calendar.set(Calendar.HOUR_OF_DAY,readInt(string,11,2));
170 calendar.set(Calendar.MINUTE,readInt(string,14,2));
171 int length = string.length();
174 //les secondes + millisecondes
175 if(checkChar(string,16,':')) {
176 calendar.set(Calendar.SECOND,readInt(string,17,2));
178 if(checkChar(string,position,'.')) {
180 StringBuffer millisecondBuffer = new StringBuffer("0.");
181 while(position<length && Character.isDigit(string.charAt(position))) {
182 millisecondBuffer.append(string.charAt(position));
185 calendar.set(Calendar.MILLISECOND,(int)(Double.parseDouble(millisecondBuffer.toString())*1000));
192 if(string.charAt(position) == 'Z') {
193 calendar.set(Calendar.ZONE_OFFSET,0);
194 if(length != position +1) {
196 throw new Exception("Invalid format of dc:date (extra tokens)");
198 } else if(string.charAt(position) == '+' || string.charAt(position) == '-') {
200 sign = string.charAt(position) == '+'?1:-1;
201 int hour = readInt(string,position+1,2);
202 int minute = readInt(string,position+4,2);
203 calendar.set(Calendar.ZONE_OFFSET,sign*(hour*60*60*1000+minute*60*1000));
204 if(length != position +6) {
206 throw new Exception("Invalid format of dc:date (extra tokens)");
209 throw new Exception("Invalid format of dc:date (invalid TZD)");
215 return calendar.getTime();
218 private static int readInt(String buffer, int position, int length) {
219 int result = Integer.parseInt(buffer.substring(position,position+length));
223 private static boolean checkChar(String buffer, int position, char expectedChar) {
224 if(buffer.length() > position && buffer.charAt(position) == expectedChar) {
232 * @return the description of this item
234 public String getDescription() {
238 * @return the author of this item
240 public String getAuthor() {
248 public String getDate() {
253 * Returns the readFlag.
256 public boolean isReadFlag() {
261 * Returns the channel.
264 public Channel getChannel() {
269 * Returns a unique ID used to remember which
270 * items were read in the ChannelStore
273 public String getUID() {
274 return getUsableLink() + ") ~ (" + getUsableTitle();