KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snipsnap > snip > XMLSnipImport


1 /*
2  * This file is part of "SnipSnap Wiki/Weblog".
3  *
4  * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel
5  * All Rights Reserved.
6  *
7  * Please visit http://snipsnap.org/ for updates and contact.
8  *
9  * --LICENSE NOTICE--
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  * --LICENSE NOTICE--
24  */

25 package org.snipsnap.snip;
26
27 import org.apache.commons.codec.binary.Base64;
28 import org.dom4j.DocumentException;
29 import org.dom4j.Element;
30 import org.dom4j.ElementHandler;
31 import org.dom4j.ElementPath;
32 import org.dom4j.io.SAXReader;
33 import org.radeox.util.logging.Logger;
34 import org.snipsnap.app.Application;
35 import org.snipsnap.config.Configuration;
36 import org.snipsnap.container.Components;
37 import org.snipsnap.jdbc.IntHolder;
38 import org.snipsnap.snip.storage.SnipSerializer;
39 import org.snipsnap.snip.storage.UserSerializer;
40 import org.snipsnap.user.User;
41 import org.snipsnap.user.UserManager;
42 import org.snipsnap.versioning.VersionManager;
43
44 import java.io.BufferedOutputStream JavaDoc;
45 import java.io.File JavaDoc;
46 import java.io.FileOutputStream JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.io.InputStream JavaDoc;
49 import java.io.InputStreamReader JavaDoc;
50 import java.util.HashMap JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.Map JavaDoc;
54
55 /**
56  * Helper class for importing serialized database backups.
57  *
58  * @author Matthias L. Jugel
59  * @version $Id: XMLSnipImport.java 1835 2005-10-05 12:57:31Z leo $
60  */

61 public class XMLSnipImport {
62   public final static int IMPORT_USERS = 0x01;
63   public final static int IMPORT_SNIPS = 0x02;
64   public final static int OVERWRITE = 0x04;
65
66   private static ThreadLocal JavaDoc instance = new ThreadLocal JavaDoc() {
67     protected synchronized Object JavaDoc initialValue() {
68       return new HashMap JavaDoc();
69     }
70   };
71
72   public static IntHolder getStatus() {
73     IntHolder current = (IntHolder) ((Map JavaDoc) instance.get()).get("current");
74     if (null == current) {
75       current = new IntHolder(0);
76       ((Map JavaDoc) instance.get()).put("current", current);
77     }
78     return current;
79   }
80
81   private static long charErrCount = 0;
82
83   /**
84    * Load snips and users into the SnipSpace from an xml document out of a stream.
85    *
86    * @param in the input stream to load from
87    * @param flags whether or not to overwrite existing content
88    */

89   public static void load(InputStream JavaDoc in, final int flags) throws IOException JavaDoc {
90     SAXReader saxReader = new SAXReader();
91     try {
92       saxReader.addHandler("/snipspace/user", new ElementHandler() {
93         public void onStart(ElementPath elementPath) {
94           // nothing to do here ...
95
}
96
97         public void onEnd(ElementPath elementPath) {
98           Element userElement = elementPath.getCurrent();
99           if ((flags & IMPORT_USERS) != 0) {
100             try {
101               XMLSnipImport.loadUser(elementPath.getCurrent(), flags);
102             } catch (Exception JavaDoc e) {
103               Logger.fatal("XMLSnipImport: error importing user: " + userElement.elementText("name"));
104             }
105             getStatus().inc();
106           }
107           // prune the element to save memory
108
userElement.detach();
109         }
110       });
111
112       saxReader.addHandler("/snipspace/snip", new ElementHandler() {
113         public void onStart(ElementPath elementPath) {
114           // nothing to do here ...
115
}
116
117         public void onEnd(ElementPath elementPath) {
118           Element snipElement = elementPath.getCurrent();
119           if ((flags & IMPORT_SNIPS) != 0) {
120             try {
121               XMLSnipImport.loadSnip(snipElement, flags);
122             } catch (Exception JavaDoc e) {
123               Logger.fatal("XMLSnipImport: error importing snip: " + snipElement.elementText("name"));
124             }
125             getStatus().inc();
126           }
127           // prune the element to save memory
128
snipElement.detach();
129         }
130       });
131
132
133       // add a reader wrapper to remove illegal characters from input stream
134
// it looks like the database export (XMLWriter) allows these to get through
135
InputStreamReader JavaDoc reader = new InputStreamReader JavaDoc(in, "UTF-8") {
136         public int read(char[] chars) throws IOException JavaDoc {
137           int n = super.read(chars);
138           for (int i = 0; i < n; i++) {
139             chars[i] = replaceIfIllegal(chars[i]);
140           }
141           return n;
142         }
143
144         public int read(char[] chars, int start, int length) throws IOException JavaDoc {
145           int n = super.read(chars, start, length);
146           for (int i = 0; i < n; i++) {
147             chars[i] = replaceIfIllegal(chars[i]);
148           }
149           return n;
150         }
151
152         private char replaceIfIllegal(char c) {
153           if (c < 0x20 && !(c == 0x09 || c == 0x0a || c == 0x0d)) {
154             charErrCount++;
155             return (char) 0x20;
156           }
157           return c;
158         }
159       };
160
161       saxReader.read(reader);
162       Logger.warn("XMLSnipImport: corrected " + charErrCount + " characters in input");
163       Logger.log("XMLSnipImport: imported " + getStatus().getValue() + " data records");
164     } catch (DocumentException e) {
165       Logger.warn("XMLSnipImport: unable to parse document", e);
166       throw new IOException JavaDoc("Error parsing document: " + e);
167     }
168   }
169
170   /**
171    * Load a user object from a serialized xml element
172    *
173    * @param userElement the xml user element
174    * @param flags flags indicating overwriting any existing users or not
175    */

176   public static void loadUser(Element userElement, int flags) {
177     Map JavaDoc userMap = UserSerializer.getInstance().getElementMap(userElement);
178     userMap.remove(UserSerializer.USER_APPLICATION);
179
180     String JavaDoc login = (String JavaDoc) userMap.get(UserSerializer.USER_NAME);
181     String JavaDoc passwd = (String JavaDoc) userMap.get(UserSerializer.USER_PASSWORD);
182     String JavaDoc email = (String JavaDoc) userMap.get(UserSerializer.USER_EMAIL);
183
184     UserManager userManager = (UserManager) Components.getComponent(UserManager.class);
185     User user = null;
186     if (userManager.exists(login)) {
187       if ((flags & OVERWRITE) == 0) {
188         Logger.log("ignoring to import user '" + login + "'");
189         return;
190       }
191       Logger.log("loading existing user '" + login + "'");
192       user = userManager.load(login);
193     } else {
194       Logger.log("creating user '" + login + "'");
195       user = userManager.create(login, passwd, email);
196     }
197
198     user = UserSerializer.getInstance().deserialize(userMap, user);
199     userManager.systemStore(user);
200   }
201
202   public static void loadSnip(Element snipElement, int flags) {
203     Map JavaDoc snipMap = SnipSerializer.getInstance().getElementMap(snipElement);
204     snipMap.remove(SnipSerializer.SNIP_APPLICATION);
205
206     String JavaDoc name = (String JavaDoc) snipMap.get(SnipSerializer.SNIP_NAME);
207     String JavaDoc content = (String JavaDoc) snipMap.get(SnipSerializer.SNIP_CONTENT);
208
209     SnipSpace space = (SnipSpace) Components.getComponent(SnipSpace.class);
210     Snip snip = null;
211     if (space.exists(name)) {
212       Logger.log("loading existing snip '" + name + "'");
213       snip = space.load(name);
214       if ((flags & OVERWRITE) == 0) {
215         snip.setContent(snip.getContent() + content);
216         snipMap.remove(SnipSerializer.SNIP_CONTENT);
217       }
218     } else {
219       Logger.log("creating snip '" + name + "'");
220       snip = space.create(name, content);
221     }
222
223     UserManager um = (UserManager) Components.getComponent(UserManager.class);
224     User importUser = Application.get().getUser();
225
226     // check existing users
227
if (!um.exists((String JavaDoc) snipMap.get(SnipSerializer.SNIP_CUSER))) {
228       snipMap.put(SnipSerializer.SNIP_CUSER, importUser.getLogin());
229     }
230     if (!um.exists((String JavaDoc) snipMap.get(SnipSerializer.SNIP_MUSER))) {
231       snipMap.put(SnipSerializer.SNIP_MUSER, importUser.getLogin());
232     }
233     if (!um.exists((String JavaDoc) snipMap.get(SnipSerializer.SNIP_OUSER))) {
234       snipMap.put(SnipSerializer.SNIP_OUSER, importUser.getLogin());
235     }
236
237     // first restore attached files, then remove the data element
238
restoreAttachments(snipElement);
239     snip = SnipSerializer.getInstance().deserialize(snipMap, snip);
240     restoreVersions(snipElement, snip, (flags & OVERWRITE) != 0);
241     snip.getBackLinks().getSize();
242     // ensure that the configuration snip is stored normally
243
// so the configuration is updated
244
if (Configuration.SNIPSNAP_CONFIG.equals(snip.getName())) {
245       space.store(snip);
246     } else {
247       space.systemStore(snip);
248     }
249   }
250
251   private static void restoreAttachments(Element snipEl) {
252     Configuration config = Application.get().getConfiguration();
253     File JavaDoc attRoot = config.getFilePath();
254     Element attachmentsEl = snipEl.element("attachments");
255     if (null != attachmentsEl) {
256       Iterator JavaDoc attIt = attachmentsEl.elements("attachment").iterator();
257       while (attIt.hasNext()) {
258         Element att = (Element) attIt.next();
259         if (att.element("data") != null) {
260           File JavaDoc attFile = new File JavaDoc(attRoot, att.elementText("location"));
261           try {
262             // make sure the directory hierarchy exists
263
attFile.getParentFile().mkdirs();
264             byte buffer[] = Base64.decodeBase64(att.elementText("data").getBytes("UTF-8"));
265             BufferedOutputStream JavaDoc os = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(attFile));
266             os.write(buffer);
267             os.flush();
268             os.close();
269           } catch (Exception JavaDoc e) {
270             Logger.fatal("unable to store attachment: " + e);
271             e.printStackTrace();
272           }
273           att.element("data").detach();
274         }
275       }
276     }
277   }
278
279   private static void restoreVersions(Element snipEl, Snip snip, boolean overwrite) {
280     VersionManager versionManager = (VersionManager) Components.getComponent(VersionManager.class);
281     List JavaDoc currentVersions = versionManager.getHistory(snip);
282     if (currentVersions.size() > 0 && overwrite) {
283       // TODO missing in version manager
284
// versionManager.removeHistory();
285
}
286
287     currentVersions = versionManager.getHistory(snip);
288     int versionNo = currentVersions.size();
289
290     SnipSerializer serializer = SnipSerializer.getInstance();
291     Element versionsEl = snipEl.element("versions");
292     if (versionsEl != null) {
293       Iterator JavaDoc versionsElIt = versionsEl.elementIterator("snip");
294       while (versionsElIt.hasNext()) {
295         Element versionSnipEl = (Element) versionsElIt.next();
296         Snip versionSnip = serializer.deserialize(versionSnipEl, SnipFactory.createSnip("", ""));
297         if (versionNo > 0) {
298           versionSnip.setVersion(versionNo++);
299         }
300         versionManager.storeVersion(versionSnip);
301       }
302     }
303   }
304 }
305
Popular Tags