/*
* Copyright 2008 - 2010 Lars Heuer (heuer[at]semagia.com). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.semagia.atomico.server.feed.impl;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.List;
import com.semagia.atomico.MediaType;
import com.semagia.atomico.dm.IAuthor;
import com.semagia.atomico.dm.IAuthorAwareEntity;
import com.semagia.atomico.dm.IEntity;
import com.semagia.atomico.dm.ISummaryAwareEntity;
import com.semagia.atomico.server.IConfiguration;
import com.semagia.atomico.server.UnsupportedMediaTypeException;
import com.semagia.atomico.server.dm.ICollectionInfo;
import com.semagia.atomico.server.dm.IVariantAwareWritableRepresentation;
import com.semagia.atomico.server.dm.IFragmentInfo;
import com.semagia.atomico.server.dm.ISnapshotInfo;
import com.semagia.atomico.server.feed.IOutputAwareFeedHandler;
import com.semagia.atomico.server.storage.IStorage;
import com.semagia.atomico.server.storage.StorageException;
import com.semagia.atomico.server.utils.LinkUtils;
import com.semagia.atomico.server.utils.MediaTypeUtils;
/**
* Factory for feeds.
*
* @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
* @version $Rev: 132 $ - $Date: 2012-07-20 11:55:23 -0500 (Fri, 20 Jul 2012) $
*/
public final class FeedFactory {
public FeedFactory() {
// noop.
}
public IVariantAwareWritableRepresentation createOverviewFeed(URI baseURI,
final IStorage storage, final IConfiguration config,
final long lastModification,
final List<MediaType> feedMediaTypes) throws StorageException, UnsupportedMediaTypeException {
final OverviewFeed feed = new OverviewFeed (
baseURI.toASCIIString(), config.getOverviewFeedTitle(),
lastModification);
applyAuthorInfo(config, feed);
for (ICollectionInfo info: storage.getCollectionInfos(config.getCollectionSortOrder())) {
feed.addEntry(info, LinkUtils.linkToCollection(baseURI, info));
}
final MediaType mediaType = getFeedMediaType(feedMediaTypes);
final IOutputAwareFeedHandler handler = makeFeedHandler(mediaType);
return new FeedWritable(new OverviewFeedWriter(feed, handler), mediaType);
}
public IVariantAwareWritableRepresentation createCollectionFeed(final URI baseURI,
final IStorage storage, final IConfiguration config,
final ICollectionInfo collInfo,
final List<MediaType> feedMediaTypes) throws StorageException, UnsupportedMediaTypeException {
final String collTitle = collInfo.getTitle();
final String collId = collInfo.getCollectionId();
final CollectionFeed feed = new CollectionFeed(baseURI.toASCIIString(),
config.getCollectionFeedTitle(collTitle),
collInfo.getUpdated());
applyAuthorInfo(config, feed, collInfo);
if (collInfo instanceof ISummaryAwareEntity) {
feed.setSummary(((ISummaryAwareEntity) collInfo).getSummary());
}
feed.setSnapshotsEntry(LinkUtils.linkToSnapshots(baseURI, collInfo).toASCIIString(),
config.getSnapshotsEntryTitle(collTitle),
storage.lastSnapshotModification(collId));
feed.setFragmentsEntry(LinkUtils.linkToFragments(baseURI, collInfo).toASCIIString(),
config.getFragmentsEntryTitle(collTitle),
storage.lastFragmentModification(collId));
final MediaType mediaType = getFeedMediaType(feedMediaTypes);
final IOutputAwareFeedHandler handler = makeFeedHandler(mediaType);
return new FeedWritable(new CollectionFeedWriter(feed, handler), mediaType);
}
public IVariantAwareWritableRepresentation createFragmentsFeed(final URI baseURI,
final IStorage storage, final IConfiguration config,
final long lastModification, final ICollectionInfo collInfo,
List<MediaType> feedMediaTypes) throws StorageException, UnsupportedMediaTypeException {
final FragmentsFeed feed = new FragmentsFeed(baseURI.toASCIIString(),
config.getFragmentFeedTitle(collInfo.getTitle()),
lastModification);
applyAuthorInfo(config, feed, collInfo);
for (IFragmentInfo info: storage.getFragmentInfos(collInfo.getCollectionId())) {
feed.addEntry(info, LinkUtils.linkTo(baseURI, collInfo, info));
}
final MediaType mediaType = getFeedMediaType(feedMediaTypes);
final IOutputAwareFeedHandler handler = makeFeedHandler(mediaType);
return new FeedWritable(new FragmentsFeedWriter(feed, handler), mediaType);
}
public IVariantAwareWritableRepresentation createSnapshotsFeed(final URI baseURI,
final IStorage storage, final IConfiguration config,
final long lastModification, final ICollectionInfo collInfo,
List<MediaType> feedMediaTypes) throws StorageException, UnsupportedMediaTypeException {
final SnapshotsFeed feed = new SnapshotsFeed(baseURI.toASCIIString(),
config.getSnapshotFeedTitle(collInfo.getTitle()),
lastModification);
applyAuthorInfo(config, feed, collInfo);
for (ISnapshotInfo info: storage.getSnapshotInfos(collInfo.getCollectionId())) {
feed.addEntry(info, LinkUtils.linkTo(baseURI, collInfo, info));
}
final MediaType mediaType = getFeedMediaType(feedMediaTypes);
final IOutputAwareFeedHandler handler = makeFeedHandler(mediaType);
return new FeedWritable(new SnapshotsFeedWriter(feed, handler), mediaType);
}
/**
* Sets the author information to the specified feed.
*
* @param feed The feed.
*/
private final void applyAuthorInfo(final IConfiguration config, final AbstractFeed<?> feed) {
feed.addAuthor(config.getAuthor());
}
private void applyAuthorInfo(final IConfiguration config, final AbstractFeed<?> feed, final IEntity entity) {
if (entity instanceof IAuthorAwareEntity) {
for (IAuthor author: ((IAuthorAwareEntity) entity).getAuthors()) {
feed.addAuthor(author);
}
}
if (feed.getAuthors().isEmpty()) {
applyAuthorInfo(config, feed);
}
}
/**
* Returns a feed handler based on the provided acceptable media types.
*
* @param builder A response builder, used to set resulting media type.
* @param acceptableMediaTypes The preferred media types (provided by a client).
* @return A feed handler.
* @throws UnsupportedMediaTypeException
*/
private IOutputAwareFeedHandler makeFeedHandler(final MediaType mediaType) throws UnsupportedMediaTypeException {
IOutputAwareFeedHandler handler = null;
if (mediaType != null) {
handler = FeedHandlerRegistry.createFeedHandler(mediaType);
}
if (handler == null) {
throw new UnsupportedMediaTypeException("", FeedHandlerRegistry.getMediaTypes());
}
return handler;
}
private static MediaType getFeedMediaType(final List<MediaType> acceptableMediaTypes) {
return MediaTypeUtils.getPreferredMediaType(FeedHandlerRegistry.getMediaTypes(), acceptableMediaTypes);
}
private static final class FeedWritable implements IVariantAwareWritableRepresentation {
private final MediaType _mediaType;
private final IFeedWriter _writer;
FeedWritable(final IFeedWriter writer, final MediaType mediaType) {
_writer = writer;
_mediaType = mediaType;
}
/* (non-Javadoc)
* @see com.semagia.atomico.dm.IWritable#write(java.io.OutputStream)
*/
@Override
public void write(OutputStream out) throws IOException {
_writer.write(out);
}
/* (non-Javadoc)
* @see com.semagia.atomico.dm.IWritableRepresentation#getMediaType()
*/
@Override
public MediaType getMediaType() {
return _mediaType;
}
/* (non-Javadoc)
* @see com.semagia.atomico.server.dm.IVariantAwareWritableRepresentation#getVariantMediaTypes()
*/
@Override
public List<MediaType> getVariantMediaTypes() {
return FeedHandlerRegistry.getMediaTypes();
}
}
}