Move rome-opml files into a subdirectory

This commit is contained in:
mishako 2016-02-13 18:50:11 +01:00
parent ff58d2ac64
commit 8bc74b1e95
37 changed files with 1393 additions and 1393 deletions

View file

View file

@ -1,87 +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 <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
*/
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();
}
}
/*
* 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 <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
*/
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();
}
}

View file

@ -1,322 +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 &lt;head&gt; tag
* of the feed.
*
* @author <a href="mailto:cooper@screaming-penguin.com"> Robert "kebernet" Cooper</a>
*/
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<Outline> outlines;
private String docs;
private String ownerEmail;
private String ownerId;
private String ownerName;
private String title;
private int[] expansionState;
/**
* <dateCreated> 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;
}
/**
* &lt;dateCreated&gt; 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) &lt;docs&gt; is the http address of documentation for the format used in the OPML file. It's probably a
* pointer to <a href="http://www.opml.org/spec2">this page</a> 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) &lt;docs&gt; is the http address of documentation for the format used in the OPML file. It's probably a
* pointer to <a href="http://www.opml.org/spec2">this page</a> 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;
}
/**
* &lt;expansionState&gt;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;
}
/**
* &lt;expansionState&gt; 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;
}
/**
* &lt;dateModified&gt; 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;
}
/**
* &lt;dateModified&gt; 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 &lt;body&gt;
*
* @param outlines Root level Outline object that should appear in the &lt;body&gt;
*/
public void setOutlines(final List<Outline> outlines) {
this.outlines = outlines;
}
/**
* Root level Outline object that should appear in the &lt;body&gt;
*
* @return Root level Outline object that should appear in the &lt;body&gt;
*/
public List<Outline> getOutlines() {
if (outlines == null) {
outlines = new ArrayList<Outline>();
}
return outlines;
}
/**
* &lt;ownerEmail&gt; 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;
}
/**
* &lt;ownerEmail&gt; 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) &lt;ownerId&gt; is the http address of a web page that contains <strike>an HTML</strike> 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 <strike>an HTML</strike> 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) &lt;ownerId&gt; is the http address of a web page that contains <strike>an HTML</strike> 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 <strike>an HTML</strike> 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;
}
/**
* &lt;ownerName&gt; is a string, the owner of the document.
*
* @param ownerName the owner of the document.
*/
public void setOwnerName(final String ownerName) {
this.ownerName = ownerName;
}
/**
* &lt;ownerName&gt; is a string, the owner of the document.
*
* @return the owner of the document.
*/
public String getOwnerName() {
return ownerName;
}
/**
* &lt;title&gt; is the title of the document.
*
* @param title title of the document.
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* &lt;title&gt; is the title of the document.
*
* @return title of the document.
*/
public String getTitle() {
return title;
}
/**
* &lt;vertScrollState&gt; 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;
}
/**
* &lt;vertScrollState&gt; 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;
}
/**
* &lt;windowBottom&gt; 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;
}
/**
* &lt;windowBottom&gt; 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;
}
/**
* &lt;windowLeft&gt; 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;
}
/**
* &lt;windowLeft&gt; 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;
}
/**
* &lt;windowRight&gt; 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;
}
/**
* &lt;windowRight&gt; 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;
}
/**
* &lt;windowTop&gt; 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;
}
/**
* &lt;windowTop&gt; 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 &lt;head&gt; tag
* of the feed.
*
* @author <a href="mailto:cooper@screaming-penguin.com"> Robert "kebernet" Cooper</a>
*/
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<Outline> outlines;
private String docs;
private String ownerEmail;
private String ownerId;
private String ownerName;
private String title;
private int[] expansionState;
/**
* <dateCreated> 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;
}
/**
* &lt;dateCreated&gt; 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) &lt;docs&gt; is the http address of documentation for the format used in the OPML file. It's probably a
* pointer to <a href="http://www.opml.org/spec2">this page</a> 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) &lt;docs&gt; is the http address of documentation for the format used in the OPML file. It's probably a
* pointer to <a href="http://www.opml.org/spec2">this page</a> 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;
}
/**
* &lt;expansionState&gt;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;
}
/**
* &lt;expansionState&gt; 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;
}
/**
* &lt;dateModified&gt; 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;
}
/**
* &lt;dateModified&gt; 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 &lt;body&gt;
*
* @param outlines Root level Outline object that should appear in the &lt;body&gt;
*/
public void setOutlines(final List<Outline> outlines) {
this.outlines = outlines;
}
/**
* Root level Outline object that should appear in the &lt;body&gt;
*
* @return Root level Outline object that should appear in the &lt;body&gt;
*/
public List<Outline> getOutlines() {
if (outlines == null) {
outlines = new ArrayList<Outline>();
}
return outlines;
}
/**
* &lt;ownerEmail&gt; 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;
}
/**
* &lt;ownerEmail&gt; 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) &lt;ownerId&gt; is the http address of a web page that contains <strike>an HTML</strike> 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 <strike>an HTML</strike> 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) &lt;ownerId&gt; is the http address of a web page that contains <strike>an HTML</strike> 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 <strike>an HTML</strike> 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;
}
/**
* &lt;ownerName&gt; is a string, the owner of the document.
*
* @param ownerName the owner of the document.
*/
public void setOwnerName(final String ownerName) {
this.ownerName = ownerName;
}
/**
* &lt;ownerName&gt; is a string, the owner of the document.
*
* @return the owner of the document.
*/
public String getOwnerName() {
return ownerName;
}
/**
* &lt;title&gt; is the title of the document.
*
* @param title title of the document.
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* &lt;title&gt; is the title of the document.
*
* @return title of the document.
*/
public String getTitle() {
return title;
}
/**
* &lt;vertScrollState&gt; 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;
}
/**
* &lt;vertScrollState&gt; 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;
}
/**
* &lt;windowBottom&gt; 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;
}
/**
* &lt;windowBottom&gt; 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;
}
/**
* &lt;windowLeft&gt; 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;
}
/**
* &lt;windowLeft&gt; 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;
}
/**
* &lt;windowRight&gt; 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;
}
/**
* &lt;windowRight&gt; 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;
}
/**
* &lt;windowTop&gt; 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;
}
/**
* &lt;windowTop&gt; 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;
}
}

View file

@ -1,367 +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 <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
*/
public class Outline implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private Date created;
private List<Attribute> attributes;
private List<String> categories;
private List<Outline> children;
private List<Module> 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<Attribute>());
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<Attribute> 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<Attribute> getAttributes() {
if (attributes == null) {
attributes = new ArrayList<Attribute>();
}
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<String> 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<String> getCategories() {
if (categories == null) {
categories = new ArrayList<String>();
}
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<Outline> children) {
this.children = children;
}
/**
* A list of sub-outlines for this entry.
*
* @return A list of sub-outlines for this entry.
*/
public List<Outline> getChildren() {
if (children == null) {
children = new ArrayList<Outline>();
}
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<Module> modules) {
this.modules = modules;
}
public List<Module> getModules() {
if (modules == null) {
modules = new ArrayList<Module>();
}
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<Attribute> 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<String>(getCategories()));
o.setComment(isComment());
o.setCreated(created != null ? (Date) created.clone() : null);
o.setModules(new ArrayList<Module>(getModules()));
o.setText(getText());
o.setTitle(getTitle());
o.setType(getType());
final ArrayList<Outline> children = new ArrayList<Outline>();
for (int i = 0; i < getChildren().size(); i++) {
children.add((Outline) this.children.get(i).clone());
}
o.setChildren(children);
final ArrayList<Attribute> attributes = new ArrayList<Attribute>();
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();
}
}
/*
* 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 <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
*/
public class Outline implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private Date created;
private List<Attribute> attributes;
private List<String> categories;
private List<Outline> children;
private List<Module> 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<Attribute>());
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<Attribute> 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<Attribute> getAttributes() {
if (attributes == null) {
attributes = new ArrayList<Attribute>();
}
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<String> 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<String> getCategories() {
if (categories == null) {
categories = new ArrayList<String>();
}
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<Outline> children) {
this.children = children;
}
/**
* A list of sub-outlines for this entry.
*
* @return A list of sub-outlines for this entry.
*/
public List<Outline> getChildren() {
if (children == null) {
children = new ArrayList<Outline>();
}
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<Module> modules) {
this.modules = modules;
}
public List<Module> getModules() {
if (modules == null) {
modules = new ArrayList<Module>();
}
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<Attribute> 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<String>(getCategories()));
o.setComment(isComment());
o.setCreated(created != null ? (Date) created.clone() : null);
o.setModules(new ArrayList<Module>(getModules()));
o.setText(getText());
o.setTitle(getTitle());
o.setType(getType());
final ArrayList<Outline> children = new ArrayList<Outline>();
for (int i = 0; i < getChildren().size(); i++) {
children.add((Outline) this.children.get(i).clone());
}
o.setChildren(children);
final ArrayList<Attribute> attributes = new ArrayList<Attribute>();
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();
}
}

View file

@ -1,349 +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#";
protected void addOwner(final Opml opml, final SyndFeed syndFeed) {
if (opml.getOwnerEmail() != null || opml.getOwnerName() != null) {
final List<SyndPerson> authors = new ArrayList<SyndPerson>();
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.
* <p>
* It assumes the given SyndFeedImpl has no properties set.
* <p>
*
* @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<Integer>(), syndFeed.getEntries(), opml.getOutlines());
}
protected void createEntries(final Stack<Integer> context, final List<SyndEntry> allEntries, final List<Outline> outlines) {
final List<Outline> so = Collections.synchronizedList(outlines);
for (int i = 0; i < so.size(); i++) {
createEntry(context, allEntries, so.get(i));
}
}
protected SyndEntry createEntry(final Stack<Integer> context, final List<SyndEntry> 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<Attribute> 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.
* <p>
*
* @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<SyndEntry> entries = Collections.synchronizedList(syndFeed.getEntries());
final HashMap<String, Outline> entriesByNode = new HashMap<String, Outline>();
// this will hold entries that we can't parent the first time.
final ArrayList<OutlineHolder> doAfterPass = new ArrayList<OutlineHolder>();
// this holds root level outlines;
final ArrayList<Outline> root = new ArrayList<Outline>();
for (int i = 0; i < entries.size(); i++) {
final SyndEntry entry = entries.get(i);
final Outline o = new Outline();
final List<SyndCategory> 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<SyndLink> 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<SyndPerson> 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;
}
}
}
/*
* 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<SyndPerson> authors = new ArrayList<SyndPerson>();
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.
* <p>
* It assumes the given SyndFeedImpl has no properties set.
* <p>
*
* @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<Integer>(), syndFeed.getEntries(), opml.getOutlines());
}
protected void createEntries(final Stack<Integer> context, final List<SyndEntry> allEntries, final List<Outline> outlines) {
final List<Outline> so = Collections.synchronizedList(outlines);
for (int i = 0; i < so.size(); i++) {
createEntry(context, allEntries, so.get(i));
}
}
protected SyndEntry createEntry(final Stack<Integer> context, final List<SyndEntry> 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<Attribute> 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.
* <p>
*
* @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<SyndEntry> entries = Collections.synchronizedList(syndFeed.getEntries());
final HashMap<String, Outline> entriesByNode = new HashMap<String, Outline>();
// this will hold entries that we can't parent the first time.
final ArrayList<OutlineHolder> doAfterPass = new ArrayList<OutlineHolder>();
// this holds root level outlines;
final ArrayList<Outline> root = new ArrayList<Outline>();
for (int i = 0; i < entries.size(); i++) {
final SyndEntry entry = entries.get(i);
final Outline o = new Outline();
final List<SyndCategory> 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<SyndLink> 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<SyndPerson> 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;
}
}
}

View file

@ -1,50 +1,50 @@
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.
* <p>
*
* @return the real feed type.
* @see WireFeed for details on the format of this string.
* <p>
*/
@Override
public String getType() {
return "opml_2.0";
}
/**
* Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl.
* <p>
* It assumes the given SyndFeedImpl has no properties set.
* <p>
*
* @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.
* <p>
*
* @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);
}
}
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.
* <p>
*
* @return the real feed type.
* @see WireFeed for details on the format of this string.
* <p>
*/
@Override
public String getType() {
return "opml_2.0";
}
/**
* Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl.
* <p>
* It assumes the given SyndFeedImpl has no properties set.
* <p>
*
* @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.
* <p>
*
* @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);
}
}

View file

@ -1,23 +1,23 @@
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;
}
}
}
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;
}
}
}

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,73 +1,73 @@
package com.rometools.opml.io.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import java.util.Arrays;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import com.rometools.opml.feed.opml.Opml;
import com.rometools.opml.feed.opml.Outline;
import com.rometools.rome.io.WireFeedOutput;
public class OPML20GeneratorTest {
@Test
public void testOutputOfNullCategory() {
assertThat(categoryOf((String) null).getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfEmptyCategory() {
assertThat(categoryOf("").getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfBlankCategory() {
assertThat(categoryOf(" ").getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfOneCategory() {
assertThat(categoryValueOf("category1"), is(equalTo("category1")));
}
@Test
public void testOutputOfMultipleCategories() {
assertThat(categoryValueOf("category1", "category2"), is(equalTo("category1,category2")));
}
private NodeList categoryOf(final String... categories) {
try {
final Outline outline = new Outline("outline1", null);
outline.setCategories(Arrays.asList(categories));
final Opml opml = new Opml();
opml.setFeedType("opml_2.0");
opml.setTitle("title");
opml.setOutlines(Arrays.asList(outline));
final WireFeedOutput output = new WireFeedOutput();
final String xml = output.outputString(opml);
final Document document = XMLUnit.buildControlDocument(xml);
return XMLUnit.newXpathEngine().getMatchingNodes("/opml/body/outline/@category", document);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private String categoryValueOf(final String... categories) {
return categoryOf(categories).item(0).getNodeValue();
}
}
package com.rometools.opml.io.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import java.util.Arrays;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import com.rometools.opml.feed.opml.Opml;
import com.rometools.opml.feed.opml.Outline;
import com.rometools.rome.io.WireFeedOutput;
public class OPML20GeneratorTest {
@Test
public void testOutputOfNullCategory() {
assertThat(categoryOf((String) null).getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfEmptyCategory() {
assertThat(categoryOf("").getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfBlankCategory() {
assertThat(categoryOf(" ").getLength(), is(equalTo(0)));
}
@Test
public void testOutputOfOneCategory() {
assertThat(categoryValueOf("category1"), is(equalTo("category1")));
}
@Test
public void testOutputOfMultipleCategories() {
assertThat(categoryValueOf("category1", "category2"), is(equalTo("category1,category2")));
}
private NodeList categoryOf(final String... categories) {
try {
final Outline outline = new Outline("outline1", null);
outline.setCategories(Arrays.asList(categories));
final Opml opml = new Opml();
opml.setFeedType("opml_2.0");
opml.setTitle("title");
opml.setOutlines(Arrays.asList(outline));
final WireFeedOutput output = new WireFeedOutput();
final String xml = output.outputString(opml);
final Document document = XMLUnit.buildControlDocument(xml);
return XMLUnit.newXpathEngine().getMatchingNodes("/opml/body/outline/@category", document);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private String categoryValueOf(final String... categories) {
return categoryOf(categories).item(0).getNodeValue();
}
}

View file

@ -1,20 +1,20 @@
package com.rometools.opml.test;
import java.io.IOException;
import java.io.Writer;
public class NullWriter extends Writer {
@Override
public void write(final char[] cbuf, final int off, final int len) throws IOException {
}
@Override
public void flush() throws IOException {
}
@Override
public void close() throws IOException {
}
}
package com.rometools.opml.test;
import java.io.IOException;
import java.io.Writer;
public class NullWriter extends Writer {
@Override
public void write(final char[] cbuf, final int off, final int len) throws IOException {
}
@Override
public void flush() throws IOException {
}
@Override
public void close() throws IOException {
}
}

View file

@ -1,15 +1,15 @@
package com.rometools.opml.test;
import java.io.InputStreamReader;
import java.io.Reader;
public final class TestUtil {
private TestUtil() {
}
public static Reader loadFile(final String path) {
return new InputStreamReader(TestUtil.class.getResourceAsStream(path));
}
}
package com.rometools.opml.test;
import java.io.InputStreamReader;
import java.io.Reader;
public final class TestUtil {
private TestUtil() {
}
public static Reader loadFile(final String path) {
return new InputStreamReader(TestUtil.class.getResourceAsStream(path));
}
}

View file

@ -1,13 +1,13 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="warn">
<appender-ref ref="STDOUT" />
</root>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="warn">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View file

@ -1,76 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<opml version="1.0">
<head>
<title>Top Ten Sources for podcasting</title>
<ownerName>Newsilike Media Group</ownerName>
<ownerEmail>opml@TopTenSources.com</ownerEmail>
<dateCreated>Thu, 27 Apr 2006 05:47:27 GMT</dateCreated>
<dateModified>Thu, 27 Apr 2006 05:47:27 GMT</dateModified>
<expansionState>0</expansionState>
<vertScrollState>0</vertScrollState>
<windowLeft>0</windowLeft>
<windowTop>0</windowTop>
<windowRight>100</windowRight>
<windowBottom>100</windowBottom>
</head>
<body>
<outline type="link" text="TopTenSources: podcasting" url="http://podcasting.TopTenSources.com/TopTenSources/" />
<outline text="CBS Technology News Podcast - Larry Magid' Tech Report">
<outline type="link" text="Larry Magid's Tech Report" url="http://www.cbsnews.com" />
</outline>
<outline text="Adam Curry: Daily Source Code">
<outline type="link" text="#374 Daily Source Code for Tuesday April 25th 2006" url="http://radio.weblogs.com/0001014/2006/04/26.html#a7304" />
<outline type="link" text="#373 Daily Source Code for Monday April 24th 2006" url="http://radio.weblogs.com/0001014/2006/04/24.html#a7303" />
<outline type="link" text="#372 Daily Source Code for Friday April 21st 2006" url="http://radio.weblogs.com/0001014/2006/04/21.html#a7302" />
<outline type="link" text="#371 Daily Source Code for Thursday April 20th 2006" url="http://radio.weblogs.com/0001014/2006/04/20.html#a7301" />
<outline type="link" text="#370 Daily Source Code for Wednesday April 19th 2006" url="http://radio.weblogs.com/0001014/2006/04/19.html#a7300" />
</outline>
<outline text="Gillmor Gang">
<outline type="link" text="Syndicate Gang Part I" url="http://gillmorgang.podshow.com/?p=44" />
<outline type="link" text="HughTrain Gang" url="http://gillmorgang.podshow.com/?p=43" />
<outline type="link" text="Phlegm at 11 Gang" url="http://gillmorgang.podshow.com/?p=42" />
<outline type="link" text="NDA Gang" url="http://gillmorgang.podshow.com/?p=41" />
<outline type="link" text="When the Musics Over Gang" url="http://gillmorgang.podshow.com/?p=40" />
</outline>
<outline text="ITC: All Programs">
<outline type="link" text="Doc Searls: Syndicate" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=689" />
<outline type="link" text="Business Panel: The Podcast Academy" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=688" />
<outline type="link" text="CN Update: April 24, 2006" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=687" />
<outline type="link" text="Hossein Eslambolchi: AT T: The Networked Future is Open" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=686" />
<outline type="link" text="Dileep George: Understanding the Neocortex to Accelerate our Understanding of Intelligence" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=685" />
</outline>
<outline text="FamilyTechTalk">
<outline type="link" text="FamilyTechTalk 24 April 15, 2006" url="http://familytechtalk.com/podcasts/ftt24.mp3" />
<outline type="link" text="FamilyTechTalk 23 April 7, 2006" url="http://familytechtalk.com/podcasts/ftt23.mp3" />
<outline type="link" text="FamilyTechTalk 22 March 31, 2006" url="http://familytechtalk.com/podcasts/ftt22.mp3" />
<outline type="link" text="FamilyTechTalk 20 March 17, 2006" url="http://familytechtalk.com/podcasts/ftt20.mp3" />
<outline type="link" text="FamilyTechTalk 21 March 24, 2006" url="http://familytechtalk.com/podcasts/ftt21.mp3" />
</outline>
<outline text="On The Media from NPR/WNYC">
<outline type="link" text="On The Media - April 14, 2006" url="http://feeds.feedburner.com/onthemedia?m=35" />
<outline type="link" text="On The Media - April 21, 2006" url="http://feeds.wnyc.org/onthemedia?m=37" />
<outline type="link" text="On The Media - April 07, 2006" url="http://feeds.feedburner.com/onthemedia?m=34" />
</outline>
<outline text="Morning Coffee Notes">
<outline type="link" text="OPML 2.0 is easy to understand if you're intelligent, have common sense and are patient. It's really simple. I explain, in this podcast, why the improvements in OPML 2.0 will help users. " url="http://static2.podcatch.com/blogs/gems/snedit/cn06mar01.mp3" />
<outline type="link" text="Today's podcast is about WordPress, Google and the OPML community. It's especially important for the leaders of the OPML community to listen to this podcast, because I want to explore ways for the support system to grow. I think we just had a very good experience and I want to build on it." url="http://static2.podcatch.com/blogs/gems/snedit/cn06feb01.mp3" />
<outline type="link" text="I just recorded a segment for Chris Lydon's show with my state of the union speech, above, and also recorded it as an MP3, so here it is the second Morning Coffee Notes of 2006. &quot;;-&gt;&quot;" url="http://static2.podcatch.com/blogs/gems/snedit/cn06jan31.mp3" />
<outline type="link" text="Morning Coffee Notes interview with John Palfrey, founder of toptensources.com, and director of Berkman Center." url="http://static2.podcatch.com/blogs/gems/snedit/cn05Jan02.mp3" />
<outline type="link" text="A Morning Coffee Notes podcast with thoughts about the scene in New Orleans and on the Gulf Coast. " url="http://static2.podcatch.com/blogs/gems/snedit/cn05Dec16.mp3" />
</outline>
<outline text="Gillmor Daily">
<outline type="link" text="Death Cab for Links Part II" url="http://gillmordaily.podshow.com/?p=66" />
<outline type="link" text="Death Cab for Links Part I" url="http://gillmordaily.podshow.com/?p=65" />
<outline type="link" text="Javas Open Sores? Part II" url="http://gillmordaily.podshow.com/?p=64" />
<outline type="link" text="Javas Open Sores? Part I" url="http://gillmordaily.podshow.com/?p=63" />
<outline type="link" text="Gillmor Daily 1 Redux Part II" url="http://gillmordaily.podshow.com/?p=62" />
</outline>
<outline text="Latest ZDNet Podcasts">
<outline type="link" text="Sling Media CEO Blake Krikorian unplugged" url="http://blogs.zdnet.com/BTL/index.php?p=2924&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Video goes Internet--the future of what you watch" url="http://blogs.zdnet.com/BTL/index.php?p=2920&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Will or could RSS get forked?" url="http://blogs.zdnet.com/BTL/index.php?p=2906&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Learning from the masters: Creating a $1 billion company" url="http://blogs.zdnet.com/BTL/index.php?p=2910&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Apple vs. bloggers, AMD vs. Intel, DRM vs. consumers Yahoo vs. China, Microsoft vs. EU and more..." url="http://blogs.zdnet.com/BTL/index.php?p=2901&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
</outline>
</body>
<?xml version="1.0" encoding="utf-8"?>
<opml version="1.0">
<head>
<title>Top Ten Sources for podcasting</title>
<ownerName>Newsilike Media Group</ownerName>
<ownerEmail>opml@TopTenSources.com</ownerEmail>
<dateCreated>Thu, 27 Apr 2006 05:47:27 GMT</dateCreated>
<dateModified>Thu, 27 Apr 2006 05:47:27 GMT</dateModified>
<expansionState>0</expansionState>
<vertScrollState>0</vertScrollState>
<windowLeft>0</windowLeft>
<windowTop>0</windowTop>
<windowRight>100</windowRight>
<windowBottom>100</windowBottom>
</head>
<body>
<outline type="link" text="TopTenSources: podcasting" url="http://podcasting.TopTenSources.com/TopTenSources/" />
<outline text="CBS Technology News Podcast - Larry Magid' Tech Report">
<outline type="link" text="Larry Magid's Tech Report" url="http://www.cbsnews.com" />
</outline>
<outline text="Adam Curry: Daily Source Code">
<outline type="link" text="#374 Daily Source Code for Tuesday April 25th 2006" url="http://radio.weblogs.com/0001014/2006/04/26.html#a7304" />
<outline type="link" text="#373 Daily Source Code for Monday April 24th 2006" url="http://radio.weblogs.com/0001014/2006/04/24.html#a7303" />
<outline type="link" text="#372 Daily Source Code for Friday April 21st 2006" url="http://radio.weblogs.com/0001014/2006/04/21.html#a7302" />
<outline type="link" text="#371 Daily Source Code for Thursday April 20th 2006" url="http://radio.weblogs.com/0001014/2006/04/20.html#a7301" />
<outline type="link" text="#370 Daily Source Code for Wednesday April 19th 2006" url="http://radio.weblogs.com/0001014/2006/04/19.html#a7300" />
</outline>
<outline text="Gillmor Gang">
<outline type="link" text="Syndicate Gang Part I" url="http://gillmorgang.podshow.com/?p=44" />
<outline type="link" text="HughTrain Gang" url="http://gillmorgang.podshow.com/?p=43" />
<outline type="link" text="Phlegm at 11 Gang" url="http://gillmorgang.podshow.com/?p=42" />
<outline type="link" text="NDA Gang" url="http://gillmorgang.podshow.com/?p=41" />
<outline type="link" text="When the Musics Over Gang" url="http://gillmorgang.podshow.com/?p=40" />
</outline>
<outline text="ITC: All Programs">
<outline type="link" text="Doc Searls: Syndicate" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=689" />
<outline type="link" text="Business Panel: The Podcast Academy" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=688" />
<outline type="link" text="CN Update: April 24, 2006" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=687" />
<outline type="link" text="Hossein Eslambolchi: AT T: The Networked Future is Open" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=686" />
<outline type="link" text="Dileep George: Understanding the Neocortex to Accelerate our Understanding of Intelligence" url="http://feeds.feedburner.com/ITConversations-EverythingMP3?m=685" />
</outline>
<outline text="FamilyTechTalk">
<outline type="link" text="FamilyTechTalk 24 April 15, 2006" url="http://familytechtalk.com/podcasts/ftt24.mp3" />
<outline type="link" text="FamilyTechTalk 23 April 7, 2006" url="http://familytechtalk.com/podcasts/ftt23.mp3" />
<outline type="link" text="FamilyTechTalk 22 March 31, 2006" url="http://familytechtalk.com/podcasts/ftt22.mp3" />
<outline type="link" text="FamilyTechTalk 20 March 17, 2006" url="http://familytechtalk.com/podcasts/ftt20.mp3" />
<outline type="link" text="FamilyTechTalk 21 March 24, 2006" url="http://familytechtalk.com/podcasts/ftt21.mp3" />
</outline>
<outline text="On The Media from NPR/WNYC">
<outline type="link" text="On The Media - April 14, 2006" url="http://feeds.feedburner.com/onthemedia?m=35" />
<outline type="link" text="On The Media - April 21, 2006" url="http://feeds.wnyc.org/onthemedia?m=37" />
<outline type="link" text="On The Media - April 07, 2006" url="http://feeds.feedburner.com/onthemedia?m=34" />
</outline>
<outline text="Morning Coffee Notes">
<outline type="link" text="OPML 2.0 is easy to understand if you're intelligent, have common sense and are patient. It's really simple. I explain, in this podcast, why the improvements in OPML 2.0 will help users. " url="http://static2.podcatch.com/blogs/gems/snedit/cn06mar01.mp3" />
<outline type="link" text="Today's podcast is about WordPress, Google and the OPML community. It's especially important for the leaders of the OPML community to listen to this podcast, because I want to explore ways for the support system to grow. I think we just had a very good experience and I want to build on it." url="http://static2.podcatch.com/blogs/gems/snedit/cn06feb01.mp3" />
<outline type="link" text="I just recorded a segment for Chris Lydon's show with my state of the union speech, above, and also recorded it as an MP3, so here it is the second Morning Coffee Notes of 2006. &quot;;-&gt;&quot;" url="http://static2.podcatch.com/blogs/gems/snedit/cn06jan31.mp3" />
<outline type="link" text="Morning Coffee Notes interview with John Palfrey, founder of toptensources.com, and director of Berkman Center." url="http://static2.podcatch.com/blogs/gems/snedit/cn05Jan02.mp3" />
<outline type="link" text="A Morning Coffee Notes podcast with thoughts about the scene in New Orleans and on the Gulf Coast. " url="http://static2.podcatch.com/blogs/gems/snedit/cn05Dec16.mp3" />
</outline>
<outline text="Gillmor Daily">
<outline type="link" text="Death Cab for Links Part II" url="http://gillmordaily.podshow.com/?p=66" />
<outline type="link" text="Death Cab for Links Part I" url="http://gillmordaily.podshow.com/?p=65" />
<outline type="link" text="Javas Open Sores? Part II" url="http://gillmordaily.podshow.com/?p=64" />
<outline type="link" text="Javas Open Sores? Part I" url="http://gillmordaily.podshow.com/?p=63" />
<outline type="link" text="Gillmor Daily 1 Redux Part II" url="http://gillmordaily.podshow.com/?p=62" />
</outline>
<outline text="Latest ZDNet Podcasts">
<outline type="link" text="Sling Media CEO Blake Krikorian unplugged" url="http://blogs.zdnet.com/BTL/index.php?p=2924&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Video goes Internet--the future of what you watch" url="http://blogs.zdnet.com/BTL/index.php?p=2920&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Will or could RSS get forked?" url="http://blogs.zdnet.com/BTL/index.php?p=2906&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Learning from the masters: Creating a $1 billion company" url="http://blogs.zdnet.com/BTL/index.php?p=2910&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
<outline type="link" text="Apple vs. bloggers, AMD vs. Intel, DRM vs. consumers Yahoo vs. China, Microsoft vs. EU and more..." url="http://blogs.zdnet.com/BTL/index.php?p=2901&amp;part=rss&amp;tag=feed&amp;subj=zdblog" />
</outline>
</body>
</opml>