Skip Headers

Agile Product Lifecycle Management Web Services Guide Release 9.3.3 E39310-01 |
| Contents

Previous |

# C Working with Java Sample Code

This section describes helper methods and other aspects useful for developing the web services.

The Java Sample Codes covered in this book, and those available for download from eDelivery.oracle.com site, demonstrate various usage characteristics of Agile 933 Web Services.

Apart from outlining the basic cases for each Web Service, they also elaborate upon more specific cases that involve usage of options or mandatory message elements.

Download these Sample Codes in 'src' directory. They are categorized into different packages based on the type of Web Service, which are AdminMetaData, Attachment, Business, Collaboration, PC, Search and Table.

Batch files for building and running samples independent of a java IDE are also provided.

## C.1 Building Stubs and Compiling the Samples

A batch file build.bat has been provided, which is located in the main directory JavaWeb Servicesamples. This batch file uses ant tasks to generate stubs for Agile Web Services and compiles the java sample files after generation of these stubs.

Along with build.bat, you will find a file custom.properties file that specifies the basic configuration properties, such as the Agile server URL, username, password of your user and also the URL of DFM. Unless this property file is edited to reflect the values appropriate for your Agile environment, you will not be able to generate stubs or run the samples.

After ensuring that 'custom.properties' has been modified appropriately, run the batch file 'build.bat'. Running the same through a command prompt may help in identifying error statements (if any) that are echoed onto the console. If the message 'BUILD SUCCESSFUL' displays on the console then the build process was completed without any errors. However, if the message 'BUILD FAILED' is observed on the console, your 'custom.properties' configuration may be incorrect and you need to verify the same.

The stubs and the compiled samples are added to the folder build/built/*.jar as two jar files 'ws_samples.jar' and 'ws_stubs.jar' which are used later while running the sample.

## C.2 Executing the Samples using ant Task

After building the stubs and compiling the sample files by following the steps outlined in Building Stubs and Compiling the Samples on page 406, any sample file can be readily executed using the batch file run.bat and specifying the fully qualified class name as an argument.

Browse the source directory 'JavaWeb Servicesamples/src' to find the package structure of the sample that you are looking for.

For example, to the run the sample 'CreateObjectAPIName' that creates an object using API names, the following command must be executed through command prompt:

run business.create.CreateObjectAPIName

Similarly, to run a sample from another sample package, say AddRowsSiteSpecific of the table Web Service, use the command:

run table.addrows.AddRowsSiteSpecific

If no argument is passed to run.bat, then all the available samples will be executed sequentially.

Note: While running samples using this ant task, the Agile server URL, username and password properties are retrieved from the same 'custom.properties' file that was used for building stubs.

## C.3 Executing the Samples using a Java IDE

To run the sample files from a Java IDE, such as JDeveloper or Eclipse, create a new project or workspace in your IDE (as applicable to your IDE) and in your project properties modify / add project source paths to include the 'JavaWeb Servicesamples/src' directory where the sample source code is located.

You will also need to update your project library or classpath information to include all the necessary classes of Axis and other Agile jar files which have been used in the course of sample development.

Ensure that you have added all the jar files under the folders 'JavaWeb Servicesamples/build/axis' and 'JavaWeb Servicesamples/build/lib' to your library / classpath.

Any sample file can now be executed by browsing through the package structure, and running the desired sample.

Note The static variables relating to Agile server url, username and password in each java sample must be modified, if you choose to run the sample through an IDE.

## C.4 Understanding the Code

Each java sample file contains header documentation at the class level explaining the functionality or usage scenario that the sample demonstrates. A set of static variables relating to server url, username, password and variables specific to that sample, like partNumber or folderName or nextStatus, are declared here.

If the sample is executed using the ant task (via run.bat), then the server configuration related static variables are overridden by the method checkArguments(String[] args(), which obtains arguments from the ant task and reinitializes server URL username, password and DFM URL variables.

In the case of a sample executed through a Java IDE, the server configuration variables must be modified manually to reflect the server settings of your Agile server.

With the exception of adminMetaData services, all samples provided here use the method prepareData() to prepare all the data prerequisites necessary to create a scenario using which a particular Web Service may be demonstrated meaningfully.

For example, if the sample demonstrates usage of the operation loadTable to load a table from a particular version of an Agile object, prepareData() will do the following:

1. Create a part object

2. Add a change, modify the part

3. Provide a new version number

4. Release the change.

After the data has been prepared, the operation loadTable is now used with the option 'version' to demonstrate the retrieval of a table from a particular version of an Agile object.

If you intend to use your own data or scenario to execute a Web Service sample, comment out the 'prepareData();' statement in the main method of that sample. After this, edit the static variables at the top of the code and specify your own data.

All the operations performed in data preparation are also achieved using Agile 93 Web Services. To gain a broader understanding of how Web Services are used in conjunction to orchestrate a larger task, examine the file DataPrepare.java in the package src/run/DataPrepare.java

The sample files are documented with comments at each stage and evince several usage characteristics of these Web Services while illustrating how basic requests are formed and how the responses obtained are used.

## C.5 AddFileSOAPAttachment Method

This sample method demonstrates addition of a file attachment to the Attachment Tab of an Agile object using SOAP.

Example: Adding a file attachment to the Attachment tab of an Agile object using SOAP

Basic Steps

- Create the request object AddFileAttachmentRequestType for the addFileAttachment operation.

- Create an array of requests of type AgileAddFileAttachmentRequestType. Batch operations may be performed by populating as many request objects as required to add several files to different objects with one single operation.

- For each batched request, specify the unique object to whose attachment tab the files are to be added. Supply class identifier and object number information for the same.

- The exact specification of the attachment to be added is defined as an object of type AgileAddFileAttachmentRequestType. This object includes information about the name of the file and its description and content.

- While using SOAP attachments, create a datahandler to specify the file source and add the content as a soap attachment to the soap request. Finally set the contentId onto AgileAddFileAttachmentRequestType.

- The request objects are set and the Agile Stub is used to make the addFileAttachment Web Service call. The status code obtained from the response object is printed to verify the success of the addFileAttachment operation.

- If the Web Service call was successful, then state the same.

- If the status code is not 'SUCCESS', then populate the list of exceptions returned by the Web Service.

Sample Code

SOAP

    try {
    setupServerLogin();

    AddFileAttachmentRequestType addFileAttachmentRequestType =
        new AddFileAttachmentRequestType();
    AgileAddFileAttachmentRequest agileAddFileAttachmentRequest[] =
        new AgileAddFileAttachmentRequest[1];
    agileAddFileAttachmentRequest[0] =
            new AgileAddFileAttachmentRequest();
    agileAddFileAttachmentRequest[0].setClassIdentifier("Part");
    agileAddFileAttachmentRequest[0].setObjectNumber(partNumber);
    System.out.println("Adding a SOAP attachment to the part '" +
                       partNumber + "'...");
    AgileAddFileAttachmentRequestType attachments[] = new AgileAddFileAttachmentRequestType[1];
    attachments[0] =
            new AgileAddFileAttachmentRequestType();
    attachments[0].setName("Filename.txt");
    attachments[0].setDescription("Description for file ");

    String filename = "sample123456.txt";
    BufferedWriter out =
        new BufferedWriter(new FileWriter(filename));
    out.write("Test file");
    out.close();

    DataHandler dh =
        new DataHandler(new FileDataSource(filename));
    AttachmentPart ap = new AttachmentPart(dh);
    agileStub.addAttachment(ap);
    attachments[0].setContentId(ap.getContentId());

    agileAddFileAttachmentRequest[0].setAttachments(attachments);
    agileAddFileAttachmentRequest[0].setSingleFolder(false);

    addFileAttachmentRequestType.setRequests(agileAddFileAttachmentRequest);
    AddFileAttachmentResponseType addFileAttachmentResponseType =
        agileStub.addFileAttachment(addFileAttachmentRequestType);
    System.out.println("\nSTATUS CODE: " +
                       addFileAttachmentResponseType.getStatusCode());
    if (!addFileAttachmentResponseType.getStatusCode().toString().equals(ResponseStatusCode.SUCCESS.getValue())) {
        AgileExceptionListType[] agileExceptionListType =
            addFileAttachmentResponseType.getExceptions();
        if (agileExceptionListType != null)
            for (int i = 0;
                 i < agileExceptionListType.length;
                 i++) {
                AgileExceptionType exceptions[] =
                    agileExceptionListType[i].getException();
                for (int j = 0;
                     j < exceptions.length; j++)
                    System.out.println("Exception Id:" +
                                       exceptions[j].getExceptionId() +
                                       "\nMessage: " +
                                       exceptions[j].getMessage());
            }

        AgileWarningListType agileWarningListType[] =
            addFileAttachmentResponseType.getWarnings();
        if (agileWarningListType != null)
            for (int i = 0;
                 i < agileWarningListType.length;
                 i++) {
                AgileWarningType warnings[] =
                    agileWarningListType[i].getWarning();
                for (int j = 0;
                     j < warnings.length; j++)
                    System.out.println("Warning Id: " +
                                       warnings[j].getWarningId() +
                                       "\nMessage: " +
                                       warnings[j].getMessage());
            }
    } else {
        AgileAddFileAttachmentResponse responses[] =
            addFileAttachmentResponseType.getResponses();
        if (responses != null)
            for (int i = 0; i < responses.length;
                 i++) {
                System.out.println("The specified SOAP attachment was successfully added to the Attachment tab");
                System.out.println("of the object: " +
                                   responses[i].getObjectNumber());
            }
    }
    }

## C.6 Helper Methods

The getRowID and getFileId are custom helper methods. These are not Agile Web Services operations.

### C.6.1 getRowId Method

Service

This topic describes how you can obtain the rowId for a row on an Agile table

Usage

Several table and attachment operations require the rowId as input for executing a Web Service. In such cases, the loadTable operation is used to load the table that contains the required row and then iterated through the results till the row is found.

To find a particular row in a table, a keyword may be used to search and identify the row. In this example, the filename is used as the key to identify a row.

Search all the rows available in the attachment table and compare all message elements with tag names 'filename' with the filename specified by the client, looking for a match. Once a match is found, the rowId information is derived from the row and returned.

Compare all 'filename' message elements, searching for a match with the filename specified by the user. If a match is found, return either the fileId or rowId based on the requirement.

Note: getValueFromSelection is a method written in this sample that handles all message elements of type AgileListEntryType. Since 'filename' is a message element of AgileListEntryType, the values are elicited by this method.

Usage

Handle all AgileListEntryType message elements, cycle through the selection element, obtain the actual selection value and the selection Id and add it to a HashMap. Here the selection value denotes the filename while the selection Id denotes the fileId.

In the case of Filefolders the message element for file name is not an AgileListEntryType. The value may be obtained directly.

Basic Steps

To get a Row ID:

1. Create the request object LoadTableRequestType for the loadTable operation.

2. For each request, specify the table to which the row belongs.

3. Tables in Agile Web Services are defined as RequestTableType objects. A specific table may be identified by specifying the class identifier and table identifier attributes.

4. The request objects are set and the agile Stub is used to make the loadTable Web Service call. The status code obtained from the response object is printed to verify the success of the loadTable operation.

5. If the status code indicates 'SUCCESS', use the table results to find the required row. Once the row is found, its rowId is returned. If the status code indicates that the Web Service call was not successful, populate a list of exceptions.

6. Search for the required row by using the filename to look for a match and return the rowId.

Sample Code getRowId

    public static int getRowId(String filename, String classIdentifier, String objectNumber, String tableId){
    try{
    setupServerLogin_LoadTable();
    LoadTableRequestType loadTableRequestType = new LoadTableRequestType();

    RequestTableType table[] = new RequestTableType[1];
    table[0] = new RequestTableType();
    table[0].setClassIdentifier(classIdentifier);
    table[0].setObjectNumber(objectNumber);
    table[0].setTableIdentifier( tableId );

    loadTableRequestType.setTableRequest(table);
    LoadTableResponseType loadTableResponseType = agileStub_Table.loadTable(loadTableRequestType);
    System.out.println("Obtaining row Id / fileId information.....");
    System.out.println("STATUS CODE: " +  loadTableResponseType.getStatusCode() );

        if( loadTableResponseType.getStatusCode().toString().equals( ResponseStatusCode.SUCCESS.getValue() ) ){
            AgileTableType[] tables = loadTableResponseType.getTableContents();
            return findRowId(tables, filename);
        }
        else{
            System.out.println("<Failed to load table information>");
            AgileExceptionListType[] agileExceptionListType = loadTableResponseType.getExceptions();
            if(agileExceptionListType!=null)
            for(int i=0; i<agileExceptionListType.length; i++){
                AgileExceptionType exceptions[] = agileExceptionListType[i].getException();
                for(int j=0; j<exceptions.length; j++)
                    System.out.println(exceptions[j].getMessage() );
            }

            AgileWarningListType agileWarningListType[] = loadTableResponseType.getWarnings();
            if(agileWarningListType!=null)
            for( int i=0; i<agileWarningListType.length; i++){
                AgileWarningType warnings[] = agileWarningListType[i].getWarning();
                for(int j=0; j<warnings.length; j++)
                    System.out.println("Warning Id: " + warnings[j].getWarningId() + "\nMessage: " + warnings[j].getMessage() );
            }
        }
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }
    return -1;
    }

    public static int findRowId(AgileTableType[] tables, String filename){
    if(tables!=null)
        for(int i=0; i<tables.length; i++){
            AgileRowType[] rows = tables[i].getRow();
            if(rows!=null)
                for(int j=0; j<rows.length; j++){
                    MessageElement[] messages = rows[j].get_any();
                    for(int m=0; m<messages.length; m++){

                        if( messages[m].getName().toString().equalsIgnoreCase("filename") ){
                            HashMap fileValues[] = getValuesFromSelection(messages[m]); for(HashMap fileValue:fileValues)
                                if( fileValue.get("filename").equals(filename) ){
                                        System.out.println("Row Id successfully retrieved.");
                                        return rows[j].getRowId();
                                }
                        }
                    }

                }

        }
    return 0;
    }

    public static HashMap[] getValuesFromSelection(MessageElement element){
        HashMap fileValues[] = null;
        if(element.getType().getLocalPart().equals("AgileListEntryType")){

            AgileListEntryType list = (AgileListEntryType) element.getObjectValue();
            SelectionType selection[] = list.getSelection();
            fileValues = new HashMap [selection.length];
            for(int i=0; i<selection.length; i++){
                fileValues[i] = new HashMap();
                fileValues[i].put("filename", selection[i].getValue() );
                fileValues[i].put("fileid", selection[i].getId() );
            }
        }
        else{
            fileValues = new HashMap [1];
            fileValues[0] = new HashMap();
            fileValues[0].put("filename", element.getFirstChild().getNodeValue() );
            fileValues[0].put("fileId", null );
        }
        return fileValues;
    }

#### C.6.1.1 getFileId Method

Service

This topic describes how you can obtain the FileId for a Row on an Agile Table.

Usage

Several attachment operations require the fileId as input for executing. For example, if a particular attachment row has several files associated with it, the fileId is necessary to differentiate between each file available on that row.

In such cases, you first use the loadTable Web Service to load the table that contains the required row, iterate through the results till the row is found. To find a particular row in a table, use a keyword and identify the row

In this example, the filename is used as the key to identify a row. Once the filename message element is obtained as an AgileListEntry Type element, the 'id' value of the SelectionType element may be returned. This 'id' tag corresponds to the fileId of that file attachment.

Search all the rows available in the attachment table and compare all message elements with tag names 'filename' with the filename specified by the client, looking for a match. Once a match is found, fileId information is derived from the filename selection elements, whose 'id' corresponds to the fileId.

Compare all 'filename' message elements, searching for a match with the filename specified by the user. If a match is found, return either fileId.

Note: If both rowId and fileId values are necessary, then a similar approach may be used to obtain both the rowId and fileId for a particular file attachment from an attachment row

Note: getValueFromSelection is a method written in this sample that handles all message elements of type AgileListEntryType. Since 'filename' is a message element of AgileListEntryType, the values are elicited by this method.

Usage

Handle all AgileListEntryType message elements, cycle through the selection element, obtain the actual selection value and the selection ID and add it to a HashMap. Here the selection value denotes the filename while the selection ID denotes the fileId.

In the case of Filefolders the message element for file name is not an AgileListEntryType. The value may be obtained directly.

Basic Steps

To get a File ID:

1. Create the request object LoadTableRequestType for the loadTable operation.

2. For each request, specify the table to which the row belongs. Tables in Agile Web Services are defined as RequestTableType objects. A specific table may be identified by specifying the class identifier and table identifier attributes.

3. The request objects are set and the agile Stub is used to make the loadTable Web Service call. The status code obtained from the response object is printed to verify the success of the loadTable operation.

4. If the status code indicates 'SUCCESS', search and retrieve the fileId.

5. Search for the necessary fileId by using the filename to look for a match and return either of the two, as per the requirement specified in the input parameter 'methodType'.

6. If the status code indicates that the Web Service call was not successful, populate a list of exceptions.

Sample Code getFileId

    public static int getFileId(String filename, String clazz, String objectNumber, String tableId){
    try{
    setupServerLogin_LoadTable();
    LoadTableRequestType loadTableRequestType = new LoadTableRequestType();
    RequestTableType table[] = new RequestTableType[1];
    table[0] = new RequestTableType();
    table[0].setClassIdentifier(clazz);
    table[0].setObjectNumber(objectNumber);
    table[0].setTableIdentifier( tableId );

    loadTableRequestType.setTableRequest(table);
    LoadTableResponseType loadTableResponseType = agileStub_Table.loadTable(loadTableRequestType);
    System.out.println("Obtaining row Id / fileId information.....");
    System.out.println("STATUS CODE: " +  loadTableResponseType.getStatusCode() );

        if( loadTableResponseType.getStatusCode().toString().equals( ResponseStatusCode.SUCCESS.getValue() ) ){
            AgileTableType[] tables = loadTableResponseType.getTableContents();
            return findFileId(tables, filename);
        }

        else{
            System.out.println("<Failed to load table information>");
            AgileExceptionListType[] agileExceptionListType = loadTableResponseType.getExceptions();
            if(agileExceptionListType!=null)
            for(int i=0; i<agileExceptionListType.length; i++){
                AgileExceptionType exceptions[] = agileExceptionListType[i].getException();
                for(int j=0; j<exceptions.length; j++)
                    System.out.println(exceptions[j].getMessage() );
            }

            AgileWarningListType agileWarningListType[] = loadTableResponseType.getWarnings();
            if(agileWarningListType!=null)
            for( int i=0; i<agileWarningListType.length; i++){
                AgileWarningType warnings[] = agileWarningListType[i].getWarning();
                for(int j=0; j<warnings.length; j++)
                    System.out.println("Warning Id: " + warnings[j].getWarningId() + "\nMessage: " + warnings[j].getMessage() );
            }
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return -1;
    }

    public static int findFileId(AgileTableType[] tables, String filename){
        if(tables!=null)
            for(int i=0; i<tables.length; i++){
                AgileRowType[] rows = tables[i].getRow();
                if(rows!=null)
                    for(int j=0; j<rows.length; j++){
                        MessageElement[] messages = rows[j].get_any();
                        for(int m=0; m<messages.length; m++){

                            if( messages[m].getName().toString().equalsIgnoreCase("filename") ){
                                HashMap fileValues[] = getValuesFromSelection(messages[m]);
                                for(HashMap fileValue:fileValues)
                                    if( fileValue.get("filename").equals(filename) ){
                                        System.out.println("File Id successfully retrieved.");
                                        return (Integer) fileValue.get("fileid");
                                    }
                            }
                        }

                    }
            }
        return 0;
    }

    public static HashMap[] getValuesFromSelection(MessageElement element){
        HashMap fileValues[] = null;
        if(element.getType().getLocalPart().equals("AgileListEntryType")){

            AgileListEntryType list = (AgileListEntryType) element.getObjectValue();
            SelectionType selection[] = list.getSelection();
            fileValues = new HashMap [selection.length];
            for(int i=0; i<selection.length; i++){
                fileValues[i] = new HashMap();
                fileValues[i].put("filename", selection[i].getValue() );
                fileValues[i].put("fileid", selection[i].getId() );
            }
        }
        else{
            fileValues = new HashMap [1];
            fileValues[0] = new HashMap();
            fileValues[0].put("filename", element.getFirstChild().getNodeValue() );
            fileValues[0].put("fileId", null );
        }
        return fileValues;
    }

## C.7 Troubleshooting

Issue #7639814: API names are not available for a huge set of lists.

Resolution: GetLists Admin service is supported only for Admin Lists which can be found in JavaClient>Admin>Lists. Some class specific lists are not exposed in Admin Lists.

To get values for these Lists, use GetAttributes Admin service, which will return AttributeType. This, in turn, has availableValues as AdminListType. This list values can be used for updateObject or createObject.

Issue #8253064: Group sign-off option cannot be set from Web Services.

Resolution: Group sign-off is not supported in the current release.

Issue #9308516: undoRedline operation error message does not convey the wrong "option name" given.

Resolution: If you do not use option "redline_change", or if it is wrongly entered as "redline_chg", the correct revision of the item will not be loaded. Only the latest released revision will be loaded. In that revision of the item BOM table, the given row id is invalid and hence the invalid rowId exception is thrown. The behavior seems acceptable.