Java tutorial
/* * 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.page; import ch.entwine.weblounge.common.content.ResourceContent; import ch.entwine.weblounge.common.content.ResourceURI; import ch.entwine.weblounge.common.content.page.Composer; import ch.entwine.weblounge.common.content.page.Page; import ch.entwine.weblounge.common.content.page.PageContentListener; import ch.entwine.weblounge.common.content.page.PagePreviewMode; import ch.entwine.weblounge.common.content.page.PageTemplate; import ch.entwine.weblounge.common.content.page.Pagelet; import ch.entwine.weblounge.common.content.page.PageletRenderer; import ch.entwine.weblounge.common.content.page.PageletURI; import ch.entwine.weblounge.common.impl.content.ResourceImpl; import ch.entwine.weblounge.common.impl.content.ResourceURIImpl; import ch.entwine.weblounge.common.language.Language; import ch.entwine.weblounge.common.site.Module; import ch.entwine.weblounge.common.site.Site; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * A <code>Page</code> encapsulates all data that is attached with a site URL. */ public class PageImpl extends ResourceImpl<ResourceContent> implements Page { /** The logging facility */ private static final Logger logger = LoggerFactory.getLogger(PageImpl.class); /** Renderer identifier */ protected String template = null; /** Layout identifier */ protected String layout = null; /** Flag to mark a page as a stationary */ protected boolean isStationary = false; /** The preview pagelets */ protected List<Pagelet> preview = null; /** The pagelet container */ protected Map<String, List<Pagelet>> composers = null; /** The page content listeners */ private List<PageContentListener> contentListeners = null; /** * Creates a new page for the given page uri. * * @param uri * the page uri */ public PageImpl(ResourceURI uri) { super(new ResourceURIImpl(TYPE, uri.getSite(), uri.getPath(), uri.getIdentifier(), uri.getVersion())); this.composers = new HashMap<String, List<Pagelet>>(); } /** * For pages, the resource langauge support equals the content support. * * @see ch.entwine.weblounge.common.impl.content.ResourceImpl#supportsContentLanguage(ch.entwine.weblounge.common.language.Language) */ @Override public boolean supportsContentLanguage(Language language) { return supportsLanguage(language); } /** * Returns the layout associated with this page. * * @return the associated layout */ public String getLayout() { return layout; } /** * Sets the layout that is used to determine default content and initial * layout. * * @param layout * the layout identifier */ public void setLayout(String layout) { this.layout = layout; } /** * Returns the template that is used to render this page. * * @return the renderer */ public String getTemplate() { return template; } /** * Sets the renderer that is used to render this page. * * @param template * the template identifier */ public void setTemplate(String template) { this.template = template; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#setStationary(boolean) */ public void setStationary(boolean stationary) { this.isStationary = stationary; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#isStationary() */ public boolean isStationary() { return isStationary; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#getComposer(java.lang.String) */ public Composer getComposer(String composerId) { Composer composer = null; List<Pagelet> pagelets = composers.get(composerId); if (pagelets != null) composer = new ComposerImpl(composerId, pagelets); return composer; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#getStage() */ public Composer getStage() { PageTemplate t = null; if (StringUtils.isNotBlank(template)) { t = uri.getSite().getTemplate(template); } else { t = uri.getSite().getDefaultTemplate(); logger.warn("Page {} has no template associated", uri); } if (t == null) throw new IllegalStateException("Page template '" + template + "' not found"); String stage = t.getStage(); if (StringUtils.isBlank(stage)) throw new IllegalStateException("Page template '" + template + "' does not define a stage"); Composer c = getComposer(stage); if (c == null) { List<Pagelet> pagelets = new ArrayList<Pagelet>(); c = new ComposerImpl(stage, pagelets); composers.put(stage, pagelets); } return c; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#getComposers() */ public Composer[] getComposers() { List<Composer> composerList = new ArrayList<Composer>(); for (String name : composers.keySet()) { composerList.add(new ComposerImpl(name, composers.get(name))); } return composerList.toArray(new Composer[composerList.size()]); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#addPagelet(ch.entwine.weblounge.common.content.page.Pagelet, * java.lang.String) */ public Pagelet addPagelet(Pagelet pagelet, String composer) { List<Pagelet> c = composers.get(composer); int position = (c == null) ? 0 : c.size(); return addPagelet(pagelet, composer, position); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#addPagelet(ch.entwine.weblounge.common.content.page.Pagelet, * java.lang.String, int) */ public Pagelet addPagelet(Pagelet pagelet, String composer, int position) { List<Pagelet> c = composers.get(composer); if (c == null) { c = new ArrayList<Pagelet>(); composers.put(composer, c); } // Test position if (position < 0 || position > c.size()) throw new IndexOutOfBoundsException("There are only " + c.size() + " pagelets in the composer"); // Insert if (position < c.size()) { c.add(position, pagelet); for (int i = position + 1; i < c.size(); i++) { c.get(i).getURI().setPosition(i); } } // Append else { c.add(pagelet); } // Adjust pagelet location PageletURI location = pagelet.getURI(); if (location == null) { location = new PageletURIImpl(uri, composer, position); pagelet.setURI(location); } else { location.setURI(uri); location.setComposer(composer); location.setPosition(position); } return pagelet; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#getPagelets() */ public Pagelet[] getPagelets() { List<Pagelet> result = new ArrayList<Pagelet>(); for (List<Pagelet> pagelets : composers.values()) { result.addAll(pagelets); } return result.toArray(new Pagelet[result.size()]); } /** * Returns the pagelets that are contained in the specified composer. * * @param composer * the composer identifier * @return the pagelets */ public Pagelet[] getPagelets(String composer) { List<Pagelet> c = composers.get(composer); if (c == null) { c = new ArrayList<Pagelet>(); } Pagelet[] pagelets = new Pagelet[c.size()]; return c.toArray(pagelets); } /** * Returns a copy of the pagelets of the given module and renderer that are * contained in the specified composer. * * @param composer * the composer identifier * @param module * the module identifier * @param id * the renderer id * @return the pagelets */ public Pagelet[] getPagelets(String composer, String module, String id) { List<Pagelet> l = new ArrayList<Pagelet>(); List<Pagelet> c = composers.get(composer); if (c != null) { l.addAll(c); int i = 0; while (i < l.size()) { Pagelet p = l.get(i); if (!p.getModule().equals(module) || !p.getIdentifier().equals(id)) { l.remove(i); } else { i++; } } } Pagelet[] pagelets = new Pagelet[l.size()]; return l.toArray(pagelets); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#removePagelet(java.lang.String, * int) */ public Pagelet removePagelet(String composer, int position) { List<Pagelet> pagelets = composers.get(composer); // Test index if (pagelets == null || pagelets.size() < position) throw new IndexOutOfBoundsException("No pagelet found at position " + position); // Remove the pagelet and update uris of following pagelets Pagelet pagelet = pagelets.remove(position); for (int i = position; i < pagelets.size(); i++) { pagelets.get(i).getURI().setPosition(i); } return pagelet; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.content.page.Page#getPreview() */ public Pagelet[] getPreview() { Site site = getURI().getSite(); PageTemplate t = null; if (StringUtils.isNotBlank(template)) { t = site.getTemplate(template); } else { t = site.getDefaultTemplate(); logger.warn("Page {} has no template associated, using site default '{}'", uri, t.getIdentifier()); } if (preview == null && t == null) { logger.warn("Can't calculate the page preview due to missing page template '{}'", template); return new Pagelet[] {}; } else if (preview == null && t.getStage() == null) { logger.warn("Can't calculate the page preview due to missing stage definition in page template '{}'", template); return new Pagelet[] {}; } else if (preview == null) { this.preview = new ArrayList<Pagelet>(); List<Pagelet> stage = composers.get(t.getStage()); Set<PageletRenderer> previewRenderers = new HashSet<PageletRenderer>(); if (stage != null) { for (Pagelet p : stage) { // Load the pagelet's module Module m = site.getModule(p.getModule()); if (m == null) { logger.warn("Skipping pagelet '{}' for preview calculation: module '{}' can't be found", p, p.getModule()); continue; } // Load the pagelet's renderer PageletRenderer r = m.getRenderer(p.getIdentifier()); if (r == null) { logger.warn( "Skipping pagelet '{}' for preview calculation: pagelet renderer '{}' can't be found", p, p.getIdentifier()); continue; } // Evaluate the preview mode PagePreviewMode previewMode = r.getPreviewMode(); if (previewMode.equals(PagePreviewMode.First) && !previewRenderers.contains(r)) { preview.add(p); previewRenderers.add(r); } else if (PagePreviewMode.All.equals(previewMode)) { preview.add(p); previewRenderers.add(r); } else if (PagePreviewMode.Boundary.equals(previewMode)) { preview.clear(); for (Pagelet p2 : stage) { if (p2.equals(p)) break; preview.add(p2); } break; } } } } return preview.toArray(new Pagelet[preview.size()]); } /** * Adds a <code>PageContentListener</code> to this page, who will be notified * (amongst others) about new, moved, deleted or altered pagelets. * * @param listener * the new page content listener */ public void addPageContentListener(PageContentListener listener) { if (contentListeners == null) contentListeners = new ArrayList<PageContentListener>(); contentListeners.add(listener); } /** * Removes a <code>PageContentListener</code> from this page. * * @param listener * the page content listener */ public void removePageContentListener(PageContentListener listener) { if (contentListeners == null) return; contentListeners.remove(listener); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.content.ResourceImpl#toXmlRootTag() */ @Override protected String toXmlRootTag() { return "page"; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.content.ResourceImpl#toXmlHead(java.lang.StringBuffer) */ @Override protected void toXmlHead(StringBuffer buffer) { if (template != null) { buffer.append("<template>"); buffer.append(template); buffer.append("</template>"); } if (isStationary) { buffer.append("<stationary>true</stationary>"); } if (layout != null) { buffer.append("<layout>"); buffer.append(layout); buffer.append("</layout>"); } } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.content.ResourceImpl#toXmlBody(java.lang.StringBuffer) */ @Override protected StringBuffer toXmlBody(StringBuffer buffer) { for (Map.Entry<String, List<Pagelet>> entry : composers.entrySet()) { buffer.append("<composer id=\""); buffer.append(entry.getKey()); buffer.append("\">"); for (Pagelet pagelet : entry.getValue()) { buffer.append(pagelet.toXml()); } buffer.append("</composer>"); } return super.toXmlBody(buffer); } }