Extending BEA netui tags

The BEA WebLogic Portal netui framework offers a useful method of creating and handling web forms. I’ve come to like how easy they are to use, specially with the Workshop wizards, one of the few advantages of using Workshop. I also like how you can put almost anything in a form class, like an XML bean generated class, and make their fields available on the form using the X-script notation (but why not EL!?). However, in the project I did in 2005 for a client, the time came when we were saying “I wish netui:textBox could do this, and netui:anchor could do that…” And although there’s not much to extend within the realm of JSP’s, tags are a noteworthy exception.

So we started to extend quite a few netui tags. Unfortunately, there was virtually no documentation to be found on this subject on BEA’s site or elsewhere on the Internet. The tag classes do not come with any apidocs either. Therefore, the first step was to decompile the tags we wished to extend, in order to uncover their internal workings. Having done this, I believe there’s no way you’re going to extend these tags without decompiling them. There’s just too much going on inside. Once you’ve figured this out though, it’s fairly easy to add your own stuff.

Example 1: adding your own formatter attribute to @netui:label@.

If every date field in your application uses the same date format (independant from the JVM’s default), it’s pretty tiring having to include a netui:format tag in each and every label displaying a date. So we decided to add a myFormat attribute to the label tag, which will format date fields. For this, we extended the label tag as well as the format tag.

public class MyLabel
        extends com.bea.wlw.netui.tags.html.Label {

    private String myFormat;

    public int doEndTag() throws JspException {
        if (myFormat != null) {
            addFormatter(new MyFormatter(myFormat));
        }
        myFormat = null; // Needed for tag lifecycle issues!
        return super.doEndTag();
    }

    public void setMyFormat(String myFormat) {
        this.myFormat = myFormat;
    }
}

public class MyFormatter
        extends com.bea.wlw.netui.tags.html.FormatTag.Formatter {

    private String myFormat = null;

    public MyFormatter(String myFormat) {
        this.myFormat = myFormat;
    }

    public String format(Object object) throws JspException {
        String formatted = "";
        if ("date".equals(myFormat)) {
            formatted = new SimpleDateFormat(MY_DATE_FORMAT)
                    .format((Date) object);
        }
        return formatted;
    }
}

Example 2: adding a readonly attribute to @netui:textBox@.

Yes, I know about the disabled attribute, but we specifically wanted to render a label tag for a readonly textBox. A disabled textBox might display its value truncated if it’s too short. The extended tag renders a hidden tag and a label tag in case the readonly attribute evaluates to true. Thanks to the inherited evaluateAttributeToString() method (in the AbstractBaseTag super class), the readonly attribute can contain an X-script expression.

public class MyTextBox
        extends com.bea.wlw.netui.tags.html.TextBox {

    private String readonly;
    private LabelTag labelTag;
    private Hidden hiddenTag;

    public int doStartTag() throws JspException {
        labelTag = null;
        hiddenTag = null;
        if (readonly != null) {
            String readonlyEval =
                    evaluateAttributeToString(readonly, null);
            if (Boolean.valueOf(readonlyEval).booleanValue()) {
                labelTag = new LabelTag();
                hiddenTag = new Hidden();
                try {
                    PropertyUtils.copyProperties(labelTag, this);
                    PropertyUtils.copyProperties(hiddenTag, this);
                    labelTag.setValue(this.getDataSource());
                    labelTag.setPageContext(this.pageContext);
                    labelTag.setParent(this.getParent());
                    labelTag.setFormatType(this.getFormatType());
                    hiddenTag.setPageContext(this.pageContext);
                    hiddenTag.setParent(this.getParent());
                } catch (Exception e) {
                    throw new JspException(e);
                }
                hiddenTag.doStartTag();
                return labelTag.doStartTag();
            }
        }
        return super.doStartTag();
    }

    public int doEndTag() throws JspException {
        int result;
        if (labelTag != null) {
            hiddenTag.doEndTag();
            result = labelTag.doEndTag();
        }
        readonly = null;
        labelTag = null;
        hiddenTag = null;
        return result;
    }

    public int doAfterBody()  throws JspException {
        if (labelTag != null) {
            hiddenTag.doAfterBody();
            return labelTag.doAfterBody();
        } else {
            return super.doAfterBody();
        }
    }

    public void doInitBody() throws JspException {
        if (labelTag != null) {
            hiddenTag.doInitBody();
            labelTag.doInitBody();
        } else {
            super.doInitBody();
        }
    }

    public void setReadonly(String readonly) {
        this.readonly = readonly;
    }
}

Don’t forget: make a TLD/TLDX.

Any extended tag you make, must be included in a .tld file in your webapp (WEB-INF directory). This is no big deal; just copy the .tld entries for the tags you’ve extended from the appropriate netui .tld, like netui-tags-html.tld. If you’ve added your own attributes, add these to the new .tld file. Also create a .tldx file and copy in the appropriate entries from the netui .tldx file, which will give you code completion in Workshop for your new tags.

(Thanks to Remco who co-developed the extended tags)

2005-11-02. 20 responses.

Comments

  1. Cool stuff! Very usefull! Small correction, resetting tag attributes in the endtag is solving an life-cycle issue, not threading.

  2. You’re right, I’ll change it. Thanks!

  3. Hi. I want to create nice URLs using this technique. This means that i have to extend Anchor. Do you have anything on such anchor extension ? Because my code is not working at all.

  4. This very minimal anchor extension checks if the user is authorized to see the link (fill in using your own authorization mechanism), and allows for passing through some custom URL (maybe something you can use).

    import com.bea.wlw.netui.tags.html.Anchor;
    
    public class AnchorTag extends Anchor {
    
        private String customURL;
    
        public AnchorTag() {
        }
    
        public String getCustomURL() {
            return customURL;
        }
    
        public void setCustomURL(String customURL) {
            this.customURL = customURL;
            String url = doSomethingToGetURL(customURL);
            setHref(url.toString());
        }
    
        public int doEndTag() throws JspException {
            if (!getAuthorizationFromSomewhere()) {
                pageContext.getOut().println("Not authorized");
                return SKIP_BODY;
            }
            return super.doEndTag();
        }
    
    }
    
  5. Hi,

    I have a requirement to change the value user enters into must display only in UpperCase and when user submits, it must insert into database only in the uppercase.

    Project is already developed and in SIT Stage,now user is asking for this change.
    Is there any posibulity to change values to upperCase without changing the existing Code.

    Please give me any idea how i can solve this problem.

    Thank you.

  6. Ramesh,
    We’ve had the same requirement on a project I was working on this year, thanks to a backend mainframe not working too well with mixed case input. Obviously you’ll have to change some code, unless you tape down all users’ Caps Lock keys. You might also be able to do something with database triggers, but we (with the mainframe) didn’t have that option.
    So if you’re going to change code, I wouldn’t do it in the JSP tags. If you did that, you’d still have to change all JSPs to use the extended tags. Is there a separate business layer in your application? That would be a good place, if some fields must be uppercased but others don’t. If you have a data abstraction layer (database controls), you could try and insert code in there (assuming that each and every field must be uppercased). If you only have pageflows and JSPs, you could alter the setter methods in the form beans. So it really depends on your application’s architecture.
    Good luck!

  7. Thank you. This is article very useful.
    I too have a requirement of the same type and have implemented as like this.

    But I’ve a small problem in implementing the readonly property. As per my requirement textbox has to be displayed, it should be disable(non-editable… I just set the disable property of the super class for this) and then real problem, empty string should be displayed in the textbox irrespective of the value in the datasource.
    Can you please give some ideas to implement this?

    Thank you

  8. […] On a different note, someone searched the answer to “what is a tldx file?” (Actually, they asked Google “what is * tldx file?”; don’t they know Google ignores the *?) That’s an easy one: in a BEA WebLogic environment, a tldx file accompanies a tld file, which contains definitions for custom JSP tags. The tldx file has additional information about the tags, to be used in Workshop for example to enable code completion in the tags. More info can be found in BEA’s documentation, under ‘Developing Tag Library Extensions’. How did they end up here? I only mentioned tldx once, very briefly… […]

  9. I am planning to extend netui anchor tag for simple pagination requirements. Any suggestions? This should help me get all the benefits of anchor tag.
    Thx

  10. Hi I’d also like a tad help if possible with the

    anchor tag

    I want to specify a parameter inside the tag so I dont have to keep adding an additional paramater tag inside an anchor tag.

    also I want for the tag to not display ahref lin if action and href are blank.

    ie. table header columns are sortable if a href/action exists. if no href or action, then just draw as a normal label.

    thanks for any help

  11. package au.sa.gov.welfare.web.tags;

    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;

    /**
    * AnchorWithDisable tag
    *
    * extends from Weblogic 8.1 SP5 NetUI Anchor class
    *
    * add this ability to disable an anchor and set anchor parameters
    *
    * requires
    *
    * – welfare-tags-html.tld
    * – welfare-tags-html.tldx
    * – netui-tags-html.jar
    *
    * Created by Kane Li 21/07/2006
    */
    public class AnchorWithDisable extends com.bea.wlw.netui.tags.html.Anchor {
    protected boolean disabled = false;
    protected String paramName;
    protected String paramValue;
    /**
    * disable the anchor
    */
    public void setDisabled(String value) {

    // check if expression
    if (isExpression(value)) {
    Object o = super.evaluateExpression(value, “disabled”);
    if (o instanceof Boolean)
    disabled = ((Boolean) o).booleanValue();
    }
    // check string value
    else {
    if (value.equalsIgnoreCase(“true”))
    disabled = true;
    else
    disabled = false;
    }
    }
    /**
    * set the param name
    */
    public void setParamName(String name) {
    if (isExpression(name)) {
    Object o = super.evaluateExpression(name, “paramName”);
    if (o instanceof String)
    paramName = (String) o;
    }
    else
    this.paramName = name;
    }
    /**
    * set the param value
    */
    public void setParamValue(String value) {
    if (isExpression(value)) {
    Object o = super.evaluateExpression(value, “paramValue”);
    if (o instanceof String)
    paramValue = (String) o;
    }
    else
    this.paramValue = value;
    }
    /**
    * do the start tag
    */
    public int doStartTag() throws JspException {
    if (disabled)
    return EVAL_BODY_INCLUDE;
    else {
    if (paramName != null && paramValue != null)
    addParameter(paramName, paramValue);
    return super.doStartTag();
    }
    }
    /**
    * do the end tag
    */
    public int doEndTag() throws JspException {
    if (disabled)
    return EVAL_PAGE;
    return super.doEndTag();
    }
    }

  12. apparently, in SP5 there is not a format type property.

    labelTag.setFormatType(this.getFormatType());

    in which SP did you test the tag ?

    Greetings and great article, you should submit it to dev2dev.

  13. @Ijon: sorry, the formatType property was our the format property that we added ourselves (like in example 1). You can safely leave it out.

  14. I’m wondering if you can customize your netui tags similar to user controls of microsoft. For example you can call multiple optionbuttons with just a single tag.

  15. Hi

    Thank you for a good article. I’m new til WLP use to work on IBM WPS. Anyway what I am trying to get my head around is to add extra parameters to the outerscope request for all URLS. The portlet developers should not need to do anything, it should somehow be done automatically. I have been looking at the URLRewriterService and the templates but cannot find any good documentation or examples on how to use these.

    Anyone got any sugestions?

    regards
    Michael

  16. Hi Danny,
    Nice article. But I’m wondering if there is any legal issue with this as we’ll be decompiling BEA APIs and using BEA’s not-public claases. Plus, this also has an issue from BEA’s one version to another.

    Any comments?
    Amit
    Technical Architect

  17. @Michael: Maybe you could do this somewhere in the Portal JSP-templates?

    @Amit: I’m not sure about any legal issues; you’re not actually using any decompiled code, just extending it. Then again, the decompiling itself may be enough to put you behind bars. The solution might be to use Beehive, which is BEA’s netui framework turned open source.

  18. Hi guys!

    I have a technical question wanna ask you guys:
    – I have a datagrid with paging inside it. Firstly, I move to page 2 and edit 1 record in page 2 but when I click Save to come back to datagrid, the screen will be back to page 1, is anyone faced with this problem? please help, thanks

    Hoang

  19. Hi Guys,

    I want a netui:anchor tag to get selected, by default, when someone runs the portal for the first time…..?
    How to do this ?

  20. Hi Danny
    Your blog is truly good and useful.
    I have a requirement wherein a netui button must be disabled after the first click ,disablesecondclick isnt working with this-says its not recognized.
    Tried using script but disable option alone isnt working however alert messages are displayed
    Thanks