package com.wooki.services;
import java.io.IOException;
import java.util.Date;
import org.apache.log4j.Logger;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.wooki.Draft;
import com.wooki.domain.biz.BookManager;
import com.wooki.domain.biz.ChapterManager;
import com.wooki.domain.biz.UserManager;
import com.wooki.domain.exception.UserAlreadyException;
import com.wooki.domain.exception.UserAlreadyOwnerException;
import com.wooki.domain.exception.UserNotFoundException;
import com.wooki.domain.model.Book;
import com.wooki.domain.model.Chapter;
import com.wooki.domain.model.User;
import com.wooki.services.security.WookiSecurityContext;
public class HTMLParser extends DefaultHandler
{
private Book book = new Book();
private EntityResolver entityResolver;
@Inject
@Autowired
private UserManager userManager;
@Inject
@Autowired
private ChapterManager chapterManager;
@Inject
@Autowired
private BookManager bookManager;
@Autowired
private WookiSecurityContext securityCtx;
private boolean isInBookTitle = false;
private boolean isInAuthor;
private String currentEmail;
private boolean isInEmail;
private String currentFirstName;
private boolean isInFirstName;
private String currentSurname;
private boolean isInSurname;
private String currentChapterTitle;
private boolean isInChapter;
private int divCount;
private Logger logger = Logger.getLogger(HTMLParser.class);
StringBuffer buffer = new StringBuffer();
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException
{
if (!isInChapter && qName.equals("h1") && attributes.getValue("class").equals("title"))
{
isInBookTitle = true;
}
else
{
if (!isInChapter && qName.equals("div") && attributes.getValue("class") != null
&& attributes.getValue("class").equals("author"))
{
isInAuthor = true;
}
else
{
if (!isInChapter && isInAuthor && qName.equals("span")
&& attributes.getValue("class").equals("firstname"))
{
isInFirstName = true;
}
else
{
if (!isInChapter && isInAuthor && qName.equals("span")
&& attributes.getValue("class").equals("surname"))
{
isInSurname = true;
}
else
{
if (!isInChapter && isInAuthor && qName.equals("code")
&& attributes.getValue("class").equals("email"))
{
isInEmail = true;
}
else
{
if (qName.equals("div") && attributes.getValue("class") != null
&& attributes.getValue("class").equals("chapter"))
{
isInChapter = true;
divCount = 0;
buffer.setLength(0);
currentChapterTitle = attributes.getValue("title");
if (currentChapterTitle == null)
{
currentChapterTitle = "No title";
}
}
else
{
if (isInChapter)
{
buffer.append("<").append(qName);
String currentName;
int length = attributes.getLength();
for (int i = 0; i < length; i++)
{
currentName = attributes.getQName(i);
buffer.append(" ").append(currentName).append("=\"")
.append(attributes.getValue(i)).append("\"");
}
buffer.append(">");
if (qName.equals("div") && isInChapter)
{
divCount++;
}
}
}
}
}
}
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (qName.equals("h1") && isInBookTitle)
{
book.setTitle(buffer.toString());
buffer.setLength(0);
isInBookTitle = false;
}
else
{
if (isInFirstName && qName.equals("span"))
{
currentFirstName = buffer.toString();
isInFirstName = false;
buffer.setLength(0);
}
else
{
if (isInSurname && qName.equals("span"))
{
currentSurname = buffer.toString();
isInSurname = false;
buffer.setLength(0);
}
else
{
if (isInEmail && qName.equals("code"))
{
currentEmail = buffer.toString();
isInEmail = false;
buffer.setLength(0);
}
else
{
if (qName.equals("div") && isInAuthor)
{
String authorName = currentFirstName + " " + currentSurname;
User user = userManager.findByUsername(authorName);
// KOLOSSAL FAILLE !
if (user == null)
{
user = new User();
user.setFullname(authorName);
user.setCreationDate(new Date());
user.setEmail(currentEmail);
user.setUsername(authorName);
user.setPassword(currentFirstName);
try
{
userManager.registerUser(user);
securityCtx.log(user);
}
catch (UserAlreadyException e)
{
logger.error(e.getLocalizedMessage());
}
}
book = bookManager.create(book.getTitle());
try
{
bookManager.addAuthor(book, authorName);
}
catch (UserNotFoundException e)
{
logger.error(e.getLocalizedMessage());
}
catch (UserAlreadyOwnerException e)
{
logger.error(e.getLocalizedMessage());
}
isInAuthor = false;
}
else
{
if (isInChapter)
{
buffer.append("</").append(qName).append(">");
if (qName.equals("div"))
{
divCount--;
if (divCount <= 0)
{
Chapter currentChapter = bookManager.addChapter(
book,
currentChapterTitle);
Draft draft = new Draft();
draft.setTimestamp(currentChapter.getLastModified());
draft.setData(buffer.toString());
chapterManager.updateContent(currentChapter.getId(), draft);
buffer.setLength(0);
}
}
}
}
}
}
}
}
}
public void characters(char[] ch, int start, int length) throws SAXException
{
buffer.append(ch, start, length);
}
public InputSource resolveEntity(String publicId, String systemId) throws IOException,
SAXException
{
return getEntityResolver().resolveEntity(publicId, systemId);
}
public EntityResolver getEntityResolver()
{
return this.entityResolver;
}
public void setEntityResolver(EntityResolver entityResolver)
{
this.entityResolver = entityResolver;
}
public Book getBook()
{
return book;
}
public void setBook(Book book)
{
this.book = book;
}
}