diff --git a/src/main/java/com/sun/syndication/feed/synd/SyndCategory.java b/src/main/java/com/sun/syndication/feed/synd/SyndCategory.java
index 82a5170..be70bb5 100644
--- a/src/main/java/com/sun/syndication/feed/synd/SyndCategory.java
+++ b/src/main/java/com/sun/syndication/feed/synd/SyndCategory.java
@@ -17,6 +17,8 @@
*/
package com.sun.syndication.feed.synd;
+import com.sun.syndication.feed.CopyFrom;
+
/**
* Bean interface for categories of SyndFeedImpl feeds and entries.
*
@@ -24,7 +26,7 @@ package com.sun.syndication.feed.synd;
* @author Alejandro Abdelnur
*
*/
-public interface SyndCategory extends Cloneable {
+public interface SyndCategory extends Cloneable, CopyFrom {
/**
* Returns the category name.
*
diff --git a/src/main/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java b/src/main/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java
index 12a0e61..c7f9f85 100644
--- a/src/main/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java
+++ b/src/main/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java
@@ -20,8 +20,13 @@ package com.sun.syndication.feed.synd;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import com.sun.syndication.feed.CopyFrom;
+import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.DCSubject;
import com.sun.syndication.feed.module.DCSubjectImpl;
@@ -175,6 +180,26 @@ public class SyndCategoryImpl implements Serializable, SyndCategory {
subject.setTaxonomyUri(taxonomyUri);
}
+ @Override
+ public Class extends CopyFrom> getInterface() {
+ return SyndCategory.class;
+ }
+
+ @Override
+ public void copyFrom(final CopyFrom extends SyndCategory> obj) {
+ COPY_FROM_HELPER.copy(this, obj);
+ }
+
+ private static final CopyFromHelper COPY_FROM_HELPER;
+
+ static {
+ final Map> basePropInterfaceMap = new HashMap>();
+ basePropInterfaceMap.put("name", String.class);
+ basePropInterfaceMap.put("taxonomyUri", String.class);
+ final Map>, Class>> basePropClassImplMap = Collections.emptyMap();
+ COPY_FROM_HELPER = new CopyFromHelper(SyndCategory.class, basePropInterfaceMap, basePropClassImplMap);
+ }
+
}
/**
diff --git a/src/main/java/com/sun/syndication/feed/synd/SyndEntryImpl.java b/src/main/java/com/sun/syndication/feed/synd/SyndEntryImpl.java
index 3b35618..61ab525 100644
--- a/src/main/java/com/sun/syndication/feed/synd/SyndEntryImpl.java
+++ b/src/main/java/com/sun/syndication/feed/synd/SyndEntryImpl.java
@@ -512,10 +512,12 @@ public class SyndEntryImpl implements Serializable, SyndEntry {
basePropInterfaceMap.put("contents", SyndContent.class);
basePropInterfaceMap.put("enclosures", SyndEnclosure.class);
basePropInterfaceMap.put("modules", Module.class);
+ basePropInterfaceMap.put("categories", SyndCategory.class);
final Map>, Class>> basePropClassImplMap = new HashMap>, Class>>();
basePropClassImplMap.put(SyndContent.class, SyndContentImpl.class);
basePropClassImplMap.put(SyndEnclosure.class, SyndEnclosureImpl.class);
+ basePropClassImplMap.put(SyndCategory.class, SyndCategoryImpl.class);
basePropClassImplMap.put(DCModule.class, DCModuleImpl.class);
basePropClassImplMap.put(SyModule.class, SyModuleImpl.class);
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 c9cd010..869a7e1 100644
--- a/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java
+++ b/src/main/java/com/sun/syndication/feed/synd/SyndFeedImpl.java
@@ -812,10 +812,12 @@ public class SyndFeedImpl implements Serializable, SyndFeed {
basePropInterfaceMap.put("image", SyndImage.class);
basePropInterfaceMap.put("entries", SyndEntry.class);
basePropInterfaceMap.put("modules", Module.class);
+ basePropInterfaceMap.put("categories", SyndCategory.class);
final Map>, Class>> basePropClassImplMap = new HashMap>, Class>>();
basePropClassImplMap.put(SyndEntry.class, SyndEntryImpl.class);
basePropClassImplMap.put(SyndImage.class, SyndImageImpl.class);
+ basePropClassImplMap.put(SyndCategory.class, SyndCategoryImpl.class);
basePropClassImplMap.put(DCModule.class, DCModuleImpl.class);
basePropClassImplMap.put(SyModule.class, SyModuleImpl.class);
diff --git a/src/test/java/com/sun/syndication/unittest/issues/Issue131Test.java b/src/test/java/com/sun/syndication/unittest/issues/Issue131Test.java
new file mode 100644
index 0000000..2e3adda
--- /dev/null
+++ b/src/test/java/com/sun/syndication/unittest/issues/Issue131Test.java
@@ -0,0 +1,67 @@
+package com.sun.syndication.unittest.issues;
+
+import java.util.List;
+
+import com.sun.syndication.feed.synd.SyndCategory;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndEntryImpl;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.SyndFeedImpl;
+import com.sun.syndication.unittest.FeedTest;
+
+/**
+ * Test for #131: SyndFeedImpl copyFrom method does not copy Entry Categories.
+ * @author Martin Kurz
+ *
+ */
+public class Issue131Test extends FeedTest {
+
+ public Issue131Test() {
+ super("issue131-rss.xml");
+ }
+
+ public void testOriginalCategories() throws Exception {
+ checkFeed(getCachedSyndFeed());
+ }
+
+ public void testCopiedFeedCategories() throws Exception {
+ final SyndFeed copiedFeed = new SyndFeedImpl();
+ copiedFeed.copyFrom(getCachedSyndFeed());
+ checkFeed(copiedFeed);
+ }
+
+ public void testCopiedFeedEntryCategories() throws Exception {
+ for (final SyndEntry entry : getCachedSyndFeed().getEntries()) {
+ final SyndEntry copiedEntry = new SyndEntryImpl();
+ copiedEntry.copyFrom(entry);
+ checkEntryCategories(copiedEntry.getCategories());
+ }
+ }
+
+ private void checkFeed(final SyndFeed feed) {
+ checkFeedCategories(feed.getCategories());
+ for (final SyndEntry entry : feed.getEntries()) {
+ checkEntryCategories(entry.getCategories());
+ }
+ }
+
+ private void checkFeedCategories(final List categories) {
+ assertNotNull(categories);
+ assertEquals(2, categories.size());
+ checkCategory(categories.get(0), "Channel Category 1");
+ checkCategory(categories.get(1), "Channel Category 2");
+ }
+
+ private void checkEntryCategories(final List categories) {
+ assertNotNull(categories);
+ assertEquals(2, categories.size());
+ checkCategory(categories.get(0), "Entry Category 1");
+ checkCategory(categories.get(1), "Entry Category 2");
+ }
+
+ private void checkCategory(final SyndCategory category, final String expectedName) {
+ assertNotNull(category);
+ assertEquals("http://somewhere.org/taxonomy", category.getTaxonomyUri());
+ assertEquals(expectedName, category.getName());
+ }
+}
diff --git a/src/test/resources/issue131-rss.xml b/src/test/resources/issue131-rss.xml
new file mode 100644
index 0000000..172402c
--- /dev/null
+++ b/src/test/resources/issue131-rss.xml
@@ -0,0 +1,30 @@
+
+
+
+ Testing
+ http://feeds.somewhere.org/
+ A dumb test feed file
+ en-us
+ Copyright (c) 200xx by nobody
+ Wed, 03 Sep 2008 00:00:00 EST
+ Wed, 03 Sep 2008 17:07:40 EST
+
+ Test Image
+ http://feeds.somewhere.org/feedImg.gif
+ http://feeds.somewhere.org
+ 125
+ 45
+ Test Feed Image
+
+ Channel Category 1
+ Channel Category 2
+ -
+ Entry 1
+ Entry Category 1
+ Entry Category 2
+ http://feeds.somewhere.org/index.jsp?id=2043
+ Entry 1 Description
+ Wed, 03 Sep 2008 17:03:03 EST
+
+
+