Bean Class Sample in Maximo
Bean Class Sample in Maximo
The information provided in this post is based on my Maximo 6 experience. I dont know if or to which extent it has changed in Maximo 7.
Answer
There are 2 types of Beans in IBM Maximo, AppBean and DataBean.
AppBean
The AppBean manage application functionality, such as WOTRACK or ASSET. This class is defined in the beanclass attribute of the presentation tag in the applications XML.
If you export the WOTRACK application xml and go to the bottom of the file you can see a group of actions (action tag) defining actions and their corresponding method in the AppBean beanclass. For instance if youd like to add a button on WOTRACK to approve a workorder (OOTB in Maximo 7 but not in 6) besides of creating the SIGOPTION and TOOLBAR records for that operation youd also have to develop custom Java code for it, this would be done in the AppBean.
DataBean
Data Beans can manage both dialog boxes and tables. The DataBean class associated is defined in the beanclass attribute of both the dialog and table tags in the applications XML. For instance, on dialog boxes you can use a DataBean to control what to do when the OK button is pressed (submit() method). On tables you can do things such as custom the way to load the MBOSet on that table (getMboSet() method).
You have to have in mind that the flow control of the dialogs execution is quite complex. For instance, if you dont provide a submit() method on your dialogs bean class, Maximo will try executing other methods and will end up executing the execute() (I think this is the method) method of the MBOSet asociated with your dialog (defined with the mboname attribute of the dialog tag).
package custom.webclient.system.beans; import psdi.webclient.system.beans.*; import java.rmi.RemoteException; import psdi.util.MXException; import java.text.ParseException; import psdi.app.workorder.WORemote; import psdi.mbo.MboSetRemote; import psdi.server.MXServer; import psdi.webclient.system.controller.Utility; import psdi.webclient.system.controller.WebClientEvent; import psdi.util.logging.FixedLoggerNames; import psdi.util.logging.MXLogger; import psdi.util.logging.MXLoggerFactory; /** * * @author Emrah Sogutoglu */ public class TesisUcretBean extends DataBean { MXLogger appLog = MXLoggerFactory.getLogger(FixedLoggerNames.LOGGERNAME_APP + ".TesisUcretSec"); private double getItemToolRate(String itemnum, WORemote wo) throws RemoteException, MXException { MboSetRemote item = MXServer.getMXServer().getMboSet("ITEMORGINFO", wo.getUserInfo());
item.setWhere("ITEMNUM='" + itemnum + "'"); item.reset(); return item.getMbo(0).getDouble("TOOLRATE"); } 29 public int Q25_0_10() throws RemoteException, MXException, ParseException { 30 //Go to the related workorder 31 DataBean appBean = Utility.getDataSource(sessionContext, 32 app.getAppHandler()); 33 WORemote wo = (WORemote) appBean.getMbo(); 34 System.out.println("WONUM: " + wo.getString("WONUM")); 35 //Building info is being fetched from workorder 36 MboSetRemote bina = wo.getMboSet("WO2BINA"); 37 bina.setWhere("BINA_ID='" + wo.getString("BINAKODU") + "'"); 38 bina.reset(); 39 try { 40 if (bina.count() > 0) { 41 bina.getMbo(0).setValue("BR_ANA_KOLON_CAPI", "Q25(3/4'')"); 42 bina.getMbo(0).setValue("SEBEKE_BINA_MESAFE", "0-10M"); 43 bina.getMbo(0).setValue("TEK_SUBE_YOL_UCRETI", getItemToolRate("T01", 44 wo)); 45 bina.save(); 46 appBean.save(); 47 appBean.fireStructureChangedEvent(); 48 Utility.sendEvent(new WebClientEvent("dialogclose", 49 app.getCurrentPageId(), null, sessionContext)); 50 sessionContext.queueRefreshEvent(); 51 } 52 } catch (Exception e) { 53 appLog.error("ERROR: " + e + "n" + e.getStackTrace()); 54 } 55 return 1; 56 } 57 } 58
26 27 28 59 60 61 62 63 64 65 66 67 68 69 70 Ok guys, this code is attached to the related button. It is easy to do that. You just need to navigate to Application Designer. And then find your dialog. Push Edit dialogs button. Seek for your dialog in the list. Go to the related button properties. Then call the Q25_0_10() method in the event field of the properties window by writing Q25_0_10 in it as shown below.
I hope this helps you to create your own custom dialog and custom bean class.
I mostly use the fields which are going to be used in dialog as non-persistent fields. Non-persistent fields are the fields which are not created as columns in database but Maximo can see them as columns but nothing are stored in the database.In Database Configuration you can add new row for attributes as non-persistent fields. Let's start with step 1. First you have to add a signature option in Application Designer. You can use this signature option in both toolbar or select action menu or as a button on screen. Go To Select Action -> Add/Modify Signature Options and add a new row.
As i said before, you need to make this dialog for the user visible somewhere on the screen such as Select Action Menu, Toolbar or as a button. Sigoption you created is important in Select Action Menu or Toolbar. You have to add this sigoption to the Select action menu or toolbar like that.
But I just added a button into the application to handle this. In the button properties, you should give the id of the dialog that you will create. Don't forget we are going to create our dialog manually. Just be patient. In this example, I will give the ID as customdialog. So the button properties event will be customdialog.
Ok now it's time to create our own custom dialog. Unfortunately, in Maximo, there is no GUI way to do this. We have to export the screen XML, manually edit the file and then re-import it.
From the App Designer screen, click the export XML button. The XML file will be opened in your web browser. Just go to File -> Save As and save the file into your local file system. Now edit the XML file with your Wordpad or Notepad editor. Dialogs are defined between DIALOG tags. Do a search for a dialog word. There is going to be more than one dialog tags. Just pick one which is simple or short. Copy everything between the open and close DIALOG tags. Then go to the end of the document and paste it just before the tag. If you tried to save and load it, you would get an error about a duplicate ID. Don't forget to change the ID's through tags. It's important. For instance, this is my dialog which is custom.
Now save your changes and go back into the App designer in Maximo. Use the import XML button to import your new screen. The main error you would get will be that one of the ID tags is not unique. Change its value and re-import. We are now ready to customize our dialog using Application Designer. Go to Application Designer, find your application, press the Edit Dialogs button on toolbar. Then you will see all the dialogs that your application uses. Find your custom made dialog by using filter option and click the dialog box. It will pop up your dialog. Mainly it is empty when you first create it. Then using the pallette customize it like i did. If you attach your dialog to Select Action Menu or Toolbar, the last step for you (and most often forgotten) is to enable security for your new dialog box. By default, when you add a new signature option, it is disabled for all. To change this, GoTo->Security->Security Group. Then edit any group that will need access to this dialog box.
Then click on the Applications tab. Now find your application and in the bottom half of the screen, enable your dialog box.
Now we're done. The next step will be the bean class step which will be attached to your dialog. I told about this subject in Bean Class Sample In Maximo section.
package custom.workorder; import java.rmi.RemoteException; import psdi.app.workorder.WOSet; 4 import psdi.app.workorder.WOSetRemote; 5 import psdi.mbo.Mbo; 6 import psdi.mbo.MboServerInterface; 7 import psdi.mbo.MboSet; 8 import psdi.util.MXException; 9 public class newWOSet extends WOSet implements WOSetRemote { 10 public newWOSet(MboServerInterface mboServerInterface) 11 throws RemoteException, MXException { 12 super(mboServerInterface); 13 } 14 protected Mbo getMboInstance(MboSet mboSet) throws MXException, 15 RemoteException { 16 return new newWO(mboSet); 17 } 18 }
2 3 19
20 21 22 23 24 This code is enough for now. Well, it is time to create our own main WO class. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 If you want maximo to do different things in save operation, you should put your code in save() method or if you want maximo to do an operation while changing status of a record, you have to use changestatus(String status, Date date, String memo, long l) method.
package custom.workorder; import java.rmi.RemoteException; import java.util.Date; import psdi.util.MXException; import psdi.app.workorder.WORemote; import psdi.app.workorder.WO; import psdi.mbo.MboSet; public class newWO extends WO implements WORemote { public newWO(MboSet ms) throws RemoteException, MXException { super(ms); } public void changeStatus(String status, Date date, String memo, long l) throws MXException, RemoteException { super.changeStatus(status, date, memo, l); //You should put your custom code here } public void save() throws MXException, RemoteException { super.save(); //You should put your custom code here } }
We also should give the classpath of our custom class in WORKORDER object.
Well, that's all up to you from now on. Don't forget you can extend any object you want. Just use your imagination :)
package custom.code; import java.rmi.RemoteException; import psdi.mbo.MboValue; import psdi.mbo.MboValueAdapter; 8 import psdi.util.MXApplicationException; 9 import psdi.util.MXException; 10 public class newFieldClass extends MboValueAdapter { 11 public newFieldClass(MboValue mbo) 12 throws MXException, MXApplicationException { 13 super(mbo); 14 } 15 16public void action() throws MXException, RemoteException { super.action(); 17 //Put Your Java Codes here 18 } 19 } 20
6 7 21 22 23 24 If you want the code to do something when you give an input to the related field, you should override the action() method. For instance, think that we attached this code to the field 'PHONE' of WORKORDER object. getMboValue("PRIMARYSMS").setValue(getMboValue().getString()); Adding this code in action() method will print the input, that you will enter into the PHONE field, to the PRIMARYSMS field of workorder. After you build your code, you have to navigate to the Database Configuration and find the attribute PHONE in WORKORDER Then you have to give the path of class. object.
4 5
package custom.actions; import java.rmi.RemoteException; 6 import psdi.common.action.ActionCustomClass; 7 import psdi.mbo.MboRemote; 8 import psdi.util.MXException; 9 public class customActionClass implements ActionCustomClass { 10 public customActionClass() { 11 } 12 public void applyCustomAction(MboRemote mbo, Object aobj[]) 13 throws MXException, RemoteException { 14 //You should put your custom code here 15 } 16 }
17 18 19 20 Now, we will create an action under System Configuration -> Platform Configuration -> Actions. Choose Custom Class in Type field and then give our classpath.
4 5
Well
guys,
That's an exciting stuff. Bean classes are mostly used for user interface operations in Maximo such as Dialog boxes or button events. Bean classes are using top classes like mbo classes to make its operations. Today I wanna give you a bean class example. My scenario is like that. I have created a custom made dialog box. I just copied it from LIBRARY.XML file and then pasted it to the applications XML. I customized the dialog using application designer. It is important that you should give the classpath of your custom made bean class in application XML file. Don't worry about that I am going to give the details in how to create a custom dialog box in Maximo section. I have added some buttons in dialog which will be triggered from custom bean class that i've Here is the sample code. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 created.
package custom.webclient.system.beans; import psdi.webclient.system.beans.*; import java.rmi.RemoteException; import psdi.util.MXException; import java.text.ParseException; import psdi.app.workorder.WORemote; import psdi.mbo.MboSetRemote; import psdi.server.MXServer; import psdi.webclient.system.controller.Utility; import psdi.webclient.system.controller.WebClientEvent; import psdi.util.logging.FixedLoggerNames; import psdi.util.logging.MXLogger; import psdi.util.logging.MXLoggerFactory; /** * * @author Emrah Sogutoglu */ public class TesisUcretBean extends DataBean { MXLogger appLog = MXLoggerFactory.getLogger(FixedLoggerNames.LOGGERNAME_APP + ".TesisUcretSec"); private double getItemToolRate(String itemnum, WORemote wo) throws RemoteException, MXException { MboSetRemote item = MXServer.getMXServer().getMboSet("ITEMORGINFO", wo.getUserInfo()); item.setWhere("ITEMNUM='" + itemnum + "'"); item.reset();
28
return item.getMbo(0).getDouble("TOOLRATE");
//Go to the related workorder DataBean appBean = Utility.getDataSource(sessionContext, app.getAppHandler()); WORemote wo = (WORemote) appBean.getMbo(); System.out.println("WONUM: " + wo.getString("WONUM")); //Building info is being fetched from workorder MboSetRemote bina = wo.getMboSet("WO2BINA"); bina.setWhere("BINA_ID='" + wo.getString("BINAKODU") + "'"); bina.reset(); try { if (bina.count() > 0) { bina.getMbo(0).setValue("BR_ANA_KOLON_CAPI", "Q25(3/4'')"); bina.getMbo(0).setValue("SEBEKE_BINA_MESAFE", "0-10M"); bina.getMbo(0).setValue("TEK_SUBE_YOL_UCRETI", getItemToolRate("T01", wo)); bina.save(); appBean.save(); appBean.fireStructureChangedEvent(); Utility.sendEvent(new WebClientEvent("dialogclose", app.getCurrentPageId(), null, sessionContext)); sessionContext.queueRefreshEvent(); } } catch (Exception e) { appLog.error("ERROR: " + e + "n" + e.getStackTrace()); } return 1; } }
I hope this helps you to create your own custom dialog and custom bean class.
Dialog boxes are the pop up windows in Maximo. All dialog boxes in Maximo has its own functionality. It is possible to create your own custom built Dialog box and give its functionality by writing a custom bean class. Ok, in the Bean Class Sample In Maximo section, I've posted about implementing a bean class. This class was about the dialog box which I am going to tell you today.
I mostly use the fields which are going to be used in dialog as non-persistent fields. Non-persistent fields are the fields which are not created as columns in database but Maximo can see them as columns but nothing are stored in the database.In Database Configuration you can add new row for attributes as non-persistent fields. Let's start with step 1. First you have to add a signature option in Application Designer. You can use this signature option in both toolbar or select action menu or as a button on screen. Go To Select Action -> Add/Modify Signature Options and add a new row.
As i said before, you need to make this dialog for the user visible somewhere on the screen such as Select Action Menu, Toolbar or as a button. Sigoption you created is important in Select Action Menu or Toolbar. You have to add this sigoption to the Select action menu or toolbar like that.
But I just added a button into the application to handle this. In the button properties, you should give the id of the dialog that you will create. Don't forget we are going to create our dialog manually. Just be patient. In this example, I will give the ID as customdialog. So the button properties event will be customdialog.
Ok now it's time to create our own custom dialog. Unfortunately, in Maximo, there is no GUI way to do this. We have to export the screen XML, manually edit the file and then re-import it. From the App Designer screen, click the export XML button. The XML file will be opened in your web browser. Just go to File -> Save As and save the file into your local file system. Now edit the XML file with your Wordpad or Notepad editor. Dialogs are defined between DIALOG tags. Do a search for a dialog word. There is going to be more than one dialog tags. Just pick one which is simple or short. Copy everything between the open and close DIALOG tags. Then go to the end of the document and paste it just before the tag. If you tried to save and load it, you would get an error about a duplicate ID. Don't forget to change the ID's through tags. It's important. For instance, this is my dialog which is custom.
Now save your changes and go back into the App designer in Maximo. Use the import XML button to import your new screen. The main error you would get will be that one of the ID tags is not unique. Change its value and re-import. We are now ready to customize our dialog using Application Designer. Go to Application Designer, find your
application, press the Edit Dialogs button on toolbar. Then you will see all the dialogs that your application uses. Find your custom made dialog by using filter option and click the dialog box. It will pop up your dialog. Mainly it is empty when you first create it. Then using the pallette customize it like i did. If you attach your dialog to Select Action Menu or Toolbar, the last step for you (and most often forgotten) is to enable security for your new dialog box. By default, when you add a new signature option, it is disabled for all. To change this, GoTo->Security->Security Group. Then edit any group that will need access to this dialog box. Then click on the Applications tab. Now find your application and in the bottom half of the screen, enable your dialog box.
Now we're done. The next step will be the bean class step which will be attached to your dialog. I told about this subject in Bean Class Sample In Maximo section.
Although Maximo (IBM Tivoli) 7 allows much customization to be done using the applications own mechanisms such as Domains, Conditional Expression Manager, etc there are still some situations which require the use of custom classes. In this post Ill describe how to use custom classes for Attributes (aka FLDs) in Maximo.
Class Inheritance
The definition of custom classes in Maximo start at the Database Configuration application. Here one can check out either if a specific attribute has a custom class associated or not. This information is stored on the MAXATTRIBUTESCFG database table. Unlike MBOs which always have a class associated, attributes may have none. When you come to the point where you need to add you own customization, if the attribute already has a class associated you only need to extend that class and add your custom code. If you want to customize an attribute that has no class associated you have several base classes points available depending on what you want your FLD to do. The starting point in the FLD inheritance hierarchy is the psdi.mbo.MboValueAdapter class. This is the class youll use for standard actions, validations and business rules . If you check the Javadocs you can see that this class is already a superclass for quite a number of classes such as Domain specific classes, application specific classes, etc. Either way you should always call for the super method in your customization in order to keep the existing functionality.
Methods
The two main methods for an FLD are validate() and action(). Theyre have similar method signatures, taking no parameters and throwing psdi.util.MXException and java.rmi.RemoteException. They should be used however for 2 different tasks.
validate()
Validate should be used to check the data introduced in the attribute. You may need to check values on other fields or obtain related data from other MBOs. All errors found during data validation should be managed using exceptions, usually psdi.util.MXApplicationException which extends psdi.util.MXException. No actions should be launched in this method. By actions I mean for instance modifying the value of another field, this should be left to be done in the action() method. The validate() method will be called prior to the action() method.
action()
This method will only be called if the data was successfully validated. Here is the place where all the actions should be performed, such as calculating values for other fields, etc.
Creating Classes
If youd like some kind of automation when it comes to generating code for FLDs, and other Maximo objects, you can check out my Maximo Framework project. Maximo Framework is an OSS project for generating class code for IBM Maximo, hosted at Google Code. It contains a Maven Plugin that generates code for MBO, FLDs, CRONTASKSs, etc.
Technote (FAQ)
Question
How can I have a domain with values that show up conditionally?
Answer
It is possible with Maximo 7.1.1.4 and newer versions to create and associate a condition to domain entries so that they only appear when the criteria is met. A domain value can have more than one condition associated to it if there was more than one condition under which you wanted the value to display in the domain. Say for example you wanted to have an ALN Domain associated to a field that allowed users to select a Sub Type value based on the current Work Type value of a Work Order record. You would create the SUBTYPE ALN Domain and associate it to a field used for the SUBTYPE field. Add all values you want to be available in the domain and save the domain. Next create a Conditon(s) to associate to the domain values. For values you want to display when the Work Type is PM you would do the following: From the Administration module, select the Conditional Expression Manager application.
Select New Row. The Condition will have a numeric value, you can change this to something you will remember like SUBPM Leave Type set to Expression. In the Expression field enter: :WORKTYPE = PM Check Always Evaluate if you want the value to be evaluated without the result being cached in the MBO first. Save. Go back to the Domains application and select the SUBTYPE domain. Select a value you want to associate this condition to and expand the details of the value by selecting the blue triangle icon to the left of the value. Select the View/Modify Conditions button Select New Row Value ID should already be filled out. Select your condition of SUBPM for the Condition Number. In this case the Object Name would be WORKORDER as this is the main object of the application in which this is used. Type is set to Expression and the Expression populates when the Condition is selected. Save. The value the condition has been associated to will only display when the condition criteria is met. If you wanted the value to display for two or more conditions, you would add a new row in the View/Modify Condition screen for that value. Note: This method can also be used to make certain domain values site specific if the condition is set for siteid without making the entire list need to be set at a site level.