/* * Copyright (C) 2009 Google Inc. * * 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.google.sites.liberation.export; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.sites.liberation.util.EntryType.ANNOUNCEMENTS_PAGE; import static com.google.sites.liberation.util.EntryType.FILE_CABINET_PAGE; import static com.google.sites.liberation.util.EntryType.LIST_PAGE; import static com.google.sites.liberation.util.EntryType.getType; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gdata.data.sites.AnnouncementEntry; import com.google.gdata.data.sites.BaseContentEntry; import com.google.gdata.data.sites.BasePageEntry; import com.google.gdata.data.sites.CommentEntry; import com.google.gdata.data.sites.ListItemEntry; import com.google.gdata.data.sites.ListPageEntry; import com.google.inject.Inject; import com.google.sites.liberation.renderers.AncestorLinksRenderer; import com.google.sites.liberation.renderers.AnnouncementsRenderer; import com.google.sites.liberation.renderers.AttachmentsRenderer; import com.google.sites.liberation.renderers.CommentsRenderer; import com.google.sites.liberation.renderers.ContentRenderer; import com.google.sites.liberation.renderers.FileCabinetRenderer; import com.google.sites.liberation.renderers.ListRenderer; import com.google.sites.liberation.renderers.SubpageLinksRenderer; import com.google.sites.liberation.renderers.TitleRenderer; import com.google.sites.liberation.util.EntryUtils; import com.google.sites.liberation.util.XmlElement; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; /** * Implements {@link PageExporter} to export a single page in a * Site as to a given {@code Appendable}. * * @author bsimon@google.com (Benjamin Simon) * @author rafael.camargo.sp@gmail.com (Rafael Camargo) */ final class PageExporterImpl implements PageExporter { private static final Comparator<BaseContentEntry<?>> updatedComparator = EntryUtils.getReverseUpdatedComparator(); private static final Comparator<BaseContentEntry<?>> titleComparator = EntryUtils.getTitleComparator(); private AncestorLinksRenderer ancestorLinksRenderer; private AnnouncementsRenderer announcementsRenderer; private AttachmentsRenderer attachmentsRenderer; private CommentsRenderer commentsRenderer; private ContentRenderer contentRenderer; private FileCabinetRenderer fileCabinetRenderer; private ListRenderer listRenderer; private SubpageLinksRenderer subpageLinksRenderer; private TitleRenderer titleRenderer; @Inject PageExporterImpl( AncestorLinksRenderer ancestorLinksRenderer, AnnouncementsRenderer announcementsRenderer, AttachmentsRenderer attachmentsRenderer, CommentsRenderer commentsRenderer, ContentRenderer contentRenderer, FileCabinetRenderer fileCabinetRenderer, ListRenderer listRenderer, SubpageLinksRenderer subpageLinksRenderer, TitleRenderer titleRenderer) { this.ancestorLinksRenderer = checkNotNull(ancestorLinksRenderer); this.announcementsRenderer = checkNotNull(announcementsRenderer); this.attachmentsRenderer = checkNotNull(attachmentsRenderer); this.commentsRenderer = checkNotNull(commentsRenderer); this.contentRenderer = checkNotNull(contentRenderer); this.fileCabinetRenderer = checkNotNull(fileCabinetRenderer); this.listRenderer = checkNotNull(listRenderer); this.subpageLinksRenderer = checkNotNull(subpageLinksRenderer); this.titleRenderer = checkNotNull(titleRenderer); } @Override public void exportPage(BaseContentEntry<?> entry, EntryStore entryStore, Appendable out, boolean revisionsExported) throws IOException { checkNotNull(entry, "entry"); checkNotNull(entryStore, "entryStore"); checkNotNull(out, "out"); XmlElement html = new XmlElement("html"); XmlElement head = new XmlElement("head"); XmlElement title = new XmlElement("title"); XmlElement meta_charset = new XmlElement("meta").setAttribute("charset", "utf-8"); title.addText(entry.getTitle().getPlainText()); html.addElement(head.addElement(title).addElement(meta_charset)); XmlElement body = new XmlElement("body"); XmlElement table = new XmlElement("table").setAttribute("width", "100%"); XmlElement row = new XmlElement("tr").setAttribute("valign", "top"); XmlElement sideBar = getSideBar(entry, entryStore); row.addElement(new XmlElement("td").addElement(sideBar).setAttribute( "width", "150px")); row.addElement(new XmlElement("td").addXml(" ")); XmlElement mainDiv = new XmlElement("div"); mainDiv.setAttribute("class", "hentry " + getType(entry).toString()); mainDiv.setAttribute("id", entry.getId()); if (entryStore.getParent(entry.getId()) != null) { List<BasePageEntry<?>> ancestors = getAncestors(entry, entryStore); mainDiv.addElement(ancestorLinksRenderer.renderAncestorLinks(ancestors)); } mainDiv.addElement(titleRenderer.renderTitle(entry)); mainDiv.addElement(contentRenderer.renderContent(entry, revisionsExported)); List<AnnouncementEntry> announcements = Lists.newArrayList(); List<BaseContentEntry<?>> attachments = Lists.newArrayList(); List<CommentEntry> comments = Lists.newArrayList(); List<ListItemEntry> listItems = Lists.newArrayList(); List<BasePageEntry<?>> subpages = Lists.newArrayList(); for (BaseContentEntry<?> child : entryStore.getChildren(entry.getId())) { switch(getType(child)) { case ANNOUNCEMENT: // TODO(gk5885): remove extra cast for // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302214 announcements.add((AnnouncementEntry) child); break; case ATTACHMENT: case WEB_ATTACHMENT: attachments.add(child); break; case COMMENT: // TODO(gk5885): remove extra cast for // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302214 comments.add((CommentEntry) child); break; case LIST_ITEM: // TODO(gk5885): remove extra cast for // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302214 listItems.add((ListItemEntry) child); break; default: subpages.add((BasePageEntry<?>) child); break; } } Collections.sort(announcements, updatedComparator); Collections.sort(attachments, updatedComparator); Collections.sort(comments, updatedComparator); Collections.sort(listItems, updatedComparator); Collections.sort(subpages, titleComparator); if (getType(entry) == ANNOUNCEMENTS_PAGE) { mainDiv.addElement(announcementsRenderer .renderAnnouncements(announcements)); } else if (getType(entry) == FILE_CABINET_PAGE) { mainDiv.addElement(fileCabinetRenderer.renderFileCabinet(attachments)); } else if (getType(entry) == LIST_PAGE) { // TODO(gk5885): remove extra cast for // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302214 mainDiv.addElement(listRenderer.renderList( (ListPageEntry) entry, listItems)); } if (!subpages.isEmpty()) { mainDiv.addElement(new XmlElement("hr")); mainDiv.addElement(subpageLinksRenderer.renderSubpageLinks(subpages)); } if (!attachments.isEmpty() && getType(entry) != FILE_CABINET_PAGE) { mainDiv.addElement(new XmlElement("hr")); mainDiv.addElement(attachmentsRenderer.renderAttachments(attachments)); } if (!comments.isEmpty()) { mainDiv.addElement(new XmlElement("hr")); mainDiv.addElement(commentsRenderer.renderComments(comments)); } row.addElement(new XmlElement("td").addElement(mainDiv)); html.addElement(body.addElement(table.addElement(row))); html.appendTo(out); } private XmlElement getSideBar(BaseContentEntry<?> entry, EntryStore entryStore) { XmlElement table = new XmlElement("table"); table.addElement(new XmlElement("tr").addElement(new XmlElement("th") .addText("Navigation").setAttribute("align", "left"))); Set<BasePageEntry<?>> pages = Sets.newTreeSet(titleComparator); pages.addAll(entryStore.getTopLevelEntries()); String pathToRoot = getPathToRoot(entry, entryStore); for (BasePageEntry<?> page : pages) { String text = page.getTitle().getPlainText(); if (page.equals(entry)) { table.addElement(new XmlElement("tr").addElement(new XmlElement("td") .addElement(new XmlElement("small").addText(text)))); } else { String href = pathToRoot + page.getPageName().getValue() + "/index.html"; XmlElement link = new XmlElement("a").addText(text) .setAttribute("href", href); table.addElement(new XmlElement("tr").addElement(new XmlElement("td") .addElement(new XmlElement("small").addElement(link)))); } } return table; } private String getPathToRoot(BaseContentEntry<?> entry, EntryStore entryStore) { BasePageEntry<?> parent = entryStore.getParent(entry.getId()); if (parent == null) { return "../"; } return getPathToRoot(parent, entryStore) + "../"; } private List<BasePageEntry<?>> getAncestors(BaseContentEntry<?> entry, EntryStore entryStore) { BasePageEntry<?> parent = entryStore.getParent(entry.getId()); if (parent == null) { return Lists.newLinkedList(); } List<BasePageEntry<?>> ancestors = getAncestors(parent, entryStore); ancestors.add(parent); return ancestors; } }