📄 basefeed.java
字号:
String.valueOf(feedState.startIndex)); } if (feedState.itemsPerPage != Query.UNDEFINED) { w.simpleElement(Namespaces.openSearchNs, "itemsPerPage", null, String.valueOf(feedState.itemsPerPage)); } // Invoke ExtensionPoint. generateExtensions(w, extProfile); } /** * Generates XML in the RSS format. * * @param w * Output writer. * * @param extProfile * Extension profile. * * @throws IOException */ public void generateRss(XmlWriter w, ExtensionProfile extProfile) throws IOException { Vector<XmlWriter.Namespace> nsDecls = new Vector<XmlWriter.Namespace>(namespaceDeclsRss); nsDecls.addAll(extProfile.getNamespaceDecls()); w.startElement(Namespaces.rssNs, "rss", rssHeaderAttrs, nsDecls); generateStartElement(w, Namespaces.rssNs, "channel", null, null); if (srcState.id != null) { w.simpleElement(Namespaces.atomNs, "id", null, srcState.id); } if (xmlBlob != null) { String lang = xmlBlob.getLang(); if (lang != null) { w.simpleElement(Namespaces.rssNs, "language", null, lang); } } if (srcState.updated != null) { w.simpleElement(Namespaces.rssNs, "lastBuildDate", null, srcState.updated.toStringRfc822()); } w.startRepeatingElement(); for (Category cat : srcState.categories) { cat.generateRss(w); } w.endRepeatingElement(); if (srcState.title != null) { srcState.title.generateRss(w, "title", TextConstruct.RssFormat.PLAIN_TEXT); } if (srcState.subtitle != null) { srcState.subtitle.generateRss(w, "description", TextConstruct.RssFormat.FULL_HTML); } else { w.simpleElement(Namespaces.rssNs, "description", null, null); } Link htmlLink = getHtmlLink(); if (htmlLink != null) { w.simpleElement(Namespaces.rssNs, "link", null, htmlLink.getHref()); } if (srcState.logo != null || srcState.icon != null) { w.startElement(Namespaces.rssNs, "image", null, null); w.simpleElement(Namespaces.rssNs, "url", null, srcState.logo != null ? srcState.logo : srcState.icon); if (srcState.title != null) { srcState.title.generateRss(w, "title", TextConstruct.RssFormat.PLAIN_TEXT); } if (htmlLink != null) { w.simpleElement(Namespaces.rssNs, "link", null, htmlLink.getHref()); } w.endElement(Namespaces.rssNs, "image"); } if (srcState.rights != null) { srcState.rights.generateRss(w, "copyright", TextConstruct.RssFormat.PLAIN_TEXT); } if (srcState.authors.size() > 0) { srcState.authors.get(0).generateRss(w, "managingEditor"); } if (srcState.generator != null) { String name = srcState.generator.getName(); if (name != null) { w.simpleElement(Namespaces.rssNs, "generator", null, name); } } if (feedState.totalResults != Query.UNDEFINED) { w.simpleElement(Namespaces.openSearchNs, "totalResults", null, String.valueOf(feedState.totalResults)); } if (feedState.startIndex != Query.UNDEFINED) { w.simpleElement(Namespaces.openSearchNs, "startIndex", null, String.valueOf(feedState.startIndex)); } if (feedState.itemsPerPage != Query.UNDEFINED) { w.simpleElement(Namespaces.openSearchNs, "itemsPerPage", null, String.valueOf(feedState.itemsPerPage)); } // Invoke ExtensionPoint. generateExtensions(w, extProfile); w.startRepeatingElement(); for (E entry : entries) { entry.generateRss(w, extProfile); } w.endRepeatingElement(); w.endElement(Namespaces.rssNs, "channel"); w.endElement(Namespaces.rssNs, "rss"); } /** Top-level namespace declarations for generated XML. */ private static final Collection<XmlWriter.Namespace> namespaceDeclsAtom = new Vector<XmlWriter.Namespace>(2); private static final Collection<XmlWriter.Namespace> namespaceDeclsRss = new Vector<XmlWriter.Namespace>(2); private static final Collection<XmlWriter.Attribute> rssHeaderAttrs = new Vector<XmlWriter.Attribute>(1); static { namespaceDeclsAtom.add(Namespaces.atomNs); namespaceDeclsAtom.add(Namespaces.openSearchNs); namespaceDeclsRss.add(Namespaces.atomNs); namespaceDeclsRss.add(Namespaces.openSearchNs); rssHeaderAttrs.add(new XmlWriter.Attribute("version", "2.0")); } /** * Reads a feed representation from the provided {@link ParseSource}. * The return type of the feed will be determined using dynamic adaptation * based upon any {@link Kind} category tag found in the input content. If * no kind tag is found a {@link Feed} instance will be returned. */ public static BaseFeed readFeed(ParseSource source) throws IOException, ParseException, ServiceException { return readFeed(source, null, null); } // This method provides the base implementation of feed reading using either // static or dynamic typing. If feedClass is non-null, the method is // guaranteed to return an instance of this type, otherwise adaptation will // be used to determine the type. The source object may be either an // InputStream, Reader, or XmlParser. public static <F extends BaseFeed> F readFeed(ParseSource source, Class <F> feedClass, ExtensionProfile extProfile) throws IOException, ParseException, ServiceException { if (source == null) { throw new NullPointerException("Null source"); } // Determine the parse feed type boolean isAdapting = (feedClass == null); if (isAdapting) { feedClass = (Class<F>) Feed.class; } // Create a new feed instance. F feed; try { feed = feedClass.newInstance(); } catch (IllegalAccessException iae) { throw new ServiceException("Unable to create feed", iae); } catch (InstantiationException ie) { throw new ServiceException("Unable to create feed", ie); } // Initialize the extension profile (if not provided) if (extProfile == null) { extProfile = new ExtensionProfile(); feed.declareExtensions(extProfile); if (isAdapting) { extProfile.setAutoExtending(true); } } // Parse the content if (source.getReader() != null) { feed.parseAtom(extProfile, source.getReader()); } else if (source.getInputStream() != null) { feed.parseAtom(extProfile, source.getInputStream()); } else if (source.getParser() != null) { feed.parseAtom(extProfile, source.getParser()); } else { throw new IllegalStateException("Invalid source: " + source.getClass()); } // Adapt if requested and the feed contained a kind tag if (isAdapting) { F adaptedFeed = (F) feed.getAdaptedFeed(); if (adaptedFeed != null) { feed = adaptedFeed; } } return feed; } /** * Parses XML in the Atom format. * * @param extProfile * Extension profile. * * @param input * XML input stream. */ public void parseAtom(ExtensionProfile extProfile, InputStream input) throws IOException, ParseException { FeedHandler handler = new FeedHandler(extProfile); new XmlParser().parse(input, handler, Namespaces.atom, "feed"); } /** * Parses XML in the Atom format. * * @param extProfile * Extension profile. * * @param reader * XML Reader. The caller is responsible for ensuring that * the character encoding is correct. */ public void parseAtom(ExtensionProfile extProfile, Reader reader) throws IOException, ParseException { FeedHandler handler = new FeedHandler(extProfile); new XmlParser().parse(reader, handler, Namespaces.atom, "feed"); } /** * Parses XML in the Atom format from a parser-defined content source. * * @param extProfile * Extension profile. * * @param parser * XML parser. */ public void parseAtom(ExtensionProfile extProfile, XmlParser parser) throws IOException, ParseException { FeedHandler handler = new FeedHandler(extProfile); parser.parse(handler, Namespaces.atom, "feed"); } /** {@code <atom:feed>} parser. */ public class FeedHandler extends SourceHandler { public FeedHandler(ExtensionProfile extProfile) throws IOException { super(extProfile, BaseFeed.this.getClass()); } public ElementHandler getChildHandler(String namespace, String localName, Attributes attrs) throws ParseException, IOException { // Try ExtensionPoint. It returns {@code null} if there's no handler. ElementHandler extensionHandler = getExtensionHandler(extProfile, Feed.class, namespace, localName, attrs); if (extensionHandler != null) { return extensionHandler; } if (namespace.equals(Namespaces.atom)) { if (localName.equals("entry")) { E entry = createEntry(); entries.add(entry); return (ElementHandler) ((BaseEntry) entry).new AtomHandler( extProfile); } // All other elements in the Atom namespace are handled by // the SourceHandler superclass return super.getChildHandler(namespace, localName, attrs); } else if (namespace.equals(Namespaces.openSearch)) { if (localName.equals("totalResults")) { return new TotalResultsHandler(); } else if (localName.equals("startIndex")) { return new StartIndexHandler(); } else if (localName.equals("itemsPerPage")) { return new ItemsPerPageHandler(); } } else { return super.getChildHandler(namespace, localName, attrs); } return null; } /** {@code <opensearch:totalResults>} parser. */ private class TotalResultsHandler extends ElementHandler { public void processEndElement() throws ParseException { if (feedState.totalResults != Query.UNDEFINED) { throw new ParseException("Duplicate totalResults."); } if (value == null) { throw new ParseException("logo must have a value."); } try { feedState.totalResults = Integer.valueOf(value).intValue(); } catch (NumberFormatException e) { throw new ParseException("totalResults is not an integer"); } } } /** {@code <opensearch:startIndex>} parser. */ private class StartIndexHandler extends ElementHandler { public void processEndElement() throws ParseException { if (feedState.startIndex != Query.UNDEFINED) { throw new ParseException("Duplicate startIndex."); } if (value == null) { throw new ParseException("logo must have a value."); } try { feedState.startIndex = Integer.valueOf(value).intValue(); } catch (NumberFormatException e) { throw new ParseException("startIndex must be an integer"); } } } /** {@code <opensearch:itemsPerPage>} parser. */ private class ItemsPerPageHandler extends ElementHandler { public void processEndElement() throws ParseException { if (feedState.itemsPerPage != Query.UNDEFINED) { throw new ParseException("Duplicate itemsPerPage."); } if (value == null) { throw new ParseException("logo must have a value."); } try { feedState.itemsPerPage = Integer.valueOf(value).intValue(); } catch (NumberFormatException e) { throw new ParseException("itemsPerPage is not an integer"); } } } public void processEndElement() throws ParseException { // Set the canPost flag based upon the presence of an entry post // link relation in the parsed feed. feedState.canPost = getEntryPostLink() != null; } } /** * Locates and returns the most specific {@link Kind.Adaptor} feed * subtype for this feed. If none can be found for the current class, * {@code null} will be returned. */ public BaseFeed<?, ?> getAdaptedFeed() throws Kind.AdaptorException { BaseFeed adaptedFeed = null; // Find the BaseFeed adaptor instance that is most specific. for (Kind.Adaptor adaptor : getAdaptors()) { if (!(adaptor instanceof BaseFeed)) { continue; } // if first matching adaptor or a narrower subtype of the current one, // then use it. if (adaptedFeed == null || adaptedFeed.getClass().isAssignableFrom(adaptor.getClass())) { adaptedFeed = (BaseFeed) adaptor; } } // If an adapted feed was found, then also synchronize the current set // of entries into it, adapting them as well. if (adaptedFeed != null) { List<E> sourceEntries; if (adaptedFeed != this) { sourceEntries = entries; } else { // Copy before clearing sourceEntries = new ArrayList<E>(); sourceEntries.addAll(entries); } adaptedFeed.getEntries().clear(); for (BaseEntry entry : sourceEntries) { adaptedFeed.getEntries().add(entry.getAdaptedEntry()); } } return adaptedFeed; } /** * Gets a list of entries of a particular kind. */ public <T extends BaseEntry> List<T> getEntries(Class<T> returnClass) { List<T> adaptedEntries = new ArrayList<T>(); for (BaseEntry<?> entry : getEntries()) { T adapted = entry.getAdaptor(returnClass); if (adapted != null) { adaptedEntries.add(adapted); } } return adaptedEntries; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -