Add attachment support
diff --git a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
index b89a36a..d13644d 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
@@ -67,6 +67,8 @@
= new QName("ows_ServerUrl");
private static final QName OWS_CONTENTTYPE_ATTRIBUTE
= new QName("ows_ContentType");
+ private static final QName OWS_ATTACHMENTS_ATTRIBUTE
+ = new QName("ows_Attachments");
private static final Logger log
= Logger.getLogger(SharePointAdaptor.class.getName());
@@ -187,16 +189,15 @@
throws Exception {
log.entering("SiteDataClient", "getDocContent",
new Object[] {request, response});
- SiteDataStub.GetURLSegments urlRequest
- = new SiteDataStub.GetURLSegments();
- urlRequest.setStrURL(request.getDocId().getUniqueId());
+ String url = request.getDocId().getUniqueId();
+ if (getAttachmentDocContent(request, response)) {
+ // Success, it was an attachment.
+ log.exiting("SiteDataClient", "getDocContent");
+ return;
+ }
+
SiteDataStub.GetURLSegmentsResponse urlResponse
- = stub.getURLSegments(urlRequest);
- log.log(Level.FINE, "GetURLSegments: Result={0}, StrWebID={1}, "
- + "StrItemID={2}, StrListID={3}, StrBucketID={4}",
- new Object[] {urlResponse.getGetURLSegmentsResult(),
- urlResponse.getStrWebID(), urlResponse.getStrListID(),
- urlResponse.getStrItemID(), urlResponse.getStrBucketID()});
+ = getUrlSegments(request.getDocId().getUniqueId());
if (!urlResponse.getGetURLSegmentsResult()) {
log.log(Level.FINE, "responding not found");
response.respondNotFound();
@@ -255,6 +256,14 @@
return docId;
}
+ private String encodeUrl(DocId docId) {
+ log.entering("SiteDataClient", "encodeUrl", docId);
+ URI uri = context.getDocIdEncoder().encodeDocId(docId);
+ String encoded = uri.toASCIIString();
+ log.exiting("SiteDataClient", "encodeUrl", encoded);
+ return encoded;
+ }
+
private String encodeUrl(String url) {
log.entering("SiteDataClient", "encodeUrl", url);
URI uri = context.getDocIdEncoder().encodeDocId(encodeDocId(url));
@@ -467,14 +476,109 @@
IOHelper.copyStream(is, response.getOutputStream());
} else {
// Some list item.
+ response.setContentType("text/html");
Writer writer
= new OutputStreamWriter(response.getOutputStream(), CHARSET);
- // TODO(ejona): Handle this case.
- writer.write("TODO: ListItem");
+ writer.write("<!DOCTYPE html>\n"
+ + "<html><head>"
+ + "<title>List Item " + title + "</title>"
+ + "</head>"
+ + "<body>"
+ + "<h1>List Item " + title + "</h1>");
+ String strAttachments
+ = row.getAttributeValue(OWS_ATTACHMENTS_ATTRIBUTE);
+ int attachments = strAttachments == null
+ ? 0 : Integer.parseInt(strAttachments);
+ if (attachments > 0) {
+ writer.write("<p>Attachments</p><ul>");
+ SiteDataStub.Item item
+ = getContentListItemAttachments(listId, itemId);
+ if (item.getAttachment() != null) {
+ for (SiteDataStub.Attachment_type0 attachment
+ : item.getAttachment()) {
+ writer.write(liUrl(attachment.getURL()));
+ }
+ }
+ writer.write("</ul>");
+ }
+ writer.write("</body></html>");
+ writer.flush();
}
log.exiting("SiteDataClient", "getListItemDocContent");
}
+ private boolean getAttachmentDocContent(Request request, Response response)
+ throws Exception {
+ log.entering("SiteDataClient", "getAttachmentDocContent", new Object[] {
+ request, response});
+ String url = request.getDocId().getUniqueId();
+ if (!url.contains("/Attachments/")) {
+ log.fine("Not an attachment: does not contain /Attachments/");
+ log.exiting("SiteDataClient", "getAttachmentDocContent", false);
+ return false;
+ }
+ String[] parts = url.split("/Attachments/", 2);
+ String listUrl = parts[0] + "/AllItems.aspx";
+ parts = parts[1].split("/", 2);
+ if (parts.length != 2) {
+ log.fine("Could not separate attachment file name and list item id");
+ log.exiting("SiteDataClient", "getAttachmentDocContent", false);
+ return false;
+ }
+ String itemId = parts[0];
+ log.log(Level.FINE, "Detected possible attachment: "
+ + "listUrl={0}, itemId={1}", new Object[] {listUrl, itemId});
+ SiteDataStub.GetURLSegmentsResponse urlResponse = getUrlSegments(listUrl);
+ if (!urlResponse.getGetURLSegmentsResult()) {
+ log.fine("Could not get list id from list url");
+ log.exiting("SiteDataClient", "getAttachmentDocContent", false);
+ return false;
+ }
+ String listId = urlResponse.getStrListID();
+ if (listId == null) {
+ log.fine("List URL does not point to a list");
+ log.exiting("SiteDataClient", "getAttachmentDocContent", false);
+ return false;
+ }
+ SiteDataStub.Item item = getContentListItemAttachments(listId, itemId);
+ boolean verifiedIsAttachment = false;
+ if (item.getAttachment() != null) {
+ for (SiteDataStub.Attachment_type0 attachment : item.getAttachment()) {
+ if (url.equals(attachment.getURL())) {
+ verifiedIsAttachment = true;
+ break;
+ }
+ }
+ }
+ if (verifiedIsAttachment) {
+ log.fine("Suspected attachment verified as being a real attachment. "
+ + "Proceeding to provide content.");
+ } else {
+ log.fine("Suspected attachment not listed in item's attachment list");
+ log.exiting("SiteDataClient", "getAttachmentDocContent", false);
+ return false;
+ }
+ // Because SP is silly, the path of the URI is unencoded, but the rest of
+ // the URI is correct. Thus, we split up the path from the host, and then
+ // turn them into URIs separately, and then turn everything into a
+ // properly-escaped string.
+ parts = url.split("/", 4);
+ String host = parts[0] + "/" + parts[1] + "/" + parts[2] + "/";
+ // host must be properly-encoded already.
+ URI hostUri = URI.create(host);
+ URI pathUri = new URI(null, null, parts[3], null);
+ url = hostUri.resolve(pathUri).toASCIIString();
+ GetMethod method = new GetMethod(url);
+ int statusCode = httpClient.executeMethod(method);
+ if (statusCode != HttpStatus.SC_OK) {
+ throw new IOException("Got status code: " + statusCode);
+ }
+ InputStream is = method.getResponseBodyAsStream();
+ IOHelper.copyStream(is, response.getOutputStream());
+ log.exiting("SiteDataClient", "getAttachmentDocContent", true);
+ return true;
+ }
+
private SiteDataStub.VirtualServer getContentVirtualServer()
throws Exception {
log.entering("SiteDataClient", "getContentVirtualServer");
@@ -514,6 +618,23 @@
return client;
}
+ private SiteDataStub.GetURLSegmentsResponse getUrlSegments(String url)
+ throws Exception {
+ log.entering("SiteDataClient", "getUrlSegments", url);
+ SiteDataStub.GetURLSegments urlRequest
+ = new SiteDataStub.GetURLSegments();
+ urlRequest.setStrURL(url);
+ SiteDataStub.GetURLSegmentsResponse urlResponse
+ = stub.getURLSegments(urlRequest);
+ log.log(Level.FINE, "GetURLSegments: Result={0}, StrWebID={1}, "
+ + "StrItemID={2}, StrListID={3}, StrBucketID={4}",
+ new Object[] {urlResponse.getGetURLSegmentsResult(),
+ urlResponse.getStrWebID(), urlResponse.getStrListID(),
+ urlResponse.getStrItemID(), urlResponse.getStrBucketID()});
+ log.exiting("SiteDataClient", "getUrlSegments", urlResponse);
+ return urlResponse;
+ }
+
private SiteDataStub.ContentDatabase getContentContentDatabase(String id)
throws Exception {
log.entering("SiteDataClient", "getContentContentDatabase", id);
@@ -626,5 +747,29 @@
log.exiting("SiteDataClient", "getContentFolder", folder);
return folder;
}
+
+ private SiteDataStub.Item getContentListItemAttachments(String listId,
+ String itemId) throws Exception {
+ log.entering("SiteDataClient", "getContentListItemAttachments",
+ new Object[] {listId, itemId});
+ SiteDataStub.GetContent request = new SiteDataStub.GetContent();
+ request.setObjectType(SiteDataStub.ObjectType.ListItemAttachments);
+ request.setRetrieveChildItems(true);
+ request.setSecurityOnly(false);
+ request.setObjectId(listId);
+ request.setFolderUrl("");
+ request.setItemId(itemId);
+ SiteDataStub.GetContentResponse response = stub.getContent(request);
+ log.log(Level.FINE, "GetContent(ListItemAttachments): Result={0}, "
+ + "LastItemIdOnPage={1}", new Object[] {
+ response.getGetContentResult(), response.getLastItemIdOnPage()});
+ String xml = response.getGetContentResult();
+ xml = xml.replace("<Item ", "<Item xmlns='" + XMLNS + "' ");
+ XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(
+ new StringReader(xml));
+ SiteDataStub.Item item = SiteDataStub.Item.Factory.parse(reader);
+ log.exiting("SiteDataClient", "getContentListItemAttachments", item);
+ return item;
+ }
}
}