1.9 Getting Items

There are different ways to retrieve items from a GroupWise container. Each of these methods has an input parameter of a container. A container is an abstract wrapper of GroupWise items. A container can be a GroupWise folder, address book, or library.

There are special strings to use as the container ID. The folders attribute can be used to search over all folders in the user’s mailbox. (This searches all of the folders with the exception of shared folders shared with the user, query folders and the Trash folder.) The books attribute can be used to search over all personal address books.

This section contains the following sections:

1.9.1 Get Items Request

getItemsRequest can retrieve items from folders, query folders, shared folders, personal address books, the GroupWise Address Book, libraries, document versions, and document version events.

NOTE:If you are getting more than 20 items, you should use the cursor request, as described in GroupWise Cursors.

For GroupWise 2012 and later:

There are times when you have an item id, but you don’t know what container the item is in. You can use getItemsRequest to return the item. You pass the id value in an <item> element of the <items> element. You pass folders or books as the container.

<getItemsRequest>
  <container>folders</container>
  <view>id status subject startDate created</view>
  <items>
    <item>4E92DD25.domain.PO1.100.1776172.1.454BF.1</item>
  </items>
</getItemsRequest>

If you have a sid, you can pass that. (You must also pass sid in the view, so the code knows the value is sid and not an id.)

<getItemsRequest>
  <container>folders</container>
  <view>id sid status subject startDate created</view>
  <items>
    <item>283839</ans1:item>
  </items>
</getItemsRequest>

On folder items, using folders as the container, the code cannot find the item in a shared folder shared with the user. On personal address books, the code can find the item even in personal address books shared with the user.

When you have events, the event sometimes does not include what container the item is in. There is a special formatted id you can use to quickly read the item. For example, if you have the following event:

event>ItemModify</event>
  <id>4E9D1539.domain.PO1.100.1776172.1.46167.1</id>
  <sid>287079</sid>
  <timeStamp>2011-10-18T12:16:24Z</timeStamp>
  <field>MessageBody Subject</field>
  <key>test</key>
  <uid>868965</uid>
  <type>Mail</type>
</event>

Then you combine the <id> and the <uid> values to generate an id:

4E9D1539.domain.PO1.100.1776172.1.46167.1@Event:868965

You pass this id in the <item> element. The code can quickly verify the user has the right to read the item.

NOTE:The event record must still exist in this case. The code uses the event record to verify that the user has access to the item. If the event record is already deleted, this method of getting the item fails.

<getItemsRequest>
  <container>folders</container>
  <view>id status subject startDate created</view>
  <items>
    <item>4E9D1539.domain.PO1.100.1776172.1.46167.1@Event:868965</item>
  </items>
</getItemsRequest>

1.9.2 GroupWise Cursors

GroupWise cursors provide you with a method to retrieve large amounts of container data in chunks. Cursors can be used to retrieve a subset of items with subsequent methods instead of getting all the items in one response. For example, suppose a user has 1,000 items in a folder and you retrieve 100 items per call. To retrieve all 1,000 items would mean calling a method 10 different times.

Cursors also provide you with the ability to read items from the start or end of a list. For example, there is a container with 1000 items. Item 1 is the start of the list and item 1000 is the end of the list. You can use cursors to read items from the start to the end of the list (item 1 to item 1000), or you can use cursors to read items from the end to the start of the list (item 1000 to item 1).

GroupWise cursors require the use of several methods. The methods are:

A cursor has an anchor position in the list of items. The anchor position can be the start of the list, the current position in the list, or the end of the list. The readCursorRequest and positionCursorRequest method can position the anchor in the list. For example, there is another container with 1,000 items, with item 1 at the start position and item 1,000 at the end position. As you read items by calling readCursorRequest, the cursor position moves. If you read 100 items with readCursorRequest, the anchor position of the cursor is 101. The next time you call readCursorRequest, reading starts at item 101 if the position element is current.

readCursorRequest has a forward element. If the forward element is True, readCursorRequest reads from the starting anchor position to the ending anchor position. If the forward element is False, readCursorRequest reads from the ending anchor position to the starting anchor position.

Cursor data can become stale. For example, you create a cursor that points to a folder. If an item is added to the folder after the cursor is created, it does not return the new item by calling readCursorRequest. You need to create a cursor, read the data, and then close or destroy the cursor.

Consider the following when working with GroupWise cursors:

  • You can create more than one cursor per logged-in user.

    NOTE:Do not create a large number of cursors per user, because it creates overhead that might degrade your system’s performance.

  • You can use cursors on folders, shared folders, personal address books, and the GroupWise Address Book.

  • You cannot use cursors on contact folders or query folders.

  • You cannot use cursors to get documents from a library.

    For example, you cannot use cursors to get documents from the Authored Library or the Default Library.

    Using cursors to read the Documents folder returns document references only; it does not return the documents themselves. Use streamedSearchRequest on document libraries in the place of cursors.

If a container does not support cursors, the following error is returned:

<createCursorResponse>
<status>
<code>59916</code> 
<description>The method called is not supported.</description> 
</status>
</createCursorResponse>

Cursor Examples

This section contains the following examples:

readCursorRequest (forward)

In the following example, readCursorRequest returns items in order of oldest to newest. The container is the Mailbox. The forward element is True, and the position element is current. Five items are returned because the count element is set to 5.

The first call to readCursorRequest returns items 1 to 5.

<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833449</cursor> 
   <forward>true</forward> 
   <position>current</position> 
   <count>5</count> 
</readCursorRequest>

<readCursorResponse> 
   <items> 
      <item> 
         <id>450AB7C1.domain1.po1.100.16E3837.1.FD0.1@1:7.
               domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-15T22:23:28Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>1</subject> 
      </item>
      . . .items 2, 3, and 4
      <item> 
         <id>450AB7EA.domain1.po1.100.16E3837.1.FD8.1@1:7.
                 domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-15T22:23:28Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>5</subject> 
      </item>
   </items>
   <status> 
      <code>0</code> 
   </status> 
</readCursorResponse>

The next call to readCursorRequest returns items 6-10.

<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833449</cursor> 
   <forward>true</forward> 
   <position>current</position> 
   <count>5</count> 
</readCursorRequest>
<readCursorResponse > 
   <items> 
      <item> 
         <id>450AD389.domain1.po1.100.16E3837.1.1002.1@1:7.
                      domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:27Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>6</subject> 
      </item> 
      . . .items 7, 8, and 9
      <item>
         <id>450AD3A8.domain1.po1.100.16E3837.1.100A.1@1:7.
                   domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:29Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>10</subject> 
      </item> 
   </items> 
   <status> 
      <code>0</code> 
   </status> 
</readCursorResponse> 

readCursorRequest (backward)

In the following example, readCursorRequest returns items in order of newest to oldest. The container is the Mailbox. The forward element is False, and the position element is end. Five items are returned because the count element is set to 5.

The first call to readCursorRequest returns items 25 to 21.

<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833450</cursor> 
   <forward>false</forward> 
   <position>end</position> 
   <count>5</count> 
</readCursorRequest>
<readCursorResponse> 
   <items> 
      <item> 
         <id>450AD40A.domain1.po1.100.16E3837.1.1028.1@1:7.
                  domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:36Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>25</subject> 
      </item> 
      . . .items 24, 23, and 22
      <item>
         <id>450AD3F2.domain1.po1.100.16E3837.1.1020.1@1:7.
                      domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:34Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>21</subject> 
      </item>
   </items>
   <status> 
      <code>0</code> 
   </status> 
</readCursorResponse>

The next call to readCursorRequest returns items 20 to 16.

<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833450</cursor> 
   <forward>false</forward> 
   <position>current</position> 
   <count>5</count> 
</readCursorRequest>
<readCursorResponse> 
   <items>
      <item> 
         <id>450AD3EB.domain1.po1.100.16E3837.1.101E.1@1:7.
                             domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:34Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>20</subject> 
      </item>
      . . .items 19, 18, and 17
      <item>
         <id>450AD3D4.domain1.po1.100.16E3837.1.1016.1@1:7.
                     domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:32Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>16</subject> 
      </item>
   </items>
   <status> 
      <code>0</code> 
   </status> 
</readCursorResponse>

positionCursorRequest (backward)

NOTE:The positionCursorRequest method can produce unexpected results. Instead of using this method, we recommend that you use readCursorRequest to read from the beginning or the end.

In the following example, positionCursorRequest positions the anchor at the end of the list with an offset of 5. The list end is item 25. Taking into account the offset from the end of the list, the anchor position is at item 20. readCursorRequest moves backward in the list because the forward element is False, and the position element is current, which means to start the read at the current anchor position of 20.

<positionCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833452</cursor> 
   <seek>end</seek> 
   <offset>5</offset> 
</positionCursorRequest>
<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1186833452</cursor> 
   <forward>false</forward> 
   <position>current</position> 
   <count>5</count> 
</readCursorRequest>
<readCursorResponse> 
   <items> 
      <item> 
         <id>450AD3EB.domain1.po1.100.16E3837.1.101E.1@1:7.
                      domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:34Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>20</subject> 
      </item> 
      . . .items 19, 18, and 17
      <item> 
         <id>450AD3D4.domain1.po1.100.16E3837.1.1016.1@1:7.
                      domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-19T19:26:32Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>16</subject> 
      </item> 
   </items> 
   <status> 
      <code>0</code> 
   </status> 
</readCursorResponse>

createCursorRequest

The following example demonstrates creating a cursor with a filter and a view by calling createCursorRequest. The view specifies the elements that should be returned for each item in the request. The filter narrows the items that are read in the user's database. The following filter indicates to read items with a created date that is greater than 2012-08-13.

<createCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <view>modified subject</view> 
   <filter> 
      <element type="FilterEntry"> 
         <op>gt</op> 
         <field>created</field> 
         <value>2012-08-13T00:00:00Z</value> 
      </element> 
   </filter> 
</createCursorRequest>
<readCursorRequest> 
   <container>7.domain1.po1.100.0.1.0.1@16</container> 
   <cursor>1188933747</cursor> 
   <forward>true</forward> 
   <position>start</position> 
   <count>5</count> 
</readCursorRequest>

<readCursorResponse>
   <items> 
      <item> 
         <id>450AB7C1.domain1.po1.100.16E3837.1.FD0.1@1:7.
                     domain1.po1.100.0.1.0.1@16</id> 
         <modified>2012-09-15T22:23:28Z</modified> 
         <container>7.domain1.po1.100.0.1.0.1@16</container> 
         <source>received</source> 
         <subject>1</subject> 
      </item>
      ...
   </items>
   <status>
      <code>0</code> 
   </status>
</readCursorResponse>

1.9.3 Stubbed Items

You can search on the statusExt field to find stubbed items. The values you can pass in the filter for the statusExt field are:

  • stubbed (thirdParthStubbed)

  • downloaded (thirdPartyDownloaded)

  • archived (thirdPartyArchive)

The following example searches for stubbed items:

<getItemsRequest>
  <container>4E2E7543.domain.PO1.100.1646A30.1.44.1@13</container>
  <view>default stubbed</view>
  <filter>
    <element>
      <op>and</op>
      <element>
        <op>isOf</op>
        <field>statusExt</field>
        <value>stubbed</value>
      </element>
      <element>
        <op>exists</op>
        <field>statusExt</field>
        <value>0</value>
      </element>
    </element>
  </filter>
</getItemsRequest>

NOTE:You must search for the existence of the statusExt field and the stubbed value being set or you get false positive matches.