1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.exorcist.midgard;
17
18 import java.io.ByteArrayInputStream;
19 import java.io.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.FileFilter;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.sql.Connection;
26 import java.sql.DriverManager;
27 import java.sql.PreparedStatement;
28 import java.sql.ResultSet;
29 import java.sql.SQLException;
30 import java.util.Iterator;
31
32 import javax.xml.parsers.ParserConfigurationException;
33
34 import org.xml.sax.SAXException;
35
36 import net.sf.exorcist.api.ContentException;
37 import net.sf.exorcist.api.ContentExporter;
38 import net.sf.exorcist.api.ContentState;
39
40 public class MidgardExporter implements ContentExporter {
41
42 static {
43 try {
44 Class.forName("com.mysql.jdbc.Driver");
45 } catch (ClassNotFoundException e) {
46 e.printStackTrace();
47 }
48 }
49
50 private ContentState state;
51
52 private DOMBuilder builder;
53
54 private Connection connection;
55
56 private GUIDResolver guidFinder;
57
58 private MidgardSchema schema;
59
60 private int sitegroup;
61
62 private String database;
63
64 private String username;
65
66 private String password;
67
68 private String filepath;
69
70 public void setSitegroup(int sitegroup) {
71 this.sitegroup = sitegroup;
72 }
73
74 public void setSchema(String file)
75 throws IOException, ParserConfigurationException, SAXException {
76 schema = new MidgardSchema();
77 schema.parse(new FileInputStream(file));
78 }
79
80 public void setFilepath(String filepath) {
81 this.filepath = filepath;
82 }
83
84 public void setDatabase(String database) {
85 this.database = database;
86 }
87
88 public void setUsername(String username) {
89 this.username = username;
90 }
91
92 public void setPassword(String password) {
93 this.password = password;
94 }
95
96 public void exportContent(ContentState state) throws ContentException {
97 try {
98 if (schema == null) {
99 InputStream input = MidgardExporter.class.getClassLoader()
100 .getResourceAsStream("net/sf/exorcist/midgard/midgard.xml");
101 try {
102 schema = new MidgardSchema();
103 schema.parse(input);
104 } finally {
105 input.close();
106 }
107 }
108
109 this.state = state;
110 this.connection =
111 DriverManager.getConnection(database, username, password);
112 this.guidFinder = new GUIDResolver(connection);
113
114 builder = new DOMBuilder(
115 "site", "http://ns.yukatan.fi/2005/midgard", "mgd");
116 exportAll(schema);
117 ByteArrayOutputStream xml = new ByteArrayOutputStream();
118 builder.write(xml);
119 state.setContent(new ByteArrayInputStream(xml.toByteArray()));
120 } catch (SQLException e) {
121 throw new ContentException(e);
122 } catch (IOException e) {
123 throw new ContentException(e);
124 } catch (SAXException e) {
125 throw new ContentException(e);
126 } catch (ParserConfigurationException e) {
127 throw new ContentException(e);
128 }
129 }
130
131 private void exportAll(MidgardSchema schema) throws IOException, SQLException {
132 Iterator types = schema.getTypes();
133 while (types.hasNext()) {
134 MidgardType type = (MidgardType) types.next();
135 MidgardProperty primary = type.getPrimary();
136 MidgardProperty parent = type.getParent();
137
138 StringBuffer sql = new StringBuffer();
139 sql.append("SELECT ");
140 sql.append(primary.getName());
141 Iterator properties = type.getProperties();
142 while (properties.hasNext()) {
143 MidgardProperty property = (MidgardProperty) properties.next();
144 if (property != primary && property != parent) {
145 sql.append(", ");
146 sql.append(property.getName());
147 }
148 }
149 sql.append(" FROM ");
150 sql.append(type.getTable());
151 sql.append(" WHERE sitegroup=?");
152 if (parent != null) {
153 sql.append(" AND ");
154 sql.append(parent.getName());
155 sql.append(" = ?");
156 }
157 PreparedStatement ps = connection.prepareStatement(sql.toString());
158 try {
159 ps.setInt(1, sitegroup);
160 if (parent != null) {
161 ps.setInt(2, 0);
162 }
163
164 ResultSet rs = ps.executeQuery();
165 try {
166 while (rs.next()) {
167 builder.startElement(type.getName());
168 int id = rs.getInt(1);
169 builder.addContentElement(
170 "guid", guidFinder.findGUID(type.getTable(), id));
171 properties = type.getProperties();
172 while (properties.hasNext()) {
173 MidgardProperty property = (MidgardProperty) properties.next();
174 if (property != primary && property != parent) {
175 MidgardType link = property.getLink();
176 if (link != null) {
177 builder.addContentElement(
178 property.getName(),
179 guidFinder.findGUID(link.getTable(), rs.getInt(property.getName())));
180 } else {
181 builder.addContentElement(
182 property.getName(),
183 rs.getString(property.getName()));
184 }
185 }
186 }
187 exportParameters(type.getTable(), id);
188 exportAttachments(type.getTable(), id);
189 exportChildren(type, id);
190 builder.endElement();
191 }
192 } finally {
193 rs.close();
194 }
195 } finally {
196 ps.close();
197 }
198 }
199 }
200
201 private void exportChildren(MidgardType type, int id)
202 throws IOException, SQLException {
203 Iterator children = type.getChildren();
204 while (children.hasNext()) {
205 MidgardType child = (MidgardType) children.next();
206 MidgardProperty primary = child.getPrimary();
207 MidgardProperty parent = child.getParent();
208
209 StringBuffer sql = new StringBuffer();
210 sql.append("SELECT ");
211 sql.append(primary.getName());
212 Iterator properties = child.getProperties();
213 while (properties.hasNext()) {
214 MidgardProperty property = (MidgardProperty) properties.next();
215 if (property != primary && property != parent) {
216 sql.append(", ");
217 sql.append(property.getName());
218 }
219 }
220 sql.append(" FROM ");
221 sql.append(child.getTable());
222 sql.append(" WHERE sitegroup=?");
223 if (parent != null) {
224 sql.append(" AND ");
225 sql.append(parent.getName());
226 sql.append(" = ?");
227 }
228 PreparedStatement ps = connection.prepareStatement(sql.toString());
229 try {
230 ps.setInt(1, sitegroup);
231 if (parent != null) {
232 ps.setInt(2, id);
233 }
234
235 ResultSet rs = ps.executeQuery();
236 try {
237 while (rs.next()) {
238 if (child.getName().equals("midgard_article")
239 && rs.getInt("type") == 2) {
240 continue;
241 }
242 builder.startElement(child.getName());
243 int childId = rs.getInt(1);
244 builder.addContentElement(
245 "guid", guidFinder.findGUID(child.getTable(), childId));
246 properties = child.getProperties();
247 while (properties.hasNext()) {
248 MidgardProperty property = (MidgardProperty) properties.next();
249 if (property != primary && property != parent) {
250 MidgardType link = property.getLink();
251 if (link != null) {
252 builder.addContentElement(
253 property.getName(),
254 guidFinder.findGUID(link.getTable(), rs.getInt(property.getName())));
255 } else {
256 builder.addContentElement(
257 property.getName(),
258 rs.getString(property.getName()));
259 }
260 }
261 }
262 exportParameters(child.getTable(), childId);
263 exportAttachments(child.getTable(), childId);
264 exportChildren(child, childId);
265 builder.endElement();
266 }
267 } finally {
268 rs.close();
269 }
270 } finally {
271 ps.close();
272 }
273 }
274 }
275
276 private void exportParameters(String table, int id) throws SQLException {
277 PreparedStatement ps = connection.prepareStatement(
278 "SELECT domain, name, value FROM record_extension"
279 + " WHERE tablename = ? AND oid = ? AND sitegroup = ?");
280 try {
281 ps.setString(1, table);
282 ps.setInt(2, id);
283 ps.setInt(3, sitegroup);
284 ResultSet rs = ps.executeQuery();
285 try {
286 while (rs.next()) {
287 builder.startElement("parameter");
288 builder.addContentElement("domain", rs.getString("domain"));
289 builder.addContentElement("name", rs.getString("name"));
290 builder.addContentElement("value", rs.getString("value"));
291 builder.endElement();
292 }
293 } finally {
294 rs.close();
295 }
296 } finally {
297 ps.close();
298 }
299 }
300
301 private void exportAttachments(String table, int id)
302 throws IOException, SQLException {
303 PreparedStatement ps = connection.prepareStatement(
304 "SELECT id, name, title, location, mimetype, author, created"
305 + " FROM blobs WHERE ptable = ? AND pid = ? AND sitegroup = ?"
306 + " ORDER BY score, name");
307 try {
308 ps.setString(1, table);
309 ps.setInt(2, id);
310 ps.setInt(3, sitegroup);
311 ResultSet rs = ps.executeQuery();
312 try {
313 while (rs.next()) {
314 String name = rs.getString("name");
315 String location = rs.getString("location");
316 File file = new File(filepath, location);
317 if (file.exists() && !name.startsWith("__")) {
318 InputStream input = new FileInputStream(filepath + location);
319 try {
320 String hash = state.addAttachment(input);
321 builder.startElement("attachment");
322 builder.addContentElement(
323 "guid", guidFinder.findGUID("blobs", rs.getInt("id")));
324 builder.addContentElement("name", name);
325 builder.addContentElement("title", rs.getString("title"));
326 builder.addContentElement("mimetype", rs.getString("mimetype"));
327 builder.addContentElement("location", hash);
328 builder.addContentElement(
329 "author", guidFinder.findGUID("person", rs.getInt("author")));
330 builder.addContentElement("created", rs.getString("created"));
331 builder.endElement();
332 } finally {
333 input.close();
334 }
335 }
336 }
337 } finally {
338 rs.close();
339 }
340 } finally {
341 ps.close();
342 }
343 }
344
345 }