View Javadoc

1   /*
2    * Copyright James Leigh (c) 2007.
3    *
4    * Licensed under the Aduna BSD-style license.
5    */
6   package org.openrdf.rio.rss;
7   
8   import java.io.File;
9   import java.io.FileNotFoundException;
10  import java.io.IOException;
11  import java.io.OutputStream;
12  import java.io.PrintWriter;
13  import java.io.UnsupportedEncodingException;
14  import java.io.Writer;
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.List;
18  import java.util.Map;
19  
20  import info.aduna.iteration.Iteration;
21  import info.aduna.iteration.Iterations;
22  
23  import org.openrdf.model.Resource;
24  import org.openrdf.model.Statement;
25  import org.openrdf.model.URI;
26  import org.openrdf.model.Value;
27  import org.openrdf.model.impl.StatementImpl;
28  import org.openrdf.model.impl.URIImpl;
29  import org.openrdf.model.vocabulary.DC;
30  import org.openrdf.model.vocabulary.RDF;
31  import org.openrdf.model.vocabulary.RDFS;
32  import org.openrdf.model.vocabulary.RSS;
33  import org.openrdf.repository.RepositoryConnection;
34  import org.openrdf.repository.RepositoryException;
35  import org.openrdf.rio.RDFHandlerException;
36  import org.openrdf.rio.rdfxml.util.RDFXMLPrettyWriter;
37  
38  /**
39   * Outputs an RSS feed from a given channel resource.
40   * 
41   * @author James Leigh
42   * 
43   */
44  public class RssWriter extends RDFXMLPrettyWriter {
45  
46  	private static List<URI> members = null;
47  
48  	private RepositoryConnection connection;
49  
50  	public RssWriter(File file, String enc)
51  		throws FileNotFoundException, UnsupportedEncodingException
52  	{
53  		this(new PrintWriter(file, enc));
54  	}
55  
56  	public RssWriter(File file)
57  		throws FileNotFoundException
58  	{
59  		this(new PrintWriter(file));
60  	}
61  
62  	public RssWriter(String filename, String enc)
63  		throws FileNotFoundException, UnsupportedEncodingException
64  	{
65  		this(new PrintWriter(filename, enc));
66  	}
67  
68  	public RssWriter(String filename)
69  		throws FileNotFoundException
70  	{
71  		this(new PrintWriter(filename));
72  	}
73  
74  	public RssWriter(OutputStream writer) {
75  		super(writer);
76  		initNamespaces();
77  	}
78  
79  	public RssWriter(Writer writer) {
80  		super(writer);
81  		initNamespaces();
82  	}
83  
84  	public void setConnection(RepositoryConnection connection) {
85  		this.connection = connection;
86  	}
87  
88  	protected void initNamespaces() {
89  		setNamespace("", RSS.NAMESPACE, true);
90  		setNamespace("dc", DC.NAMESPACE, false);
91  		setNamespace("rdf", RDF.NAMESPACE, false);
92  		setNamespace("rdfs", RDFS.NAMESPACE, false);
93  	}
94  
95  	public void printChannel(Resource channel)
96  		throws RepositoryException, RDFHandlerException
97  	{
98  		printStatement(channel, RDF.TYPE, RSS.CHANNEL);
99  		printProperty(channel, RSS.TITLE);
100 		printProperty(channel, RSS.LINK);
101 		printProperty(channel, RSS.DESCRIPTION);
102 		printProperty(channel, RSS.IMAGE);
103 		printProperty(channel, RSS.TEXTINPUT);
104 
105 		printDCProperties(channel);
106 
107 		Iteration<? extends Statement, RepositoryException> items = null;
108 		try {
109 			items = connection.getStatements(channel, RSS.ITEMS, null, true);
110 			while (items.hasNext()) {
111 				Resource seq = (Resource)items.next().getObject();
112 				printStatement(channel, RSS.ITEMS, seq);
113 				printStatement(seq, RDF.TYPE, RDF.SEQ);
114 				Map<URI, Value> properties = getProperties(seq);
115 				for (int i = 0; properties.containsKey(getMemberPredicate(i)); i++)
116 					printStatement(seq, RDF.LI, properties.get(getMemberPredicate(i)));
117 				try {
118 					flushPendingStatements();
119 				} catch (IOException e) {
120 					throw new RDFHandlerException(e);
121 				}
122 				for (int i = 0; properties.containsKey(getMemberPredicate(i)); i++)
123 					printItem((Resource)properties.get(getMemberPredicate(i)));
124 			}
125 		}
126 		finally {
127 			Iterations.closeCloseable(items);
128 		}
129 	}
130 
131 	public void printItem(Resource item)
132 		throws RDFHandlerException, RepositoryException
133 	{
134 		printStatement(item, RDF.TYPE, RSS.ITEM);
135 		printProperty(item, RSS.TITLE);
136 		printProperty(item, RSS.LINK);
137 		printProperty(item, RSS.DESCRIPTION);
138 	}
139 
140 	protected void printDCProperties(Resource subj)
141 		throws RDFHandlerException, RepositoryException
142 	{
143 		printProperty(subj, DC.TITLE);
144 		printProperty(subj, DC.SUBJECT);
145 		printProperty(subj, DC.DESCRIPTION);
146 		printProperty(subj, DC.DATE);
147 		printProperty(subj, DC.TYPE);
148 		printProperty(subj, DC.CONTRIBUTOR);
149 		printProperty(subj, DC.COVERAGE);
150 		printProperty(subj, DC.CREATOR);
151 		printProperty(subj, DC.FORMAT);
152 		printProperty(subj, DC.IDENTIFIER);
153 		printProperty(subj, DC.LANGUAGE);
154 		printProperty(subj, DC.PUBLISHER);
155 		printProperty(subj, DC.RELATION);
156 		printProperty(subj, DC.RIGHTS);
157 		printProperty(subj, DC.SOURCE);
158 	}
159 
160 	private void printProperty(Resource subj, URI pred)
161 		throws RDFHandlerException, RepositoryException
162 	{
163 		Iteration<? extends Statement, RepositoryException> iter = null;
164 		try {
165 			iter = connection.getStatements(subj, pred, null, false);
166 			while (iter.hasNext()) {
167 				Statement st = iter.next();
168 				printStatement(subj, pred, st.getObject());
169 			}
170 		}
171 		finally {
172 			Iterations.closeCloseable(iter);
173 		}
174 	}
175 
176 	private void printStatement(Resource subject, URI predicate, Value object)
177 		throws RDFHandlerException
178 	{
179 		handleStatement(new StatementImpl(subject, predicate, object));
180 	}
181 
182 	protected Map<URI, Value> getProperties(Resource subj)
183 		throws RepositoryException
184 	{
185 		Iteration<? extends Statement, RepositoryException> iter = null;
186 		try {
187 			Map<URI, Value> map = new HashMap<URI, Value>();
188 			iter = connection.getStatements(subj, null, null, false);
189 			while (iter.hasNext()) {
190 				Statement stmt = iter.next();
191 				map.put(stmt.getPredicate(), stmt.getObject());
192 			}
193 			return map;
194 		}
195 		finally {
196 			Iterations.closeCloseable(iter);
197 		}
198 	}
199 
200 	protected URI getMemberPredicate(int index) {
201 		if (members != null && members.size() > index)
202 			return members.get(index);
203 		synchronized (RDFXMLPrettyWriter.class) {
204 			if (members != null && members.size() > index)
205 				return members.get(index);
206 			List<URI> old_members = members;
207 			int capasity = 16;
208 			if (old_members != null)
209 				capasity = old_members.size() * 2;
210 			if (capasity <= index)
211 				capasity = index + 1;
212 			List<URI> new_members = new ArrayList<URI>(capasity);
213 			if (old_members != null)
214 				new_members.addAll(old_members);
215 			for (int i = new_members.size(); i < capasity; i++) {
216 				new_members.add(i, new URIImpl(RDF.NAMESPACE + "_" + (i + 1)));
217 			}
218 			members = new_members;
219 			return new_members.get(index);
220 		}
221 	}
222 
223 }