/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.structure.menuitem;
import java.util.Collection;
public class MenuItemKeysByPathResolver
{
private static final MenuItemEntity MENUITEM_NOT_FOUND = new MenuItemEntity();
private static final String PATH_SEPARATOR = "/";
private static final String MENUITEM_SEPARATOR = ",";
private MenuItemEntity menuItem;
/**
* @param menuItem menu-item to resolve relative paths from
*/
public MenuItemKeysByPathResolver( MenuItemEntity menuItem )
{
this.menuItem = menuItem;
}
public String getPageKeyByPath( String path )
{
final MenuItemEntity menuItemEntityByPath = getMenuItemEntityByPath( path );
if ( menuItemEntityByPath == MENUITEM_NOT_FOUND )
{
return "";
}
if ( menuItemEntityByPath == null ) // root menu item
{
return "";
}
return menuItemEntityByPath.getKey().toString();
}
public String getPageKeysByPath( String path )
{
final MenuItemEntity menuItemEntityByPath = getMenuItemEntityByPath( path );
if ( menuItemEntityByPath == MENUITEM_NOT_FOUND )
{
return "";
}
final Collection<MenuItemEntity> itemEntityList = getMenuItemChildren( menuItemEntityByPath );
String result = "";
String separator = "";
for ( final MenuItemEntity mi : itemEntityList )
{
result = result + separator + mi.getKey().toString();
separator = MENUITEM_SEPARATOR;
}
return result;
}
/**
* returns children for menu item.
*
* for root folder ( menuItemEntity == null) will return root children.
*
* @param menuItemEntity - menu item
* @return children of menuItemEntity
*/
private Collection<MenuItemEntity> getMenuItemChildren( final MenuItemEntity menuItemEntity )
{
return menuItemEntity == null ? menuItem.getSite().getTopMenuItems() : menuItemEntity.getChildren();
}
/**
* <p>reads page key by menu path </p>
* <p>path may be absolute or relative</p>
* <p/>
* Examples: <br/>
* <p/>
* <code>/</code> - MenuItemEntity of root folder<br/>
* <code>./</code> - MenuItemEntity of current folder<br/>
* <code>fldr</code> - MenuItemEntity of fldr folder in current folder<br/>
* <code>./fldr</code> - MenuItemEntity of fldr folder in current folder<br/>
* <code>../welcome/fldr</code> - more relative path<br/>
* <code>../././welcome/./fldr/../fldr</code> - complex path<br/>
* <p/>
* if parent folder or relative folder does not exist function returns MENUITEM_NOT_FOUND constant
*
* @param path path to page
* @return MenuItemEntity
*/
protected MenuItemEntity getMenuItemEntityByPath( String path )
{
final String[] parts = path.split( PATH_SEPARATOR ); // split works strange. "////" will return ZERO parts !
// currentItemEntity = null for absolute path (root folder) or current menuItem for relative
MenuItemEntity currentItemEntity = parts.length == 0 || "".equals( parts[0] ) ? null : menuItem;
searching:
for ( int num = 0; num < parts.length; num++ )
{
final String part = parts[num];
if ( "".equals( part ) || ".".equals( part ) )
{
// nothing to do with . and empty parts
}
else if ( "..".equals( part ) )
{
// check if system is trying go up from /
if ( currentItemEntity == null ) // already root
{
// do not go up to root - does not have sense
currentItemEntity = MENUITEM_NOT_FOUND;
break; // searching
}
// go up
currentItemEntity = currentItemEntity.getParent();
}
else
{
// something other than . or .. here
Collection<MenuItemEntity> itemEntityList = getMenuItemChildren( currentItemEntity );
for ( MenuItemEntity itemEntity : itemEntityList )
{
if ( part.equalsIgnoreCase( itemEntity.getName() ) )
{
currentItemEntity = itemEntity;
if ( num == parts.length - 1 )
{ // success! found and it is last in path
break searching;
}
else
{
// found and it is not last in path
continue searching;
}
}
}
// did not find matching name in current folder
currentItemEntity = MENUITEM_NOT_FOUND;
break; // searching
}
}
return currentItemEntity;
}
}