Require ASPX page to be a direct child of the Web

This fixes the behavior experienced in b/11436727 where the non-default view for
Lists could be served thinking they were ASPX pages.

Code Review : https://codereview.appspot.com/61950043/
diff --git a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
index a5b4f71..8fee0f5 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
@@ -1728,14 +1728,28 @@
         return;
       }
 
+      String aspxId = request.getDocId().getUniqueId();
+      String parentId = aspxId.substring(0, aspxId.lastIndexOf('/'));
+      boolean isDirectChild = webUrl.equalsIgnoreCase(parentId);
+      // Check for valid ASPX pages
+      // Process only direct child for current web
+      if (!isDirectChild) {
+        // Alternative approach to this string comparison is to make a
+        // additional web service call for SiteData.GetContentWeb and
+        // check if ASPX page is available under Web.getFPFolder().getFiles()
+        log.log(Level.FINE, "Document [{0}] is not a direct child of Web [{1}]",
+            new Object[] {aspxId, webUrl});
+        response.respondNotFound();
+        log.exiting("SiteAdaptor", "getAspxDocContent");
+        return;
+      }
+
       boolean allowAnonymousAccess
           = isAllowAnonymousReadForWeb(w)
           // Check if anonymous access is denied by web application policy
           && !isDenyAnonymousAccessOnVirtualServer(
               rareModCache.getVirtualServer());
       if (!allowAnonymousAccess) {
-        String aspxId = request.getDocId().getUniqueId();
-        String parentId = aspxId.substring(0, aspxId.lastIndexOf('/'));
         response.setAcl(new Acl.Builder()
             .setInheritFrom(new DocId(parentId))
             .build());
diff --git a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
index d55defb..f38e3cd 100644
--- a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
@@ -836,6 +836,31 @@
   }
 
   @Test
+  public void testGetDocContentListNonDefaultView() throws Exception {
+    SiteDataSoap siteData = MockSiteData.blank()
+        .register(SITES_SITECOLLECTION_S_CONTENT_EXCHANGE)       
+        .register(new URLSegmentsExchange(
+          "http://localhost:1/sites/SiteCollection/Lists/Custom List"
+          + "/NonDefault.aspx",false, null, null, null, null))
+        .register(SITES_SITECOLLECTION_LISTS_CUSTOMLIST_L_CONTENT_EXCHANGE);
+    adaptor = new SharePointAdaptor(initableSoapFactory,
+        new UnsupportedHttpClient(), executorFactory);
+    adaptor.init(new MockAdaptorContext(config, pusher));
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    GetContentsRequest request = new GetContentsRequest(
+        new DocId("http://localhost:1/sites/SiteCollection/Lists/Custom List/"
+          + "NonDefault.aspx"));
+    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 testGetDocContentAttachment() throws Exception {
     SiteDataSoap siteData = MockSiteData.blank()
         .register(SITES_SITECOLLECTION_S_CONTENT_EXCHANGE)