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);
48 this.description = readValue("description", itemElement, 0);
49 this.author = readValue("author", itemElement, 0);
50 this.guid = readValue("guid", itemElement, 1);
51 String pubDate = readValue("pubDate", itemElement, 0);
52 String dcDate = readValue("dc:date", itemElement, 0);
57 theDate = pubDateParser.parse(pubDate);
58 } else if(dcDate != null) {
59 theDate = decodeDCDate(dcDate);
63 this.date = dateFormat.format(theDate);
64 } catch(Exception e) {
67 } else if(dcDate != null) {
70 this.date = e.toString();
72 Plugin.logInfo("Unable to parse date",e);
76 protected String readValue(String elementName, Element parent, int type) {
77 Element element = (Element)parent.getElementsByTagName(elementName).item(0);
82 if(element.hasAttribute("isPermaLink") && element.getAttribute("isPermaLink").equals("false")) {
83 this.isPermaLink = false;
87 NodeList children = element.getChildNodes();
88 StringBuffer buffer = new StringBuffer();
89 for(int i=0; i<children.getLength(); i++) {
90 Node node = children.item(i);
91 if(node.getNodeType()==Node.TEXT_NODE || node.getNodeType()==Node.CDATA_SECTION_NODE) {
92 buffer.append(((Text)node).getData());
95 return buffer.toString().trim();
101 public String getUsableTitle() {
104 } else if (description != null) {
107 return "!! No title in feed !!";
111 public String getUsableLink() {
114 } else if (guid != null && isPermaLink) {
117 return "about:blank";
121 public boolean isBanned() {
122 return Plugin.getDefault().isBannedTitle(title);
125 public TableItem toTableItem(Table table) {
126 TableItem tableItem = new TableItem(table, SWT.NONE);
127 fillTableItem(tableItem);
131 public void fillTableItem(TableItem tableItem) {
132 tableItem.setText(new String[] {date,readFlag?"":"*",getUsableTitle()});
133 tableItem.setData(this);
137 * Sets the readFlag and notifies the listeners
138 * that the status changed.
139 * @param readFlag The readFlag to set
141 public void setReadFlag(boolean readFlag) {
142 if(readFlag != this.readFlag) {
143 this.readFlag = readFlag;
144 channel.computeUnRead();
149 * @see java.lang.Object#equals(Object)
151 public boolean equals(Object obj) {
152 return (obj instanceof Item)
153 && ((Item)obj).getUID().equals(this.getUID());
156 protected static Date decodeDCDate(String string) throws Exception {
157 GregorianCalendar calendar = new GregorianCalendar(readInt(string,0,4),0,1,0,0,0);
158 calendar.set(Calendar.MILLISECOND,0);
159 calendar.set(Calendar.DST_OFFSET,0);
160 if(checkChar(string,4,'-')) {
161 calendar.set(Calendar.MONTH,readInt(string,5,2)-1);
162 if(checkChar(string,7,'-')) {
163 calendar.set(Calendar.DATE,readInt(string,8,2));
164 if(checkChar(string,10,'T')) {
165 calendar.set(Calendar.HOUR_OF_DAY,readInt(string,11,2));
166 calendar.set(Calendar.MINUTE,readInt(string,14,2));
167 int length = string.length();
170 //les secondes + millisecondes
171 if(checkChar(string,16,':')) {
172 calendar.set(Calendar.SECOND,readInt(string,17,2));
174 if(checkChar(string,position,'.')) {
176 StringBuffer millisecondBuffer = new StringBuffer("0.");
177 while(position<length && Character.isDigit(string.charAt(position))) {
178 millisecondBuffer.append(string.charAt(position));
181 calendar.set(Calendar.MILLISECOND,(int)(Double.parseDouble(millisecondBuffer.toString())*1000));
188 if(string.charAt(position) == 'Z') {
189 calendar.set(Calendar.ZONE_OFFSET,0);
190 if(length != position +1) {
192 throw new Exception("Invalid format of dc:date (extra tokens)");
194 } else if(string.charAt(position) == '+' || string.charAt(position) == '-') {
196 sign = string.charAt(position) == '+'?1:-1;
197 int hour = readInt(string,position+1,2);
198 int minute = readInt(string,position+4,2);
199 calendar.set(Calendar.ZONE_OFFSET,sign*(hour*60*60*1000+minute*60*1000));
200 if(length != position +6) {
202 throw new Exception("Invalid format of dc:date (extra tokens)");
205 throw new Exception("Invalid format of dc:date (invalid TZD)");
211 return calendar.getTime();
214 private static int readInt(String buffer, int position, int length) {
215 int result = Integer.parseInt(buffer.substring(position,position+length));
219 private static boolean checkChar(String buffer, int position, char expectedChar) {
220 if(buffer.length() > position && buffer.charAt(position) == expectedChar) {
228 * @return the description of this item
230 public String getDescription() {
234 * @return the author of this item
236 public String getAuthor() {
244 public String getDate() {
249 * Returns the readFlag.
252 public boolean isReadFlag() {
257 * Returns the channel.
260 public Channel getChannel() {
265 * Returns a unique ID used to remember which
266 * items were read in the ChannelStore
269 public String getUID() {
270 return getUsableLink() + ") ~ (" + getUsableTitle();