1 19 20 package org.myorg.feedreader; 21 22 import com.sun.syndication.feed.synd.SyndEntry; 23 import com.sun.syndication.feed.synd.SyndFeed; 24 import java.awt.Image ; 25 import java.awt.event.ActionEvent ; 26 import java.beans.IntrospectionException ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.ObjectOutputStream ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 import javax.swing.AbstractAction ; 33 import javax.swing.Action ; 34 import org.openide.DialogDisplayer; 35 import org.openide.ErrorManager; 36 import org.openide.NotifyDescriptor; 37 import org.openide.actions.DeleteAction; 38 import org.openide.actions.OpenAction; 39 import org.openide.cookies.InstanceCookie; 40 import org.openide.cookies.OpenCookie; 41 import org.openide.filesystems.FileLock; 42 import org.openide.filesystems.FileObject; 43 import org.openide.filesystems.Repository; 44 import org.openide.loaders.DataFolder; 45 import org.openide.loaders.DataObject; 46 import org.openide.loaders.DataObjectNotFoundException; 47 import org.openide.nodes.BeanNode; 48 import org.openide.nodes.Children; 49 import org.openide.nodes.FilterNode; 50 import org.openide.nodes.Node; 51 import org.openide.util.Lookup; 52 import org.openide.util.NbBundle; 53 import org.openide.util.Utilities; 54 import org.openide.util.actions.SystemAction; 55 import org.openide.util.lookup.Lookups; 56 import org.openide.util.lookup.ProxyLookup; 57 58 public class RssNode extends FilterNode { 59 60 61 public RssNode(Node folderNode) { 62 super(folderNode, new RssFolderChildren(folderNode)); 63 } 64 65 66 public Action [] getActions(boolean popup) { 67 DataFolder df = (DataFolder)getLookup().lookup(DataFolder.class); 68 return new Action [] { 69 new AddRssAction(df), 70 new AddFolderAction(df) 71 }; 72 } 73 74 75 public static class RootRssNode extends RssNode { 76 public RootRssNode() throws DataObjectNotFoundException { 77 super(DataObject.find( 78 Repository.getDefault().getDefaultFileSystem() 79 .getRoot().getFileObject("RssFeeds")).getNodeDelegate()); 80 } 81 82 public String getDisplayName() { 83 return NbBundle.getMessage(RssNode.class, "FN_title"); 84 } 85 } 86 87 88 private static class RssFolderChildren extends FilterNode.Children { 89 RssFolderChildren(Node rssFolderNode) { 90 super(rssFolderNode); 91 } 92 93 protected Node[] createNodes(Object key) { 94 Node n = (Node) key; 95 if (n.getLookup().lookup(DataFolder.class) != null) { 96 return new Node[] {new RssNode(n)}; 97 } else { 98 Feed feed = getFeed(n); 99 if (feed != null) { 100 try { 101 return new Node[] {new OneFeedNode(n, feed.getSyndFeed())}; 102 } catch (IOException ioe) { 103 ErrorManager.getDefault().notify(ioe); 104 } 105 } 106 } 107 return new Node[] {new FilterNode(n)}; 109 } 110 } 111 112 113 private static class OneFeedNode extends FilterNode { 114 115 OneFeedNode(Node feedFileNode, SyndFeed feed) { 116 super(feedFileNode, 117 new FeedChildren(feed), 118 new ProxyLookup(new Lookup[] { 119 Lookups.fixed(new Object [] {feed}), 120 feedFileNode.getLookup() 121 })); 122 } 123 124 public String getDisplayName() { 125 SyndFeed feed = (SyndFeed) getLookup().lookup(SyndFeed.class); 126 return feed.getTitle(); 127 } 128 129 public Image getIcon(int type) { 130 return Utilities.loadImage("org/myorg/feedreader/rss16.gif"); 131 } 132 133 public Image getOpenedIcon(int type) { 134 return getIcon(type); 135 } 136 137 public Action [] getActions(boolean context) { 138 return new Action [] { SystemAction.get(DeleteAction.class) }; 139 } 140 141 } 142 143 144 private static class FeedChildren extends Children.Keys { 145 private final SyndFeed feed; 146 public FeedChildren(SyndFeed feed) { 147 this.feed = feed; 148 } 149 150 protected void addNotify() { 151 setKeys(feed.getEntries()); 152 } 153 154 public Node[] createNodes(Object key) { 155 try { 156 return new Node[] { new EntryBeanNode((SyndEntry) key) }; 157 } catch (IntrospectionException ex) { 158 assert false : ex; 159 return new Node[0]; 160 } 161 } 162 } 163 164 165 private static class EntryBeanNode extends FilterNode { 166 167 private final SyndEntry entry; 168 169 public EntryBeanNode(SyndEntry entry) throws IntrospectionException { 170 super(new BeanNode(entry), Children.LEAF, Lookups.fixed(new Object [] { entry, new EntryOpenCookie(entry) })); 171 this.entry = entry; 172 } 173 174 175 public String getHtmlDisplayName() { 176 return entry.getTitle(); 177 } 178 179 180 public String getShortDescription() { 181 StringBuffer sb = new StringBuffer (); 182 sb.append("Author: " + entry.getAuthor() + "; "); 183 if (entry.getPublishedDate() != null) { 184 sb.append("Published: ").append(entry.getPublishedDate().toString()); 185 } 186 return sb.toString(); 187 } 188 189 190 public Action [] getActions(boolean popup) { 191 return new Action [] { SystemAction.get(OpenAction.class) }; 192 } 193 194 public Action getPreferredAction() { 195 return (SystemAction) getActions(false) [0]; 196 } 197 198 } 199 200 201 private static class EntryOpenCookie implements OpenCookie { 202 203 private final SyndEntry entry; 204 205 EntryOpenCookie(SyndEntry entry) { 206 this.entry = entry; 207 } 208 209 public void open() { 210 BrowserTopComponent btc = BrowserTopComponent.getBrowserComponent(entry.getTitle()); 211 btc.open(); 212 btc.requestActive(); 213 btc.setPage(entry.getUri()); 214 } 215 216 } 217 218 219 private static Feed getFeed(Node node) { 220 InstanceCookie ck = (InstanceCookie) node.getCookie(InstanceCookie.class); 221 if (ck == null) { 222 throw new IllegalStateException ("Bogus file in feeds folder: " + node.getLookup().lookup(FileObject.class)); 223 } 224 try { 225 return (Feed) ck.instanceCreate(); 226 } catch (ClassNotFoundException ex) { 227 ErrorManager.getDefault().notify(ex); 228 } catch (IOException ex) { 229 ErrorManager.getDefault().notify(ex); 230 } 231 return null; 232 } 233 234 235 private static class AddFolderAction extends AbstractAction { 236 237 private final DataFolder folder; 238 239 public AddFolderAction(DataFolder df) { 240 super(NbBundle.getMessage(RssNode.class, "FN_addfolderbutton")); 241 folder = df; 242 } 243 244 public void actionPerformed(ActionEvent ae) { 245 NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine( 246 NbBundle.getMessage(RssNode.class, "FN_askfolder_msg"), 247 NbBundle.getMessage(RssNode.class, "FN_askfolder_title"), 248 NotifyDescriptor.OK_CANCEL_OPTION, 249 NotifyDescriptor.PLAIN_MESSAGE); 250 251 Object result = DialogDisplayer.getDefault().notify(nd); 252 253 if (result.equals(NotifyDescriptor.OK_OPTION)) { 254 final String folderString = nd.getInputText(); 255 try { 256 DataFolder.create(folder, folderString); 257 } catch (IOException ex) { 258 ErrorManager.getDefault().notify(ex); 259 } 260 } 261 } 262 } 263 264 265 private static class AddRssAction extends AbstractAction { 266 267 private final DataFolder folder; 268 269 public AddRssAction(DataFolder df) { 270 super(NbBundle.getMessage(RssNode.class, "FN_addbutton")); 271 folder = df; 272 } 273 274 public void actionPerformed(ActionEvent ae) { 275 NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine( 276 NbBundle.getMessage(RssNode.class, "FN_askurl_msg"), 277 NbBundle.getMessage(RssNode.class, "FN_askurl_title"), 278 NotifyDescriptor.OK_CANCEL_OPTION, 279 NotifyDescriptor.PLAIN_MESSAGE); 280 281 Object result = DialogDisplayer.getDefault().notify(nd); 282 283 if (result.equals(NotifyDescriptor.OK_OPTION)) { 284 String urlString = nd.getInputText(); 285 URL url; 286 try { 287 url = new URL (urlString); 288 } catch (MalformedURLException e) { 289 String message = NbBundle.getMessage(RssNode.class, "FN_askurl_err", urlString); 290 ErrorManager.getDefault().annotate(e, ErrorManager.ERROR, null, message, null, null); 291 ErrorManager.getDefault().notify(e); 292 return; 293 } 294 try { 295 checkConnection(url); 296 } catch (IOException e) { 297 String message = NbBundle.getMessage(RssNode.class, "FN_cannotConnect_err", urlString); 298 ErrorManager.getDefault().annotate(e, ErrorManager.ERROR, null, message, null, null); 299 ErrorManager.getDefault().notify(e); 300 return; 301 } 302 Feed f = new Feed(url); 303 FileObject fld = folder.getPrimaryFile(); 304 String baseName = "RssFeed"; 305 int ix = 1; 306 while (fld.getFileObject(baseName + ix, "ser") != null) { 307 ix++; 308 } 309 try { 310 FileObject writeTo = fld.createData(baseName + ix, "ser"); 311 FileLock lock = writeTo.lock(); 312 try { 313 ObjectOutputStream str = new ObjectOutputStream (writeTo.getOutputStream(lock)); 314 try { 315 str.writeObject(f); 316 } finally { 317 str.close(); 318 } 319 } finally { 320 lock.releaseLock(); 321 } 322 } catch (IOException ioe) { 323 ErrorManager.getDefault().notify(ioe); 324 } 325 } 326 } 327 328 private static void checkConnection(final URL url) throws IOException { 329 InputStream is = url.openStream(); 330 is.close(); 331 } 332 333 } 334 335 } 336 | Popular Tags |