/* * Weblounge: Web Content Management System * Copyright (c) 2003 - 2011 The Weblounge Team * http://entwinemedia.com/weblounge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ch.entwine.weblounge.common.impl.content; import ch.entwine.weblounge.common.content.ResourceContent; import ch.entwine.weblounge.common.content.ResourceContentReader; import ch.entwine.weblounge.common.impl.language.LanguageUtils; import ch.entwine.weblounge.common.impl.security.UserImpl; import ch.entwine.weblounge.common.impl.util.xml.WebloungeSAXHandler; import ch.entwine.weblounge.common.security.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; import java.util.Date; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * Utility class used to parse <code>Content</code> data for simple files. */ public abstract class ResourceContentReaderImpl<T extends ResourceContent> extends WebloungeSAXHandler implements ResourceContentReader<T> { /** Logging facility */ private static final Logger logger = LoggerFactory.getLogger(ResourceContentReaderImpl.class); /** Parser factory */ protected static final SAXParserFactory parserFactory = SAXParserFactory.newInstance(); /** The SAX parser */ protected WeakReference<SAXParser> parserRef = null; /** The file content data */ protected T content = null; /** * Creates a new file content reader that will parse serialized XML version of * the file content and store it in the {@link ResourceContent} that is * returned by the {@link #read} method. * * @throws ParserConfigurationException * if the SAX parser setup failed * @throws SAXException * if an error occurs while parsing * * @see #createFromXml(InputStream) */ public ResourceContentReaderImpl() throws ParserConfigurationException, SAXException { parserRef = new WeakReference<SAXParser>(parserFactory.newSAXParser()); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.ResourceContentReader#createFromXml(java.io.InputStream) */ public T createFromXml(InputStream is) throws SAXException, IOException, ParserConfigurationException { SAXParser parser = parserRef.get(); if (parser == null) { parser = parserFactory.newSAXParser(); parserRef = new WeakReference<SAXParser>(parser); } parser.parse(is, this); return content; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.ResourceContentReader#reset() */ public void reset() { super.reset(); content = null; SAXParser parser = parserRef.get(); if (parser != null) parser.reset(); } /** * Returns the content that has been read in. * * @return the content */ public T getContent() { return content; } /** * Creates an empty resource content object that will be populated by the * parser. * * @return the new content object */ protected abstract T createContent(); /** * {@inheritDoc} * * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, * java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String local, String raw, Attributes attrs) throws SAXException { super.startElement(uri, local, raw, attrs); // start of a new content element if ("content".equals(raw)) { String languageId = attrs.getValue("language"); content = createContent(); content.setLanguage(LanguageUtils.getLanguage(languageId)); logger.debug("Started reading file content {}", content); } // creator else if ("user".equals(raw)) { clipboard.put("user", attrs.getValue("id")); clipboard.put("realm", attrs.getValue("realm")); } } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#endElement(java.lang.String, * java.lang.String, java.lang.String) */ public void endElement(String uri, String local, String raw) throws SAXException { // content if ("content".equals(raw)) { logger.debug("Finished reading content {}", content); } // filename else if ("filename".equals(raw)) { content.setFilename(getCharacters()); logger.trace("Content's filename is '{}'", content.getFilename()); } // source else if ("source".equals(raw)) { content.setSource(getCharacters()); logger.trace("Content's source is '{}'", content.getSource()); } // external else if ("external".equals(raw)) { try { content.setExternalLocation(new URL(getCharacters())); } catch (MalformedURLException e) { throw new SAXException(e); } logger.trace("Content's external location is '{}'", content.getSource()); } // author else if ("author".equals(raw)) { content.setAuthor(getCharacters()); logger.trace("Content's author is '{}'", content.getAuthor()); } // user else if ("user".equals(raw)) { String login = (String) clipboard.remove("user"); String realm = (String) clipboard.remove("realm"); String name = getCharacters(); User user = new UserImpl(login, realm, name); clipboard.put("user", user); } // date else if ("date".equals(raw)) { try { Date d = dateFormat.parse(getCharacters()); clipboard.put("date", d); } catch (ParseException e) { throw new IllegalStateException("Reading date failed: '" + getCharacters() + "'"); } } // created else if ("created".equals(raw)) { User owner = (User) clipboard.remove("user"); Date date = (Date) clipboard.remove("date"); if (date == null) throw new IllegalStateException("Creation date not found"); content.setCreationDate(date); if (owner != null) content.setCreator(owner); } super.endElement(uri, local, raw); } }