001: // wikiBoard.java
002: // -------------------------------------
003: // (C) by Michael Peter Christen; mc@anomic.de
004: // first published on http://www.anomic.de
005: // Frankfurt, Germany, 2004
006: // last major change: 20.07.2004
007: //
008: // This program is free software; you can redistribute it and/or modify
009: // it under the terms of the GNU General Public License as published by
010: // the Free Software Foundation; either version 2 of the License, or
011: // (at your option) any later version.
012: //
013: // This program is distributed in the hope that it will be useful,
014: // but WITHOUT ANY WARRANTY; without even the implied warranty of
015: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: // GNU General Public License for more details.
017: //
018: // You should have received a copy of the GNU General Public License
019: // along with this program; if not, write to the Free Software
020: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: //
022: // Using this software in any meaning (reading, learning, copying, compiling,
023: // running) means that you agree that the Author(s) is (are) not responsible
024: // for cost, loss of data or any harm that may be caused directly or indirectly
025: // by usage of this softare or this documentation. The usage of this software
026: // is on your own risk. The installation and usage (starting/running) of this
027: // software may allow other people or application to access your computer and
028: // any attached devices and is highly dependent on the configuration of the
029: // software which must be done by the user of the software; the author(s) is
030: // (are) also not responsible for proper configuration and usage of the
031: // software, even if provoked by documentation provided together with
032: // the software.
033: //
034: // Any changes to this file according to the GPL as documented in the file
035: // gpl.txt aside this file in the shipment you received can be done to the
036: // lines that follows this copyright notice here, but changes must not be
037: // done inside the copyright notive above. A re-distribution must contain
038: // the intact and unchanged copyright notice.
039: // Contributions and changes to the program code must be marked as such.
040:
041: // This file is contributed by Jan Sandbrink
042: // based on the Code of wikiBoard.java
043:
044: package de.anomic.data;
045:
046: import java.io.ByteArrayInputStream;
047: import java.io.File;
048: import java.io.IOException;
049: import java.io.UnsupportedEncodingException;
050: import java.text.ParseException;
051: import java.text.SimpleDateFormat;
052: import java.util.ArrayList;
053: import java.util.Date;
054: import java.util.HashMap;
055: import java.util.Iterator;
056: import java.util.TimeZone;
057:
058: import javax.xml.parsers.DocumentBuilder;
059: import javax.xml.parsers.DocumentBuilderFactory;
060: import javax.xml.parsers.ParserConfigurationException;
061:
062: import org.w3c.dom.Document;
063: import org.w3c.dom.Node;
064: import org.w3c.dom.NodeList;
065: import org.xml.sax.SAXException;
066:
067: import de.anomic.kelondro.kelondroBase64Order;
068: import de.anomic.kelondro.kelondroDyn;
069: import de.anomic.kelondro.kelondroMapObjects;
070: import de.anomic.kelondro.kelondroNaturalOrder;
071:
072: public class blogBoardComments {
073:
074: public static final int keyLength = 64;
075: private static final String dateFormat = "yyyyMMddHHmmss";
076: private static final int recordSize = 512;
077:
078: private static SimpleDateFormat SimpleFormatter = new SimpleDateFormat(
079: dateFormat);
080:
081: static {
082: SimpleFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
083: }
084:
085: private kelondroMapObjects datbase = null;
086:
087: public blogBoardComments(File actpath, long preloadTime) {
088: new File(actpath.getParent()).mkdir();
089: if (datbase == null) {
090: datbase = new kelondroMapObjects(new kelondroDyn(actpath,
091: true, true, preloadTime, keyLength, recordSize,
092: '_', kelondroNaturalOrder.naturalOrder, false,
093: false, false), 500);
094: }
095: }
096:
097: public int size() {
098: return datbase.size();
099: }
100:
101: public void close() {
102: datbase.close();
103: }
104:
105: private static String dateString(Date date) {
106: synchronized (SimpleFormatter) {
107: return SimpleFormatter.format(date);
108: }
109: }
110:
111: private static String normalize(String key) {
112: if (key == null)
113: return "null";
114: return key.trim().toLowerCase();
115: }
116:
117: public static String webalize(String key) {
118: if (key == null)
119: return "null";
120: key = key.trim().toLowerCase();
121: int p;
122: while ((p = key.indexOf(" ")) >= 0)
123: key = key.substring(0, p) + "%20" + key.substring(p + 1);
124: return key;
125: }
126:
127: public String guessAuthor(String ip) {
128: return wikiBoard.guessAuthor(ip);
129: }
130:
131: public CommentEntry newEntry(String key, byte[] subject,
132: byte[] author, String ip, Date date, byte[] page) {
133: return new CommentEntry(normalize(key), subject, author, ip,
134: date, page);
135: }
136:
137: public class CommentEntry {
138:
139: String key;
140: HashMap<String, String> record;
141:
142: public CommentEntry(String nkey, byte[] subject, byte[] author,
143: String ip, Date date, byte[] page) {
144: record = new HashMap<String, String>();
145: key = nkey;
146: if (key.length() > keyLength)
147: key = key.substring(0, keyLength);
148: if (date == null)
149: date = new Date();
150: record.put("date", dateString(date));
151: if (subject == null)
152: record.put("subject", "");
153: else
154: record.put("subject", kelondroBase64Order.enhancedCoder
155: .encode(subject));
156: if (author == null)
157: record.put("author", "");
158: else
159: record.put("author", kelondroBase64Order.enhancedCoder
160: .encode(author));
161: if ((ip == null) || (ip.length() == 0))
162: ip = "";
163: record.put("ip", ip);
164: if (page == null)
165: record.put("page", "");
166: else
167: record.put("page", kelondroBase64Order.enhancedCoder
168: .encode(page));
169:
170: wikiBoard.setAuthor(ip, new String(author));
171: //System.out.println("DEBUG: setting author " + author + " for ip = " + ip + ", authors = " + authors.toString());
172: }
173:
174: private CommentEntry(String key, HashMap<String, String> record) {
175: this .key = key;
176: this .record = record;
177: if (this .record.get("comments") == null)
178: this .record.put("comments", listManager
179: .collection2string(new ArrayList<String>()));
180: }
181:
182: public String key() {
183: return key;
184: }
185:
186: public byte[] subject() {
187: String m = (String) record.get("subject");
188: if (m == null)
189: return new byte[0];
190: byte[] b = kelondroBase64Order.enhancedCoder.decode(m,
191: "de.anomic.data.blogBoardComments.subject()");
192: if (b == null)
193: return "".getBytes();
194: return b;
195: }
196:
197: public Date date() {
198: try {
199: String c = (String) record.get("date");
200: if (c == null) {
201: System.out
202: .println("DEBUG - ERROR: date field missing in blogBoard");
203: return new Date();
204: }
205: synchronized (SimpleFormatter) {
206: return SimpleFormatter.parse(c);
207: }
208: } catch (ParseException e) {
209: return new Date();
210: }
211: }
212:
213: public String timestamp() {
214: String c = (String) record.get("date");
215: if (c == null) {
216: System.out
217: .println("DEBUG - ERROR: date field missing in blogBoard");
218: return dateString(new Date());
219: }
220: return c;
221: }
222:
223: public byte[] author() {
224: String m = (String) record.get("author");
225: if (m == null)
226: return new byte[0];
227: byte[] b = kelondroBase64Order.enhancedCoder.decode(m,
228: "de.anomic.data.blogBoardComments.author()");
229: if (b == null)
230: return "".getBytes();
231: return b;
232: }
233:
234: public String ip() {
235: String a = (String) record.get("ip");
236: if (a == null)
237: return "127.0.0.1";
238: return a;
239: }
240:
241: public byte[] page() {
242: String m = (String) record.get("page");
243: if (m == null)
244: return new byte[0];
245: byte[] b = kelondroBase64Order.enhancedCoder.decode(m,
246: "de.anomic.data.blogBoardComments.page()");
247: if (b == null)
248: return "".getBytes();
249: return b;
250: }
251:
252: public boolean isAllowed() {
253: return (record.get("moderated") != null)
254: && record.get("moderated").equals("true");
255: }
256:
257: public void allow() {
258: record.put("moderated", "true");
259: }
260:
261: }
262:
263: public String write(CommentEntry page) {
264: // writes a new page and returns key
265: try {
266: datbase.set(page.key, page.record);
267: return page.key;
268: } catch (IOException e) {
269: return null;
270: }
271: }
272:
273: public CommentEntry read(String key) {
274: //System.out.println("DEBUG: read from blogBoardComments");
275: return read(key, datbase);
276: }
277:
278: private CommentEntry read(String key, kelondroMapObjects base) {
279: key = normalize(key);
280: if (key.length() > keyLength)
281: key = key.substring(0, keyLength);
282: HashMap<String, String> record = base.getMap(key);
283: if (record == null)
284: return newEntry(key, "".getBytes(), "anonymous".getBytes(),
285: "127.0.0.1", new Date(), "".getBytes());
286: return new CommentEntry(key, record);
287: }
288:
289: /* private CommentEntry read(String key, kelondroMapObjects base) {
290: key = normalize(key);
291: if (key.length() > keyLength) key = key.substring(0, keyLength);
292: CommentEntry record = null;
293: try {
294: record = (CommentEntry) base.get(key);
295: } catch (IOException e) {
296: e.printStackTrace();
297: }
298: if (record == null) return newEntry(key, "".getBytes(), "anonymous".getBytes(), "127.0.0.1", new Date(), "".getBytes());
299: return new CommentEntry(key, record.record);
300: }*/
301:
302: public boolean importXML(String input) {
303: DocumentBuilderFactory factory = DocumentBuilderFactory
304: .newInstance();
305: try {
306: DocumentBuilder builder = factory.newDocumentBuilder();
307: Document doc = builder.parse(new ByteArrayInputStream(input
308: .getBytes()));
309: return parseXMLimport(doc);
310: } catch (ParserConfigurationException e) {
311: } catch (SAXException e) {
312: } catch (IOException e) {
313: }
314:
315: return false;
316: }
317:
318: private boolean parseXMLimport(Document doc) {
319: if (!doc.getDocumentElement().getTagName().equals("blog"))
320: return false;
321:
322: NodeList items = doc.getDocumentElement().getElementsByTagName(
323: "item");
324: if (items.getLength() == 0)
325: return false;
326:
327: for (int i = 0; i < items.getLength(); ++i) {
328: String key = null, ip = null, StrSubject = null, StrAuthor = null, StrPage = null, StrDate = null;
329: Date date = null;
330:
331: if (!items.item(i).getNodeName().equals("item"))
332: continue;
333:
334: NodeList currentNodeChildren = items.item(i)
335: .getChildNodes();
336:
337: for (int j = 0; j < currentNodeChildren.getLength(); ++j) {
338: Node currentNode = currentNodeChildren.item(j);
339: if (currentNode.getNodeName().equals("id"))
340: key = currentNode.getFirstChild().getNodeValue();
341: else if (currentNode.getNodeName().equals("ip"))
342: ip = currentNode.getFirstChild().getNodeValue();
343: else if (currentNode.getNodeName().equals("timestamp"))
344: StrDate = currentNode.getFirstChild()
345: .getNodeValue();
346: else if (currentNode.getNodeName().equals("subject"))
347: StrSubject = currentNode.getFirstChild()
348: .getNodeValue();
349: else if (currentNode.getNodeName().equals("author"))
350: StrAuthor = currentNode.getFirstChild()
351: .getNodeValue();
352: else if (currentNode.getNodeName().equals("content"))
353: StrPage = currentNode.getFirstChild()
354: .getNodeValue();
355: }
356:
357: try {
358: date = SimpleFormatter.parse(StrDate);
359: } catch (ParseException e1) {
360: date = new Date();
361: }
362:
363: if (key == null || ip == null || StrSubject == null
364: || StrAuthor == null || StrPage == null
365: || date == null)
366: return false;
367:
368: byte[] subject, author, page;
369: try {
370: subject = StrSubject.getBytes("UTF-8");
371: } catch (UnsupportedEncodingException e1) {
372: subject = StrSubject.getBytes();
373: }
374: try {
375: author = StrAuthor.getBytes("UTF-8");
376: } catch (UnsupportedEncodingException e1) {
377: author = StrAuthor.getBytes();
378: }
379: try {
380: page = StrPage.getBytes("UTF-8");
381: } catch (UnsupportedEncodingException e1) {
382: page = StrPage.getBytes();
383: }
384:
385: write(newEntry(key, subject, author, ip, date, page));
386: }
387: return true;
388: }
389:
390: public void delete(String key) {
391: key = normalize(key);
392: try {
393: datbase.remove(key);
394: } catch (IOException e) {
395: }
396: }
397:
398: public Iterator<String> keys(boolean up) throws IOException {
399: return datbase.keys(up, false);
400: }
401:
402: }
|