diff --git a/src/main/java/com/sun/syndication/feed/WireFeed.java b/src/main/java/com/sun/syndication/feed/WireFeed.java index d0b9b45..01f4fc5 100644 --- a/src/main/java/com/sun/syndication/feed/WireFeed.java +++ b/src/main/java/com/sun/syndication/feed/WireFeed.java @@ -47,6 +47,7 @@ public abstract class WireFeed implements Cloneable, Serializable, Extendable { private final ObjectBean objBean; private String feedType; private String encoding; + private String styleSheet; private List modules; private List foreignMarkup; @@ -251,4 +252,24 @@ public abstract class WireFeed implements Cloneable, Serializable, Extendable { public void setForeignMarkup(final List foreignMarkup) { this.foreignMarkup = foreignMarkup; } + + /** + * URL of XSL-Stylesheet. + * + * @since 2.0.0 + * @return styleSheet URL or {@code null} + */ + public String getStyleSheet() { + return styleSheet; + } + + /** + * URL of XSL-Stylesheet. + * + * @since 2.0.0 + * @param styleSheet URL or {@code null} + */ + public void setStyleSheet(String styleSheet) { + this.styleSheet = styleSheet; + } } diff --git a/src/main/java/com/sun/syndication/feed/synd/SyndFeed.java b/src/main/java/com/sun/syndication/feed/synd/SyndFeed.java index 1669f17..a353082 100644 --- a/src/main/java/com/sun/syndication/feed/synd/SyndFeed.java +++ b/src/main/java/com/sun/syndication/feed/synd/SyndFeed.java @@ -642,6 +642,22 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable { */ void setWebMaster(String webMaster); + /** + * URL of XSL-Stylesheet. + * + * @since 2.0.0 + * @return styleSheet URL or {@code null} + */ + String getStyleSheet(); + + /** + * URL of XSL-Stylesheet. + * + * @since 2.0.0 + * @param styleSheet URL or {@code null} + */ + void setStyleSheet(String styleSheet); + /** * Creates a deep clone of the object. *

diff --git a/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java b/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java index 4bb5a53..c9cd010 100644 --- a/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java +++ b/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java @@ -66,6 +66,7 @@ public class SyndFeedImpl implements Serializable, SyndFeed { private String managingEditor; private String docs; private String generator; + private String styleSheet; private List links; private SyndImage image; private List entries; @@ -997,4 +998,20 @@ public class SyndFeedImpl implements Serializable, SyndFeed { public void setWebMaster(String webMaster) { this.webMaster = webMaster; } + + /** + * {@inheritDoc} + */ + @Override + public String getStyleSheet() { + return styleSheet; + } + + /** + * {@inheritDoc} + */ + @Override + public void setStyleSheet(String styleSheet) { + this.styleSheet = styleSheet; + } } diff --git a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom03.java b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom03.java index 58f48a0..baea28b 100644 --- a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom03.java +++ b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom03.java @@ -70,6 +70,7 @@ public class ConverterForAtom03 implements Converter { } syndFeed.setEncoding(aFeed.getEncoding()); + syndFeed.setStyleSheet(aFeed.getStyleSheet()); syndFeed.setUri(aFeed.getId()); @@ -267,6 +268,7 @@ public class ConverterForAtom03 implements Converter { aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); aFeed.setEncoding(syndFeed.getEncoding()); + aFeed.setStyleSheet(syndFeed.getStyleSheet()); aFeed.setId(syndFeed.getUri()); diff --git a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java index b8c58f5..87ffe49 100644 --- a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java +++ b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForAtom10.java @@ -72,6 +72,7 @@ public class ConverterForAtom10 implements Converter { } syndFeed.setEncoding(aFeed.getEncoding()); + syndFeed.setStyleSheet(aFeed.getStyleSheet()); syndFeed.setUri(aFeed.getId()); @@ -314,6 +315,7 @@ public class ConverterForAtom10 implements Converter { aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); aFeed.setEncoding(syndFeed.getEncoding()); + aFeed.setStyleSheet(syndFeed.getStyleSheet()); aFeed.setId(syndFeed.getUri()); diff --git a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForRSS090.java b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForRSS090.java index 452c359..e30718e 100644 --- a/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForRSS090.java +++ b/src/main/java/com/sun/syndication/feed/synd/impl/ConverterForRSS090.java @@ -57,6 +57,7 @@ public class ConverterForRSS090 implements Converter { if (feed.getForeignMarkup().size() > 0) { syndFeed.setForeignMarkup(feed.getForeignMarkup()); } + syndFeed.setStyleSheet(feed.getStyleSheet()); syndFeed.setEncoding(feed.getEncoding()); final Channel channel = (Channel) feed; syndFeed.setTitle(channel.getTitle()); @@ -129,7 +130,7 @@ public class ConverterForRSS090 implements Converter { protected WireFeed createRealFeed(final String type, final SyndFeed syndFeed) { final Channel channel = new Channel(type); channel.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); - + channel.setStyleSheet(syndFeed.getStyleSheet()); channel.setEncoding(syndFeed.getEncoding()); channel.setTitle(syndFeed.getTitle()); diff --git a/src/main/java/com/sun/syndication/io/impl/Atom03Parser.java b/src/main/java/com/sun/syndication/io/impl/Atom03Parser.java index 7d431db..24484d4 100644 --- a/src/main/java/com/sun/syndication/io/impl/Atom03Parser.java +++ b/src/main/java/com/sun/syndication/io/impl/Atom03Parser.java @@ -28,6 +28,7 @@ import org.jdom2.output.XMLOutputter; import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.atom.Content; import com.sun.syndication.feed.atom.Entry; +import com.sun.syndication.feed.atom.Feed; import com.sun.syndication.feed.atom.Generator; import com.sun.syndication.feed.atom.Link; import com.sun.syndication.feed.atom.Person; @@ -80,7 +81,8 @@ public class Atom03Parser extends BaseWireFeedParser { protected WireFeed parseFeed(final Element eFeed) { - final com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType()); + final Feed feed = new Feed(getType()); + feed.setStyleSheet(getStyleSheet(eFeed.getDocument())); Element e = eFeed.getChild("title", getAtomNamespace()); if (e != null) { diff --git a/src/main/java/com/sun/syndication/io/impl/Atom10Parser.java b/src/main/java/com/sun/syndication/io/impl/Atom10Parser.java index 3c5c765..528a225 100644 --- a/src/main/java/com/sun/syndication/io/impl/Atom10Parser.java +++ b/src/main/java/com/sun/syndication/io/impl/Atom10Parser.java @@ -113,6 +113,7 @@ public class Atom10Parser extends BaseWireFeedParser { } final Feed feed = parseFeedMetadata(baseURI, eFeed); + feed.setStyleSheet(getStyleSheet(eFeed.getDocument())); final String xmlBase = eFeed.getAttributeValue("base", Namespace.XML_NAMESPACE); if (xmlBase != null) { diff --git a/src/main/java/com/sun/syndication/io/impl/BaseWireFeedParser.java b/src/main/java/com/sun/syndication/io/impl/BaseWireFeedParser.java index 036ac86..a8d5534 100644 --- a/src/main/java/com/sun/syndication/io/impl/BaseWireFeedParser.java +++ b/src/main/java/com/sun/syndication/io/impl/BaseWireFeedParser.java @@ -5,8 +5,12 @@ import java.util.Iterator; import java.util.List; import org.jdom2.Attribute; +import org.jdom2.Content; +import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.Namespace; +import org.jdom2.ProcessingInstruction; +import org.jdom2.filter.ContentFilter; import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.module.Extendable; @@ -117,4 +121,15 @@ public abstract class BaseWireFeedParser implements WireFeedParser { } } + protected String getStyleSheet(final Document doc) { + String styleSheet = null; + for (final Content c : doc.getContent(new ContentFilter(ContentFilter.PI))) { + final ProcessingInstruction pi = (ProcessingInstruction) c; + if ("text/xsl".equals(pi.getPseudoAttributeValue("type"))) { + styleSheet = pi.getPseudoAttributeValue("href"); + break; + } + } + return styleSheet; + } } diff --git a/src/main/java/com/sun/syndication/io/impl/RSS090Parser.java b/src/main/java/com/sun/syndication/io/impl/RSS090Parser.java index 87d9970..684d8e4 100644 --- a/src/main/java/com/sun/syndication/io/impl/RSS090Parser.java +++ b/src/main/java/com/sun/syndication/io/impl/RSS090Parser.java @@ -150,6 +150,7 @@ public class RSS090Parser extends BaseWireFeedParser { final Element eChannel = rssRoot.getChild("channel", getRSSNamespace()); final Channel channel = new Channel(getType()); + channel.setStyleSheet(getStyleSheet(rssRoot.getDocument())); Element e = eChannel.getChild("title", getRSSNamespace()); if (e != null) { diff --git a/src/test/java/com/sun/syndication/unittest/issues/Issue88Test.java b/src/test/java/com/sun/syndication/unittest/issues/Issue88Test.java new file mode 100644 index 0000000..d896567 --- /dev/null +++ b/src/test/java/com/sun/syndication/unittest/issues/Issue88Test.java @@ -0,0 +1,21 @@ +package com.sun.syndication.unittest.issues; + +import com.sun.syndication.unittest.FeedTest; + +/** + * Test for #134: Incorrect handling of CDATA sections. + * @author Martin Kurz + * + */ +public class Issue88Test extends FeedTest { + + public Issue88Test() { + super("rss_2.0.xml"); + } + + public void testStyleSheet() throws Exception { + assertEquals("stylesheet in syndfeed missing", "http://test.example/test.xslt", this.getCachedSyndFeed().getStyleSheet()); + assertEquals("stylesheet in wirefeed missing", "http://test.example/test.xslt", this.getCachedWireFeed().getStyleSheet()); + } + +} diff --git a/src/test/resources/rss_2.0.xml b/src/test/resources/rss_2.0.xml index e033320..a26e447 100644 --- a/src/test/resources/rss_2.0.xml +++ b/src/test/resources/rss_2.0.xml @@ -1,4 +1,5 @@ +