public get* methods getting called on init?

Hi,

Just curious, CAI seems to have some weird behaviour when the Adapter object gets created the first time. It seems to call all the get* methods in the class even if they are user created public void get* methods. Changing this to a private void get* seems to fix the problem but why does it do this?

Heres my test XML and Java code.



// This class is a generated one.

import java.util.*;
import com.softwareag.cis.server.*;
import com.softwareag.cis.server.util.*;
import com.softwareag.cis.util.*;

public class IndexAdapter
    extends Adapter
{
    /** */
    public void test()
    {
        // TODO Auto-generated method stub
    }


    public void getwhateva()
    {
    	System.out.println("testing");
    }
    
    private void getwhateva2()
    {
    	System.out.println("testing23");
    }
    
}

<page model="IndexAdapter">
    <titlebar name="Template" withclose="false">
    </titlebar>
    <header withdistance="false">
    </header>
    <pagebody>
        <rowarea>
            <itr align="center">
                <button name="test" method="test">
                </button>
            </itr>
        </rowarea>
    </pagebody>
    <statusbar withdistance="false">
    </statusbar>
</page>

…you are right. We should only call get-methods returning something… (on the other hand: to name a method get* and not return something is against all programming styles… ;-)…).

Please have a look into the Developer’s Guid chapter “Binding between page and adapter” to get detailled infos on which get methods are called at which point of time.

Bjoern

Thanks Bjoern, that makes more sense after reading the developers guide.

I haven’t programmed in an object oriented language for a while, Natural programming for the past few years, so I do tend to use get in a different sense of the word. :oops:

On a side note can we suggest features or something for the IDE somewhere? or just directly in this forum?

Thanks

Tony.

Bjoern,

Let’s say I have 5 objects in the layout. Let’s say all these objects have getters. Plus to these getters there are 5 getters not related to layout objects (whatever the reason to have them public). CAI calls all 10 methods with get* irrespectively. What is the rational behind that behavior? Shouldn’t CAI call just related 5 get methods? :?

Hi Mikhail,

to be very precise: when we have an object (e.g. an adapter) then we…

/1/ always process the get-ters for simple types (String/int/…/Integer/…/CDate/…)

/2/ process these getters for “complex” objects which are required from page point of view

The reason behind: “it was always done this way” - we always a little bit mis-trust that controls are 100% correct in referencing the properties they require. We keep this information internally (and e.g. use it inside the code assistant part of the layout editor) but are not brave enough to use this also at runtime. - This answer is true and honest ;-), maybe we are braver in one of the next releases.

BTW: there is a special interface with which you can tell us not to collect some properties:

package com.softwareag.cis.server;

/**

  • Adapter classes and other classes that are accessed by the CI
  • runtime in order to provide for data to be send to the browser client
  • may optionally implement this interface in order to fine-tune the
  • property access.
  • The interface is used the first time an object is accessed, afterwards
  • the CISrunimte internally buffers the data and does not access
  • the interface anymore.
    /
    public interface IControlPropertyAccess
    {
    /
    *
    • When CISaccesses an object ot collect data then all
    • properties are collected that represent simple data type
    • objects. Simple data type objects are of class: int/ Integer/
    • String/ float/ Float/ BigDecimal/ and more.
    • With this method you can define get-Porperties that are not
    • accessed by CISand as consequence are not transferred
    • to the browser client.

    • This method is only relevant for get-Properties that are
    • implemented as corresponding get-methods. Dynamic properties
    • that you may provide by using IDynamicAccess interface are not
    • trreated.
      */
      public String[] findPropertiesNotToBeCollected();
      }

Thank you for the detailed and honest answer.

… just one further question.

I implemented the IControlPropertyAccess interface and wrote some method names in the method findPropertiesNotToBeCollected(). But some of these methods are called anyway (although they are not called via the xml-file).

Is there something wrong in the method?


public class Test implements IControlPropertyAccess
{
    public String getTestSystem() throws SomeException
    {
        // ....
    }

    public int getTimestampStatus() throws SomeException
    {
         // ...
    }

    /**
     * @see com.softwareag.cis.server.IControlPropertyAccess#findPropertiesNotToBeCollected()
     */
    public String[] findPropertiesNotToBeCollected()
    {
        String toReturn[] = { 
                "getTimestampStatus", "getTestSystem" };
        return toReturn;
    }
}

…change “getTimestpamStatus” into “timestampStatus” when building the String[], that should be it…

Bjoern

… but if I use the method in a xml file, now, the method is not called anymore by grids (with text fields, it works fine).

Do you have any advice?

Thanks in advance.

Unfortunately not.

Here’s the code:

Adapter

public class PlantAdapter extends IPageInitAdapter
{
    // Members
    private Plant m_Plant;
    private TEXTGRIDCollection m_PlantList;

    /**
     * @see com.casabac.server.AbstractAdapter#init()
     */
    public void init()
    {
        super.init();

        m_PlantList = new TEXTGRIDCollection();
        initPage();
    }

    /**
     * initialisiert m_PlantList (die Liste mit allen Werken)
     */
    public void initPage()
    {
        clearPlantList();

        try
        {
            Collection plants = Plant.getAllPlants(this);
            if(plants == null)
            {
                return;
            }

            m_PlantList.addAll(plants);
        }
        catch(SomeException e)
        {
              //...
        }
    }

    /**
     * Wird in einem normalen Textfeld angezeigt => funktioniert
     * @return
     */
    public String getName()
    {
        if(m_Plant == null)
        {
            return "";
        }
        return m_Plant.getName();
    }

    /**
     * enthaelt Plant-Objekte => keine Anzeige
     * @return
     */
    public SSSARRAYInfo getPlantList()
    {
        return m_PlantList;
    }
}

The value classe

public class Plant implements IControlPropertyAccess
{
    public static Collection getAllPlants(Model model) throws SomeException
    {
          // holt Collection aus DB
          Collection toReturn =....;
          return toReturn;
    }
    /**
     * Liefert Namen des Werks zurueck
     * 
     * @return
     */
    public String getName()
    {
        return m_ValueObject.getName();
    }

    /**
     * @see com.softwareag.cis.server.IControlPropertyAccess#findPropertiesNotToBeCollected()
     */
    public String[] findPropertiesNotToBeCollected()
    {
        String toReturn[] = { "name", "assignedPlanner", "valueObject" };
        return toReturn;
    }
}

And the xml file:

<?xml version="1.0" encoding="UTF-8"?>
<page model="com.bmw.pplandb.gui.adapter.PlantAdapter" translationreference="main"
	stylesheetfile="../casabac/styles/BMW.css">
	<titlebar textid="plants" withclose="false" helpid="plant">
	</titlebar>
	
	<pagebody takefullheight="true">
		<rowarea textid="plantdata">
			<vdist height="5"/>
			<itr>
				<label textid="name" width="150">
				</label>
				<field valueprop="name" length="20" displayonly="true">
				</field>
			</itr>
			<vdist height="10"/>
		</rowarea>
		<vdist height="10">
		</vdist>
		<rowarea textid="plants" height="100%">
			<vdist height="5"/>
			<itr>
				<button textid="create" method="doCreatePlant" width="100"
					visibleprop="createButtonVisible"/>
			</itr>
			<itr takefullwidth="true" height="100%">
				<textgridsss2 griddataprop="plantList" width="100%" height="100%"
					rowcount="50" selectprop="checked" singleselect="true"
					withselectioncolumn="true" directselectmethod="onSelect"
					directselectevent="onclick"
					oncontextmenumethod="reactOnContextMenuRequest"
					singleselectcontextmenu="true">
					<column textid="name" property="name"
						cuttextline="false">
					</column>
				</textgridsss2>
			</itr>
			<vdist height="10"/>
		</rowarea>
	</pagebody>
</page>

BTW if the adapter implements the IControlPropertyAccess interface, too, the text field does not display the name any longer…

Sorry, I am a bit confused: getName() on grid item level should not be called anymore according to your interface implementation. If it is used in the grid or not - this is not relevant, the interface just decides not to use it.

Is this matching your problem? If not: please tell me what you expect to happen in the code above or what you expect not to happen…

Thanks! Bjoern

Yes, this is the problem.

E.g. I have the value class Plant with the methods getName() and getValue(), implementing the IControlPropertyAccess interface for these methods.


public class Plant implements IControlPropertyAccess
{
    // ...
    public String getName() { return "something"; }
    public String getValue() { return "something different"; }
    public String[] findPropertiesNotToBeCollected()
    {
        String toReturn[] = { "name", "value" };
        return toReturn;
    }
}

Besides, there are two different layouts and their adapters.
LayoutA


<!-- ... -->
<textgrid2 griddataprop="plantList" >
	<column textid="name" property="name" cuttextline="false"/>
</textgrid2>
<!-- ... -->

and LayoutB


<!-- ... -->
<textgrid2 griddataprop="plantList" >
	<column textid="value" property="value" cuttextline="false"/>
</textgrid2>
<!-- ... -->

I expected that getName() would be called by LayoutA and getValue() by LayoutB independent from the content in findPropertiesNotToBeCollected. Otherwise, this method doesn’t make much sense in my opinion because that would be like “take all or nothing” (either all methods would be called - regardless if they are really called by the xml file - or none of them).

I hope you understand my problem now a bit better…

Is there no possibilty to call only the getter methods which are really used by the current xml file?
For example: if I display all customers in a grid with their names and ids, I do not want that the method getOrders() in the customer class is also called which I perhaps need for another grid in another xml file.

Thanks in advance.

…no. The simple type get-ters are always called (if not explicitly switched off by IControlPropertyAccess).
Bjoern