/src/main/java/org/randombits/supplier/confluence/content/AbstractContentSupplier.java
Java | 385 lines | 276 code | 72 blank | 37 comment | 46 complexity | 6006c9c99a1bfef29bf1068dddf24094 MD5 | raw file
- /*
- * Copyright (c) 2007, CustomWare Asia Pacific
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of "CustomWare Asia Pacific" nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- package org.randombits.supplier.confluence.content;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Set;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.commons.collections.IteratorUtils;
- import org.apache.commons.collections.Transformer;
- import org.apache.commons.lang.StringUtils;
- import org.apache.log4j.Logger;
- import org.jsoup.Jsoup;
- import org.randombits.supplier.confluence.AbstractConfluenceSupplier;
- import org.randombits.supplier.core.annotate.KeyValue;
- import org.randombits.supplier.core.annotate.KeyWeight;
- import org.randombits.supplier.core.annotate.SupplierKey;
- import org.randombits.support.confluence.render.DefaultRenderAssistant;
- import org.randombits.support.confluence.render.RenderAssistant;
- import org.randombits.support.confluence.render.RenderException;
- import org.randombits.support.confluence.render.RenderType;
- import org.randombits.utils.lang.API;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Qualifier;
- import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext;
- import com.atlassian.confluence.core.BodyContent;
- import com.atlassian.confluence.core.BodyType;
- import com.atlassian.confluence.core.ContentEntityManager;
- import com.atlassian.confluence.core.ContentEntityObject;
- import com.atlassian.confluence.core.ContentPropertyManager;
- import com.atlassian.confluence.core.VersionHistorySummary;
- import com.atlassian.confluence.labels.Label;
- import com.atlassian.confluence.links.OutgoingLink;
- import com.atlassian.confluence.pages.Attachment;
- import com.atlassian.confluence.pages.AttachmentManager;
- import com.atlassian.confluence.search.v2.SearchResult;
- import com.atlassian.confluence.security.Permission;
- import com.atlassian.confluence.util.ExcerptHelper;
- import com.atlassian.confluence.xhtml.api.XhtmlContent;
- import com.atlassian.renderer.links.Link;
- import com.atlassian.renderer.links.UnpermittedLink;
- import com.atlassian.renderer.links.UnresolvedLink;
- import com.atlassian.spring.container.ContainerManager;
- import com.atlassian.user.User;
- /**
- * Looks up values against standard Confluence properties.
- *
- * @author David Peterson
- */
- public abstract class AbstractContentSupplier<T extends ContentEntityObject> extends AbstractEntitySupplier<T> {
- private static final String MAILTO_PREFIX = "mailto:";
-
- private static final Logger LOG = Logger.getLogger( AbstractContentSupplier.class );
- private ContentPropertyManager contentPropertyManager;
- private AttachmentManager attachmentManager;
- private ContentEntityManager contentEntityManager;
-
- private static final ExcerptHelper excerptHelper = new ExcerptHelper();
-
- private RenderAssistant renderAssistant;
-
- private XhtmlContent xhtmlContent;
-
- static {
- ContainerManager.autowireComponent(excerptHelper);
- }
-
- @SupplierKey("version comment")
- @KeyWeight(5)
- @API("1.0.0")
- public String getVersionComment( @KeyValue SearchResult result ) {
- return result.getLastUpdateDescription();
- }
- @SupplierKey("version comment")
- @API("1.0.0")
- public String getVersionComment( @KeyValue T content ) {
- return content.getVersionComment();
- }
- @SupplierKey("attachments")
- @API("1.0.0")
- public List<Attachment> getAttachments( @KeyValue T content ) {
- return attachmentManager.getLatestVersionsOfAttachments( content );
- }
- @SupplierKey("body content")
- @API("1.0.0")
- public BodyContent getBodyContent( @KeyValue T content ) {
- return content.getBodyContent();
- }
- @SupplierKey("body")
- @API("1.0.0")
- public BodyContent getBody( @KeyValue T content ) {
- return content.getBodyContent();
- }
- @SupplierKey("images")
- @API("1.0.0")
- public List<Attachment> getImages( @KeyValue T content ) {
- List<Attachment> attachments = attachmentManager.getLatestVersionsOfAttachments( content );
- List<Attachment> images = new java.util.ArrayList<Attachment>();
- for ( Attachment attachment : attachments ) {
- if ( attachment.getContentType().startsWith( "image/" ) )
- images.add( attachment );
- }
- return images;
- }
- @SupplierKey("version history")
- @API("1.0.0")
- public Iterator<? extends ContentEntityObject> getVersionHistory( @KeyValue T content ) {
- List<VersionHistorySummary> history = getContentEntityManager().getVersionHistorySummaries( content );
- if ( history != null ) {
- //noinspection unchecked
- return (Iterator<? extends ContentEntityObject>) IteratorUtils.transformedIterator( history.iterator(), new Transformer() {
- public Object transform( Object object ) {
- return getContentEntityManager().getById( ( (VersionHistorySummary) object ).getId() );
- }
- } );
- }
- return null;
- }
- @Autowired
- public void setContentPropertyManager( ContentPropertyManager contentPropertyManager ) {
- this.contentPropertyManager = contentPropertyManager;
- }
- private ContentPropertyManager getContentPropertyManager() {
- return contentPropertyManager;
- }
- @Autowired
- public void setContentEntityManager( @Qualifier("contentEntityManager") ContentEntityManager contentEntityManager ) {
- this.contentEntityManager = contentEntityManager;
- }
- private ContentEntityManager getContentEntityManager() {
- return contentEntityManager;
- }
- @SupplierKey("summary")
- @API("1.0.0")
- public String getSummary( @KeyValue T content ) {
- String excerpt = getExcerpt( content );
-
- if ( StringUtils.isBlank( excerpt ) )
- excerpt = createSummary( content.getBodyContent(), 200 );
- return excerpt;
- }
- private String createSummary( BodyContent bodyContent, int maxLength ) {
- if ( bodyContent != null ) {
- BodyType type = bodyContent.getBodyType();
- if ( type == BodyType.WIKI )
- return createWikiSummary( bodyContent.getBody(), maxLength );
- else if ( type == BodyType.XHTML)
- return createRichTextSummary( bodyContent.getBody(), maxLength );
- }
- return bodyContent.getBody();
- }
- // Matches {macros...}, {noformat} and {code} content from wiki markup.
- private static final Pattern STRIP_WIKI_PATTERN = Pattern.compile(
- "(?<!\\\\)(?:\\{(noformat|code)[^\\}]*\\}.*?(?<!\\\\)\\{\\1\\}|\\{[^\\}]+\\})", Pattern.DOTALL );
-
- private static final Pattern AC_TAG_PATTERN = Pattern.compile(
- "(<ac:.+?>|</ac:.+?>)", Pattern.DOTALL );
- private static final Pattern SUMMARY_PATTERN = Pattern.compile( "(.*(?=\\s)).*", Pattern.DOTALL );
- private String createWikiSummary( String content, int maxLength ) {
- if ( content != null )
- return trimString( STRIP_WIKI_PATTERN.matcher( content ).replaceAll( "" ) , maxLength );
-
- return null;
- }
-
- private String createRichTextSummary( String content, int maxLength ) {
- if ( content != null )
- return trimString( stripHtmlTags( stripXhtmlTags( content ) ), maxLength );
-
- return null;
- }
-
- private String stripXhtmlTags( String content ) {
- return AC_TAG_PATTERN.matcher( content ).replaceAll( "" );
- }
-
- private String stripHtmlTags( String content ) {
- if ( content != null )
- return Jsoup.parse( content ).text() ;
-
- return null;
- }
-
- private String trimString( String content, int maxLength ){
- String value = content;
-
- if ( content.length() > maxLength ) {
- // Grab the last complete word the maximum length.
- value = content.substring( 0, maxLength );
- Matcher matcher = SUMMARY_PATTERN.matcher( value );
-
- if ( matcher.matches() )
- value = matcher.group( 1 );
- else
- value = content.substring( 0, maxLength );
- }
-
- // Add ellipses if the summary does not match the original content.
- if ( value.length() < content.length() )
- value = value.trim() + "...";
- return value;
- }
-
- @SupplierKey("outgoing links")
- @API("1.0.0")
- public Set<Link> getOutgoingLinks( @KeyValue T content ) {
- if ( content != null ) {
- @SuppressWarnings("unchecked")
- List<OutgoingLink> outgoingLinks = content.getOutgoingLinks();
- Set<Link> uniqueLinks = new HashSet<Link>();
- Link link;
- String linkText;
- for ( OutgoingLink outLink : outgoingLinks ) {
- String destPageTitle = outLink.getDestinationPageTitle();
- if ( destPageTitle != null && destPageTitle.startsWith( MAILTO_PREFIX ) )
- linkText = outLink.getDestinationPageTitle();
- else
- linkText = outLink.getDestinationSpaceKey() + ":"
- + ( destPageTitle == null ? "" : destPageTitle );
- if ( outLink.getLinkTitle() != null )
- linkText = outLink.getLinkTitle() + "|" + linkText;
- LOG.debug( "resolving outgoing link: '" + linkText + "'" );
- link = getLinkResolver().createLink( content.toPageContext(), linkText );
- if ( link != null && !( link instanceof UnpermittedLink ) && !( link instanceof UnresolvedLink ) ) {
- LOG.debug( "link found: " + link );
- uniqueLinks.add( link );
- }
- }
- return uniqueLinks;
- } else {
- return null;
- }
- }
- @SuppressWarnings("unchecked")
- @SupplierKey("labels")
- @API("1.0.0")
- public Collection<Label> getLabels( @KeyValue T content ) {
- return content.getLabelsForDisplay( AbstractConfluenceSupplier.getCurrentUser() );
- }
- @SupplierKey("excerpt")
- @API("1.0.0")
- public String getExcerpt( @KeyValue T content ) {
- return excerptHelper.getExcerpt(content);
- }
-
- @Override
- protected String findType( T entity ) {
- String type = entity.getType().toLowerCase();
- return getText( type + ".type", type );
- }
- @SupplierKey("incoming links")
- @API("1.0.0")
- public Set<Link> getIncomingLinks( @KeyValue T content ) {
- if ( content != null ) {
- Set<Link> uniquePages = new HashSet<Link>();
- @SuppressWarnings("unchecked")
- List<OutgoingLink> incomingLinks = getLinkManager().getIncomingLinksToContent( content );
- if ( incomingLinks != null ) {
- ContentEntityObject source;
- User user = AbstractConfluenceSupplier.getCurrentUser();
- for ( OutgoingLink outLink : incomingLinks ) {
- source = outLink.getSourceContent();
- if ( getPermissionManager().hasPermission( user, Permission.VIEW, source ) ) {
- Link link = getLinkResolver().createLink( content.toPageContext(), "$" + source.getId() );
- if ( link != null )
- uniquePages.add( link );
- }
- }
- }
- return uniquePages;
- }
- return null;
- }
- @Override
- protected String findIconURL( T entity ) {
- String fileName = findIconFileName( entity );
- if ( fileName == null )
- fileName = getText( "default.icon", null );
- return "/images/icons/" + fileName;
- }
- protected String findIconFileName( T entity ) {
- String type = entity.getType().toLowerCase();
- return getText( type + ".icon", null );
- }
- @Override
- public String findTitle( T entity ) {
- return entity.getTitle();
- }
- @Override
- public String findUrl( T entity ) {
- return entity.getUrlPath();
- }
-
- @Autowired
- public void setRenderAssistant(RenderAssistant renderAssistant) {
- this.renderAssistant = renderAssistant;
- }
-
- @Autowired
- public void getXhtmlContent(XhtmlContent xhtmlContent) {
- this.xhtmlContent = xhtmlContent;
- }
-
- @Autowired
- public void setAttachmentManager( AttachmentManager attachmentManager ) {
- this.attachmentManager = attachmentManager;
- }
- }