Return 404 for attachment documents when parent list item is deleted or not available.
b/11051596
Code Review : https://codereview.appspot.com/105790045/
diff --git a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
index 16e682a..dfb3af3 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
@@ -2338,12 +2338,20 @@
         log.exiting("SiteAdaptor", "getAttachmentDocContent", true);
         return true;
       }
-      // TODO(ejona): Figure out a way to give a Not Found if the itemId is
-      // wrong. getContentItem() will throw an exception if the itemId does not
-      // exist.
+
       ItemData itemData = siteDataClient.getContentItem(listId, itemId);
       Xml xml = itemData.getXml();
       Element data = getFirstChildWithName(xml, DATA_ELEMENT);
+      String itemCount = data.getAttribute("ItemCount");
+      if ("0".equals(itemCount)) {
+        log.fine("Could not get parent list item as ItemCount is 0.");
+        log.exiting("SiteAdaptor", "getAttachmentDocContent", false);
+        // Returing false here instead of returing 404 to avoid wrongly
+        // identifying file documents as attachments when DocumentLibrary has
+        // folder name Attachments. Returing false here would allow code
+        // to see if this document was a regular file in DocumentLibrary.
+        return false;
+      }
       Element row = getChildrenWithName(data, ROW_ELEMENT).get(0);
       String scopeId
           = row.getAttribute(OWS_SCOPEID_ATTRIBUTE).split(";#", 2)[1];
diff --git a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
index 210a391..682b0e8 100644
--- a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
@@ -1207,6 +1207,54 @@
         response.getDisplayUrl());
     assertEquals(new Date(1335910481000L), response.getLastModified());
   }
+  
+  @Test
+  public void testGetDocContentAttachmentDeletedParent() throws Exception {
+    SiteDataSoap siteData = MockSiteData.blank()
+        .register(SITES_SITECOLLECTION_S_CONTENT_EXCHANGE)
+        .register(SITES_SITECOLLECTION_LISTS_CUSTOMLIST_URLSEG_EXCHANGE)
+        .register(SITES_SITECOLLECTION_LISTS_CUSTOMLIST_L_CONTENT_EXCHANGE)
+        .register(SITES_SITECOLLECTION_LISTS_CUSTOMLIST_2_LI_CONTENT_EXCHANGE
+            .replaceInContent("data ItemCount=\"1\"", "data ItemCount=\"0\""))
+        .register(new URLSegmentsExchange(
+            "http://localhost:1/sites/SiteCollection/Lists/Custom List"
+                + "/Attachments/2/1046000.pdf", false, null, null, null, null));
+
+    final String site = "http://localhost:1/sites/SiteCollection";
+    final String attachmentId = site 
+        + "/Lists/Custom List/Attachments/2/1046000.pdf";
+    adaptor = new SharePointAdaptor(initableSoapFactory,
+        new HttpClient() {
+      @Override
+      public FileInfo issueGetRequest(URL url,
+          List<String> authenticationCookies) {
+        throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public String getRedirectLocation(URL url,
+          List<String> authenticationCookies) throws IOException {
+        assertEquals(
+            "http://localhost:1/sites/SiteCollection/Lists/Custom%20List",
+            url.toString());
+
+        return "http://localhost:1/sites/SiteCollection/Lists/Custom List"
+            + "/AllItems.aspx";
+      }
+    }, executorFactory, new MockAuthenticationClientFactoryForms());
+    adaptor.init(new MockAdaptorContext(config, pusher));
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    GetContentsRequest request = new GetContentsRequest(
+        new DocId(attachmentId));
+    GetContentsResponse response = new GetContentsResponse(baos);
+    adaptor.new SiteAdaptor("http://localhost:1/sites/SiteCollection",
+          "http://localhost:1/sites/SiteCollection", siteData,
+          new UnsupportedUserGroupSoap(), new UnsupportedPeopleSoap(),
+          new UnsupportedCallable<MemberIdMapping>(),
+          new UnsupportedCallable<MemberIdMapping>())
+        .getDocContent(request, response);
+    assertTrue(response.isNotFound());
+  }
 
   @Test
   public void testGetDocContentAttachmentSpecialMimeType() throws Exception {