/*
* Feed.java
*
* Created on July 16, 2007, 12:06 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.app.client;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Collection;
import java.util.Collections;
import org.infoset.xml.Child;
import org.infoset.xml.Document;
import org.infoset.xml.Element;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.Item;
import org.infoset.xml.ItemConstructor;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.XMLException;
import org.infoset.xml.util.DocumentSource;
/**
*
* @author alex
*/
public class Feed extends CategorizedXMLEntity
{
Map<String,Entry> byId;
List<Entry> byOrder;
Map<URI,List<Entry>> byCategory;
/** Creates a new instance of Feed */
public Feed(Document doc)
throws XMLException
{
this(doc,false,true);
}
public Feed(Document doc,boolean ordered,boolean loadEntries)
throws XMLException
{
super(doc);
byId = new TreeMap<String,Entry>();
byOrder = ordered ? new ArrayList<Entry>() : null;
byCategory = null;
init(loadEntries);
}
public Feed()
{
super(null);
byId = new TreeMap<String,Entry>();
byOrder = null;
byCategory = null;
try {
doc = InfosetFactory.getDefaultInfoset().createItemConstructor().createDocument();
doc.createDocumentElement(XML.FEED_NAME);
} catch (XMLException ex) {
// THis should only happen if the infoset is misconfigured
throw new RuntimeException("Cannot create feed document.",ex);
}
index();
}
protected void init(boolean loadEntries)
throws XMLException
{
if (loadEntries) {
Iterator<Element> entries = doc.getDocumentElement().getElementsByName(XML.ENTRY_NAME);
ItemConstructor constructor = InfosetFactory.getDefaultInfoset().createItemConstructor();
while (entries.hasNext()) {
Document entryDoc = constructor.createDocument(doc.getBaseURI());
entryDoc.add((Child)entries.next().copyOfItem(true));
add(new Entry(entryDoc));
}
}
}
public void add(Entry entry)
{
String id = entry.getId();
byId.put(id,entry);
if (byOrder!=null) {
byOrder.add(entry);
}
}
public Collection<String> getEntryIds() {
return byId.keySet();
}
public Collection<Entry> getEntries() {
return byOrder==null ? byId.values() : byOrder;
}
public void index() {
super.index();
byCategory = new TreeMap<URI,List<Entry>>();
for (Entry entry : byId.values()) {
entry.index();
for (Term term : entry.getTerms().values()) {
List<Entry> entries = byCategory.get(term.getURI());
if (entries==null) {
entries = new ArrayList<Entry>();
byCategory.put(term.getURI(),entries);
}
entries.add(entry);
}
}
}
public Collection<Entry> getEntriesByTerm(URI term)
{
if (byCategory==null) {
Collection<Entry> empty = Collections.emptyList();
return empty;
} else {
Collection<Entry> entries = byCategory.get(term);
if (entries==null) {
entries = Collections.emptyList();
}
return entries;
}
}
public void generate(final ItemDestination dest)
throws XMLException
{
if (doc==null) {
throw new XMLException("The feed instance was not instantiated using a document.");
}
ItemDestination top = new ItemDestination() {
int level = 0;
public void send(Item item)
throws XMLException
{
switch (item.getType()) {
case DocumentItem:
level++;
break;
case ElementItem:
level++;
break;
case ElementEndItem:
if (level==2) {
for (Entry entry : byId.values()) {
DocumentSource.generate(entry.getDocument().getDocumentElement(),false,dest);
}
}
}
dest.send(item);
switch (item.getType()) {
case DocumentEndItem:
level--;
break;
case ElementEndItem:
level--;
break;
}
}
};
DocumentSource.generate(doc, false, top);
}
}