From f9576b8d00e9fd7b94c770591dfd988782ba7bc3 Mon Sep 17 00:00:00 2001 From: Patrick Gotthard Date: Fri, 8 Jan 2016 18:29:50 +0100 Subject: [PATCH] Refactored some code --- .../rometools/opml/feed/opml/Attribute.java | 201 ++--- .../com/rometools/opml/feed/opml/Opml.java | 655 ++++++++------- .../com/rometools/opml/feed/opml/Outline.java | 744 +++++++++--------- .../feed/synd/impl/ConverterForOPML10.java | 714 ++++++++--------- .../feed/synd/impl/ConverterForOPML20.java | 117 ++- .../opml/feed/synd/impl/TreeCategoryImpl.java | 61 +- .../opml/io/impl/OPML10Generator.java | 11 +- .../rometools/opml/io/impl/OPML10Parser.java | 10 +- .../opml/io/impl/OPML20Generator.java | 35 +- 9 files changed, 1215 insertions(+), 1333 deletions(-) diff --git a/src/main/java/com/rometools/opml/feed/opml/Attribute.java b/src/main/java/com/rometools/opml/feed/opml/Attribute.java index 5934d75..7e29065 100644 --- a/src/main/java/com/rometools/opml/feed/opml/Attribute.java +++ b/src/main/java/com/rometools/opml/feed/opml/Attribute.java @@ -1,114 +1,87 @@ -/* - * Attribute.java - * - * Created on April 24, 2006, 11:11 PM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.rometools.opml.feed.opml; - -import java.io.Serializable; - -import com.rometools.rome.feed.impl.EqualsBean; -import com.rometools.rome.feed.impl.ToStringBean; - -/** - * This is a simple name-value pair attribute for outlines. - * - * @author Robert "kebernet" Cooper - */ -public class Attribute implements Cloneable, Serializable { - - private static final long serialVersionUID = 1L; - - private String _name; - private String _value; - - /** Creates a new instance of Attribute */ - public Attribute() { - super(); - } - - /** - * Creates a new instance of Attribute. - * - * @param name name of the attribute. - * @param value value of the attribute. - */ - public Attribute(final String name, final String value) { - if (name == null || value == null) { - throw new NullPointerException("Name and value are required."); - } - setName(name); - setValue(value); - } - - /** - * name of the attribute. - * - * @param name name of the attribute. - */ - public void setName(final String name) { - _name = name; - } - - /** - * name of the attribute. - * - * @return name of the attribute. - */ - public String getName() { - return _name; - } - - /** - * value of the attribute. - * - * @param value value of the attribute. - */ - public void setValue(final String value) { - _value = value; - } - - /** - * value of the attribute. - * - * @return value of the attribute. - */ - public String getValue() { - return _value; - } - - @Override - public Object clone() { - return new Attribute(_name, _value); - } - - @Override - public boolean equals(final Object obj) { - final EqualsBean eBean = new EqualsBean(Attribute.class, this); - return eBean.beanEquals(obj); - } - - @Override - public int hashCode() { - final EqualsBean equals = new EqualsBean(Attribute.class, this); - return equals.beanHashCode(); - } - - @Override - public String toString() { - final ToStringBean tsBean = new ToStringBean(Attribute.class, this); - return tsBean.toString(); - } -} +/* + * Attribute.java + * + * Created on April 24, 2006, 11:11 PM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rometools.opml.feed.opml; + +import java.io.Serializable; + +import com.rometools.rome.feed.impl.EqualsBean; +import com.rometools.rome.feed.impl.ToStringBean; + +/** + * This is a simple name-value pair attribute for outlines. + * + * @author Robert "kebernet" Cooper + */ +public class Attribute implements Cloneable, Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + private String value; + + /** + * Creates a new instance of Attribute. + * + * @param name name of the attribute. + * @param value value of the attribute. + */ + public Attribute(final String name, final String value) { + if (name == null || value == null) { + throw new NullPointerException("Name and value are required."); + } + setName(name); + setValue(value); + } + + public void setName(final String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setValue(final String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public Object clone() { + return new Attribute(name, value); + } + + @Override + public boolean equals(final Object obj) { + return new EqualsBean(Attribute.class, this).beanEquals(obj); + } + + @Override + public int hashCode() { + return new EqualsBean(Attribute.class, this).beanHashCode(); + } + + @Override + public String toString() { + return new ToStringBean(Attribute.class, this).toString(); + } + +} diff --git a/src/main/java/com/rometools/opml/feed/opml/Opml.java b/src/main/java/com/rometools/opml/feed/opml/Opml.java index da17604..3b1fbd8 100644 --- a/src/main/java/com/rometools/opml/feed/opml/Opml.java +++ b/src/main/java/com/rometools/opml/feed/opml/Opml.java @@ -1,333 +1,322 @@ -/* - * Opml.java - * - * Created on April 24, 2006, 11:00 PM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.rometools.opml.feed.opml; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import com.rometools.rome.feed.WireFeed; - -/** - * This class represents the root of an OPML 1/2 feed and contains the elements that may appear in - * the <head> tag of the feed. - * - * @author Robert "kebernet" Cooper - */ -public class Opml extends WireFeed { - - private static final long serialVersionUID = 1L; - - private Date _created; - private Date _modified; - private Integer _verticalScrollState; - private Integer _windowBottom; - private Integer _windowLeft; - private Integer _windowRight; - private Integer _windowTop; - private List _outlines; - private String _docs; - private String _ownerEmail; - private String _ownerId; - private String _ownerName; - private String _title; - private int[] _expansionState; - - /** Creates a new instance of Opml */ - public Opml() { - super(); - } - - /** - * is a date-time, indicating when the document was created. - * - * @param created date-time, indicating when the document was created. - */ - public void setCreated(final Date created) { - _created = created; - } - - /** - * <dateCreated> is a date-time, indicating when the document was created. - * - * @return date-time, indicating when the document was created. - */ - public Date getCreated() { - return _created; - } - - /** - * (OPML 2) <docs> is the http address of documentation for the format used in the OPML - * file. It's probably a pointer to this page for people - * who might stumble across the file on a web server 25 years from now and wonder what it is. - * - * @param docs http address of documentation for the format used - */ - public void setDocs(final String docs) { - _docs = docs; - } - - /** - * (OPML 2) <docs> is the http address of documentation for the format used in the OPML - * file. It's probably a pointer to this page for people - * who might stumble across the file on a web server 25 years from now and wonder what it is. - * - * @return http address of documentation for the format used - */ - public String getDocs() { - return _docs; - } - - /** - * <expansionState>is a comma-separated list of line numbers that are expanded. The line - * numbers in the list tell you which headlines to expand. The order is important. For each - * element in the list, X, starting at the first summit, navigate flatdown X times and expand. - * Repeat for each element in the list. - * - * @param expansionState int array containing expanded elements. - */ - public void setExpansionState(final int[] expansionState) { - _expansionState = expansionState; - } - - /** - * <expansionState> is a comma-separated list of line numbers that are expanded. The line - * numbers in the list tell you which headlines to expand. The order is important. For each - * element in the list, X, starting at the first summit, navigate flatdown X times and expand. - * Repeat for each element in the list. - * - * @return int array containing expanded elements. - */ - public int[] getExpansionState() { - return _expansionState; - } - - /** - * <dateModified> is a date-time, indicating when the document was last modified. - * - * @param modified date-time, indicating when the document was last modified. - */ - public void setModified(final Date modified) { - _modified = modified; - } - - /** - * <dateModified> is a date-time, indicating when the document was last modified. - * - * @return date-time, indicating when the document was last modified. - */ - public Date getModified() { - return _modified; - } - - /** - * Root level Outline object that should appear in the <body> - * - * @param outlines Root level Outline object that should appear in the <body> - */ - public void setOutlines(final List outlines) { - _outlines = outlines; - } - - /** - * Root level Outline object that should appear in the <body> - * - * @return Root level Outline object that should appear in the <body> - */ - public List getOutlines() { - if (_outlines == null) { - _outlines = new ArrayList(); - } - - return _outlines; - } - - /** - * <ownerEmail> is a string, the email address of the owner of the document. - * - * @param ownerEmail the email address of the owner of the document. - */ - public void setOwnerEmail(final String ownerEmail) { - _ownerEmail = ownerEmail; - } - - /** - * <ownerEmail> is a string, the email address of the owner of the document. - * - * @return the email address of the owner of the document. - */ - public String getOwnerEmail() { - return _ownerEmail; - } - - /** - * (OPML 2) <ownerId> is the http address of a web page that contains an - * HTML a form that allows a human reader to communicate with the author of the - * document via email or other means. - * - * @param ownerId http address of a web page that contains an HTML a form that - * allows a human reader to communicate with the author of the document via email or - * other means. - */ - public void setOwnerId(final String ownerId) { - _ownerId = ownerId; - } - - /** - * (OPML 2) <ownerId> is the http address of a web page that contains an - * HTML a form that allows a human reader to communicate with the author of the - * document via email or other means. - * - * @return http address of a web page that contains an HTML a form that allows - * a human reader to communicate with the author of the document via email or other - * means. - */ - public String getOwnerId() { - return _ownerId; - } - - /** - * <ownerName> is a string, the owner of the document. - * - * @param ownerName the owner of the document. - */ - public void setOwnerName(final String ownerName) { - _ownerName = ownerName; - } - - /** - * <ownerName> is a string, the owner of the document. - * - * @return the owner of the document. - */ - public String getOwnerName() { - return _ownerName; - } - - /** - * <title> is the title of the document. - * - * @param title title of the document. - */ - public void setTitle(final String title) { - _title = title; - } - - /** - * <title> is the title of the document. - * - * @return title of the document. - */ - public String getTitle() { - return _title; - } - - /** - * <vertScrollState> is a number, saying which line of the outline is displayed on the top - * line of the window. This number is calculated with the expansion state already applied. - * - * @param verticalScrollState which line of the outline is displayed on the top line of the - * window. - */ - public void setVerticalScrollState(final Integer verticalScrollState) { - _verticalScrollState = verticalScrollState; - } - - /** - * <vertScrollState> is a number, saying which line of the outline is displayed on the top - * line of the window. This number is calculated with the expansion state already applied. - * - * @return which line of the outline is displayed on the top line of the window. This number is - * calculated with the expansion state already applied. - */ - public Integer getVerticalScrollState() { - return _verticalScrollState; - } - - /** - * <windowBottom> is a number, the pixel location of the bottom edge of the window. - * - * @param windowBottom the pixel location of the bottom edge of the window. - */ - public void setWindowBottom(final Integer windowBottom) { - _windowBottom = windowBottom; - } - - /** - * <windowBottom> is a number, the pixel location of the bottom edge of the window. - * - * @return the pixel location of the bottom edge of the window. - */ - public Integer getWindowBottom() { - return _windowBottom; - } - - /** - * <windowLeft> is a number, the pixel location of the left edge of the window. - * - * @param windowLeft the pixel location of the left edge of the window. - */ - public void setWindowLeft(final Integer windowLeft) { - _windowLeft = windowLeft; - } - - /** - * <windowLeft> is a number, the pixel location of the left edge of the window. - * - * @return the pixel location of the left edge of the window. - */ - public Integer getWindowLeft() { - return _windowLeft; - } - - /** - * <windowRight> is a number, the pixel location of the right edge of the window. - * - * @param windowRight the pixel location of the right edge of the window. - */ - public void setWindowRight(final Integer windowRight) { - _windowRight = windowRight; - } - - /** - * <windowRight> is a number, the pixel location of the right edge of the window. - * - * @return the pixel location of the right edge of the window. - */ - public Integer getWindowRight() { - return _windowRight; - } - - /** - * <windowTop> is a number, the pixel location of the top edge of the window. - * - * @param windowTop the pixel location of the top edge of the window. - */ - public void setWindowTop(final Integer windowTop) { - _windowTop = windowTop; - } - - /** - * <windowTop> is a number, the pixel location of the top edge of the window. - * - * @return the pixel location of the top edge of the window. - */ - public Integer getWindowTop() { - return _windowTop; - } -} +/* + * Opml.java + * + * Created on April 24, 2006, 11:00 PM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rometools.opml.feed.opml; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.rometools.rome.feed.WireFeed; + +/** + * This class represents the root of an OPML 1/2 feed and contains the elements that may appear in the <head> tag + * of the feed. + * + * @author Robert "kebernet" Cooper + */ +public class Opml extends WireFeed { + + private static final long serialVersionUID = 1L; + + private Date created; + private Date modified; + private Integer verticalScrollState; + private Integer windowBottom; + private Integer windowLeft; + private Integer windowRight; + private Integer windowTop; + private List outlines; + private String docs; + private String ownerEmail; + private String ownerId; + private String ownerName; + private String title; + private int[] expansionState; + + /** + * is a date-time, indicating when the document was created. + * + * @param created date-time, indicating when the document was created. + */ + public void setCreated(final Date created) { + this.created = created; + } + + /** + * <dateCreated> is a date-time, indicating when the document was created. + * + * @return date-time, indicating when the document was created. + */ + public Date getCreated() { + return created; + } + + /** + * (OPML 2) <docs> is the http address of documentation for the format used in the OPML file. It's probably a + * pointer to this page for people who might stumble across the file on a + * web server 25 years from now and wonder what it is. + * + * @param docs http address of documentation for the format used + */ + public void setDocs(final String docs) { + this.docs = docs; + } + + /** + * (OPML 2) <docs> is the http address of documentation for the format used in the OPML file. It's probably a + * pointer to this page for people who might stumble across the file on a + * web server 25 years from now and wonder what it is. + * + * @return http address of documentation for the format used + */ + public String getDocs() { + return docs; + } + + /** + * <expansionState>is a comma-separated list of line numbers that are expanded. The line numbers in the list + * tell you which headlines to expand. The order is important. For each element in the list, X, starting at the + * first summit, navigate flatdown X times and expand. Repeat for each element in the list. + * + * @param expansionState int array containing expanded elements. + */ + public void setExpansionState(final int[] expansionState) { + this.expansionState = expansionState; + } + + /** + * <expansionState> is a comma-separated list of line numbers that are expanded. The line numbers in the list + * tell you which headlines to expand. The order is important. For each element in the list, X, starting at the + * first summit, navigate flatdown X times and expand. Repeat for each element in the list. + * + * @return int array containing expanded elements. + */ + public int[] getExpansionState() { + return expansionState; + } + + /** + * <dateModified> is a date-time, indicating when the document was last modified. + * + * @param modified date-time, indicating when the document was last modified. + */ + public void setModified(final Date modified) { + this.modified = modified; + } + + /** + * <dateModified> is a date-time, indicating when the document was last modified. + * + * @return date-time, indicating when the document was last modified. + */ + public Date getModified() { + return modified; + } + + /** + * Root level Outline object that should appear in the <body> + * + * @param outlines Root level Outline object that should appear in the <body> + */ + public void setOutlines(final List outlines) { + this.outlines = outlines; + } + + /** + * Root level Outline object that should appear in the <body> + * + * @return Root level Outline object that should appear in the <body> + */ + public List getOutlines() { + if (outlines == null) { + outlines = new ArrayList(); + } + + return outlines; + } + + /** + * <ownerEmail> is a string, the email address of the owner of the document. + * + * @param ownerEmail the email address of the owner of the document. + */ + public void setOwnerEmail(final String ownerEmail) { + this.ownerEmail = ownerEmail; + } + + /** + * <ownerEmail> is a string, the email address of the owner of the document. + * + * @return the email address of the owner of the document. + */ + public String getOwnerEmail() { + return ownerEmail; + } + + /** + * (OPML 2) <ownerId> is the http address of a web page that contains an HTML a form that + * allows a human reader to communicate with the author of the document via email or other means. + * + * @param ownerId http address of a web page that contains an HTML a form that allows a human + * reader to communicate with the author of the document via email or other means. + */ + public void setOwnerId(final String ownerId) { + this.ownerId = ownerId; + } + + /** + * (OPML 2) <ownerId> is the http address of a web page that contains an HTML a form that + * allows a human reader to communicate with the author of the document via email or other means. + * + * @return http address of a web page that contains an HTML a form that allows a human reader to + * communicate with the author of the document via email or other means. + */ + public String getOwnerId() { + return ownerId; + } + + /** + * <ownerName> is a string, the owner of the document. + * + * @param ownerName the owner of the document. + */ + public void setOwnerName(final String ownerName) { + this.ownerName = ownerName; + } + + /** + * <ownerName> is a string, the owner of the document. + * + * @return the owner of the document. + */ + public String getOwnerName() { + return ownerName; + } + + /** + * <title> is the title of the document. + * + * @param title title of the document. + */ + public void setTitle(final String title) { + this.title = title; + } + + /** + * <title> is the title of the document. + * + * @return title of the document. + */ + public String getTitle() { + return title; + } + + /** + * <vertScrollState> is a number, saying which line of the outline is displayed on the top line of the window. + * This number is calculated with the expansion state already applied. + * + * @param verticalScrollState which line of the outline is displayed on the top line of the window. + */ + public void setVerticalScrollState(final Integer verticalScrollState) { + this.verticalScrollState = verticalScrollState; + } + + /** + * <vertScrollState> is a number, saying which line of the outline is displayed on the top line of the window. + * This number is calculated with the expansion state already applied. + * + * @return which line of the outline is displayed on the top line of the window. This number is calculated with the + * expansion state already applied. + */ + public Integer getVerticalScrollState() { + return verticalScrollState; + } + + /** + * <windowBottom> is a number, the pixel location of the bottom edge of the window. + * + * @param windowBottom the pixel location of the bottom edge of the window. + */ + public void setWindowBottom(final Integer windowBottom) { + this.windowBottom = windowBottom; + } + + /** + * <windowBottom> is a number, the pixel location of the bottom edge of the window. + * + * @return the pixel location of the bottom edge of the window. + */ + public Integer getWindowBottom() { + return windowBottom; + } + + /** + * <windowLeft> is a number, the pixel location of the left edge of the window. + * + * @param windowLeft the pixel location of the left edge of the window. + */ + public void setWindowLeft(final Integer windowLeft) { + this.windowLeft = windowLeft; + } + + /** + * <windowLeft> is a number, the pixel location of the left edge of the window. + * + * @return the pixel location of the left edge of the window. + */ + public Integer getWindowLeft() { + return windowLeft; + } + + /** + * <windowRight> is a number, the pixel location of the right edge of the window. + * + * @param windowRight the pixel location of the right edge of the window. + */ + public void setWindowRight(final Integer windowRight) { + this.windowRight = windowRight; + } + + /** + * <windowRight> is a number, the pixel location of the right edge of the window. + * + * @return the pixel location of the right edge of the window. + */ + public Integer getWindowRight() { + return windowRight; + } + + /** + * <windowTop> is a number, the pixel location of the top edge of the window. + * + * @param windowTop the pixel location of the top edge of the window. + */ + public void setWindowTop(final Integer windowTop) { + this.windowTop = windowTop; + } + + /** + * <windowTop> is a number, the pixel location of the top edge of the window. + * + * @return the pixel location of the top edge of the window. + */ + public Integer getWindowTop() { + return windowTop; + } + +} diff --git a/src/main/java/com/rometools/opml/feed/opml/Outline.java b/src/main/java/com/rometools/opml/feed/opml/Outline.java index 14e988d..2d97405 100644 --- a/src/main/java/com/rometools/opml/feed/opml/Outline.java +++ b/src/main/java/com/rometools/opml/feed/opml/Outline.java @@ -1,377 +1,367 @@ -/* - * Outline.java - * - * Created on April 24, 2006, 11:04 PM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.rometools.opml.feed.opml; - -import java.io.Serializable; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import com.rometools.rome.feed.impl.EqualsBean; -import com.rometools.rome.feed.impl.ToStringBean; -import com.rometools.rome.feed.module.Module; - -/** - * This class represents an OPML outline element. - * - * @author Robert "kebernet" Cooper - */ -public class Outline implements Cloneable, Serializable { - - private static final long serialVersionUID = 1L; - - private Date _created; - private List _attributes; - private List _categories; - private List _children; - private List _modules; - private String _text; - private String _title; - private String _type; - private boolean _breakpoint; - private boolean _comment; - - /** Creates a new instance of Outline */ - public Outline() { - super(); - } - - /** - * Creates a new outline with the specified type and text values. - * - * @param type type attribute value/ - * @param text text attribute value - */ - public Outline(final String type, final String text) { - super(); - setType(type); - setText(text); - } - - /** - * Creates an outline with the given title, xmlUrl and htmlUrl. This is traditionally used for - * aggregator feed lists and will get a type of "rss". - * - * @param title Title of the entry. - * @param xmlUrl link to XML file. - * @param htmlUrl link to html page. - */ - public Outline(final String title, final URL xmlUrl, final URL htmlUrl) { - super(); - setType("rss"); - setTitle(title); - setAttributes(new ArrayList()); - - if (xmlUrl != null) { - getAttributes().add(new Attribute("xmlUrl", xmlUrl.toString())); - } - - if (htmlUrl != null) { - getAttributes().add(new Attribute("htmlUrl", htmlUrl.toString())); - } - } - - /** - * List of attributes on this outline excluding the "common types" for the specification. - * - * @param attributes List of attributes on this outline. - */ - public void setAttributes(final List attributes) { - _attributes = attributes; - } - - /** - * List of attributes on this outline excluding the "common types" for the specification. - * - * @return List of attributes on this outline. - */ - public List getAttributes() { - if (_attributes == null) { - _attributes = new ArrayList(); - } - - return _attributes; - } - - /** - * isBreakpoint is a string, either "true" or "false", indicating whether a breakpoint is set on - * this outline. This attribute is mainly necessary for outlines used to edit scripts. If it's - * not present, the value is false. - * - * @param breakpoint whether a breakpoint is set on this outline. - */ - public void setBreakpoint(final boolean breakpoint) { - _breakpoint = breakpoint; - } - - /** - * isBreakpoint is a string, either "true" or "false", indicating whether a breakpoint is set on - * this outline. This attribute is mainly necessary for outlines used to edit scripts. If it's - * not present, the value is false. - * - * @return whether a breakpoint is set on this outline - */ - public boolean isBreakpoint() { - return _breakpoint; - } - - /** - * (OPML 2) A List of Strings indicating values in the category attribute. - * - * @param categories (OPML 2) A List of Strings indicating values in the category attribute. - */ - public void setCategories(final List categories) { - _categories = categories; - } - - /** - * (OPML 2) A List of Strings indicating values in the category attribute. - * - * @return (OPML 2) A List of Strings indicating values in the category attribute. - */ - public List getCategories() { - if (_categories == null) { - _categories = new ArrayList(); - } - - return _categories; - } - - /** - * A list of sub-outlines for this entry. - * - * @param children A list of sub-outlines for this entry. - */ - public void setChildren(final List children) { - _children = children; - } - - /** - * A list of sub-outlines for this entry. - * - * @return A list of sub-outlines for this entry. - */ - public List getChildren() { - if (_children == null) { - _children = new ArrayList(); - } - - return _children; - } - - /** - * isComment is a string, either "true" or "false", indicating whether the outline is commented - * or not. By convention if an outline is commented, all subordinate outlines are considered to - * also be commented. If it's not present, the value is false. - * - * @param comment whether the outline is commented - */ - public void setComment(final boolean comment) { - _comment = comment; - } - - /** - * isComment is a string, either "true" or "false", indicating whether the outline is commented - * or not. By convention if an outline is commented, all subordinate outlines are considered to - * also be commented. If it's not present, the value is false. - * - * @return whether the outline is commented - */ - public boolean isComment() { - return _comment; - } - - /** - * (OPML 2) created is the date-time that the outline node was created. - * - * @param created date-time that the outline node was created. - */ - public void setCreated(final Date created) { - _created = created; - } - - /** - * (OPML 2) created is the date-time that the outline node was created. - * - * @return date-time that the outline node was created. - */ - public Date getCreated() { - return _created; - } - - /** - * A convenience method to return the value of the url attribute. - * - * @return value of the htmlUrl attribute. - */ - public String getUrl() { - return getAttributeValue("url"); - } - - /** - * A convenience method to return the value of the htmlUrl attribute. - * - * @return value of the htmlUrl attribute. - */ - public String getHtmlUrl() { - return getAttributeValue("htmlUrl"); - } - - public void setModules(final List modules) { - _modules = modules; - } - - public List getModules() { - if (_modules == null) { - _modules = new ArrayList(); - } - - return _modules; - } - - /** - * The "text" attribute of the outline. - * - * @param text The "text" attribute of the outline. - */ - public void setText(final String text) { - _text = text; - } - - /** - * The "text" attribute of the outline. - * - * @return The "text" attribute of the outline. - */ - public String getText() { - return _text; - } - - /** - * The "title" attribute of the outline. - * - * @param title The "title" attribute of the outline. - */ - public void setTitle(final String title) { - _title = title; - } - - /** - * The "title" attribute of the outline. - * - * @return The "title" attribute of the outline. - */ - public String getTitle() { - return _title; - } - - /** - * The "type" attribute of the outline. - * - * @param type The "type" attribute of the outline. - */ - public void setType(final String type) { - _type = type; - } - - /** - * The "type" attribute of the outline. - * - * @return The "type" attribute of the outline. - */ - public String getType() { - return _type; - } - - /** - * A convenience method to return the value of the xmlUrl attribute. - * - * @return value of the xmlUrl attribute. - */ - public String getXmlUrl() { - return getAttributeValue("xmlUrl"); - } - - /** - * Returns the value of an attribute on the outline or null. - * - * @param name name of the attribute. - */ - public String getAttributeValue(final String name) { - final List attributes = Collections.synchronizedList(getAttributes()); - for (int i = 0; i < attributes.size(); i++) { - final Attribute a = attributes.get(i); - - if (a.getName() != null && a.getName().equals(name)) { - return a.getValue(); - } - } - return null; - } - - @Override - public Object clone() { - - final Outline o = new Outline(); - o.setBreakpoint(isBreakpoint()); - o.setCategories(new ArrayList(getCategories())); - o.setComment(isComment()); - o.setCreated(_created != null ? (Date) _created.clone() : null); - o.setModules(new ArrayList(getModules())); - o.setText(getText()); - o.setTitle(getTitle()); - o.setType(getType()); - - final ArrayList children = new ArrayList(); - for (int i = 0; i < getChildren().size(); i++) { - children.add((Outline) _children.get(i).clone()); - } - o.setChildren(children); - - final ArrayList attributes = new ArrayList(); - for (int i = 0; i < getAttributes().size(); i++) { - attributes.add((Attribute) _attributes.get(i).clone()); - } - o.setAttributes(attributes); - - return o; - } - - @Override - public boolean equals(final Object obj) { - final EqualsBean eBean = new EqualsBean(Outline.class, this); - - return eBean.beanEquals(obj); - } - - @Override - public int hashCode() { - final EqualsBean equals = new EqualsBean(Outline.class, this); - - return equals.beanHashCode(); - } - - @Override - public String toString() { - final ToStringBean tsBean = new ToStringBean(Outline.class, this); - - return tsBean.toString(); - } -} +/* + * Outline.java + * + * Created on April 24, 2006, 11:04 PM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rometools.opml.feed.opml; + +import java.io.Serializable; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import com.rometools.rome.feed.impl.EqualsBean; +import com.rometools.rome.feed.impl.ToStringBean; +import com.rometools.rome.feed.module.Module; + +/** + * This class represents an OPML outline element. + * + * @author Robert "kebernet" Cooper + */ +public class Outline implements Cloneable, Serializable { + + private static final long serialVersionUID = 1L; + + private Date created; + private List attributes; + private List categories; + private List children; + private List modules; + private String text; + private String title; + private String type; + private boolean breakpoint; + private boolean comment; + + public Outline() { + } + + /** + * Creates a new outline with the specified type and text values. + * + * @param type type attribute value/ + * @param text text attribute value + */ + public Outline(final String type, final String text) { + setType(type); + setText(text); + } + + /** + * Creates an outline with the given title, xmlUrl and htmlUrl. This is traditionally used for aggregator feed lists + * and will get a type of "rss". + * + * @param title Title of the entry. + * @param xmlUrl link to XML file. + * @param htmlUrl link to html page. + */ + public Outline(final String title, final URL xmlUrl, final URL htmlUrl) { + super(); + setType("rss"); + setTitle(title); + setAttributes(new ArrayList()); + + if (xmlUrl != null) { + getAttributes().add(new Attribute("xmlUrl", xmlUrl.toString())); + } + + if (htmlUrl != null) { + getAttributes().add(new Attribute("htmlUrl", htmlUrl.toString())); + } + } + + /** + * List of attributes on this outline excluding the "common types" for the specification. + * + * @param attributes List of attributes on this outline. + */ + public void setAttributes(final List attributes) { + this.attributes = attributes; + } + + /** + * List of attributes on this outline excluding the "common types" for the specification. + * + * @return List of attributes on this outline. + */ + public List getAttributes() { + if (attributes == null) { + attributes = new ArrayList(); + } + + return attributes; + } + + /** + * isBreakpoint is a string, either "true" or "false", indicating whether a breakpoint is set on this outline. This + * attribute is mainly necessary for outlines used to edit scripts. If it's not present, the value is false. + * + * @param breakpoint whether a breakpoint is set on this outline. + */ + public void setBreakpoint(final boolean breakpoint) { + this.breakpoint = breakpoint; + } + + /** + * isBreakpoint is a string, either "true" or "false", indicating whether a breakpoint is set on this outline. This + * attribute is mainly necessary for outlines used to edit scripts. If it's not present, the value is false. + * + * @return whether a breakpoint is set on this outline + */ + public boolean isBreakpoint() { + return breakpoint; + } + + /** + * (OPML 2) A List of Strings indicating values in the category attribute. + * + * @param categories (OPML 2) A List of Strings indicating values in the category attribute. + */ + public void setCategories(final List categories) { + this.categories = categories; + } + + /** + * (OPML 2) A List of Strings indicating values in the category attribute. + * + * @return (OPML 2) A List of Strings indicating values in the category attribute. + */ + public List getCategories() { + if (categories == null) { + categories = new ArrayList(); + } + + return categories; + } + + /** + * A list of sub-outlines for this entry. + * + * @param children A list of sub-outlines for this entry. + */ + public void setChildren(final List children) { + this.children = children; + } + + /** + * A list of sub-outlines for this entry. + * + * @return A list of sub-outlines for this entry. + */ + public List getChildren() { + if (children == null) { + children = new ArrayList(); + } + + return children; + } + + /** + * isComment is a string, either "true" or "false", indicating whether the outline is commented or not. By + * convention if an outline is commented, all subordinate outlines are considered to also be commented. If it's not + * present, the value is false. + * + * @param comment whether the outline is commented + */ + public void setComment(final boolean comment) { + this.comment = comment; + } + + /** + * isComment is a string, either "true" or "false", indicating whether the outline is commented or not. By + * convention if an outline is commented, all subordinate outlines are considered to also be commented. If it's not + * present, the value is false. + * + * @return whether the outline is commented + */ + public boolean isComment() { + return comment; + } + + /** + * (OPML 2) created is the date-time that the outline node was created. + * + * @param created date-time that the outline node was created. + */ + public void setCreated(final Date created) { + this.created = created; + } + + /** + * (OPML 2) created is the date-time that the outline node was created. + * + * @return date-time that the outline node was created. + */ + public Date getCreated() { + return created; + } + + /** + * A convenience method to return the value of the url attribute. + * + * @return value of the htmlUrl attribute. + */ + public String getUrl() { + return getAttributeValue("url"); + } + + /** + * A convenience method to return the value of the htmlUrl attribute. + * + * @return value of the htmlUrl attribute. + */ + public String getHtmlUrl() { + return getAttributeValue("htmlUrl"); + } + + public void setModules(final List modules) { + this.modules = modules; + } + + public List getModules() { + if (modules == null) { + modules = new ArrayList(); + } + + return modules; + } + + /** + * The "text" attribute of the outline. + * + * @param text The "text" attribute of the outline. + */ + public void setText(final String text) { + this.text = text; + } + + /** + * The "text" attribute of the outline. + * + * @return The "text" attribute of the outline. + */ + public String getText() { + return text; + } + + /** + * The "title" attribute of the outline. + * + * @param title The "title" attribute of the outline. + */ + public void setTitle(final String title) { + this.title = title; + } + + /** + * The "title" attribute of the outline. + * + * @return The "title" attribute of the outline. + */ + public String getTitle() { + return title; + } + + /** + * The "type" attribute of the outline. + * + * @param type The "type" attribute of the outline. + */ + public void setType(final String type) { + this.type = type; + } + + /** + * The "type" attribute of the outline. + * + * @return The "type" attribute of the outline. + */ + public String getType() { + return type; + } + + /** + * A convenience method to return the value of the xmlUrl attribute. + * + * @return value of the xmlUrl attribute. + */ + public String getXmlUrl() { + return getAttributeValue("xmlUrl"); + } + + /** + * Returns the value of an attribute on the outline or null. + * + * @param name name of the attribute. + */ + public String getAttributeValue(final String name) { + final List attributes = Collections.synchronizedList(getAttributes()); + for (int i = 0; i < attributes.size(); i++) { + final Attribute a = attributes.get(i); + + if (a.getName() != null && a.getName().equals(name)) { + return a.getValue(); + } + } + return null; + } + + @Override + public Object clone() { + + final Outline o = new Outline(); + o.setBreakpoint(isBreakpoint()); + o.setCategories(new ArrayList(getCategories())); + o.setComment(isComment()); + o.setCreated(created != null ? (Date) created.clone() : null); + o.setModules(new ArrayList(getModules())); + o.setText(getText()); + o.setTitle(getTitle()); + o.setType(getType()); + + final ArrayList children = new ArrayList(); + for (int i = 0; i < getChildren().size(); i++) { + children.add((Outline) this.children.get(i).clone()); + } + o.setChildren(children); + + final ArrayList attributes = new ArrayList(); + for (int i = 0; i < getAttributes().size(); i++) { + attributes.add((Attribute) this.attributes.get(i).clone()); + } + o.setAttributes(attributes); + + return o; + } + + @Override + public boolean equals(final Object obj) { + return new EqualsBean(Outline.class, this).beanEquals(obj); + } + + @Override + public int hashCode() { + return new EqualsBean(Outline.class, this).beanHashCode(); + } + + @Override + public String toString() { + return new ToStringBean(Outline.class, this).toString(); + } + +} diff --git a/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML10.java b/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML10.java index 28c8020..4cf6363 100644 --- a/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML10.java +++ b/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML10.java @@ -1,365 +1,349 @@ -/* - * ConverterForOPML10.java - * - * Created on April 25, 2006, 1:26 AM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.rometools.opml.feed.synd.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.rometools.opml.feed.opml.Attribute; -import com.rometools.opml.feed.opml.Opml; -import com.rometools.opml.feed.opml.Outline; -import com.rometools.rome.feed.WireFeed; -import com.rometools.rome.feed.synd.Converter; -import com.rometools.rome.feed.synd.SyndCategory; -import com.rometools.rome.feed.synd.SyndCategoryImpl; -import com.rometools.rome.feed.synd.SyndContent; -import com.rometools.rome.feed.synd.SyndContentImpl; -import com.rometools.rome.feed.synd.SyndEntry; -import com.rometools.rome.feed.synd.SyndEntryImpl; -import com.rometools.rome.feed.synd.SyndFeed; -import com.rometools.rome.feed.synd.SyndLink; -import com.rometools.rome.feed.synd.SyndLinkImpl; -import com.rometools.rome.feed.synd.SyndPerson; -import com.rometools.rome.feed.synd.SyndPersonImpl; - -/** - * - * @author cooper - */ -public class ConverterForOPML10 implements Converter { - - private static final Logger LOG = LoggerFactory.getLogger(ConverterForOPML10.class); - - public static final String URI_TREE = "urn:rome.tree"; - public static final String URI_ATTRIBUTE = "urn:rome.attribute#"; - - /** Creates a new instance of ConverterForOPML10 */ - public ConverterForOPML10() { - super(); - } - - protected void addOwner(final Opml opml, final SyndFeed syndFeed) { - if (opml.getOwnerEmail() != null || opml.getOwnerName() != null) { - final List authors = new ArrayList(); - final SyndPerson person = new SyndPersonImpl(); - person.setEmail(opml.getOwnerEmail()); - person.setName(opml.getOwnerName()); - authors.add(person); - syndFeed.setAuthors(authors); - } - } - - /** - * Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl. - *

- * It assumes the given SyndFeedImpl has no properties set. - *

- * - * @param feed real feed to copy/convert. - * @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real - * feed. - */ - @Override - public void copyInto(final WireFeed feed, final SyndFeed syndFeed) { - final Opml opml = (Opml) feed; - syndFeed.setTitle(opml.getTitle()); - addOwner(opml, syndFeed); - syndFeed.setPublishedDate(opml.getModified() != null ? opml.getModified() : opml.getCreated()); - syndFeed.setFeedType(opml.getFeedType()); - syndFeed.setModules(opml.getModules()); - syndFeed.setFeedType(getType()); - - createEntries(new TreeContext(), syndFeed.getEntries(), opml.getOutlines()); - } - - protected void createEntries(final TreeContext context, final List allEntries, final List outlines) { - final List so = Collections.synchronizedList(outlines); - - for (int i = 0; i < so.size(); i++) { - createEntry(context, allEntries, so.get(i)); - } - } - - protected SyndEntry createEntry(final TreeContext context, final List allEntries, final Outline outline) { - final SyndEntry entry = new SyndEntryImpl(); - - if (outline.getType() != null && outline.getType().equals("rss")) { - entry.setLink(outline.getHtmlUrl() != null ? outline.getHtmlUrl() : outline.getXmlUrl()); - } else if (outline.getType() != null && outline.getType().equals("link")) { - entry.setLink(outline.getUrl()); - } - - if (outline.getHtmlUrl() != null) { - final SyndLink link = new SyndLinkImpl(); - link.setRel("alternate"); - link.setType("text/html"); - link.setHref(outline.getHtmlUrl()); - entry.getLinks().add(link); - entry.setLink(outline.getHtmlUrl()); - } - - if (outline.getXmlUrl() != null && outline.getType() != null && outline.getType().equalsIgnoreCase("rss")) { - final SyndLink link = new SyndLinkImpl(); - link.setRel("alternate"); - link.setType("application/rss+xml"); - link.setHref(outline.getXmlUrl()); - entry.getLinks().add(link); - - if (entry.getLink() == null) { - entry.setLink(outline.getXmlUrl()); - } - } - - if (outline.getXmlUrl() != null && outline.getType() != null && outline.getType().equalsIgnoreCase("atom")) { - final SyndLink link = new SyndLinkImpl(); - link.setRel("alternate"); - link.setType("application/atom+xml"); - link.setHref(outline.getXmlUrl()); - entry.getLinks().add(link); - - if (entry.getLink() == null) { - entry.setLink(outline.getXmlUrl()); - } - } - - if (outline.getType() != null && outline.getType().equals("rss")) { - entry.setTitle(outline.getTitle()); - } else { - entry.setTitle(outline.getText()); - } - - if (outline.getText() == null && entry.getTitle() != null) { - final SyndContent c = new SyndContentImpl(); - c.setValue(outline.getText()); - entry.setDescription(c); - } - - entry.setPublishedDate(outline.getCreated()); - - final String nodeName = "node." + outline.hashCode(); - - final SyndCategory cat = new TreeCategoryImpl(); - cat.setTaxonomyUri(URI_TREE); - cat.setName(nodeName); - entry.getCategories().add(cat); - - if (!context.isEmpty()) { - final Integer parent = context.peek(); - final SyndCategory pcat = new TreeCategoryImpl(); - pcat.setTaxonomyUri(URI_TREE); - pcat.setName("parent." + parent); - entry.getCategories().add(pcat); - } - - final List attributes = Collections.synchronizedList(outline.getAttributes()); - - for (int i = 0; i < attributes.size(); i++) { - final Attribute a = attributes.get(i); - final SyndCategory acat = new SyndCategoryImpl(); - acat.setName(a.getValue()); - acat.setTaxonomyUri(URI_ATTRIBUTE + a.getName()); - entry.getCategories().add(acat); - } - - entry.setModules(outline.getModules()); - allEntries.add(entry); - context.push(new Integer(outline.hashCode())); - createEntries(context, allEntries, outline.getChildren()); - context.pop(); - - return entry; - } - - /** - * Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl. - *

- * - * @param syndFeed SyndFeedImpl to copy/convert value from. - * @return a real feed with copied/converted values of the SyndFeedImpl. - * - */ - @Override - public WireFeed createRealFeed(final SyndFeed syndFeed) { - - final List entries = Collections.synchronizedList(syndFeed.getEntries()); - - final HashMap entriesByNode = new HashMap(); - - // this will hold entries that we can't parent the first time. - final ArrayList doAfterPass = new ArrayList(); - - // this holds root level outlines; - final ArrayList root = new ArrayList(); - - for (int i = 0; i < entries.size(); i++) { - final SyndEntry entry = entries.get(i); - final Outline o = new Outline(); - - final List cats = Collections.synchronizedList(entry.getCategories()); - boolean parentFound = false; - final StringBuffer category = new StringBuffer(); - - for (int j = 0; j < cats.size(); j++) { - final SyndCategory cat = cats.get(j); - - if (cat.getTaxonomyUri() != null && cat.getTaxonomyUri().equals(URI_TREE)) { - final String nodeVal = cat.getName().substring(cat.getName().lastIndexOf("."), cat.getName().length()); - - if (cat.getName().startsWith("node.")) { - entriesByNode.put(nodeVal, o); - } else if (cat.getName().startsWith("parent.")) { - parentFound = true; - - final Outline parent = entriesByNode.get(nodeVal); - - if (parent != null) { - parent.getChildren().add(o); - } else { - doAfterPass.add(new OutlineHolder(o, nodeVal)); - } - } - } else if (cat.getTaxonomyUri() != null && cat.getTaxonomyUri().startsWith(URI_ATTRIBUTE)) { - final String name = cat.getTaxonomyUri().substring(cat.getTaxonomyUri().indexOf("#") + 1, cat.getTaxonomyUri().length()); - o.getAttributes().add(new Attribute(name, cat.getName())); - } else { - if (category.length() > 0) { - category.append(", "); - } - - category.append(cat.getName()); - } - } - - if (!parentFound) { - root.add(o); - } - - if (category.length() > 0) { - o.getAttributes().add(new Attribute("category", category.toString())); - } - - final List links = Collections.synchronizedList(entry.getLinks()); - // final String entryLink = entry.getLink(); - - for (int j = 0; j < links.size(); j++) { - final SyndLink link = links.get(j); - - // if(link.getHref().equals(entryLink)) { - if (link.getType() != null && link.getRel() != null && link.getRel().equals("alternate") - && (link.getType().equals("application/rss+xml") || link.getType().equals("application/atom+xml"))) { - o.setType("rss"); - - if (o.getXmlUrl() == null) { - o.getAttributes().add(new Attribute("xmlUrl", link.getHref())); - } - } else if (link.getType() != null && link.getType().equals("text/html")) { - if (o.getHtmlUrl() == null) { - o.getAttributes().add(new Attribute("htmlUrl", link.getHref())); - } - } else { - o.setType(link.getType()); - } - - // } - } - - if (o.getType() == null || o.getType().equals("link")) { - o.setText(entry.getTitle()); - - } else { - o.setTitle(entry.getTitle()); - } - - if (o.getText() == null && entry.getDescription() != null) { - o.setText(entry.getDescription().getValue()); - } - } - - // Do back and parenting for things we missed. - for (int i = 0; i < doAfterPass.size(); i++) { - final OutlineHolder o = doAfterPass.get(i); - final Outline parent = entriesByNode.get(o.parent); - - if (parent == null) { - root.add(o.outline); - LOG.warn("Unable to find parent node: {}", o.parent); - } else { - parent.getChildren().add(o.outline); - } - } - - final Opml opml = new Opml(); - opml.setFeedType(getType()); - opml.setCreated(syndFeed.getPublishedDate()); - opml.setTitle(syndFeed.getTitle()); - - final List authors = Collections.synchronizedList(syndFeed.getAuthors()); - - for (int i = 0; i < authors.size(); i++) { - final SyndPerson p = authors.get(i); - - if (syndFeed.getAuthor() == null || syndFeed.getAuthor().equals(p.getName())) { - opml.setOwnerName(p.getName()); - opml.setOwnerEmail(p.getEmail()); - opml.setOwnerId(p.getUri()); - } - } - - opml.setOutlines(root); - - return opml; - } - - /** - * Returns the type (version) of the real feed this converter handles. - *

- * - * @return the real feed type. - * @see WireFeed for details on the format of this string. - *

- */ - @Override - public String getType() { - return "opml_1.0"; - } - - private static class OutlineHolder { - Outline outline; - String parent; - - public OutlineHolder(final Outline outline, final String parent) { - this.outline = outline; - this.parent = parent; - } - } - - private static class TreeContext extends Stack { - - private static final long serialVersionUID = 1L; - - TreeContext() { - super(); - } - } -} +/* + * ConverterForOPML10.java + * + * Created on April 25, 2006, 1:26 AM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.rometools.opml.feed.synd.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.rometools.opml.feed.opml.Attribute; +import com.rometools.opml.feed.opml.Opml; +import com.rometools.opml.feed.opml.Outline; +import com.rometools.rome.feed.WireFeed; +import com.rometools.rome.feed.synd.Converter; +import com.rometools.rome.feed.synd.SyndCategory; +import com.rometools.rome.feed.synd.SyndCategoryImpl; +import com.rometools.rome.feed.synd.SyndContent; +import com.rometools.rome.feed.synd.SyndContentImpl; +import com.rometools.rome.feed.synd.SyndEntry; +import com.rometools.rome.feed.synd.SyndEntryImpl; +import com.rometools.rome.feed.synd.SyndFeed; +import com.rometools.rome.feed.synd.SyndLink; +import com.rometools.rome.feed.synd.SyndLinkImpl; +import com.rometools.rome.feed.synd.SyndPerson; +import com.rometools.rome.feed.synd.SyndPersonImpl; + +/** + * @author cooper + */ +public class ConverterForOPML10 implements Converter { + + private static final Logger LOG = LoggerFactory.getLogger(ConverterForOPML10.class); + + public static final String URI_TREE = "urn:rome.tree"; + public static final String URI_ATTRIBUTE = "urn:rome.attribute#"; + + protected void addOwner(final Opml opml, final SyndFeed syndFeed) { + if (opml.getOwnerEmail() != null || opml.getOwnerName() != null) { + final List authors = new ArrayList(); + final SyndPerson person = new SyndPersonImpl(); + person.setEmail(opml.getOwnerEmail()); + person.setName(opml.getOwnerName()); + authors.add(person); + syndFeed.setAuthors(authors); + } + } + + /** + * Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl. + *

+ * It assumes the given SyndFeedImpl has no properties set. + *

+ * + * @param feed real feed to copy/convert. + * @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real feed. + */ + @Override + public void copyInto(final WireFeed feed, final SyndFeed syndFeed) { + final Opml opml = (Opml) feed; + syndFeed.setTitle(opml.getTitle()); + addOwner(opml, syndFeed); + syndFeed.setPublishedDate(opml.getModified() != null ? opml.getModified() : opml.getCreated()); + syndFeed.setFeedType(opml.getFeedType()); + syndFeed.setModules(opml.getModules()); + syndFeed.setFeedType(getType()); + + createEntries(new Stack(), syndFeed.getEntries(), opml.getOutlines()); + } + + protected void createEntries(final Stack context, final List allEntries, final List outlines) { + final List so = Collections.synchronizedList(outlines); + + for (int i = 0; i < so.size(); i++) { + createEntry(context, allEntries, so.get(i)); + } + } + + protected SyndEntry createEntry(final Stack context, final List allEntries, final Outline outline) { + final SyndEntry entry = new SyndEntryImpl(); + + if (outline.getType() != null && outline.getType().equals("rss")) { + entry.setLink(outline.getHtmlUrl() != null ? outline.getHtmlUrl() : outline.getXmlUrl()); + } else if (outline.getType() != null && outline.getType().equals("link")) { + entry.setLink(outline.getUrl()); + } + + if (outline.getHtmlUrl() != null) { + final SyndLink link = new SyndLinkImpl(); + link.setRel("alternate"); + link.setType("text/html"); + link.setHref(outline.getHtmlUrl()); + entry.getLinks().add(link); + entry.setLink(outline.getHtmlUrl()); + } + + if (outline.getXmlUrl() != null && outline.getType() != null && outline.getType().equalsIgnoreCase("rss")) { + final SyndLink link = new SyndLinkImpl(); + link.setRel("alternate"); + link.setType("application/rss+xml"); + link.setHref(outline.getXmlUrl()); + entry.getLinks().add(link); + + if (entry.getLink() == null) { + entry.setLink(outline.getXmlUrl()); + } + } + + if (outline.getXmlUrl() != null && outline.getType() != null && outline.getType().equalsIgnoreCase("atom")) { + final SyndLink link = new SyndLinkImpl(); + link.setRel("alternate"); + link.setType("application/atom+xml"); + link.setHref(outline.getXmlUrl()); + entry.getLinks().add(link); + + if (entry.getLink() == null) { + entry.setLink(outline.getXmlUrl()); + } + } + + if (outline.getType() != null && outline.getType().equals("rss")) { + entry.setTitle(outline.getTitle()); + } else { + entry.setTitle(outline.getText()); + } + + if (outline.getText() == null && entry.getTitle() != null) { + final SyndContent c = new SyndContentImpl(); + c.setValue(outline.getText()); + entry.setDescription(c); + } + + entry.setPublishedDate(outline.getCreated()); + + final String nodeName = "node." + outline.hashCode(); + + final SyndCategory cat = new TreeCategoryImpl(); + cat.setTaxonomyUri(URI_TREE); + cat.setName(nodeName); + entry.getCategories().add(cat); + + if (!context.isEmpty()) { + final Integer parent = context.peek(); + final SyndCategory pcat = new TreeCategoryImpl(); + pcat.setTaxonomyUri(URI_TREE); + pcat.setName("parent." + parent); + entry.getCategories().add(pcat); + } + + final List attributes = Collections.synchronizedList(outline.getAttributes()); + + for (int i = 0; i < attributes.size(); i++) { + final Attribute a = attributes.get(i); + final SyndCategory acat = new SyndCategoryImpl(); + acat.setName(a.getValue()); + acat.setTaxonomyUri(URI_ATTRIBUTE + a.getName()); + entry.getCategories().add(acat); + } + + entry.setModules(outline.getModules()); + allEntries.add(entry); + context.push(new Integer(outline.hashCode())); + createEntries(context, allEntries, outline.getChildren()); + context.pop(); + + return entry; + } + + /** + * Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl. + *

+ * + * @param syndFeed SyndFeedImpl to copy/convert value from. + * @return a real feed with copied/converted values of the SyndFeedImpl. + */ + @Override + public WireFeed createRealFeed(final SyndFeed syndFeed) { + + final List entries = Collections.synchronizedList(syndFeed.getEntries()); + + final HashMap entriesByNode = new HashMap(); + + // this will hold entries that we can't parent the first time. + final ArrayList doAfterPass = new ArrayList(); + + // this holds root level outlines; + final ArrayList root = new ArrayList(); + + for (int i = 0; i < entries.size(); i++) { + final SyndEntry entry = entries.get(i); + final Outline o = new Outline(); + + final List cats = Collections.synchronizedList(entry.getCategories()); + boolean parentFound = false; + final StringBuffer category = new StringBuffer(); + + for (int j = 0; j < cats.size(); j++) { + final SyndCategory cat = cats.get(j); + + if (cat.getTaxonomyUri() != null && cat.getTaxonomyUri().equals(URI_TREE)) { + final String nodeVal = cat.getName().substring(cat.getName().lastIndexOf("."), cat.getName().length()); + + if (cat.getName().startsWith("node.")) { + entriesByNode.put(nodeVal, o); + } else if (cat.getName().startsWith("parent.")) { + parentFound = true; + + final Outline parent = entriesByNode.get(nodeVal); + + if (parent != null) { + parent.getChildren().add(o); + } else { + doAfterPass.add(new OutlineHolder(o, nodeVal)); + } + } + } else if (cat.getTaxonomyUri() != null && cat.getTaxonomyUri().startsWith(URI_ATTRIBUTE)) { + final String name = cat.getTaxonomyUri().substring(cat.getTaxonomyUri().indexOf("#") + 1, cat.getTaxonomyUri().length()); + o.getAttributes().add(new Attribute(name, cat.getName())); + } else { + if (category.length() > 0) { + category.append(", "); + } + + category.append(cat.getName()); + } + } + + if (!parentFound) { + root.add(o); + } + + if (category.length() > 0) { + o.getAttributes().add(new Attribute("category", category.toString())); + } + + final List links = Collections.synchronizedList(entry.getLinks()); + // final String entryLink = entry.getLink(); + + for (int j = 0; j < links.size(); j++) { + final SyndLink link = links.get(j); + + // if(link.getHref().equals(entryLink)) { + if (link.getType() != null && link.getRel() != null && link.getRel().equals("alternate") + && (link.getType().equals("application/rss+xml") || link.getType().equals("application/atom+xml"))) { + o.setType("rss"); + + if (o.getXmlUrl() == null) { + o.getAttributes().add(new Attribute("xmlUrl", link.getHref())); + } + } else if (link.getType() != null && link.getType().equals("text/html")) { + if (o.getHtmlUrl() == null) { + o.getAttributes().add(new Attribute("htmlUrl", link.getHref())); + } + } else { + o.setType(link.getType()); + } + + // } + } + + if (o.getType() == null || o.getType().equals("link")) { + o.setText(entry.getTitle()); + + } else { + o.setTitle(entry.getTitle()); + } + + if (o.getText() == null && entry.getDescription() != null) { + o.setText(entry.getDescription().getValue()); + } + } + + // Do back and parenting for things we missed. + for (int i = 0; i < doAfterPass.size(); i++) { + final OutlineHolder o = doAfterPass.get(i); + final Outline parent = entriesByNode.get(o.parent); + + if (parent == null) { + root.add(o.outline); + LOG.warn("Unable to find parent node: {}", o.parent); + } else { + parent.getChildren().add(o.outline); + } + } + + final Opml opml = new Opml(); + opml.setFeedType(getType()); + opml.setCreated(syndFeed.getPublishedDate()); + opml.setTitle(syndFeed.getTitle()); + + final List authors = Collections.synchronizedList(syndFeed.getAuthors()); + + for (int i = 0; i < authors.size(); i++) { + final SyndPerson p = authors.get(i); + + if (syndFeed.getAuthor() == null || syndFeed.getAuthor().equals(p.getName())) { + opml.setOwnerName(p.getName()); + opml.setOwnerEmail(p.getEmail()); + opml.setOwnerId(p.getUri()); + } + } + + opml.setOutlines(root); + + return opml; + } + + /** + * Returns the type (version) of the real feed this converter handles. + * + * @return the real feed type. + * @see WireFeed for details on the format of this string. + */ + @Override + public String getType() { + return "opml_1.0"; + } + + private static class OutlineHolder { + + private final Outline outline; + private final String parent; + + public OutlineHolder(final Outline outline, final String parent) { + this.outline = outline; + this.parent = parent; + } + + } + +} diff --git a/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML20.java b/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML20.java index b467b46..672da88 100644 --- a/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML20.java +++ b/src/main/java/com/rometools/opml/feed/synd/impl/ConverterForOPML20.java @@ -1,67 +1,50 @@ -/* - * ConverterForOPML20.java - * - * Created on April 25, 2006, 5:29 PM - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ -package com.rometools.opml.feed.synd.impl; - -import com.rometools.rome.feed.WireFeed; -import com.rometools.rome.feed.synd.SyndFeed; - -/** - * - * @author cooper - */ -public class ConverterForOPML20 extends ConverterForOPML10 { - /** Creates a new instance of ConverterForOPML20 */ - public ConverterForOPML20() { - super(); - } - - /** - * Returns the type (version) of the real feed this converter handles. - *

- * - * @return the real feed type. - * @see WireFeed for details on the format of this string. - *

- */ - @Override - public String getType() { - return "opml_2.0"; - } - - /** - * Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl. - *

- * It assumes the given SyndFeedImpl has no properties set. - *

- * - * @param feed real feed to copy/convert. - * @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real - * feed. - */ - @Override - public void copyInto(final WireFeed feed, final SyndFeed syndFeed) { - super.copyInto(feed, syndFeed); - } - - /** - * Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl. - *

- * - * @param syndFeed SyndFeedImpl to copy/convert value from. - * @return a real feed with copied/converted values of the SyndFeedImpl. - */ - @Override - public WireFeed createRealFeed(final SyndFeed syndFeed) { - WireFeed retValue; - - retValue = super.createRealFeed(syndFeed); - - return retValue; - } -} +package com.rometools.opml.feed.synd.impl; + +import com.rometools.rome.feed.WireFeed; +import com.rometools.rome.feed.synd.SyndFeed; + +/** + * @author cooper + */ +public class ConverterForOPML20 extends ConverterForOPML10 { + + /** + * Returns the type (version) of the real feed this converter handles. + *

+ * + * @return the real feed type. + * @see WireFeed for details on the format of this string. + *

+ */ + @Override + public String getType() { + return "opml_2.0"; + } + + /** + * Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl. + *

+ * It assumes the given SyndFeedImpl has no properties set. + *

+ * + * @param feed real feed to copy/convert. + * @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real feed. + */ + @Override + public void copyInto(final WireFeed feed, final SyndFeed syndFeed) { + super.copyInto(feed, syndFeed); + } + + /** + * Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl. + *

+ * + * @param syndFeed SyndFeedImpl to copy/convert value from. + * @return a real feed with copied/converted values of the SyndFeedImpl. + */ + @Override + public WireFeed createRealFeed(final SyndFeed syndFeed) { + return super.createRealFeed(syndFeed); + } + +} diff --git a/src/main/java/com/rometools/opml/feed/synd/impl/TreeCategoryImpl.java b/src/main/java/com/rometools/opml/feed/synd/impl/TreeCategoryImpl.java index c3c8e18..b338798 100644 --- a/src/main/java/com/rometools/opml/feed/synd/impl/TreeCategoryImpl.java +++ b/src/main/java/com/rometools/opml/feed/synd/impl/TreeCategoryImpl.java @@ -1,38 +1,23 @@ -/* - * TreeCategoryImpl.java - * - * Created on April 27, 2006, 3:44 AM - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ - -package com.rometools.opml.feed.synd.impl; - -import com.rometools.rome.feed.synd.SyndCategory; -import com.rometools.rome.feed.synd.SyndCategoryImpl; - -/** - * - * @author cooper - */ -public class TreeCategoryImpl extends SyndCategoryImpl { - - private static final long serialVersionUID = 1L; - - /** Creates a new instance of TreeCategoryImpl */ - public TreeCategoryImpl() { - super(); - } - - @Override - public boolean equals(final Object o) { - final SyndCategory c = (SyndCategory) o; - if (c.getTaxonomyUri() != null && c.getTaxonomyUri().equals(getTaxonomyUri())) { - return true; - } else { - return false; - } - } - -} +package com.rometools.opml.feed.synd.impl; + +import com.rometools.rome.feed.synd.SyndCategory; +import com.rometools.rome.feed.synd.SyndCategoryImpl; + +/** + * @author cooper + */ +public class TreeCategoryImpl extends SyndCategoryImpl { + + private static final long serialVersionUID = 1L; + + @Override + public boolean equals(final Object o) { + final SyndCategory c = (SyndCategory) o; + if (c.getTaxonomyUri() != null && c.getTaxonomyUri().equals(getTaxonomyUri())) { + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/com/rometools/opml/io/impl/OPML10Generator.java b/src/main/java/com/rometools/opml/io/impl/OPML10Generator.java index dfb0368..8851312 100644 --- a/src/main/java/com/rometools/opml/io/impl/OPML10Generator.java +++ b/src/main/java/com/rometools/opml/io/impl/OPML10Generator.java @@ -35,11 +35,10 @@ import com.rometools.rome.io.impl.BaseWireFeedGenerator; import com.rometools.rome.io.impl.DateParser; /** - * * @author Robert "kebernet" Cooper */ public class OPML10Generator extends BaseWireFeedGenerator implements WireFeedGenerator { - /** Creates a new instance of Opml10Generator */ + public OPML10Generator() { super("opml_1.0"); } @@ -50,16 +49,16 @@ public class OPML10Generator extends BaseWireFeedGenerator implements WireFeedGe /** * Creates an XML document (JDOM) for the given feed bean. - *

* * @param feed the feed bean to generate the XML document from. * @return the generated XML document (JDOM). - * @throws IllegalArgumentException thrown if the type of the given feed bean does not match - * with the type of the WireFeedGenerator. + * @throws IllegalArgumentException thrown if the type of the given feed bean does not match with the type of the + * WireFeedGenerator. * @throws FeedException thrown if the XML Document could not be created. */ @Override public Document generate(final WireFeed feed) throws IllegalArgumentException, FeedException { + if (!(feed instanceof Opml)) { throw new IllegalArgumentException("Not an OPML file"); } @@ -88,9 +87,7 @@ public class OPML10Generator extends BaseWireFeedGenerator implements WireFeedGe if (target == null || name == null || value == null) { return false; } - target.setAttribute(name, value.toString()); - return true; } diff --git a/src/main/java/com/rometools/opml/io/impl/OPML10Parser.java b/src/main/java/com/rometools/opml/io/impl/OPML10Parser.java index 576182e..02b1bf5 100644 --- a/src/main/java/com/rometools/opml/io/impl/OPML10Parser.java +++ b/src/main/java/com/rometools/opml/io/impl/OPML10Parser.java @@ -37,14 +37,12 @@ import com.rometools.rome.io.impl.BaseWireFeedParser; import com.rometools.rome.io.impl.DateParser; /** - * * @author Robert "kebernet" Cooper */ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { private static Logger LOG = LoggerFactory.getLogger(OPML10Parser.class); - /** Creates a new instance of Opml10Parser */ public OPML10Parser() { super("opml_1.0", null); } @@ -111,7 +109,6 @@ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { opml.setWindowBottom(readInteger(head.getChildText("windowBottom"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse windowBottom", nfe); - if (validate) { throw new FeedException("Unable to parse windowBottom", nfe); } @@ -121,13 +118,15 @@ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { opml.setWindowLeft(readInteger(head.getChildText("windowLeft"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse windowLeft", nfe); + if (validate) { + throw new FeedException("Unable to parse windowLeft", nfe); + } } try { opml.setWindowRight(readInteger(head.getChildText("windowRight"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse windowRight", nfe); - if (validate) { throw new FeedException("Unable to parse windowRight", nfe); } @@ -137,7 +136,6 @@ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { opml.setWindowLeft(readInteger(head.getChildText("windowLeft"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse windowLeft", nfe); - if (validate) { throw new FeedException("Unable to parse windowLeft", nfe); } @@ -147,7 +145,6 @@ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { opml.setWindowTop(readInteger(head.getChildText("windowTop"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse windowTop", nfe); - if (validate) { throw new FeedException("Unable to parse windowTop", nfe); } @@ -157,7 +154,6 @@ public class OPML10Parser extends BaseWireFeedParser implements WireFeedParser { opml.setExpansionState(readIntArray(head.getChildText("expansionState"))); } catch (final NumberFormatException nfe) { LOG.warn("Unable to parse expansionState", nfe); - if (validate) { throw new FeedException("Unable to parse expansionState", nfe); } diff --git a/src/main/java/com/rometools/opml/io/impl/OPML20Generator.java b/src/main/java/com/rometools/opml/io/impl/OPML20Generator.java index c87dbfe..dfc4137 100644 --- a/src/main/java/com/rometools/opml/io/impl/OPML20Generator.java +++ b/src/main/java/com/rometools/opml/io/impl/OPML20Generator.java @@ -1,11 +1,3 @@ -/* - * OPML20Generator.java - * - * Created on April 25, 2006, 5:31 PM - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ package com.rometools.opml.io.impl; import java.util.Locale; @@ -20,21 +12,18 @@ import com.rometools.rome.io.FeedException; import com.rometools.rome.io.impl.DateParser; /** - * * @author cooper */ public class OPML20Generator extends OPML10Generator { - /** Creates a new instance of OPML20Generator */ + public OPML20Generator() { } /** * Returns the type of feed the generator creates. - *

* * @return the type of feed the generator creates. * @see WireFeed for details on the format of this string. - *

*/ @Override public String getType() { @@ -43,47 +32,43 @@ public class OPML20Generator extends OPML10Generator { /** * Creates an XML document (JDOM) for the given feed bean. - *

* * @param feed the feed bean to generate the XML document from. * @return the generated XML document (JDOM). - * @throws IllegalArgumentException thrown if the type of the given feed bean does not match - * with the type of the WireFeedGenerator. + * @throws IllegalArgumentException thrown if the type of the given feed bean does not match with the type of the + * WireFeedGenerator. * @throws FeedException thrown if the XML Document could not be created. */ @Override public Document generate(final WireFeed feed) throws IllegalArgumentException, FeedException { - Document retValue; - - retValue = super.generate(feed); + final Document retValue = super.generate(feed); retValue.getRootElement().setAttribute("version", "2.0"); - return retValue; } @Override protected Element generateHead(final Opml opml) { - Element retValue; - - retValue = super.generateHead(opml); final Element docs = new Element("docs"); docs.setText(opml.getDocs()); - retValue.addContent(docs); + final Element retValue = super.generateHead(opml); + retValue.addContent(docs); return retValue; + } @Override protected Element generateOutline(final Outline outline) { - Element retValue; - retValue = super.generateOutline(outline); + final Element retValue = super.generateOutline(outline); if (outline.getCreated() != null) { retValue.setAttribute("created", DateParser.formatRFC822(outline.getCreated(), Locale.US)); } return retValue; + } + }