/*
* 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.contentrepository.impl;
import static ch.entwine.weblounge.search.impl.IndexSchema.HEADER_XML;
import static ch.entwine.weblounge.search.impl.IndexSchema.PATH;
import static ch.entwine.weblounge.search.impl.IndexSchema.PREVIEW_XML;
import static ch.entwine.weblounge.search.impl.IndexSchema.RESOURCE_ID;
import static ch.entwine.weblounge.search.impl.IndexSchema.VERSION;
import static ch.entwine.weblounge.search.impl.IndexSchema.XML;
import ch.entwine.weblounge.common.content.PreviewGenerator;
import ch.entwine.weblounge.common.content.Resource;
import ch.entwine.weblounge.common.content.ResourceContent;
import ch.entwine.weblounge.common.content.ResourceContentReader;
import ch.entwine.weblounge.common.content.ResourceMetadata;
import ch.entwine.weblounge.common.content.ResourceReader;
import ch.entwine.weblounge.common.content.ResourceURI;
import ch.entwine.weblounge.common.content.SearchResultItem;
import ch.entwine.weblounge.common.content.page.Page;
import ch.entwine.weblounge.common.content.page.PagePreviewGenerator;
import ch.entwine.weblounge.common.impl.content.page.PageImpl;
import ch.entwine.weblounge.common.impl.content.page.PageReader;
import ch.entwine.weblounge.common.impl.content.page.PageSearchResultItemImpl;
import ch.entwine.weblounge.common.impl.content.page.PageURIImpl;
import ch.entwine.weblounge.common.impl.url.WebUrlImpl;
import ch.entwine.weblounge.common.language.Language;
import ch.entwine.weblounge.common.security.User;
import ch.entwine.weblounge.common.site.Site;
import ch.entwine.weblounge.common.url.WebUrl;
import ch.entwine.weblounge.search.impl.PageInputDocument;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
/**
* Resource serializer for pages.
*/
public class PageSerializer extends AbstractResourceSerializer<ResourceContent, Page> {
/** The logging facility */
private static final Logger logger = LoggerFactory.getLogger(PageSerializer.class);
/** The preview generators */
protected List<PagePreviewGenerator> previewGenerators = new ArrayList<PagePreviewGenerator>();
/**
* Creates a new page serializer.
*/
public PageSerializer() {
super(Page.TYPE);
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#getMimeType(ch.entwine.weblounge.common.content.ResourceContent)
*/
public String getMimeType(ResourceContent resourceContent) {
return "text/html";
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#supports(java.lang.String)
*/
public boolean supports(String mimeType) {
return false;
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#newResource(ch.entwine.weblounge.common.site.Site)
*/
public Resource<ResourceContent> newResource(Site site) {
return new PageImpl(new PageURIImpl(site));
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#newResource(ch.entwine.weblounge.common.site.Site,
* java.io.InputStream, ch.entwine.weblounge.common.security.User,
* ch.entwine.weblounge.common.language.Language)
*/
public Resource<ResourceContent> newResource(Site site, InputStream is,
User user, Language language) {
return newResource(site);
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.contentrepository.impl.AbstractResourceSerializer#createNewReader()
*/
@Override
protected PageReader createNewReader() throws ParserConfigurationException,
SAXException {
return new PageReader();
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#toMetadata(ch.entwine.weblounge.common.content.Resource)
*/
public List<ResourceMetadata<?>> toMetadata(Resource<?> resource) {
return new PageInputDocument((Page) resource).getMetadata();
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#toResource(ch.entwine.weblounge.common.site.Site,
* java.util.List)
*/
public Resource<?> toResource(Site site, List<ResourceMetadata<?>> metadata) {
for (ResourceMetadata<?> metadataItem : metadata) {
if (XML.equals(metadataItem.getName())) {
String resourceXml = (String) metadataItem.getValues().get(0);
try {
ResourceReader<ResourceContent, Page> reader = getReader();
Page page = reader.read(IOUtils.toInputStream(resourceXml, "UTF-8"), site);
return page;
} catch (SAXException e) {
logger.warn("Error parsing page from metadata", e);
return null;
} catch (IOException e) {
logger.warn("Error parsing page from metadata", e);
return null;
} catch (ParserConfigurationException e) {
logger.warn("Error parsing page from metadata", e);
return null;
}
}
}
return null;
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#toSearchResultItem(ch.entwine.weblounge.common.site.Site,
* double, List)
*/
public SearchResultItem toSearchResultItem(Site site, double relevance,
List<ResourceMetadata<?>> metadata) {
Map<String, ResourceMetadata<?>> metadataMap = new HashMap<String, ResourceMetadata<?>>();
for (ResourceMetadata<?> metadataItem : metadata) {
metadataMap.put(metadataItem.getName(), metadataItem);
}
// resource id
String id = (String) metadataMap.get(RESOURCE_ID).getValues().get(0);
// resource path
String path = (String) metadataMap.get(PATH).getValues().get(0);
// resource version
long version = (Long) metadataMap.get(VERSION).getValues().get(0);
// FIXME Add exception handling
ResourceURI uri = new PageURIImpl(site, path, id, version);
WebUrl url = new WebUrlImpl(site, path);
PageSearchResultItemImpl result = new PageSearchResultItemImpl(uri, url, relevance, site, metadata);
if (metadataMap.get(XML) != null)
result.setResourceXml((String) metadataMap.get(XML).getValues().get(0));
if (metadataMap.get(HEADER_XML) != null)
result.setPageHeaderXml((String) metadataMap.get(HEADER_XML).getValues().get(0));
if (metadataMap.get(PREVIEW_XML) != null)
result.setPagePreviewXml((String) metadataMap.get(PREVIEW_XML).getValues().get(0));
return result;
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#getContentReader()
*/
public ResourceContentReader<ResourceContent> getContentReader()
throws ParserConfigurationException, SAXException {
return null;
}
/**
* {@inheritDoc}
*
* @see ch.entwine.weblounge.common.repository.ResourceSerializer#getPreviewGenerator(Resource)
*/
public PreviewGenerator getPreviewGenerator(Resource<?> resource) {
for (PagePreviewGenerator generator : previewGenerators) {
if (generator.supports(resource)) {
logger.trace("Page preview generator {} agrees to handle {}", generator, resource);
return generator;
}
}
logger.trace("No page preview generator found to handle {}", resource);
return null;
}
/**
* Adds the preview generator to the list of registered preview generators.
*
* @param generator
* the generator
*/
void addPreviewGenerator(PagePreviewGenerator generator) {
previewGenerators.add(generator);
Collections.sort(previewGenerators, new Comparator<PreviewGenerator>() {
public int compare(PreviewGenerator a, PreviewGenerator b) {
return Integer.valueOf(b.getPriority()).compareTo(a.getPriority());
}
});
}
/**
* Removes the preview generator from the list of registered preview
* generators.
*
* @param generator
* the generator
*/
void removePreviewGenerator(PagePreviewGenerator generator) {
previewGenerators.remove(generator);
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Page serializer";
}
}