001: package org.openedit.logger;
002:
003: import java.io.File;
004: import java.io.FileInputStream;
005: import java.io.FileNotFoundException;
006: import java.io.FileWriter;
007: import java.io.IOException;
008: import java.io.RandomAccessFile;
009: import java.io.Reader;
010: import java.io.StringReader;
011: import java.io.StringWriter;
012: import java.text.DateFormat;
013: import java.text.ParseException;
014: import java.text.SimpleDateFormat;
015: import java.util.ArrayList;
016: import java.util.Collections;
017: import java.util.Date;
018: import java.util.Iterator;
019: import java.util.List;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.dom4j.Attribute;
024: import org.dom4j.Document;
025: import org.dom4j.DocumentHelper;
026: import org.dom4j.Element;
027: import org.openedit.xml.XmlArchive;
028:
029: import com.openedit.OpenEditException;
030: import com.openedit.page.Page;
031: import com.openedit.page.PageProperty;
032: import com.openedit.page.manage.PageManager;
033: import com.openedit.util.FileUtils;
034: import com.openedit.util.OutputFiller;
035: import com.openedit.util.PathUtilities;
036: import com.openedit.util.XmlUtil;
037:
038: public class LogDirectory {
039: private static final Log log = LogFactory
040: .getLog(LogDirectory.class);
041: protected XmlArchive fieldLogFiles;
042: protected int fieldMaxLength = 50;
043: protected int fieldChangeCount = 0;
044: protected PageManager fieldPageManager;
045: protected String fieldType;
046: protected XmlUtil fieldXmlUtil;
047: protected DateFormat fieldLogDateFormat;
048: protected File fieldRootLogsDirectory;
049: protected DateFormat fieldFileDateFormat;
050:
051: public LogDirectory() {
052: }
053:
054: public String getType() {
055: return fieldType;
056: }
057:
058: public void setType(String inType) {
059: fieldType = inType;
060: }
061:
062: public void setMaxLength(int i) {
063: fieldMaxLength = i;
064: }
065:
066: public int getMaxLength() {
067: return fieldMaxLength;
068: }
069:
070: public void init() throws Exception {
071: try {
072: //load log file
073:
074: Page logdir = getPageManager().getPage(
075: "/WEB-INF/logs/" + getType() + "/_site.xconf");
076: if (!logdir.exists()) {
077: PageProperty prop = new PageProperty("logchanges");
078: prop.setValue("false");
079: logdir.getPageSettings().putProperty(prop);
080: getPageManager().getPageSettingsManager().saveSetting(
081: logdir.getPageSettings());
082: }
083: // List changes = new ArrayList();
084: //
085: // Page recent = getPageManager().getPage(getLogFilePath());
086: // if( recent.exists())
087: // {
088: // StringWriter stringw = new StringWriter();
089: // stringw.append("<log>");
090: // new OutputFiller().fill(recent.getReader(), stringw);
091: // stringw.append("</log>");
092: // Element root = getXmlUtil().getXml(new StringReader(stringw.toString()),recent.getCharacterEncoding());
093: // for (Iterator iter = root.elementIterator("log"); iter.hasNext();)
094: // {
095: // Element element = (Element) iter.next();
096: // changes.add(change);
097: // }
098: // }
099: // setChangeStack(changes);
100: } catch (Exception e) {
101: throw new RuntimeException("Could not load log " + e);
102: } finally {
103: }
104: }
105:
106: //XML only
107: protected List loadChangeLog(String inFileName) throws Exception {
108: Page page = getPageManager().getPage(inFileName);
109: Reader reader = null;
110: if (page.exists()) {
111: reader = page.getReader();
112: Element doc = getXmlUtil().getXml(reader,
113: page.getCharacterEncoding());
114:
115: return loadChangeFromElement(doc);
116: }
117: return Collections.EMPTY_LIST;
118: }
119:
120: private List loadChangeFromElement(Element doc)
121: throws ParseException {
122: //newest ones come first
123: List changes = doc.elements("event");
124: List done = new ArrayList(changes.size());
125: for (int i = 0; (i < getMaxLength()) && (i < changes.size()); i++) {
126: Element change = (Element) changes.get(i);
127: done.add(createChange(change));
128: }
129: //Put the first elements back in the top of the list
130: Collections.reverse(done);
131: return done;
132: }
133:
134: protected List loadRecentEvents(Date inCutOffDate) throws Exception {
135: Page page = getPageManager().getPage(getLogFilePath());
136: if (!page.exists()
137: || page.getLastModified().before(inCutOffDate)) {
138: return null;
139: }
140: StringWriter text = new StringWriter();
141: text.write("<log>");
142: new OutputFiller().fill(page.getReader(), text);
143: text.write("</log>");
144:
145: Element root = getXmlUtil().getXml(
146: new StringReader(text.toString()),
147: page.getCharacterEncoding());
148: return loadChangeFromElement(root);
149: }
150:
151: protected List loadAllRecentEvents() throws Exception {
152: Page page = getPageManager().getPage(getLogFilePath());
153: if (!page.exists()) {
154: return null;
155: }
156: StringWriter text = new StringWriter();
157: text.write("<log>");
158: new OutputFiller().fill(page.getReader(), text);
159: text.write("</log>");
160:
161: Element root = getXmlUtil().getXml(
162: new StringReader(text.toString()),
163: page.getCharacterEncoding());
164: return loadChangeFromElement(root);
165: }
166:
167: /**
168: * Save the list of changes to the days change log file
169: *
170: */
171: public synchronized void save(Change inChange) {
172: try {
173: File recent = new File(getRootLogsDirectory(), getType()
174: + "/recent.log");
175: FileWriter out = null;
176: if (!recent.exists() || recent.length() == 0) {
177: recent.getParentFile().mkdirs();
178: out = new FileWriter(recent);
179: } else {
180: out = new FileWriter(recent, true);
181: }
182: try {
183: Element element = DocumentHelper.createElement("event");
184: populateElement(inChange, element);
185: out.write(element.asXML());
186: out.write("\n");
187: } finally {
188: FileUtils.safeClose(out);
189: }
190: fieldChangeCount++;
191:
192: if (getChangeCount() >= getMaxLength()) {
193: moveRecent(recent);
194: fieldChangeCount = 0;
195: }
196: } catch (Exception ex) {
197: log.error(ex);
198: ex.printStackTrace();
199: return;
200: }
201: }
202:
203: private void moveRecent(File recent) throws FileNotFoundException,
204: IOException {
205: //setTimeStampCounter(0);
206: String stampedFileName = getType() + "/" + getType() + "-"
207: + getFileDateFormat().format(new Date()) + ".xml";
208: File archive = new File(getRootLogsDirectory(), stampedFileName);
209: RandomAccessFile archiveout = null;
210: FileInputStream finalreader = null;
211: try {
212: if (!archive.exists() || archive.length() == 0) {
213: //create file and headers
214: archiveout = new RandomAccessFile(archive, "rw");
215: archiveout.write("<log>\n".getBytes());
216: } else {
217: archiveout = new RandomAccessFile(archive, "rws");
218: archiveout.seek(archive.length() - "</log>".length()); //Back up the /log
219: }
220: finalreader = new FileInputStream(recent);
221: byte[] bytes = new byte[1024];
222: int iRead = -1;
223: while (true) {
224: iRead = finalreader.read(bytes);
225: if (iRead != -1) {
226: archiveout.write(bytes, 0, iRead);
227: } else {
228: break;
229: }
230: }
231: archiveout.write("</log>".getBytes());
232: } finally {
233: FileUtils.safeClose(finalreader);
234: archiveout.close();
235: }
236: recent.delete();
237: }
238:
239: protected String getLogFilePath() {
240: return "/WEB-INF/logs/" + getType() + "/recent.log";
241: }
242:
243: protected Change createChange(Element inElement)
244: throws ParseException {
245: Change change = new Change();
246: for (Iterator iter = inElement.attributeIterator(); iter
247: .hasNext();) {
248: Attribute attrib = (Attribute) iter.next();
249: if (!attrib.getName().equals("date")) {
250: change.put(attrib.getName(), attrib.getValue());
251: }
252: }
253: String date = inElement.attributeValue("date");
254: if (date != null) {
255: change.setDate(getDateFormat().parse(date));
256: }
257: return change;
258: }
259:
260: protected Document buildDocument(List inStack) {
261: Element root = DocumentHelper.createElement("log");
262: //root.addAttribute("timeStampCounter", String.valueOf(getTimeStampCounter()));
263:
264: for (Iterator iter = inStack.iterator(); iter.hasNext();) {
265: Change change = (Change) iter.next();
266: Element changeElem = root.addElement("event");
267:
268: populateElement(change, changeElem);
269: }
270:
271: return DocumentHelper.createDocument(root);
272: }
273:
274: private void populateElement(Change change, Element changeElem) {
275: for (Iterator iterator = change.keys().iterator(); iterator
276: .hasNext();) {
277: String key = (String) iterator.next();
278: changeElem.addAttribute(key, change.get(key));
279: }
280: changeElem.addAttribute("date", getDateFormat().format(
281: change.getDate()));
282: }
283:
284: public PageManager getPageManager() {
285: return fieldPageManager;
286: }
287:
288: public void setPageManager(PageManager inPageManager) {
289: fieldPageManager = inPageManager;
290: }
291:
292: public void addChange(Change inChange) {
293: if (inChange.getDate() == null) {
294: inChange.setDate(new Date());
295: }
296: save(inChange);
297:
298: }
299:
300: public XmlUtil getXmlUtil() {
301: if (fieldXmlUtil == null) {
302: fieldXmlUtil = new XmlUtil();
303: }
304: return fieldXmlUtil;
305: }
306:
307: public void setXmlUtil(XmlUtil inXmlUtil) {
308: fieldXmlUtil = inXmlUtil;
309: }
310:
311: public DateFormat getDateFormat() {
312: if (fieldLogDateFormat == null) {
313: fieldLogDateFormat = new SimpleDateFormat(
314: "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
315: }
316: return fieldLogDateFormat;
317: }
318:
319: public void setDateFormat(DateFormat inDateFormat) {
320: fieldLogDateFormat = inDateFormat;
321: }
322:
323: public List getAllEntriesFrom(Date inStart, Date inEnd)
324: throws Exception {
325: List allchanges = new ArrayList();
326: String stampedPath = PathUtilities
327: .extractDirectoryPath(getLogFilePath());
328: List l = getPageManager().getChildrenPaths(stampedPath);
329: Collections.sort(l);
330:
331: List recent = loadRecentEvents(inStart);
332: if (recent != null) {
333: allchanges.addAll(recent);
334: }
335:
336: for (Iterator iter = l.iterator(); iter.hasNext();) {
337: String path = (String) iter.next();
338: if (path.endsWith(".xml")) {
339: String find = getType() + "-";
340: String datestring = path.substring(path.indexOf(find)
341: + find.length());
342: Date dated = getFileDateFormat().parse(datestring);
343:
344: if (dated.before(inStart)) {
345:
346: continue;
347: }
348: if (dated.after(inStart) && dated.before(inEnd)) {
349: List changeList = loadChangeLog(path);
350: allchanges.addAll(changeList);
351: } else if (dated.after(inEnd)) {
352: //add this one extra in case of some older logs
353: List changeList = loadChangeLog(path);
354: allchanges.addAll(changeList);
355: break;
356: }
357: }
358: }
359: List done = new ArrayList(allchanges.size());
360: for (Iterator iter = allchanges.iterator(); iter.hasNext();) {
361: Change change = (Change) iter.next();
362: if (change.getDate().after(inStart)
363: && change.getDate().before(inEnd)) {
364: done.add(change);
365: }
366: }
367:
368: return done;
369: }
370:
371: public File getRootLogsDirectory() {
372: return fieldRootLogsDirectory;
373: }
374:
375: public void setRootLogsDirectory(File inRootLogsDirectory) {
376: fieldRootLogsDirectory = inRootLogsDirectory;
377: }
378:
379: public int getChangeCount() {
380: return fieldChangeCount;
381: }
382:
383: public void setChangeCount(int inChangeCount) {
384: fieldChangeCount = inChangeCount;
385: }
386:
387: public DateFormat getFileDateFormat() {
388: if (fieldFileDateFormat == null) {
389: fieldFileDateFormat = new SimpleDateFormat("yyyy-MM-dd");
390: }
391: return fieldFileDateFormat;
392: }
393:
394: public void setFileDateFormat(DateFormat inFileDateFormat) {
395: fieldFileDateFormat = inFileDateFormat;
396: }
397:
398: public List getAllEntries() throws Exception {
399: List allchanges = new ArrayList();
400: String stampedPath = PathUtilities
401: .extractDirectoryPath(getLogFilePath());
402: List l = getPageManager().getChildrenPaths(stampedPath);
403: Collections.sort(l);
404:
405: List recent = loadAllRecentEvents();
406: if (recent != null) {
407: allchanges.addAll(recent);
408: }
409:
410: for (Iterator iter = l.iterator(); iter.hasNext();) {
411: String path = (String) iter.next();
412: if (path.endsWith(".xml")) {
413: String find = getType() + "-";
414: String datestring = path.substring(path.indexOf(find)
415: + find.length());
416: Date dated = getFileDateFormat().parse(datestring);
417:
418: List changeList = loadChangeLog(path);
419: allchanges.addAll(changeList);
420:
421: }
422: }
423: return allchanges;
424: }
425:
426: }
|