0

I have got this simpe composite component:

    <!-- INTERFACE -->
<cc:interface>
    <cc:attribute name="username" required="true" type="java.lang.String"/>
    <cc:attribute name="password" required="true" type="java.lang.String"/>
    <cc:editableValueHolder name="input" targets="username password"/>
    <cc:attribute name="validator" method-signature=
                  "void Action(javax.faces.context.FacesContext, 
                  javax.faces.component.UIComponent,Object)"
                  required="true"/>
</cc:interface>

<!-- IMPLEMENTATION -->
<cc:implementation>
    <h:panelGrid columns="3" styleClass="components" cellpadding="5px">
        <h:outputText value="#{msg['login.username']}"/>
        <h:inputText id="username" value="#{cc.attrs.username}" required="true"/>
        <h:message styleClass="error" for="username"/>
        <h:outputText value="#{msg['login.password']}"/>
        <h:inputSecret id="password" value="#{cc.attrs.password}" 
                       validator="#{cc.attrs.validator}" required="true"/>
        <h:message styleClass="error" for="password"/>
        <h:commandButton value="#{msg['login.confirm']}"/>
    </h:panelGrid>
</cc:implementation>

I am using it this way (all inside a h:form tag of course):

<imp:loginComponent username="#{databaseManager.username}" 
                            password="#{databaseManager.password}"
                            validator="#{databaseManager.validator}" >
        </imp:loginComponent>

Here you can see my validation method:

 public void validator(FacesContext context, UIComponent component, Object value)
        throws ValidatorException {
    // ziskani username a password komponent
    UIInput passwordComponent = (UIInput) component;
    UIInput usernameComponent = ((UIInput) component.findComponent("username"));
    // az do teto chvile byl vstup validni?
    if (usernameComponent.isValid() && passwordComponent.isValid()) {
        // validace proti DB
        String username = usernameComponent.getValue().toString();
        String password = value.toString();
        if (!userRecordFacade.authorizedAcces(username, password)) {
            System.out.println("blbe");
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", null);
            throw new ValidatorException(message);
        }
    }
}

Everything works fine until I thwor the ValidatorException. There is no exception but some strange message in h:message by password input: /login.xhtml @16,75 validator="#{databaseManager.validator}": The class 'com.dusek.DatabaseManager' does not have the property 'validator'.

How is it possible? If the method does not throw the ValidatorException, it is good. But this is very bad behaviour, I mean :-).

Could you tell me some advice? Thanks.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Petr Dušek
  • 627
  • 4
  • 12
  • 26
  • I know, that it is possible to make some "application-validation" (http://www.ibm.com/developerworks/library/j-jsf3/), but I am afraid, it is not semantically right. – Petr Dušek Aug 27 '13 at 12:32
  • I can't explain the problem off top of head right now as I've never used this approach and I'm not in a mood to recreate and debug it locally, but I can at least tell that this is a strange approach. You should be doing like this: http://stackoverflow.com/a/10874531. Also, the choice for a composite component in this design is somewhat strange as it binds ultimately to multiple properties in the model while a proper composite should be bound to only one property in the model. See also http://stackoverflow.com/a/6822269. A composite is essentially the wrong tool for the job you have in mind. – BalusC Aug 27 '13 at 12:36
  • But there is still one trouble: I would like to use EJB inside the validation method (this is this line: if (!userRecordFacade.authorizedAcces(username, password))) – Petr Dušek Aug 27 '13 at 12:41
  • I think this is one of the 10000.... bugs of composite components. I think it is solved when you implement a getter `getValidator`. It won't be used, but for some reason JSF wants it. – noone Aug 27 '13 at 12:44
  • Petr: http://stackoverflow.com/q/7572335 @noone: I won't call it a bug as it's essentially an abuse. A lot, really a lot of JSF starters fail to see the point of composites and use them for things they initially weren't designed for. – BalusC Aug 27 '13 at 12:45

1 Answers1

-1

I think this is one of the 10000.... bugs of composite components. I think it is solved when you implement a getter getValidator. It won't be used, but for some reason JSF wants it.

Furthermore why do want a reusable login component which is so dynamic? How many different variations of logins does your application have? I think you should not use a composite component here at all.

noone
  • 19,520
  • 5
  • 61
  • 76
  • This is not an answer. This is more a comment. You're nowhere explaining the *why* and *how* in technical detail. – BalusC Aug 27 '13 at 12:46
  • @BalusC Well, I'm pretty sure it is the solution for his problem. And as I said I think it is a bug, even though I couldn't find a bugreport for it yet. But I once faced the same problem when writing a cross-component validator using a composite component. There is no "real" technical explanation as to "why" it is needed. I accept the downvote though, just because your comments are most of the time better than my answers ;) – noone Aug 27 '13 at 12:50