1 12 13 16 package com.openedit.modules.changelog; 17 18 import java.io.Reader ; 19 import java.io.StringWriter ; 20 import java.text.SimpleDateFormat ; 21 import java.util.ArrayList ; 22 import java.util.Collections ; 23 import java.util.Date ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 import org.dom4j.Attribute; 30 import org.dom4j.Document; 31 import org.dom4j.DocumentHelper; 32 import org.dom4j.Element; 33 import org.dom4j.io.OutputFormat; 34 import org.dom4j.io.SAXReader; 35 import org.dom4j.io.XMLWriter; 36 import org.openedit.repository.ContentItem; 37 import org.openedit.repository.filesystem.StringItem; 38 39 import com.openedit.OpenEditException; 40 import com.openedit.PageAccessListener; 41 import com.openedit.page.Page; 42 import com.openedit.page.manage.PageManager; 43 import com.openedit.util.PathUtilities; 44 import com.openedit.util.XmlUtil; 45 46 47 54 public class ChangeLog implements PageAccessListener 55 { 56 protected Log log = LogFactory.getLog(ChangeLog.class); 57 protected SimpleDateFormat fieldFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 58 protected SimpleDateFormat fieldRSSFormat = new SimpleDateFormat ("EEE, d MMM yyyy HH:mm:ss Z"); 59 protected List fieldChangeStack; 60 protected List fieldNewChanges; 61 protected String fieldChangeFilePath = "/openedit/stats/changelog.xml"; 62 protected int fieldMaxLength = 50; 63 protected PageManager fieldPageManager; 64 protected int fieldTimeStampCounter; 65 66 71 public void setChangeFilePath(String string) 72 { 73 fieldChangeFilePath = string; 74 } 75 76 81 public String getChangeFilePath() 82 { 83 return fieldChangeFilePath; 84 } 85 86 91 public void setMaxLength(int i) 92 { 93 fieldMaxLength = i; 94 } 95 96 101 public int getMaxLength() 102 { 103 return fieldMaxLength; 104 } 105 106 111 public void setNewChanges(List inStack) 112 { 113 fieldNewChanges = inStack; 114 } 115 116 121 public List getNewChanges() 122 { 123 if (fieldNewChanges == null) 124 { 125 fieldNewChanges = new ArrayList (); 126 } 127 128 return fieldNewChanges; 129 } 130 131 136 public int changeCount() 137 { 138 return getChangeStack().size(); 139 } 140 141 146 public int changeNotificationCount() 147 { 148 return getNewChanges().size(); 149 } 150 151 154 public void clearNotifications() 155 { 156 getNewChanges().clear(); 157 } 158 159 165 public void init() throws Exception 166 { 167 setChangeStack(new ArrayList ()); 168 169 Reader reader = null; 170 try 171 { 172 Page page = getPageManager().getPage( getChangeFilePath()); 173 174 if (page.exists()) 175 { 176 reader = page.getReader(); 177 Document doc = new SAXReader(false).read(reader ); 178 179 List changes = doc.getRootElement().elements("Change"); 181 182 for (int i = 0; (i < getMaxLength()) && (i < changes.size()); i++) 183 { 184 Element change = (Element) changes.get(i); 185 addChange(change); 186 } 187 Collections.reverse( getChangeStack() ); 189 190 Attribute counterAttribute = doc.getRootElement().attribute("timeStampCounter"); 192 if (counterAttribute != null) 193 { 194 String counter = counterAttribute.getValue(); 195 if (counter != null && counter.length() > 0) 196 { 197 setTimeStampCounter(Integer.parseInt(counter)); 198 } 199 } 200 else 201 { 202 setTimeStampCounter(0); 203 } 204 205 } 206 } 207 catch (Exception e) 208 { 209 throw new RuntimeException ("Could not load changelog " + e); 210 } 211 finally 212 { 213 if ( reader != null) 214 { 215 reader.close(); 216 } 217 } 218 219 221 230 231 clearNotifications(); 232 233 getPageManager().addPageAccessListener(this); 234 } 235 236 237 245 public void pageAdded(Page inPage) 246 { 247 ContentItem item = inPage.getContentItem(); 248 if ( shouldMakeVersion(inPage) ) 249 { 250 logCopy(item); 251 save(); 252 } 253 254 } 255 256 public boolean shouldMakeVersion(Page inPage) 257 { 258 String path = inPage.getPath(); 259 return (!path.startsWith("/openedit/stats/")); 260 } 261 262 270 public void pageModified(Page inPage) 271 { 272 ContentItem item = inPage.getContentItem(); 274 if ( shouldMakeVersion(inPage) ) 275 { 276 logCopy(item); 277 save(); 278 } 279 } 280 281 289 public void pageRemoved(Page inPage) 290 { 291 ContentItem item = inPage.getContentItem(); 292 if ( shouldMakeVersion(inPage) ) 293 { 294 RevisionItem revision = new RevisionItem(); 295 296 revision.setType(item.getType()); 297 298 revision.setDate(new Date () ); 299 300 revision.setPath(item.getPath()); 301 302 revision.setAuthor(item.getAuthor()); 303 revision.setMessage(item.getMessage()); 304 revision.setVersion(item.getVersion()); 305 log( revision ); 306 307 save(); 308 } 309 } 310 311 318 public void pageRequested(Page inPage) 319 { 320 } 321 322 327 public void resetNotificationsToDate(Date inDate) 328 { 329 List changes = new ArrayList (); 331 332 for (Iterator iter = getNewChanges().iterator(); iter.hasNext();) 333 { 334 RevisionItem rev = (RevisionItem) iter.next(); 335 336 if (rev.lastModified() != null && rev.lastModified().getTime() > inDate.getTime()) 337 { 338 changes.add(rev); 339 } 340 } 341 342 clearNotifications(); 343 getNewChanges().addAll(changes); 344 } 345 346 350 public void save() 351 { 352 incrementTimeStampCounter(); 353 try 354 { 355 Page page = getPageManager().getPage(getChangeFilePath()); 356 StringWriter out = new StringWriter (); 357 358 new XmlUtil().saveXml(toXmlDocument(), out, page.getCharacterEncoding()); 359 360 StringItem item = new StringItem(getChangeFilePath(),out.toString(),page.getCharacterEncoding()); 361 item.setMakeVersion(false); 362 page.setContentItem(item); 363 getPageManager().putPage(page); 364 365 366 if (getTimeStampCounter() >= getMaxLength()) 367 { 368 setTimeStampCounter(0); 369 String stampedFileName = "changelog-" 370 + new SimpleDateFormat ("yyyy-MM-dd-H-m-s").format(new Date ()) 371 + ".xml"; 372 String stampedPath = PathUtilities.extractDirectoryPath(getChangeFilePath()) 373 + "/" + stampedFileName; 374 Page stampedPage = getPageManager().getPage(stampedPath); 375 stampedPage.getContentItem().setMakeVersion(false); 376 getPageManager().copyPage(page, stampedPage); 377 378 379 new XmlUtil().saveXml(toXmlDocument(), out, page.getCharacterEncoding()); 380 381 item = new StringItem(getChangeFilePath(),out.toString(),page.getCharacterEncoding()); 382 item.setMakeVersion(false); 383 page.setContentItem(item); 384 getPageManager().putPage(page); 385 386 } 387 } 388 catch (Exception ex) 389 { 390 log.error(ex); 391 return; 392 } 393 } 394 395 400 public Document toNotifyXmlDocument() 401 { 402 return buildDocument(getNewChanges()); 404 } 405 406 411 public String toNotifyXmlString() throws Exception 412 { 413 StringWriter out = new StringWriter (); 414 new XMLWriter(out, OutputFormat.createPrettyPrint()).write( 415 buildDocument(getNewChanges()).getRootElement()); 416 417 return out.toString(); 418 } 419 420 425 public Document toXmlDocument() 426 { 427 return buildDocument(getChangeStack()); 428 } 429 430 435 protected void setChangeStack(List stack) 436 { 437 fieldChangeStack = stack; 438 } 439 440 445 public List getChangeStack() 446 { 447 return fieldChangeStack; 448 } 449 450 455 protected void setFormat(SimpleDateFormat inFormat) 456 { 457 fieldFormat = inFormat; 458 } 459 460 465 protected SimpleDateFormat getFormat() 466 { 467 return fieldFormat; 468 } 469 public String formatDate(RevisionItem inItem) 470 { 471 if( inItem.lastModified() == null) 472 { 473 return ""; 474 } 475 return SimpleDateFormat.getDateTimeInstance().format(inItem.lastModified()); 476 } 477 478 public String formatRssDate(RevisionItem inItem) 479 { 480 Date date = inItem.lastModified(); 481 if( date == null) 482 { 483 return "no date"; 484 } 485 else 486 { 487 return getRSSFormat().format(date); 488 } 489 } 490 491 498 protected void addChange(Element inChange) throws Exception 499 { 500 RevisionItem revision = new RevisionItem(); 501 revision.setType(inChange.attributeValue("type")); 502 503 String text = inChange.elementText("Date"); 504 revision.setDate(fieldFormat.parse(text)); 505 506 String path = inChange.elementText("Url"); 507 revision.setPath(path); 508 509 revision.setAuthor(inChange.elementText("Author")); 510 revision.setMessage(inChange.elementText("Message")); 511 revision.setVersion(inChange.elementText("Version")); 512 513 514 log(revision); 515 } 516 517 protected Document buildDocument(List inStack) 518 { 519 Element root = DocumentHelper.createElement("ChangeLog"); 520 root.addAttribute("timeStampCounter", "" + getTimeStampCounter()); 521 522 for (Iterator iter = inStack.iterator(); iter.hasNext();) 523 { 524 ContentItem revision = (ContentItem) iter.next(); 525 Element change = root.addElement("Change"); 526 527 if (revision.getType() != null) 528 { 529 change.addAttribute("type", revision.getType()); 530 } 531 532 Element date = change.addElement("Date"); 533 date.addAttribute("type", "xsd:date"); 534 535 if (revision.lastModified() == null) 536 { 537 date.setText(fieldFormat.format(new Date ())); 538 } 539 else 540 { 541 date.setText(fieldFormat.format(revision.lastModified())); 542 } 543 544 if (revision.getAuthor() != null) 545 { 546 change.addElement("Author").setText( 547 revision.getAuthor()); 548 } 549 if (revision.getMessage() != null) 550 { 551 change.addElement("Message").setText( 552 revision.getMessage()); 553 } 554 if (revision.getVersion() != null) 555 { 556 change.addElement("Version").setText( 557 revision.getVersion()); 558 } 559 560 change.addElement("Url").setText(revision.getPath()); 561 } 562 563 return DocumentHelper.createDocument(root); 564 } 565 566 571 protected void log(ContentItem revision) 572 { 573 574 if ( getChangeStack().size() > 0) 575 { 576 getChangeStack().add(0,revision); 577 } 578 else 579 { 580 getChangeStack().add(revision); 581 } 582 583 if (getChangeStack().size() > getMaxLength()) 584 { 585 getChangeStack().remove(getChangeStack().size() - 1); 586 } 587 if ( getNewChanges().size() > 0) 588 { 589 getNewChanges().add(0,revision); 590 } 591 else 592 { 593 getNewChanges().add(revision); 594 } 595 } 596 600 protected void logCopy( ContentItem inItem) 601 { 602 RevisionItem revision = new RevisionItem(); 603 revision.setType(inItem.getType()); 604 605 Date date = inItem.lastModified(); 606 if( date == null) 607 { 608 date = new Date (); 609 } 610 revision.setDate(date); 611 612 revision.setPath(inItem.getPath()); 613 614 revision.setAuthor(inItem.getAuthor()); 615 revision.setMessage(inItem.getMessage()); 616 revision.setVersion(inItem.getVersion()); 617 log( revision ); 618 } 619 public PageManager getPageManager() 620 { 621 return fieldPageManager; 622 } 623 public void setPageManager(PageManager inPageManager) 624 { 625 fieldPageManager = inPageManager; 626 } 627 628 public int getTimeStampCounter() 629 { 630 return fieldTimeStampCounter; 631 } 632 633 public void setTimeStampCounter(int inTimeStampCounter) 634 { 635 fieldTimeStampCounter = inTimeStampCounter; 636 } 637 638 public void incrementTimeStampCounter() 639 { 640 setTimeStampCounter(getTimeStampCounter() + 1); 641 } 642 643 public SimpleDateFormat getRSSFormat() 644 { 645 return fieldRSSFormat; 646 } 647 } 648 | Popular Tags |