/* * $Id: DefaultViewNode.java,v 1.12.2.1 2007/01/12 19:32:12 idegaweb Exp $ * Created on 14.9.2004 * * Copyright (C) 2004 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.core.view; import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; import javax.faces.application.ViewHandler; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import com.idega.idegaweb.IWMainApplication; import com.idega.util.StringHandler; /** * The default implementation of the ViewNode interface.<br> * * Last modified: $Date: 2007/01/12 19:32:12 $ by $Author: idegaweb $ * * @author <a href="mailto:tryggvil@idega.com">tryggvil</a> * @version $Revision: 1.12.2.1 $ */ public class DefaultViewNode implements ViewNode { private String viewId; private Map children; private ViewHandler viewHandler; private boolean isResourceBased; private boolean isComponentBased; private String resourceUri; private ViewNode parent; private Collection roles; private IWMainApplication iwma; protected static String SLASH="/"; static String NODE_SEPARATOR=SLASH; private boolean isRendered = true; private String name; private KeyboardShortcut keyboardShortcut; /** * @param viewId the ViewId of this node (must be unique under its parent) * @param parent the Parent of this node. This node will be added as a child under its parent implicitly by this constructor */ public DefaultViewNode(String viewId,ViewNode parent) { this.setViewId(viewId); setParent(parent); } /** * @param iwma the IWMainApplication instance to register to this ViewNode */ public DefaultViewNode(IWMainApplication iwma) { this.setIWMainApplication(iwma); } public String getViewId() { return this.viewId; } public void setViewId(String viewId){ this.viewId=viewId; } protected Map getChildrenMap(){ if(this.children==null){ this.children=new HashMap(); } return this.children; } public String getURI(){ StringBuffer path = new StringBuffer(NODE_SEPARATOR); String contextURI = getIWMainApplication().getApplicationContextURI(); ViewNode view = this; while(view!=null){ String viewId = view.getViewId(); if(!viewId.equals(NODE_SEPARATOR)){ //path.insert(0,NODE_SEPARATOR); path.insert(0,view.getViewId()); path.insert(0,NODE_SEPARATOR); } view = view.getParent(); } if(contextURI != null ){ if(!contextURI.equals(SLASH)){ path.insert(0,contextURI); } } return path.toString(); } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#addChildViewNode(com.idega.faces.view.ViewNode) */ public void addChildViewNode(ViewNode node) { getChildrenMap().put(node.getViewId(),node); } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getChildren() */ public Collection getChildren() { return getChildrenMap().values(); } /** * This method retorns a child that is a direct child of this instance (not a child of a child). * This method assumes that childId does not contain the / (SLASH) character. * @param childId * @return */ protected ViewNode getDirectChild(String realChildId){ ViewNode theReturn = (ViewNode)getChildrenMap().get(realChildId); if(theReturn==null){ theReturn = loadChild(realChildId); if(theReturn!=null){ getChildrenMap().put(realChildId,theReturn); return theReturn; } } else{ return theReturn; } return null; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getChild(java.lang.String) */ public ViewNode getChild(String childViewId) { if(childViewId!=null){ String realChildId=childViewId; String childrenOfChildId = null; if(childViewId.indexOf(SLASH)!=-1){ String[] childArray = parseChildren(childViewId); realChildId=childArray[0]; if(childArray.length==2){ //In this case the '/' character must have been somewhere in the middle of the string //If however this is NOT case the '/' must have been in the beginning of the string, and thus only one element in the array. childrenOfChildId = childArray[1]; } } ViewNode directChild = getDirectChild(realChildId); if(directChild!=null){ if(childrenOfChildId!=null){ return directChild.getChild(childrenOfChildId); } else{ return directChild; } } } return this; /* if(newChildViewId.equals(StringHandler.SLASH)){ return this; } elseif(childViewId!=null){ int slashIndex = childViewId.indexOf(StringHandler.SLASH); if(childViewId.equals(StringHandler.SLASH)){ return this; } else if (slashIndex!=-1){ //String[] split = StringHandler.breakDownURL(childViewId); String[] split; if(slashIndex==0){ //This case is when the '/' is in the beginning of the string. //This results that the array returned out of s.split(s,i) returns an empty string as the first result: String[] firstSplit = split= childViewId.split(StringHandler.SLASH,3); //So we shift the results that we want if(firstSplit.length==3){ if(firstSplit[2].equals("")){ // In this case there are empty strings in indexes 0 and 2 split = new String[1]; split[0]=firstSplit[1]; } else{ split = new String[2]; split[0]=firstSplit[1]; split[1]=firstSplit[2]; } } else if(firstSplit.length==2){ split = new String[1]; split[0]=firstSplit[1]; } else{ split = new String[2]; split[0]=firstSplit[1]; split[1]=firstSplit[2]; } } else{ split= childViewId.split(StringHandler.SLASH,2); } int length = split.length; if(length==2){ //In this case the '/' character must have been somewhere in the middle of the string String prefix = split[0]; String rest = split[1]; ViewNode child = (ViewNode)getChildrenMap().get(prefix); if(child==null){ //Instead of returning null we return this if no chid is found return this; } else{ return child.getChild(rest); } } else if(length==1){ String prefix = split[0]; //In this case the '/' must have been in the beginning of the string ViewNode theReturn = (ViewNode)getChildrenMap().get(prefix); if(theReturn==null){ //Instead of returning null we return this if no chid is found theReturn = this; } return theReturn; } } else{ ViewNode child = (ViewNode)getChildrenMap().get(childViewId); if(child==null){ //Instead of returning null we return this. child=this; } return child; } } */ } /** * This method is called if a node instance is not found in the map. * This can be overrided in suclasses and can be a relatively expensive operation, * therefore is only called the first time (lazy-loading) when getting the child and after that accessed from the map instance variable. */ protected ViewNode loadChild(String childId){ return null; } /** * This method parses the childViewId with the first separating slash found.<br> * This method should return either an array of size 1 or 2 depending on if the '/' is in the middle of the string or in the beginning. * @param childViewId * @return */ protected String[] parseChildren(String childViewId){ if(childViewId!=null){ int slashIndex = childViewId.indexOf(StringHandler.SLASH); //if(childViewId.equals(StringHandler.SLASH)){ // return this; //} if (slashIndex!=-1){ //String[] split = StringHandler.breakDownURL(childViewId); String[] split; if(slashIndex==0){ //This case is when the '/' is in the beginning of the string. //This results that the array returned out of s.split(s,i) returns an empty string as the first result: String[] firstSplit = split= childViewId.split(StringHandler.SLASH,3); //So we shift the results that we want if(firstSplit.length==3){ if(firstSplit[2].equals("")){ //In this case there are empty strings in indexes 0 and 2 split = new String[1]; split[0]=firstSplit[1]; } else{ split = new String[2]; split[0]=firstSplit[1]; split[1]=firstSplit[2]; } } else if(firstSplit.length==2){ split = new String[1]; split[0]=firstSplit[1]; } else{ split = new String[2]; split[0]=firstSplit[1]; split[1]=firstSplit[2]; } } else{ split= childViewId.split(StringHandler.SLASH,2); } //int length = split.length; return split; /* if(length==2){ //In this case the '/' character must have been somewhere in the middle of the string String prefix = split[0]; String rest = split[1]; //ViewNode child = (ViewNode)getChildrenMap().get(prefix); //if(child==null){ // //Instead of returning null we return this if no chid is found // return this; //} //else{ // return child.getChild(rest); //} return prefix; } else if(length==1){ String prefix = split[0]; //In this case the '/' must have been in the beginning of the string //ViewNode theReturn = (ViewNode)getChildrenMap().get(prefix); //if(theReturn==null){ // //Instead of returning null we return this if no chid is found // theReturn = this; // //} //return theReturn; return prefix; }*/ } } return null; } /** * If no special Viewhandler is set then this method returns * the ViewHandler from the parent ViewNode */ public ViewHandler getViewHandler() { if(this.viewHandler==null){ ViewNode parent = getParent(); if(parent!=null){ return parent.getViewHandler(); } } return this.viewHandler; } public void setViewHandler(ViewHandler viewHandler) { this.viewHandler=viewHandler; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#isJSP() */ public boolean isResourceBased() { return this.isResourceBased; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#isCBP() */ public boolean isComponentBased() { return this.isComponentBased; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getJSPURI() */ public String getResourceURI() { return this.resourceUri; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getComponentClass() */ public UIComponent createComponent(FacesContext context) { //return componentClass; return null; } /** * If no special roles are set then this method returns * the roles from the parent ViewNode */ public Collection getAuthorizedRoles() { if(this.roles==null){ ViewNode parent = getParent(); if(parent!=null){ return parent.getAuthorizedRoles(); } } return this.roles; } public void setAuthorizedRoles(Collection coll){ this.roles=coll; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getIcon() */ public Icon getIcon() { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getLocalizedName(java.util.Locale) */ public String getLocalizedName(Locale locale) { return this.getViewId(); } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getName() */ public String getName() { if(this.name==null){ return StringHandler.firstCharacterToUpperCase(getViewId()); } else{ return this.name; } } /** * <p> * This method supports setting the name as a JSF ValueBinding (that can be localized) * </p> * @param name */ public void setName(String name){ this.name=name; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getKeyboardShortcut() */ public KeyboardShortcut getKeyboardShortcut() { return this.keyboardShortcut; } /** * @param keyboardShortcut The keyboardShortcut to set. */ public void setKeyboardShortcut(KeyboardShortcut keyboardShortcut) { this.keyboardShortcut = keyboardShortcut; } /* (non-Javadoc) * @see com.idega.faces.view.ViewNode#getToolTip(java.util.Locale) */ public ToolTip getToolTip(Locale locale) { // TODO Auto-generated method stub return null; } /** * @param isCBP The isCBP to set. */ public void setComponentBased(boolean isCBP) { this.isComponentBased = isCBP; } /** * @param isJSP The isJSP to set. */ public void setResourceBased(boolean isJSP) { this.isResourceBased = isJSP; } /** * @param jspUri The jspUri to set. */ public void setJspUri(String jspUri) { this.setResourceBased(true); this.resourceUri = jspUri; } /** * @return Returns the parent. */ public ViewNode getParent() { return this.parent; } /** * @param parent The parent to set. */ public void setParent(ViewNode parent) { parent.addChildViewNode(this); this.parent = parent; } /** * If no special IWMainApplication instance is set then this method returns * the IWMainApplication from the parent ViewNode */ public IWMainApplication getIWMainApplication() { if(this.iwma==null){ DefaultViewNode parent = (DefaultViewNode)getParent(); if(parent!=null){ return parent.getIWMainApplication(); } } return this.iwma; } /** * @param iwma The iwma to set. */ public void setIWMainApplication(IWMainApplication iwma) { this.iwma = iwma; } /** * @return Returns the isRendered. */ public boolean isVisibleInMenus() { return this.isRendered; } /** * @param isRendered The isRendered to set. */ public void setVisibleInMenus(boolean isRendered) { this.isRendered = isRendered; } }