=======
Agile Product Lifecycle Management SDK Developer Guide - Using APIs Release 9.3.6 E71152-01 |
|
![]() Previous |
![]() Next |
About Tables
Retrieving a Table
Accessing the New and Merged Relationships Tables
Retrieving the Metadata of a Table
Adding Table Rows
Adding and Updating Multiple Table Rows
Managing PSR Affected Items Tables with Bulk Edit APIs
Iterating Over Table Rows
Sorting Table Rows
Removing Table Rows
Retrieving the Referenced Object for a Row
Checking the Status Flags of a Row
Working with Page 1, Page 2, and Page 3
Getting and Setting Revisions and Flags
Redlining
Removing Redline Changes
Identifying Redlined Rows and Redlined Cells
When you work with an Agile PLM object in your program, you inevitably need to get and display the object's data. The data is contained in one or more tables. In Agile Web Client, these tables are equivalent to the separate tabs in a window, such as the Manufacturers and BOM tabs.
In some cases, a tab in Agile Web Client contains multiple tables. For example, the Changes tab for an item contains the Pending Changes table and the Change History table. The tabs and the tables that they contain is not always the same for different Agile products. Also, they are not the same for each Agile PLM Dataobject. For example, tables for Parts objects are different from tables for Manufacturers objects. See ”Retrieving a Table” on page 4-3.
To work with data in an Agile PLM table, follow these basic steps:
Create or get an object (for example, an Item or a Change Order).
Retrieve a table (for example, the BOM table).
Iterate through the table rows to retrieve a row.
Get or set one or more attribute values for the selected row.
ITable
, similar to IFolder
, extends java.util.Collection
and supports all methods provided by that superinterface. Consequently, you can work with an ITable
object as you would with any Java Collection.
Interface | Inherited methods |
---|---|
java.util.Collection |
add(), addAll(), clear(), contains(), containsAll(), equals(), hashCode(), isEmpty(), iterator(), remove(), removeAll(), retainAll(), size(), toArray(), toArray() |
After you create or get an object, you can use the IDataObject.getTable()
method to retrieve a particular Agile PLM table. IDataObject
is a general-purpose object that represents any Agile PLM object that contains tables of data. It is a superinterface of several other objects, including IItem
, IChange
, and IUser
.
Note: When retrieving PG&C's Supplier Declaration of Conformance (SDOC) tables, IDataObject.getTable()retrieves all 14 SDOC tables belonging to this base class. However, six of these tables (Items, Manufacturer Parts, Part Groups, Item Composition, Manufacturer Part Composition, Part Group Composition) are not enabled. |
Tables vary for each Agile PLM data object. Tables for change objects are different from tables for items. Each table for a particular data object is identified by a constant in the constants class for that data object. Item constants are contained in the ItemConstants
class, change constants are contained in the ChangeConstants
class, and so on.
For information to use these tables, refer to the following Agile product administration documents:
Getting Started with Agile PLM
Agile PLM Administrator Guide
Agile PLM Product Governance & Compliance User Guide
Agile PLM Product Portfolio Management User Guide
In Release 9.2.2, the following tables were merged into a single table, called the Relationships table.
Relationships.AffectedBy
Relationships.Affects
Relationships.Reference
In addition, the constants that are used by these tables (TABLE_REFERENCES, TABLE_RELATIONSHIPSAFFECTS, and TABLE_RELATIONSHIPSAFFECTEDBY)
were also removed. If you need these constants, you must rewrite them in your routines.
Note: For a complete list of table constants that are merged and mapped into a single constant, or mapped into a new constant, see Appendix B, "Migrating Table Constants to Release 9.2.2." |
For information to use these tables, refer to the following Agile documents:
To use these tables in Agile PLM products, refer to Getting Started with Agile PLM and Agile PLM Administrator Guide
To use these tables in Agile PPM products, refer to Agile PLM Product Portfolio Management User Guide
The IRelationshipContainer
interface is designed to access this table. Any Agile business object that contains the Relationships table, implements this interface. You can access this table using IRelationshipContainer
or, IDataObject.getTable()
with the
CommonConstants
.TABLE_RELATIONSHIPS
constant.
IRelationshipContainer
container
= (IRelationshipContainer) object;
ITable relationship = container.getRelationship()
;
If you used these tables in previous releases of Agile PLM, and require the functionalities that they provided, modify your code as shown below.
Code used in Release 9.2.1.x and earlier releases:
ITable affectedBy =object.getTable(ChangeConstants.TABLE_RELATIONSHIPSAFFECTEDBY);
Code recommended for this release:
ITable affectedBy =object.getTable(CommonConstants.TABLE_RELATIONSHIPS).where("[2000007912] == 1", null);
Code used in Release 9.2.1.x and earlier releases:
ITable affects =object.getTable(ChangeConstants.TABLE_RELATIONSHIPSAFFECTS);
Code recommended for later releases:
ITable affects =object.getTable(CommonConstants.TABLE_RELATIONSHIPS).where("[2000007912] == 2", null);
Code used in Release 9.2.1.x and earlier releases:
ITable references =object.getTable(ChangeConstants.TABLE_RELATIONSHIPS_REFERENCES);
Code recommended for this release:
ITable references =object.getTable(CommonConstants.TABLE_RELATIONSHIPS).where("[2000007912] == 3", null);
Note: The ITable.where() method is certified for deployment with these three tables only, and it may fail if it is used to access other tables from the SDK. |
Several Agile PLM tables store history information or data about related objects. These tables are read-only and as such, you cannot modify these tables. When you write code to access a table, use the ITable.isReadOnly()
method to check if the table is read-only.
The ITableDesc
is an interface that represents the metadata of a table which is the underlying data that describes a table's properties. ITableDesc
is related to ITable
in the same way that IAgileClass
is related to IDataObject
. At times you may need to identify the attributes for a particular table, its ID, or its table name without loading a dataobject. The following example shows how to use the ITableDesc
interface to retrieve the collection of all attributes (including ones that aren't visible) for a table.
Example 4-2 Retrieving the metadata of a table
private IAttribute[] getBOMAttributes() throws APIException {IAgileClass cls = admin.getAgileClass(ItemConstants.CLASS_PART);ITableDesc td = cls.getTableDescriptor(ItemConstants.TABLE_BOM);
IAttribute[]attrs = td.getAttributes();
return attrs;}
You can also use the API Name field to identify a table's name or ID. For information to use this field, see Chapter 9, "Accessing Metadata Using the APIName Field." For information to use the Agile API to work with metadata, see Chapter 23, "Performing Administrative Tasks."
To create a table row, use the ITable.createRow(java.lang.Object)
method, which creates a new row and initializes it with the data specified in the param
parameter. The param
parameter of createRow
is available to pass the following data:
A set of attributes and values for the row's cells
Files or URLs to add to the Attachments table
An Agile PLM object (such as an IItem
) to add to the table
When you add a row to a table, it's not necessarily added at the end of the table.
Note: There is also a deprecated, parameter-less version ofcreateRow() which creates an empty row. Avoid using this method because it may not be supported in future Agile PLM releases. Also, you must initialize a row with data when you create it. |
You can add table rows in a batch format with ITable.createRow()
. See ”Adding and Updating Multiple Table Rows” on page 4-9.
The following example uses ITable.createRow()
to add an item to a BOM table.
Example 4-3 Adding a row and setting values
private static void addToBOM(String number) throws APIException { IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, number);ITable table = item.getTable(ItemConstants.TABLE_BOM); Map params = new HashMap(); params.put(ItemConstants.ATT_BOM_ITEM_NUMBER, "1543-01"); params.put(ItemConstants.ATT_BOM_QTY, "1"); item.setManufacturingSite(ManufacturingSiteConstants.COMMON_SITE); IRow row = table.createRow(params)
;
}
Note: To add a site-specific row to the BOM table, useIManufacturerSiteSelectable.setManufacturingSite() to select a specific site before calling ITable.createRow(). |
The following example shows how to use the ITable.createRow(java.lang.Object)
method to add a row to the Attachments table. The code adds a row to the table and initializes it with the specified file.
Example 4-4 Adding a row to an Attachments table
private static void (String number) throws APIException { File file = new File("d:/MyDocuments/1543-01.dwg"); IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, number); ITable table = item.getTable(ItemConstants.TABLE_ATTACHMENTS); IRow row = table.createRow(file);
}
}
Anytime the ITable.createRow(java.lang.Object)
method fails to add attachments and generates the java.lang.NullPointerException
error, you must modify the value of agile.sso.expirationTime
,the duration in seconds, between the time that you log in and authentication by the PLM FileManager. The default value is 120 seconds which is not enough, modify the default setting as shown below.
To modify the value of agile.sso.expirationTime:
Locate agile.properties
file as follow:
Depending on your installation, the three possible locations for this file are:
<Agile_Home>\agileDomain\applications\application.ear\APP-INF\ classes
\
Note: This path is generated after PLM is installed. |
<Agile_Home>\agileDomain\confi
g
Note: This path is generated after PLM is installed. |
<Agile_Home>\agileDomain\servers\BEJ301388-AgileServer\tmp\
_WL_
user \AgilePLM\eokg58\APP-INF\classes
Note: This path is generated after starting the server. You can delete it, but will regenerate as part the WebLogic Server startup process. The directory eokg58 is generated randomly. |
In agile.properties file, increase the value of agile.sso.expirationTime from 120 seconds to a larger number, for example, 600 seconds.
Restart the Agile PLM server.
The following example shows how to use the ITable.createRow(java.lang.Object)
method to add a row to the Manufacturers table of an item. The code adds a row to the table and initializes it with the specified IManufacturerPart
object.
Example 4-5 Adding a row to the Manufacturers table
private static void addMfrPartRow(String number) throws APIException {HashMap info = new HashMap(); info.put(ManufacturerPartConstants.ATT_GENERAL_INFO_MANUFACTURER_PART_NUMBER, "TPS100-256"); info.put(ManufacturerPartConstants.ATT_GENERAL_INFO_MANUFACTURER_NAME, "TPS_POWER"); ManufacturerPart mfrPart = (IManufacturerPart)(ManufacturerPartConstants. CLASS_MANUFACTURER_PART, info); IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, number); item.setManufacturingSite(ManufacturingSiteConstants.COMMON_SITE); ITable table = item.getTable(ItemConstants.TABLE_MANUFACTURERS); IRow row = table.createRow(mfrPart); }
Note: To add a site-specific row to the Manufacturers table, useIManufacturerSiteSelectable.setManufacturingSite() to select a specific site before calling ITable.createRow() . |
The following example shows how to use the ITable.createRow(java.lang.Object
) method to add a row to the Affected Items table of a change order. The code adds a row to the table and initializes it with the specified IItem
object.
Example 4-6 Adding a row to the Affected Items table
private static void addItemRow(String number) throws APIException {IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, "P522-103"); IChange change = (IChange)m_session.getObject(ChangeConstants.CLASS_ECO, number); ITable table = change.getTable(ChangeConstants.TABLE_AFFECTEDITEMS); IRow row = table.createRow(item);}
The following example shows how to use the ITable.createRow(java.lang.Object)
method to add a row to the Schedule table of a Project. The code adds a row to the table and initializes it with the specified IProgram
object.
Example 4-7 Adding a row to the Schedule table
private static void addTaskRow(IProgram program, IProgram task) throws APIException {
// Get the Schedule table of the program ITable table = program.getTable(ProgramConstants.TABLE_SCHEDULE);
// Add the task to the schedule
IRow row = table.createRow(task);
}
The ITable
interface provides two convenient methods for adding and updating multiple table rows with one API call:
ITable.createRows()
ITable.updateRows()
Because these methods group multiple table rows in one API call, they can improve performance by reducing the number of Remote Procedure Calls (RPCs), particularly if you are connecting to the server across a Wide Area Network (WAN). However, these methods do not result in efficient batch operations on the Agile Application Server, which simply iterates through each row being added or updated.
Important: TheITable.createRows() and ITable.updateRows() methods are supported only when you are adding or updating multiple rows on the BOM table of items, or the Affected Items table of Changes. |
The following example shows how the ITable.createRows()
method supports the Team Table of a Project.
Example 4-8 Adding Multiple Team members to a Program with Bulk API
private static void createTeamRows(String[] addTeamMembers) throws APIException {//Get the Project IProgram program = (IProgram)session.getObject(IProgram.OBJECT_TYPE, programNumber);//Get the Team Table ITable teamTable = program.getTable(ProgramConstants.TABLE_TEAM); IAgileList attrRolesValues = teamTable.getAvailableValues(ProgramConstants.ATT_TEAM_ROLES); attrRolesValues.setSelection(new Object[]{"Change Analyst", "Program Team Member"});//Collect team members already on Team Table Set presentMembers = new HashSet(); Iterator it = teamTable.iterator(); while(it.hasNext()) {IRow row = (IRow)it.next();IUser user = (IUser)row.getReferent();presentMembers.add(user);}//Validate new team members and filter out existing members to and to Team Table IUser user = null; IUser[] newUsers= new IUser[addTeamMembers.length]; int usrCount = 0; for(int i =0; i<addTeamMembers.length; i++ ) { user = (IUser)session.getObject(IUser.OBJECT_TYPE, addTeamMembers[i]); if(!presentMembers.contains(user) || user==null) { newUsers[usrCount++]=user; }}//Using createRows() API to add all Team members at onece//In this bulk approach, make sure each map in array is complete by it self to //create a new row in Team Table. List<Map> newTeam=new ArrayList<Map>(); for (int i=0; i<usrCount; i++) { Map teamMap = new HashMap();teamMap.put(ProgramConstants.ATT_TEAM_NAME, newUsers[i]); teamMap.put(ProgramConstants.ATT_TEAM_ROLES, attrRolesValues); teamMap.put(ProgramConstants.ATT_TEAM_ALLOCATION, 0); newTeam.add(teamMap); } teamTable.createRows(newTeam.toArray(new Object[0]));}
The following example shows how to use the ITable.createRows()
method to add multiple items to a BOM table.
Example 4-9 Adding multiple rows and setting values
private static void createBOMRows(String partNumber) throws APIException { IItem[] child =new
IItem [3]; IItem parent =null
; ITable tab = null; // Get the parent item parent = (IItem) m_session.getObject(IItem.OBJECT_TYPE, partNumber); // Get the BOM table tab = parent.getTable(ItemConstants.TABLE_BOM); // Create child items child[0] = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-1"); child[1] = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-2"); child[2] = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-3"); // Create a row array IRow[] rowArray = new IRow[3]; // Add the items to the BOM rowArray = tab.createRows(new Object[]{child[0], child[1], child[2]}); }
Note: To add a site-specific row to the BOM table, useIManufacturerSiteSelectable.setManufacturingSite() to select a specific site before calling ITable.createRow() . |
To update multiple rows, use the ITable.updateRows()
method. This method batches together multiple update operations into a single call. Instead of calling IRow.setValues()
for multiple rows in a table, this API updates an entire table in one method call.
The rows parameter of updateRow()
can be used to pass a Map containing IRow
instances as keys with instances for values. The value Map objects should have attribute IDs as keys and replacement data for values.
Example 4-10 Updating Multiple BOM Rows
private static void updateBOMRows(String partNumber) throws APIException
{ IItem parent =null
; ITable tab =null
; HashMap[] mapx = new HashMap[3]; Map rows = new HashMap(); IRow[] rowArray = new IRow[3]; // Get the parent item parent = (IItem) m_session.getObject(IItem.OBJECT_TYPE, partNumber); // Get the BOM table tab = parent.getTable(ItemConstants.TABLE_BOM); // Create three items IItem child1 = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-1"); IItem child2 = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-2"); IItem child2 = (IItem) m_session.createObject(ItemConstants.CLASS_PART, partNumber + "-3"); // Add these items to BOM table rowArray = tab.createRows(new Object[]{child1, child2, child3}); // New values for child[0] mapx[0] = new HashMap(); mapx[0].put(ItemConstants.ATT_BOM_FIND_NUM, new Integer(1)); mapx[0].put(ItemConstants.ATT_BOM_QTY, new Integer(3)); mapx[0].put(ItemConstants.ATT_BOM_REF_DES, "A1-A3"); rows.put(rowArray[0], mapx[0]); // New values for child[1] mapx[1] = new HashMap(); mapx[1].put(ItemConstants.ATT_BOM_FIND_NUM, new Integer(2)); mapx[1].put(ItemConstants.ATT_BOM_QTY, new Integer(3)); mapx[1].put(ItemConstants.ATT_BOM_REF_DES, "B1-B3"); rows.put(rowArray[1], mapx[1]); // new values for child[2] mapx[2] = new HashMap(); String strA = "BOM-Notes" + System.currentTimeMillis(); mapx[2].put(ItemConstants.ATT_BOM_BOM_NOTES, strA); mapx[2].put(ItemConstants.ATT_BOM_FIND_NUM, new Integer(3)); rows.put(rowArray[2], mapx[2]); // Update the BOM table rows tab.updateRows(rows); }
Bulk Edit APIs are designed to improve PLM server performance by reducing the duration of the PSR Affected Items (AIs) edits (create, update, remove), when editing the status of these AIs. Invoking the ITable
interface (See Metadata Interface under Types of Agile API Classes and Interfaces) deteriorates server performance because it edits a single PSR AI which triggers the entire set of the associated Events, and each associated Event in turn, invokes several additional unnecessary server calls. Thus, the resolution of this issue was sought in a similar interface that performs the functions of the ITable
interfaceFoot 1 , in the Bulk execution mode.
The com.agile.api.IServiceRequestAITable
interface enables creating, updating, and removing the entire rows of a service Request Action Item table, thus reducing a multitude of often unnecessary remote server calls to a single call. This proves to be most valuable when updating PSR AI tables having large numbers of rows.
You can cast ITable
to IServiceRequestAITable
table and use the methods defined in this interface.
IRow [] bulkCreateRows (Object[] rows) throws APIException
This bulk operation creates multiple rows with a single remote call. Rather than calling ITable.createRow(...)
to create multiple rows, this API can improve performance and reduce unnecessary event invocations. However, if an error/warning occurred, all operations are rolled back. This method accepts an array of objects and returns an array of IRow
corresponding objects. See createRow(Object)
for more information on the possible makeup of each element in the rows array.
boolean bulkRemoveAll ( Collection c ) throws APIException
This operation removes all of this collection's elements from this table in a single remote call. This API can improve the performance and reduce unnecessary event Invocations. This collection's elements must be IRow
. If an error/warning occurred, all operations are rolled back.
void bulkUpdateRows ( Map rows ) throws APIException
This bulk operation updates multiple rows with a single remote call. Rather than call IRow.setValues(...)
for multiple rows in a table, this API can potentially improve the performance and reduce unnecessary event Invocation. If an error/warning occurred, all operations are rolled back.
The following three bulk APIs aim to improve the performance of PLM when creating, updating, or deleting the PSR Affected Items tab rows:
ServiceRequestAITable.bulkCreateRows(Object[] rows) throws APIException;ServiceRequestAITable.bulkUpdateRows(Map rows) throws APIException;ServiceRequestAITable.bulkRemoveAll(Collection c) throws APIException;
Example 4-11 Creating table rows in the Bulk execution mode
//Bulk Create List<Map> list = new ArrayList<Map>(); Map map = new HashMap(); map.put(ServiceRequestConstants.ATT_AFFECTED_ITEMS_ITEM_NUMBER, (IItem)session.getObject(IItem.OBJECT_TYPE,"PARTXXX")); list.add(map); aiTable.bulkCreateRows(list.toArray());//Bulk Update Map retmap = new HashMap(); Iterator it = aiTable.iterator(); while (it.hasNext()) { IRow row = (IRow) it.next(); Map map = new HashMap(); map.put(ServiceRequestConstants.ATT_AFFECTED_ITEMS_TEXT01, "AI.Text01"); retmap.put(row, map); } aiTable.bulkUpdateRows(retmap);//Bulk Remove List list = new ArrayList(); Iterator it = aiTable.iterator(); while (it.hasNext()) { IRow row = (IRow) it.next(); list.add(row); } aiTable.bulkRemoveAll(list);
Because the input and outputs parameters of ServiceRequestAITable APIs are similar to those of ITable
, you can cast ITable
variables to those of IServiceRequestAITable
by renaming the method, as shown below, and performing the required tasks in the Bulk mode.
When you use the Agile API to get a table, such as a BOM table, your program often needs to browse the rows contained in the table. To access an individual row, you first have to get an iterator for the table. You can then iterate over each row to set cell values.
The Agile API does not support random access of rows in a table. This means that you can't retrieve a specific row by index number and then update it. When you add or remove a row, the entire table is resorted and the existing table iterator is no longer valid.
To browse the data in table, create an iterator for the table using one of these methods:
ITable.iterator()
- returns an Iterator object, allowing you to traverse the table from the first row to the last.
ITable.getTableIterator()
- returns an ITwoWayIterator
object, allowing you to traverse the table rows forwards or backwards. You can also use ITwoWayIterator
to skip a number of rows. ITwoWayIterator
is preferred over Iterator
if your program displays table rows in a user interface.
ITable.getTableIterator(ITable.ISortBy[]
) - returns a sorted ITwoWayIterator
object.
ITable.getReferentIterator()
- returns an ITwoWayIterator
object for the objects referenced in the table.
When you work with an iterator for a table, you don't need to know the total number of rows in the table. Instead, you work with one row at a time. Although the ITable
interface provides a size ()
method, which calculates the total number of rows in the table, it's considered a resource extensive operation performance-wise and as such, is not recommended for large tables, particularly if your code already uses an iterator to browse the table.
The following example demonstrates how to get an iterator for a table and use ITwoWayIterator to traverse forwards and backwards over the table rows.
Example 4-14 Iterating over table rows
try {// Get an item IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, "1000-02");// Get the BOM table ITable bom = item.getTable(ItemConstants.TABLE_BOM); ITwoWayIterator i = bom.getTableIterator()
;// Traverse forwards through the table while (i.hasNext()) { IRow row = (IRow)i.next(); // Add code here to do something with the row} // Traverse backwards through the table while (i.hasPrevious()) { IRow row = (IRow)i.previous(); // Add code here to do something with the row }} catch (APIException ex) { System.out.println(ex);}
The ITwoWayIterator
object allows a user interface to display table rows on multiple pages, which is perhaps more practical than the use of ITwoWayIterator
shown in the preceding example. For example, instead of displaying a single scrolling page of several hundred BOM items, you can break the table into pages displaying 20 BOM items per page. To navigate from page to page, your program should provide navigation controls such as those displayed in Figure 4–2 below.
When you invoke getReferentIterator
to update objects in search results tables that contain more than 200 results, getReferentIterator
will not update all the objects that are returned by the query. For example, when you run a query to match a value in a field, and then edit the same value while iterating through the results with getReferentIterator
, the query completes the first page with no problem. However, when it queries the remaining pages, some table rows are not updated. There are several ways to overcome this limitation. The following is one such example.
To update all table rows when iterating large query results:
Increase the table page size for this query so that it can contain the results in a single page.
Run the query several times and keep updating the results until query results are empty.
Do not query on the same field that you are updating.
To sort the rows in a table by a particular attribute, use getTableIterator(ITable.ISortBy[])
which will return a sorted iterator. The ISortBy
parameter of getTableIterator()
is an array of ITable.ISortBy
objects. To create an ISortBy
object, usecreateSortBy(IAttribute, ITable.ISortBy.Order)
. The order parameter of createSortBy()
is one of the ITable.ISortBy.Order
constants either ASCENDING
or DESCENDING
.
Note: The Agile API allows you to sort a table by only one attribute. Therefore, theISortBy array that you specify for the ISortBy parameter of getTableIterator () must contain only one ISortBy object. |
The following example sorts the BOM table by the BOM | Item Number attribute.
Example 4-15 Sorting a table iterator
try {// Get an item IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, "1000-02");// Get the BOM table ITable bom = item.getTable(ItemConstants.TABLE_BOM); // Get the BOM | Item Number attribute IAgileClass cls = item.getAgileClass(); IAttribute attr = cls.getAttribute(ItemConstants.ATT_BOM_ITEM_NUMBER); // Specify the sort attribute for the table iterator ITable.ISortBy sortByNumber = bom.createSortBy(attr, ITable.ISortBy.Order.ASCENDING);
// Create a sorted table iterator ITwoWayIterator i = bom.getTableIterator(new ITable.ISortBy[] {sortByNumber});
// Traverse forwards through the table while (i.hasNext()
) { IRow row = (IRow)i.next()
; // Add code here to modify the row } } catch (APIException ex) { System.out.println(ex); }
The following Product Sourcing and Projects Execution objects load tables a bit differently and therefore cannot be sorted using the getTableIterator(ITable.ISortBy[])
method. For any tables of these objects, create an unsorted iterator using either the iterator()
or getTableIterator()
methods.
IDiscussion
IPrice
IProgram
IProject
IRequestForQuote
ISupplier
ISupplierResponse
The ITable.ISortBy
interface is not supported for query result tables. To sort query results, use SQL syntax and specify an ORDER BY statement with the search criteria. For more information, see "Using SQL Syntax for Search Criteria."
To remove a row from a table, use the ITable.removeRow()
method, which takes one parameter, an IRow
object. You can retrieve a row by iterating over the table rows.
If a table is read-only, you can't remove rows from it. For more information, see ”Working with Read-only Tables” on page 4-5. If you are working with a released revision of an item, you can't remove a row from the item's tables until you create a change order for a new revision.
Example 4-16 Removing a table row
try {// get an item IItem item = (IItem)m_session.getObject(ItemConstants.CLASS_PART, "1000-02");
// get the BOM table ITable bom = item.getTable(ItemConstants.TABLE_BOM); ITwoWayIterator i = bom.getTableIterator();
// Find bom component 6642-01 and remove it from the table row while (i.hasNext()) { IRow row = (IRow)i.next(); String bomitem = (String)row.getValue(ItemConstants.ATT_BOM_ITEM_NUMBER); if (bomitem.equals("6642-01")) { bom.removeRow(row)
; break; }
}} catch (APIException ex) { System.out.println(ex);}
Because ITable
implements the Collection interface, you can use the Collection methods to remove table rows. To remove all rows in a table, use Collection.clear()
.
Several Agile PLM tables contain rows of information that reference other Agile PLM objects. For example, the BOM table lists all items that are included in a Bill of Material. Each row of the BOM table represents an item. While working with a row on a BOM table, your program can allow the user to open the referenced item to view or modify its data.
The table below lists Agile PLM tables that reference other Agile PLM objects. All Agile PLM objects are referenced by number (for example, Item Number, Change Number, or Manufacturer Part Number).
Object | Table | Referenced Object(s) |
---|---|---|
IChange |
Affected Items
Affected Prices Attachments Relationships |
IItem
IPrice IAttachmentFile Multiple object types |
ICommodity |
Attachments
Compositions Parts Specifications Substances Suppliers |
IAttachmentFile
IDeclaration IItem ISpecification ISubstance ISupplier |
ICustomer | Attachments
Quality PSRs Quality QCRs |
IAttachmentFile
IServiceRequest IQualityChangeRequest |
IDeclaration | Attachments
Item Composition Items Manufacturer Part Composition Manufacturer Parts Part Group Composition Part Groups Relationships Specifications |
IAttachmentFile
ISubstance IItem ISubstance IManufacturerPart ISubstance ICommodity Multiple object types ISpecification |
IDiscussion | Attachments
Where Used |
IAttachmentFile
Not supported |
IFileFolder | Files
Relationships Where Used |
IAttachmentFile
Multiple object types Multiple object types |
IItem | Attachments
BOM Change History Compositions Manufacturers Pending Change Where Used Pending Changes Prices Quality Redline BOM Redline Manufacturers Sites Specifications Substances Where Used |
IAttachmentFile
IItem IChange IDeclaration IManufacturerPart IItem IChange IPrice IServiceRequest or IQualityChangeRequest IItem IManufacturerPart IManufacturingSite ISpecification ISubstance IItem |
IManufacturerPart | Attachments
Compositions Prices Specifications Substances Suppliers Where Used |
IAttachmentFile
IDeclaration IPrice ISpecification ISubstance ISupplier IItem |
IManufacturer | Attachments
Where Used |
IAttachmentFile
IManufacturerPart |
IManufacturingSite | Attachments | IAttachmentFile |
IPackage | Attachments | IAttachmentFile |
IPrice | Attachments
Change History Pending Changes |
IAttachmentFile
IChange IChange |
IProgram | Attachments
Deliverables - Affected By Deliverables - Affects Dependencies - Dependent Upon Dependencies - Required For Discussion Links Schedule Team |
IAttachmentFile
Multiple object types Multiple object types IProgram IProgram IDiscussion Multiple object types
|
IProject | Attachments
BOM Item Changes Items Manufacturer Items Pending Change Responses RFQs |
IAttachmentFile
IItem IChange IItem IManufacturerPart IChange ISupplierResponse IRequestForQuote |
IQualityChangeRequest | Affected Items
Attachments PSR Items Relationships |
IItem
IAttachmentFile IItem Multiple object types |
IRequestForQuote | Attachments | IAttachmentFile |
IServiceRequest | Affected Items
Attachments Related PSR Relationships |
IItem
IAttachmentFile IServiceRequest Multiple object types |
ISpecification | Attachments
Substances |
IAttachmentFile
ISubstance |
ISubstance | Attachments
Composition Where Used |
IAttachmentFile
ISubstance Multiple object types |
ISupplierResponse | Attachments | IAttachmentFile |
ISupplier | Attachments
Manufacturers Quality PSRs Quality QCRs |
IAttachmentFile
IManufacturer IServiceRequest IQualityChangeRequest |
ITransferOrder | Attachments
Selected Objects |
IAttachmentFile
Multiple object types |
IUser | Attachments
Subscription User Group |
IAttachmentFile
Multiple object types IUserGroup |
IUserGroup |
Attachments
Users |
IAttachmentFile
IUser |
The following example shows how to retrieve the referenced IChange
object from the Pending Changes table for an item.
Example 4-18 Retrieving a referenced Change object
void getReferencedChangeObject(ITable changesTable) throws APIException { Iterator i = changesTable.iterator(); while (i.hasNext()) { IRow row = (IRow)i.next(); IChange changeObj = (IChange)row.getReferent(); if (changeObj != null) { //Add code here to do something with the IChange object } } }
The following example shows how to simplify the code in the previous example by using the ITable.getReferentIterator()
method to iterate through the table's referenced objects.
void iterateReferencedChangeObjects(ITable changesTable) throws APIException {
Iterator i =
changesTable.getReferentIterator()
;
while (i.hasNext()) {
IChange changeObj = (IChange)i.next();
if (changeObj != null) {
//Add code here to do something with the IChange object
}
}
}
Sometimes you may want to perform an action on an object only if it meets certain status criteria. For example, if the selected object is a released change order, your program may not allow the user to modify it. To check the status of an object, use the IRow.isFlagSet()
method. The isFlagSet()
method returns a boolean value true or false.
Status flag constants are defined in the following classes:
CommonConstants
- Contains status flag constants common to Agile PLM objects.
ChangeConstants
- Contains status flag constants for IChange
objects.
ItemConstants
- Contains status flag constants for IItem
objects.
The following example shows how to use the isFlagSet()
method to determine whether an item has attachments.
Example 4-20 Checking the status flag of an object
private static void checkAttachments(IRow row) throws APIException {try { boolean b; b = row.isFlagSet(CommonConstants.FLAG_HAS_ATTACHMENTS);
if (!b) { JOptionPane.showMessageDialog(null, "The specified row does not have attached files.", "Error", JOptionPane.ERROR_MESSAGE); } } catch (Exception ex) {}}
Page One (that is, Title Block, Cover Page, and General Info pages), Page Two, and Page Three contain a single row of data and are therefore not tabular in format. All other tables contain multiple rows. Consequently, the data on PLM's Page One, Page Two, and Page Three are directly accessible. To get and set values for these pages, you don't need to get a table and then select a row. Instead, get a specified cell, and then use the getValue()
and setValue()
methods to display or modify the data.
If you prefer accessing data cells in a consistent way throughout your program, you can still use the Page One, Page Two, and Page Three tables to get and set values. The following example shows two methods that edit the values for several Page Two fields for an item. The first method retrieves the Page Two table and then sets the values for several cells. The second method accesses the Page Two cells directly by calling the IDataObject.getCell()
method. Either approach is valid, but you can see that the second approach results in fewer lines of code.
Example 4-21 Editing Page Two cells
// Edit Page Two cells by first getting the Page Two tableprivate static void editPageTwoCells(IItem item) throws Exception { ICell cell = null; DateFormat df = new SimpleDateFormat("MM/dd/yy"); ITable table = item.getTable(ItemConstants.TABLE_PAGETWO); Iterator it = table.iterator(); IRow row = (IRow)it.next(); cell = row.getCell(ItemConstants.ATT_PAGE_TWO_TEXT01); cell.setValue("Aluminum clips"); cell = row.getCell(ItemConstants.ATT_PAGE_TWO_MONEY01); cell.setValue(new Money(new Double(9.95), "USD")); cell = row.getCell(ItemConstants.ATT_PAGE_TWO_DATE01); cell.setValue(df.parse("12/01/03")); } // Edit Page Two cells by calling IDataObject.getCell()private static void editPageTwoCells2(IItem item) throws Exception { ICell cell = null; DateFormat df = new SimpleDateFormat("MM/dd/yy"); cell = item.getCell(ItemConstants.ATT_PAGE_TWO_TEXT01); cell.setValue("Aluminum clips"); cell = item.getCell(ItemConstants.ATT_PAGE_TWO_MONEY01); cell.setValue(new Money(new Double(9.95), "USD")); cell = item.getCell(ItemConstants.ATT_PAGE_TWO_DATE01); cell.setValue(df.parse("12/01/03"));}
SDK has added additional attributes in the CommonConstants
Class to support these new features, described below.
SDK supports setting and getting the following flags for Relationship rows that are Revision controlled.
RevisionChangeTrack Impact
Note: Because the impacted flag is set by releasing the change, SDK does not need to support setting the impacted flag. |
To enable this feature, the following attributes are added in SDK's CommonConstants
class:
public static final Integer ATT_RELATIONSHIPS_REVISION = new Integer(2000025267); public static final Integer ATT_RELATIONSHIPS_IMPACTED = new Integer(2000025266); public static final Integer ATT_RELATIONSHIPS_TRACK_IMPACT = new Integer(2000025268); public static final Integer ATT_RELATIONSHIPS_CHANGE = new Integer(2000025422);
The following example uses these attributes to set a revision change and track flags.
Example 4-22 Using attributes that set Revisions and track Flags
IItem item = (IItem) session.getObject(ItemConstants.CLASS_PART,"P00001");IChange change = (IChange) session.getObject(ChangeConstants.CLASS_ECO,"C00001"); item.setRevision(change); IRelationshipTable table = (IRelationshipTable) change.getRelationship(); Iterator it = table.iterator(); while (it.hasNext()) { IRow row = (IRow) it.next(); Object revision = row.getValue(ItemConstants.ATT_RELATIONSHIPS_REVISION); Object impacted = row.getValue(ItemConstants.ATT_RELATIONSHIPS_IMPACTED); Object trackImpact = row.getValue(ItemConstants.ATT_RELATIONSHIPS_TRACK_IMPACT); Object rchange = row.getValue(ItemConstants.ATT_RELATIONSHIPS_CHANGE); row.setValue(ItemConstants.ATT_RELATIONSHIPS_TRACK_IMPACT, "Yes"); }
The IRelationshipTable
is the interface for operations that are specific to the Relationships table. Once a Relationships table is retrieved, you can cast the ITable
object to IRelationshipTable
and use the following methods:
getRevisions(IDataObject dataObject)
throws APIException
- Gets all available revision values including ALL and Latest which can be used for adding revision specific relationships
addRevSpecificRelationship(IDataObject reatedObject,Object
- Gets all available revision values including ALL and Latest which can be used for adding revision specific relationships
acceptNewRevisions(IRow[] rows)
throws APIException - Accepts all new revisions
rejectNewRevisions(IRow[] rows) throws APIException
- Rejects all new revisions
Because SDK can interact with Revision, Change, Impacted attributes and the Track Impact attribute, you can set different relationships when setting different revisions for an Item. This is shown in Example 4-23.
Example 4-23 Setting changes for Item's Revisions and Relationships
// When Revision specific relationship is enabled on Change Object, you can add// two different Revisions of the same Part object into one Change Object's // relationship table. IChange change = (IChange) session.getObject(ChangeConstants.CLASS_ECO, "C00001");IRelationshipTable table = (IRelationshipTable) change.getRelationship();IItem item = (IItem) session.getObject(ItemConstants.CLASS_PART, "P00001");item.setRevision('A C00001');// Add Part "P00001" with Rev "A" into Change "C00001"'s relationshiptable.addRevSpecificRelationship(item, null);item.setRevision('B C00002');// Add Part "P00002" with Rev "B" into Change "C00002"'s relationshiptable.addRevSpecificRelationship(item, null);
When you issue a change for a released item or a price agreement, the you can invoke Agile API to redline certain tables affected by the change. In the Agile PLM Clients, redline tables visually identify values that were modified from the previous revision. Red underlined text, thus the term ”redline” indicates values that were added, and red strikeout text indicates values that were deleted. Users responsible for approving the change can review the redline data.
The Agile PLM system provides the following redline tables:
Redline BOM
Redline Manufacturers (AML)
Redline Price Lines
Redline Title Block
Note: The Web Client supports redlining the Item's Cover Page, Page Two, and Page Three tables together. However, in the SDK, these operations are performed separately, using different tables for each page. |
Use the following procedure to redline these tables.
To redline BOM, Manufacturers, or Price Lines tables:
Get a released revision of an item or price object.
Create a new change, such as an ECO, MCO, SCO, or PCO
ECOs enable modifying an item's BOM or Manufacturers tables
MCOs enable modifying an item's Manufacturers table
SCOs enable modifying an item's site-specific BOM, Manufacturers
PCOs enable modifying a price's Price Lines table
Add the item or price to the Affected Items or Affected Prices table of the change.
For ECOs and PCOs, specify the new revision for the change.
SCOs and MCOs do not affect an item's revision.
Modify a redline table, such as the Redline BOM, Redline Manufacturers (AML), Redline Price Lines.
Example 4-24 redlines the Manufacturers table (AML) of an item.
Example 4-24 Redlining the Manufacturers table of an item
private void redlineAML() throws APIException {IAttribute attrPrefStat = null;IAgileList listvalues = null;Map params = new HashMap(); // Get a released itemIItem item = (IItem)m_session.getObject("Part", "1000-02"); // Get the Preferrred status valueIAgileClass cls = item.getAgileClass();attrPrefStat = cls.getAttribute(ItemConstants.ATT_MANUFACTURERS_PREFERRED_STATUS);listvalues = attrPrefStat.getAvailableValues(); // Create an MCOIChange change = (IChange)m_session.createObject(ChangeConstants.CLASS_MCO, "M000024"); // Set the Workflow ID of the MCOchange.setWorkflow(change.getWorkflows()[0]); // Get the Affected Items tableITable affectedItems = change.getTable(ChangeConstants.TABLE_AFFECTEDITEMS); // Add a new row to the Affected Items tableIRow affectedItemRow = affectedItems.createRow(item); // Get the Redline Manufacturers tableITable redlineAML = item.getTable(ItemConstants.TABLE_REDLINEMANUFACTURERS); // Add a manufacturer part to the tableparams.put(ItemConstants.ATT_MANUFACTURERS_MFR_NAME, "AMD");params.put(ItemConstants.ATT_MANUFACTURERS_MFR_PART_NUMBER, "1234-009");params.put(ItemConstants.ATT_MANUFACTURERS_PREFERRED_STATUS, listvalues);redlineAML.createRow(params); // Add another manufacturer part to the tableparams.clear();params.put(ItemConstants.ATT_MANUFACTURERS_MFR_NAME, "DIGITAL POWER");params.put(ItemConstants.ATT_MANUFACTURERS_MFR_PART_NUMBER, "355355");params.put(ItemConstants.ATT_MANUFACTURERS_PREFERRED_STATUS, listvalues);redlineAML.createRow(params); }
The following is an example of redlining the Title Block table of the item. It assumes Item.Page_Two and the attribute Text01 are visible and Text01 is change controlled.
Example 4-25 Redlining the Title Block table of an item
ITable page2Tab = item.getTable(ItemConstants.TABLE_REDLINEPAGETWO);Iterator it = page2Tab.getTableIterator();IRow redPage2Row = (IRow)it.next();ICell cell = redPage2Row.getCell(CommonConstants.ATT_PAGE_TWO_TEXT01);System.out.println("old value, before update: " + cell.getOldValue());redPage2Row.getCell (CommonConstants.ATT_PAGE_TWO_TEXT01).setValue("updated Text01);
When you make redline changes to a table such as a BOM table, you may want to undo the changes for a row and restore it to its original state. You can use the IRedlinedRow.undoRedline() method to undo any redline changes to a row.
If you undo the redlines for a row, any cells that are modified are restored to their original values. A redlined row can also be one that was added or deleted. If you undo the redlines for a row that was added, the entire row is removed from that revision. If you undo the redlines for a row that was deleted, the entire row is restored.
Example 4-26 Removing redline changes from the BOM table
private static undoBOMRedlines(IItem item, String rev) throws APIException { ITable redlineBOM = item.getTable(ItemConstants.TABLE_REDLINEBOM); Iterator it = redlineBOM.iterator(); while (it.hasNext()) { IRedlinedRow row = (IRedlinedRow)it.next(); row.undoRedline(); }}
Agile SDK enables removing (undoing) redlines with the aid of IRedlinedTable. This interface provides the API to perform bulk redline undos with the aid of the following interfaces:
IRedlinedTable.undoRedline(Collection rows)
;
IRedlinedTable.undoAllRedline();
Example 4-27 Typecasting Redline tables to IRedlinedTable interface
IItem item = (IItem) session.getObject(ItemConstants.CLASS_PART, "PART_001"); item.setRevision("B"); // Unreleased changeITable bomTable = item.getTable(ItemConstants.TABLE_REDLINEBOM);Iterator it = bomTable.iterator(); List rows = new ArrayList(); while(it.hasNext()) { IRow row = (IRow) it.next(); if(((IRedlined)row).isRedlineModified())rows.add(row);}
Note: Only Redline tables can be typecasted to IRedlinedTable interface in the following two ways. For more information, see "Redlining."
|
The IRedlined interface is designed to identify redlined rows and redlined cells. It is only supported on redlined tables. The interface works in conjunction with the isRedlineModified() method to show if objects are redlined. The interface typecasts IRow and ICell objects as follows:
IRow indicates if the row is redline modified
ICell indicates if the cell is redline modified.
Note: The IRedlined.isRedlineModified() method returns a boolean value. This value is TRUE when cells or rows are redlined and FALSE value for all cells on redline added or redline removed rows. |
With the introduction of the IRedlined interface, the ICell.getOldValue() method is no longer defined for redline added and redline removed rows. The ICell.getOldValue() method has a meaningful result only when FLAG_IS_REDLINE_MODIFIED is true for the row.
Note: Do not call this method for redline added or redlined removed rows. |
Footnote Legend
Footnote 1: See Metadata Interface under "Types of Agile API Classes and Interfaces."