3d com |
Adding a New List DialogHow to add a new dialog and execute multiple server commands from it |
|
Use Case |
AbstractThis article shows how to add a new panel in the Portal transient area and execute multiple Update Object commands from it. |
This use case is intended to help you add a new dialog in the Portal transient area. This dialog is created with the CATJDialog APIs. It is displayed by selecting one or more rows in a list and clicking a new icon added to the Toolbar and the Contextual Menu.
[Top]
CAALCANavCustoList is a use case of the CAALCANavigator.edu framework that illustrates the LCANavigator customization capabilities.
[Top]
For CAALCANavCustoList create a new command named custolist and associate a new icon with it.
For the command to be executed, implement the execute
function in a class extending LCANavCommand.
Finally create a new CATJDialog panel named CustoList which controller is CAALcnCustoListController.java
[Top]
To launch CAALCANavCustoList, you will need to set up the build time environment, customize the runtime view, then compile CAALCANavCustoList along with its prerequisites, set up the run time environment, and then execute the use case [1].
Customize the untime view: Replace in the runtime view CustoTestGeneric.xml and rename it to Generic.xml
[Top]
The CAALCANavCustoList use case is made of a single module CAALcnCustoList.mj module of the CAALCANavigator.edu framework:
Windows | InstallRootDirectory\CAALCANavigator.edu\CAALcnCustoList.mj\ |
Unix | InstallRootDirectory/CAALCANavigator.edu/CAALcnCustoList.mj/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
To create the custolist command and its panel, there are four steps:
[Top]
Name the new command: custolist.
To map the new command to the desired action defined in the new command class :
Create/Update manually the properties files to be deployed in the runtime view.
Create:/resources/pprregistry/command/definition/custolist.xml with the following content:
<Command name="custolist" readonly="true" icon="$/I_CMD_custolist.gif" msgcatalog="CustoList"/>
Update (for this new command to apply to all LCA types): /resources/pprregistry/command/ENOVIA/assignment/Generic.xml
Add the following line:
<Command name="custolist" multiRowEnabled="false" enablement="true" visibility="true"/>
[Top]
Create a new icon of 16x16 pixels identifying the new command on the Toolbar/Contextual menu:
[Top]
In the new class CAALcnCustobase.CAALcnCustocmds.command.custolist.Generic.java
extending LCANavCommand implements the
execute
function:
This new class implement the "custolist" command for
the object type "Generic" (the parent of all types.)
... public void execute( CATSession iSession ){ //Get the list of input objects String[] uuids = getUUIDs( iSession ); if( uuids == null || uuids.length == 0 ) { return; } String webType = null; String prevWebType = null; ENOVIDataObject[] queryResults = new ENOVIDataObject[uuids.length]; for( int i=0; i<uuids.length; i++){ queryResults[i] = LCANavUtils.getDataObject( iSession, uuids[i], ENOVTypeMask.EDIT_MASK ); ENOVWebType type = queryResults[i].getWebType(); //Check that all selected objects derive from the same parent and pass //parent name to the CulstoList dialog //This is done prior calling ErrorOncheckAttributes(), because two objects deriving //from two different parents may have identical attribute names. //For that find the highest WebType parent except GENERIC, DOCCOMMON, ACTCOMMON, RSCBASE String parentName = null; webType = type.getNoun(); while (true) { parentName = type.getParent(); if (parentName == null || parentName.equalsIgnoreCase("GENERIC") || parentName.equalsIgnoreCase("DOCCOMMON") || parentName.equalsIgnoreCase("ACTCOMMON") || parentName.equalsIgnoreCase("RSCBASE")) { break; }else{ webType = parentName; type = ENOVWebType.getWebType(parentName); } } if (prevWebType == null) prevWebType = webType; else { if (! prevWebType.equals(webType) ) { MessageStack.pushInfoMessage( "custolist", "ObjectsOfDifferentTypes", null, iSession ); showStatusMessage( iSession, false ); return; } } } if ( ! ErrorOncheckAttributes(queryResults)) { MessageStack.pushInfoMessage( "custolist", "ObjectsOfDifferentTypes", null, iSession ); showStatusMessage( iSession, false ); return; } iSession.setVolatileProperty("ENOVIDataObjects", queryResults); String parms = "DATAOBECTS=ENOVIDataObjects"+";"+"WEBTYPE="+webType; this.stackSingleObjectDialog( iSession, "CustoList", parms ); } ... |
Because of type the customization which allows for additonal attributes on derived types, check for same attribute names for all selected objects and same editable attribute names for all selected objects. There is still a risk that two new attributes on two derived types of the same parent have the same name but are of different types. This risk is minimal and checking type equality is not necessary. ... private boolean ErrorOncheckAttributes(ENOVIDataObject[] iQueryResults) { Vector vAttr = null; Vector vEditableAttr = null; int iNrAtt = 0; int iNrEditAtt=0; boolean bFirst = true; for (int i=0; i<iQueryResults.length; i++ ) { if (vEditableAttr == null) { vEditableAttr = new Vector(); vAttr = new Vector(); }else{ bFirst = false; } Enumeration e = iQueryResults[i].getAttributes(); int iTotalAtt=0; int iEditAtt=0; while(e.hasMoreElements()){ ENOVIAttribute att = (ENOVIAttribute)e.nextElement(); iTotalAtt++; if (bFirst) { vAttr.addElement(att.getName()); }else if ( ! vAttr.contains(att.getName())) return false; if (att.isEditable()){ iEditAtt++; if (bFirst){ vEditableAttr.addElement(att.getName()); }else if ( ! vEditableAttr.contains(att.getName())) return false; } } if (iNrAtt == 0){ iNrAtt = iTotalAtt; iNrEditAtt = iEditAtt; }else{ if (iTotalAtt != iNrAtt || iEditAtt != iNrEditAtt) return false; } } return true; } ... |
[Top]
Create the new CATJDialog panel CustoList to be displayed in the transient area. The new controller extends LCANavDialogController
Call super in Create for the controller to automatically retrieve the document: ... public void onCreate(CATDialog iDialog, CATNotification iNotification, Object iData){ super.onCreate( iDialog, iNotification, iData ); _btnSelectAll.setTitle("Select All"); _date = new CATDateEditor( _frameActions, "date" ); _frameActions.setConstraints( _date, new GC(3, 0, 1, 1, GC.LEFT|GC.TOP, GC.NOFILL) ); _date.setVisibility(false); _select = new CATComboBox( _frameActions, "select" ); _frameActions.setConstraints( _select, new GC(3, 0, 1, 1, GC.LEFT|GC.TOP, GC.NOFILL) ); _select.setVisibility(false); _text = new CATTextField( _frameActions, "text" ); _frameActions.setConstraints( _text, new GC(3, 0, 1, 1, GC.LEFT|GC.TOP, GC.NOFILL) ); _text.setVisibility(false); } ... |
Implement the onDocumentChanged method:
... public void onDocumentChanged(CATDialog iDialog, CATNotification iNotification, Object iData) { String dataObjects = (String)getParameter("DATAOBECTS"); _queryResults = (ENOVIDataObject[])iDialog.getSession().getVolatileProperty(dataObjects); _webType = (String)getParameter("WEBTYPE"); if (fillTable()) fillColumnComboBox(); onSelectAll( iDialog, iNotification, iData); } ... |
Fill the list table with objects
... private boolean fillTable(){ if( _queryResults == null || _queryResults.length == 0 ) return false; _model = new ENOVDataPPRTableModel( _tableResults, _webType, _queryResults, getLogonToken(), true); _model.setPreferencePrefix("custolist");//List Specific Preferences _tableResults.setKeyModel( _model ); _tableResults.setMultipleSelection( true ); return true; } ... |
Upon column selection fill combo box: ... private void fillColumnComboBox(){ ENOVIDataObject dob = _queryResults[0]; Enumeration e = dob.getAttributes(); while(e.hasMoreElements()) { ENOVIAttribute attr = (ENOVIAttribute)e.nextElement(); if (attr.isEditable() && ! (attr.getName().indexOf("ID")>-1)) _cbColumns.addItem(attr.getAlias()); } if (_cbColumns.getItemCount()>0){ _cbColumns.setSelection(0); onColumnSelected(_cbColumns,null, null ); } } ... |
onColunnSelected callback:
... public void onColumnSelected(CATDialog iDialog, CATNotification iNotification, Object iData){ String textDefaultValue = null; Vector vAllAuthorizedValues = new Vector(); _vCommonIntValue = new Vector(); _vCommonExtValue = new Vector(); int index = ((CATComboBox)iDialog).getSelectionIndex(); for (int i=0; i<_queryResults.length; i++){ ENOVIDataObject dataObj = _queryResults[i]; Enumeration enum = dataObj.getAttributes(); while (enum.hasMoreElements()){ ENOVIAttribute attr = (ENOVIAttribute)enum.nextElement(); String sal = attr.getAlias(); if (attr.getAlias().equals(((CATComboBox)iDialog).getSelection())) { _changedAttrName = attr.getName(); ENOVAttributeType attType = attr.getType(); if( attType == ENOVAttributeType.DATE_TYPE ) { if (i==0) { _date.setVisibility(true); _select.setVisibility(false); _text.setVisibility(false); Object attrVal = attr.getDefaultInternalValue(); if( attrVal instanceof Date ){ CATDate cDate = new CATDate( (Date)attrVal ); _date.setDate( cDate ); } } } else if (attr.valueTranslatable()) { if ( i==0 ){ _date.setVisibility(false); _select.setVisibility(true); _text.setVisibility(false); getComboValues(attr); } }else{ if ( i==0 ){ _date.setVisibility(false); _select.setVisibility(false); _text.setVisibility(true); _text.setText(""); _text.setExpectedFormat( "" ); if (attr.isRequired()) _text.setExpectedFormat( "." ); if (attType.equals(ENOVAttributeType.INTEGER_TYPE)){ if (attr.isRequired()) _text.setExpectedFormat("^[0-9]+$"); else _text.setExpectedFormat("^[0-9]*$"); } Object attrVal = attr.getDefaultExternalValue(); if( attrVal != null ){ if( attrVal instanceof String[] ) _text.setText( arrayToString((String[])attrVal) ); } } } } } if (_select.isDisplayed()){ try{ if (_vCommonIntValue != null){ _select.setItems(_vCommonIntValue.elements()); String[] extValues = new String[_vCommonExtValue.size()]; _vCommonIntValue.copyInto(extValues); _select.setItemTranslator( new LCACATTranslator(_select.getItemList(), extValues, false ) ); } }catch (Exception e) {;} } } ... |
Retrieve authorized and help values for combo box ... private void getComboValues(ENOVIAttribute attr){ String[] extValue = null; String[] intValue = attr.getInternalAuthorizedValues(); if( intValue != null && intValue.length > 0 ) { extValue = attr.getAuthorizedValues(); }else{ intValue = attr.getInternalHelpValues(); extValue = attr.getHelpValues(); } } ... |
Unstack the panel on onCancel calback ... public void onCancel(CATDialog iDialog, CATNotification iNotification, Object iData){ CATDocumentManager docManager = CATDocumentManager.getDocumentManager(_dialogBox); if (docManager != null) docManager.unstack(); } ... |
onApply callback. Update objects ... public void onApply(CATDialog iDialog, CATNotification iNotification, Object iData){ String[] keys = _tableResults.getSelectedKeys(); if (keys == null){ MessageStack.pushInfoMessage( "custolist", "NoRowSelected", null, iDialog.getSession()); showStatusMessage( false ); return; }else{ _bSave = save(keys, iDialog, iNotification, iData); } } ... |
onOK callback: Execute onApply + onCancel ... public void onOK(CATDialog iDialog, CATNotification iNotification, Object iData){ _bSave = false; onApply(iDialog, iNotification, iData); if (_bSave) onCancel(iDialog, iNotification, iData); } ... |
onSelectall callback ... public void onSelectAll(CATDialog iDialog, CATNotification iNotification, Object iData){ PortalUID[] puid = LCAJPortalUtils.getPortalUIDs(iDialog.getSession(),_queryResults ); String[] keys = new String[puid.length]; for (int i=0; i<puid.length; i++) keys[i] = puid[i].toString(); _tableResults.setSelectedKeys(keys); } ... |
Retrieve the selected objects on which to apply the update ... private ENOVIDataObject getDataObjectFromKey(String key, CATSession iSession){ PortalUID[] puid = LCAJPortalUtils.getPortalUIDs(iSession,_queryResults ); for (int i=0; i< puid.length; i++){ if (puid[i].toString().equals(key)) return _queryResults[i]; } return null; } ... |
Save method. Update all selected objects ... private boolean save(String[] keys, CATDialog iDialog, CATNotification iNotification, Object iData) { boolean bSaveOk = true; for (int i=0; i<keys.length; i++){ EVIDataObject dobj = getDataObjectFromKey( keys[i], iDialog.getSession()); if (updateDataObject( dobj)){ boolean ok = validateDataObject(dobj); if (ok){ ENOVIClientCommand cmd = ENOVCommandFactory.createClientCommand( getCommandName(dobj), getLogonToken() ); cmd.setParameter( "object", dobj, false ); ok = cmd.execute(); MessageStack.pushMessages( cmd, _session, i==0? true : false ); showStatusMessage( ok ); if (!ok) { restoreObject(dobj); bSaveOk = false; } }else{ restoreObject(dobj); bSaveOk = false; } }else{ MessageStack.pushInfoMessage( "custolist", "RequiredField", null, iDialog.getSession()); bSaveOk = false; } } showStatusMessage( bSaveOk ); return bSaveOk; } ... |
Return server command name ... private String getCommandName(ENOVIDataObject dataObj){ String noun = dataObj.getObjectType(); String cmd = ENOVWebType.getWebType( noun ).getCommandName( "lcaedit" ); if( cmd == null ) cmd = "UpdateObjectCommand"; return cmd; } ... |
Update object to be saved ... private boolean updateDataObject( ENOVIDataObject iDataObj){ boolean ok = false; ENOVIType type = iDataObj.getType(); Enumeration enum = type.getAttributes(); while( enum.hasMoreElements() ){ ENOVIAttribute attr = (ENOVIAttribute)enum.nextElement(); if (attr.getName().equals(_changedAttrName)){ ENOVAttributeType attrType = attr.getType(); Object val = null; if( attrType == ENOVAttributeType.DATE_TYPE ){ CATDate cDate = _date.getDate(); if( cDate != null ) val = new Date( cDate.getTime() ); } else if( attr.valueTranslatable() ){//Combo box and Check box val = _select.getSelection(); }else{ val = _text.getText(); } if( val != null ){ if ( ! (attr.isRequired() && ((String)val).length() == 0)){ iDataObj.setAttrValue( attr.getID(), val ); ok = true; } } } } return ok; } ... |
Restore object if save failed ... private void restoreObject( ENOVIDataObject dobj){ String uuid = dobj.getObjectUUID(); ENOVIDataObject oldObj = LCANavUtils.getDataObject( _dialogBox.getSession(), uuid, ENOVTypeMask.EDIT_MASK ); for (int i=0; i<_queryResults.length; i++){ if (_queryResults[i].equals(dobj)){ _queryResults[i] = oldObj; break; } } } ... |
Validate object before saving ... private boolean validateDataObject( ENOVIDataObject iObject ){ boolean ok = true; Enumeration attrEnum = iObject.getType().getAttributes(); while( attrEnum.hasMoreElements() ){ ENOVIAttribute attr = (ENOVIAttribute)attrEnum.nextElement(); if( attr.isRequired() ){ Object val = iObject.getAttrValue( attr ); boolean thisOneOk = true; if( val == null ){ thisOneOk = false; } else if( String.valueOf(val).trim().length() == 0 ){ thisOneOk = false; } if( !thisOneOk ){ ok = false; String[] parms = new String[] { attr.getAlias() }; MessageStack.pushErrorMessage( "custolist", "Message.MissingRequired", parms, _session ); } } } return ok; } ... |
Create the CustoList.CATNls file with the following content for all new NLS values
Title="My Customized List";
NoRowSelected = "No row has been selected";
RequiredField = "Field is required";
NotUpdatableObject = "This type of object cannot be updated in LCANav";
ObjectsOfDifferentTypes = "Selection must comprise objects of the same type";
OnlyOneObjectSelected = "More then one row must be selected";
SelectAll.Title = "Select All";
Frame1.FrameToolbar.SelectAll.Title = "Select All";
Command.custolist.title = "Customized List";
[Top]
This use case shows hwo to create a command that can be executed from a new CATJDialog
panel in the Portal transient area. First a new comand is created thanks to RADE,
and a new icon is associated with it. Then the command code is created by extending
LCANavCommand to implement the execute
function. The CATJDialog
panel is finally created along with its different callbacks to allow for triggering
the server command.
[Top]
[1] | Building and Launching a CAA V5 Use Case |
[Top] |
Version: 1 [Jun 2005] | Document created |
[Top] |
Copyright © 1994-2005, Dassault Systèmes. All rights reserved.