Skip to content

Instantly share code, notes, and snippets.

@trajano
Created March 18, 2014 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trajano/9626235 to your computer and use it in GitHub Desktop.
Save trajano/9626235 to your computer and use it in GitHub Desktop.
NonRelativizingDecorationModelInheritanceAssembler
package net.trajano.maven.doxia.site.decoration.inheritance;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.doxia.site.decoration.Banner;
import org.apache.maven.doxia.site.decoration.Body;
import org.apache.maven.doxia.site.decoration.DecorationModel;
import org.apache.maven.doxia.site.decoration.LinkItem;
import org.apache.maven.doxia.site.decoration.Logo;
import org.apache.maven.doxia.site.decoration.Menu;
import org.apache.maven.doxia.site.decoration.MenuItem;
import org.apache.maven.doxia.site.decoration.inheritance.DecorationModelInheritanceAssembler;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* A copy of
* {@link org.apache.maven.doxia.site.decoration.inheritance.DefaultDecorationModelInheritanceAssembler}
* where the methods that would perform relativization have been changed not to
* perform any relativization.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
*/
@Component( role = DecorationModelInheritanceAssembler.class )
public class NonRelativizingDecorationModelInheritanceAssembler
implements DecorationModelInheritanceAssembler
{
/** {@inheritDoc} */
public void assembleModelInheritance( String name, DecorationModel child, DecorationModel parent,
String childBaseUrl, String parentBaseUrl )
{
System.out.println("HERE!!!!" + name);
// cannot inherit from null parent.
if ( parent == null )
{
return;
}
URLContainer urlContainer = new URLContainer( parentBaseUrl, childBaseUrl );
if ( child.getBannerLeft() == null && parent.getBannerLeft() != null )
{
child.setBannerLeft( parent.getBannerLeft().clone());
rebaseBannerPaths( child.getBannerLeft(), urlContainer );
}
if ( child.getBannerRight() == null && parent.getBannerRight() != null)
{
child.setBannerRight( parent.getBannerRight().clone());
rebaseBannerPaths( child.getBannerRight(), urlContainer );
}
if ( child.isDefaultPublishDate() && parent.getPublishDate() != null )
{
child.setPublishDate( parent.getPublishDate().clone());
}
if ( child.isDefaultVersion() && parent.getVersion() != null )
{
child.setVersion( parent.getVersion().clone());
}
if ( child.getSkin() == null && parent.getSkin() != null )
{
child.setSkin( parent.getSkin().clone());
}
child.setPoweredBy( mergePoweredByLists( child.getPoweredBy(), parent.getPoweredBy(), urlContainer ) );
if ( parent.getLastModified() > child.getLastModified() )
{
child.setLastModified( parent.getLastModified() );
}
assembleBodyInheritance( name, child, parent, urlContainer );
assembleCustomInheritance( child, parent );
}
/** {@inheritDoc} */
public void resolvePaths( final DecorationModel decoration, final String baseUrl )
{
if ( baseUrl == null )
{
return;
}
if ( decoration.getBannerLeft() != null )
{
relativizeBannerPaths( decoration.getBannerLeft(), baseUrl );
}
if ( decoration.getBannerRight() != null )
{
relativizeBannerPaths( decoration.getBannerRight(), baseUrl );
}
for ( Logo logo : decoration.getPoweredBy() )
{
relativizeLogoPaths( logo, baseUrl );
}
if ( decoration.getBody() != null )
{
for ( LinkItem linkItem : decoration.getBody().getLinks() )
{
relativizeLinkItemPaths( linkItem, baseUrl );
}
for ( LinkItem linkItem : decoration.getBody().getBreadcrumbs() )
{
relativizeLinkItemPaths( linkItem, baseUrl );
}
for ( Menu menu : decoration.getBody().getMenus() )
{
relativizeMenuPaths( menu.getItems(), baseUrl );
}
}
}
/**
* Resolves all relative paths between the elements in a banner. The banner element might contain relative paths
* to the oldBaseUrl, these are changed to the newBannerUrl.
*
* @param banner
* @param baseUrl
*/
private void relativizeBannerPaths( final Banner banner, final String baseUrl )
{
// banner has been checked to be not null, both href and src may be empty or null
banner.setHref( relativizeLink( banner.getHref(), baseUrl ) );
banner.setSrc( relativizeLink( banner.getSrc(), baseUrl ) );
}
private void rebaseBannerPaths( final Banner banner, final URLContainer urlContainer )
{
if ( banner.getHref() != null ) // it may be empty
{
banner.setHref( rebaseLink( banner.getHref(), urlContainer ) );
}
if ( banner.getSrc() != null )
{
banner.setSrc( rebaseLink( banner.getSrc(), urlContainer ) );
}
}
private void assembleCustomInheritance( final DecorationModel child, final DecorationModel parent )
{
if ( child.getCustom() == null )
{
child.setCustom( parent.getCustom() );
}
else
{
child.setCustom( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) child.getCustom(), (Xpp3Dom) parent.getCustom() ) );
}
}
private void assembleBodyInheritance( final String name, final DecorationModel child, final DecorationModel parent,
final URLContainer urlContainer )
{
Body cBody = child.getBody();
Body pBody = parent.getBody();
if ( cBody != null || pBody != null )
{
if ( cBody == null )
{
cBody = new Body();
child.setBody( cBody );
}
if ( pBody == null )
{
pBody = new Body();
}
if ( cBody.getHead() == null )
{
cBody.setHead( pBody.getHead() );
}
else
{
cBody.setHead( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) cBody.getHead(), (Xpp3Dom) pBody.getHead() ) );
}
cBody.setLinks( mergeLinkItemLists( cBody.getLinks(), pBody.getLinks(), urlContainer, false ) );
if ( cBody.getBreadcrumbs().isEmpty() && !pBody.getBreadcrumbs().isEmpty() )
{
LinkItem breadcrumb = new LinkItem();
breadcrumb.setName( name );
breadcrumb.setHref( "" );
cBody.getBreadcrumbs().add( breadcrumb );
}
cBody.setBreadcrumbs( mergeLinkItemLists( cBody.getBreadcrumbs(), pBody.getBreadcrumbs(), urlContainer,
true ) );
cBody.setMenus( mergeMenus( cBody.getMenus(), pBody.getMenus(), urlContainer ) );
if ( cBody.getFooter() == null && pBody.getFooter() != null )
{
cBody.setFooter( pBody.getFooter() );
}
}
}
private List<Menu> mergeMenus( final List<Menu> childMenus, final List<Menu> parentMenus,
final URLContainer urlContainer )
{
List<Menu> menus = new ArrayList<Menu>( childMenus.size() + parentMenus.size() );
for ( Menu menu : childMenus )
{
menus.add( menu );
}
int topCounter = 0;
for ( Menu menu : parentMenus )
{
if ( "top".equals( menu.getInherit() ) )
{
final Menu clone = menu.clone();
rebaseMenuPaths( clone.getItems(), urlContainer );
menus.add( topCounter, clone );
topCounter++;
}
else if ( "bottom".equals( menu.getInherit() ) )
{
final Menu clone = menu.clone();
rebaseMenuPaths( clone.getItems(), urlContainer );
menus.add( clone );
}
}
return menus;
}
private void relativizeMenuPaths( final List<MenuItem> items, final String baseUrl )
{
for ( MenuItem item : items )
{
relativizeLinkItemPaths( item, baseUrl );
relativizeMenuPaths( item.getItems(), baseUrl );
}
}
private void rebaseMenuPaths( final List<MenuItem> items, final URLContainer urlContainer )
{
for ( MenuItem item : items )
{
rebaseLinkItemPaths( item, urlContainer );
rebaseMenuPaths( item.getItems(), urlContainer );
}
}
private void relativizeLinkItemPaths( final LinkItem item, final String baseUrl )
{
item.setHref( relativizeLink( item.getHref(), baseUrl ) );
}
private void rebaseLinkItemPaths( final LinkItem item, final URLContainer urlContainer )
{
item.setHref( rebaseLink( item.getHref(), urlContainer ) );
}
private void relativizeLogoPaths( final Logo logo, final String baseUrl )
{
logo.setImg( relativizeLink( logo.getImg(), baseUrl ) );
relativizeLinkItemPaths( logo, baseUrl );
}
private void rebaseLogoPaths( final Logo logo, final URLContainer urlContainer )
{
logo.setImg( rebaseLink( logo.getImg(), urlContainer ) );
rebaseLinkItemPaths( logo, urlContainer );
}
private List<LinkItem> mergeLinkItemLists( final List<LinkItem> childList, final List<LinkItem> parentList,
final URLContainer urlContainer, boolean cutParentAfterDuplicate )
{
List<LinkItem> items = new ArrayList<LinkItem>( childList.size() + parentList.size() );
for ( LinkItem item : parentList )
{
if ( !items.contains( item ) && !childList.contains( item ) )
{
final LinkItem clone = item.clone();
rebaseLinkItemPaths( clone, urlContainer );
items.add( clone );
}
else if ( cutParentAfterDuplicate )
{
// if a parent item is found in child, ignore next items (case for breadcrumbs)
// merge ( "B > E", "A > B > C > D" ) -> "A > B > E" (notice missing "C > D")
// see http://jira.codehaus.org/browse/DOXIASITETOOLS-62
break;
}
}
for ( LinkItem item : childList )
{
if ( !items.contains( item ) )
{
items.add( item );
}
}
return items;
}
private List<Logo> mergePoweredByLists( final List<Logo> childList, final List<Logo> parentList,
final URLContainer urlContainer )
{
List<Logo> logos = new ArrayList<Logo>( childList.size() + parentList.size() );
for ( Logo logo : parentList )
{
if ( !logos.contains( logo ) )
{
final Logo clone = logo.clone();
rebaseLogoPaths( clone, urlContainer );
logos.add( clone );
}
}
for ( final Logo logo : childList )
{
if ( !logos.contains( logo ) )
{
logos.add( logo );
}
}
return logos;
}
/**
* Returns the original link. Does not perform any relativization.
*
* @param link
* link to relativize, but returned as-is.
* @param urlContainer
* URL Container unused
* @return the original link
*/
private String rebaseLink(final String link, final URLContainer urlContainer) {
return link;
}
/**
* Returns the original link. Does not perform any relativization.
*
* @param link
* link to relativize, but returned as-is.
* @param baseUri
* base URI unused
* @return the original link
*/
private String relativizeLink(final String link, final String baseUri) {
return link;
}
/**
* Contains an old and a new path.
*/
private final class URLContainer
{
private final String oldPath;
private final String newPath;
/**
* Construct a URLContainer.
*
* @param oldPath the old path.
* @param newPath the new path.
*/
public URLContainer( final String oldPath, final String newPath )
{
this.oldPath = oldPath;
this.newPath = newPath;
}
/**
* Get the new path.
*
* @return the new path.
*/
public String getNewPath()
{
return this.newPath;
}
/**
* Get the old path.
*
* @return the old path.
*/
public String getOldPath()
{
return this.oldPath;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment