com.rometools.modules.sse.SSE091Parser Maven / Gradle / Ivy
/*
* 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.modules.sse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.jdom2.Attribute;
import org.jdom2.DataConversionException;
import org.jdom2.Element;
import org.jdom2.filter.AbstractFilter;
import com.rometools.modules.sse.modules.Conflict;
import com.rometools.modules.sse.modules.Conflicts;
import com.rometools.modules.sse.modules.History;
import com.rometools.modules.sse.modules.Related;
import com.rometools.modules.sse.modules.SSEModule;
import com.rometools.modules.sse.modules.Sharing;
import com.rometools.modules.sse.modules.Sync;
import com.rometools.modules.sse.modules.Update;
import com.rometools.rome.feed.module.Module;
import com.rometools.rome.feed.rss.Item;
import com.rometools.rome.io.DelegatingModuleParser;
import com.rometools.rome.io.WireFeedParser;
import com.rometools.rome.io.impl.DateParser;
import com.rometools.rome.io.impl.RSS20Parser;
/**
* Parses embedded SSE content from RSS channel and item content.
*
* @author ldornin
*/
public class SSE091Parser implements DelegatingModuleParser {
// root of the sharing element
private RSS20Parser rssParser;
/** Creates a new instance of SSE091Parser */
public SSE091Parser() {
}
@Override
public void setFeedParser(final WireFeedParser feedParser) {
rssParser = (RSS20Parser) feedParser;
}
@Override
public String getNamespaceUri() {
return SSEModule.SSE_SCHEMA_URI;
}
@Override
public Module parse(final Element element, final Locale locale) {
SSEModule sseModule = null;
final String name = element.getName();
if (name.equals("rss")) {
sseModule = parseSharing(element, locale);
} else if (name.equals("item")) {
sseModule = parseSync(element, locale);
}
return sseModule;
}
private Sharing parseSharing(final Element element, final Locale locale) {
final Element root = getRoot(element);
Sharing sharing = null;
final Element sharingChild = root.getChild(Sharing.NAME, SSEModule.SSE_NS);
if (sharingChild != null) {
sharing = new Sharing();
sharing.setOrdered(parseBooleanAttr(sharingChild, Sharing.ORDERED_ATTRIBUTE));
sharing.setSince(parseDateAttribute(sharingChild, Sharing.SINCE_ATTRIBUTE, locale));
sharing.setUntil(parseDateAttribute(sharingChild, Sharing.UNTIL_ATTRIBUTE, locale));
sharing.setWindow(parseIntegerAttribute(sharingChild, Sharing.WINDOW_ATTRIBUTE));
sharing.setVersion(parseStringAttribute(sharingChild, Sharing.VERSION_ATTRIBUTE));
parseRelated(root, sharing, locale);
}
return sharing;
}
private void parseRelated(final Element root, final Sharing sharing, final Locale locale) {
Related related;
final Element relatedChild = root.getChild(Related.NAME, SSEModule.SSE_NS);
if (relatedChild != null) {
related = new Related();
// TODO; is this an attribute?
related.setLink(parseStringAttribute(relatedChild, Related.LINK_ATTRIBUTE));
related.setSince(parseDateAttribute(relatedChild, Related.SINCE_ATTRIBUTE, locale));
related.setTitle(parseStringAttribute(relatedChild, Related.TITLE_ATTRIBUTE));
related.setType(parseIntegerAttribute(relatedChild, Related.TYPE_ATTRIBUTE));
related.setUntil(parseDateAttribute(relatedChild, Related.UNTIL_ATTRIBUTE, locale));
sharing.setRelated(related);
}
}
private Sync parseSync(final Element element, final Locale locale) {
// Now I am going to get the item specific tags
final Element syncChild = element.getChild(Sync.NAME, SSEModule.SSE_NS);
Sync sync = null;
if (syncChild != null) {
sync = new Sync();
sync.setId(parseStringAttribute(syncChild, Sync.ID_ATTRIBUTE));
sync.setVersion(parseIntegerAttribute(syncChild, Sync.VERSION_ATTRIBUTE));
sync.setDeleted(parseBooleanAttr(syncChild, Sync.DELETED_ATTRIBUTE));
sync.setConflict(parseBooleanAttr(syncChild, Sync.CONFLICT_ATTRIBUTE));
sync.setHistory(parseHistory(syncChild, locale));
sync.setConflicts(parseConflicts(syncChild, locale));
}
return sync;
}
private List parseConflicts(final Element syncElement, final Locale locale) {
List conflicts = null;
final List conflictsContent = syncElement.getContent(new ContentFilter(Conflicts.NAME));
for (final Element conflictsElement : conflictsContent) {
final List conflictContent = conflictsElement.getContent(new ContentFilter(Conflict.NAME));
for (final Element element : conflictContent) {
final Element conflictElement = element;
final Conflict conflict = new Conflict();
conflict.setBy(parseStringAttribute(conflictElement, Conflict.BY_ATTRIBUTE));
conflict.setWhen(parseDateAttribute(conflictElement, Conflict.WHEN_ATTRIBUTE, locale));
conflict.setVersion(parseIntegerAttribute(conflictElement, Conflict.VERSION_ATTRIBUTE));
final List conflictItemContent = conflictElement.getContent(new ContentFilter("item"));
for (final Element element2 : conflictItemContent) {
final Element conflictItemElement = element2;
final Element root = getRoot(conflictItemElement);
final Item conflictItem = rssParser.parseItem(root, conflictItemElement, locale);
conflict.setItem(conflictItem);
if (conflicts == null) {
conflicts = new ArrayList();
}
conflicts.add(conflict);
}
}
}
return conflicts;
}
private Element getRoot(final Element start) {
// reach up to grab the sharing element out of the root
Element root = start;
while (root.getParent() != null && root.getParent() instanceof Element) {
root = (Element) root.getParent();
}
return root;
}
private History parseHistory(final Element historyElement, final Locale locale) {
final Element historyContent = getFirstContent(historyElement, History.NAME);
History history = null;
if (historyContent != null) {
history = new History();
history.setBy(parseStringAttribute(historyContent, History.BY_ATTRIBUTE));
history.setWhen(parseDateAttribute(historyContent, History.WHEN_ATTRIBUTE, locale));
parseUpdates(historyContent, history, locale);
}
return history;
}
private Element getFirstContent(final Element element, final String name) {
final List filterList = element.getContent(new ContentFilter(name));
Element firstContent = null;
if (filterList != null && !filterList.isEmpty()) {
firstContent = filterList.get(0);
}
return firstContent;
}
private void parseUpdates(final Element historyChild, final History history, final Locale locale) {
final List updatedChildren = historyChild.getContent(new ContentFilter(Update.NAME));
for (final Element updateChild : updatedChildren) {
final Update update = new Update();
update.setBy(parseStringAttribute(updateChild, Update.BY_ATTRIBUTE));
update.setWhen(parseDateAttribute(updateChild, Update.WHEN_ATTRIBUTE, locale));
history.addUpdate(update);
}
}
private String parseStringAttribute(final Element syncChild, final String attrName) {
final Attribute idAttribute = syncChild.getAttribute(attrName);
return idAttribute != null ? idAttribute.getValue().trim() : null;
}
private Integer parseIntegerAttribute(final Element sharingChild, final String attrName) {
final Attribute integerAttribute = sharingChild.getAttribute(attrName);
Integer integerAttr = null;
if (integerAttribute != null) {
try {
integerAttr = new Integer(integerAttribute.getIntValue());
} catch (final DataConversionException e) {
// dont use the data
}
}
return integerAttr;
}
private Boolean parseBooleanAttr(final Element sharingChild, final String attrName) {
final Attribute attribute = sharingChild.getAttribute(attrName);
Boolean attrValue = null;
if (attribute != null) {
try {
attrValue = Boolean.valueOf(attribute.getBooleanValue());
} catch (final DataConversionException e) {
// dont use the data
}
}
return attrValue;
}
private Date parseDateAttribute(final Element childElement, final String attrName, final Locale locale) {
final Attribute dateAttribute = childElement.getAttribute(attrName);
final Date date = null;
if (dateAttribute != null) {
// SSE spec requires the timezone to be 'GMT'
// admittedly, this is a bit heavy-handed
final String dateAttr = dateAttribute.getValue().trim();
return DateParser.parseRFC822(dateAttr, locale);
}
return date;
}
private static class ContentFilter extends AbstractFilter {
private static final long serialVersionUID = 1L;
private final String name;
private ContentFilter(final String name) {
this.name = name;
}
@Override
public Element filter(final Object content) {
final Element returnValue;
if (content instanceof Element && name.equals(((Element) content).getName())) {
returnValue = (Element) content;
} else {
returnValue = null;
}
return returnValue;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy