All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.servicerocket.confluence.randombits.filtering.confluence.criteria.content.ContentScopeCriterion Maven / Gradle / Ivy

There is a newer version: 2.5.12
Show newest version
/*
 * Copyright (c) 2006, David Peterson
 * 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 "randombits.org" 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 com.servicerocket.confluence.randombits.filtering.confluence.criteria.content;

import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext;
import com.atlassian.confluence.core.ConfluenceEntityObject;
import com.atlassian.confluence.core.ContentEntityObject;
import com.atlassian.confluence.core.SpaceContentEntityObject;
import com.atlassian.confluence.links.linktypes.AbstractContentEntityLink;
import com.atlassian.confluence.pages.Attachment;
import com.atlassian.confluence.pages.Comment;
import com.atlassian.confluence.pages.Page;
import com.atlassian.confluence.search.v2.SearchResult;
import com.atlassian.confluence.spaces.Space;
import com.servicerocket.confluence.randombits.filtering.core.criteria.CriteriaException;
import com.servicerocket.confluence.randombits.filtering.core.criteria.Criterion;
import com.servicerocket.confluence.randombits.filtering.core.criteria.CriterionInterpreter;
import com.servicerocket.confluence.randombits.filtering.core.criteria.SourceCriterion;
import com.servicerocket.confluence.randombits.support.confluence.LinkAssistant;
import com.servicerocket.confluence.randombits.support.core.convert.ConversionAssistant;
import com.servicerocket.confluence.randombits.support.core.convert.ConversionException;

import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;

/**
 * Checks if the supplied object matches the scope criterion.
 *
 * @author David Peterson
 */
public class ContentScopeCriterion implements SourceCriterion {

    public static class Interpreter implements CriterionInterpreter {

        /**
         * This marks the delimitation between the content and the scope.
         */
        public static final char SCOPE_DELIMITER = '>';

        private ContentEntityObject content;

        private final LinkAssistant linkAssistant;
        private final ConversionAssistant conversionAssistant; 
        
        public Interpreter( LinkAssistant linkAssistant, ConversionAssistant conversionAssistant) {
            this( conversionAssistant, linkAssistant, null );
         }

        public Interpreter( ConversionAssistant conversionAssistant, LinkAssistant linkAssistant, ContentEntityObject content ) {
            this.content = content;
            this.linkAssistant = linkAssistant;
            this.conversionAssistant = conversionAssistant; 
        }

        public Criterion createCriterion( String value ) throws CriteriaException {
            int scopeIndex = value.indexOf( SCOPE_DELIMITER );
            EnumSet scope = EnumSet.noneOf( Scope.class );

            if ( scopeIndex >= 0 ) {
                String scopeString = value.substring( scopeIndex + 1 ).trim().toLowerCase();
                value = value.substring( 0, scopeIndex ).trim();

                if ( "ancestors".equals( scopeString ) ) {
                    scope.add( Scope.ANCESTORS );
                } else if ( "children".equals( scopeString ) ) {
                    scope.add( Scope.CHILDREN );
                } else if ( "descendents".equals( scopeString ) || "descendants".equals( scopeString ) ) {
                    scope.add( Scope.DESCENDANTS );
                } else {
                    throw new CriteriaException( "Unsupported scope: " + scopeString );
                }
            } else {
                scope.add( Scope.SELF );
            }

            ContentEntityObject context = null;

            if ( "@self".equals( value ) ) {
                context = this.content;
            } else if ( "@parent".equals( value ) ) {
                if ( content instanceof Page ) {
                    context = ( (Page) content ).getParent();
                } else
                    throw new CriteriaException( "@parent can only be used on pages." );
            } else if ( "@home".equals( value ) ) {
                if ( content instanceof SpaceContentEntityObject ) {
                    Space space = ( (SpaceContentEntityObject) content ).getSpace();
                    if ( space != null )
                        context = space.getHomePage();
                }
            } else {
                ConfluenceEntityObject entity = linkAssistant.getEntityForWikiLink(
                        new DefaultConversionContext( content.toPageContext() ), value );
                if ( entity instanceof ContentEntityObject )
                    context = (ContentEntityObject) entity;
            }

            if ( context != null )
                return new ContentScopeCriterion(conversionAssistant, context, scope );
            else
                throw new CriteriaException( "Unable to locate the specified content: '" + value + "'" );
        }
    }

    public enum Scope {
        SELF, CHILDREN, DESCENDANTS, ANCESTORS
    }

    private ContentEntityObject rootContent;
    private final ConversionAssistant conversionAssistant; 

    private EnumSet scope;

    public ContentScopeCriterion( ConversionAssistant conversionAssistant, ContentEntityObject ceo ) {
        this(conversionAssistant, ceo, Scope.SELF );
    }

    public ContentScopeCriterion( ConversionAssistant conversionAssistant, ContentEntityObject ceo, Scope... scopes ) {
        this(conversionAssistant, ceo, EnumSet.copyOf( Arrays.asList( scopes ) ) );
    }

    public ContentScopeCriterion(ConversionAssistant conversionAssistant, ContentEntityObject ceo, EnumSet scope ) {
        rootContent = ceo;
        this.scope = scope;
        this.conversionAssistant = conversionAssistant; 
    }

    public boolean matches( Object object ) {
    	ConfluenceEntityObject ceo = null;
    	Object obj = object; 

		if (object instanceof SearchResult
				 && conversionAssistant.canConvert(object, ConfluenceEntityObject.class) ) {
	 		try {
	 			obj = conversionAssistant.convert(object, ConfluenceEntityObject.class); 
			} catch (ConversionException e) {
				e.printStackTrace();
			}
		} 
		
		if ( obj instanceof Comment ) {
            ceo = ( (Comment) obj ).getContainer();
        } else if ( obj instanceof Attachment ) {
            ceo = ( (Attachment) obj ).getContainer();
        } else if ( obj instanceof AbstractContentEntityLink ) {
            ceo = ( (AbstractContentEntityLink) obj ).getDestinationContent();
        } else if ( obj instanceof ContentEntityObject ) {
            ceo = (ContentEntityObject) obj;
        } 

        if ( ceo != null ) {
            if ( hasScope( Scope.SELF ) ) {
                if ( rootContent.equals( ceo ) )
                    return true;
            }

            if ( !( scope.size() == 1 && scope.contains( Scope.SELF ) ) && rootContent instanceof Page && ceo instanceof Page ) {
                // there are other scopes set
                Page page = (Page) ceo;

                if ( hasScope( Scope.CHILDREN ) ) {
                    if ( rootContent.equals( page.getParent() ) )
                        return true;
                }

                if ( hasScope( Scope.DESCENDANTS ) ) {
                    if ( isAncestor( page, (Page) rootContent ) )
                        return true;
                }

                if ( hasScope( Scope.ANCESTORS ) ) {
                    if ( isAncestor( (Page) rootContent, page ) )
                        return true;
                }
            }
        }
        return false;
    }

    private boolean hasScope( Scope checkScope ) {
        return scope.contains( checkScope );
    }

    private boolean isAncestor( Page page, Page ancestor ) {
        page = page.getParent();
        while ( page != null && !page.equals( ancestor ) )
            page = page.getParent();

        return page != null;
    }

    @Override
    public String toString() {
        return "{content scope: "
                + rootContent
                + ( scope.size() == 0 ? "" : " >" + ( hasScope( Scope.CHILDREN ) ? " children" : "" )
                + ( hasScope( Scope.DESCENDANTS ) ? " descendents" : "" )
                + ( hasScope( Scope.ANCESTORS ) ? " ancestors" : "" ) ) + "}";
    }

    public Collection getMatchingValues() {
        Set values = new java.util.HashSet();

        if ( rootContent != null && !scope.isEmpty() ) {
            if ( hasScope( Scope.SELF ) ) {
                values.add( rootContent );
            }

            if ( rootContent instanceof Page ) {
                Page page = (Page) rootContent;
                if ( hasScope( Scope.DESCENDANTS ) ) {
                    values.addAll( page.getDescendants() );
                } else if ( hasScope( Scope.CHILDREN ) ) {
                    values.addAll( page.getChildren() );
                }

                if ( hasScope( Scope.ANCESTORS ) ) {
                    values.addAll( page.getAncestors() );
                }
            }
        }

        return values;
    }

    public Weight getWeight() {
        return Weight.MEDIUM;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy