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

net.sf.ahtutils.jsf.menu.MenuFactory Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package net.sf.ahtutils.jsf.menu;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.sf.ahtutils.exception.ejb.UtilsNotFoundException;
import net.sf.ahtutils.xml.access.Access;
import net.sf.ahtutils.xml.access.Category;
import net.sf.ahtutils.xml.access.View;
import net.sf.ahtutils.xml.navigation.Menu;
import net.sf.ahtutils.xml.navigation.MenuItem;
import net.sf.ahtutils.xml.navigation.UrlMapping;
import net.sf.ahtutils.xml.status.Lang;
import net.sf.ahtutils.xml.xpath.AccessXpath;
import net.sf.ahtutils.xml.xpath.NavigationXpath;
import net.sf.exlp.util.exception.ExlpXpathNotFoundException;
import net.sf.exlp.util.exception.ExlpXpathNotUniqueException;

import org.jgrapht.DirectedGraph;
import org.jgrapht.alg.DijkstraShortestPath;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MenuFactory
{
	final static Logger logger = LoggerFactory.getLogger(MenuFactory.class);
	
	private String lang;
	private String contextRoot;
	
	public void setContextRoot(String contextRoot) {this.contextRoot = contextRoot;}

	private Access access;
	private boolean noRestrictions;
	private Map mapViewAllowed;
	private Map translationsMenu,translationsAccess;
	private Map mapView;
	private Map mapMenuItems;
	
	private String rootNode;
	private DirectedGraph graph;
	
	private int alwaysUpToLevel;
	
	public MenuFactory(Menu menu,String lang){this(menu,null,lang, UUID.randomUUID().toString(),true);}
	public MenuFactory(Menu menu,String lang, String rootNode){this(menu,null,lang,rootNode,true);}	
	public MenuFactory(Menu menu, Access access,String lang){this(menu,access,lang, UUID.randomUUID().toString(),false);}
	public MenuFactory(Menu menu, Access access,String lang, String rootNode){this(menu,access,lang, rootNode,false);}
	public MenuFactory(Menu menu, Access access,String lang, String rootNode, boolean noRestrictions)
	{

		this.access=access;
		this.lang=lang;
		this.rootNode=rootNode;
		this.noRestrictions=noRestrictions;
		translationsMenu = new Hashtable();
		mapMenuItems = new Hashtable();
		processMenu(menu);
		
		if(logger.isTraceEnabled())
		{
			
			logger.info("Graph: "+graph);
			logger.info("mapMenuItems.size()"+mapMenuItems.size());
		}
		
		mapView = new Hashtable();
		translationsAccess = new Hashtable();
		if(access!=null){createAccessMaps();}
		alwaysUpToLevel = 1;
	}
	
	private void processMenu(Menu menu)
	{
		graph = new DefaultDirectedGraph(DefaultEdge.class);
		graph.addVertex(rootNode);
		
		logger.trace("Added Root: "+rootNode);
	     	
		for(MenuItem mi : menu.getMenuItem())
		{
			processMenuItem(rootNode,mi);
		}
	}
	
	private void processMenuItem(String parentNode, MenuItem mi)
	{
		graph.addVertex(mi.getCode());
		graph.addEdge(parentNode, mi.getCode());
		
		logger.trace("Added Vertex: "+mi.getCode());
		
		if(mi.isSetLangs())
		{
			for(Lang l : mi.getLangs().getLang())
			{
				if(l.getKey().equals(lang)){translationsMenu.put(mi.getCode(), l.getTranslation());}
			}
		}
		for(MenuItem miChild : mi.getMenuItem())
		{
			processMenuItem(mi.getCode(),miChild);
		}
		mi.getMenuItem().clear();
		mapMenuItems.put(mi.getCode(), mi);
	}
	
	public void setAlwaysUpToLevel(int alwaysUpToLevel) {this.alwaysUpToLevel = alwaysUpToLevel;}
	
	private void createAccessMaps()
	{
		for(Category c : access.getCategory())
		{
			if(c.isSetViews())
			{
				for(View v : c.getViews().getView())
				{
					mapView.put(v.getCode(), v);
					if(v.isSetLangs())
					{
						for(Lang l : v.getLangs().getLang())
						{
							if(l.getKey().equals(lang)){translationsAccess.put(v.getCode(), l.getTranslation());}
						}
					}
				}
			}
		}
	}
	
	public Menu build()
	{
		noRestrictions=true;
		return build(null,rootNode);
	}
	public Menu build(String codeCurrent) {return build(null,codeCurrent);}
	public Menu build(Map mapViewAllowed) {return build(mapViewAllowed,rootNode);}
	public Menu build(Map mapViewAllowed, String codeCurrent){return build(mapViewAllowed,codeCurrent,false);}
	public Menu build(Map mapViewAllowed, String codeCurrent, boolean isLoggedIn)
	{
		logger.trace("Building ("+rootNode+"): "+codeCurrent);
		this.mapViewAllowed=mapViewAllowed;
		Menu result = new Menu();
		
		try {result.getMenuItem().addAll(processChilds(1,rootNode,codeCurrent,isLoggedIn));}
		catch (UtilsNotFoundException e) {logger.warn(e.getMessage());}
		
		return result;
	}
	
	private List processChilds(int level, String node, String codeCurrent, boolean isLoggedIn) throws UtilsNotFoundException
	{
		List result = new ArrayList();
		
		Iterator iterator = graph.outgoingEdgesOf(node).iterator();
		while(iterator.hasNext())
		{
			DefaultEdge edge = iterator.next();
			MenuItem miAdd = null;
			MenuItem mi = mapMenuItems.get(graph.getEdgeTarget(edge));
			if(mi.isSetView())
			{
				if(!mapView.containsKey(mi.getView().getCode())){throw new UtilsNotFoundException("No view with code="+mi.getView().getCode());}
				View view = mapView.get(mi.getView().getCode());
				if(noRestrictions
						|| view.isPublic()
						|| (view.isSetOnlyLoginRequired() && view.isOnlyLoginRequired() && isLoggedIn)
						|| (mapViewAllowed!=null && mapViewAllowed.containsKey(mi.getView().getCode()) && mapViewAllowed.get(mi.getView().getCode())))
				{
					miAdd = processItem(mi,codeCurrent,view);
				}
			}
			else {miAdd = processItem(mi,codeCurrent,null);}
			if(miAdd!=null)
			{
				if(mi.getCode().equals(codeCurrent))
				{
					miAdd.setActive(true);
				}
				else{miAdd.setActive(false);}
				
				boolean currentIsChild = false;
				
				DijkstraShortestPath dsp;
				List path = null;
				
				try
				{
					dsp = new DijkstraShortestPath(graph, mi.getCode(), codeCurrent);
					path = dsp.getPathEdgeList();
				}
				catch (IllegalArgumentException e)
				{
					logger.error("Error in graph from "+mi.getCode()+" to "+codeCurrent);
					logger.error(e.getMessage());
				}
				
				if(path!=null)
				{
					currentIsChild = true;
					miAdd.setActive(true);
				}
				
				if(level0){sbLabel.append(" ");}
			sbLabel.append(viewCode.getLabel());	
		}
		return sbLabel.toString();
	}
	
	private String getHrefFromViews(View viewCode)
	{
		try
		{
			View view = AccessXpath.getView(access, viewCode.getCode());
			if(view.isSetNavigation() && view.getNavigation().isSetUrlMapping())
			{
				UrlMapping urlMapping = view.getNavigation().getUrlMapping();
				StringBuffer sb = new StringBuffer();
				if(contextRoot!=null)
				{
					sb.append("/").append(contextRoot);
				}
				if(urlMapping.isSetUrl())
				{
					
					sb.append(urlMapping.getUrl());
					if(viewCode.isSetUrlParameter()){sb.append(viewCode.getUrlParameter());}
				}
				else{sb.append(urlMapping.getValue());}
				return sb.toString();
			}
		}
		catch (ExlpXpathNotFoundException e) {}
		catch (ExlpXpathNotUniqueException e) {}
		return "#";
	}
	
	public void removeChilds(String dynamicRoot, String dynKey)
	{
		Iterator iterator = graph.outgoingEdgesOf(dynamicRoot).iterator();
		List list = new ArrayList();
		while(iterator.hasNext())
		{
			DefaultEdge edge = iterator.next();
			String target = graph.getEdgeTarget(edge);
			if(target.startsWith(dynKey))
			{
				list.add(edge);
			}
		}
		graph.removeAllEdges(list);
	}
	
	private void removeEdgeToTemplate(String dynamicRoot, String templateNode)
	{
		Iterator iterator = graph.getAllEdges(dynamicRoot, templateNode).iterator();
		List list = new ArrayList();
		while(iterator.hasNext()){list.add(iterator.next());}
		graph.removeAllEdges(list);
	}
	
	public void addDynamicNodes(Menu dynamicMenu)
	{
		for(MenuItem mi : dynamicMenu.getMenuItem())
		{
			removeEdgeToTemplate(dynamicMenu.getCode(), mi.getView().getCode());
			
			graph.addVertex(mi.getCode());
			graph.addEdge(dynamicMenu.getCode(), mi.getCode());
			
			mapMenuItems.put(mi.getCode(), mi);
		}
	}
	
	public List breadcrumb(String code){return breadcrumb(false,code);}
	public List breadcrumb(boolean withRoot, String code)
	{
		List result = new ArrayList();
		
		DijkstraShortestPath dsp = new DijkstraShortestPath(graph,rootNode, code);
		List path = dsp.getPathEdgeList();
		if(path.size()>0)
		{
			result.add(mapMenuItems.get(graph.getEdgeSource(path.get(0))));
		}
		for(DefaultEdge de : path)
		{
			String src = graph.getEdgeTarget(de);
			result.add(mapMenuItems.get(src));
		}
		if(!withRoot){result.remove(0);}
		return result;
	}
	
	public MenuItem subMenu(Menu menu, String code)
	{
		MenuItem result;
		try {result = NavigationXpath.getMenuItem(menu, code);}
		catch (ExlpXpathNotFoundException e) {result = new MenuItem();}
		catch (ExlpXpathNotUniqueException e) {result = new MenuItem();}
		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy