voyent
Messages posted by: kdean  XML
Profile for kdean -> Messages posted by kdean [37] Go to Page: 1, 2, 3 Next 
Author Message
I have narrowed this down to a test case. The Immediate_Bug.war file is the final deployed WAR file after Liferay does its thing; the Immediate_Bug_src.zip file is the source.

The test is very simple:

  • Install the portlet.
  • Start network activity monitor.
  • Press the button.
  • Note only one request/response pair in activity monitor.
  • Press the button.
  • Note multiple request/response pairs in activity monitor.
  • Press the button.
  • Note multiple request/response pairs in activity monitor. It seems that the "immediate" setting corrupts further interaction with the portlet.

    This is deployed to GlassFish 3.1.2.2.
  • The Liferay post is here:

    http://www.liferay.com/community/forums/-/message_boards/message/24605920
    I'm trying to track down a problem I'm having with an application. We're seeing some strange behaviour when the "immediate" attribute is set to true on a button.

    Normally, we set the "immediate" attribute on any buttons that cancel the current operation. For obvious reasons, we need to bypass the validation process when any such button is pressed. The flow is basically this:

    Porlet X -> Initial view A -> User selects option -> Selected view B -> User presses "Cancel" -> Returned to view A

    If the "immediate" attribute on the "Cancel" button in view B is left out (or set to false), this is what shows up in the Chrome network monitor (assuming I fill in data that satisfies the validation requirements):

    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway__jsfBridgeAjax=true&_session_manager_WAR_Gateway__facesViewIdResource=%2Fsession%2Flogin.xhtml

    If the "immediate" attribute is set to "true", this is what shows up:

    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway__jsfBridgeAjax=true&_session_manager_WAR_Gateway__facesViewIdResource=%2Fsession%2Flogin.xhtml
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=jsf.js&_session_manager_WAR_Gateway_ln=javax.faces
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=bridge.js&_session_manager_WAR_Gateway_ln=ice.core
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=util%2Face-jquery.js&_session_manager_WAR_Gateway_ln=icefaces.ace
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=compat.js&_session_manager_WAR_Gateway_ln=ice.compat
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=util%2Face-components.js&_session_manager_WAR_Gateway_ln=icefaces.ace
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=icefaces-compat.js&_session_manager_WAR_Gateway_ln=ice.compat
    http://localhost:8080/home?p_p_id=session_manager_WAR_Gateway&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1&_session_manager_WAR_Gateway_javax.faces.resource=util%2Face-menu.js&_session_manager_WAR_Gateway_ln=icefaces.ace

    Note that "localhost" is mapped to an organization site in Liferay.

    The first line in the "immediate" true case is the same as the line in the false case. The subsequent lines have several problems.

    Problem 1: There's no logical reason for all this extra traffic. Pressing the button in the false case sends only a single request/response; pressing the button in the true case isn't doing anything more from an application perspective so the extra traffic is completely unwarranted.

    Problem 2: The first line is properly encoded. The second line has the query parameters escaped, with '&" replaced with "&"; this thoroughly messes things up for Liferay.

    Problem 3: As a result of problem 2, bean management goes to hell in a handbasket. All of our beans use @CustomScoped("#{window}") and tracking the constructor for the bean in view A shows that it's being called multiple times, once for each request other than the first one. Deep inspection of the bean map in the window scope shows that a different window map is being created for each request (hardly surprising given the mess of the URLs). This, naturally, has an impact on application functionality as well as on its performance (the constructors often have side effects such as loading data from the database).

    Although we're using ICEfaces for the bulk of our components, the problem occurs whether we use <ace:pushButton> or <h:commandButton> to cancel view B; it's the "immediate" attribute that is causing the grief.

    At this point, I have no clue as to where the problem lies. I'm cross-posting this problem to the Liferay forums in case it has anything to do with their portlet management.

    The attached file contains HTTP archives of all the traffic.

    This appears to be the same problem as here:

    http://www.icesoft.org/JForum/posts/list/19216.page#sthash.7B7Gx4NN.dpbs
    http://jira.icesoft.org/browse/ICE-7002
    The solution is in the NodeStateMap. In the code below, selectedTreeNode is the currently selected tree node (not necessarily the same as the parent), parentTreeNode is the parent to which the child is being added, and index is the index within the parent's children where the child is being added:

    Code:
     	private void addChild(MutableTreeNode selectedTreeNode, MutableTreeNode parentTreeNode, int index) {
     		BlankTreeNode childTreeNode = new BlankTreeNode(parentTreeNode);
     		parentTreeNode.insert(childTreeNode, index);
     		
     		// Deselect currently selected tree node.
     		nodeStateMap.get(selectedTreeNode).setSelected(false);
     		
     		// Make sure that parent is expanded.
     		nodeStateMap.get(parentTreeNode).setExpanded(true);
     		
     		NodeState childTreeNodeState = new NodeState();
     		
     		childTreeNodeState.setExpansionEnabled(true);
     		childTreeNodeState.setSelectionEnabled(true);
     		childTreeNodeState.setSelected(true);
     		
     		nodeStateMap.put(childTreeNode, childTreeNodeState);
     	}
     
    I have a tree that displays correctly and I can easily navigate through the tree, select a node, and have the display refresh with data associated with the selected node.

    I need the ability to add to the tree. So far, adding a node works fine:

    // This gets the currently selected node.
    MutableTreeNode parentTreeNode = getSelectedTreeNode();

    // A blank tree node is a custom class that displays "<< New >>" in the tree.
    BlankTreeNode childTreeNode = new BlankTreeNode(parentTreeNode);

    // Add the blank tree node to the end of the children.
    parentTreeNode.insert(childTreeNode, parentTreeNode.getChildCount());

    The display refreshes and the new node is present in the tree.

    I have two problems:

    The first is that, if the node being added is the first child, the parent to which it is being added is collapsed. I see '+' indicating that child nodes are available, but I would prefer that the parent be expanded.

    The second problem, and solving this would probably solve the first, is that after adding the node I want the new node to be the selected node. This provides additional visual feedback to the user that they are working on a new entry.

    In my code I have full access to the Tree, the NodeDataModel, and the NodeStateMap. However, I can't find any method that allows me to expand to and select the new child node.

    Any help would be much appreciated.
    Voted. Thanks.
    That doesn't look like it would work, though I may be misunderstanding ICEfaces. First of all, the ValueChangeListener could be fired by something other than the ENTER key (e.g. on blur when tabbing or mousing out of the field). Also, since it's not part of the JSF flow, how do I then direct the user to the "successful login" page?
    I have a simple login form: ace:textEntry for the email address, h:inputSecret for the password, ace:checkBoxButton for "Remember me", ace:pushButton for "OK", and ace:pushButton for "Cancel".

    I would like the user to be able to login by pressing ENTER in the password field. In fact, I would like a general purpose "trigger this button when ENTER is pressed" capability. I cannot, however, find any reference anywhere as to how to do that.

    Any help on this would be much appreciated.
    It's probably going to be too much to create a sample case, but here's the basic outline:

    - create a converter annotated with @FacesConverter (no parameters)

    - put "throw new UnsupportedOperationException()" into each method

    - deploy to a web application that has an "ace:textEntry" component in a form

    - submit the form

    The problem code is in org.icefaces.ace.renderkit.InputRenderer starting at line 130:

    Code:
    	@Override
     	public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
     		UIInput uiInput = (UIInput) component;
     		String value = (String) submittedValue;
     		Converter converter = uiInput.getConverter();
     		
     		//first ask the converter
     		if(converter != null) {
     			return converter.getAsObject(context, uiInput, value);
     		}
     		//Try to guess
     		else {
                 ValueExpression ve = uiInput.getValueExpression("value");
     
                 if(ve != null) {
                     Class<?> valueType = ve.getType(context.getELContext());
                     Converter converterForType = context.getApplication().createConverter(valueType);
     
                     if(converterForType != null) {
                         return converterForType.getAsObject(context, uiInput, value);
                     }
                 }
     		}
     		
     		return value;
     	}
     


    The way the "else" clause is written, it will pick up any unqualified FacesConverter.
    I have a simple converter that I use to translate an ISO language code (e.g. "en", "fr") into its equivalent text in its own language (e.g. "English", "fran├žais"). Because the converter doesn't work on an object, it has a simple "@FacesConverter" annotation with no associated type.

    The "getString" method returns the name of the language and the "getObject" method throws UnsupportedOperationException.

    I have a form with an <ace:textEntry> component. When I submit the form, I get an exception thrown from the converter's getObject() method, even though that converter is not associated with the text entry component. I took a look at the code up the stack trace and it seems that the text entry component is looking at all registered components even though they're not associated with the object.

    Is there a reason for this? I have had to disable this converter for now.
    VICTORY!!!

    I had the following settings in portal-ext.properties:

    request.shared.attributes=MYAPP_SHARED_
    session.shared.attributes=COMPANY_,MYAPP_SHARED_,org.apache.struts.action.LOCALE,PORTLET_RENDER_PARAMETERS_,PUBLIC_RENDER_PARAMETERS_POOL_,USER_

    In essence, I had replaced LIFERAY_SHARED_ with MYAPP_SHARED_. This was fine under Liferay 5.2.3 and ICEfaces 1.8.2, but in hindsight it falls into the category of "Do not meddle in the affairs of wizards, for they are subtle and quick to anger." Replacing those lines with:

    request.shared.attributes=LIFERAY_SHARED_,MYAPP_SHARED_
    session.shared.attributes=COMPANY_,LIFERAY_SHARED_,org.apache.struts.action.LOCALE,PORTLET_RENDER_PARAMETERS_,PUBLIC_RENDER_PARAMETERS_POOL_,USER_,MYAPP_SHARED_

    solved the problem.

    Thank you very much for your time; sorry to have wasted it on this.
    I have good news, of sorts.

    I installed the stock GlassFish.

    I copied the required Liferay dependencies to the domain library.

    I modifed the GlassFish configuration to expand the memory and set a couple of flags required by Liferay.

    I started GlassFish.

    I copied the unmodified Liferay WAR file to the domain autodeploy directory.

    Once Liferay started up, I copied the showcase portlet WAR file to the Liferay autodeploy directory.

    I restarted GlassFish (Liferay throws an exception after the first deployment and won't show the ICEfaces applications in its portlet list).

    I added the Push Button sample to the main page.

    The sample worked.

    Now all I have to do is work through all of my configuration options to figure out which one is causing me the grief. I'll keep you posted.
    I have created the following thread in the Liferay forums:

    http://www.liferay.com/community/forums/-/message_boards/message/17402476

    I know that the ICEfaces and Liferay teams work very closely together; if you could prod someone in Liferay to look at this quickly it would be greatly appreciated.
    I checked for some of the other .js files; they're in the log but not in the HTML either.
    The URL is successfully resolved and I can download the bridge.js file. However, when I examine the HTML output (see one of my previous postings), the URL in question isn't anywhere to be found in the "head" tag.
     
    Profile for kdean -> Messages posted by kdean [37] Go to Page: 1, 2, 3 Next 
    Go to:   
    Powered by JForum 2.1.7ice © JForum Team